This source file includes following definitions.
- compose_tab_cmp
- wskbd_compose_value
- ksym_upcase
- fillmapentry
- wskbd_get_mapentry
- wskbd_init_keymap
- wskbd_load_keymap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #include <sys/param.h>
41 #include <sys/types.h>
42 #include <sys/cdefs.h>
43 #include <sys/errno.h>
44 #include <sys/systm.h>
45 #include <sys/malloc.h>
46 #include <dev/wscons/wsksymdef.h>
47 #include <dev/wscons/wsksymvar.h>
48
49 static struct compose_tab_s {
50 keysym_t elem[2];
51 keysym_t result;
52 } compose_tab[] = {
53 { { KS_plus, KS_plus }, KS_numbersign },
54 { { KS_a, KS_a }, KS_at },
55 { { KS_parenleft, KS_parenleft }, KS_bracketleft },
56 { { KS_slash, KS_slash }, KS_backslash },
57 { { KS_parenright, KS_parenright }, KS_bracketright },
58 { { KS_parenleft, KS_minus }, KS_braceleft },
59 { { KS_slash, KS_minus }, KS_bar },
60 { { KS_parenright, KS_minus }, KS_braceright },
61 { { KS_exclam, KS_exclam }, KS_exclamdown },
62 { { KS_c, KS_slash }, KS_cent },
63 { { KS_l, KS_minus }, KS_sterling },
64 { { KS_y, KS_minus }, KS_yen },
65 { { KS_s, KS_o }, KS_section },
66 { { KS_x, KS_o }, KS_currency },
67 { { KS_c, KS_o }, KS_copyright },
68 { { KS_less, KS_less }, KS_guillemotleft },
69 { { KS_greater, KS_greater }, KS_guillemotright },
70 { { KS_question, KS_question }, KS_questiondown },
71 { { KS_dead_acute, KS_space }, KS_apostrophe },
72 { { KS_dead_grave, KS_space }, KS_grave },
73 { { KS_dead_tilde, KS_space }, KS_asciitilde },
74 { { KS_dead_circumflex, KS_space }, KS_asciicircum },
75 { { KS_dead_diaeresis, KS_space }, KS_quotedbl },
76 { { KS_dead_cedilla, KS_space }, KS_comma },
77 { { KS_dead_circumflex, KS_A }, KS_Acircumflex },
78 { { KS_dead_diaeresis, KS_A }, KS_Adiaeresis },
79 { { KS_dead_grave, KS_A }, KS_Agrave },
80 { { KS_dead_abovering, KS_A }, KS_Aring },
81 { { KS_dead_tilde, KS_A }, KS_Atilde },
82 { { KS_dead_cedilla, KS_C }, KS_Ccedilla },
83 { { KS_dead_acute, KS_E }, KS_Eacute },
84 { { KS_dead_circumflex, KS_E }, KS_Ecircumflex },
85 { { KS_dead_diaeresis, KS_E }, KS_Ediaeresis },
86 { { KS_dead_grave, KS_E }, KS_Egrave },
87 { { KS_dead_acute, KS_I }, KS_Iacute },
88 { { KS_dead_circumflex, KS_I }, KS_Icircumflex },
89 { { KS_dead_diaeresis, KS_I }, KS_Idiaeresis },
90 { { KS_dead_grave, KS_I }, KS_Igrave },
91 { { KS_dead_tilde, KS_N }, KS_Ntilde },
92 { { KS_dead_acute, KS_O }, KS_Oacute },
93 { { KS_dead_circumflex, KS_O }, KS_Ocircumflex },
94 { { KS_dead_diaeresis, KS_O }, KS_Odiaeresis },
95 { { KS_dead_grave, KS_O }, KS_Ograve },
96 { { KS_dead_tilde, KS_O }, KS_Otilde },
97 { { KS_dead_acute, KS_U }, KS_Uacute },
98 { { KS_dead_circumflex, KS_U }, KS_Ucircumflex },
99 { { KS_dead_diaeresis, KS_U }, KS_Udiaeresis },
100 { { KS_dead_grave, KS_U }, KS_Ugrave },
101 { { KS_dead_acute, KS_Y }, KS_Yacute },
102 { { KS_dead_acute, KS_a }, KS_aacute },
103 { { KS_dead_circumflex, KS_a }, KS_acircumflex },
104 { { KS_dead_diaeresis, KS_a }, KS_adiaeresis },
105 { { KS_dead_grave, KS_a }, KS_agrave },
106 { { KS_dead_abovering, KS_a }, KS_aring },
107 { { KS_dead_tilde, KS_a }, KS_atilde },
108 { { KS_dead_cedilla, KS_c }, KS_ccedilla },
109 { { KS_dead_acute, KS_e }, KS_eacute },
110 { { KS_dead_circumflex, KS_e }, KS_ecircumflex },
111 { { KS_dead_diaeresis, KS_e }, KS_ediaeresis },
112 { { KS_dead_grave, KS_e }, KS_egrave },
113 { { KS_dead_acute, KS_i }, KS_iacute },
114 { { KS_dead_circumflex, KS_i }, KS_icircumflex },
115 { { KS_dead_diaeresis, KS_i }, KS_idiaeresis },
116 { { KS_dead_grave, KS_i }, KS_igrave },
117 { { KS_dead_tilde, KS_n }, KS_ntilde },
118 { { KS_dead_acute, KS_o }, KS_oacute },
119 { { KS_dead_circumflex, KS_o }, KS_ocircumflex },
120 { { KS_dead_diaeresis, KS_o }, KS_odiaeresis },
121 { { KS_dead_grave, KS_o }, KS_ograve },
122 { { KS_dead_tilde, KS_o }, KS_otilde },
123 { { KS_dead_acute, KS_u }, KS_uacute },
124 { { KS_dead_circumflex, KS_u }, KS_ucircumflex },
125 { { KS_dead_diaeresis, KS_u }, KS_udiaeresis },
126 { { KS_dead_grave, KS_u }, KS_ugrave },
127 { { KS_dead_acute, KS_y }, KS_yacute },
128 { { KS_dead_diaeresis, KS_y }, KS_ydiaeresis },
129 { { KS_quotedbl, KS_A }, KS_Adiaeresis },
130 { { KS_quotedbl, KS_E }, KS_Ediaeresis },
131 { { KS_quotedbl, KS_I }, KS_Idiaeresis },
132 { { KS_quotedbl, KS_O }, KS_Odiaeresis },
133 { { KS_quotedbl, KS_U }, KS_Udiaeresis },
134 { { KS_quotedbl, KS_a }, KS_adiaeresis },
135 { { KS_quotedbl, KS_e }, KS_ediaeresis },
136 { { KS_quotedbl, KS_i }, KS_idiaeresis },
137 { { KS_quotedbl, KS_o }, KS_odiaeresis },
138 { { KS_quotedbl, KS_u }, KS_udiaeresis },
139 { { KS_quotedbl, KS_y }, KS_ydiaeresis },
140 { { KS_acute, KS_A }, KS_Aacute },
141 { { KS_asciicircum, KS_A }, KS_Acircumflex },
142 { { KS_grave, KS_A }, KS_Agrave },
143 { { KS_asterisk, KS_A }, KS_Aring },
144 { { KS_asciitilde, KS_A }, KS_Atilde },
145 { { KS_cedilla, KS_C }, KS_Ccedilla },
146 { { KS_acute, KS_E }, KS_Eacute },
147 { { KS_asciicircum, KS_E }, KS_Ecircumflex },
148 { { KS_grave, KS_E }, KS_Egrave },
149 { { KS_acute, KS_I }, KS_Iacute },
150 { { KS_asciicircum, KS_I }, KS_Icircumflex },
151 { { KS_grave, KS_I }, KS_Igrave },
152 { { KS_asciitilde, KS_N }, KS_Ntilde },
153 { { KS_acute, KS_O }, KS_Oacute },
154 { { KS_asciicircum, KS_O }, KS_Ocircumflex },
155 { { KS_grave, KS_O }, KS_Ograve },
156 { { KS_asciitilde, KS_O }, KS_Otilde },
157 { { KS_acute, KS_U }, KS_Uacute },
158 { { KS_asciicircum, KS_U }, KS_Ucircumflex },
159 { { KS_grave, KS_U }, KS_Ugrave },
160 { { KS_acute, KS_Y }, KS_Yacute },
161 { { KS_acute, KS_a }, KS_aacute },
162 { { KS_asciicircum, KS_a }, KS_acircumflex },
163 { { KS_grave, KS_a }, KS_agrave },
164 { { KS_asterisk, KS_a }, KS_aring },
165 { { KS_asciitilde, KS_a }, KS_atilde },
166 { { KS_cedilla, KS_c }, KS_ccedilla },
167 { { KS_acute, KS_e }, KS_eacute },
168 { { KS_asciicircum, KS_e }, KS_ecircumflex },
169 { { KS_grave, KS_e }, KS_egrave },
170 { { KS_acute, KS_i }, KS_iacute },
171 { { KS_asciicircum, KS_i }, KS_icircumflex },
172 { { KS_grave, KS_i }, KS_igrave },
173 { { KS_asciitilde, KS_n }, KS_ntilde },
174 { { KS_acute, KS_o }, KS_oacute },
175 { { KS_asciicircum, KS_o }, KS_ocircumflex },
176 { { KS_grave, KS_o }, KS_ograve },
177 { { KS_asciitilde, KS_o }, KS_otilde },
178 { { KS_acute, KS_u }, KS_uacute },
179 { { KS_asciicircum, KS_u }, KS_ucircumflex },
180 { { KS_grave, KS_u }, KS_ugrave },
181 { { KS_acute, KS_y }, KS_yacute }
182 };
183
184 #define COMPOSE_SIZE sizeof(compose_tab)/sizeof(compose_tab[0])
185
186 static int compose_tab_inorder = 0;
187
188 inline int compose_tab_cmp(struct compose_tab_s *,
189 struct compose_tab_s *);
190 keysym_t ksym_upcase(keysym_t);
191 void fillmapentry(const keysym_t *, int, struct wscons_keymap *);
192
193 inline int
194 compose_tab_cmp(i, j)
195 struct compose_tab_s *i, *j;
196 {
197 if (i->elem[0] == j->elem[0])
198 return(i->elem[1] - j->elem[1]);
199 else
200 return(i->elem[0] - j->elem[0]);
201 }
202
203 keysym_t
204 wskbd_compose_value(compose_buf)
205 keysym_t *compose_buf;
206 {
207 int i, j, r;
208 struct compose_tab_s v;
209
210 if (! compose_tab_inorder) {
211
212 for (i = 1; i < COMPOSE_SIZE; i++) {
213 v = compose_tab[i];
214
215 for (j = i; --j >= 0 && compose_tab_cmp(& v, & compose_tab[j]) < 0; )
216 compose_tab[j + 1] = compose_tab[j];
217 compose_tab[j + 1] = v;
218 }
219 compose_tab_inorder = 1;
220 }
221
222 for (j = 0, i = COMPOSE_SIZE; i != 0; i /= 2) {
223 if (compose_tab[j + i/2].elem[0] == compose_buf[0]) {
224 if (compose_tab[j + i/2].elem[1] == compose_buf[1])
225 return(compose_tab[j + i/2].result);
226 r = compose_tab[j + i/2].elem[1] < compose_buf[1];
227 } else
228 r = compose_tab[j + i/2].elem[0] < compose_buf[0];
229 if (r) {
230 j += i/2 + 1;
231 i--;
232 }
233 }
234
235 return(KS_voidSymbol);
236 }
237
238 static const u_char latin1_to_upper[256] = {
239
240 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
241 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
242 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
245 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
246 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
248 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
249 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
250 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
251 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
252 0x00, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
253 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
254 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
255 'X', 'Y', 'Z', 0x00, 0x00, 0x00, 0x00, 0x00,
256 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
257 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
258 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
259 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
260 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
261 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
262 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
263 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
264 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
265 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
266 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
267 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
268 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
269 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
270 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0x00,
271 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0x00,
272 };
273
274 keysym_t
275 ksym_upcase(ksym)
276 keysym_t ksym;
277 {
278 if (ksym >= KS_f1 && ksym <= KS_f20)
279 return(KS_F1 - KS_f1 + ksym);
280
281 if (KS_GROUP(ksym) == KS_GROUP_Ascii && ksym <= 0xff &&
282 latin1_to_upper[ksym] != 0x00)
283 return(latin1_to_upper[ksym]);
284
285 return(ksym);
286 }
287
288 void
289 fillmapentry(kp, len, mapentry)
290 const keysym_t *kp;
291 int len;
292 struct wscons_keymap *mapentry;
293 {
294 switch (len) {
295 case 0:
296 mapentry->group1[0] = KS_voidSymbol;
297 mapentry->group1[1] = KS_voidSymbol;
298 mapentry->group2[0] = KS_voidSymbol;
299 mapentry->group2[1] = KS_voidSymbol;
300 break;
301
302 case 1:
303 mapentry->group1[0] = kp[0];
304 mapentry->group1[1] = ksym_upcase(kp[0]);
305 mapentry->group2[0] = mapentry->group1[0];
306 mapentry->group2[1] = mapentry->group1[1];
307 break;
308
309 case 2:
310 mapentry->group1[0] = kp[0];
311 mapentry->group1[1] = kp[1];
312 mapentry->group2[0] = mapentry->group1[0];
313 mapentry->group2[1] = mapentry->group1[1];
314 break;
315
316 case 3:
317 mapentry->group1[0] = kp[0];
318 mapentry->group1[1] = kp[1];
319 mapentry->group2[0] = kp[2];
320 mapentry->group2[1] = ksym_upcase(kp[2]);
321 break;
322
323 case 4:
324 mapentry->group1[0] = kp[0];
325 mapentry->group1[1] = kp[1];
326 mapentry->group2[0] = kp[2];
327 mapentry->group2[1] = kp[3];
328 break;
329
330 }
331 }
332
333 void
334 wskbd_get_mapentry(mapdata, kc, mapentry)
335 const struct wskbd_mapdata *mapdata;
336 int kc;
337 struct wscons_keymap *mapentry;
338 {
339 kbd_t cur;
340 const keysym_t *kp;
341 const struct wscons_keydesc *mp;
342 int l;
343 keysym_t ksg;
344
345 mapentry->command = KS_voidSymbol;
346 mapentry->group1[0] = KS_voidSymbol;
347 mapentry->group1[1] = KS_voidSymbol;
348 mapentry->group2[0] = KS_voidSymbol;
349 mapentry->group2[1] = KS_voidSymbol;
350
351 for (cur = mapdata->layout & ~KB_HANDLEDBYWSKBD; cur != 0; ) {
352 mp = mapdata->keydesc;
353 while (mp->map_size > 0) {
354 if (mp->name == cur)
355 break;
356 mp++;
357 }
358
359
360 if (mp->map_size <= 0)
361 return;
362
363 for (kp = mp->map; kp < mp->map + mp->map_size; kp++) {
364 ksg = KS_GROUP(*kp);
365 if (ksg == KS_GROUP_Keycode &&
366 KS_VALUE(*kp) == kc) {
367
368 kp++;
369 if (KS_GROUP(*kp) == KS_GROUP_Command ||
370 *kp == KS_Cmd || *kp == KS_Cmd1 || *kp == KS_Cmd2)
371 mapentry->command = *kp++;
372
373 for (l = 0; kp + l < mp->map + mp->map_size;
374 l++) {
375 ksg = KS_GROUP(kp[l]);
376 if (ksg == KS_GROUP_Keycode)
377 break;
378 }
379 if (l > 4)
380 panic("wskbd_get_mapentry: %d(%d): bad entry",
381 mp->name, *kp);
382 fillmapentry(kp, l, mapentry);
383 return;
384 }
385 }
386
387 cur = mp->base;
388 }
389 }
390
391 void
392 wskbd_init_keymap(newlen, map, maplen)
393 int newlen;
394 struct wscons_keymap **map;
395 int *maplen;
396 {
397 int i;
398
399 if (newlen != *maplen) {
400 if (*maplen > 0)
401 free(*map, M_TEMP);
402 *maplen = newlen;
403 *map = malloc(newlen*sizeof(struct wscons_keymap),
404 M_TEMP, M_WAITOK);
405 }
406
407 for (i = 0; i < *maplen; i++) {
408 (*map)[i].command = KS_voidSymbol;
409 (*map)[i].group1[0] = KS_voidSymbol;
410 (*map)[i].group1[1] = KS_voidSymbol;
411 (*map)[i].group2[0] = KS_voidSymbol;
412 (*map)[i].group2[1] = KS_voidSymbol;
413 }
414 }
415
416 int
417 wskbd_load_keymap(mapdata, map, maplen)
418 const struct wskbd_mapdata *mapdata;
419 struct wscons_keymap **map;
420 int *maplen;
421 {
422 int i, s, kc, stack_ptr;
423 const keysym_t *kp;
424 const struct wscons_keydesc *mp, *stack[10];
425 kbd_t cur;
426 keysym_t ksg;
427
428 for (cur = mapdata->layout & ~KB_HANDLEDBYWSKBD, stack_ptr = 0;
429 cur != 0; stack_ptr++) {
430 mp = mapdata->keydesc;
431 while (mp->map_size > 0) {
432 if (cur == 0 || mp->name == cur) {
433 break;
434 }
435 mp++;
436 }
437
438 if (stack_ptr == sizeof(stack)/sizeof(stack[0]))
439 panic("wskbd_load_keymap: %d: recursion too deep",
440 mapdata->layout);
441 if (mp->map_size <= 0)
442 return(EINVAL);
443
444 stack[stack_ptr] = mp;
445 cur = mp->base;
446 }
447
448 for (i = 0, s = stack_ptr - 1; s >= 0; s--) {
449 mp = stack[s];
450 for (kp = mp->map; kp < mp->map + mp->map_size; kp++) {
451 ksg = KS_GROUP(*kp);
452 if (ksg == KS_GROUP_Keycode && KS_VALUE(*kp) > i)
453 i = KS_VALUE(*kp);
454 }
455 }
456
457 wskbd_init_keymap(i + 1, map, maplen);
458
459 for (s = stack_ptr - 1; s >= 0; s--) {
460 mp = stack[s];
461 for (kp = mp->map; kp < mp->map + mp->map_size; ) {
462 ksg = KS_GROUP(*kp);
463 if (ksg != KS_GROUP_Keycode)
464 panic("wskbd_load_keymap: %d(%d): bad entry",
465 mp->name, *kp);
466
467 kc = KS_VALUE(*kp);
468 kp++;
469
470 if (KS_GROUP(*kp) == KS_GROUP_Command ||
471 *kp == KS_Cmd || *kp == KS_Cmd1 || *kp == KS_Cmd2) {
472 (*map)[kc].command = *kp;
473 kp++;
474 }
475
476 for (i = 0; kp + i < mp->map + mp->map_size; i++) {
477 ksg = KS_GROUP(kp[i]);
478 if (ksg == KS_GROUP_Keycode)
479 break;
480 }
481
482 if (i > 4)
483 panic("wskbd_load_keymap: %d(%d): bad entry",
484 mp->name, *kp);
485
486 fillmapentry(kp, i, &(*map)[kc]);
487 kp += i;
488 }
489 }
490
491 return(0);
492 }