2 ===================================================================
3 --- kvm-86.orig/curses.c 2009-05-22 10:09:19.000000000 +0200
4 +++ kvm-86/curses.c 2009-05-22 10:10:38.000000000 +0200
9 - keycode |= keysym2scancode(kbd_layout, keysym);
11 + keydata_t *kd = find_keysym(kbd_layout, keysym);
13 + keycode |= kd->keycode;
17 if (is_graphic_console()) {
18 Index: kvm-86/keymaps.c
19 ===================================================================
20 --- kvm-86.orig/keymaps.c 2009-05-22 10:09:24.000000000 +0200
21 +++ kvm-86/keymaps.c 2009-05-22 10:10:38.000000000 +0200
28 snprintf(file_name, sizeof(file_name),
29 "%s/keymaps/%s", bios_dir, language);
45 + keymod |= KEYMOD_SHIFT;
49 keysym = get_keysym(table, line);
51 // fprintf(stderr, "Warning: unknown keysym %s\n", line);
53 const char *rest = end_of_keysym + 1;
56 int keycode = strtol(rest, &rest2, 0);
58 - if (rest && strstr(rest, "numlock")) {
59 - add_to_key_range(&k->keypad_range, keycode);
60 - add_to_key_range(&k->numlock_range, keysym);
61 - //fprintf(stderr, "keypad keysym %04x keycode %d\n", keysym, keycode);
62 + modifier = strtok (rest2, " ");
63 + while (modifier != NULL) {
64 + if (!strcmp(modifier, "shift")) {
65 + keymod |= KEYMOD_SHIFT;
67 + if (!strcmp(modifier, "addupper")) {
70 + if (!strcmp(modifier, "ctrl")) {
71 + keymod |= KEYMOD_CTRL;
73 + if (!strcmp(modifier, "alt")) {
74 + keymod |= KEYMOD_ALT;
76 + if (!strcmp(modifier, "altgr")) {
77 + keymod |= KEYMOD_ALTGR;
79 + if (!strncmp(modifier, "dead_",5)) {
80 + keymod |= KEYMOD_DEAD;
81 + deadsym = get_keysym(table, modifier);
83 + if (!strcmp(modifier, "numlock")) {
84 + add_to_key_range(&k->keypad_range, keycode);
85 + add_to_key_range(&k->numlock_range, keysym);
86 + //fprintf(stderr, "keypad keysym %04x keycode %d\n", keysym, keycode);
88 + modifier = strtok (NULL," ");
92 keycode=(keycode<<8)^0x80e0; */
93 if (keysym < MAX_NORMAL_KEYCODE) {
94 //fprintf(stderr,"Setting keysym %s (%d) to %d\n",line,keysym,keycode);
95 - k->keysym2keycode[keysym] = keycode;
96 + k->keysym2keycode[keysym].keycode = keycode;
97 + k->keysym2keycode[keysym].keymod = keymod;
98 + k->keysym2keycode[keysym].deadsym = deadsym;
100 if (k->extra_count >= MAX_EXTRA_COUNT) {
102 @@ -128,11 +170,18 @@
104 k->keysym2keycode_extra[k->extra_count].
106 - k->keysym2keycode_extra[k->extra_count].
108 + k->keysym2keycode_extra[k->extra_count].kdata.
110 + k->keysym2keycode_extra[k->extra_count].kdata.
112 + k->keysym2keycode_extra[k->extra_count].kdata.
123 @@ -148,14 +197,11 @@
127 -int keysym2scancode(void *kbd_layout, int keysym)
128 +keydata_t *find_keysym(void *kbd_layout, int keysym)
130 kbd_layout_t *k = kbd_layout;
131 if (keysym < MAX_NORMAL_KEYCODE) {
132 - if (k->keysym2keycode[keysym] == 0)
133 - fprintf(stderr, "Warning: no scancode found for keysym %d\n",
135 - return k->keysym2keycode[keysym];
136 + return &k->keysym2keycode[keysym];
139 #ifdef XK_ISO_Left_Tab
140 @@ -163,10 +209,10 @@
143 for (i = 0; i < k->extra_count; i++)
144 - if (k->keysym2keycode_extra[i].keysym == keysym)
145 - return k->keysym2keycode_extra[i].keycode;
146 + if (k->keysym2keycode_extra[i].keysym == keysym)
147 + return &k->keysym2keycode_extra[i].kdata;
153 int keycode_is_keypad(void *kbd_layout, int keycode)
154 Index: kvm-86/keymaps.h
155 ===================================================================
156 --- kvm-86.orig/keymaps.h 2009-05-22 10:09:32.000000000 +0200
157 +++ kvm-86/keymaps.h 2009-05-22 10:10:38.000000000 +0200
159 struct key_range *next;
162 +#define KEYMOD_SHIFT 0x01
163 +#define KEYMOD_CTRL 0x02
164 +#define KEYMOD_ALT 0x04
165 +#define KEYMOD_DEAD 0x08
166 +#define KEYMOD_ALTGR 0x10
168 #define MAX_NORMAL_KEYCODE 512
169 #define MAX_EXTRA_COUNT 256
178 - uint16_t keysym2keycode[MAX_NORMAL_KEYCODE];
179 + keydata_t keysym2keycode[MAX_NORMAL_KEYCODE];
184 } keysym2keycode_extra[MAX_EXTRA_COUNT];
186 struct key_range *keypad_range;
190 void *init_keyboard_layout(const name2keysym_t *table, const char *language);
191 -int keysym2scancode(void *kbd_layout, int keysym);
192 +keydata_t *find_keysym(void *kbd_layout, int keysym);
193 int keycode_is_keypad(void *kbd_layout, int keycode);
194 int keysym_is_numlock(void *kbd_layout, int keysym);
197 ===================================================================
198 --- kvm-86.orig/sdl.c 2009-05-22 10:09:43.000000000 +0200
199 +++ kvm-86/sdl.c 2009-05-22 10:10:38.000000000 +0200
201 if (keysym == 92 && ev->keysym.scancode == 133) {
204 - return keysym2scancode(kbd_layout, keysym);
205 + keydata_t *kd = find_keysym(kbd_layout, keysym);
209 + return kd->keycode;
212 /* specific keyboard conversions from scan codes */
214 ===================================================================
215 --- kvm-86.orig/vnc.c 2009-05-22 10:09:54.000000000 +0200
216 +++ kvm-86/vnc.c 2009-05-22 10:10:38.000000000 +0200
217 @@ -1257,27 +1257,85 @@
218 check_pointer_type_change(vs, kbd_mouse_is_absolute());
221 +static void do_keycode(int keycode, int down)
223 + // fprintf (stderr, "KEY: %04x %d\n", keycode, down);
224 + if (keycode & 0x80)
225 + kbd_put_keycode(0xe0);
227 + kbd_put_keycode(keycode & 0x7f);
229 + kbd_put_keycode(keycode | 0x80);
232 +static void do_modifier(VncState *vs, int keycode, int down, int level)
234 + do_keycode(keycode, down);
235 + vs->modifiers_state[level][keycode] = down;
237 + vs->modifiers_state[1][keycode] = down;
241 static void reset_keys(VncState *vs)
244 for(i = 0; i < 256; i++) {
245 - if (vs->modifiers_state[i]) {
247 - kbd_put_keycode(0xe0);
248 - kbd_put_keycode(i | 0x80);
249 - vs->modifiers_state[i] = 0;
250 + if (vs->modifiers_state[0][i]) {
251 + do_modifier (vs, i, 0, 0);
256 +static void set_modifiers(VncState *vs, uint8_t reqstate, int down, int full)
259 + for(m=test_modifier; m->bit; m++) {
260 + int requested = reqstate & m->bit;
261 + /* Release unwanted modifiers */
262 + if (!down || full) {
263 + if (vs->modifiers_state[1][m->keycode] && !requested)
264 + do_modifier(vs, m->keycode, 0, 1);
266 + /* Press desired modifiers */
267 + if (down || full) {
268 + int already_set = vs->modifiers_state[1][m->keycode];
269 + if (!already_set && requested)
270 + do_modifier(vs, m->keycode, 1, 1);
275 +static void restore_modifiers(VncState *vs)
277 + /* Restore modifiers from reference */
279 + for(m=test_modifier; m->bit; m++) {
280 + if (vs->modifiers_state[0][m->keycode] !=
281 + vs->modifiers_state[1][m->keycode])
282 + do_modifier(vs, m->keycode, vs->modifiers_state[0][m->keycode], 0);
285 static void press_key(VncState *vs, int keysym)
287 - kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) & 0x7f);
288 - kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) | 0x80);
289 + keydata_t *kd = find_keysym(vs->vd->kbd_layout, keysym & 0xFFFF);
293 + kbd_put_keycode(kd->keycode & 0x7f);
294 + kbd_put_keycode(kd->keycode | 0x80);
297 -static void do_key_event(VncState *vs, int down, int keycode, int sym)
298 +static void do_key_event(VncState *vs, int down, keydata_t *kd, int sym)
303 + int keycode = kd->keycode;
304 + //fprintf (stderr, "SYM: %04x SCANCODE: %04x MOD %04x\n",
305 + // sym, keycode, kd->keymod);
308 /* QEMU console switch */
310 case 0x2a: /* Left Shift */
311 @@ -1286,23 +1344,24 @@
312 case 0x9d: /* Right CTRL */
313 case 0x38: /* Left ALT */
314 case 0xb8: /* Right ALT */
316 - vs->modifiers_state[keycode] = 1;
318 - vs->modifiers_state[keycode] = 0;
320 + do_modifier(vs, keycode, down, 0);
322 case 0x02 ... 0x0a: /* '1' to '9' keys */
323 - if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
324 + if (down && vs->modifiers_state[0][0x1d] && vs->modifiers_state[0][0x38]) {
325 /* Reset the modifiers sent to the current console */
327 console_select(keycode - 0x02);
331 - case 0x3a: /* CapsLock */
332 - case 0x45: /* NumLock */
334 - vs->modifiers_state[keycode] ^= 1;
335 + case 0x3a: /* CapsLock */
336 + case 0x45: /* NumLock */
338 + if (vs->modifiers_state[0][0x45])
339 + do_modifier(vs, keycode, 0, 0);
341 + do_modifier(vs, keycode, 1, 0);
346 @@ -1312,25 +1371,42 @@
347 toggles numlock away from the VNC window.
349 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
350 - if (!vs->modifiers_state[0x45]) {
351 - vs->modifiers_state[0x45] = 1;
352 + if (!vs->modifiers_state[0][0x45]) {
353 + do_modifier(vs, 0x45, 1, 0);
354 press_key(vs, 0xff7f);
357 - if (vs->modifiers_state[0x45]) {
358 - vs->modifiers_state[0x45] = 0;
359 - press_key(vs, 0xff7f);
360 + if (vs->modifiers_state[0][0x45]) {
361 + do_modifier(vs, 0x45, 0, 0);
362 + press_key(vs, 0xff7f);
367 if (is_graphic_console()) {
368 - if (keycode & 0x80)
369 - kbd_put_keycode(0xe0);
371 - kbd_put_keycode(keycode & 0x7f);
373 - kbd_put_keycode(keycode | 0x80);
376 + if (kd->keymod & KEYMOD_DEAD) {
377 + keydata_t *deaddata;
378 + deaddata = find_keysym(vs->vd->kbd_layout, kd->deadsym);
379 + if (deaddata != NULL) {
380 + set_modifiers(vs, deaddata->keymod, 0, 1);
381 + do_keycode(deaddata->keycode, 1);
382 + do_keycode(deaddata->keycode, 0);
383 + restore_modifiers(vs);
386 + set_modifiers(vs, kd->keymod, 1, 0);
388 + restore_modifiers(vs);
390 + do_keycode (keycode, down);
392 + /* vnc never sends ALTGR, so we create an artificial up event */
393 + if (down && (kd->keymod & KEYMOD_ALTGR)) {
394 + set_modifiers(vs, kd->keymod, 0, 0);
398 /* QEMU console emulation */
400 @@ -1388,13 +1464,9 @@
402 static void key_event(VncState *vs, int down, uint32_t sym)
406 - if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
407 - sym = sym - 'A' + 'a';
408 + keydata_t *kd = find_keysym(vs->vd->kbd_layout, sym & 0xFFFF);
410 - keycode = keysym2scancode(vs->vd->kbd_layout, sym & 0xFFFF);
411 - do_key_event(vs, down, keycode, sym);
412 + do_key_event(vs, down, kd, sym & 0xFFFF);
415 static void ext_key_event(VncState *vs, int down,
416 @@ -1403,8 +1475,15 @@
417 /* if the user specifies a keyboard layout, always use it */
419 key_event(vs, down, sym);
421 - do_key_event(vs, down, keycode, sym);
425 + kd.keycode = keycode;
429 + do_key_event(vs, down, &kd, sym & 0xFFFF);
433 static void framebuffer_update_request(VncState *vs, int incremental,
435 ===================================================================
436 --- kvm-86.orig/vnc.h 2009-05-22 10:10:08.000000000 +0200
437 +++ kvm-86/vnc.h 2009-05-22 10:10:38.000000000 +0200
440 *****************************************************************************/
447 +static modifier_t test_modifier[]={
448 + {0x2a, KEYMOD_SHIFT},
449 + {0x36, KEYMOD_SHIFT},
450 + {0x1d, KEYMOD_CTRL},
451 + {0x9d, KEYMOD_CTRL},
452 + {0x38, KEYMOD_ALT},
453 + {0xb8, KEYMOD_ALTGR},
457 typedef struct Buffer
461 VncReadEvent *read_handler;
462 size_t read_handler_expect;
464 - uint8_t modifiers_state[256];
465 + uint8_t modifiers_state[2][256];