⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kb_ctrl.c

📁 早期freebsd实现
💻 C
字号:
/* * Copyright (c) 1992, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: $Hdr: kb_ctrl.c,v 4.300 91/06/09 06:14:49 root Rel41 $ SONY * *	@(#)kb_ctrl.c	8.1 (Berkeley) 6/10/93 *//* *	Keyboard driver */#ifdef IPC_MRX#include <sys/ioctl.h>#include <news3400/iop/keyboard.h>#include <news3400/iop/kbreg.h>#else#include <sys/ioctl.h>#include <sys/param.h>#include <sys/systm.h>#include <sys/types.h>#include <news3400/iop/keyboard.h>#include <news3400/iop/kbreg.h>#endifextern int tmode;extern int kbd_status;int iscaps = 0;int change_country = K_JAPANESE_J;int country;extern Key_table default_table[];#ifdef CPU_SINGLEextern Key_table key_table[];Key_table *key_table_addr = key_table;#endif#ifdef CPU_DOUBLEKey_table *key_table_addr = default_table;#endif#ifdef CPU_SINGLE#include "ms.h"#include <sys/clist.h>	#include <sys/ttydev.h>#include <sys/tty.h>#include <news3400/sio/scc.h>#include <sys/time.h>#include <news3400/iop/mouse.h>extern int cnrint();kbd_open(chan)	int chan;{	register int i;#if defined(news3400)	kbm_open(chan);#endif	return (0);}kbd_read(chan, buf, n)	int chan;	char *buf;	int n;{#if defined(news1700) || defined(news1200)	return (kbd_read_raw(chan, buf, n));#endif}kbd_write(chan, buf, n)	int chan;	char *buf;	int n;{#if defined(news3400)	return (kbm_write(SCC_KEYBOARD, buf, n));#endif}kbd_back(buf, len)	register char *buf;	register int len;{	int s;	while (--len >= 0) {		s = spltty();		cnrint(*buf++);		(void) splx(s);	}	return (0);}#define	KBPRI	(PZERO+1)struct clist scode_buf;struct clist keyboard_buf;char	kb_rwait;kbd_flush(){	ndflush(&scode_buf, scode_buf.c_cc);	return (0);}statickbd_put_raw(scode)	int scode;{	extern char kb_busy;	if (kb_busy) {		if (scode_buf.c_cc < CBSIZE)			putc(scode, &scode_buf);		if (kb_rwait) {			kb_rwait = 0;			wakeup((caddr_t)&kb_rwait);		}	}	return (scode);	}kbd_read_raw(chan, buf, count)	int chan;	char *buf;	register int count;{	register int i;	register int n;	register int s;	if (count <= 0)		return (count);	s = splscc();	while ((n = min(scode_buf.c_cc, count)) == 0) {		kb_rwait = 1;		sleep((caddr_t)&kb_rwait, KBPRI);		kb_rwait = 0;	}	(void) splx(s);	for (i = n; i > 0 ; i--)		*buf++ = getc(&scode_buf);	return (n);}kbd_nread(){	return (scode_buf.c_cc);}kbd_bell(n)	register int n;{#if defined(news3400)	(void) kbm_write(SCC_KEYBOARD, NULL, n);#endif	return (0);}kbd_putcode(code)	int code;{	int c;	kbd_put_raw(code);	kbd_encode(code);	while ((c = getc(&keyboard_buf)) != -1)		cnrint(c); }put_code(buf, cnt)	register char *buf;	register int cnt;{	while (--cnt >= 0)		putc(*buf++, &keyboard_buf);}kb_softint(){	int code;	extern int tty00_is_console;	while ((code = xgetc(SCC_KEYBOARD)) >= 0) {#if defined(news3200)		/* BEGIN reiko */		if ((code & 0x7f) == KEY_EISUU) {			int up = code & OFF;			static int kana = 0;			if (kana) {				if (up) {					kana = 0;				}			} else {				if (up) {					code = KEY_KANA | OFF;					kana = 1;				} else {					code = KEY_KANA;				}			}		}#endif#ifdef NOTDEF /* KU:XXX */		if (!tty00_is_console) #endif			rst_dimmer_cnt();#if NMS > 0		if (!mskeytrigger(0, code & OFF, code & 0x7f))#endif		kbd_putcode(code);	}}#endif /* CPU_SINGLE */#ifdef IPC_MRX#include "mrx.h"#include "queue.h"#include "process.h"#include "buffer.h"#include "port.h"#include "message.h"#include "machdep.h"#include "malloc.h"#include "config.h"#include "kbms.h"static struct buffer *kbd_buf;static int port_kbd_intr;static int port_kbd_back;static int port_kbd_ctrl;keyboard(chan)	int chan;{	int kbd_ctrl(), kbd_output();	int kbd_read(), kbd_ioctl(), kbd_io();#ifdef news3800	extern int (*Xkb_intr)();	int kb_intr();	Xkb_intr = kb_intr;#endif	kb_ioctl = kbd_ioctl;	kb_read = kbd_read;	kbd_init();	proc_create("kbd_ctrl", kbd_ctrl, 300, DEFAULT_STACK_SIZE, 0);	proc_create("kbd_output", kbd_output, 300, DEFAULT_STACK_SIZE, 0);	proc_create("kbd_io", kbd_io, 300, DEFAULT_STACK_SIZE, 0);}int (*reset_dimmer)();kbd_ctrl(){	register int m, n;	register int select;	int *len, from, count;	char *addr;	int ports[3];	static char buf[16];	ports[0] = port_kbd_intr = port_create("kb_intr");	ports[1] = port_kbd_back = port_create("kb_echoback");	ports[2] = port_kbd_ctrl = STDPORT;#ifdef news3800	*(char *)KEYBD_RESET = 0;	*(char *)KEYBD_INTE = 1;#endif	kbd_buf = buffer_alloc(32);	(void) spl0();	for (;;) {		if (buffer_status(kbd_buf) > 0)			m = 3;		else			m = 2;		if ((select = msg_select(m, ports)) == 0) {			msg_recv(ports[0], NULL, &addr, &count, 0);			if (reset_dimmer)				(*reset_dimmer)();			while (--count >= 0) {				if (send_mouse == 0 || (*send_mouse)(*addr) == 0)					kbd_encode(*addr);				addr++;			}		} else if (select == 1) {	/* ESC [ 6 n */			msg_recv(ports[select], NULL, &addr, &count, 0);			put(kbd_buf, addr, count);		} else {			msg_recv(ports[select], &from, &len, NULL, 0); 			n = buffer_status(kbd_buf);			n = min(n, *len);			n = get(kbd_buf, buf, min(n, sizeof (buf)));			msg_send(from, ports[select], buf, n, 0);		}	}}kbd_output(){	char *addr;	int from, len;	(void) spl0();	for (;;) {		msg_recv(STDPORT, &from, &addr, &len, 0);#ifdef news3800		len = kbd_write(0, addr, len);#endif		msg_send(from, STDPORT, &len, sizeof(len), 0);	}}kbd_io(){	struct kb_ctrl_req *req;	int from, reply;	(void) spl0();	for (;;) {		msg_recv(STDPORT, &from, &req, NULL, 0);		if (req->kb_func == KIOCCHTBL || req->kb_func == KIOCOYATBL)			kbd_ioctl(0, req->kb_func, req->kb_arg);		else			kbd_ioctl(0, req->kb_func, &req->kb_arg);		reply = req->kb_arg;		msg_send(from, STDPORT, &reply, sizeof(reply), 0);	}}kbd_read(chan, buf, n)	int chan;	char *buf;	int n;{	static int port;	char *addr;	int len;	if (port == 0)		port = port_create("port_kbd_read");	if (n <= 0)		return (0);	msg_send(port_kbd_ctrl, port, &n, sizeof (n), 0);	msg_recv(port, NULL, &addr, &len, 0);	bcopy(addr, buf, len);	msg_free(port);	return (len);}kbd_write(chan, buf, n)	int chan;	char *buf;	int n;{#ifdef news3800	*(char *)BEEP_FREQ = ~(n & 1);	*(char *)KEYBD_BEEP = 1;	return (n);#endif}kbd_back(buf, len)	char *buf;	int len;{	msg_send(port_kbd_back, 0, buf, len, 0);	return (0);}kbd_nread(){	return (buffer_status(kbd_buf));}kbd_flush(){	buffer_flush(kbd_buf);	return (0);}#ifdef news3800kb_intr(){	char c;	if (port_kbd_intr > 0)		while (*(char *)KBMS_STAT & (1 << b_KBREADY)) {			c = *(char *)KEYBD_DATA;			msg_send(port_kbd_intr, 0, &c, sizeof (char), 0);		}}#endif /* news3800 */kbd_bell(n, port)	int n, port;{#ifdef news3800	(void) kbd_write(0, NULL, n);#else	kbd_bell_scc(n, port);#endif	return (0);}put_code(buf, cnt)	char *buf;	int cnt;{	put(kbd_buf, buf, cnt);}#endif /* IPC_MRX */kbd_ioctl(chan, cmd, argp)	int chan;	int cmd;	int *argp;{	switch (cmd) {	case KIOCFLUSH:		return (kbd_flush());	case KIOCSETS:	case KIOCGETS:		return (kbd_string(cmd, (Pfk_string *)argp));	case KIOCBELL:		return (kbd_bell(*argp));	case KIOCBACK:		if (argp == NULL)			return (-1);		if ((int)((Key_string *)argp)->key_string == NULL)			return (-1);		if ((int)((Key_string *)argp)->key_length <= 0)			return (-1);		return (kbd_back(((Key_string *)argp)->key_string,		    ((Key_string *)argp)->key_length));	case KIOCREPT:		return (kbd_repeat(1));	case KIOCNRPT:		return (kbd_repeat(0));	case KIOCNREAD:		*argp = kbd_nread();		return (0);	case KIOCSETLOCK:		iscaps = *argp;		return (0);	case KIOCGETCNUM:		*argp = country;		return (0);	case KIOCSETCNUM:		country = *argp;		change_country = country;		return (0);	case KIOCDEFTBL:		key_table_addr = default_table;		country = K_JAPANESE_J;		return (0);	case KIOCCHTBL:		key_table_addr = (Key_table *)argp;		country = change_country;		return (0);	case KIOCGETSTAT:		*argp = kbd_status;		return (0);	case KIOCSETSTAT:		kbd_status = *argp;		return (0);	default:		return (-1);	}}kbd_bell_scc(n)	register int n;{	register int i;	static char bell_data[] = {		0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,		0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,		0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,		0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0	};	while (n > 0) {		i = min(n, sizeof (bell_data));		(void) kbd_write(0, bell_data, i);		n -= i;	}}#ifdef KBDEBUGscc_error_puts(chan, buf)	int chan;	char *buf;{	while (*buf) {		scc_error_write(chan, *buf++, 1);	}}scc_error_write_hex(chan, n, zs)	int chan;	unsigned int n;	int zs;{	int i;	int tmp, al;	static char hex[] = "0123456789abcdef";	al = 0;	for (i = 28; i >= 0; i -= 4) {		tmp = (n >> i) & 0x0f;		if (tmp || al || !zs || !i) {			al++;			scc_error_write(chan, hex[tmp], 1);		}	}}#endif /* KBDEBUG */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -