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