7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 /*
30 * Generic keyboard support: translation
31 *
32 * This module is project private. Please see PSARC/1998/176 and
33 * PSARC/1998/026 for references to the kbtrans module.
34 *
35 * It is believed that it is safe to call these functions within debugger mode
36 * except kbtrans_dprintf. Debugger mode is a single threaded mode where most
37 * kernel services are not available, including memory allocation. Debugger
38 * mode is for kmdb and OBP debugging, where the debugger calls back into the
39 * kernel to obtain console input.
40 *
41 * Please be _very_ careful about what external functions you call.
42 */
43
44 #define KEYMAP_SIZE_VARIABLE
45
46 #include <sys/types.h>
47 #include <sys/cred.h>
48 #include <sys/ddi.h>
49 #include <sys/sunddi.h>
50 #include <sys/kmem.h>
51 #include <sys/kbd.h>
52 #include <sys/cmn_err.h>
53 #include <sys/modctl.h>
54 #include <sys/kbio.h>
55 #include <sys/vuid_event.h>
56 #include <sys/consdev.h>
57 #include <sys/kbtrans.h>
58 #include <sys/errno.h>
59 #include <sys/promif.h>
60 #include <sys/varargs.h>
61 #include "kbtrans_lower.h"
62
63 /*
64 * Internal Function Prototypes
65 */
66 static boolean_t kbtrans_do_compose(struct kbtrans_lower *, ushort_t,
67 ushort_t, ushort_t *);
68 static void kbtrans_translate(struct kbtrans_lower *,
69 struct keyboard_callback *, kbtrans_key_t,
70 enum keystate);
71 /*
72 * kbtrans_processkey:
73 *
74 * lower - state information used by the calling driver
75 * this parameter is passed back to the callback routines.
76 * key - scancode
77 * state - KEY_PRESSED / KEY_RELEASED
78 *
79 * This routine checks to see if there is a raw callback, and calls it
80 * if it exists. If there is no raw callback, the key is translated.
81 * The raw callback allows the driver that called the translation module
82 * to be passed untranslated scancodes.
83 */
84 void
85 kbtrans_processkey(struct kbtrans_lower *lower,
86 struct keyboard_callback *cb,
87 kbtrans_key_t key,
88 enum keystate state)
89 {
90 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (lower, "kbtrans_processkey: "
91 "newstate=%d key=%d", state, key));
92
93 /*
94 * If there is a raw routine, then call it and return.
95 */
96 if (cb->kc_keypressed_raw != NULL) {
97
98 if (state == KEY_PRESSED) {
99
100 cb->kc_keypressed_raw(lower->kbtrans_upper, key);
101 } else {
102
103 cb->kc_keyreleased_raw(lower->kbtrans_upper, key);
104 }
105
106 return;
107 }
108
109 /*
110 * translate the scancode into a key.
111 */
112 kbtrans_translate(lower, cb, key, state);
113 }
114
115
116 /*
117 * kbtrans_translate:
118 *
119 * lower - state information used by the calling driver
120 * this parameter is passed back to the callback routines.
121 * key - scan code
122 * state - KEY_PRESSED / KEY_RELEASED
123 *
124 * Called to process key events if we are in TR_ASCII or TR_EVENT
125 * (sunview) mode. This routine will call the appropriate translation_callback
126 * for the character when it is done translating it.
127 */
128 static void
129 kbtrans_translate(struct kbtrans_lower *lower,
130 struct keyboard_callback *cb,
131 kbtrans_key_t key,
132 enum keystate newstate)
133 {
134 unsigned shiftmask;
135 register ushort_t entry;
136 register ushort_t entrytype;
137 ushort_t result_iso;
138 unsigned short *ke;
139 int i;
140 boolean_t good_compose;
141
142 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (lower, "KEY TRANSLATE "
143 "newstate=0x%x key=0x%x\n", newstate, key));
144
145 if (lower->kbtrans_keyboard == NULL) {
146 /*
147 * Nobody has told us about this keyboard yet.
148 */
149 return;
150 }
151
152 /*
153 * Get the current state of the shiftmask
154 */
155 shiftmask = lower->kbtrans_shiftmask;
156
157 /*
158 * If the key has been released, then or in the UPMASK flag.
171 * This is a gross error. Cancel the repeat key and exit,
172 * we can not translate this scancode.
173 */
174 cb->kc_cancel_repeat(lower->kbtrans_upper);
175
176 return;
177 }
178
179 /*
180 * Get the key for this scancode.
181 */
182 entry = *ke;
183
184 if (entry == NONL) {
185 /*
186 * NONL appears only in the Num Lock table, and indicates that
187 * this key is not affected by Num Lock. This means we should
188 * ask for the table we would have gotten had Num Lock not been
189 * down, and translate using that table.
190 */
191 ke = kbtrans_find_entry(lower, shiftmask & ~NUMLOCKMASK,
192 key);
193
194 if (ke == NULL) {
195 /*
196 * This is a gross error. Cancel the repeat key and
197 * exit, we can not translate this scancode.
198 */
199 cb->kc_cancel_repeat(lower->kbtrans_upper);
200
201 return;
202 }
203
204 /*
205 * Get the new key for this scancode.
206 */
207 entry = *ke;
208 }
209
210 /*
211 * The entrytype indicates what category of key we are processing.
212 * Categories include shift keys, function keys, and numeric keypad
213 * keys.
214 */
215 entrytype = (ushort_t)(entry & 0xFF00);
216
217 if (entrytype == SHIFTKEYS) {
218 /*
219 * Handle the state of toggle shifts specially.
220 * Ups should be ignored, and downs should be mapped to ups if
221 * that shift is currently on.
222 */
223 if ((1 << (entry & 0x0F)) &
224 lower->kbtrans_keyboard->k_toggleshifts) {
225 if ((1 << (entry & 0x0F)) &
226 lower->kbtrans_togglemask) {
227 newstate = KEY_RELEASED; /* toggling off */
228 } else {
229 newstate = KEY_PRESSED; /* toggling on */
230 }
231 }
232 } else {
233 /*
234 * Handle Compose and floating accent key sequences
235 */
236 switch (lower->kbtrans_state) {
237 case COMPOSE1:
238 if (newstate == KEY_RELEASED)
239
240 return;
241
242 if (entry < ASCII_SET_SIZE) {
243 if (lower->kbtrans_compose_map[entry] >= 0) {
244 lower->kbtrans_compose_key = entry;
245 lower->kbtrans_state = COMPOSE2;
246
247 return;
248 }
249 }
250 lower->kbtrans_state = NORMAL;
251 lower->kbtrans_led_state &= ~LED_COMPOSE;
252
253 cb->kc_setled(lower->kbtrans_upper);
254
255 return;
256
257 case COMPOSE2:
258 if (newstate == KEY_RELEASED)
259 return;
260
261 /* next state is "normal" */
262 lower->kbtrans_state = NORMAL;
263 lower->kbtrans_led_state &= ~LED_COMPOSE;
264
265 cb->kc_setled(lower->kbtrans_upper);
266
267 good_compose = kbtrans_do_compose(lower,
268 lower->kbtrans_compose_key, entry,
269 &result_iso);
270 if (good_compose) {
271 if (lower->kbtrans_compat)
272 result_iso += ISO_FIRST;
273 else
274 result_iso += EUC_FIRST;
275 cb->kc_keypressed(lower->kbtrans_upper,
276 entrytype, key, result_iso);
277 }
278 return;
279
280 case FLTACCENT:
281 if (newstate == KEY_RELEASED)
282
283 return;
284
285 /* next state is "normal" */
286 lower->kbtrans_state = NORMAL;
287 for (i = 0;
288 (lower->kbtrans_fltaccent_table[i].fa_entry
289 != lower->kbtrans_fltaccent_entry) ||
290 (lower->kbtrans_fltaccent_table[i].ascii != entry);
291 i++) {
292 if (lower->kbtrans_fltaccent_table[i].fa_entry
293 == 0) {
294 /* Invalid second key: ignore key */
295
296 return;
297 }
298 }
299
300 cb->kc_keypressed(lower->kbtrans_upper, entrytype,
301 key, (lower->kbtrans_compat ?
302 ISO_FIRST : EUC_FIRST) +
303 lower->kbtrans_fltaccent_table[i].iso);
304
305 return;
306 }
307 }
308
309 /*
310 * If the key is going down, and it's not one of the keys that doesn't
311 * auto-repeat, set up the auto-repeat timeout.
312 *
313 * The keys that don't auto-repeat are the Compose key,
314 * the shift keys, the "bucky bit" keys, the "floating accent" keys,
315 * and the function keys when in TR_EVENT mode.
316 */
317 if (newstate == KEY_PRESSED && entrytype != SHIFTKEYS &&
318 entrytype != BUCKYBITS && entrytype != FUNNY &&
319 entrytype != FA_CLASS) {
320
321 if (lower->kbtrans_repeatkey != key) {
322 cb->kc_cancel_repeat(lower->kbtrans_upper);
323 cb->kc_setup_repeat(lower->kbtrans_upper, entrytype,
325 }
326 /* key going up */
327 } else if (key == lower->kbtrans_repeatkey) {
328
329 cb->kc_cancel_repeat(lower->kbtrans_upper);
330 }
331
332 if (newstate == KEY_RELEASED) {
333 cb->kc_keyreleased(lower->kbtrans_upper, key);
334 }
335
336 /*
337 * We assume here that keys other than shift keys and bucky keys have
338 * entries in the "up" table that cause nothing to be done, and thus we
339 * don't have to check for newstate == KEY_RELEASED.
340 */
341 switch (entrytype) {
342
343 case 0x0: /* regular key */
344 cb->kc_keypressed(lower->kbtrans_upper, entrytype, key,
345 entry | lower->kbtrans_buckybits);
346 break;
347
348 case SHIFTKEYS: {
349 uint_t shiftbit = 1 << (entry & 0x0F);
350
351 /* Modify toggle state (see toggle processing above) */
352 if (shiftbit & lower->kbtrans_keyboard->k_toggleshifts) {
353 if (newstate == KEY_RELEASED) {
354 if (shiftbit == CAPSMASK) {
355 lower->kbtrans_led_state &=
356 ~LED_CAPS_LOCK;
357
358 cb->kc_setled(lower->kbtrans_upper);
359
360 } else if (shiftbit == NUMLOCKMASK) {
361 lower->kbtrans_led_state &=
362 ~LED_NUM_LOCK;
363
364 cb->kc_setled(lower->kbtrans_upper);
365 }
377 cb->kc_setled(lower->kbtrans_upper);
378 }
379 lower->kbtrans_togglemask |= shiftbit;
380 }
381 }
382
383 if (newstate == KEY_RELEASED)
384 lower->kbtrans_shiftmask &= ~shiftbit;
385 else
386 lower->kbtrans_shiftmask |= shiftbit;
387
388 if (newstate == KEY_PRESSED) {
389 cb->kc_keypressed(lower->kbtrans_upper, entrytype, key,
390 entry);
391 }
392
393 break;
394 }
395
396 case BUCKYBITS:
397 lower->kbtrans_buckybits ^= 1 << (7 + (entry & 0x0F));
398
399 if (newstate == KEY_PRESSED) {
400 cb->kc_keypressed(lower->kbtrans_upper, entrytype, key,
401 entry);
402 }
403
404 break;
405
406 case FUNNY:
407 switch (entry) {
408 case NOP:
409 break;
410
411 case IDLE:
412 /* Fall thru into RESET code */
413 /* FALLTHRU */
414 case RESET:
415 case ERROR:
416 lower->kbtrans_shiftmask &=
417 lower->kbtrans_keyboard->k_idleshifts;
463 cb->kc_keypressed(lower->kbtrans_upper, entrytype, key, entry);
464
465 break;
466
467 /*
468 * Remember when adding new entries that,
469 * if they should NOT auto-repeat,
470 * they should be put into the IF statement
471 * just above this switch block.
472 */
473 case PADKEYS:
474 cb->kc_keypressed(lower->kbtrans_upper, entrytype, key, entry);
475
476 break;
477 }
478 }
479
480 /*
481 * kbtrans_do_compose:
482 * Given a two key compose sequence, lookup the iso equivalent and put
483 * the result in the result_iso_ptr.
484 */
485 static boolean_t
486 kbtrans_do_compose(struct kbtrans_lower *lower,
487 ushort_t first_entry,
488 ushort_t second_entry,
489 ushort_t *result_iso_ptr)
490 {
491 struct compose_sequence_t *ptr;
492 ushort_t tmp;
493
494 /*
495 * Validate the second keystroke.
496 */
497 if (second_entry >= ASCII_SET_SIZE)
498 return (B_FALSE);
499
500 if (lower->kbtrans_compose_map[second_entry] < 0)
501 return (B_FALSE);
502
503 /*
504 * Get them in code order, rather than press order.
505 */
506 if (first_entry > second_entry) {
507 tmp = first_entry;
508 first_entry = second_entry;
509 second_entry = tmp;
510 }
511
512 ptr = lower->kbtrans_compose_table +
513 lower->kbtrans_compose_map[first_entry];
514
515 while (ptr->first == first_entry) {
516 if (ptr->second == second_entry) {
517 *result_iso_ptr = ptr->iso;
518
519 return (B_TRUE);
520 }
521 ptr++;
522 }
523 return (B_FALSE);
524 }
525
526
527 /*
528 * kbtrans_find_entry:
529 * This routine finds the entry corresponding to the current shift
530 * state and keycode.
531 */
532 unsigned short *
533 kbtrans_find_entry(struct kbtrans_lower *lower,
534 register uint_t mask,
535 kbtrans_key_t key_station)
536 {
537 register struct keyboard *kp;
538 keymap_entry_t *km;
539 struct exception_map *ex;
540
541 kp = lower->kbtrans_keyboard;
542
543 if (kp == NULL)
544 return (NULL);
545
546 if (key_station < 0 || key_station >= kp->k_keymap_size)
547 return (NULL);
548
549 ex = kp->k_except;
550 if (ex != NULL) {
551 for (; ex->exc_care != 0; ex++) {
552 if ((mask & ex->exc_care) == ex->exc_mask &&
553 key_station == ex->exc_key)
554 return (&ex->exc_entry);
|
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Generic keyboard support: translation
29 *
30 * This module is project private. Please see PSARC/1998/176 and
31 * PSARC/1998/026 for references to the kbtrans module.
32 *
33 * It is believed that it is safe to call these functions within debugger mode
34 * except kbtrans_dprintf. Debugger mode is a single threaded mode where most
35 * kernel services are not available, including memory allocation. Debugger
36 * mode is for kmdb and OBP debugging, where the debugger calls back into the
37 * kernel to obtain console input.
38 *
39 * Please be _very_ careful about what external functions you call.
40 */
41
42 #define KEYMAP_SIZE_VARIABLE
43
44 #include <sys/types.h>
45 #include <sys/cred.h>
46 #include <sys/ddi.h>
47 #include <sys/sunddi.h>
48 #include <sys/kmem.h>
49 #include <sys/kbd.h>
50 #include <sys/cmn_err.h>
51 #include <sys/modctl.h>
52 #include <sys/kbio.h>
53 #include <sys/vuid_event.h>
54 #include <sys/consdev.h>
55 #include <sys/kbtrans.h>
56 #include <sys/errno.h>
57 #include <sys/promif.h>
58 #include <sys/varargs.h>
59 #include "kbtrans_lower.h"
60
61 /*
62 * Internal Function Prototypes
63 */
64 static boolean_t kbtrans_do_compose(struct kbtrans_lower *, keymap_entry_t,
65 keymap_entry_t, keymap_entry_t *);
66 static void kbtrans_translate(struct kbtrans_lower *,
67 struct keyboard_callback *, kbtrans_key_t, enum keystate);
68
69 /*
70 * kbtrans_processkey:
71 *
72 * lower - state information used by the calling driver
73 * this parameter is passed back to the callback routines.
74 * key - scancode
75 * state - KEY_PRESSED / KEY_RELEASED
76 *
77 * This routine checks to see if there is a raw callback, and calls it
78 * if it exists. If there is no raw callback, the key is translated.
79 * The raw callback allows the driver that called the translation module
80 * to be passed untranslated scancodes.
81 */
82 void
83 kbtrans_processkey(struct kbtrans_lower *lower,
84 struct keyboard_callback *cb, kbtrans_key_t key, enum keystate state)
85 {
86 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (lower, "kbtrans_processkey: "
87 "newstate=%d key=%d", state, key));
88
89 /*
90 * If there is a raw routine, then call it and return.
91 */
92 if (cb->kc_keypressed_raw != NULL) {
93
94 if (state == KEY_PRESSED) {
95
96 cb->kc_keypressed_raw(lower->kbtrans_upper, key);
97 } else {
98
99 cb->kc_keyreleased_raw(lower->kbtrans_upper, key);
100 }
101
102 return;
103 }
104
105 /*
106 * translate the scancode into a key.
107 */
108 kbtrans_translate(lower, cb, key, state);
109 }
110
111
112 /*
113 * kbtrans_translate:
114 *
115 * lower - state information used by the calling driver
116 * this parameter is passed back to the callback routines.
117 * key - scan code
118 * state - KEY_PRESSED / KEY_RELEASED
119 *
120 * Called to process key events if we are in TR_ASCII or TR_EVENT
121 * (sunview) mode. This routine will call the appropriate translation_callback
122 * for the character when it is done translating it.
123 */
124 static void
125 kbtrans_translate(struct kbtrans_lower *lower, struct keyboard_callback *cb,
126 kbtrans_key_t key, enum keystate newstate)
127 {
128 unsigned shiftmask;
129 register keymap_entry_t entry;
130 register unsigned entrytype;
131 keymap_entry_t result;
132 keymap_entry_t *ke;
133 int i;
134 boolean_t good_compose;
135
136 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (lower, "KEY TRANSLATE "
137 "newstate=0x%x key=0x%x\n", newstate, key));
138
139 if (lower->kbtrans_keyboard == NULL) {
140 /*
141 * Nobody has told us about this keyboard yet.
142 */
143 return;
144 }
145
146 /*
147 * Get the current state of the shiftmask
148 */
149 shiftmask = lower->kbtrans_shiftmask;
150
151 /*
152 * If the key has been released, then or in the UPMASK flag.
165 * This is a gross error. Cancel the repeat key and exit,
166 * we can not translate this scancode.
167 */
168 cb->kc_cancel_repeat(lower->kbtrans_upper);
169
170 return;
171 }
172
173 /*
174 * Get the key for this scancode.
175 */
176 entry = *ke;
177
178 if (entry == NONL) {
179 /*
180 * NONL appears only in the Num Lock table, and indicates that
181 * this key is not affected by Num Lock. This means we should
182 * ask for the table we would have gotten had Num Lock not been
183 * down, and translate using that table.
184 */
185 ke = kbtrans_find_entry(lower, shiftmask & ~NUMLOCKMASK, key);
186
187 if (ke == NULL) {
188 /*
189 * This is a gross error. Cancel the repeat key and
190 * exit, we can not translate this scancode.
191 */
192 cb->kc_cancel_repeat(lower->kbtrans_upper);
193
194 return;
195 }
196
197 /*
198 * Get the new key for this scancode.
199 */
200 entry = *ke;
201 }
202
203 /*
204 * The entrytype indicates what category of key we are processing.
205 * Categories include shift keys, function keys, and numeric keypad
206 * keys.
207 */
208 entrytype = KEYFLAGS(entry);
209
210 if (entrytype == SHIFTKEYS) {
211 /*
212 * Handle the state of toggle shifts specially.
213 * Ups should be ignored, and downs should be mapped to ups if
214 * that shift is currently on.
215 */
216 if ((1 << (entry & 0x0F)) &
217 lower->kbtrans_keyboard->k_toggleshifts) {
218 if ((1 << (entry & 0x0F)) & lower->kbtrans_togglemask) {
219 newstate = KEY_RELEASED; /* toggling off */
220 } else {
221 newstate = KEY_PRESSED; /* toggling on */
222 }
223 }
224 } else {
225 /*
226 * Handle Compose and floating accent key sequences
227 */
228 switch (lower->kbtrans_state) {
229 case COMPOSE1:
230 if (newstate == KEY_RELEASED)
231 return;
232
233 if (entry < ASCII_SET_SIZE) {
234 if (lower->kbtrans_compose_map[entry] >= 0) {
235 lower->kbtrans_compose_key = entry;
236 lower->kbtrans_state = COMPOSE2;
237
238 return;
239 }
240 }
241 lower->kbtrans_state = NORMAL;
242 lower->kbtrans_led_state &= ~LED_COMPOSE;
243
244 cb->kc_setled(lower->kbtrans_upper);
245
246 return;
247
248 case COMPOSE2:
249 if (newstate == KEY_RELEASED)
250 return;
251
252 /* next state is "normal" */
253 lower->kbtrans_state = NORMAL;
254 lower->kbtrans_led_state &= ~LED_COMPOSE;
255
256 cb->kc_setled(lower->kbtrans_upper);
257
258 good_compose = kbtrans_do_compose(lower,
259 lower->kbtrans_compose_key, entry, &result);
260 if (good_compose) {
261 cb->kc_keypressed(lower->kbtrans_upper,
262 entrytype, key, result);
263 }
264 return;
265
266 case FLTACCENT:
267 if (newstate == KEY_RELEASED)
268 return;
269
270 /* next state is "normal" */
271 lower->kbtrans_state = NORMAL;
272 for (i = 0;
273 (lower->kbtrans_fltaccent_table[i].fa_entry !=
274 lower->kbtrans_fltaccent_entry) ||
275 (lower->kbtrans_fltaccent_table[i].ascii != entry);
276 i++) {
277 if (lower->kbtrans_fltaccent_table[i].fa_entry
278 == 0) {
279 /* Invalid second key: ignore key */
280
281 return;
282 }
283 }
284
285 cb->kc_keypressed(lower->kbtrans_upper, entrytype, key,
286 lower->kbtrans_fltaccent_table[i].utf8);
287
288 return;
289 }
290 }
291
292 /*
293 * If the key is going down, and it's not one of the keys that doesn't
294 * auto-repeat, set up the auto-repeat timeout.
295 *
296 * The keys that don't auto-repeat are the Compose key,
297 * the shift keys, the "bucky bit" keys, the "floating accent" keys,
298 * and the function keys when in TR_EVENT mode.
299 */
300 if (newstate == KEY_PRESSED && entrytype != SHIFTKEYS &&
301 entrytype != BUCKYBITS && entrytype != FUNNY &&
302 entrytype != FA_CLASS) {
303
304 if (lower->kbtrans_repeatkey != key) {
305 cb->kc_cancel_repeat(lower->kbtrans_upper);
306 cb->kc_setup_repeat(lower->kbtrans_upper, entrytype,
308 }
309 /* key going up */
310 } else if (key == lower->kbtrans_repeatkey) {
311
312 cb->kc_cancel_repeat(lower->kbtrans_upper);
313 }
314
315 if (newstate == KEY_RELEASED) {
316 cb->kc_keyreleased(lower->kbtrans_upper, key);
317 }
318
319 /*
320 * We assume here that keys other than shift keys and bucky keys have
321 * entries in the "up" table that cause nothing to be done, and thus we
322 * don't have to check for newstate == KEY_RELEASED.
323 */
324 switch (entrytype) {
325
326 case 0x0: /* regular key */
327 cb->kc_keypressed(lower->kbtrans_upper, entrytype, key,
328 SPECIAL(lower->kbtrans_buckybits, entry));
329 break;
330
331 case SHIFTKEYS: {
332 uint_t shiftbit = 1 << (entry & 0x0F);
333
334 /* Modify toggle state (see toggle processing above) */
335 if (shiftbit & lower->kbtrans_keyboard->k_toggleshifts) {
336 if (newstate == KEY_RELEASED) {
337 if (shiftbit == CAPSMASK) {
338 lower->kbtrans_led_state &=
339 ~LED_CAPS_LOCK;
340
341 cb->kc_setled(lower->kbtrans_upper);
342
343 } else if (shiftbit == NUMLOCKMASK) {
344 lower->kbtrans_led_state &=
345 ~LED_NUM_LOCK;
346
347 cb->kc_setled(lower->kbtrans_upper);
348 }
360 cb->kc_setled(lower->kbtrans_upper);
361 }
362 lower->kbtrans_togglemask |= shiftbit;
363 }
364 }
365
366 if (newstate == KEY_RELEASED)
367 lower->kbtrans_shiftmask &= ~shiftbit;
368 else
369 lower->kbtrans_shiftmask |= shiftbit;
370
371 if (newstate == KEY_PRESSED) {
372 cb->kc_keypressed(lower->kbtrans_upper, entrytype, key,
373 entry);
374 }
375
376 break;
377 }
378
379 case BUCKYBITS:
380 lower->kbtrans_buckybits ^= 1 << (entry & 0x0F);
381
382 if (newstate == KEY_PRESSED) {
383 cb->kc_keypressed(lower->kbtrans_upper, entrytype, key,
384 entry);
385 }
386
387 break;
388
389 case FUNNY:
390 switch (entry) {
391 case NOP:
392 break;
393
394 case IDLE:
395 /* Fall thru into RESET code */
396 /* FALLTHRU */
397 case RESET:
398 case ERROR:
399 lower->kbtrans_shiftmask &=
400 lower->kbtrans_keyboard->k_idleshifts;
446 cb->kc_keypressed(lower->kbtrans_upper, entrytype, key, entry);
447
448 break;
449
450 /*
451 * Remember when adding new entries that,
452 * if they should NOT auto-repeat,
453 * they should be put into the IF statement
454 * just above this switch block.
455 */
456 case PADKEYS:
457 cb->kc_keypressed(lower->kbtrans_upper, entrytype, key, entry);
458
459 break;
460 }
461 }
462
463 /*
464 * kbtrans_do_compose:
465 * Given a two key compose sequence, lookup the iso equivalent and put
466 * the result in the result_ptr.
467 */
468 static boolean_t
469 kbtrans_do_compose(struct kbtrans_lower *lower, keymap_entry_t first_entry,
470 keymap_entry_t second_entry, keymap_entry_t *result_ptr)
471 {
472 struct compose_sequence_t *ptr;
473 keymap_entry_t tmp;
474
475 /*
476 * Validate the second keystroke.
477 */
478 if (second_entry >= ASCII_SET_SIZE)
479 return (B_FALSE);
480
481 if (lower->kbtrans_compose_map[second_entry] < 0)
482 return (B_FALSE);
483
484 /*
485 * Get them in code order, rather than press order.
486 */
487 if (first_entry > second_entry) {
488 tmp = first_entry;
489 first_entry = second_entry;
490 second_entry = tmp;
491 }
492
493 ptr = lower->kbtrans_compose_table +
494 lower->kbtrans_compose_map[first_entry];
495
496 while (ptr->first == first_entry) {
497 if (ptr->second == second_entry) {
498 *result_ptr = ptr->utf8;
499
500 return (B_TRUE);
501 }
502 ptr++;
503 }
504 return (B_FALSE);
505 }
506
507
508 /*
509 * kbtrans_find_entry:
510 * This routine finds the entry corresponding to the current shift
511 * state and keycode.
512 */
513 keymap_entry_t *
514 kbtrans_find_entry(struct kbtrans_lower *lower, uint_t mask,
515 kbtrans_key_t key_station)
516 {
517 register struct keyboard *kp;
518 keymap_entry_t *km;
519 struct exception_map *ex;
520
521 kp = lower->kbtrans_keyboard;
522
523 if (kp == NULL)
524 return (NULL);
525
526 if (key_station < 0 || key_station >= kp->k_keymap_size)
527 return (NULL);
528
529 ex = kp->k_except;
530 if (ex != NULL) {
531 for (; ex->exc_care != 0; ex++) {
532 if ((mask & ex->exc_care) == ex->exc_mask &&
533 key_station == ex->exc_key)
534 return (&ex->exc_entry);
|