1*3de6a9c0SDavid du Colombier /*
2*3de6a9c0SDavid du Colombier * simulated keyboard input for systems with none (except via uart or usb)
3*3de6a9c0SDavid du Colombier *
4*3de6a9c0SDavid du Colombier * gutted version of ps2 version from ../pc
5*3de6a9c0SDavid du Colombier */
6*3de6a9c0SDavid du Colombier #include "u.h"
7*3de6a9c0SDavid du Colombier #include "../port/lib.h"
8*3de6a9c0SDavid du Colombier #include "mem.h"
9*3de6a9c0SDavid du Colombier #include "dat.h"
10*3de6a9c0SDavid du Colombier #include "fns.h"
11*3de6a9c0SDavid du Colombier #include "io.h"
12*3de6a9c0SDavid du Colombier #include "../port/error.h"
13*3de6a9c0SDavid du Colombier
14*3de6a9c0SDavid du Colombier enum {
15*3de6a9c0SDavid du Colombier Spec= 0xF800, /* Unicode private space */
16*3de6a9c0SDavid du Colombier PF= Spec|0x20, /* num pad function key */
17*3de6a9c0SDavid du Colombier View= Spec|0x00, /* view (shift window up) */
18*3de6a9c0SDavid du Colombier KF= 0xF000, /* function key (begin Unicode private space) */
19*3de6a9c0SDavid du Colombier Shift= Spec|0x60,
20*3de6a9c0SDavid du Colombier Break= Spec|0x61,
21*3de6a9c0SDavid du Colombier Ctrl= Spec|0x62,
22*3de6a9c0SDavid du Colombier Latin= Spec|0x63,
23*3de6a9c0SDavid du Colombier Caps= Spec|0x64,
24*3de6a9c0SDavid du Colombier Num= Spec|0x65,
25*3de6a9c0SDavid du Colombier Middle= Spec|0x66,
26*3de6a9c0SDavid du Colombier Altgr= Spec|0x67,
27*3de6a9c0SDavid du Colombier Kmouse= Spec|0x100,
28*3de6a9c0SDavid du Colombier No= 0x00, /* peter */
29*3de6a9c0SDavid du Colombier
30*3de6a9c0SDavid du Colombier Home= KF|13,
31*3de6a9c0SDavid du Colombier Up= KF|14,
32*3de6a9c0SDavid du Colombier Pgup= KF|15,
33*3de6a9c0SDavid du Colombier Print= KF|16,
34*3de6a9c0SDavid du Colombier Left= KF|17,
35*3de6a9c0SDavid du Colombier Right= KF|18,
36*3de6a9c0SDavid du Colombier End= KF|24,
37*3de6a9c0SDavid du Colombier Down= View,
38*3de6a9c0SDavid du Colombier Pgdown= KF|19,
39*3de6a9c0SDavid du Colombier Ins= KF|20,
40*3de6a9c0SDavid du Colombier Del= 0x7F,
41*3de6a9c0SDavid du Colombier Scroll= KF|21,
42*3de6a9c0SDavid du Colombier
43*3de6a9c0SDavid du Colombier Nscan= 128,
44*3de6a9c0SDavid du Colombier
45*3de6a9c0SDavid du Colombier Int= 0, /* kbscans indices */
46*3de6a9c0SDavid du Colombier Ext,
47*3de6a9c0SDavid du Colombier Nscans,
48*3de6a9c0SDavid du Colombier };
49*3de6a9c0SDavid du Colombier
50*3de6a9c0SDavid du Colombier /*
51*3de6a9c0SDavid du Colombier * The codes at 0x79 and 0x7b are produced by the PFU Happy Hacking keyboard.
52*3de6a9c0SDavid du Colombier * A 'standard' keyboard doesn't produce anything above 0x58.
53*3de6a9c0SDavid du Colombier */
54*3de6a9c0SDavid du Colombier Rune kbtab[Nscan] =
55*3de6a9c0SDavid du Colombier {
56*3de6a9c0SDavid du Colombier [0x00] No, 0x1b, '1', '2', '3', '4', '5', '6',
57*3de6a9c0SDavid du Colombier [0x08] '7', '8', '9', '0', '-', '=', '\b', '\t',
58*3de6a9c0SDavid du Colombier [0x10] 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
59*3de6a9c0SDavid du Colombier [0x18] 'o', 'p', '[', ']', '\n', Ctrl, 'a', 's',
60*3de6a9c0SDavid du Colombier [0x20] 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
61*3de6a9c0SDavid du Colombier [0x28] '\'', '`', Shift, '\\', 'z', 'x', 'c', 'v',
62*3de6a9c0SDavid du Colombier [0x30] 'b', 'n', 'm', ',', '.', '/', Shift, '*',
63*3de6a9c0SDavid du Colombier [0x38] Latin, ' ', Ctrl, KF|1, KF|2, KF|3, KF|4, KF|5,
64*3de6a9c0SDavid du Colombier [0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, Scroll, '7',
65*3de6a9c0SDavid du Colombier [0x48] '8', '9', '-', '4', '5', '6', '+', '1',
66*3de6a9c0SDavid du Colombier [0x50] '2', '3', '0', '.', No, No, No, KF|11,
67*3de6a9c0SDavid du Colombier [0x58] KF|12, No, No, No, No, No, No, No,
68*3de6a9c0SDavid du Colombier [0x60] No, No, No, No, No, No, No, No,
69*3de6a9c0SDavid du Colombier [0x68] No, No, No, No, No, No, No, No,
70*3de6a9c0SDavid du Colombier [0x70] No, No, No, No, No, No, No, No,
71*3de6a9c0SDavid du Colombier [0x78] No, View, No, Up, No, No, No, No,
72*3de6a9c0SDavid du Colombier };
73*3de6a9c0SDavid du Colombier
74*3de6a9c0SDavid du Colombier Rune kbtabshift[Nscan] =
75*3de6a9c0SDavid du Colombier {
76*3de6a9c0SDavid du Colombier [0x00] No, 0x1b, '!', '@', '#', '$', '%', '^',
77*3de6a9c0SDavid du Colombier [0x08] '&', '*', '(', ')', '_', '+', '\b', '\t',
78*3de6a9c0SDavid du Colombier [0x10] 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
79*3de6a9c0SDavid du Colombier [0x18] 'O', 'P', '{', '}', '\n', Ctrl, 'A', 'S',
80*3de6a9c0SDavid du Colombier [0x20] 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
81*3de6a9c0SDavid du Colombier [0x28] '"', '~', Shift, '|', 'Z', 'X', 'C', 'V',
82*3de6a9c0SDavid du Colombier [0x30] 'B', 'N', 'M', '<', '>', '?', Shift, '*',
83*3de6a9c0SDavid du Colombier [0x38] Latin, ' ', Ctrl, KF|1, KF|2, KF|3, KF|4, KF|5,
84*3de6a9c0SDavid du Colombier [0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, Scroll, '7',
85*3de6a9c0SDavid du Colombier [0x48] '8', '9', '-', '4', '5', '6', '+', '1',
86*3de6a9c0SDavid du Colombier [0x50] '2', '3', '0', '.', No, No, No, KF|11,
87*3de6a9c0SDavid du Colombier [0x58] KF|12, No, No, No, No, No, No, No,
88*3de6a9c0SDavid du Colombier [0x60] No, No, No, No, No, No, No, No,
89*3de6a9c0SDavid du Colombier [0x68] No, No, No, No, No, No, No, No,
90*3de6a9c0SDavid du Colombier [0x70] No, No, No, No, No, No, No, No,
91*3de6a9c0SDavid du Colombier [0x78] No, Up, No, Up, No, No, No, No,
92*3de6a9c0SDavid du Colombier };
93*3de6a9c0SDavid du Colombier
94*3de6a9c0SDavid du Colombier Rune kbtabesc1[Nscan] =
95*3de6a9c0SDavid du Colombier {
96*3de6a9c0SDavid du Colombier [0x00] No, No, No, No, No, No, No, No,
97*3de6a9c0SDavid du Colombier [0x08] No, No, No, No, No, No, No, No,
98*3de6a9c0SDavid du Colombier [0x10] No, No, No, No, No, No, No, No,
99*3de6a9c0SDavid du Colombier [0x18] No, No, No, No, '\n', Ctrl, No, No,
100*3de6a9c0SDavid du Colombier [0x20] No, No, No, No, No, No, No, No,
101*3de6a9c0SDavid du Colombier [0x28] No, No, Shift, No, No, No, No, No,
102*3de6a9c0SDavid du Colombier [0x30] No, No, No, No, No, '/', No, Print,
103*3de6a9c0SDavid du Colombier [0x38] Altgr, No, No, No, No, No, No, No,
104*3de6a9c0SDavid du Colombier [0x40] No, No, No, No, No, No, Break, Home,
105*3de6a9c0SDavid du Colombier [0x48] Up, Pgup, No, Left, No, Right, No, End,
106*3de6a9c0SDavid du Colombier [0x50] Down, Pgdown, Ins, Del, No, No, No, No,
107*3de6a9c0SDavid du Colombier [0x58] No, No, No, No, No, No, No, No,
108*3de6a9c0SDavid du Colombier [0x60] No, No, No, No, No, No, No, No,
109*3de6a9c0SDavid du Colombier [0x68] No, No, No, No, No, No, No, No,
110*3de6a9c0SDavid du Colombier [0x70] No, No, No, No, No, No, No, No,
111*3de6a9c0SDavid du Colombier [0x78] No, Up, No, No, No, No, No, No,
112*3de6a9c0SDavid du Colombier };
113*3de6a9c0SDavid du Colombier
114*3de6a9c0SDavid du Colombier Rune kbtabaltgr[Nscan] =
115*3de6a9c0SDavid du Colombier {
116*3de6a9c0SDavid du Colombier [0x00] No, No, No, No, No, No, No, No,
117*3de6a9c0SDavid du Colombier [0x08] No, No, No, No, No, No, No, No,
118*3de6a9c0SDavid du Colombier [0x10] No, No, No, No, No, No, No, No,
119*3de6a9c0SDavid du Colombier [0x18] No, No, No, No, '\n', Ctrl, No, No,
120*3de6a9c0SDavid du Colombier [0x20] No, No, No, No, No, No, No, No,
121*3de6a9c0SDavid du Colombier [0x28] No, No, Shift, No, No, No, No, No,
122*3de6a9c0SDavid du Colombier [0x30] No, No, No, No, No, '/', No, Print,
123*3de6a9c0SDavid du Colombier [0x38] Altgr, No, No, No, No, No, No, No,
124*3de6a9c0SDavid du Colombier [0x40] No, No, No, No, No, No, Break, Home,
125*3de6a9c0SDavid du Colombier [0x48] Up, Pgup, No, Left, No, Right, No, End,
126*3de6a9c0SDavid du Colombier [0x50] Down, Pgdown, Ins, Del, No, No, No, No,
127*3de6a9c0SDavid du Colombier [0x58] No, No, No, No, No, No, No, No,
128*3de6a9c0SDavid du Colombier [0x60] No, No, No, No, No, No, No, No,
129*3de6a9c0SDavid du Colombier [0x68] No, No, No, No, No, No, No, No,
130*3de6a9c0SDavid du Colombier [0x70] No, No, No, No, No, No, No, No,
131*3de6a9c0SDavid du Colombier [0x78] No, Up, No, No, No, No, No, No,
132*3de6a9c0SDavid du Colombier };
133*3de6a9c0SDavid du Colombier
134*3de6a9c0SDavid du Colombier Rune kbtabctrl[Nscan] =
135*3de6a9c0SDavid du Colombier {
136*3de6a9c0SDavid du Colombier [0x00] No, '', '', '', '', '', '', '',
137*3de6a9c0SDavid du Colombier [0x08] '', '', '', '', '
138*3de6a9c0SDavid du Colombier ', '', '\b', '\t',
139*3de6a9c0SDavid du Colombier [0x10] '', '', '', '', '', '', '', '\t',
140*3de6a9c0SDavid du Colombier [0x18] '', '', '', '', '\n', Ctrl, '', '',
141*3de6a9c0SDavid du Colombier [0x20] '', '', '', '\b', '\n', '', '', '',
142*3de6a9c0SDavid du Colombier [0x28] '', No, Shift, '', '', '', '', '',
143*3de6a9c0SDavid du Colombier [0x30] '', '', '
144*3de6a9c0SDavid du Colombier ', '', '', '', Shift, '\n',
145*3de6a9c0SDavid du Colombier [0x38] Latin, No, Ctrl, '', '', '', '', '',
146*3de6a9c0SDavid du Colombier [0x40] '', '', '', '
147*3de6a9c0SDavid du Colombier ', '', '', '', '',
148*3de6a9c0SDavid du Colombier [0x48] '', '', '
149*3de6a9c0SDavid du Colombier ', '', '', '', '', '',
150*3de6a9c0SDavid du Colombier [0x50] '', '', '', '', No, No, No, '',
151*3de6a9c0SDavid du Colombier [0x58] '', No, No, No, No, No, No, No,
152*3de6a9c0SDavid du Colombier [0x60] No, No, No, No, No, No, No, No,
153*3de6a9c0SDavid du Colombier [0x68] No, No, No, No, No, No, No, No,
154*3de6a9c0SDavid du Colombier [0x70] No, No, No, No, No, No, No, No,
155*3de6a9c0SDavid du Colombier [0x78] No, '', No, '\b', No, No, No, No,
156*3de6a9c0SDavid du Colombier };
157*3de6a9c0SDavid du Colombier
158*3de6a9c0SDavid du Colombier int mouseshifted;
159*3de6a9c0SDavid du Colombier void (*kbdmouse)(int);
160*3de6a9c0SDavid du Colombier
161*3de6a9c0SDavid du Colombier static int kdebug;
162*3de6a9c0SDavid du Colombier
163*3de6a9c0SDavid du Colombier typedef struct Kbscan Kbscan;
164*3de6a9c0SDavid du Colombier struct Kbscan {
165*3de6a9c0SDavid du Colombier int esc1;
166*3de6a9c0SDavid du Colombier int esc2;
167*3de6a9c0SDavid du Colombier int alt;
168*3de6a9c0SDavid du Colombier int altgr;
169*3de6a9c0SDavid du Colombier int caps;
170*3de6a9c0SDavid du Colombier int ctl;
171*3de6a9c0SDavid du Colombier int num;
172*3de6a9c0SDavid du Colombier int shift;
173*3de6a9c0SDavid du Colombier int collecting;
174*3de6a9c0SDavid du Colombier int nk;
175*3de6a9c0SDavid du Colombier Rune kc[5];
176*3de6a9c0SDavid du Colombier int buttons;
177*3de6a9c0SDavid du Colombier };
178*3de6a9c0SDavid du Colombier
179*3de6a9c0SDavid du Colombier Kbscan kbscans[Nscans]; /* kernel and external scan code state */
180*3de6a9c0SDavid du Colombier
kbdputsc(int c,int external)181*3de6a9c0SDavid du Colombier /*
182*3de6a9c0SDavid du Colombier * Scan code processing
183*3de6a9c0SDavid du Colombier */
184*3de6a9c0SDavid du Colombier void
185*3de6a9c0SDavid du Colombier kbdputsc(int c, int external)
186*3de6a9c0SDavid du Colombier {
187*3de6a9c0SDavid du Colombier int i, keyup;
188*3de6a9c0SDavid du Colombier Kbscan *kbscan;
189*3de6a9c0SDavid du Colombier
190*3de6a9c0SDavid du Colombier if(external)
191*3de6a9c0SDavid du Colombier kbscan = &kbscans[Ext];
192*3de6a9c0SDavid du Colombier else
193*3de6a9c0SDavid du Colombier kbscan = &kbscans[Int];
194*3de6a9c0SDavid du Colombier
195*3de6a9c0SDavid du Colombier if(kdebug)
196*3de6a9c0SDavid du Colombier print("sc %x ms %d\n", c, mouseshifted);
197*3de6a9c0SDavid du Colombier /*
198*3de6a9c0SDavid du Colombier * e0's is the first of a 2 character sequence, e1 the first
199*3de6a9c0SDavid du Colombier * of a 3 character sequence (on the safari)
200*3de6a9c0SDavid du Colombier */
201*3de6a9c0SDavid du Colombier if(c == 0xe0){
202*3de6a9c0SDavid du Colombier kbscan->esc1 = 1;
203*3de6a9c0SDavid du Colombier return;
204*3de6a9c0SDavid du Colombier } else if(c == 0xe1){
205*3de6a9c0SDavid du Colombier kbscan->esc2 = 2;
206*3de6a9c0SDavid du Colombier return;
207*3de6a9c0SDavid du Colombier }
208*3de6a9c0SDavid du Colombier
209*3de6a9c0SDavid du Colombier keyup = c & 0x80;
210*3de6a9c0SDavid du Colombier c &= 0x7f;
211*3de6a9c0SDavid du Colombier if(c > sizeof kbtab){
212*3de6a9c0SDavid du Colombier c |= keyup;
213*3de6a9c0SDavid du Colombier if(c != 0xFF) /* these come fairly often: CAPSLOCK U Y */
214*3de6a9c0SDavid du Colombier print("unknown key %ux\n", c);
215*3de6a9c0SDavid du Colombier return;
216*3de6a9c0SDavid du Colombier }
217*3de6a9c0SDavid du Colombier
218*3de6a9c0SDavid du Colombier if(kbscan->esc1){
219*3de6a9c0SDavid du Colombier c = kbtabesc1[c];
220*3de6a9c0SDavid du Colombier kbscan->esc1 = 0;
221*3de6a9c0SDavid du Colombier } else if(kbscan->esc2){
222*3de6a9c0SDavid du Colombier kbscan->esc2--;
223*3de6a9c0SDavid du Colombier return;
224*3de6a9c0SDavid du Colombier } else if(kbscan->shift)
225*3de6a9c0SDavid du Colombier c = kbtabshift[c];
226*3de6a9c0SDavid du Colombier else if(kbscan->altgr)
227*3de6a9c0SDavid du Colombier c = kbtabaltgr[c];
228*3de6a9c0SDavid du Colombier else if(kbscan->ctl)
229*3de6a9c0SDavid du Colombier c = kbtabctrl[c];
230*3de6a9c0SDavid du Colombier else
231*3de6a9c0SDavid du Colombier c = kbtab[c];
232*3de6a9c0SDavid du Colombier
233*3de6a9c0SDavid du Colombier if(kbscan->caps && c<='z' && c>='a')
234*3de6a9c0SDavid du Colombier c += 'A' - 'a';
235*3de6a9c0SDavid du Colombier
236*3de6a9c0SDavid du Colombier /*
237*3de6a9c0SDavid du Colombier * keyup only important for shifts
238*3de6a9c0SDavid du Colombier */
239*3de6a9c0SDavid du Colombier if(keyup){
240*3de6a9c0SDavid du Colombier switch(c){
241*3de6a9c0SDavid du Colombier case Latin:
242*3de6a9c0SDavid du Colombier kbscan->alt = 0;
243*3de6a9c0SDavid du Colombier break;
244*3de6a9c0SDavid du Colombier case Shift:
245*3de6a9c0SDavid du Colombier kbscan->shift = 0;
246*3de6a9c0SDavid du Colombier mouseshifted = 0;
247*3de6a9c0SDavid du Colombier if(kdebug)
248*3de6a9c0SDavid du Colombier print("shiftclr\n");
249*3de6a9c0SDavid du Colombier break;
250*3de6a9c0SDavid du Colombier case Ctrl:
251*3de6a9c0SDavid du Colombier kbscan->ctl = 0;
252*3de6a9c0SDavid du Colombier break;
253*3de6a9c0SDavid du Colombier case Altgr:
254*3de6a9c0SDavid du Colombier kbscan->altgr = 0;
255*3de6a9c0SDavid du Colombier break;
256*3de6a9c0SDavid du Colombier case Kmouse|1:
257*3de6a9c0SDavid du Colombier case Kmouse|2:
258*3de6a9c0SDavid du Colombier case Kmouse|3:
259*3de6a9c0SDavid du Colombier case Kmouse|4:
260*3de6a9c0SDavid du Colombier case Kmouse|5:
261*3de6a9c0SDavid du Colombier kbscan->buttons &= ~(1<<(c-Kmouse-1));
262*3de6a9c0SDavid du Colombier if(kbdmouse)
263*3de6a9c0SDavid du Colombier kbdmouse(kbscan->buttons);
264*3de6a9c0SDavid du Colombier break;
265*3de6a9c0SDavid du Colombier }
266*3de6a9c0SDavid du Colombier return;
267*3de6a9c0SDavid du Colombier }
268*3de6a9c0SDavid du Colombier
269*3de6a9c0SDavid du Colombier /*
270*3de6a9c0SDavid du Colombier * normal character
271*3de6a9c0SDavid du Colombier */
272*3de6a9c0SDavid du Colombier if(!(c & (Spec|KF))){
273*3de6a9c0SDavid du Colombier if(kbscan->ctl)
274*3de6a9c0SDavid du Colombier if(kbscan->alt && c == Del)
275*3de6a9c0SDavid du Colombier exit(0);
276*3de6a9c0SDavid du Colombier if(!kbscan->collecting){
277*3de6a9c0SDavid du Colombier kbdputc(kbdq, c);
278*3de6a9c0SDavid du Colombier return;
279*3de6a9c0SDavid du Colombier }
280*3de6a9c0SDavid du Colombier kbscan->kc[kbscan->nk++] = c;
281*3de6a9c0SDavid du Colombier c = latin1(kbscan->kc, kbscan->nk);
282*3de6a9c0SDavid du Colombier if(c < -1) /* need more keystrokes */
283*3de6a9c0SDavid du Colombier return;
284*3de6a9c0SDavid du Colombier if(c != -1) /* valid sequence */
285*3de6a9c0SDavid du Colombier kbdputc(kbdq, c);
286*3de6a9c0SDavid du Colombier else /* dump characters */
287*3de6a9c0SDavid du Colombier for(i=0; i<kbscan->nk; i++)
288*3de6a9c0SDavid du Colombier kbdputc(kbdq, kbscan->kc[i]);
289*3de6a9c0SDavid du Colombier kbscan->nk = 0;
290*3de6a9c0SDavid du Colombier kbscan->collecting = 0;
291*3de6a9c0SDavid du Colombier return;
292*3de6a9c0SDavid du Colombier } else {
293*3de6a9c0SDavid du Colombier switch(c){
294*3de6a9c0SDavid du Colombier case Caps:
295*3de6a9c0SDavid du Colombier kbscan->caps ^= 1;
296*3de6a9c0SDavid du Colombier return;
297*3de6a9c0SDavid du Colombier case Num:
298*3de6a9c0SDavid du Colombier kbscan->num ^= 1;
299*3de6a9c0SDavid du Colombier return;
300*3de6a9c0SDavid du Colombier case Shift:
301*3de6a9c0SDavid du Colombier kbscan->shift = 1;
302*3de6a9c0SDavid du Colombier if(kdebug)
303*3de6a9c0SDavid du Colombier print("shift\n");
304*3de6a9c0SDavid du Colombier mouseshifted = 1;
305*3de6a9c0SDavid du Colombier return;
306*3de6a9c0SDavid du Colombier case Latin:
307*3de6a9c0SDavid du Colombier kbscan->alt = 1;
308*3de6a9c0SDavid du Colombier /*
309*3de6a9c0SDavid du Colombier * VMware and Qemu use Ctl-Alt as the key combination
310*3de6a9c0SDavid du Colombier * to make the VM give up keyboard and mouse focus.
311*3de6a9c0SDavid du Colombier * This has the unfortunate side effect that when you
312*3de6a9c0SDavid du Colombier * come back into focus, Plan 9 thinks you want to type
313*3de6a9c0SDavid du Colombier * a compose sequence (you just typed alt).
314*3de6a9c0SDavid du Colombier *
315*3de6a9c0SDavid du Colombier * As a clumsy hack around this, we look for ctl-alt
316*3de6a9c0SDavid du Colombier * and don't treat it as the start of a compose sequence.
317*3de6a9c0SDavid du Colombier */
318*3de6a9c0SDavid du Colombier if(!kbscan->ctl){
319*3de6a9c0SDavid du Colombier kbscan->collecting = 1;
320*3de6a9c0SDavid du Colombier kbscan->nk = 0;
321*3de6a9c0SDavid du Colombier }
322*3de6a9c0SDavid du Colombier return;
323*3de6a9c0SDavid du Colombier case Ctrl:
324*3de6a9c0SDavid du Colombier kbscan->ctl = 1;
325*3de6a9c0SDavid du Colombier return;
326*3de6a9c0SDavid du Colombier case Altgr:
327*3de6a9c0SDavid du Colombier kbscan->altgr = 1;
328*3de6a9c0SDavid du Colombier return;
329*3de6a9c0SDavid du Colombier case Kmouse|1:
330*3de6a9c0SDavid du Colombier case Kmouse|2:
331*3de6a9c0SDavid du Colombier case Kmouse|3:
332*3de6a9c0SDavid du Colombier case Kmouse|4:
333*3de6a9c0SDavid du Colombier case Kmouse|5:
334*3de6a9c0SDavid du Colombier kbscan->buttons |= 1<<(c-Kmouse-1);
335*3de6a9c0SDavid du Colombier if(kbdmouse)
336*3de6a9c0SDavid du Colombier kbdmouse(kbscan->buttons);
337*3de6a9c0SDavid du Colombier return;
338*3de6a9c0SDavid du Colombier case KF|11:
339*3de6a9c0SDavid du Colombier print("kbd debug on, F12 turns it off\n");
340*3de6a9c0SDavid du Colombier kdebug = 1;
341*3de6a9c0SDavid du Colombier break;
342*3de6a9c0SDavid du Colombier case KF|12:
343*3de6a9c0SDavid du Colombier kdebug = 0;
344*3de6a9c0SDavid du Colombier break;
345*3de6a9c0SDavid du Colombier }
346*3de6a9c0SDavid du Colombier }
347*3de6a9c0SDavid du Colombier kbdputc(kbdq, c);
348*3de6a9c0SDavid du Colombier }
349*3de6a9c0SDavid du Colombier
350*3de6a9c0SDavid du Colombier void
351*3de6a9c0SDavid du Colombier kbdenable(void)
352*3de6a9c0SDavid du Colombier {
353*3de6a9c0SDavid du Colombier #ifdef notdef
354*3de6a9c0SDavid du Colombier kbdq = qopen(4*1024, 0, 0, 0);
355*3de6a9c0SDavid du Colombier if(kbdq == nil)
356*3de6a9c0SDavid du Colombier panic("kbdinit");
357*3de6a9c0SDavid du Colombier qnoblock(kbdq, 1);
358*3de6a9c0SDavid du Colombier #endif
kbdputmap(ushort m,ushort scanc,Rune r)359*3de6a9c0SDavid du Colombier kbscans[Int].num = 0;
360*3de6a9c0SDavid du Colombier }
361*3de6a9c0SDavid du Colombier
362*3de6a9c0SDavid du Colombier void
363*3de6a9c0SDavid du Colombier kbdputmap(ushort m, ushort scanc, Rune r)
364*3de6a9c0SDavid du Colombier {
365*3de6a9c0SDavid du Colombier if(scanc >= Nscan)
366*3de6a9c0SDavid du Colombier error(Ebadarg);
367*3de6a9c0SDavid du Colombier switch(m) {
368*3de6a9c0SDavid du Colombier default:
369*3de6a9c0SDavid du Colombier error(Ebadarg);
370*3de6a9c0SDavid du Colombier case 0:
371*3de6a9c0SDavid du Colombier kbtab[scanc] = r;
372*3de6a9c0SDavid du Colombier break;
373*3de6a9c0SDavid du Colombier case 1:
374*3de6a9c0SDavid du Colombier kbtabshift[scanc] = r;
375*3de6a9c0SDavid du Colombier break;
376*3de6a9c0SDavid du Colombier case 2:
377*3de6a9c0SDavid du Colombier kbtabesc1[scanc] = r;
378*3de6a9c0SDavid du Colombier break;
379*3de6a9c0SDavid du Colombier case 3:
380*3de6a9c0SDavid du Colombier kbtabaltgr[scanc] = r;
381*3de6a9c0SDavid du Colombier break;
382*3de6a9c0SDavid du Colombier case 4:
383*3de6a9c0SDavid du Colombier kbtabctrl[scanc] = r;
384*3de6a9c0SDavid du Colombier break;
kbdgetmap(uint offset,int * t,int * sc,Rune * r)385*3de6a9c0SDavid du Colombier }
386*3de6a9c0SDavid du Colombier }
387*3de6a9c0SDavid du Colombier
388*3de6a9c0SDavid du Colombier int
389*3de6a9c0SDavid du Colombier kbdgetmap(uint offset, int *t, int *sc, Rune *r)
390*3de6a9c0SDavid du Colombier {
391*3de6a9c0SDavid du Colombier if ((int)offset < 0)
392*3de6a9c0SDavid du Colombier error(Ebadarg);
393*3de6a9c0SDavid du Colombier *t = offset/Nscan;
394*3de6a9c0SDavid du Colombier *sc = offset%Nscan;
395*3de6a9c0SDavid du Colombier switch(*t) {
396*3de6a9c0SDavid du Colombier default:
397*3de6a9c0SDavid du Colombier return 0;
398*3de6a9c0SDavid du Colombier case 0:
399*3de6a9c0SDavid du Colombier *r = kbtab[*sc];
400*3de6a9c0SDavid du Colombier return 1;
401*3de6a9c0SDavid du Colombier case 1:
402*3de6a9c0SDavid du Colombier *r = kbtabshift[*sc];
403*3de6a9c0SDavid du Colombier return 1;
404*3de6a9c0SDavid du Colombier case 2:
405*3de6a9c0SDavid du Colombier *r = kbtabesc1[*sc];
406*3de6a9c0SDavid du Colombier return 1;
407*3de6a9c0SDavid du Colombier case 3:
408*3de6a9c0SDavid du Colombier *r = kbtabaltgr[*sc];
409*3de6a9c0SDavid du Colombier return 1;
410*3de6a9c0SDavid du Colombier case 4:
411 *r = kbtabctrl[*sc];
412 return 1;
413 }
414 }
415