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

📄 kbd.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1992, 1993 *	The Regents of the University of California.  All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and * contributed to Berkeley. * * 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, Lawrence Berkeley Laboratory. * * 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. * *	@(#)kbd.c	8.2 (Berkeley) 10/30/93 * * from: $Header: kbd.c,v 1.18 93/10/31 05:44:01 torek Exp $ (LBL) *//* * Keyboard driver (/dev/kbd -- note that we do not have minor numbers * [yet?]).  Translates incoming bytes to ASCII or to `firm_events' and * passes them up to the appropriate reader. */#include <sys/param.h>#include <sys/conf.h>#include <sys/device.h>#include <sys/ioctl.h>#include <sys/kernel.h>#include <sys/proc.h>#include <sys/syslog.h>#include <sys/systm.h>#include <sys/tty.h>#include <machine/autoconf.h>#include <sparc/dev/vuid_event.h>#include <sparc/dev/event_var.h>#include <sparc/dev/kbd.h>#include <sparc/dev/kbio.h>/* * Sun keyboard definitions (from Sprite). * These apply to type 2, 3 and 4 keyboards. */#define	KEY_CODE(c)	((c) & KBD_KEYMASK)	/* keyboard code index */#define	KEY_UP(c)	((c) & KBD_UP)		/* true => key went up *//* * Each KEY_CODE(x) can be translated via the tables below. * The result is either a valid ASCII value in [0..0x7f] or is one * of the following `magic' values saying something interesting * happened.  If LSHIFT or RSHIFT has changed state the next * lookup should come from the appropriate table; if ALLUP is * sent all keys (including both shifts and the control key) are * now up, and the next byte is the keyboard ID code. * * These tables ignore all function keys (on the theory that if you * want these keys, you should use a window system).  Note that * `caps lock' is just mapped as `ignore' (so there!). (Only the * type 3 and 4 keyboards have a caps lock key anyway.) */#define	KEY_MAGIC	0x80		/* flag => magic value */#define	KEY_IGNORE	0x80#define	KEY_L1		KEY_IGNORE#define	KEY_CAPSLOCK	KEY_IGNORE#define	KEY_LSHIFT	0x81#define	KEY_RSHIFT	0x82#define	KEY_CONTROL	0x83#define	KEY_ALLUP	0x84		/* all keys are now up; also reset *//* * Decode tables for type 2, 3, and 4 keyboards * (stolen from Sprite; see also kbd.h). */static const u_char kbd_unshifted[] = {/*   0 */	KEY_IGNORE,	KEY_L1,		KEY_IGNORE,	KEY_IGNORE,/*   4 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*   8 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*  12 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*  16 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*  20 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*  24 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*  28 */	KEY_IGNORE,	'\033',		'1',		'2',/*  32 */	'3',		'4',		'5',		'6',/*  36 */	'7',		'8',		'9',		'0',/*  40 */	'-',		'=',		'`',		'\b',/*  44 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*  48 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*  52 */	KEY_IGNORE,	'\t',		'q',		'w',/*  56 */	'e',		'r',		't',		'y',/*  60 */	'u',		'i',		'o',		'p',/*  64 */	'[',		']',		'\177',		KEY_IGNORE,/*  68 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*  72 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*  76 */	KEY_CONTROL,	'a',		's',		'd',/*  80 */	'f',		'g',		'h',		'j',/*  84 */	'k',		'l',		';',		'\'',/*  88 */	'\\',		'\r',		KEY_IGNORE,	KEY_IGNORE,/*  92 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*  96 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_LSHIFT,/* 100 */	'z',		'x',		'c',		'v',/* 104 */	'b',		'n',		'm',		',',/* 108 */	'.',		'/',		KEY_RSHIFT,	'\n',/* 112 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/* 116 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_CAPSLOCK,/* 120 */	KEY_IGNORE,	' ',		KEY_IGNORE,	KEY_IGNORE,/* 124 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_ALLUP,};static const u_char kbd_shifted[] = {/*   0 */	KEY_IGNORE,	KEY_L1,		KEY_IGNORE,	KEY_IGNORE,/*   4 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*   8 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*  12 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*  16 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*  20 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*  24 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*  28 */	KEY_IGNORE,	'\033',		'!',		'@',/*  32 */	'#',		'$',		'%',		'^',/*  36 */	'&',		'*',		'(',		')',/*  40 */	'_',		'+',		'~',		'\b',/*  44 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*  48 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*  52 */	KEY_IGNORE,	'\t',		'Q',		'W',/*  56 */	'E',		'R',		'T',		'Y',/*  60 */	'U',		'I',		'O',		'P',/*  64 */	'{',		'}',		'\177',		KEY_IGNORE,/*  68 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*  72 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*  76 */	KEY_CONTROL,	'A',		'S',		'D',/*  80 */	'F',		'G',		'H',		'J',/*  84 */	'K',		'L',		':',		'"',/*  88 */	'|',		'\r',		KEY_IGNORE,	KEY_IGNORE,/*  92 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/*  96 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_LSHIFT,/* 100 */	'Z',		'X',		'C',		'V',/* 104 */	'B',		'N',		'M',		'<',/* 108 */	'>',		'?',		KEY_RSHIFT,	'\n',/* 112 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,/* 116 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_CAPSLOCK,/* 120 */	KEY_IGNORE,	' ',		KEY_IGNORE,	KEY_IGNORE,/* 124 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_ALLUP,};/* * We need to remember the state of the keyboard's shift and control * keys, and we need a per-type translation table. */struct kbd_state {	const u_char *kbd_unshifted;	/* unshifted keys */	const u_char *kbd_shifted;	/* shifted keys */	const u_char *kbd_cur;	/* current keys (either of the preceding) */	union {		char	c[2];	/* left and right shift keys */		short	s;	/* true => either shift key */	} kbd_shift;#define	kbd_lshift	kbd_shift.c[0]#define	kbd_rshift	kbd_shift.c[1]#define	kbd_anyshift	kbd_shift.s	char	kbd_control;	/* true => ctrl down */	char	kbd_click;	/* true => keyclick enabled */	char	kbd_takeid;	/* take next byte as ID */	u_char	kbd_id;		/* a place to store the ID */};/* * Keyboard driver state.  The ascii and kbd links go up and down and * we just sit in the middle doing translation.  Note that it is possible * to get just one of the two links, in which case /dev/kbd is unavailable. * The downlink supplies us with `internal' open and close routines which * will enable dataflow across the downlink.  We promise to call open when * we are willing to take keystrokes, and to call close when we are not. * If /dev/kbd is not the console tty input source, we do this whenever * /dev/kbd is in use; otherwise we just leave it open forever. */struct kbd_softc {	struct	tty *k_cons;		/* uplink for ASCII data to console */	struct	tty *k_kbd;		/* downlink for output to keyboard */	void	(*k_open) __P((struct tty *));	/* enable dataflow */	void	(*k_close) __P((struct tty *));	/* disable dataflow */	int	k_evmode;		/* set if we should produce events */	struct	kbd_state k_state;	/* ASCII decode state */	struct	evvar k_events;		/* event queue state */} kbd_softc;/* Prototypes */void	kbd_ascii(struct tty *);void	kbd_serial(struct tty *, void (*)(), void (*)());static	void kbd_getid(void *);void	kbd_reset(struct kbd_state *);static	int kbd_translate(int, struct kbd_state *);void	kbd_rint(int);int	kbdopen(dev_t, int, int, struct proc *);int	kbdclose(dev_t, int, int, struct proc *);int	kbdread(dev_t, struct uio *, int);int	kbdwrite(dev_t, struct uio *, int);int	kbdioctl(dev_t, int, caddr_t, int, struct proc *);int	kbdselect(dev_t, int, struct proc *);int	kbd_docmd(int, int);/* * Attach the console keyboard ASCII (up-link) interface. * This happens before kbd_serial. */voidkbd_ascii(struct tty *tp){	kbd_softc.k_cons = tp;}/* * Attach the console keyboard serial (down-link) interface. * We pick up the initial keyboard click state here as well. */voidkbd_serial(struct tty *tp, void (*iopen)(), void (*iclose)()){	register struct kbd_softc *k;	register char *cp;	k = &kbd_softc;	k->k_kbd = tp;	k->k_open = iopen;	k->k_close = iclose;	cp = getpropstring(optionsnode, "keyboard-click?");	if (cp && strcmp(cp, "true") == 0)		k->k_state.kbd_click = 1;}/* * Called from main() during pseudo-device setup.  If this keyboard is * the console, this is our chance to open the underlying serial port and * send a RESET, so that we can find out what kind of keyboard it is. */voidkbdattach(int nkbd){	register struct kbd_softc *k;	register struct tty *tp;	if (kbd_softc.k_cons != NULL) {		k = &kbd_softc;		tp = k->k_kbd;		(*k->k_open)(tp);	/* never to be closed */		if (ttyoutput(KBD_CMD_RESET, tp) >= 0)			panic("kbdattach");		(*tp->t_oproc)(tp);	/* get it going */	}}voidkbd_reset(register struct kbd_state *ks){	/*	 * On first identification, wake up anyone waiting for type	 * and set up the table pointers.	 */	if (ks->kbd_unshifted == NULL) {		wakeup((caddr_t)ks);		ks->kbd_unshifted = kbd_unshifted;		ks->kbd_shifted = kbd_shifted;		ks->kbd_cur = ks->kbd_unshifted;	}	/* Restore keyclick, if necessary */	switch (ks->kbd_id) {	case KB_SUN2:		/* Type 2 keyboards don't support keyclick */		break;	case KB_SUN3:		/* Type 3 keyboards come up with keyclick on */		if (!ks->kbd_click)			(void) kbd_docmd(KBD_CMD_NOCLICK, 0);		break;	case KB_SUN4:		/* Type 4 keyboards come up with keyclick off */		if (ks->kbd_click)			(void) kbd_docmd(KBD_CMD_CLICK, 0);		break;	}}/* * Turn keyboard up/down codes into ASCII. */static intkbd_translate(register int c, register struct kbd_state *ks){	register int down;	if (ks->kbd_cur == NULL) {		/*		 * Do not know how to translate yet.

⌨️ 快捷键说明

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