xref: /plan9/sys/src/cmd/vnc/kbds.c (revision a6a9e07217f318acf170f99684a55fba5200524f)
1 #include	<u.h>
2 #include	<libc.h>
3 #include	"compat.h"
4 #include	"kbd.h"
5 
6 enum
7 {
8 	VKSpecial = 0xff00,
9 
10 	/*
11 	 * plan 9 key mappings
12 	 */
13 	Spec=		0x80,
14 
15 	PF=		Spec|0x20,	/* num pad function key */
16 	View=		Spec|0x00,	/* view (shift window up) */
17 	KF=		0xF000,	/* function key (begin Unicode private space) */
18 	Shift=		Spec|0x60,
19 	Break=		Spec|0x61,
20 	Ctrl=		Spec|0x62,
21 	Latin=		Spec|0x63,
22 	Caps=		Spec|0x64,
23 	Num=		Spec|0x65,
24 	Middle=		Spec|0x66,
25 	No=		0x00,		/* peter */
26 
27 	Home=		KF|13,
28 	Up=		KF|14,
29 	Pgup=		KF|15,
30 	Print=		KF|16,
31 	Left=		KF|17,
32 	Right=		KF|18,
33 	End=		'\r',
34 	Down=		View,
35 	Pgdown=		KF|19,
36 	Ins=		KF|20,
37 	Del=		0x7F,
38 	Scroll=		KF|21,
39 
40 	Esc = 0x1b,
41 	Delete = 0x7f,
42 };
43 
44 static Rune vnckeys[] =
45 {
46 [0x00]	No,	No,	No,	No,	No,	No,	No,	No,
47 [0x08]	'\b',	'\t',	'\r',	No,	No,	'\n',	No,	No,
48 [0x10]	No,	No,	No,	No,	Scroll,	No,	No,	No,
49 [0x18]	No,	No,	No,	Esc,	No,	No,	No,	No,
50 [0x20]	No,	No,	No,	No,	No,	No,	No,	No,
51 [0x28]	No,	No,	No,	No,	No,	No,	No,	No,
52 [0x30]	No,	No,	No,	No,	No,	No,	No,	No,
53 [0x38]	No,	No,	No,	No,	No,	No,	No,	No,
54 [0x40]	No,	No,	No,	No,	No,	No,	No,	No,
55 [0x48]	No,	No,	No,	No,	No,	No,	No,	No,
56 [0x50]	Home,	Left,	Up,	Right,	Down,	Pgup,	Pgdown,	No,
57 [0x58]	No,	No,	No,	No,	No,	No,	No,	No,
58 [0x60]	No,	Print,	No,	Ins,	No,	No,	No,	No,
59 [0x68]	No,	No,	No,	Break,	No,	No,	No,	No,
60 [0x70]	No,	No,	No,	No,	No,	No,	No,	No,
61 [0x78]	No,	No,	No,	No,	No,	No,	No,	Num,
62 [0x80]	No,	No,	No,	No,	No,	No,	No,	No,
63 [0x88]	No,	No,	No,	No,	No,	No,	No,	No,
64 [0x90]	No,	No,	No,	No,	No,	No,	No,	No,
65 [0x98]	No,	No,	No,	No,	No,	No,	No,	No,
66 [0xa0]	No,	No,	No,	No,	No,	No,	No,	No,
67 [0xa8]	No,	No,	'*',	'+',	No,	'-',	'.',	'/',
68 [0xb0]	'0',	'1',	'2',	'3',	'4',	'5',	'6',	'7',
69 [0xb8]	'8',	'9',	No,	No,	No,	'=',	No,	No,
70 [0xc0]	No,	No,	No,	No,	No,	No,	No,	No,
71 [0xc8]	No,	No,	No,	No,	No,	No,	No,	No,
72 [0xd0]	No,	No,	No,	No,	No,	No,	No,	No,
73 [0xd8]	No,	No,	No,	No,	No,	No,	No,	No,
74 [0xe0]	No,	Shift,	Shift,	Ctrl,	Ctrl,	Caps,	Caps,	No,
75 [0xe8]	No,	Latin,	Latin,	No,	No,	No,	No,	No,
76 [0xf0]	No,	No,	No,	No,	No,	No,	No,	No,
77 [0xf8]	No,	No,	No,	No,	No,	No,	No,	Delete,
78 };
79 
80 /*
81  *  keyboard interrupt
82  */
83 void
84 vncputc(int keyup, int c)
85 {
86 	int i;
87 	static int esc1, esc2;
88 	static int alt, caps, ctl, num, shift;
89 	static int collecting, nk;
90 	static Rune kc[5];
91 
92 	if(caps && c<='z' && c>='a')
93 		c += 'A' - 'a';
94 
95 	/*
96  	 *  character mapping
97 	 */
98 	if((c & VKSpecial) == VKSpecial){
99 		c = vnckeys[c & 0xff];
100 		if(c == No)
101 			return;
102 	}else if(c & ~0xff)
103 		return;
104 
105 	/*
106 	 *  keyup only important for shifts
107 	 */
108 	if(keyup){
109 		switch(c){
110 		case Latin:
111 			alt = 0;
112 			break;
113 		case Shift:
114 			shift = 0;
115 			break;
116 		case Ctrl:
117 			ctl = 0;
118 			break;
119 		}
120 		return;
121 	}
122 
123 	/*
124  	 *  normal character
125 	 */
126 	if(!(c & (Spec|KF))){
127 		if(ctl){
128 			c &= 0x1f;
129 		}
130 		if(!collecting){
131 			kbdputc(c);
132 			return;
133 		}
134 		kc[nk++] = c;
135 		c = latin1(kc, nk);
136 		if(c < -1)	/* need more keystrokes */
137 			return;
138 		if(c != -1)	/* valid sequence */
139 			kbdputc(c);
140 		else	/* dump characters */
141 			for(i=0; i<nk; i++)
142 				kbdputc(kc[i]);
143 		nk = 0;
144 		collecting = 0;
145 		return;
146 	}else{
147 		switch(c){
148 		case Caps:
149 			caps ^= 1;
150 			return;
151 		case Num:
152 			num ^= 1;
153 			return;
154 		case Shift:
155 			shift = 1;
156 			return;
157 		case Latin:
158 			alt = 1;
159 			collecting = 1;
160 			nk = 0;
161 			return;
162 		case Ctrl:
163 			ctl = 1;
164 			return;
165 		}
166 	}
167 	kbdputc(c);
168 }
169