Annotation of sys/dev/wscons/wskbdutil.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: wskbdutil.c,v 1.6 2006/12/17 22:04:04 miod Exp $ */
2: /* $NetBSD: wskbdutil.c,v 1.7 1999/12/21 11:59:13 drochner Exp $ */
3:
4: /*-
5: * Copyright (c) 1997 The NetBSD Foundation, Inc.
6: * All rights reserved.
7: *
8: * This code is derived from software contributed to The NetBSD Foundation
9: * by Juergen Hannken-Illjes.
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. All advertising materials mentioning features or use of this software
20: * must display the following acknowledgement:
21: * This product includes software developed by the NetBSD
22: * Foundation, Inc. and its contributors.
23: * 4. Neither the name of The NetBSD Foundation nor the names of its
24: * contributors may be used to endorse or promote products derived
25: * from this software without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37: * POSSIBILITY OF SUCH DAMAGE.
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: /* Insertion sort. */
212: for (i = 1; i < COMPOSE_SIZE; i++) {
213: v = compose_tab[i];
214: /* find correct slot, moving others up */
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: /* 0 8 1 9 2 a 3 b 4 c 5 d 6 e 7 f */
240: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0 */
241: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0 */
242: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1 */
243: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1 */
244: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 2 */
245: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 2 */
246: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 3 */
247: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 3 */
248: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 4 */
249: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 4 */
250: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 5 */
251: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 5 */
252: 0x00, 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* 6 */
253: 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', /* 6 */
254: 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 7 */
255: 'X', 'Y', 'Z', 0x00, 0x00, 0x00, 0x00, 0x00, /* 7 */
256: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8 */
257: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8 */
258: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9 */
259: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9 */
260: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
261: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
262: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
263: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
264: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c */
265: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c */
266: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d */
267: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d */
268: 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* e */
269: 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* e */
270: 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0x00, /* f */
271: 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0x00, /* f */
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: /* If map not found, return */
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: /* First skip keycode and possible command */
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: }
CVSweb