xref: /plan9/sys/src/9/omap/kbd.c (revision 58da3067adcdccaaa043d0bfde28ba83b7ced07d)
193631029SDavid du Colombier /*
2aeee3693SDavid du Colombier  * simulated keyboard input for systems with none (except via uart or usb)
393631029SDavid du Colombier  *
493631029SDavid du Colombier  * gutted version of ps2 version from ../pc
593631029SDavid du Colombier  */
693631029SDavid du Colombier #include	"u.h"
793631029SDavid du Colombier #include	"../port/lib.h"
893631029SDavid du Colombier #include	"mem.h"
993631029SDavid du Colombier #include	"dat.h"
1093631029SDavid du Colombier #include	"fns.h"
1193631029SDavid du Colombier #include	"io.h"
1293631029SDavid du Colombier #include	"../port/error.h"
1393631029SDavid du Colombier 
1493631029SDavid du Colombier enum {
1593631029SDavid du Colombier 	Spec=		0xF800,		/* Unicode private space */
1693631029SDavid du Colombier 	PF=		Spec|0x20,	/* num pad function key */
1793631029SDavid du Colombier 	View=		Spec|0x00,	/* view (shift window up) */
1893631029SDavid du Colombier 	KF=		0xF000,		/* function key (begin Unicode private space) */
1993631029SDavid du Colombier 	Shift=		Spec|0x60,
2093631029SDavid du Colombier 	Break=		Spec|0x61,
2193631029SDavid du Colombier 	Ctrl=		Spec|0x62,
2293631029SDavid du Colombier 	Latin=		Spec|0x63,
2393631029SDavid du Colombier 	Caps=		Spec|0x64,
2493631029SDavid du Colombier 	Num=		Spec|0x65,
2593631029SDavid du Colombier 	Middle=		Spec|0x66,
2693631029SDavid du Colombier 	Altgr=		Spec|0x67,
2793631029SDavid du Colombier 	Kmouse=		Spec|0x100,
2893631029SDavid du Colombier 	No=		0x00,		/* peter */
2993631029SDavid du Colombier 
3093631029SDavid du Colombier 	Home=		KF|13,
3193631029SDavid du Colombier 	Up=		KF|14,
3293631029SDavid du Colombier 	Pgup=		KF|15,
3393631029SDavid du Colombier 	Print=		KF|16,
3493631029SDavid du Colombier 	Left=		KF|17,
3593631029SDavid du Colombier 	Right=		KF|18,
3693631029SDavid du Colombier 	End=		KF|24,
3793631029SDavid du Colombier 	Down=		View,
3893631029SDavid du Colombier 	Pgdown=		KF|19,
3993631029SDavid du Colombier 	Ins=		KF|20,
4093631029SDavid du Colombier 	Del=		0x7F,
4193631029SDavid du Colombier 	Scroll=		KF|21,
4293631029SDavid du Colombier 
4393631029SDavid du Colombier 	Nscan=	128,
4493631029SDavid du Colombier 
4593631029SDavid du Colombier 	Int=	0,			/* kbscans indices */
4693631029SDavid du Colombier 	Ext,
4793631029SDavid du Colombier 	Nscans,
4893631029SDavid du Colombier };
4993631029SDavid du Colombier 
5093631029SDavid du Colombier /*
5193631029SDavid du Colombier  * The codes at 0x79 and 0x7b are produced by the PFU Happy Hacking keyboard.
5293631029SDavid du Colombier  * A 'standard' keyboard doesn't produce anything above 0x58.
5393631029SDavid du Colombier  */
5493631029SDavid du Colombier Rune kbtab[Nscan] =
5593631029SDavid du Colombier {
5693631029SDavid du Colombier [0x00]	No,	0x1b,	'1',	'2',	'3',	'4',	'5',	'6',
5793631029SDavid du Colombier [0x08]	'7',	'8',	'9',	'0',	'-',	'=',	'\b',	'\t',
5893631029SDavid du Colombier [0x10]	'q',	'w',	'e',	'r',	't',	'y',	'u',	'i',
5993631029SDavid du Colombier [0x18]	'o',	'p',	'[',	']',	'\n',	Ctrl,	'a',	's',
6093631029SDavid du Colombier [0x20]	'd',	'f',	'g',	'h',	'j',	'k',	'l',	';',
6193631029SDavid du Colombier [0x28]	'\'',	'`',	Shift,	'\\',	'z',	'x',	'c',	'v',
6293631029SDavid du Colombier [0x30]	'b',	'n',	'm',	',',	'.',	'/',	Shift,	'*',
6393631029SDavid du Colombier [0x38]	Latin,	' ',	Ctrl,	KF|1,	KF|2,	KF|3,	KF|4,	KF|5,
6493631029SDavid du Colombier [0x40]	KF|6,	KF|7,	KF|8,	KF|9,	KF|10,	Num,	Scroll,	'7',
6593631029SDavid du Colombier [0x48]	'8',	'9',	'-',	'4',	'5',	'6',	'+',	'1',
6693631029SDavid du Colombier [0x50]	'2',	'3',	'0',	'.',	No,	No,	No,	KF|11,
6793631029SDavid du Colombier [0x58]	KF|12,	No,	No,	No,	No,	No,	No,	No,
6893631029SDavid du Colombier [0x60]	No,	No,	No,	No,	No,	No,	No,	No,
6993631029SDavid du Colombier [0x68]	No,	No,	No,	No,	No,	No,	No,	No,
7093631029SDavid du Colombier [0x70]	No,	No,	No,	No,	No,	No,	No,	No,
7193631029SDavid du Colombier [0x78]	No,	View,	No,	Up,	No,	No,	No,	No,
7293631029SDavid du Colombier };
7393631029SDavid du Colombier 
7493631029SDavid du Colombier Rune kbtabshift[Nscan] =
7593631029SDavid du Colombier {
7693631029SDavid du Colombier [0x00]	No,	0x1b,	'!',	'@',	'#',	'$',	'%',	'^',
7793631029SDavid du Colombier [0x08]	'&',	'*',	'(',	')',	'_',	'+',	'\b',	'\t',
7893631029SDavid du Colombier [0x10]	'Q',	'W',	'E',	'R',	'T',	'Y',	'U',	'I',
7993631029SDavid du Colombier [0x18]	'O',	'P',	'{',	'}',	'\n',	Ctrl,	'A',	'S',
8093631029SDavid du Colombier [0x20]	'D',	'F',	'G',	'H',	'J',	'K',	'L',	':',
8193631029SDavid du Colombier [0x28]	'"',	'~',	Shift,	'|',	'Z',	'X',	'C',	'V',
8293631029SDavid du Colombier [0x30]	'B',	'N',	'M',	'<',	'>',	'?',	Shift,	'*',
8393631029SDavid du Colombier [0x38]	Latin,	' ',	Ctrl,	KF|1,	KF|2,	KF|3,	KF|4,	KF|5,
8493631029SDavid du Colombier [0x40]	KF|6,	KF|7,	KF|8,	KF|9,	KF|10,	Num,	Scroll,	'7',
8593631029SDavid du Colombier [0x48]	'8',	'9',	'-',	'4',	'5',	'6',	'+',	'1',
8693631029SDavid du Colombier [0x50]	'2',	'3',	'0',	'.',	No,	No,	No,	KF|11,
8793631029SDavid du Colombier [0x58]	KF|12,	No,	No,	No,	No,	No,	No,	No,
8893631029SDavid du Colombier [0x60]	No,	No,	No,	No,	No,	No,	No,	No,
8993631029SDavid du Colombier [0x68]	No,	No,	No,	No,	No,	No,	No,	No,
9093631029SDavid du Colombier [0x70]	No,	No,	No,	No,	No,	No,	No,	No,
9193631029SDavid du Colombier [0x78]	No,	Up,	No,	Up,	No,	No,	No,	No,
9293631029SDavid du Colombier };
9393631029SDavid du Colombier 
9493631029SDavid du Colombier Rune kbtabesc1[Nscan] =
9593631029SDavid du Colombier {
9693631029SDavid du Colombier [0x00]	No,	No,	No,	No,	No,	No,	No,	No,
9793631029SDavid du Colombier [0x08]	No,	No,	No,	No,	No,	No,	No,	No,
9893631029SDavid du Colombier [0x10]	No,	No,	No,	No,	No,	No,	No,	No,
9993631029SDavid du Colombier [0x18]	No,	No,	No,	No,	'\n',	Ctrl,	No,	No,
10093631029SDavid du Colombier [0x20]	No,	No,	No,	No,	No,	No,	No,	No,
10193631029SDavid du Colombier [0x28]	No,	No,	Shift,	No,	No,	No,	No,	No,
10293631029SDavid du Colombier [0x30]	No,	No,	No,	No,	No,	'/',	No,	Print,
10393631029SDavid du Colombier [0x38]	Altgr,	No,	No,	No,	No,	No,	No,	No,
10493631029SDavid du Colombier [0x40]	No,	No,	No,	No,	No,	No,	Break,	Home,
10593631029SDavid du Colombier [0x48]	Up,	Pgup,	No,	Left,	No,	Right,	No,	End,
10693631029SDavid du Colombier [0x50]	Down,	Pgdown,	Ins,	Del,	No,	No,	No,	No,
10793631029SDavid du Colombier [0x58]	No,	No,	No,	No,	No,	No,	No,	No,
10893631029SDavid du Colombier [0x60]	No,	No,	No,	No,	No,	No,	No,	No,
10993631029SDavid du Colombier [0x68]	No,	No,	No,	No,	No,	No,	No,	No,
11093631029SDavid du Colombier [0x70]	No,	No,	No,	No,	No,	No,	No,	No,
11193631029SDavid du Colombier [0x78]	No,	Up,	No,	No,	No,	No,	No,	No,
11293631029SDavid du Colombier };
11393631029SDavid du Colombier 
114*58da3067SDavid du Colombier Rune kbtabshiftesc1[Nscan] =
115*58da3067SDavid du Colombier {
116*58da3067SDavid du Colombier [0x00]	No,	No,	No,	No,	No,	No,	No,	No,
117*58da3067SDavid du Colombier [0x08]	No,	No,	No,	No,	No,	No,	No,	No,
118*58da3067SDavid du Colombier [0x10]	No,	No,	No,	No,	No,	No,	No,	No,
119*58da3067SDavid du Colombier [0x18]	No,	No,	No,	No,	No,	No,	No,	No,
120*58da3067SDavid du Colombier [0x20]	No,	No,	No,	No,	No,	No,	No,	No,
121*58da3067SDavid du Colombier [0x28]	No,	No,	No,	No,	No,	No,	No,	No,
122*58da3067SDavid du Colombier [0x30]	No,	No,	No,	No,	No,	No,	No,	No,
123*58da3067SDavid du Colombier [0x38]	No,	No,	No,	No,	No,	No,	No,	No,
124*58da3067SDavid du Colombier [0x40]	No,	No,	No,	No,	No,	No,	No,	No,
125*58da3067SDavid du Colombier [0x48]	Up,	No,	No,	No,	No,	No,	No,	No,
126*58da3067SDavid du Colombier [0x50]	No,	No,	No,	No,	No,	No,	No,	No,
127*58da3067SDavid du Colombier [0x58]	No,	No,	No,	No,	No,	No,	No,	No,
128*58da3067SDavid du Colombier [0x60]	No,	No,	No,	No,	No,	No,	No,	No,
129*58da3067SDavid du Colombier [0x68]	No,	No,	No,	No,	No,	No,	No,	No,
130*58da3067SDavid du Colombier [0x70]	No,	No,	No,	No,	No,	No,	No,	No,
131*58da3067SDavid du Colombier [0x78]	No,	Up,	No,	No,	No,	No,	No,	No,
132*58da3067SDavid du Colombier };
133*58da3067SDavid du Colombier 
134*58da3067SDavid du Colombier Rune kbtabctrlesc1[Nscan] =
135*58da3067SDavid du Colombier {
136*58da3067SDavid du Colombier [0x00]	No,	No,	No,	No,	No,	No,	No,	No,
137*58da3067SDavid du Colombier [0x08]	No,	No,	No,	No,	No,	No,	No,	No,
138*58da3067SDavid du Colombier [0x10]	No,	No,	No,	No,	No,	No,	No,	No,
139*58da3067SDavid du Colombier [0x18]	No,	No,	No,	No,	No,	No,	No,	No,
140*58da3067SDavid du Colombier [0x20]	No,	No,	No,	No,	No,	No,	No,	No,
141*58da3067SDavid du Colombier [0x28]	No,	No,	No,	No,	No,	No,	No,	No,
142*58da3067SDavid du Colombier [0x30]	No,	No,	No,	No,	No,	No,	No,	No,
143*58da3067SDavid du Colombier [0x38]	No,	No,	No,	No,	No,	No,	No,	No,
144*58da3067SDavid du Colombier [0x40]	No,	No,	No,	No,	No,	No,	No,	No,
145*58da3067SDavid du Colombier [0x48]	Up,	No,	No,	No,	No,	No,	No,	No,
146*58da3067SDavid du Colombier [0x50]	No,	No,	No,	No,	No,	No,	No,	No,
147*58da3067SDavid du Colombier [0x58]	No,	No,	No,	No,	No,	No,	No,	No,
148*58da3067SDavid du Colombier [0x60]	No,	No,	No,	No,	No,	No,	No,	No,
149*58da3067SDavid du Colombier [0x68]	No,	No,	No,	No,	No,	No,	No,	No,
150*58da3067SDavid du Colombier [0x70]	No,	No,	No,	No,	No,	No,	No,	No,
151*58da3067SDavid du Colombier [0x78]	No,	Up,	No,	No,	No,	No,	No,	No,
152*58da3067SDavid du Colombier };
153*58da3067SDavid du Colombier 
15493631029SDavid du Colombier Rune kbtabaltgr[Nscan] =
15593631029SDavid du Colombier {
15693631029SDavid du Colombier [0x00]	No,	No,	No,	No,	No,	No,	No,	No,
15793631029SDavid du Colombier [0x08]	No,	No,	No,	No,	No,	No,	No,	No,
15893631029SDavid du Colombier [0x10]	No,	No,	No,	No,	No,	No,	No,	No,
15993631029SDavid du Colombier [0x18]	No,	No,	No,	No,	'\n',	Ctrl,	No,	No,
16093631029SDavid du Colombier [0x20]	No,	No,	No,	No,	No,	No,	No,	No,
16193631029SDavid du Colombier [0x28]	No,	No,	Shift,	No,	No,	No,	No,	No,
16293631029SDavid du Colombier [0x30]	No,	No,	No,	No,	No,	'/',	No,	Print,
16393631029SDavid du Colombier [0x38]	Altgr,	No,	No,	No,	No,	No,	No,	No,
16493631029SDavid du Colombier [0x40]	No,	No,	No,	No,	No,	No,	Break,	Home,
16593631029SDavid du Colombier [0x48]	Up,	Pgup,	No,	Left,	No,	Right,	No,	End,
16693631029SDavid du Colombier [0x50]	Down,	Pgdown,	Ins,	Del,	No,	No,	No,	No,
16793631029SDavid du Colombier [0x58]	No,	No,	No,	No,	No,	No,	No,	No,
16893631029SDavid du Colombier [0x60]	No,	No,	No,	No,	No,	No,	No,	No,
16993631029SDavid du Colombier [0x68]	No,	No,	No,	No,	No,	No,	No,	No,
17093631029SDavid du Colombier [0x70]	No,	No,	No,	No,	No,	No,	No,	No,
17193631029SDavid du Colombier [0x78]	No,	Up,	No,	No,	No,	No,	No,	No,
17293631029SDavid du Colombier };
17393631029SDavid du Colombier 
17493631029SDavid du Colombier Rune kbtabctrl[Nscan] =
17593631029SDavid du Colombier {
17693631029SDavid du Colombier [0x00]	No,	'', 	'', 	'', 	'', 	'', 	'', 	'',
17793631029SDavid du Colombier [0x08]	'', 	'', 	'', 	'', 	'
17893631029SDavid du Colombier ', 	'', 	'\b',	'\t',
17993631029SDavid du Colombier [0x10]	'', 	'', 	'', 	'', 	'', 	'', 	'', 	'\t',
18093631029SDavid du Colombier [0x18]	'', 	'', 	'', 	'', 	'\n',	Ctrl,	'', 	'',
18193631029SDavid du Colombier [0x20]	'', 	'', 	'', 	'\b',	'\n',	'', 	'', 	'',
18293631029SDavid du Colombier [0x28]	'', 	No, 	Shift,	'', 	'', 	'', 	'', 	'',
18393631029SDavid du Colombier [0x30]	'', 	'', 	'
18493631029SDavid du Colombier ', 	'', 	'', 	'', 	Shift,	'\n',
18593631029SDavid du Colombier [0x38]	Latin,	No, 	Ctrl,	'', 	'', 	'', 	'', 	'',
18693631029SDavid du Colombier [0x40]	'', 	'', 	'', 	'
18793631029SDavid du Colombier ', 	'', 	'', 	'', 	'',
18893631029SDavid du Colombier [0x48]	'', 	'', 	'
18993631029SDavid du Colombier ', 	'', 	'', 	'', 	'', 	'',
19093631029SDavid du Colombier [0x50]	'', 	'', 	'', 	'', 	No,	No,	No,	'',
19193631029SDavid du Colombier [0x58]	'', 	No,	No,	No,	No,	No,	No,	No,
19293631029SDavid du Colombier [0x60]	No,	No,	No,	No,	No,	No,	No,	No,
19393631029SDavid du Colombier [0x68]	No,	No,	No,	No,	No,	No,	No,	No,
19493631029SDavid du Colombier [0x70]	No,	No,	No,	No,	No,	No,	No,	No,
19593631029SDavid du Colombier [0x78]	No,	'', 	No,	'\b',	No,	No,	No,	No,
19693631029SDavid du Colombier };
19793631029SDavid du Colombier 
19893631029SDavid du Colombier int mouseshifted;
19993631029SDavid du Colombier void (*kbdmouse)(int);
20093631029SDavid du Colombier 
20193631029SDavid du Colombier static int kdebug;
20293631029SDavid du Colombier 
20393631029SDavid du Colombier typedef struct Kbscan Kbscan;
20493631029SDavid du Colombier struct Kbscan {
20593631029SDavid du Colombier 	int	esc1;
20693631029SDavid du Colombier 	int	esc2;
20793631029SDavid du Colombier 	int	alt;
20893631029SDavid du Colombier 	int	altgr;
20993631029SDavid du Colombier 	int	caps;
21093631029SDavid du Colombier 	int	ctl;
21193631029SDavid du Colombier 	int	num;
21293631029SDavid du Colombier 	int	shift;
21393631029SDavid du Colombier 	int	collecting;
21493631029SDavid du Colombier 	int	nk;
21593631029SDavid du Colombier 	Rune	kc[5];
21693631029SDavid du Colombier 	int	buttons;
21793631029SDavid du Colombier };
21893631029SDavid du Colombier 
21993631029SDavid du Colombier Kbscan kbscans[Nscans];	/* kernel and external scan code state */
22093631029SDavid du Colombier 
kbdputsc(int c,int external)22193631029SDavid du Colombier /*
22293631029SDavid du Colombier  * Scan code processing
22393631029SDavid du Colombier  */
22493631029SDavid du Colombier void
22593631029SDavid du Colombier kbdputsc(int c, int external)
22693631029SDavid du Colombier {
22793631029SDavid du Colombier 	int i, keyup;
22893631029SDavid du Colombier 	Kbscan *kbscan;
22993631029SDavid du Colombier 
23093631029SDavid du Colombier 	if(external)
23193631029SDavid du Colombier 		kbscan = &kbscans[Ext];
23293631029SDavid du Colombier 	else
23393631029SDavid du Colombier 		kbscan = &kbscans[Int];
23493631029SDavid du Colombier 
23593631029SDavid du Colombier 	if(kdebug)
23693631029SDavid du Colombier 		print("sc %x ms %d\n", c, mouseshifted);
23793631029SDavid du Colombier 	/*
23893631029SDavid du Colombier 	 *  e0's is the first of a 2 character sequence, e1 the first
23993631029SDavid du Colombier 	 *  of a 3 character sequence (on the safari)
24093631029SDavid du Colombier 	 */
24193631029SDavid du Colombier 	if(c == 0xe0){
24293631029SDavid du Colombier 		kbscan->esc1 = 1;
24393631029SDavid du Colombier 		return;
24493631029SDavid du Colombier 	} else if(c == 0xe1){
24593631029SDavid du Colombier 		kbscan->esc2 = 2;
24693631029SDavid du Colombier 		return;
24793631029SDavid du Colombier 	}
24893631029SDavid du Colombier 
24993631029SDavid du Colombier 	keyup = c & 0x80;
25093631029SDavid du Colombier 	c &= 0x7f;
25193631029SDavid du Colombier 	if(c > sizeof kbtab){
25293631029SDavid du Colombier 		c |= keyup;
25393631029SDavid du Colombier 		if(c != 0xFF)	/* these come fairly often: CAPSLOCK U Y */
254*58da3067SDavid du Colombier 			print("unknown key %ux\n", c);
255*58da3067SDavid du Colombier 		return;
256*58da3067SDavid du Colombier 	}
257*58da3067SDavid du Colombier 
25893631029SDavid du Colombier 	if(kbscan->esc1 && kbscan->shift){
25993631029SDavid du Colombier 		c = kbtabshiftesc1[c];
26093631029SDavid du Colombier 		kbscan->esc1 = 0;
26193631029SDavid du Colombier 	} else if(kbscan->esc1){
26293631029SDavid du Colombier 		c = kbtabesc1[c];
26393631029SDavid du Colombier 		kbscan->esc1 = 0;
26493631029SDavid du Colombier 	} else if(kbscan->esc2){
26593631029SDavid du Colombier 		kbscan->esc2--;
26693631029SDavid du Colombier 		return;
26793631029SDavid du Colombier 	} else if(kbscan->shift)
26893631029SDavid du Colombier 		c = kbtabshift[c];
26993631029SDavid du Colombier 	else if(kbscan->altgr)
27093631029SDavid du Colombier 		c = kbtabaltgr[c];
27193631029SDavid du Colombier 	else if(kbscan->ctl)
27293631029SDavid du Colombier 		c = kbtabctrl[c];
27393631029SDavid du Colombier 	else
27493631029SDavid du Colombier 		c = kbtab[c];
27593631029SDavid du Colombier 
27693631029SDavid du Colombier 	if(kbscan->caps && c<='z' && c>='a')
27793631029SDavid du Colombier 		c += 'A' - 'a';
27893631029SDavid du Colombier 
27993631029SDavid du Colombier 	/*
28093631029SDavid du Colombier 	 *  keyup only important for shifts
28193631029SDavid du Colombier 	 */
28293631029SDavid du Colombier 	if(keyup){
28393631029SDavid du Colombier 		switch(c){
28493631029SDavid du Colombier 		case Latin:
28593631029SDavid du Colombier 			kbscan->alt = 0;
28693631029SDavid du Colombier 			break;
28793631029SDavid du Colombier 		case Shift:
28893631029SDavid du Colombier 			kbscan->shift = 0;
28993631029SDavid du Colombier 			mouseshifted = 0;
29093631029SDavid du Colombier 			if(kdebug)
29193631029SDavid du Colombier 				print("shiftclr\n");
29293631029SDavid du Colombier 			break;
29393631029SDavid du Colombier 		case Ctrl:
29493631029SDavid du Colombier 			kbscan->ctl = 0;
29593631029SDavid du Colombier 			break;
29693631029SDavid du Colombier 		case Altgr:
29793631029SDavid du Colombier 			kbscan->altgr = 0;
29893631029SDavid du Colombier 			break;
29993631029SDavid du Colombier 		case Kmouse|1:
30093631029SDavid du Colombier 		case Kmouse|2:
30193631029SDavid du Colombier 		case Kmouse|3:
30293631029SDavid du Colombier 		case Kmouse|4:
30393631029SDavid du Colombier 		case Kmouse|5:
30493631029SDavid du Colombier 			kbscan->buttons &= ~(1<<(c-Kmouse-1));
30593631029SDavid du Colombier 			if(kbdmouse)
30693631029SDavid du Colombier 				kbdmouse(kbscan->buttons);
30793631029SDavid du Colombier 			break;
30893631029SDavid du Colombier 		}
30993631029SDavid du Colombier 		return;
31093631029SDavid du Colombier 	}
31193631029SDavid du Colombier 
31293631029SDavid du Colombier 	/*
31393631029SDavid du Colombier 	 *  normal character
31493631029SDavid du Colombier 	 */
31593631029SDavid du Colombier 	if(!(c & (Spec|KF))){
31693631029SDavid du Colombier 		if(kbscan->ctl)
31793631029SDavid du Colombier 			if(kbscan->alt && c == Del)
31893631029SDavid du Colombier 				exit(0);
31993631029SDavid du Colombier 		if(!kbscan->collecting){
32093631029SDavid du Colombier 			kbdputc(kbdq, c);
32193631029SDavid du Colombier 			return;
32293631029SDavid du Colombier 		}
32393631029SDavid du Colombier 		kbscan->kc[kbscan->nk++] = c;
32493631029SDavid du Colombier 		c = latin1(kbscan->kc, kbscan->nk);
32593631029SDavid du Colombier 		if(c < -1)	/* need more keystrokes */
32693631029SDavid du Colombier 			return;
32793631029SDavid du Colombier 		if(c != -1)	/* valid sequence */
32893631029SDavid du Colombier 			kbdputc(kbdq, c);
32993631029SDavid du Colombier 		else	/* dump characters */
33093631029SDavid du Colombier 			for(i=0; i<kbscan->nk; i++)
33193631029SDavid du Colombier 				kbdputc(kbdq, kbscan->kc[i]);
33293631029SDavid du Colombier 		kbscan->nk = 0;
33393631029SDavid du Colombier 		kbscan->collecting = 0;
33493631029SDavid du Colombier 		return;
33593631029SDavid du Colombier 	} else {
33693631029SDavid du Colombier 		switch(c){
33793631029SDavid du Colombier 		case Caps:
33893631029SDavid du Colombier 			kbscan->caps ^= 1;
33993631029SDavid du Colombier 			return;
34093631029SDavid du Colombier 		case Num:
34193631029SDavid du Colombier 			kbscan->num ^= 1;
34293631029SDavid du Colombier 			return;
34393631029SDavid du Colombier 		case Shift:
34493631029SDavid du Colombier 			kbscan->shift = 1;
34593631029SDavid du Colombier 			if(kdebug)
34693631029SDavid du Colombier 				print("shift\n");
34793631029SDavid du Colombier 			mouseshifted = 1;
34893631029SDavid du Colombier 			return;
34993631029SDavid du Colombier 		case Latin:
35093631029SDavid du Colombier 			kbscan->alt = 1;
35193631029SDavid du Colombier 			/*
35293631029SDavid du Colombier 			 * VMware and Qemu use Ctl-Alt as the key combination
35393631029SDavid du Colombier 			 * to make the VM give up keyboard and mouse focus.
354*58da3067SDavid du Colombier 			 * This has the unfortunate side effect that when you
355*58da3067SDavid du Colombier 			 * come back into focus, Plan 9 thinks you want to type
35693631029SDavid du Colombier 			 * a compose sequence (you just typed alt).
35793631029SDavid du Colombier 			 *
35893631029SDavid du Colombier 			 * As a clumsy hack around this, we look for ctl-alt and
35993631029SDavid du Colombier 			 * don't treat it as the start of a compose sequence.
36093631029SDavid du Colombier 			 */
36193631029SDavid du Colombier 			if(!kbscan->ctl){
36293631029SDavid du Colombier 				kbscan->collecting = 1;
36393631029SDavid du Colombier 				kbscan->nk = 0;
36493631029SDavid du Colombier 			}
36593631029SDavid du Colombier 			return;
36693631029SDavid du Colombier 		case Ctrl:
36793631029SDavid du Colombier 			kbscan->ctl = 1;
36893631029SDavid du Colombier 			return;
36993631029SDavid du Colombier 		case Altgr:
37093631029SDavid du Colombier 			kbscan->altgr = 1;
37193631029SDavid du Colombier 			return;
37293631029SDavid du Colombier 		case Kmouse|1:
37393631029SDavid du Colombier 		case Kmouse|2:
37493631029SDavid du Colombier 		case Kmouse|3:
37593631029SDavid du Colombier 		case Kmouse|4:
37693631029SDavid du Colombier 		case Kmouse|5:
37793631029SDavid du Colombier 			kbscan->buttons |= 1<<(c-Kmouse-1);
37893631029SDavid du Colombier 			if(kbdmouse)
37993631029SDavid du Colombier 				kbdmouse(kbscan->buttons);
38093631029SDavid du Colombier 			return;
38193631029SDavid du Colombier 		case KF|11:
38293631029SDavid du Colombier 			print("kbd debug on, F12 turns it off\n");
38393631029SDavid du Colombier 			kdebug = 1;
38493631029SDavid du Colombier 			break;
38593631029SDavid du Colombier 		case KF|12:
38693631029SDavid du Colombier 			kdebug = 0;
38793631029SDavid du Colombier 			break;
38893631029SDavid du Colombier 		}
38993631029SDavid du Colombier 	}
39093631029SDavid du Colombier 	kbdputc(kbdq, c);
39193631029SDavid du Colombier }
39293631029SDavid du Colombier 
39393631029SDavid du Colombier void
39493631029SDavid du Colombier kbdenable(void)
39593631029SDavid du Colombier {
39693631029SDavid du Colombier #ifdef notdef
39793631029SDavid du Colombier 	kbdq = qopen(4*1024, 0, 0, 0);
39893631029SDavid du Colombier 	if(kbdq == nil)
39993631029SDavid du Colombier 		panic("kbdinit");
40093631029SDavid du Colombier 	qnoblock(kbdq, 1);
40193631029SDavid du Colombier #endif
kbdputmap(ushort m,ushort scanc,Rune r)40293631029SDavid du Colombier 	kbscans[Int].num = 0;
40393631029SDavid du Colombier }
40493631029SDavid du Colombier 
40593631029SDavid du Colombier void
40693631029SDavid du Colombier kbdputmap(ushort m, ushort scanc, Rune r)
40793631029SDavid du Colombier {
40893631029SDavid du Colombier 	if(scanc >= Nscan)
40993631029SDavid du Colombier 		error(Ebadarg);
41093631029SDavid du Colombier 	switch(m) {
41193631029SDavid du Colombier 	default:
41293631029SDavid du Colombier 		error(Ebadarg);
41393631029SDavid du Colombier 	case 0:
41493631029SDavid du Colombier 		kbtab[scanc] = r;
41593631029SDavid du Colombier 		break;
41693631029SDavid du Colombier 	case 1:
41793631029SDavid du Colombier 		kbtabshift[scanc] = r;
41893631029SDavid du Colombier 		break;
41993631029SDavid du Colombier 	case 2:
42093631029SDavid du Colombier 		kbtabesc1[scanc] = r;
42193631029SDavid du Colombier 		break;
42293631029SDavid du Colombier 	case 3:
42393631029SDavid du Colombier 		kbtabaltgr[scanc] = r;
424*58da3067SDavid du Colombier 		break;
425*58da3067SDavid du Colombier 	case 4:
426*58da3067SDavid du Colombier 		kbtabctrl[scanc] = r;
427*58da3067SDavid du Colombier 		break;
428*58da3067SDavid du Colombier 	case 5:
429*58da3067SDavid du Colombier 		kbtabctrlesc1[scanc] = r;
43093631029SDavid du Colombier 		break;
43193631029SDavid du Colombier 	case 6:
43293631029SDavid du Colombier 		kbtabshiftesc1[scanc] = r;
43393631029SDavid du Colombier 		break;
kbdgetmap(uint offset,int * t,int * sc,Rune * r)43493631029SDavid du Colombier 	}
43593631029SDavid du Colombier }
43693631029SDavid du Colombier 
43793631029SDavid du Colombier int
43893631029SDavid du Colombier kbdgetmap(uint offset, int *t, int *sc, Rune *r)
43993631029SDavid du Colombier {
44093631029SDavid du Colombier 	if ((int)offset < 0)
44193631029SDavid du Colombier 		error(Ebadarg);
44293631029SDavid du Colombier 	*t = offset/Nscan;
44393631029SDavid du Colombier 	*sc = offset%Nscan;
44493631029SDavid du Colombier 	switch(*t) {
44593631029SDavid du Colombier 	default:
44693631029SDavid du Colombier 		return 0;
44793631029SDavid du Colombier 	case 0:
44893631029SDavid du Colombier 		*r = kbtab[*sc];
44993631029SDavid du Colombier 		return 1;
45093631029SDavid du Colombier 	case 1:
45193631029SDavid du Colombier 		*r = kbtabshift[*sc];
45293631029SDavid du Colombier 		return 1;
45393631029SDavid du Colombier 	case 2:
45493631029SDavid du Colombier 		*r = kbtabesc1[*sc];
45593631029SDavid du Colombier 		return 1;
45693631029SDavid du Colombier 	case 3:
45793631029SDavid du Colombier 		*r = kbtabaltgr[*sc];
458*58da3067SDavid du Colombier 		return 1;
459*58da3067SDavid du Colombier 	case 4:
460*58da3067SDavid du Colombier 		*r = kbtabctrl[*sc];
461*58da3067SDavid du Colombier 		return 1;
462*58da3067SDavid du Colombier 	case 5:
463*58da3067SDavid du Colombier 		*r = kbtabctrlesc1[*sc];
46493631029SDavid du Colombier 		return 1;
46593631029SDavid du Colombier 	case 6:
466 		*r = kbtabshiftesc1[*sc];
467 		return 1;
468 	}
469 }
470