1 /* $NetBSD: wskbdutil.c,v 1.15 2008/04/28 20:24:01 martin Exp $ */
4 * Copyright (c) 1997 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Juergen Hannken-Illjes.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: wskbdutil.c,v 1.15 2008/04/28 20:24:01 martin Exp $");
35 #include <sys/param.h>
36 #include <sys/errno.h>
37 #include <sys/systm.h>
38 #include <sys/malloc.h>
39 #include <dev/wscons/wsksymdef.h>
40 #include <dev/wscons/wsksymvar.h>
42 static struct compose_tab_s
{
46 { { KS_plus
, KS_plus
}, KS_numbersign
},
47 { { KS_a
, KS_a
}, KS_at
},
48 { { KS_parenleft
, KS_parenleft
}, KS_bracketleft
},
49 { { KS_slash
, KS_slash
}, KS_backslash
},
50 { { KS_parenright
, KS_parenright
}, KS_bracketright
},
51 { { KS_parenleft
, KS_minus
}, KS_braceleft
},
52 { { KS_slash
, KS_minus
}, KS_bar
},
53 { { KS_parenright
, KS_minus
}, KS_braceright
},
54 { { KS_exclam
, KS_exclam
}, KS_exclamdown
},
55 { { KS_c
, KS_slash
}, KS_cent
},
56 { { KS_l
, KS_minus
}, KS_sterling
},
57 { { KS_y
, KS_minus
}, KS_yen
},
58 { { KS_s
, KS_o
}, KS_section
},
59 { { KS_x
, KS_o
}, KS_currency
},
60 { { KS_c
, KS_o
}, KS_copyright
},
61 { { KS_less
, KS_less
}, KS_guillemotleft
},
62 { { KS_greater
, KS_greater
}, KS_guillemotright
},
63 { { KS_question
, KS_question
}, KS_questiondown
},
64 { { KS_dead_acute
, KS_space
}, KS_acute
},
65 { { KS_dead_grave
, KS_space
}, KS_grave
},
66 { { KS_dead_tilde
, KS_space
}, KS_asciitilde
},
67 { { KS_dead_circumflex
, KS_space
}, KS_asciicircum
},
68 { { KS_dead_circumflex
, KS_A
}, KS_Acircumflex
},
69 { { KS_dead_diaeresis
, KS_A
}, KS_Adiaeresis
},
70 { { KS_dead_grave
, KS_A
}, KS_Agrave
},
71 { { KS_dead_abovering
, KS_A
}, KS_Aring
},
72 { { KS_dead_tilde
, KS_A
}, KS_Atilde
},
73 { { KS_dead_cedilla
, KS_C
}, KS_Ccedilla
},
74 { { KS_dead_acute
, KS_E
}, KS_Eacute
},
75 { { KS_dead_circumflex
, KS_E
}, KS_Ecircumflex
},
76 { { KS_dead_diaeresis
, KS_E
}, KS_Ediaeresis
},
77 { { KS_dead_grave
, KS_E
}, KS_Egrave
},
78 { { KS_dead_acute
, KS_I
}, KS_Iacute
},
79 { { KS_dead_circumflex
, KS_I
}, KS_Icircumflex
},
80 { { KS_dead_diaeresis
, KS_I
}, KS_Idiaeresis
},
81 { { KS_dead_grave
, KS_I
}, KS_Igrave
},
82 { { KS_dead_tilde
, KS_N
}, KS_Ntilde
},
83 { { KS_dead_acute
, KS_O
}, KS_Oacute
},
84 { { KS_dead_circumflex
, KS_O
}, KS_Ocircumflex
},
85 { { KS_dead_diaeresis
, KS_O
}, KS_Odiaeresis
},
86 { { KS_dead_grave
, KS_O
}, KS_Ograve
},
87 { { KS_dead_tilde
, KS_O
}, KS_Otilde
},
88 { { KS_dead_acute
, KS_U
}, KS_Uacute
},
89 { { KS_dead_circumflex
, KS_U
}, KS_Ucircumflex
},
90 { { KS_dead_diaeresis
, KS_U
}, KS_Udiaeresis
},
91 { { KS_dead_grave
, KS_U
}, KS_Ugrave
},
92 { { KS_dead_acute
, KS_Y
}, KS_Yacute
},
93 { { KS_dead_acute
, KS_a
}, KS_aacute
},
94 { { KS_dead_circumflex
, KS_a
}, KS_acircumflex
},
95 { { KS_dead_diaeresis
, KS_a
}, KS_adiaeresis
},
96 { { KS_dead_grave
, KS_a
}, KS_agrave
},
97 { { KS_dead_abovering
, KS_a
}, KS_aring
},
98 { { KS_dead_tilde
, KS_a
}, KS_atilde
},
99 { { KS_dead_cedilla
, KS_c
}, KS_ccedilla
},
100 { { KS_dead_acute
, KS_e
}, KS_eacute
},
101 { { KS_dead_circumflex
, KS_e
}, KS_ecircumflex
},
102 { { KS_dead_diaeresis
, KS_e
}, KS_ediaeresis
},
103 { { KS_dead_grave
, KS_e
}, KS_egrave
},
104 { { KS_dead_acute
, KS_i
}, KS_iacute
},
105 { { KS_dead_circumflex
, KS_i
}, KS_icircumflex
},
106 { { KS_dead_diaeresis
, KS_i
}, KS_idiaeresis
},
107 { { KS_dead_grave
, KS_i
}, KS_igrave
},
108 { { KS_dead_tilde
, KS_n
}, KS_ntilde
},
109 { { KS_dead_acute
, KS_o
}, KS_oacute
},
110 { { KS_dead_circumflex
, KS_o
}, KS_ocircumflex
},
111 { { KS_dead_diaeresis
, KS_o
}, KS_odiaeresis
},
112 { { KS_dead_grave
, KS_o
}, KS_ograve
},
113 { { KS_dead_tilde
, KS_o
}, KS_otilde
},
114 { { KS_dead_acute
, KS_u
}, KS_uacute
},
115 { { KS_dead_circumflex
, KS_u
}, KS_ucircumflex
},
116 { { KS_dead_diaeresis
, KS_u
}, KS_udiaeresis
},
117 { { KS_dead_grave
, KS_u
}, KS_ugrave
},
118 { { KS_dead_acute
, KS_y
}, KS_yacute
},
119 { { KS_dead_diaeresis
, KS_y
}, KS_ydiaeresis
},
120 { { KS_quotedbl
, KS_A
}, KS_Adiaeresis
},
121 { { KS_quotedbl
, KS_E
}, KS_Ediaeresis
},
122 { { KS_quotedbl
, KS_I
}, KS_Idiaeresis
},
123 { { KS_quotedbl
, KS_O
}, KS_Odiaeresis
},
124 { { KS_quotedbl
, KS_U
}, KS_Udiaeresis
},
125 { { KS_quotedbl
, KS_a
}, KS_adiaeresis
},
126 { { KS_quotedbl
, KS_e
}, KS_ediaeresis
},
127 { { KS_quotedbl
, KS_i
}, KS_idiaeresis
},
128 { { KS_quotedbl
, KS_o
}, KS_odiaeresis
},
129 { { KS_quotedbl
, KS_u
}, KS_udiaeresis
},
130 { { KS_quotedbl
, KS_y
}, KS_ydiaeresis
},
131 { { KS_acute
, KS_A
}, KS_Aacute
},
132 { { KS_asciicircum
, KS_A
}, KS_Acircumflex
},
133 { { KS_grave
, KS_A
}, KS_Agrave
},
134 { { KS_asterisk
, KS_A
}, KS_Aring
},
135 { { KS_asciitilde
, KS_A
}, KS_Atilde
},
136 { { KS_cedilla
, KS_C
}, KS_Ccedilla
},
137 { { KS_acute
, KS_E
}, KS_Eacute
},
138 { { KS_asciicircum
, KS_E
}, KS_Ecircumflex
},
139 { { KS_grave
, KS_E
}, KS_Egrave
},
140 { { KS_acute
, KS_I
}, KS_Iacute
},
141 { { KS_asciicircum
, KS_I
}, KS_Icircumflex
},
142 { { KS_grave
, KS_I
}, KS_Igrave
},
143 { { KS_asciitilde
, KS_N
}, KS_Ntilde
},
144 { { KS_acute
, KS_O
}, KS_Oacute
},
145 { { KS_asciicircum
, KS_O
}, KS_Ocircumflex
},
146 { { KS_grave
, KS_O
}, KS_Ograve
},
147 { { KS_asciitilde
, KS_O
}, KS_Otilde
},
148 { { KS_acute
, KS_U
}, KS_Uacute
},
149 { { KS_asciicircum
, KS_U
}, KS_Ucircumflex
},
150 { { KS_grave
, KS_U
}, KS_Ugrave
},
151 { { KS_acute
, KS_Y
}, KS_Yacute
},
152 { { KS_acute
, KS_a
}, KS_aacute
},
153 { { KS_asciicircum
, KS_a
}, KS_acircumflex
},
154 { { KS_grave
, KS_a
}, KS_agrave
},
155 { { KS_asterisk
, KS_a
}, KS_aring
},
156 { { KS_asciitilde
, KS_a
}, KS_atilde
},
157 { { KS_cedilla
, KS_c
}, KS_ccedilla
},
158 { { KS_acute
, KS_e
}, KS_eacute
},
159 { { KS_asciicircum
, KS_e
}, KS_ecircumflex
},
160 { { KS_grave
, KS_e
}, KS_egrave
},
161 { { KS_acute
, KS_i
}, KS_iacute
},
162 { { KS_asciicircum
, KS_i
}, KS_icircumflex
},
163 { { KS_grave
, KS_i
}, KS_igrave
},
164 { { KS_asciitilde
, KS_n
}, KS_ntilde
},
165 { { KS_acute
, KS_o
}, KS_oacute
},
166 { { KS_asciicircum
, KS_o
}, KS_ocircumflex
},
167 { { KS_grave
, KS_o
}, KS_ograve
},
168 { { KS_asciitilde
, KS_o
}, KS_otilde
},
169 { { KS_acute
, KS_u
}, KS_uacute
},
170 { { KS_asciicircum
, KS_u
}, KS_ucircumflex
},
171 { { KS_grave
, KS_u
}, KS_ugrave
},
172 { { KS_acute
, KS_y
}, KS_yacute
},
173 { { KS_dead_semi
, KS_gr_A
}, KS_gr_At
},
174 { { KS_dead_semi
, KS_gr_E
}, KS_gr_Et
},
175 { { KS_dead_semi
, KS_gr_H
}, KS_gr_Ht
},
176 { { KS_dead_semi
, KS_gr_I
}, KS_gr_It
},
177 { { KS_dead_semi
, KS_gr_O
}, KS_gr_Ot
},
178 { { KS_dead_semi
, KS_gr_Y
}, KS_gr_Yt
},
179 { { KS_dead_semi
, KS_gr_V
}, KS_gr_Vt
},
180 { { KS_dead_colon
, KS_gr_I
}, KS_gr_Id
},
181 { { KS_dead_colon
, KS_gr_Y
}, KS_gr_Yd
},
182 { { KS_dead_semi
, KS_gr_a
}, KS_gr_at
},
183 { { KS_dead_semi
, KS_gr_e
}, KS_gr_et
},
184 { { KS_dead_semi
, KS_gr_h
}, KS_gr_ht
},
185 { { KS_dead_semi
, KS_gr_i
}, KS_gr_it
},
186 { { KS_dead_semi
, KS_gr_o
}, KS_gr_ot
},
187 { { KS_dead_semi
, KS_gr_y
}, KS_gr_yt
},
188 { { KS_dead_semi
, KS_gr_v
}, KS_gr_vt
},
189 { { KS_dead_colon
, KS_gr_i
}, KS_gr_id
},
190 { { KS_dead_colon
, KS_gr_y
}, KS_gr_yd
},
194 { { KS_dead_acute
, KS_S
}, KS_Sacute
},
195 { { KS_dead_acute
, KS_Z
}, KS_Zacute
},
196 { { KS_dead_acute
, KS_s
}, KS_sacute
},
197 { { KS_dead_acute
, KS_z
}, KS_zacute
},
198 { { KS_dead_acute
, KS_R
}, KS_Racute
},
199 { { KS_dead_acute
, KS_A
}, KS_Aacute
},
200 { { KS_dead_acute
, KS_L
}, KS_Lacute
},
201 { { KS_dead_acute
, KS_C
}, KS_Cacute
},
202 { { KS_dead_acute
, KS_E
}, KS_Eacute
},
203 { { KS_dead_acute
, KS_I
}, KS_Iacute
},
204 { { KS_dead_acute
, KS_N
}, KS_Nacute
},
205 { { KS_dead_acute
, KS_O
}, KS_Oacute
},
206 { { KS_dead_acute
, KS_U
}, KS_Uacute
},
207 { { KS_dead_acute
, KS_Y
}, KS_Yacute
},
208 { { KS_dead_acute
, KS_r
}, KS_racute
},
209 { { KS_dead_acute
, KS_a
}, KS_aacute
},
210 { { KS_dead_acute
, KS_l
}, KS_lacute
},
211 { { KS_dead_acute
, KS_c
}, KS_cacute
},
212 { { KS_dead_acute
, KS_e
}, KS_eacute
},
213 { { KS_dead_acute
, KS_i
}, KS_iacute
},
214 { { KS_dead_acute
, KS_n
}, KS_nacute
},
215 { { KS_dead_acute
, KS_o
}, KS_oacute
},
216 { { KS_dead_acute
, KS_u
}, KS_uacute
},
217 { { KS_dead_acute
, KS_y
}, KS_yacute
},
218 { { KS_dead_breve
, KS_A
}, KS_Abreve
},
219 { { KS_dead_breve
, KS_a
}, KS_abreve
},
220 { { KS_dead_caron
, KS_L
}, KS_Lcaron
},
221 { { KS_dead_caron
, KS_S
}, KS_Scaron
},
222 { { KS_dead_caron
, KS_T
}, KS_Tcaron
},
223 { { KS_dead_caron
, KS_Z
}, KS_Zcaron
},
224 { { KS_dead_caron
, KS_l
}, KS_lcaron
},
225 { { KS_dead_caron
, KS_s
}, KS_scaron
},
226 { { KS_dead_caron
, KS_t
}, KS_tcaron
},
227 { { KS_dead_caron
, KS_z
}, KS_zcaron
},
228 { { KS_dead_caron
, KS_C
}, KS_Ccaron
},
229 { { KS_dead_caron
, KS_E
}, KS_Ecaron
},
230 { { KS_dead_caron
, KS_D
}, KS_Dcaron
},
231 { { KS_dead_caron
, KS_N
}, KS_Ncaron
},
232 { { KS_dead_caron
, KS_R
}, KS_Rcaron
},
233 { { KS_dead_caron
, KS_c
}, KS_ccaron
},
234 { { KS_dead_caron
, KS_e
}, KS_ecaron
},
235 { { KS_dead_caron
, KS_d
}, KS_dcaron
},
236 { { KS_dead_caron
, KS_n
}, KS_ncaron
},
237 { { KS_dead_caron
, KS_r
}, KS_rcaron
},
238 { { KS_dead_cedilla
, KS_S
}, KS_Scedilla
},
239 { { KS_dead_cedilla
, KS_s
}, KS_scedilla
},
240 { { KS_dead_cedilla
, KS_C
}, KS_Ccedilla
},
241 { { KS_dead_cedilla
, KS_T
}, KS_Tcedilla
},
242 { { KS_dead_cedilla
, KS_c
}, KS_ccedilla
},
243 { { KS_dead_cedilla
, KS_t
}, KS_tcedilla
},
244 { { KS_dead_circumflex
, KS_A
}, KS_Acircumflex
},
245 { { KS_dead_circumflex
, KS_I
}, KS_Icircumflex
},
246 { { KS_dead_circumflex
, KS_O
}, KS_Ocircumflex
},
247 { { KS_dead_circumflex
, KS_a
}, KS_acircumflex
},
248 { { KS_dead_circumflex
, KS_i
}, KS_icircumflex
},
249 { { KS_dead_circumflex
, KS_o
}, KS_ocircumflex
},
250 { { KS_dead_diaeresis
, KS_A
}, KS_Adiaeresis
},
251 { { KS_dead_diaeresis
, KS_E
}, KS_Ediaeresis
},
252 { { KS_dead_diaeresis
, KS_O
}, KS_Odiaeresis
},
253 { { KS_dead_diaeresis
, KS_U
}, KS_Udiaeresis
},
254 { { KS_dead_diaeresis
, KS_a
}, KS_adiaeresis
},
255 { { KS_dead_diaeresis
, KS_e
}, KS_ediaeresis
},
256 { { KS_dead_diaeresis
, KS_o
}, KS_odiaeresis
},
257 { { KS_dead_diaeresis
, KS_u
}, KS_udiaeresis
},
258 { { KS_dead_ogonek
, KS_A
}, KS_Aogonek
},
259 { { KS_dead_ogonek
, KS_a
}, KS_aogonek
},
260 { { KS_dead_ogonek
, KS_E
}, KS_Eogonek
},
261 { { KS_dead_ogonek
, KS_e
}, KS_eogonek
}
264 #define COMPOSE_SIZE sizeof(compose_tab)/sizeof(compose_tab[0])
266 static int compose_tab_inorder
= 0;
268 static inline int compose_tab_cmp(struct compose_tab_s
*, struct compose_tab_s
*);
269 static keysym_t
ksym_upcase(keysym_t
);
270 static void fillmapentry(const keysym_t
*, int, struct wscons_keymap
*);
273 compose_tab_cmp(struct compose_tab_s
*i
, struct compose_tab_s
*j
)
275 if (i
->elem
[0] == j
->elem
[0])
276 return(i
->elem
[1] - j
->elem
[1]);
278 return(i
->elem
[0] - j
->elem
[0]);
282 wskbd_compose_value(keysym_t
*compose_buf
)
285 struct compose_tab_s v
;
287 if (! compose_tab_inorder
) {
288 /* Insertion sort. */
289 for (i
= 1; i
< COMPOSE_SIZE
; i
++) {
291 /* find correct slot, moving others up */
292 for (j
= i
; --j
>= 0 && compose_tab_cmp(& v
, & compose_tab
[j
]) < 0; )
293 compose_tab
[j
+ 1] = compose_tab
[j
];
294 compose_tab
[j
+ 1] = v
;
296 compose_tab_inorder
= 1;
299 for (j
= 0, i
= COMPOSE_SIZE
; i
!= 0; i
/= 2) {
300 if (compose_tab
[j
+ i
/2].elem
[0] == compose_buf
[0]) {
301 if (compose_tab
[j
+ i
/2].elem
[1] == compose_buf
[1])
302 return(compose_tab
[j
+ i
/2].result
);
303 r
= compose_tab
[j
+ i
/2].elem
[1] < compose_buf
[1];
305 r
= compose_tab
[j
+ i
/2].elem
[0] < compose_buf
[0];
312 return(KS_voidSymbol
);
315 static const u_char latin1_to_upper
[256] = {
316 /* 0 8 1 9 2 a 3 b 4 c 5 d 6 e 7 f */
317 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0 */
318 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0 */
319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1 */
320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1 */
321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 2 */
322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 2 */
323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 3 */
324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 3 */
325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 4 */
326 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 4 */
327 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 5 */
328 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 5 */
329 0x00, 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* 6 */
330 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', /* 6 */
331 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 7 */
332 'X', 'Y', 'Z', 0x00, 0x00, 0x00, 0x00, 0x00, /* 7 */
333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8 */
334 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8 */
335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9 */
336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9 */
337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */
341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c */
342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c */
343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d */
344 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d */
345 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* e */
346 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* e */
347 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0x00, /* f */
348 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0x00, /* f */
352 ksym_upcase(keysym_t ksym
)
354 if (ksym
>= KS_f1
&& ksym
<= KS_f20
)
355 return(KS_F1
- KS_f1
+ ksym
);
357 if (KS_GROUP(ksym
) == KS_GROUP_Ascii
&& ksym
<= 0xff &&
358 latin1_to_upper
[ksym
] != 0x00)
359 return(latin1_to_upper
[ksym
]);
365 fillmapentry(const keysym_t
*kp
, int len
, struct wscons_keymap
*mapentry
)
369 mapentry
->group1
[0] = KS_voidSymbol
;
370 mapentry
->group1
[1] = KS_voidSymbol
;
371 mapentry
->group2
[0] = KS_voidSymbol
;
372 mapentry
->group2
[1] = KS_voidSymbol
;
376 mapentry
->group1
[0] = kp
[0];
377 mapentry
->group1
[1] = ksym_upcase(kp
[0]);
378 mapentry
->group2
[0] = mapentry
->group1
[0];
379 mapentry
->group2
[1] = mapentry
->group1
[1];
383 mapentry
->group1
[0] = kp
[0];
384 mapentry
->group1
[1] = kp
[1];
385 mapentry
->group2
[0] = mapentry
->group1
[0];
386 mapentry
->group2
[1] = mapentry
->group1
[1];
390 mapentry
->group1
[0] = kp
[0];
391 mapentry
->group1
[1] = kp
[1];
392 mapentry
->group2
[0] = kp
[2];
393 mapentry
->group2
[1] = ksym_upcase(kp
[2]);
397 mapentry
->group1
[0] = kp
[0];
398 mapentry
->group1
[1] = kp
[1];
399 mapentry
->group2
[0] = kp
[2];
400 mapentry
->group2
[1] = kp
[3];
407 wskbd_get_mapentry(const struct wskbd_mapdata
*mapdata
, int kc
,
408 struct wscons_keymap
*mapentry
)
412 const struct wscons_keydesc
*mp
;
415 mapentry
->command
= KS_voidSymbol
;
416 mapentry
->group1
[0] = KS_voidSymbol
;
417 mapentry
->group1
[1] = KS_voidSymbol
;
418 mapentry
->group2
[0] = KS_voidSymbol
;
419 mapentry
->group2
[1] = KS_voidSymbol
;
421 for (cur
= mapdata
->layout
& ~KB_HANDLEDBYWSKBD
; cur
!= 0; ) {
422 mp
= mapdata
->keydesc
;
423 while (mp
->map_size
> 0) {
429 /* If map not found, return */
430 if (mp
->map_size
<= 0)
433 for (kp
= mp
->map
; kp
< mp
->map
+ mp
->map_size
; kp
++)
434 if (KS_GROUP(*kp
) == KS_GROUP_Keycode
&&
435 KS_VALUE(*kp
) == kc
) {
436 /* First skip keycode and possible command */
438 if (KS_GROUP(*kp
) == KS_GROUP_Command
||
439 *kp
== KS_Cmd
|| *kp
== KS_Cmd1
|| *kp
== KS_Cmd2
)
440 mapentry
->command
= *kp
++;
442 for (l
= 0; kp
+ l
< mp
->map
+ mp
->map_size
; l
++)
443 if (KS_GROUP(kp
[l
]) == KS_GROUP_Keycode
)
446 panic("wskbd_get_mapentry: %d(%d): bad entry",
448 fillmapentry(kp
, l
, mapentry
);
457 wskbd_init_keymap(int newlen
, struct wscons_keymap
**map
, int *maplen
)
461 if (newlen
!= *maplen
) {
465 *map
= malloc(newlen
*sizeof(struct wscons_keymap
),
469 for (i
= 0; i
< *maplen
; i
++) {
470 (*map
)[i
].command
= KS_voidSymbol
;
471 (*map
)[i
].group1
[0] = KS_voidSymbol
;
472 (*map
)[i
].group1
[1] = KS_voidSymbol
;
473 (*map
)[i
].group2
[0] = KS_voidSymbol
;
474 (*map
)[i
].group2
[1] = KS_voidSymbol
;
479 wskbd_load_keymap(const struct wskbd_mapdata
*mapdata
,
480 struct wscons_keymap
**map
, int *maplen
)
482 int i
, s
, kc
, stack_ptr
;
484 const struct wscons_keydesc
*mp
, *stack
[10];
487 for (cur
= mapdata
->layout
& ~KB_HANDLEDBYWSKBD
, stack_ptr
= 0;
488 cur
!= 0; stack_ptr
++) {
489 mp
= mapdata
->keydesc
;
490 while (mp
->map_size
> 0) {
491 if (cur
== 0 || mp
->name
== cur
) {
497 if (stack_ptr
== sizeof(stack
)/sizeof(stack
[0]))
498 panic("wskbd_load_keymap: %d: recursion too deep",
500 if (mp
->map_size
<= 0)
503 stack
[stack_ptr
] = mp
;
507 for (i
= 0, s
= stack_ptr
- 1; s
>= 0; s
--) {
509 for (kp
= mp
->map
; kp
< mp
->map
+ mp
->map_size
; kp
++)
510 if (KS_GROUP(*kp
) == KS_GROUP_Keycode
&& KS_VALUE(*kp
) > i
)
514 wskbd_init_keymap(i
+ 1, map
, maplen
);
516 for (s
= stack_ptr
- 1; s
>= 0; s
--) {
518 for (kp
= mp
->map
; kp
< mp
->map
+ mp
->map_size
; ) {
519 if (KS_GROUP(*kp
) != KS_GROUP_Keycode
)
520 panic("wskbd_load_keymap: %d(%d): bad entry",
526 if (KS_GROUP(*kp
) == KS_GROUP_Command
||
527 *kp
== KS_Cmd
|| *kp
== KS_Cmd1
|| *kp
== KS_Cmd2
) {
528 (*map
)[kc
].command
= *kp
;
532 for (i
= 0; kp
+ i
< mp
->map
+ mp
->map_size
; i
++)
533 if (KS_GROUP(kp
[i
]) == KS_GROUP_Keycode
)
537 panic("wskbd_load_keymap: %d(%d): bad entry",
540 fillmapentry(kp
, i
, &(*map
)[kc
]);