Print this page
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
loader: pxe receive cleanup
9475 libefi: Do not return only if ReceiveFilter
installboot: should support efi system partition
8931 boot1.efi: scan all display modes rather than
loader: spinconsole updates
loader: gfx experiment to try GOP Blt() function.
sha1 build test
loader: add sha1 hash calculation
common/sha1: update for loader build
loader: biosdisk rework
uts: 32-bit kernel FB needs mapping in low memory
uts: add diag-device
uts: boot console mirror with diag-device
uts: enable very early console on ttya
kmdb: add diag-device as input/output device
uts: test VGA memory exclusion from mapping
uts: clear boot mapping and protect boot pages test
uts: add dboot map debug printf
uts: need to release FB pages in release_bootstrap()
uts: add screenmap ioctl
uts: update sys/queue.h
loader: add illumos uts/common to include path
loader: tem/gfx font cleanup
loader: vbe checks
uts: gfx_private set KD_TEXT when KD_RESETTEXT is
uts: gfx 8-bit update
loader: gfx 8-bit fix
loader: always set media size from partition.
uts: MB2 support for 32-bit kernel
loader: x86 should have tem 80x25
uts: x86 should have tem 80x25
uts: font update
loader: font update
uts: tem attributes
loader: tem.c comment added
uts: use font module
loader: add font module
loader: build rules for new font setup
uts: gfx_private update for new font structure
uts: early boot update for new font structure
uts: font update
uts: font build rules update for new fonts
uts: tem update to new font structure
loader: module.c needs to include tem_impl.h
uts: gfx_private 8x16 font rework
uts: make font_lookup public
loader: font rework
uts: font rework
9259 libefi: efi_alloc_and_read should check for PMBR
uts: tem utf-8 support
loader: implement tem utf-8 support
loader: tem should be able to display UTF-8
7784 uts: console input should support utf-8
7796 uts: ldterm default to utf-8
uts: do not reset serial console
uts: set up colors even if tem is not console
uts: add type for early boot properties
uts: gfx_private experiment with drm and vga
uts: gfx_private should use setmode drm callback.
uts: identify FB types and set up gfx_private based
loader: replace gop and vesa with framebuffer
uts: boot needs simple tem to support mdb
uts: boot_keyboard should emit esc sequences for
uts: gfx_private FB showuld be written by line
kmdb: set terminal window size
uts: gfx_private needs to keep track of early boot FB
pnglite: move pnglite to usr/src/common
loader: gfx_fb
ficl-sys: add gfx primitives
loader: add illumos.png logo
ficl: add fb-putimage
loader: add png support
loader: add alpha blending for gfx_fb
loader: use term-drawrect for menu frame
ficl: add simple gfx words
uts: provide fb_info via fbgattr dev_specific array.
uts: gfx_private add alpha blending
uts: update sys/ascii.h
uts: tem OSC support (incomplete)
uts: implement env module support and use data from
uts: tem get colors from early boot data
loader: use crc32 from libstand (libz)
loader: optimize for size
loader: pass tem info to the environment
loader: import tem for loader console
loader: UEFI loader needs to set ISADIR based on
loader: need UEFI32 support
8918 loader.efi: add vesa edid support
uts: tem_safe_pix_clear_prom_output() should only
uts: tem_safe_pix_clear_entire_screen() should use
uts: tem_safe_check_first_time() should query cursor
uts: tem implement cls callback & visual_io v4
uts: gfx_vgatext use block cursor for vgatext
uts: gfx_private implement cls callback & visual_io
uts: gfx_private bitmap framebuffer implementation
uts: early start frame buffer console support
uts: font functions should check the input char
uts: font rendering should support 16/24/32bit depths
uts: use smallest font as fallback default.
uts: update terminal dimensions based on selected
7834 uts: vgatext should use gfx_private
uts: add spacing property to 8859-1.bdf
terminfo: add underline for sun-color
terminfo: sun-color has 16 colors
uts: add font load callback type
loader: do not repeat int13 calls with error 0x20 and
8905 loader: add skein/edonr support
8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Revert "NEX-16819 loader UEFI support"
This reverts commit ec06b9fc617b99234e538bf2e7e4d02a24993e0c.
Reverting due to failures in the zfs-tests and the sharefs-tests
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
loader: pxe receive cleanup
9475 libefi: Do not return only if ReceiveFilter
installboot: should support efi system partition
8931 boot1.efi: scan all display modes rather than
loader: spinconsole updates
loader: gfx experiment to try GOP Blt() function.
sha1 build test
loader: add sha1 hash calculation
common/sha1: update for loader build
loader: biosdisk rework
uts: 32-bit kernel FB needs mapping in low memory
uts: add diag-device
uts: boot console mirror with diag-device
uts: enable very early console on ttya
kmdb: add diag-device as input/output device
uts: test VGA memory exclusion from mapping
uts: clear boot mapping and protect boot pages test
uts: add dboot map debug printf
uts: need to release FB pages in release_bootstrap()
uts: add screenmap ioctl
uts: update sys/queue.h
loader: add illumos uts/common to include path
loader: tem/gfx font cleanup
loader: vbe checks
uts: gfx_private set KD_TEXT when KD_RESETTEXT is
uts: gfx 8-bit update
loader: gfx 8-bit fix
loader: always set media size from partition.
uts: MB2 support for 32-bit kernel
loader: x86 should have tem 80x25
uts: x86 should have tem 80x25
uts: font update
loader: font update
uts: tem attributes
loader: tem.c comment added
uts: use font module
loader: add font module
loader: build rules for new font setup
uts: gfx_private update for new font structure
uts: early boot update for new font structure
uts: font update
uts: font build rules update for new fonts
uts: tem update to new font structure
loader: module.c needs to include tem_impl.h
uts: gfx_private 8x16 font rework
uts: make font_lookup public
loader: font rework
uts: font rework
libefi: efi_alloc_and_read should check for PMBR
uts: tem utf-8 support
loader: implement tem utf-8 support
loader: tem should be able to display UTF-8
7784 uts: console input should support utf-8
7796 uts: ldterm default to utf-8
uts: do not reset serial console
uts: set up colors even if tem is not console
uts: add type for early boot properties
uts: gfx_private experiment with drm and vga
uts: gfx_private should use setmode drm callback.
uts: identify FB types and set up gfx_private based
loader: replace gop and vesa with framebuffer
uts: boot needs simple tem to support mdb
uts: boot_keyboard should emit esc sequences for
uts: gfx_private FB showuld be written by line
kmdb: set terminal window size
uts: gfx_private needs to keep track of early boot FB
pnglite: move pnglite to usr/src/common
loader: gfx_fb
ficl-sys: add gfx primitives
loader: add illumos.png logo
ficl: add fb-putimage
loader: add png support
loader: add alpha blending for gfx_fb
loader: use term-drawrect for menu frame
ficl: add simple gfx words
uts: provide fb_info via fbgattr dev_specific array.
uts: gfx_private add alpha blending
uts: update sys/ascii.h
uts: tem OSC support (incomplete)
uts: implement env module support and use data from
uts: tem get colors from early boot data
loader: use crc32 from libstand (libz)
loader: optimize for size
loader: pass tem info to the environment
loader: import tem for loader console
loader: UEFI loader needs to set ISADIR based on
loader: need UEFI32 support
8918 loader.efi: add vesa edid support
uts: tem_safe_pix_clear_prom_output() should only
uts: tem_safe_pix_clear_entire_screen() should use
uts: tem_safe_check_first_time() should query cursor
uts: tem implement cls callback & visual_io v4
uts: gfx_vgatext use block cursor for vgatext
uts: gfx_private implement cls callback & visual_io
uts: gfx_private bitmap framebuffer implementation
uts: early start frame buffer console support
uts: font functions should check the input char
uts: font rendering should support 16/24/32bit depths
uts: use smallest font as fallback default.
uts: update terminal dimensions based on selected
7834 uts: vgatext should use gfx_private
uts: add spacing property to 8859-1.bdf
terminfo: add underline for sun-color
terminfo: sun-color has 16 colors
uts: add font load callback type
loader: do not repeat int13 calls with error 0x20 and
8905 loader: add skein/edonr support
8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/io/kbtrans/kbtrans_streams.c
+++ new/usr/src/uts/common/io/kbtrans/kbtrans_streams.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27 /*
28 28 * Generic keyboard support: streams and administration.
29 29 */
30 30
31 31 #define KEYMAP_SIZE_VARIABLE
32 32
33 33 #include <sys/types.h>
34 34 #include <sys/cred.h>
35 35 #include <sys/stream.h>
36 36 #include <sys/stropts.h>
37 37 #include <sys/strsun.h>
38 38 #include <sys/ddi.h>
39 39 #include <sys/vuid_event.h>
40 40 #include <sys/modctl.h>
41 41 #include <sys/errno.h>
42 42 #include <sys/kmem.h>
43 43 #include <sys/cmn_err.h>
44 44 #include <sys/kbd.h>
45 45 #include <sys/kbio.h>
46 46 #include <sys/consdev.h>
47 47 #include <sys/kbtrans.h>
48 48 #include <sys/policy.h>
49 49 #include <sys/sunldi.h>
50 50 #include <sys/class.h>
51 51 #include <sys/spl.h>
52 52 #include "kbtrans_lower.h"
53 53 #include "kbtrans_streams.h"
54 54
55 55 #ifdef DEBUG
56 56 int kbtrans_errmask;
57 57 int kbtrans_errlevel;
58 58 #endif
59 59
60 60 #define KB_NR_FUNCKEYS 12
61 61
62 62 /*
63 63 * Repeat rates set in static variables so they can be tweeked with
64 64 * debugger.
65 65 */
66 66 static int kbtrans_repeat_rate;
67 67 static int kbtrans_repeat_delay;
68 68
69 69 /* Printing message on q overflow */
70 70 static int kbtrans_overflow_msg = 1;
71 71
72 72 /*
73 73 * This value corresponds approximately to max 10 fingers
74 74 */
75 75 static int kbtrans_downs_size = 15;
76 76
77 77 /*
78 78 * modload support
79 79 */
80 80 extern struct mod_ops mod_miscops;
81 81
82 82 static struct modlmisc modlmisc = {
83 83 &mod_miscops, /* Type of module */
84 84 "kbtrans (key translation)"
85 85 };
86 86
87 87 static struct modlinkage modlinkage = {
88 88 MODREV_1, (void *)&modlmisc, NULL
89 89 };
90 90
91 91 int
92 92 _init(void)
93 93 {
94 94 return (mod_install(&modlinkage));
95 95 }
96 96
97 97 int
98 98 _fini(void)
99 99 {
100 100 return (mod_remove(&modlinkage));
101 101 }
102 102
103 103 int
104 104 _info(struct modinfo *modinfop)
105 105 {
106 106 return (mod_info(&modlinkage, modinfop));
107 107 }
108 108
109 109 /*
110 110 * Internal Function Prototypes
111 111 */
112 112 static char *kbtrans_strsetwithdecimal(char *, uint_t, uint_t);
113 113 static void kbtrans_set_translation_callback(struct kbtrans *);
114 114 static void kbtrans_reioctl(void *);
115 115 static void kbtrans_send_esc_event(char, struct kbtrans *);
116 116 static void kbtrans_keypressed(struct kbtrans *, uchar_t, Firm_event *,
117 117 ushort_t);
118 118 static void kbtrans_putbuf(char *, queue_t *);
119 119 static void kbtrans_cancelrpt(struct kbtrans *);
120 120 static void kbtrans_queuepress(struct kbtrans *, uchar_t, Firm_event *);
121 121 static void kbtrans_putcode(register struct kbtrans *, uint_t);
122 122 static void kbtrans_keyreleased(struct kbtrans *, uchar_t);
123 123 static void kbtrans_queueevent(struct kbtrans *, Firm_event *);
124 124 static void kbtrans_untrans_keypressed_raw(struct kbtrans *, kbtrans_key_t);
125 125 static void kbtrans_untrans_keyreleased_raw(struct kbtrans *,
126 126 kbtrans_key_t);
127 127 static void kbtrans_ascii_keypressed(struct kbtrans *, uint_t,
128 128 kbtrans_key_t, uint_t);
129 129 static void kbtrans_ascii_keyreleased(struct kbtrans *, kbtrans_key_t);
130 130 static void kbtrans_ascii_setup_repeat(struct kbtrans *, uint_t,
131 131 kbtrans_key_t);
132 132 static void kbtrans_trans_event_keypressed(struct kbtrans *, uint_t,
133 133 kbtrans_key_t, uint_t);
134 134 static void kbtrans_trans_event_keyreleased(struct kbtrans *,
135 135 kbtrans_key_t);
136 136 static void kbtrans_trans_event_setup_repeat(struct kbtrans *, uint_t,
137 137 kbtrans_key_t);
138 138 static void kbtrans_rpt(void *);
139 139 static void kbtrans_setled(struct kbtrans *);
140 140 static void kbtrans_flush(struct kbtrans *);
141 141 static enum kbtrans_message_response kbtrans_ioctl(struct kbtrans *upper,
142 142 mblk_t *mp);
143 143 static int kbtrans_setkey(struct kbtrans_lower *, struct kiockey *,
144 144 cred_t *);
145 145 static int kbtrans_getkey(struct kbtrans_lower *, struct kiockey *);
146 146 static int kbtrans_skey(struct kbtrans_lower *, struct kiockeymap *,
147 147 cred_t *cr);
148 148 static int kbtrans_gkey(struct kbtrans_lower *, struct kiockeymap *);
149 149
150 150 /*
151 151 * Keyboard Translation Mode (TR_NONE)
152 152 *
153 153 * Functions to be called when keyboard translation is turned off
154 154 * and up/down key codes are reported.
155 155 */
156 156 struct keyboard_callback untrans_event_callback = {
157 157 kbtrans_untrans_keypressed_raw,
158 158 kbtrans_untrans_keyreleased_raw,
159 159 NULL,
160 160 NULL,
161 161 NULL,
162 162 NULL,
163 163 NULL,
164 164 };
165 165
166 166 /*
167 167 * Keyboard Translation Mode (TR_ASCII)
168 168 *
169 169 * Functions to be called when ISO 8859/1 codes are reported
170 170 */
171 171 struct keyboard_callback ascii_callback = {
172 172 NULL,
173 173 NULL,
174 174 kbtrans_ascii_keypressed,
175 175 kbtrans_ascii_keyreleased,
176 176 kbtrans_ascii_setup_repeat,
177 177 kbtrans_cancelrpt,
178 178 kbtrans_setled,
179 179 };
180 180
181 181 /*
182 182 * Keyboard Translation Mode (TR_EVENT)
183 183 *
184 184 * Functions to be called when firm_events are reported.
185 185 */
186 186 struct keyboard_callback trans_event_callback = {
187 187 NULL,
188 188 NULL,
189 189 kbtrans_trans_event_keypressed,
190 190 kbtrans_trans_event_keyreleased,
191 191 kbtrans_trans_event_setup_repeat,
192 192 kbtrans_cancelrpt,
193 193 kbtrans_setled,
194 194 };
195 195
196 196 static void
197 197 progressbar_key_abort_thread(struct kbtrans *upper)
198 198 {
199 199 ldi_ident_t li;
200 200 extern void progressbar_key_abort(ldi_ident_t);
201 201
202 202 if (ldi_ident_from_stream(upper->kbtrans_streams_readq, &li) != 0) {
203 203 cmn_err(CE_NOTE, "!ldi_ident_from_stream failed");
204 204 } else {
205 205 mutex_enter(&upper->progressbar_key_abort_lock);
206 206 while (upper->progressbar_key_abort_flag == 0)
207 207 cv_wait(&upper->progressbar_key_abort_cv,
208 208 &upper->progressbar_key_abort_lock);
209 209 if (upper->progressbar_key_abort_flag == 1) {
210 210 mutex_exit(&upper->progressbar_key_abort_lock);
211 211 progressbar_key_abort(li);
212 212 } else {
213 213 mutex_exit(&upper->progressbar_key_abort_lock);
214 214 }
215 215 ldi_ident_release(li);
216 216 }
217 217
218 218 thread_exit();
219 219 }
220 220
221 221 /*
222 222 * kbtrans_streams_init:
223 223 * Initialize the stream, keytables, callbacks, etc.
224 224 */
225 225 int
226 226 kbtrans_streams_init(
227 227 queue_t *q,
228 228 int sflag,
229 229 struct kbtrans_hardware *hw,
230 230 struct kbtrans_callbacks *hw_cb,
231 231 struct kbtrans **ret_kbd,
232 232 int initial_leds,
233 233 int initial_led_mask)
234 234 {
235 235 struct kbtrans *upper;
236 236 struct kbtrans_lower *lower;
237 237 kthread_t *tid;
238 238
239 239 /*
240 240 * Default to relatively generic tables.
241 241 */
242 242 extern signed char kb_compose_map[];
243 243 extern struct compose_sequence_t kb_compose_table[];
244 244 extern struct fltaccent_sequence_t kb_fltaccent_table[];
245 245 extern char keystringtab[][KTAB_STRLEN];
246 246 extern unsigned char kb_numlock_table[];
247 247
248 248 /* Set these up only once so that they could be changed from adb */
249 249 if (!kbtrans_repeat_rate) {
250 250 kbtrans_repeat_rate = (hz+29)/30;
251 251 kbtrans_repeat_delay = hz/2;
252 252 }
253 253
254 254 switch (sflag) {
255 255
256 256 case MODOPEN:
257 257 break;
258 258
259 259 case CLONEOPEN:
260 260 DPRINTF(PRINT_L1, PRINT_MASK_OPEN, (NULL,
261 261 "kbtrans_streams_init: Clone open not supported"));
262 262
263 263 return (EINVAL);
264 264 }
265 265
266 266 /* allocate keyboard state structure */
267 267 upper = kmem_zalloc(sizeof (struct kbtrans), KM_SLEEP);
268 268
269 269 *ret_kbd = upper;
270 270
271 271 upper->kbtrans_polled_buf[0] = '\0';
272 272 upper->kbtrans_polled_pending_chars = upper->kbtrans_polled_buf;
273 273
274 274 upper->kbtrans_streams_hw = hw;
275 275 upper->kbtrans_streams_hw_callbacks = hw_cb;
276 276 upper->kbtrans_streams_readq = q;
277 277 upper->kbtrans_streams_iocpending = NULL;
278 278 upper->kbtrans_streams_translatable = TR_CAN;
279 279 upper->kbtrans_overflow_cnt = 0;
280 280 upper->kbtrans_streams_translate_mode = TR_ASCII;
281 281
282 282 /* Set the translation callback based on the translation type */
283 283 kbtrans_set_translation_callback(upper);
284 284
285 285 lower = &upper->kbtrans_lower;
286 286
287 287 /*
288 288 * Set defaults for relatively generic tables.
289 289 */
290 290 lower->kbtrans_compose_map = kb_compose_map;
291 291 lower->kbtrans_compose_table = kb_compose_table;
292 292 lower->kbtrans_fltaccent_table = kb_fltaccent_table;
293 293 lower->kbtrans_numlock_table = kb_numlock_table;
294 294 lower->kbtrans_keystringtab = keystringtab;
295 295
296 296 lower->kbtrans_upper = upper;
297 297 lower->kbtrans_compat = 1;
298 298
299 299 /*
300 300 * We have a generic default for the LED state, and let the
301 301 * hardware-specific driver supply overrides.
302 302 */
303 303 lower->kbtrans_led_state = 0;
304 304 lower->kbtrans_led_state &= ~initial_led_mask;
305 305 lower->kbtrans_led_state |= initial_leds;
306 306 lower->kbtrans_togglemask = 0;
307 307
308 308 if (lower->kbtrans_led_state & LED_CAPS_LOCK)
309 309 lower->kbtrans_togglemask |= CAPSMASK;
310 310 if (lower->kbtrans_led_state & LED_NUM_LOCK)
311 311 lower->kbtrans_togglemask |= NUMLOCKMASK;
312 312
313 313 #if defined(SCROLLMASK)
314 314 if (lower->kbtrans_led_state & LED_SCROLL_LOCK)
315 315 lower->kbtrans_togglemask |= SCROLLMASK;
316 316 #endif
317 317
318 318 lower->kbtrans_shiftmask = lower->kbtrans_togglemask;
319 319
320 320 upper->kbtrans_streams_vuid_addr.ascii = ASCII_FIRST;
321 321 upper->kbtrans_streams_vuid_addr.top = TOP_FIRST;
322 322 upper->kbtrans_streams_vuid_addr.vkey = VKEY_FIRST;
323 323
324 324 /* Allocate dynamic memory for downs table */
325 325 upper->kbtrans_streams_num_downs_entries = kbtrans_downs_size;
326 326 upper->kbtrans_streams_downs_bytes =
327 327 (uint32_t)(kbtrans_downs_size * sizeof (Key_event));
328 328 upper->kbtrans_streams_downs =
329 329 kmem_zalloc(upper->kbtrans_streams_downs_bytes, KM_SLEEP);
330 330 upper->kbtrans_streams_abortable = B_FALSE;
331 331
332 332 upper->kbtrans_streams_flags = KBTRANS_STREAMS_OPEN;
333 333
334 334 upper->progressbar_key_abort_flag = 0;
335 335 cv_init(&upper->progressbar_key_abort_cv, NULL, CV_DEFAULT, NULL);
336 336 /* this counts on no keyboards being above ipl 12 */
337 337 mutex_init(&upper->progressbar_key_abort_lock, NULL, MUTEX_SPIN,
338 338 (void *)ipltospl(12));
339 339 tid = thread_create(NULL, 0, progressbar_key_abort_thread, upper,
340 340 0, &p0, TS_RUN, minclsyspri);
341 341 upper->progressbar_key_abort_t_did = tid->t_did;
342 342
343 343 DPRINTF(PRINT_L1, PRINT_MASK_OPEN, (upper, "kbtrans_streams_init "
344 344 "exiting"));
345 345 return (0);
346 346 }
347 347
348 348
349 349 /*
350 350 * kbtrans_streams_fini:
351 351 * Free structures and uninitialize the stream
352 352 */
353 353 int
354 354 kbtrans_streams_fini(struct kbtrans *upper)
355 355 {
356 356 /*
357 357 * Since we're about to destroy our private data, turn off
358 358 * our open flag first, so we don't accept any more input
359 359 * and try to use that data.
360 360 */
361 361 upper->kbtrans_streams_flags = 0;
362 362
363 363 /* clear all timeouts */
364 364 if (upper->kbtrans_streams_bufcallid) {
365 365 qunbufcall(upper->kbtrans_streams_readq,
366 366 upper->kbtrans_streams_bufcallid);
367 367 }
368 368 if (upper->kbtrans_streams_rptid) {
369 369 (void) quntimeout(upper->kbtrans_streams_readq,
370 370 upper->kbtrans_streams_rptid);
371 371 }
372 372 kmem_free(upper->kbtrans_streams_downs,
373 373 upper->kbtrans_streams_downs_bytes);
374 374
375 375 mutex_enter(&upper->progressbar_key_abort_lock);
376 376 if (upper->progressbar_key_abort_flag == 0) {
377 377 upper->progressbar_key_abort_flag = 2;
378 378 cv_signal(&upper->progressbar_key_abort_cv);
379 379 mutex_exit(&upper->progressbar_key_abort_lock);
380 380 thread_join(upper->progressbar_key_abort_t_did);
381 381 } else {
382 382 mutex_exit(&upper->progressbar_key_abort_lock);
383 383 }
384 384 cv_destroy(&upper->progressbar_key_abort_cv);
385 385 mutex_destroy(&upper->progressbar_key_abort_lock);
386 386
387 387 kmem_free(upper, sizeof (struct kbtrans));
388 388
389 389 DPRINTF(PRINT_L1, PRINT_MASK_CLOSE, (upper, "kbtrans_streams_fini "
390 390 "exiting"));
391 391 return (0);
392 392 }
393 393
394 394 /*
395 395 * kbtrans_streams_releaseall :
396 396 * This function releases all the held keys.
397 397 */
398 398 void
399 399 kbtrans_streams_releaseall(struct kbtrans *upper)
400 400 {
401 401 register struct key_event *ke;
402 402 register int i;
403 403
404 404 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (NULL, "USBKBM RELEASE ALL\n"));
405 405
406 406 /* Scan table of down key stations */
407 407 for (i = 0, ke = upper->kbtrans_streams_downs;
408 408 i < upper->kbtrans_streams_num_downs_entries; i++, ke++) {
409 409
410 410 /* Key station not zero */
411 411 if (ke->key_station) {
412 412
413 413 kbtrans_keyreleased(upper, ke->key_station);
414 414 /* kbtrans_keyreleased resets downs entry */
415 415 }
416 416 }
417 417 }
418 418
419 419 /*
420 420 * kbtrans_streams_message:
421 421 * keyboard module output queue put procedure: handles M_IOCTL
422 422 * messages.
423 423 *
424 424 * Return KBTRANS_MESSAGE_HANDLED if the message was handled by
425 425 * kbtrans and KBTRANS_MESSAGE_NOT_HANDLED otherwise. If
426 426 * KBTRANS_MESSAGE_HANDLED is returned, no further action is required.
427 427 * If KBTRANS_MESSAGE_NOT_HANDLED is returned, the hardware module
428 428 * is responsible for any action.
429 429 */
430 430 enum kbtrans_message_response
431 431 kbtrans_streams_message(struct kbtrans *upper, register mblk_t *mp)
432 432 {
433 433 queue_t *q = upper->kbtrans_streams_readq;
434 434 enum kbtrans_message_response ret;
435 435
436 436 DPRINTF(PRINT_L1, PRINT_MASK_ALL, (upper,
437 437 "kbtrans_streams_message entering"));
438 438 /*
439 439 * Process M_FLUSH, and some M_IOCTL, messages here; pass
440 440 * everything else down.
441 441 */
442 442 switch (mp->b_datap->db_type) {
443 443
444 444 case M_IOCTL:
445 445 ret = kbtrans_ioctl(upper, mp);
446 446 break;
447 447
448 448 case M_FLUSH:
449 449 if (*mp->b_rptr & FLUSHW)
450 450 flushq(q, FLUSHDATA);
451 451 if (*mp->b_rptr & FLUSHR)
452 452 flushq(RD(q), FLUSHDATA);
453 453 /*
454 454 * White lie: we say we didn't handle the message,
455 455 * so that it gets handled by our client.
456 456 */
457 457 ret = KBTRANS_MESSAGE_NOT_HANDLED;
458 458 break;
459 459
460 460 default:
461 461 ret = KBTRANS_MESSAGE_NOT_HANDLED;
462 462 break;
463 463
464 464 }
465 465 DPRINTF(PRINT_L1, PRINT_MASK_ALL, (upper,
466 466 "kbtrans_streams_message exiting\n"));
467 467
468 468 return (ret);
469 469 }
470 470
471 471 /*
472 472 * kbtrans_streams_key:
473 473 * When a key is pressed or released, the hardware module should
474 474 * call kbtrans, passing the key number and its new
475 475 * state. kbtrans is responsible for autorepeat handling;
476 476 * the hardware module should report only actual press/release
477 477 * events, suppressing any hardware-generated autorepeat.
478 478 */
479 479 void
480 480 kbtrans_streams_key(
481 481 struct kbtrans *upper,
482 482 kbtrans_key_t key,
483 483 enum keystate state)
484 484 {
485 485 struct kbtrans_lower *lower;
486 486 struct keyboard *kp;
487 487
488 488 lower = &upper->kbtrans_lower;
489 489 kp = lower->kbtrans_keyboard;
490 490
491 491 /* trigger switch back to text mode */
492 492 mutex_enter(&upper->progressbar_key_abort_lock);
493 493 if (upper->progressbar_key_abort_flag == 0) {
494 494 upper->progressbar_key_abort_flag = 1;
495 495 cv_signal(&upper->progressbar_key_abort_cv);
496 496 }
497 497 mutex_exit(&upper->progressbar_key_abort_lock);
498 498
499 499 if (upper->kbtrans_streams_abortable) {
500 500 switch (upper->kbtrans_streams_abort_state) {
501 501 case ABORT_NORMAL:
502 502 if (state != KEY_PRESSED)
503 503 break;
504 504
505 505 if (key == (kbtrans_key_t)kp->k_abort1 ||
506 506 key == (kbtrans_key_t)kp->k_abort1a) {
507 507 upper->kbtrans_streams_abort_state =
508 508 ABORT_ABORT1_RECEIVED;
509 509 upper->kbtrans_streams_abort1_key = key;
510 510 return;
511 511 }
512 512 /* Shift key needs to be sent to upper immediately */
513 513 if (key == (kbtrans_key_t)kp->k_newabort1 ||
514 514 key == (kbtrans_key_t)kp->k_newabort1a) {
515 515 upper->kbtrans_streams_abort_state =
516 516 NEW_ABORT_ABORT1_RECEIVED;
517 517 upper->kbtrans_streams_new_abort1_key = key;
518 518 }
519 519 break;
520 520 case ABORT_ABORT1_RECEIVED:
521 521 upper->kbtrans_streams_abort_state = ABORT_NORMAL;
522 522 if (state == KEY_PRESSED &&
523 523 key == (kbtrans_key_t)kp->k_abort2) {
524 524 abort_sequence_enter((char *)NULL);
525 525 return;
526 526 } else {
527 527 kbtrans_processkey(lower,
528 528 upper->kbtrans_streams_callback,
529 529 upper->kbtrans_streams_abort1_key,
530 530 KEY_PRESSED);
531 531 }
532 532 break;
533 533 case NEW_ABORT_ABORT1_RECEIVED:
534 534 upper->kbtrans_streams_abort_state = ABORT_NORMAL;
535 535 if (state == KEY_PRESSED &&
536 536 key == (kbtrans_key_t)kp->k_newabort2) {
537 537 abort_sequence_enter((char *)NULL);
538 538 kbtrans_processkey(lower,
539 539 upper->kbtrans_streams_callback,
540 540 upper->kbtrans_streams_new_abort1_key,
541 541 KEY_RELEASED);
542 542 return;
543 543 }
544 544 }
545 545 }
546 546
547 547 kbtrans_processkey(lower, upper->kbtrans_streams_callback, key, state);
548 548 }
549 549
550 550 /*
551 551 * kbtrans_streams_set_keyboard:
552 552 * At any time after calling kbtrans_streams_init, the hardware
553 553 * module should make this call to report the id of the keyboard
554 554 * attached. id is the keyboard type, typically KB_SUN4,
555 555 * KB_PC, or KB_USB.
556 556 */
557 557 void
558 558 kbtrans_streams_set_keyboard(
559 559 struct kbtrans *upper,
560 560 int id,
561 561 struct keyboard *k)
562 562 {
563 563 upper->kbtrans_lower.kbtrans_keyboard = k;
564 564 upper->kbtrans_streams_id = id;
565 565 }
566 566
567 567 /*
568 568 * kbtrans_streams_has_reset:
569 569 * At any time between kbtrans_streams_init and kbtrans_streams_fini,
570 570 * the hardware module can call this routine to report that the
571 571 * keyboard has been reset, e.g. by being unplugged and reattached.
572 572 */
573 573 /*ARGSUSED*/
574 574 void
575 575 kbtrans_streams_has_reset(struct kbtrans *upper)
576 576 {
577 577 /*
578 578 * If this routine is implemented it should probably (a)
579 579 * simulate releases of all pressed keys and (b) call
580 580 * the hardware module to set the LEDs.
581 581 */
582 582 }
583 583
584 584 /*
585 585 * kbtrans_streams_enable:
586 586 * This is the routine that is called back when the the stream is ready
587 587 * to take messages.
588 588 */
589 589 void
590 590 kbtrans_streams_enable(struct kbtrans *upper)
591 591 {
592 592 /* Set the LED's */
593 593 kbtrans_setled(upper);
594 594 }
595 595
596 596 /*
597 597 * kbtrans_streams_setled():
598 598 * This is the routine that is called to only update the led state
599 599 * in kbtrans.
600 600 */
601 601 void
602 602 kbtrans_streams_setled(struct kbtrans *upper, int led_state)
603 603 {
604 604 struct kbtrans_lower *lower;
605 605
606 606 lower = &upper->kbtrans_lower;
607 607 lower->kbtrans_led_state = (uchar_t)led_state;
608 608
609 609 if (lower->kbtrans_led_state & LED_CAPS_LOCK)
610 610 lower->kbtrans_togglemask |= CAPSMASK;
611 611 if (lower->kbtrans_led_state & LED_NUM_LOCK)
612 612 lower->kbtrans_togglemask |= NUMLOCKMASK;
613 613
614 614 #if defined(SCROLLMASK)
615 615 if (lower->kbtrans_led_state & LED_SCROLL_LOCK)
616 616 lower->kbtrans_togglemask |= SCROLLMASK;
617 617 #endif
618 618
619 619 lower->kbtrans_shiftmask = lower->kbtrans_togglemask;
620 620
621 621 }
622 622
623 623 /*
624 624 * kbtrans_streams_set_queue:
625 625 * Set the overlying queue, to support multiplexors.
626 626 */
627 627 void
628 628 kbtrans_streams_set_queue(struct kbtrans *upper, queue_t *q)
629 629 {
630 630
631 631 upper->kbtrans_streams_readq = q;
632 632 }
633 633
634 634 /*
635 635 * kbtrans_streams_get_queue:
636 636 * Return the overlying queue.
637 637 */
638 638 queue_t *
639 639 kbtrans_streams_get_queue(struct kbtrans *upper)
640 640 {
641 641 return (upper->kbtrans_streams_readq);
642 642 }
643 643
644 644 /*
645 645 * kbtrans_streams_untimeout
646 646 * Cancell all timeout
647 647 */
648 648 void
649 649 kbtrans_streams_untimeout(struct kbtrans *upper)
650 650 {
651 651 /* clear all timeouts */
652 652 if (upper->kbtrans_streams_bufcallid) {
653 653 qunbufcall(upper->kbtrans_streams_readq,
654 654 upper->kbtrans_streams_bufcallid);
655 655 upper->kbtrans_streams_bufcallid = 0;
656 656 }
657 657 if (upper->kbtrans_streams_rptid) {
658 658 (void) quntimeout(upper->kbtrans_streams_readq,
659 659 upper->kbtrans_streams_rptid);
660 660 upper->kbtrans_streams_rptid = 0;
661 661 }
662 662 }
663 663
664 664 /*
665 665 * kbtrans_reioctl:
666 666 * This function is set up as call-back function should an ioctl fail
667 667 * to allocate required resources.
668 668 */
669 669 static void
670 670 kbtrans_reioctl(void *arg)
671 671 {
672 672 struct kbtrans *upper = (struct kbtrans *)arg;
673 673 mblk_t *mp;
674 674
675 675 upper->kbtrans_streams_bufcallid = 0;
676 676
677 677 if ((mp = upper->kbtrans_streams_iocpending) != NULL) {
678 678 /* not pending any more */
679 679 upper->kbtrans_streams_iocpending = NULL;
680 680 (void) kbtrans_ioctl(upper, mp);
681 681 }
682 682 }
683 683
684 684 /*
685 685 * kbtrans_ioctl:
686 686 * process ioctls we recognize and own. Otherwise, pass it down.
687 687 */
688 688 static enum kbtrans_message_response
689 689 kbtrans_ioctl(struct kbtrans *upper, register mblk_t *mp)
690 690 {
691 691 register struct iocblk *iocp;
692 692 register short new_translate;
693 693 register Vuid_addr_probe *addr_probe;
694 694 register short *addr_ptr;
695 695 size_t ioctlrespsize;
696 696 int err = 0;
697 697 struct kbtrans_lower *lower;
698 698 mblk_t *datap;
699 699 int translate;
700 700
701 701 static int kiocgetkey, kiocsetkey;
702 702
703 703 lower = &upper->kbtrans_lower;
704 704
705 705 iocp = (struct iocblk *)mp->b_rptr;
706 706
707 707 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper,
708 708 "kbtrans_ioctl: ioc_cmd 0x%x - ", iocp->ioc_cmd));
709 709 switch (iocp->ioc_cmd) {
710 710
711 711 case VUIDSFORMAT:
712 712 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "VUIDSFORMAT\n"));
713 713
714 714 err = miocpullup(mp, sizeof (int));
715 715 if (err != 0)
716 716 break;
717 717 new_translate = (*(int *)mp->b_cont->b_rptr == VUID_NATIVE) ?
718 718 TR_ASCII : TR_EVENT;
719 719
720 720 if (new_translate == upper->kbtrans_streams_translate_mode)
721 721 break;
722 722 upper->kbtrans_streams_translate_mode = new_translate;
723 723
724 724 kbtrans_set_translation_callback(upper);
725 725
726 726 kbtrans_flush(upper);
727 727 break;
728 728
729 729 case KIOCTRANS:
730 730 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "KIOCTRANS\n"));
731 731 err = miocpullup(mp, sizeof (int));
732 732 if (err != 0)
733 733 break;
734 734 new_translate = *(int *)mp->b_cont->b_rptr;
735 735 if (new_translate == upper->kbtrans_streams_translate_mode)
736 736 break;
737 737 upper->kbtrans_streams_translate_mode = new_translate;
738 738 kbtrans_set_translation_callback(upper);
739 739
740 740 kbtrans_flush(upper);
741 741 break;
742 742
743 743 case KIOCSLED:
744 744 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "KIOCSLED\n"));
745 745
746 746 err = miocpullup(mp, sizeof (uchar_t));
747 747 if (err != 0)
748 748 break;
749 749 lower->kbtrans_led_state = *(uchar_t *)mp->b_cont->b_rptr;
750 750
751 751 kbtrans_setled(upper);
752 752 break;
753 753
754 754 case KIOCGLED:
755 755 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "KIOCGLED\n"));
756 756 if ((datap = allocb(sizeof (uchar_t), BPRI_HI)) == NULL) {
757 757 ioctlrespsize = sizeof (int);
758 758 goto allocfailure;
759 759 }
760 760
761 761 *(uchar_t *)datap->b_wptr = lower->kbtrans_led_state;
762 762 datap->b_wptr += sizeof (uchar_t);
763 763 if (mp->b_cont)
764 764 freemsg(mp->b_cont);
765 765 mp->b_cont = datap;
766 766 iocp->ioc_count = sizeof (uchar_t);
767 767 break;
768 768
769 769 case VUIDGFORMAT:
770 770 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "VUIDGFORMAT\n"));
771 771 if ((datap = allocb(sizeof (int), BPRI_HI)) == NULL) {
772 772 ioctlrespsize = sizeof (int);
773 773 goto allocfailure;
774 774 }
775 775 *(int *)datap->b_wptr =
776 776 (upper->kbtrans_streams_translate_mode == TR_EVENT ||
777 777 upper->kbtrans_streams_translate_mode == TR_UNTRANS_EVENT) ?
778 778 VUID_FIRM_EVENT: VUID_NATIVE;
779 779 datap->b_wptr += sizeof (int);
780 780 if (mp->b_cont) /* free msg to prevent memory leak */
781 781 freemsg(mp->b_cont);
782 782 mp->b_cont = datap;
783 783 iocp->ioc_count = sizeof (int);
784 784 break;
785 785
786 786 case KIOCGTRANS:
787 787 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "KIOCGTRANS\n"));
788 788 if ((datap = allocb(sizeof (int), BPRI_HI)) == NULL) {
789 789 ioctlrespsize = sizeof (int);
790 790 goto allocfailure;
791 791 }
792 792 *(int *)datap->b_wptr = upper->kbtrans_streams_translate_mode;
793 793 datap->b_wptr += sizeof (int);
794 794 if (mp->b_cont) /* free msg to prevent memory leak */
795 795 freemsg(mp->b_cont);
796 796 mp->b_cont = datap;
797 797 iocp->ioc_count = sizeof (int);
798 798 break;
799 799
800 800 case VUIDSADDR:
801 801 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "VUIDSADDR\n"));
802 802
803 803 err = miocpullup(mp, sizeof (Vuid_addr_probe));
804 804 if (err != 0)
805 805 break;
806 806 addr_probe = (Vuid_addr_probe *)mp->b_cont->b_rptr;
807 807 switch (addr_probe->base) {
808 808
809 809 case ASCII_FIRST:
810 810 addr_ptr = &upper->kbtrans_streams_vuid_addr.ascii;
811 811 break;
812 812
813 813 case TOP_FIRST:
814 814 addr_ptr = &upper->kbtrans_streams_vuid_addr.top;
815 815 break;
816 816
817 817 case VKEY_FIRST:
818 818 addr_ptr = &upper->kbtrans_streams_vuid_addr.vkey;
819 819 break;
820 820
821 821 default:
822 822 err = ENODEV;
823 823 }
824 824
825 825 if ((err == 0) && (*addr_ptr != addr_probe->data.next)) {
826 826 *addr_ptr = addr_probe->data.next;
827 827 kbtrans_flush(upper);
828 828 }
829 829 break;
830 830
831 831 case VUIDGADDR:
832 832 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "VUIDGADDR\n"));
833 833
834 834 err = miocpullup(mp, sizeof (Vuid_addr_probe));
835 835 if (err != 0)
836 836 break;
837 837 addr_probe = (Vuid_addr_probe *)mp->b_cont->b_rptr;
838 838 switch (addr_probe->base) {
839 839
840 840 case ASCII_FIRST:
841 841 addr_probe->data.current =
842 842 upper->kbtrans_streams_vuid_addr.ascii;
843 843 break;
844 844
845 845 case TOP_FIRST:
846 846 addr_probe->data.current =
847 847 upper->kbtrans_streams_vuid_addr.top;
848 848 break;
849 849
850 850 case VKEY_FIRST:
851 851 addr_probe->data.current =
852 852 upper->kbtrans_streams_vuid_addr.vkey;
853 853 break;
854 854
855 855 default:
856 856 err = ENODEV;
857 857 }
858 858 break;
859 859
860 860 case KIOCTRANSABLE:
861 861 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "KIOCTRANSABLE\n"));
862 862
863 863 err = miocpullup(mp, sizeof (int));
864 864 if (err != 0)
865 865 break;
866 866 /*
867 867 * called during console setup in kbconfig()
868 868 * If set to false, means we are a serial keyboard,
869 869 * and we should pass all data up without modification.
870 870 */
871 871 translate = *(int *)mp->b_cont->b_rptr;
872 872 if (upper->kbtrans_streams_translatable != translate)
873 873 upper->kbtrans_streams_translatable = translate;
874 874
875 875 if (translate != TR_CAN)
876 876 DPRINTF(PRINT_L4, PRINT_MASK_ALL, (upper,
877 877 "Cannot translate keyboard using tables.\n"));
878 878 break;
879 879
880 880 case KIOCGTRANSABLE:
881 881 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "KIOCGTRANSABLE\n"));
882 882 if ((datap = allocb(sizeof (int), BPRI_HI)) == NULL) {
883 883 ioctlrespsize = sizeof (int);
884 884 goto allocfailure;
885 885 }
886 886 *(int *)datap->b_wptr = upper->kbtrans_streams_translatable;
887 887 datap->b_wptr += sizeof (int);
888 888 if (mp->b_cont) /* free msg to prevent memory leak */
889 889 freemsg(mp->b_cont);
890 890 mp->b_cont = datap;
891 891 iocp->ioc_count = sizeof (int);
892 892 break;
893 893
894 894 case KIOCSCOMPAT:
895 895 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "KIOCSCOMPAT\n"));
896 896
897 897 err = miocpullup(mp, sizeof (int));
898 898 if (err != 0)
899 899 break;
900 900 lower->kbtrans_compat = *(int *)mp->b_cont->b_rptr;
901 901 break;
902 902
903 903 case KIOCGCOMPAT:
904 904 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "KIOCGCOMPAT\n"));
905 905 if ((datap = allocb(sizeof (int), BPRI_HI)) == NULL) {
906 906 ioctlrespsize = sizeof (int);
907 907 goto allocfailure;
908 908 }
909 909 *(int *)datap->b_wptr = lower->kbtrans_compat;
910 910 datap->b_wptr += sizeof (int);
911 911 if (mp->b_cont) /* free msg to prevent memory leak */
912 912 freemsg(mp->b_cont);
913 913 mp->b_cont = datap;
914 914 iocp->ioc_count = sizeof (int);
915 915 break;
916 916
917 917 case KIOCSETKEY:
918 918 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "KIOCSETKEY %d\n",
919 919 kiocsetkey++));
920 920 err = miocpullup(mp, sizeof (struct kiockey));
921 921 if (err != 0)
922 922 break;
923 923 err = kbtrans_setkey(&upper->kbtrans_lower,
924 924 (struct kiockey *)mp->b_cont->b_rptr, iocp->ioc_cr);
925 925 /*
926 926 * Since this only affects any subsequent key presses,
927 927 * don't flush soft state. One might want to
928 928 * toggle the keytable entries dynamically.
929 929 */
930 930 break;
931 931
932 932 case KIOCGETKEY:
933 933 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "KIOCGETKEY %d\n",
934 934 kiocgetkey++));
935 935 err = miocpullup(mp, sizeof (struct kiockey));
936 936 if (err != 0)
937 937 break;
938 938 err = kbtrans_getkey(&upper->kbtrans_lower,
939 939 (struct kiockey *)mp->b_cont->b_rptr);
940 940 break;
941 941
942 942 case KIOCSKEY:
943 943 err = miocpullup(mp, sizeof (struct kiockeymap));
944 944 if (err != 0)
945 945 break;
946 946 err = kbtrans_skey(&upper->kbtrans_lower,
947 947 (struct kiockeymap *)mp->b_cont->b_rptr, iocp->ioc_cr);
948 948 /*
949 949 * Since this only affects any subsequent key presses,
950 950 * don't flush soft state. One might want to
951 951 * toggle the keytable entries dynamically.
952 952 */
953 953 break;
954 954
955 955 case KIOCGKEY:
956 956 err = miocpullup(mp, sizeof (struct kiockeymap));
957 957 if (err != 0)
958 958 break;
959 959 err = kbtrans_gkey(&upper->kbtrans_lower,
960 960 (struct kiockeymap *)mp->b_cont->b_rptr);
961 961 break;
962 962
963 963 case KIOCSDIRECT:
964 964 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "KIOCSDIRECT\n"));
965 965 kbtrans_flush(upper);
966 966 break;
967 967
968 968 case KIOCGDIRECT:
969 969 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "KIOCSGDIRECT\n"));
970 970 if ((datap = allocb(sizeof (int), BPRI_HI)) == NULL) {
971 971 ioctlrespsize = sizeof (int);
972 972 goto allocfailure;
973 973 }
974 974 *(int *)datap->b_wptr = 1; /* always direct */
975 975 datap->b_wptr += sizeof (int);
976 976 if (mp->b_cont) /* free msg to prevent memory leak */
977 977 freemsg(mp->b_cont);
978 978 mp->b_cont = datap;
979 979 iocp->ioc_count = sizeof (int);
980 980 break;
981 981
982 982 case KIOCTYPE:
983 983 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "KIOCTYPE\n"));
984 984 if ((datap = allocb(sizeof (int), BPRI_HI)) == NULL) {
985 985 ioctlrespsize = sizeof (int);
986 986 goto allocfailure;
987 987 }
988 988 *(int *)datap->b_wptr = upper->kbtrans_streams_id;
989 989 datap->b_wptr += sizeof (int);
990 990 if (mp->b_cont) /* free msg to prevent memory leak */
991 991 freemsg(mp->b_cont);
992 992 mp->b_cont = datap;
993 993 iocp->ioc_count = sizeof (int);
994 994 break;
995 995
996 996 case CONSSETABORTENABLE:
997 997 /*
998 998 * Peek as it goes by; must be a TRANSPARENT ioctl.
999 999 */
1000 1000 if (iocp->ioc_count != TRANSPARENT) {
1001 1001 err = EINVAL;
1002 1002 break;
1003 1003 }
1004 1004
1005 1005 upper->kbtrans_streams_abortable =
1006 1006 (boolean_t)*(intptr_t *)mp->b_cont->b_rptr;
1007 1007
1008 1008 /*
1009 1009 * Let the hardware module see it too.
1010 1010 */
1011 1011 return (KBTRANS_MESSAGE_NOT_HANDLED);
1012 1012
1013 1013 case KIOCGRPTDELAY:
1014 1014 /*
1015 1015 * Report the autorepeat delay, unit in millisecond
1016 1016 */
1017 1017 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "KIOCGRPTDELAY\n"));
1018 1018 if ((datap = allocb(sizeof (int), BPRI_HI)) == NULL) {
1019 1019 ioctlrespsize = sizeof (int);
1020 1020 goto allocfailure;
1021 1021 }
1022 1022 *(int *)datap->b_wptr = TICK_TO_MSEC(kbtrans_repeat_delay);
1023 1023 datap->b_wptr += sizeof (int);
1024 1024
1025 1025 /* free msg to prevent memory leak */
1026 1026 if (mp->b_cont != NULL)
1027 1027 freemsg(mp->b_cont);
1028 1028 mp->b_cont = datap;
1029 1029 iocp->ioc_count = sizeof (int);
1030 1030 break;
1031 1031
1032 1032 case KIOCSRPTDELAY:
1033 1033 /*
1034 1034 * Set the autorepeat delay
1035 1035 */
1036 1036 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "KIOCSRPTDELAY\n"));
1037 1037 err = miocpullup(mp, sizeof (int));
1038 1038
1039 1039 if (err != 0)
1040 1040 break;
1041 1041
1042 1042 /* validate the input */
1043 1043 if (*(int *)mp->b_cont->b_rptr < KIOCRPTDELAY_MIN) {
1044 1044 err = EINVAL;
1045 1045 break;
1046 1046 }
1047 1047 kbtrans_repeat_delay = MSEC_TO_TICK(*(int *)mp->b_cont->b_rptr);
1048 1048 if (kbtrans_repeat_delay <= 0)
1049 1049 kbtrans_repeat_delay = 1;
1050 1050 break;
1051 1051
1052 1052 case KIOCGRPTRATE:
1053 1053 /*
1054 1054 * Report the autorepeat rate
1055 1055 */
1056 1056 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "KIOCGRPTRATE\n"));
1057 1057 if ((datap = allocb(sizeof (int), BPRI_HI)) == NULL) {
1058 1058 ioctlrespsize = sizeof (int);
1059 1059 goto allocfailure;
1060 1060 }
1061 1061 *(int *)datap->b_wptr = TICK_TO_MSEC(kbtrans_repeat_rate);
1062 1062 datap->b_wptr += sizeof (int);
1063 1063
1064 1064 /* free msg to prevent memory leak */
1065 1065 if (mp->b_cont != NULL)
1066 1066 freemsg(mp->b_cont);
1067 1067 mp->b_cont = datap;
1068 1068 iocp->ioc_count = sizeof (int);
1069 1069 break;
1070 1070
1071 1071 case KIOCSRPTRATE:
1072 1072 /*
1073 1073 * Set the autorepeat rate
1074 1074 */
1075 1075 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "KIOCSRPTRATE\n"));
1076 1076 err = miocpullup(mp, sizeof (int));
1077 1077
1078 1078 if (err != 0)
1079 1079 break;
1080 1080
1081 1081 /* validate the input */
1082 1082 if (*(int *)mp->b_cont->b_rptr < KIOCRPTRATE_MIN) {
1083 1083 err = EINVAL;
1084 1084 break;
1085 1085 }
1086 1086 kbtrans_repeat_rate = MSEC_TO_TICK(*(int *)mp->b_cont->b_rptr);
1087 1087 if (kbtrans_repeat_rate <= 0)
1088 1088 kbtrans_repeat_rate = 1;
1089 1089 break;
1090 1090
1091 1091 default:
1092 1092 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (upper, "unknown\n"));
1093 1093 return (KBTRANS_MESSAGE_NOT_HANDLED);
1094 1094 } /* end switch */
1095 1095
1096 1096 if (err != 0) {
1097 1097 iocp->ioc_rval = 0;
1098 1098 iocp->ioc_error = err;
1099 1099 mp->b_datap->db_type = M_IOCNAK;
1100 1100 } else {
1101 1101 iocp->ioc_rval = 0;
1102 1102 iocp->ioc_error = 0; /* brain rot */
1103 1103 mp->b_datap->db_type = M_IOCACK;
1104 1104 }
1105 1105 putnext(upper->kbtrans_streams_readq, mp);
1106 1106
1107 1107 return (KBTRANS_MESSAGE_HANDLED);
1108 1108
1109 1109 allocfailure:
1110 1110 /*
1111 1111 * We needed to allocate something to handle this "ioctl", but
1112 1112 * couldn't; save this "ioctl" and arrange to get called back when
1113 1113 * it's more likely that we can get what we need.
1114 1114 * If there's already one being saved, throw it out, since it
1115 1115 * must have timed out.
1116 1116 */
1117 1117 if (upper->kbtrans_streams_iocpending != NULL)
1118 1118 freemsg(upper->kbtrans_streams_iocpending);
1119 1119 upper->kbtrans_streams_iocpending = mp;
1120 1120 if (upper->kbtrans_streams_bufcallid) {
1121 1121 qunbufcall(upper->kbtrans_streams_readq,
1122 1122 upper->kbtrans_streams_bufcallid);
1123 1123 }
1124 1124 upper->kbtrans_streams_bufcallid =
1125 1125 qbufcall(upper->kbtrans_streams_readq, ioctlrespsize, BPRI_HI,
1126 1126 kbtrans_reioctl, upper);
1127 1127 /*
1128 1128 * This is a white lie... we *will* handle it, eventually.
1129 1129 */
1130 1130 return (KBTRANS_MESSAGE_HANDLED);
1131 1131 }
1132 1132
1133 1133 /*
1134 1134 * kbtrans_flush:
1135 1135 * Flush data upstream
1136 1136 */
1137 1137 static void
1138 1138 kbtrans_flush(register struct kbtrans *upper)
1139 1139 {
1140 1140 register queue_t *q;
1141 1141
1142 1142 /* Flush pending data already sent upstream */
1143 1143 if ((q = upper->kbtrans_streams_readq) != NULL && q->q_next != NULL)
1144 1144 (void) putnextctl1(q, M_FLUSH, FLUSHR);
1145 1145
1146 1146 /* Flush pending ups */
1147 1147 bzero(upper->kbtrans_streams_downs, upper->kbtrans_streams_downs_bytes);
1148 1148
1149 1149 kbtrans_cancelrpt(upper);
1150 1150 }
1151 1151
1152 1152 /*
1153 1153 * kbtrans_setled:
1154 1154 * Update the keyboard LEDs to match the current keyboard state.
1155 1155 */
1156 1156 static void
1157 1157 kbtrans_setled(struct kbtrans *upper)
1158 1158 {
1159 1159 upper->kbtrans_streams_hw_callbacks->kbtrans_streams_setled(
1160 1160 upper->kbtrans_streams_hw,
1161 1161 upper->kbtrans_lower.kbtrans_led_state);
1162 1162 }
1163 1163
1164 1164 /*
1165 1165 * kbtrans_rpt:
1166 1166 * If a key is held down, this function is set up to be called
1167 1167 * after kbtrans_repeat_rate time elapses.
1168 1168 */
1169 1169 static void
1170 1170 kbtrans_rpt(void *arg)
1171 1171 {
1172 1172 struct kbtrans *upper = arg;
1173 1173 struct kbtrans_lower *lower = &upper->kbtrans_lower;
1174 1174
1175 1175 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (NULL,
1176 1176 "kbtrans_rpt: repeat key %X\n",
1177 1177 lower->kbtrans_repeatkey));
1178 1178
1179 1179 upper->kbtrans_streams_rptid = 0;
1180 1180
1181 1181 /*
1182 1182 * NB: polled code zaps kbtrans_repeatkey without cancelling
1183 1183 * timeout.
1184 1184 */
1185 1185 if (lower->kbtrans_repeatkey != 0) {
1186 1186 kbtrans_keyreleased(upper, lower->kbtrans_repeatkey);
1187 1187
1188 1188 kbtrans_processkey(lower,
1189 1189 upper->kbtrans_streams_callback,
1190 1190 lower->kbtrans_repeatkey,
1191 1191 KEY_PRESSED);
1192 1192
1193 1193 upper->kbtrans_streams_rptid =
1194 1194 qtimeout(upper->kbtrans_streams_readq, kbtrans_rpt,
1195 1195 (caddr_t)upper, kbtrans_repeat_rate);
1196 1196 }
1197 1197 }
1198 1198
1199 1199 /*
1200 1200 * kbtrans_cancelrpt:
1201 1201 * Cancel the repeating key
1202 1202 */
1203 1203 static void
1204 1204 kbtrans_cancelrpt(struct kbtrans *upper)
1205 1205 {
1206 1206 upper->kbtrans_lower.kbtrans_repeatkey = 0;
1207 1207
1208 1208 if (upper->kbtrans_streams_rptid != 0) {
1209 1209 (void) quntimeout(upper->kbtrans_streams_readq,
1210 1210 upper->kbtrans_streams_rptid);
1211 1211 upper->kbtrans_streams_rptid = 0;
1212 1212 }
1213 1213 }
1214 1214
1215 1215 /*
1216 1216 * kbtrans_send_esc_event:
1217 1217 * Send character up stream. Used for the case of
1218 1218 * sending strings upstream.
1219 1219 */
1220 1220 static void
1221 1221 kbtrans_send_esc_event(char c, register struct kbtrans *upper)
1222 1222 {
1223 1223 Firm_event fe;
1224 1224
1225 1225 fe.id = c;
1226 1226 fe.value = 1;
1227 1227 fe.pair_type = FE_PAIR_NONE;
1228 1228 fe.pair = 0;
1229 1229 /*
1230 1230 * Pretend as if each cp pushed and released
1231 1231 * Calling kbtrans_queueevent avoids addr translation
1232 1232 * and pair base determination of kbtrans_keypressed.
1233 1233 */
1234 1234 kbtrans_queueevent(upper, &fe);
1235 1235 fe.value = 0;
1236 1236 kbtrans_queueevent(upper, &fe);
1237 1237 }
1238 1238
1239 1239 /*
1240 1240 * kbtrans_strsetwithdecimal:
1241 1241 * Used for expanding a function key to the ascii equivalent
1242 1242 */
1243 1243 static char *
1244 1244 kbtrans_strsetwithdecimal(char *buf, uint_t val, uint_t maxdigs)
1245 1245 {
1246 1246 int hradix = 5;
1247 1247 char *bp;
1248 1248 int lowbit;
1249 1249 char *tab = "0123456789abcdef";
1250 1250
1251 1251 bp = buf + maxdigs;
1252 1252 *(--bp) = '\0';
1253 1253 while (val) {
1254 1254 lowbit = val & 1;
1255 1255 val = (val >> 1);
1256 1256 *(--bp) = tab[val % hradix * 2 + lowbit];
1257 1257 val /= hradix;
|
↓ open down ↓ |
1257 lines elided |
↑ open up ↑ |
1258 1258 }
1259 1259 return (bp);
1260 1260 }
1261 1261
1262 1262 /*
1263 1263 * kbtrans_keypressed:
1264 1264 * Modify Firm event to be sent up the stream
1265 1265 */
1266 1266 static void
1267 1267 kbtrans_keypressed(struct kbtrans *upper, uchar_t key_station,
1268 - Firm_event *fe, ushort_t base)
1268 + Firm_event *fe, ushort_t base)
1269 1269 {
1270 1270
1271 1271 register short id_addr;
1272 1272 struct kbtrans_lower *lower = &upper->kbtrans_lower;
1273 1273
1274 1274 /* Set pair values */
1275 1275 if (fe->id < (ushort_t)VKEY_FIRST) {
1276 1276 /*
1277 1277 * If CTRLed, find the ID that would have been used had it
1278 1278 * not been CTRLed.
1279 1279 */
1280 1280 if (lower->kbtrans_shiftmask & (CTRLMASK | CTLSMASK)) {
1281 - unsigned short *ke;
1281 + keymap_entry_t *ke;
1282 1282 unsigned int mask;
1283 1283
1284 1284 mask = lower->kbtrans_shiftmask &
1285 1285 ~(CTRLMASK | CTLSMASK | UPMASK);
1286 1286
1287 1287 ke = kbtrans_find_entry(lower, mask, key_station);
1288 1288 if (ke == NULL)
1289 1289 return;
1290 1290
1291 1291 base = *ke;
1292 1292 }
1293 1293 if (base != fe->id) {
1294 1294 fe->pair_type = FE_PAIR_SET;
1295 1295 fe->pair = (uchar_t)base;
1296 1296
1297 1297 goto send;
1298 1298 }
1299 1299 }
1300 1300 fe->pair_type = FE_PAIR_NONE;
1301 1301 fe->pair = 0;
1302 1302
1303 1303 send:
1304 1304 /* Adjust event id address for multiple keyboard/workstation support */
1305 1305 switch (vuid_id_addr(fe->id)) {
1306 1306 case ASCII_FIRST:
1307 1307 id_addr = upper->kbtrans_streams_vuid_addr.ascii;
1308 1308 break;
1309 1309 case TOP_FIRST:
1310 1310 id_addr = upper->kbtrans_streams_vuid_addr.top;
1311 1311 break;
1312 1312 case VKEY_FIRST:
1313 1313 id_addr = upper->kbtrans_streams_vuid_addr.vkey;
1314 1314 break;
1315 1315 default:
1316 1316 id_addr = vuid_id_addr(fe->id);
1317 1317 break;
1318 1318 }
1319 1319 fe->id = vuid_id_offset(fe->id) | id_addr;
|
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
1320 1320
1321 1321 kbtrans_queuepress(upper, key_station, fe);
1322 1322 }
1323 1323
1324 1324 /*
1325 1325 * kbtrans_queuepress:
1326 1326 * Add keypress to the "downs" table
1327 1327 */
1328 1328 static void
1329 1329 kbtrans_queuepress(struct kbtrans *upper,
1330 - uchar_t key_station, Firm_event *fe)
1330 + uchar_t key_station, Firm_event *fe)
1331 1331 {
1332 1332 register struct key_event *ke, *ke_free;
1333 1333 register int i;
1334 1334
1335 1335 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (NULL, "kbtrans_queuepress:"
1336 1336 " key=%d", key_station));
1337 1337
1338 1338 ke_free = 0;
1339 1339
1340 1340 /* Scan table of down key stations */
1341 1341
1342 1342 for (i = 0, ke = upper->kbtrans_streams_downs;
1343 1343 i < upper->kbtrans_streams_num_downs_entries; i++, ke++) {
1344 1344
1345 1345 /* Keycode already down? */
1346 1346 if (ke->key_station == key_station) {
1347 1347
1348 1348 DPRINTF(PRINT_L0, PRINT_MASK_ALL,
1349 1349 (NULL, "kbtrans: Double "
1350 1350 "entry in downs table (%d,%d)!\n",
1351 1351 key_station, i));
1352 1352
1353 1353 goto add_event;
1354 1354 }
1355 1355
1356 1356 if (ke->key_station == 0)
1357 1357 ke_free = ke;
1358 1358 }
1359 1359
1360 1360 if (ke_free) {
1361 1361 ke = ke_free;
1362 1362 goto add_event;
1363 1363 }
1364 1364
1365 1365 ke = upper->kbtrans_streams_downs;
1366 1366
1367 1367 add_event:
1368 1368 ke->key_station = key_station;
1369 1369 ke->event = *fe;
1370 1370 kbtrans_queueevent(upper, fe);
1371 1371 }
1372 1372
1373 1373 /*
1374 1374 * kbtrans_keyreleased:
1375 1375 * Remove entry from the downs table
1376 1376 */
1377 1377 static void
1378 1378 kbtrans_keyreleased(register struct kbtrans *upper, uchar_t key_station)
1379 1379 {
1380 1380 register struct key_event *ke;
1381 1381 register int i;
1382 1382
1383 1383 DPRINTF(PRINT_L0, PRINT_MASK_ALL, (NULL, "RELEASE key=%d\n",
1384 1384 key_station));
1385 1385
1386 1386 if (upper->kbtrans_streams_translate_mode != TR_EVENT &&
1387 1387 upper->kbtrans_streams_translate_mode != TR_UNTRANS_EVENT) {
1388 1388
1389 1389 return;
1390 1390 }
1391 1391
1392 1392 /* Scan table of down key stations */
1393 1393 for (i = 0, ke = upper->kbtrans_streams_downs;
1394 1394 i < upper->kbtrans_streams_num_downs_entries;
1395 1395 i++, ke++) {
1396 1396 /* Found? */
1397 1397 if (ke->key_station == key_station) {
1398 1398 ke->key_station = 0;
1399 1399 ke->event.value = 0;
1400 1400 kbtrans_queueevent(upper, &ke->event);
1401 1401 }
1402 1402 }
1403 1403
1404 1404 /*
1405 1405 * Ignore if couldn't find because may be called twice
1406 1406 * for the same key station in the case of the kbtrans_rpt
1407 1407 * routine being called unnecessarily.
1408 1408 */
1409 1409 }
1410 1410
1411 1411
1412 1412 /*
1413 1413 * kbtrans_putcode:
1414 1414 * Pass a keycode up the stream, if you can, otherwise throw it away.
1415 1415 */
1416 1416 static void
1417 1417 kbtrans_putcode(register struct kbtrans *upper, uint_t code)
1418 1418 {
1419 1419 register mblk_t *bp;
1420 1420
1421 1421 /*
1422 1422 * If we can't send it up, then we just drop it.
1423 1423 */
1424 1424 if (!canputnext(upper->kbtrans_streams_readq)) {
1425 1425
1426 1426 return;
1427 1427 }
1428 1428
1429 1429 /*
1430 1430 * Allocate a messsage block to send up.
1431 1431 */
|
↓ open down ↓ |
91 lines elided |
↑ open up ↑ |
1432 1432 if ((bp = allocb(sizeof (uint_t), BPRI_HI)) == NULL) {
1433 1433
1434 1434 cmn_err(CE_WARN, "kbtrans_putcode: Can't allocate block\
1435 1435 for keycode.");
1436 1436
1437 1437 return;
1438 1438 }
1439 1439
1440 1440 /*
1441 1441 * We will strip out any high order information here.
1442 + * Convert to UTF-8.
1442 1443 */
1443 - /* NOTE the implicit cast here */
1444 - *bp->b_wptr++ = (uchar_t)code;
1444 + code = KEYCHAR(code);
1445 + if (code < 0x80) {
1446 + *bp->b_wptr++ = (char)code;
1447 + } else if (code < 0x800) {
1448 + *bp->b_wptr++ = 0xc0 | (code >> 6);
1449 + *bp->b_wptr++ = 0x80 | (code & 0x3f);
1450 + } else if (code < 0x10000) {
1451 + *bp->b_wptr++ = 0xe0 | (code >> 12);
1452 + *bp->b_wptr++ = 0x80 | ((code >> 6) & 0x3f);
1453 + *bp->b_wptr++ = 0x80 | (code & 0x3f);
1454 + } else {
1455 + *bp->b_wptr++ = 0xf0 | (code >> 18);
1456 + *bp->b_wptr++ = 0x80 | ((code >> 12) & 0x3f);
1457 + *bp->b_wptr++ = 0x80 | ((code >> 6) & 0x3f);
1458 + *bp->b_wptr++ = 0x80 | (code & 0x3f);
1459 + }
1445 1460
1446 1461 /*
1447 1462 * Send the message up.
1448 1463 */
1449 1464 (void) putnext(upper->kbtrans_streams_readq, bp);
1450 1465 }
1451 1466
1452 1467
1453 1468 /*
1454 1469 * kbtrans_putbuf:
1455 1470 * Pass generated keycode sequence to upstream, if possible.
1456 1471 */
1457 1472 static void
1458 1473 kbtrans_putbuf(char *buf, queue_t *q)
1459 1474 {
1460 1475 register mblk_t *bp;
1461 1476
1462 1477 if (!canputnext(q)) {
1463 1478 cmn_err(CE_WARN, "kbtrans_putbuf: Can't put block for keycode");
1464 1479 } else {
1465 1480 if ((bp = allocb((int)strlen(buf), BPRI_HI)) == NULL) {
1466 1481 cmn_err(CE_WARN, "kbtrans_putbuf: "
1467 1482 "Can't allocate block for keycode");
1468 1483 } else {
1469 1484 while (*buf) {
1470 1485 *bp->b_wptr++ = *buf;
1471 1486 buf++;
1472 1487 }
1473 1488 putnext(q, bp);
1474 1489 }
1475 1490 }
1476 1491 }
1477 1492
1478 1493 /*
1479 1494 * kbtrans_queueevent:
1480 1495 * Pass a VUID "firm event" up the stream, if you can.
1481 1496 */
1482 1497 static void
1483 1498 kbtrans_queueevent(struct kbtrans *upper, Firm_event *fe)
1484 1499 {
1485 1500 register queue_t *q;
1486 1501 register mblk_t *bp;
1487 1502
1488 1503 if ((q = upper->kbtrans_streams_readq) == NULL)
1489 1504
1490 1505 return;
1491 1506
1492 1507 if (!canputnext(q)) {
1493 1508 if (kbtrans_overflow_msg) {
1494 1509 DPRINTF(PRINT_L2, PRINT_MASK_ALL, (NULL,
1495 1510 "kbtrans: Buffer flushed when overflowed."));
1496 1511 }
1497 1512
1498 1513 kbtrans_flush(upper);
1499 1514 upper->kbtrans_overflow_cnt++;
1500 1515 } else {
1501 1516 if ((bp = allocb(sizeof (Firm_event), BPRI_HI)) == NULL) {
1502 1517 cmn_err(CE_WARN, "kbtrans_queueevent: Can't allocate \
1503 1518 block for event.");
1504 1519 } else {
1505 1520 uniqtime32(&fe->time);
1506 1521 *(Firm_event *)bp->b_wptr = *fe;
1507 1522 bp->b_wptr += sizeof (Firm_event);
1508 1523 (void) putnext(q, bp);
1509 1524
1510 1525
1511 1526 }
1512 1527 }
1513 1528 }
1514 1529
1515 1530 /*
1516 1531 * kbtrans_set_translation_callback:
1517 1532 * This code sets the translation_callback pointer based on the
1518 1533 * translation mode.
1519 1534 */
1520 1535 static void
1521 1536 kbtrans_set_translation_callback(register struct kbtrans *upper)
1522 1537 {
1523 1538 switch (upper->kbtrans_streams_translate_mode) {
1524 1539
1525 1540 default:
1526 1541 case TR_ASCII:
1527 1542 upper->vt_switch_keystate = VT_SWITCH_KEY_NONE;
1528 1543
1529 1544 /* Discard any obsolete CTRL/ALT/SHIFT keys */
1530 1545 upper->kbtrans_lower.kbtrans_shiftmask &=
1531 1546 ~(CTRLMASK | ALTMASK | SHIFTMASK);
1532 1547 upper->kbtrans_lower.kbtrans_togglemask &=
1533 1548 ~(CTRLMASK | ALTMASK | SHIFTMASK);
1534 1549
1535 1550 upper->kbtrans_streams_callback = &ascii_callback;
1536 1551
1537 1552 break;
1538 1553
1539 1554 case TR_EVENT:
1540 1555 upper->kbtrans_streams_callback = &trans_event_callback;
1541 1556
1542 1557 break;
1543 1558
1544 1559 case TR_UNTRANS_EVENT:
1545 1560 upper->kbtrans_streams_callback = &untrans_event_callback;
1546 1561
1547 1562 break;
1548 1563 }
1549 1564 }
1550 1565
1551 1566 /*
1552 1567 * kbtrans_untrans_keypressed_raw:
1553 1568 * This is the callback we get if we are in TR_UNTRANS_EVENT and a
1554 1569 * key is pressed. This code will just send the scancode up the
1555 1570 * stream.
1556 1571 */
1557 1572 static void
1558 1573 kbtrans_untrans_keypressed_raw(struct kbtrans *upper, kbtrans_key_t key)
1559 1574 {
1560 1575 Firm_event fe;
1561 1576
1562 1577 bzero(&fe, sizeof (fe));
1563 1578
1564 1579 /*
1565 1580 * fill in the event
1566 1581 */
1567 1582 fe.id = (unsigned short)key;
1568 1583 fe.value = 1;
1569 1584
1570 1585 /*
1571 1586 * Send the event upstream.
1572 1587 */
1573 1588 kbtrans_queuepress(upper, key, &fe);
1574 1589 }
1575 1590
1576 1591 /*
1577 1592 * kbtrans_untrans_keyreleased_raw:
1578 1593 * This is the callback we get if we are in TR_UNTRANS_EVENT mode
1579 1594 * and a key is released. This code will just send the scancode up
1580 1595 * the stream.
1581 1596 */
1582 1597 static void
1583 1598 kbtrans_untrans_keyreleased_raw(struct kbtrans *upper, kbtrans_key_t key)
1584 1599 {
1585 1600 /*
1586 1601 * Deal with a key released event.
1587 1602 */
1588 1603 kbtrans_keyreleased(upper, key);
1589 1604 }
1590 1605
1591 1606 /*
1592 1607 * kbtrans_vt_compose:
1593 1608 * To compose the key sequences for virtual terminal switching.
1594 1609 *
1595 1610 * 'ALTL + F#' for 1-12 terminals
1596 1611 * 'ALTGR + F#' for 13-24 terminals
1597 1612 * 'ALT + UPARROW' for last terminal
1598 1613 * 'ALT + LEFTARROW' for previous terminal
1599 1614 * 'ALT + RIGHTARROW' for next terminal
1600 1615 *
1601 1616 * the vt switching message is encoded as:
1602 1617 *
1603 1618 * -------------------------------------------------------------
1604 1619 * | \033 | 'Q' | vtno + 'A' | opcode | 'z' | '\0' |
1605 1620 * -------------------------------------------------------------
1606 1621 *
1607 1622 * opcode:
1608 1623 * 'B' to switch to previous terminal
1609 1624 * 'F' to switch to next terminal
1610 1625 * 'L' to switch to last terminal
1611 1626 * 'H' to switch to the terminal as specified by vtno,
1612 1627 * which is from 1 to 24.
1613 1628 *
1614 1629 * Here keyid is the keycode of UPARROW, LEFTARROW, or RIGHTARROW
1615 1630 * when it is a kind of arrow key as indicated by is_arrow_key,
1616 1631 * otherwise it indicates a function key and keyid is the number
1617 1632 * corresponding to that function key.
1618 1633 */
1619 1634 static void
1620 1635 kbtrans_vt_compose(struct kbtrans *upper, unsigned short keyid,
1621 1636 boolean_t is_arrow_key, char *buf)
1622 1637 {
1623 1638 char *bufp;
1624 1639
1625 1640 bufp = buf;
1626 1641 *bufp++ = '\033'; /* Escape */
1627 1642 *bufp++ = 'Q';
1628 1643 if (is_arrow_key) {
1629 1644 *bufp++ = 'A';
1630 1645 switch (keyid) {
1631 1646 case UPARROW: /* last vt */
1632 1647 *bufp++ = 'L';
1633 1648 break;
1634 1649 case LEFTARROW: /* previous vt */
1635 1650 *bufp++ = 'B';
1636 1651 break;
1637 1652 case RIGHTARROW: /* next vt */
1638 1653 *bufp++ = 'F';
1639 1654 break;
1640 1655 default:
1641 1656 break;
1642 1657 }
1643 1658 } else {
1644 1659 /* this is funckey specifying vtno for switch */
1645 1660 *bufp++ = keyid +
1646 1661 (upper->vt_switch_keystate - VT_SWITCH_KEY_ALT) *
1647 1662 KB_NR_FUNCKEYS + 'A';
1648 1663 *bufp++ = 'H';
1649 1664 }
1650 1665 *bufp++ = 'z';
1651 1666 *bufp = '\0';
1652 1667
1653 1668 /*
1654 1669 * Send the result upstream.
1655 1670 */
1656 1671 kbtrans_putbuf(buf, upper->kbtrans_streams_readq);
1657 1672
1658 1673 }
1659 1674
1660 1675 /*
1661 1676 * kbtrans_ascii_keypressed:
1662 1677 * This is the code if we are in TR_ASCII mode and a key
1663 1678 * is pressed. This is where we will do any special processing that
1664 1679 * is specific to ASCII key translation.
1665 1680 */
1666 1681 /* ARGSUSED */
1667 1682 static void
1668 1683 kbtrans_ascii_keypressed(
1669 1684 struct kbtrans *upper,
1670 1685 uint_t entrytype,
1671 1686 kbtrans_key_t key,
1672 1687 uint_t entry)
1673 1688 {
1674 1689 register char *cp;
1675 1690 register char *bufp;
1676 1691 char buf[14];
1677 1692 unsigned short keyid;
1678 1693 struct kbtrans_lower *lower = &upper->kbtrans_lower;
1679 1694
1680 1695 /*
1681 1696 * Based on the type of key, we may need to do some ASCII
1682 1697 * specific post processing. Note that the translated entry
1683 1698 * is constructed as the actual keycode plus entrytype. see
1684 1699 * sys/kbd.h for details of each entrytype.
1685 1700 */
1686 1701 switch (entrytype) {
1687 1702
1688 1703 case BUCKYBITS:
1689 1704 return;
1690 1705
1691 1706 case SHIFTKEYS:
1692 1707 keyid = entry & 0xFF;
1693 1708 if (keyid == ALT) {
1694 1709 upper->vt_switch_keystate = VT_SWITCH_KEY_ALT;
1695 1710 } else if (keyid == ALTGRAPH) {
1696 1711 upper->vt_switch_keystate = VT_SWITCH_KEY_ALTGR;
1697 1712 }
1698 1713 return;
1699 1714
1700 1715 case FUNNY:
1701 1716 /*
1702 1717 * There is no ascii equivalent. We will ignore these
1703 1718 * keys
1704 1719 */
1705 1720 return;
1706 1721
1707 1722 case FUNCKEYS:
1708 1723 if (upper->vt_switch_keystate > VT_SWITCH_KEY_NONE) {
1709 1724 if (entry >= TOPFUNC &&
1710 1725 entry < (TOPFUNC + KB_NR_FUNCKEYS)) {
1711 1726
1712 1727 /*
1713 1728 * keyid is the number correspoding to F#
1714 1729 * and its value is from 1 to 12.
1715 1730 */
1716 1731 keyid = (entry & 0xF) + 1;
1717 1732
1718 1733 kbtrans_vt_compose(upper, keyid, B_FALSE, buf);
1719 1734 return;
1720 1735 }
1721 1736 }
1722 1737
1723 1738 /*
1724 1739 * We need to expand this key to get the ascii
1725 1740 * equivalent. These are the function keys (F1, F2 ...)
1726 1741 */
1727 1742 bufp = buf;
1728 1743 cp = kbtrans_strsetwithdecimal(bufp + 2,
1729 1744 (uint_t)((entry & 0x003F) + 192),
1730 1745 sizeof (buf) - 5);
1731 1746 *bufp++ = '\033'; /* Escape */
1732 1747 *bufp++ = '[';
1733 1748 while (*cp != '\0')
1734 1749 *bufp++ = *cp++;
1735 1750 *bufp++ = 'z';
1736 1751 *bufp = '\0';
1737 1752
1738 1753 /*
1739 1754 * Send the result upstream.
1740 1755 */
1741 1756 kbtrans_putbuf(buf, upper->kbtrans_streams_readq);
1742 1757
1743 1758 return;
1744 1759
1745 1760 case STRING:
1746 1761 if (upper->vt_switch_keystate > VT_SWITCH_KEY_NONE) {
1747 1762 keyid = entry & 0xFF;
1748 1763 if (keyid == UPARROW ||
1749 1764 keyid == RIGHTARROW ||
1750 1765 keyid == LEFTARROW) {
1751 1766
1752 1767 kbtrans_vt_compose(upper, keyid, B_TRUE, buf);
1753 1768 return;
1754 1769 }
1755 1770 }
1756 1771
1757 1772 /*
1758 1773 * These are the multi byte keys (Home, Up, Down ...)
1759 1774 */
1760 1775 cp = &lower->kbtrans_keystringtab[entry & 0x0F][0];
1761 1776
1762 1777 /*
1763 1778 * Copy the string from the keystringtable, and send it
1764 1779 * upstream a character at a time.
1765 1780 */
1766 1781 while (*cp != '\0') {
1767 1782
1768 1783 kbtrans_putcode(upper, (uchar_t)*cp);
1769 1784
1770 1785 cp++;
1771 1786 }
1772 1787
1773 1788 return;
1774 1789
1775 1790 case PADKEYS:
1776 1791 /*
1777 1792 * These are the keys on the keypad. Look up the
1778 1793 * answer in the kb_numlock_table and send it upstream.
1779 1794 */
1780 1795 kbtrans_putcode(upper,
|
↓ open down ↓ |
326 lines elided |
↑ open up ↑ |
1781 1796 lower->kbtrans_numlock_table[entry&0x1F]);
1782 1797
1783 1798 return;
1784 1799
1785 1800 case 0: /* normal character */
1786 1801 default:
1787 1802 break;
1788 1803 }
1789 1804
1790 1805 /*
1791 - * Send the byte upstream.
1806 + * Send the char upstream.
1792 1807 */
1793 1808 kbtrans_putcode(upper, entry);
1794 1809
1795 1810 }
1796 1811
1797 1812 #define KB_SCANCODE_ALT 0xe2
1798 1813 #define KB_SCANCODE_ALTGRAPH 0xe6
1799 1814
1800 1815 /*
1801 1816 * kbtrans_ascii_keyreleased:
1802 1817 * This is the function if we are in TR_ASCII mode and a key
1803 1818 * is released. ASCII doesn't have the concept of released keys,
1804 1819 * or make/break codes. So there is nothing for us to do except
1805 1820 * checking 'Alt/AltGraph' release key in order to reset the state
1806 1821 * of vt switch key sequence.
1807 1822 */
1808 1823 /* ARGSUSED */
1809 1824 static void
1810 1825 kbtrans_ascii_keyreleased(struct kbtrans *upper, kbtrans_key_t key)
1811 1826 {
1812 1827 if (key == KB_SCANCODE_ALT || key == KB_SCANCODE_ALTGRAPH) {
1813 1828 upper->vt_switch_keystate = VT_SWITCH_KEY_NONE;
1814 1829 }
1815 1830 }
1816 1831
1817 1832 /*
1818 1833 * kbtrans_ascii_setup_repeat:
1819 1834 * This is the function if we are in TR_ASCII mode and the
1820 1835 * translation module has decided that a key needs to be repeated.
1821 1836 */
1822 1837 /* ARGSUSED */
1823 1838 static void
1824 1839 kbtrans_ascii_setup_repeat(
1825 1840 struct kbtrans *upper,
1826 1841 uint_t entrytype,
1827 1842 kbtrans_key_t key)
1828 1843 {
1829 1844 struct kbtrans_lower *lower = &upper->kbtrans_lower;
1830 1845
1831 1846 /*
1832 1847 * Cancel any currently repeating keys. This will be a new
1833 1848 * key to repeat.
1834 1849 */
1835 1850 kbtrans_cancelrpt(upper);
1836 1851
1837 1852 /*
1838 1853 * Set the value of the key to be repeated.
1839 1854 */
1840 1855 lower->kbtrans_repeatkey = key;
1841 1856
1842 1857 /*
1843 1858 * Start the timeout for repeating this key. kbtrans_rpt will
1844 1859 * be called to repeat the key.
1845 1860 */
1846 1861 upper->kbtrans_streams_rptid = qtimeout(upper->kbtrans_streams_readq,
1847 1862 kbtrans_rpt, (caddr_t)upper, kbtrans_repeat_delay);
1848 1863 }
1849 1864
1850 1865 /*
1851 1866 * kbtrans_trans_event_keypressed:
1852 1867 * This is the function if we are in TR_EVENT mode and a key
1853 1868 * is pressed. This is where we will do any special processing that
1854 1869 * is specific to EVENT key translation.
1855 1870 */
1856 1871 static void
1857 1872 kbtrans_trans_event_keypressed(
1858 1873 struct kbtrans *upper,
1859 1874 uint_t entrytype,
1860 1875 kbtrans_key_t key,
1861 1876 uint_t entry)
1862 1877 {
1863 1878 Firm_event fe;
1864 1879 register char *cp;
1865 1880 struct kbtrans_lower *lower = &upper->kbtrans_lower;
1866 1881
1867 1882 /*
1868 1883 * Based on the type of key, we may need to do some EVENT
1869 1884 * specific post processing.
1870 1885 */
1871 1886 switch (entrytype) {
1872 1887
1873 1888 case SHIFTKEYS:
1874 1889 /*
1875 1890 * Relying on ordinal correspondence between
1876 1891 * vuid_event.h SHIFT_META-SHIFT_TOP &
1877 1892 * kbd.h METABIT-SYSTEMBIT in order to
1878 1893 * correctly translate entry into fe.id.
1879 1894 */
1880 1895 fe.id = SHIFT_CAPSLOCK + (entry & 0x0F);
1881 1896 fe.value = 1;
1882 1897 kbtrans_keypressed(upper, key, &fe, fe.id);
1883 1898
1884 1899 return;
1885 1900
1886 1901 case BUCKYBITS:
1887 1902 /*
1888 1903 * Relying on ordinal correspondence between
1889 1904 * vuid_event.h SHIFT_CAPSLOCK-SHIFT_RIGHTCTRL &
1890 1905 * kbd.h CAPSLOCK-RIGHTCTRL in order to
1891 1906 * correctly translate entry into fe.id.
1892 1907 */
1893 1908 fe.id = SHIFT_META + (entry & 0x0F);
1894 1909 fe.value = 1;
1895 1910 kbtrans_keypressed(upper, key, &fe, fe.id);
1896 1911
1897 1912 return;
1898 1913
1899 1914 case FUNCKEYS:
1900 1915 /*
1901 1916 * Take advantage of the similar
1902 1917 * ordering of kbd.h function keys and
1903 1918 * vuid_event.h function keys to do a
1904 1919 * simple translation to achieve a
1905 1920 * mapping between the 2 different
1906 1921 * address spaces.
1907 1922 */
1908 1923 fe.id = KEY_LEFTFIRST + (entry & 0x003F);
1909 1924 fe.value = 1;
1910 1925
1911 1926 /*
1912 1927 * Assume "up" table only generates
1913 1928 * shift changes.
1914 1929 */
1915 1930 kbtrans_keypressed(upper, key, &fe, fe.id);
1916 1931
1917 1932 /*
1918 1933 * Function key events can be expanded
1919 1934 * by terminal emulator software to
1920 1935 * produce the standard escape sequence
1921 1936 * generated by the TR_ASCII case above
1922 1937 * if a function key event is not used
1923 1938 * by terminal emulator software
1924 1939 * directly.
1925 1940 */
1926 1941 return;
1927 1942
1928 1943 case STRING:
1929 1944 /*
1930 1945 * These are the multi byte keys (Home, Up, Down ...)
1931 1946 */
1932 1947 cp = &lower->kbtrans_keystringtab[entry & 0x0F][0];
1933 1948
1934 1949 /*
1935 1950 * Copy the string from the keystringtable, and send it
1936 1951 * upstream a character at a time.
1937 1952 */
1938 1953 while (*cp != '\0') {
1939 1954
1940 1955 kbtrans_send_esc_event(*cp, upper);
1941 1956
1942 1957 cp++;
1943 1958 }
1944 1959
1945 1960 return;
1946 1961
1947 1962 case PADKEYS:
1948 1963 /*
1949 1964 * Take advantage of the similar
1950 1965 * ordering of kbd.h keypad keys and
1951 1966 * vuid_event.h keypad keys to do a
1952 1967 * simple translation to achieve a
1953 1968 * mapping between the 2 different
1954 1969 * address spaces.
1955 1970 */
1956 1971 fe.id = VKEY_FIRSTPAD + (entry & 0x001F);
1957 1972 fe.value = 1;
1958 1973
1959 1974 /*
1960 1975 * Assume "up" table only generates
1961 1976 * shift changes.
1962 1977 */
1963 1978 kbtrans_keypressed(upper, key, &fe, fe.id);
1964 1979
1965 1980 /*
1966 1981 * Keypad key events can be expanded
1967 1982 * by terminal emulator software to
1968 1983 * produce the standard ascii character
1969 1984 * generated by the TR_ASCII case above
1970 1985 * if a keypad key event is not used
1971 1986 * by terminal emulator software
1972 1987 * directly.
1973 1988 */
1974 1989 return;
1975 1990
1976 1991 case FUNNY:
1977 1992 /*
1978 1993 * These are not events.
1979 1994 */
1980 1995 switch (entry) {
1981 1996 case IDLE:
1982 1997 case RESET:
1983 1998 case ERROR:
1984 1999 /*
1985 2000 * Something has happened. Mark all keys as released.
1986 2001 */
1987 2002 kbtrans_streams_releaseall(upper);
1988 2003 break;
1989 2004 }
1990 2005
1991 2006 return;
1992 2007
1993 2008 case 0: /* normal character */
1994 2009 default:
1995 2010 break;
1996 2011 }
1997 2012
1998 2013 /*
1999 2014 * Send the event upstream.
2000 2015 */
2001 2016 fe.id = entry;
2002 2017
2003 2018 fe.value = 1;
2004 2019
2005 2020 kbtrans_queueevent(upper, &fe);
2006 2021 }
2007 2022
2008 2023 /*
2009 2024 * kbtrans_trans_event_keyreleased:
2010 2025 * This is the function if we are in TR_EVENT mode and a key
2011 2026 * is released.
2012 2027 */
2013 2028 /* ARGSUSED */
2014 2029 static void
2015 2030 kbtrans_trans_event_keyreleased(struct kbtrans *upper, kbtrans_key_t key)
2016 2031 {
2017 2032 /*
2018 2033 * Mark the key as released and send an event upstream.
2019 2034 */
2020 2035 kbtrans_keyreleased(upper, key);
2021 2036 }
2022 2037
2023 2038 /*
2024 2039 * kbtrans_trans_event_setup_repeat:
2025 2040 * This is the function if we are in TR_EVENT mode and the
2026 2041 * translation module has decided that a key needs to be repeated.
2027 2042 * We will set a timeout to retranslate the repeat key.
2028 2043 */
2029 2044 static void
2030 2045 kbtrans_trans_event_setup_repeat(
2031 2046 struct kbtrans *upper,
2032 2047 uint_t entrytype,
2033 2048 kbtrans_key_t key)
2034 2049 {
2035 2050 struct kbtrans_lower *lower = &upper->kbtrans_lower;
2036 2051
2037 2052 /*
2038 2053 * Function keys and keypad keys do not repeat when we are in
2039 2054 * EVENT mode.
2040 2055 */
2041 2056 if (entrytype == FUNCKEYS || entrytype == PADKEYS) {
2042 2057
2043 2058 return;
2044 2059 }
2045 2060
2046 2061 /*
2047 2062 * Cancel any currently repeating keys. This will be a new
2048 2063 * key to repeat.
2049 2064 */
2050 2065 kbtrans_cancelrpt(upper);
2051 2066
2052 2067 /*
2053 2068 * Set the value of the key to be repeated.
2054 2069 */
2055 2070 lower->kbtrans_repeatkey = key;
2056 2071
2057 2072 /*
2058 2073 * Start the timeout for repeating this key. kbtrans_rpt will
2059 2074 * be called to repeat the key.
2060 2075 */
2061 2076 upper->kbtrans_streams_rptid = qtimeout(upper->kbtrans_streams_readq,
2062 2077 kbtrans_rpt, (caddr_t)upper, kbtrans_repeat_delay);
2063 2078 }
2064 2079
2065 2080 /*
2066 2081 * Administer the key tables.
2067 2082 */
2068 2083
2069 2084 /*
2070 2085 * Old special codes.
2071 2086 */
2072 2087 #define OLD_SHIFTKEYS 0x80
2073 2088 #define OLD_BUCKYBITS 0x90
2074 2089 #define OLD_FUNNY 0xA0
2075 2090 #define OLD_FA_UMLAUT 0xA9
2076 2091 #define OLD_FA_CFLEX 0xAA
2077 2092 #define OLD_FA_TILDE 0xAB
2078 2093 #define OLD_FA_CEDILLA 0xAC
2079 2094 #define OLD_FA_ACUTE 0xAD
2080 2095 #define OLD_FA_GRAVE 0xAE
2081 2096 #define OLD_ISOCHAR 0xAF
|
↓ open down ↓ |
280 lines elided |
↑ open up ↑ |
2082 2097 #define OLD_STRING 0xB0
2083 2098 #define OLD_LEFTFUNC 0xC0
2084 2099 #define OLD_RIGHTFUNC 0xD0
2085 2100 #define OLD_TOPFUNC 0xE0
2086 2101 #define OLD_BOTTOMFUNC 0xF0
2087 2102
2088 2103 /*
2089 2104 * Map old special codes to new ones.
2090 2105 * Indexed by ((old special code) >> 4) & 0x07; add (old special code) & 0x0F.
2091 2106 */
2092 -static ushort_t special_old_to_new[] = {
2107 +static keymap_entry_t special_old_to_new[] = {
2093 2108 SHIFTKEYS,
2094 2109 BUCKYBITS,
2095 2110 FUNNY,
2096 2111 STRING,
2097 2112 LEFTFUNC,
2098 2113 RIGHTFUNC,
2099 2114 TOPFUNC,
2100 2115 BOTTOMFUNC,
2101 2116 };
2102 2117
2103 2118
2104 2119 /*
2105 2120 * kbtrans_setkey:
2106 2121 * Set individual keystation translation from old-style entry.
2107 2122 */
2108 2123 static int
2109 2124 kbtrans_setkey(struct kbtrans_lower *lower, struct kiockey *key, cred_t *cr)
2110 2125 {
2111 2126 int strtabindex, i;
2112 - unsigned short *ke;
2127 + keymap_entry_t *ke;
2113 2128 register int tablemask;
2114 - register ushort_t entry;
2129 + register keymap_entry_t entry;
2115 2130 register struct keyboard *kp;
2116 2131
2117 2132 kp = lower->kbtrans_keyboard;
2118 2133
2119 2134 if (key->kio_station >= kp->k_keymap_size)
2120 -
2121 2135 return (EINVAL);
2122 2136
2123 2137 if (lower->kbtrans_keyboard == NULL)
2124 2138
2125 2139 return (EINVAL);
2126 2140
2127 2141 tablemask = key->kio_tablemask;
2128 2142
2129 2143 switch (tablemask) {
2130 2144 case KIOCABORT1:
2131 2145 case KIOCABORT1A:
2132 2146 case KIOCABORT2:
2133 2147 i = secpolicy_console(cr);
2134 2148 if (i != 0)
2135 2149 return (i);
2136 2150
2137 2151 switch (tablemask) {
2138 2152 case KIOCABORT1:
2139 2153 kp->k_abort1 = key->kio_station;
2140 2154 break;
2141 2155 case KIOCABORT1A:
2142 2156 kp->k_abort1a = key->kio_station;
2143 2157 break;
2144 2158 case KIOCABORT2:
2145 2159 kp->k_abort2 = key->kio_station;
2146 2160 break;
2147 2161 }
2148 2162 return (0);
2149 2163 }
2150 2164
2151 2165 if (tablemask & ALTGRAPHMASK)
2152 2166 return (EINVAL);
2153 2167
2154 2168 ke = kbtrans_find_entry(lower, (uint_t)tablemask, key->kio_station);
2155 2169 if (ke == NULL)
2156 2170 return (EINVAL);
2157 2171
2158 2172 if (key->kio_entry >= (uchar_t)OLD_STRING &&
2159 2173 key->kio_entry <= (uchar_t)(OLD_STRING + 15)) {
2160 2174 strtabindex = key->kio_entry - OLD_STRING;
2161 2175 bcopy(key->kio_string,
2162 2176 lower->kbtrans_keystringtab[strtabindex], KTAB_STRLEN);
2163 2177 lower->kbtrans_keystringtab[strtabindex][KTAB_STRLEN-1] = '\0';
2164 2178 }
2165 2179
2166 2180 entry = key->kio_entry;
2167 2181
2168 2182 /*
2169 2183 * There's nothing we need do with OLD_ISOCHAR.
2170 2184 */
2171 2185 if (entry != OLD_ISOCHAR) {
2172 2186 if (entry & 0x80) {
2173 2187 if (entry >= OLD_FA_UMLAUT && entry <= OLD_FA_GRAVE)
2174 2188 entry = FA_CLASS + (entry & 0x0F) - 9;
2175 2189 else
2176 2190 entry =
2177 2191 special_old_to_new[entry >> 4 & 0x07]
2178 2192 + (entry & 0x0F);
2179 2193 }
2180 2194 }
2181 2195
2182 2196 *ke = entry;
2183 2197
2184 2198 return (0);
2185 2199 }
2186 2200
2187 2201
2188 2202 /*
2189 2203 * Map new special codes to old ones.
2190 2204 * Indexed by (new special code) >> 8; add (new special code) & 0xFF.
2191 2205 */
2192 2206 static uchar_t special_new_to_old[] = {
2193 2207 0, /* normal */
2194 2208 OLD_SHIFTKEYS, /* SHIFTKEYS */
2195 2209 OLD_BUCKYBITS, /* BUCKYBITS */
2196 2210 OLD_FUNNY, /* FUNNY */
2197 2211 OLD_FA_UMLAUT, /* FA_CLASS */
2198 2212 OLD_STRING, /* STRING */
2199 2213 OLD_LEFTFUNC, /* FUNCKEYS */
2200 2214 };
|
↓ open down ↓ |
70 lines elided |
↑ open up ↑ |
2201 2215
2202 2216
2203 2217 /*
2204 2218 * kbtrans_getkey:
2205 2219 * Get individual keystation translation as old-style entry.
2206 2220 */
2207 2221 static int
2208 2222 kbtrans_getkey(struct kbtrans_lower *lower, struct kiockey *key)
2209 2223 {
2210 2224 int strtabindex;
2211 - unsigned short *ke;
2212 - register ushort_t entry;
2225 + keymap_entry_t *ke;
2226 + register keymap_entry_t entry;
2213 2227 struct keyboard *kp;
2214 2228
2215 2229 kp = lower->kbtrans_keyboard;
2216 2230
2217 2231 if (key->kio_station >= kp->k_keymap_size)
2218 2232 return (EINVAL);
2219 2233
2220 2234 if (lower->kbtrans_keyboard == NULL)
2221 2235 return (EINVAL);
2222 2236
2223 2237 switch (key->kio_tablemask) {
2224 2238 case KIOCABORT1:
2225 2239 key->kio_station = kp->k_abort1;
2226 2240 return (0);
2227 2241 case KIOCABORT1A:
2228 2242 key->kio_station = kp->k_abort1a;
2229 2243 return (0);
2230 2244 case KIOCABORT2:
2231 2245 key->kio_station = kp->k_abort2;
2232 2246 return (0);
2233 2247 }
2234 2248
2235 2249 ke = kbtrans_find_entry(lower, (uint_t)key->kio_tablemask,
2236 2250 key->kio_station);
2237 2251 if (ke == NULL)
2238 2252 return (EINVAL);
2239 2253
2240 2254 entry = *ke;
2241 2255
2242 2256 if (entry & 0xFF00)
2243 2257 key->kio_entry =
2244 2258 special_new_to_old[(ushort_t)(entry & 0xFF00) >> 8]
2245 2259 + (entry & 0x00FF);
2246 2260 else {
2247 2261 if (entry & 0x80)
2248 2262 key->kio_entry = (ushort_t)OLD_ISOCHAR; /* you lose */
2249 2263 else
2250 2264 key->kio_entry = (ushort_t)entry;
2251 2265 }
2252 2266
2253 2267 if (entry >= STRING && entry <= (uchar_t)(STRING + 15)) {
2254 2268 strtabindex = entry - STRING;
2255 2269 bcopy(lower->kbtrans_keystringtab[strtabindex],
2256 2270 key->kio_string, KTAB_STRLEN);
2257 2271 }
2258 2272 return (0);
2259 2273 }
|
↓ open down ↓ |
37 lines elided |
↑ open up ↑ |
2260 2274
2261 2275
2262 2276 /*
2263 2277 * kbtrans_skey:
2264 2278 * Set individual keystation translation from new-style entry.
2265 2279 */
2266 2280 static int
2267 2281 kbtrans_skey(struct kbtrans_lower *lower, struct kiockeymap *key, cred_t *cr)
2268 2282 {
2269 2283 int strtabindex, i;
2270 - unsigned short *ke;
2284 + keymap_entry_t *ke;
2271 2285 struct keyboard *kp;
2272 2286
2273 2287 kp = lower->kbtrans_keyboard;
2274 2288
2275 2289 if (key->kio_station >= kp->k_keymap_size) {
2276 2290 return (EINVAL);
2277 2291
2278 2292 }
2279 2293
2280 2294 if (lower->kbtrans_keyboard == NULL) {
2281 2295 return (EINVAL);
2282 2296 }
2283 2297
2284 2298 switch (key->kio_tablemask) {
2285 2299 case KIOCABORT1:
2286 2300 case KIOCABORT1A:
2287 2301 case KIOCABORT2:
2288 2302 i = secpolicy_console(cr);
2289 2303 if (i != 0)
2290 2304 return (i);
2291 2305 switch (key->kio_tablemask) {
2292 2306 case KIOCABORT1:
2293 2307 kp->k_abort1 = key->kio_station;
2294 2308 break;
2295 2309 case KIOCABORT1A:
2296 2310 kp->k_abort1a = key->kio_station;
2297 2311 break;
2298 2312 case KIOCABORT2:
2299 2313 kp->k_abort2 = key->kio_station;
2300 2314 break;
|
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
2301 2315 }
2302 2316 return (0);
2303 2317 }
2304 2318
2305 2319 ke = kbtrans_find_entry(lower, (uint_t)key->kio_tablemask,
2306 2320 key->kio_station);
2307 2321 if (ke == NULL)
2308 2322 return (EINVAL);
2309 2323
2310 2324 if (key->kio_entry >= STRING &&
2311 - key->kio_entry <= (ushort_t)(STRING + 15)) {
2325 + key->kio_entry <= (STRING + 15)) {
2312 2326 strtabindex = key->kio_entry-STRING;
2313 2327 bcopy(key->kio_string,
2314 2328 lower->kbtrans_keystringtab[strtabindex], KTAB_STRLEN);
2315 2329 lower->kbtrans_keystringtab[strtabindex][KTAB_STRLEN-1] = '\0';
2316 2330 }
2317 2331
2318 2332 *ke = key->kio_entry;
2319 2333
2320 2334 return (0);
2321 2335 }
2322 2336
2323 2337
2324 2338 /*
2325 2339 * kbtrans_gkey:
2326 2340 * Get individual keystation translation as new-style entry.
2327 2341 */
2328 2342 static int
2329 -kbtrans_gkey(struct kbtrans_lower *lower, struct kiockeymap *key)
2343 +kbtrans_gkey(struct kbtrans_lower *lower, struct kiockeymap *key)
2330 2344 {
2331 2345 int strtabindex;
2332 - unsigned short *ke;
2346 + keymap_entry_t *ke;
2333 2347 struct keyboard *kp;
2334 2348
2335 2349 kp = lower->kbtrans_keyboard;
2336 2350
2337 2351 if (key->kio_station >= kp->k_keymap_size)
2338 2352 return (EINVAL);
2339 2353
2340 2354 if (lower->kbtrans_keyboard == NULL)
2341 2355 return (EINVAL);
2342 2356
2343 2357 switch (key->kio_tablemask) {
2344 2358 case KIOCABORT1:
2345 2359 key->kio_station = kp->k_abort1;
2346 2360 return (0);
2347 2361 case KIOCABORT1A:
2348 2362 key->kio_station = kp->k_abort1a;
2349 2363 return (0);
2350 2364 case KIOCABORT2:
2351 2365 key->kio_station = kp->k_abort2;
2352 2366 return (0);
|
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
2353 2367 }
2354 2368
2355 2369 ke = kbtrans_find_entry(lower, (uint_t)key->kio_tablemask,
2356 2370 key->kio_station);
2357 2371 if (ke == NULL)
2358 2372 return (EINVAL);
2359 2373
2360 2374 key->kio_entry = *ke;
2361 2375
2362 2376 if (key->kio_entry >= STRING &&
2363 - key->kio_entry <= (ushort_t)(STRING + 15)) {
2377 + key->kio_entry <= (STRING + 15)) {
2364 2378 strtabindex = key->kio_entry-STRING;
2365 2379 bcopy(lower->kbtrans_keystringtab[strtabindex],
2366 2380 key->kio_string, KTAB_STRLEN);
2367 2381 }
2368 2382 return (0);
2369 2383 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX