]>
Commit | Line | Data |
---|---|---|
4676c0af DM |
1 | Index: kvm-86/curses.c |
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 | |
5 | @@ -238,7 +238,11 @@ | |
6 | keysym = chr; | |
7 | ||
8 | keycode &= ~KEY_MASK; | |
9 | - keycode |= keysym2scancode(kbd_layout, keysym); | |
10 | + | |
11 | + keydata_t *kd = find_keysym(kbd_layout, keysym); | |
12 | + if (kd) { | |
13 | + keycode |= kd->keycode; | |
14 | + } | |
15 | } | |
16 | ||
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 | |
22 | @@ -67,6 +67,7 @@ | |
23 | char file_name[1024]; | |
24 | char line[1024]; | |
25 | int len; | |
26 | + int upper; | |
27 | ||
28 | snprintf(file_name, sizeof(file_name), | |
29 | "%s/keymaps/%s", bios_dir, language); | |
30 | @@ -97,25 +98,66 @@ | |
31 | if (*end_of_keysym) { | |
32 | int keysym; | |
33 | *end_of_keysym = 0; | |
34 | + uint8_t keymod; | |
35 | + int deadsym; | |
36 | + | |
37 | + keymod = 0; | |
38 | + deadsym = 0; | |
39 | + upper = 0; | |
40 | +redo: | |
41 | + if (upper==1){ | |
42 | + char *c; | |
43 | + for(c=line;*c;c++) | |
44 | + *c=toupper(*c); | |
45 | + keymod |= KEYMOD_SHIFT; | |
46 | + upper++; | |
47 | + } | |
48 | + | |
49 | keysym = get_keysym(table, line); | |
50 | if (keysym == 0) { | |
51 | // fprintf(stderr, "Warning: unknown keysym %s\n", line); | |
52 | } else { | |
53 | const char *rest = end_of_keysym + 1; | |
54 | char *rest2; | |
55 | + char *modifier; | |
56 | int keycode = strtol(rest, &rest2, 0); | |
57 | ||
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; | |
66 | + } else | |
67 | + if (!strcmp(modifier, "addupper")) { | |
68 | + upper++; | |
69 | + } else | |
70 | + if (!strcmp(modifier, "ctrl")) { | |
71 | + keymod |= KEYMOD_CTRL; | |
72 | + } else | |
73 | + if (!strcmp(modifier, "alt")) { | |
74 | + keymod |= KEYMOD_ALT; | |
75 | + } else | |
76 | + if (!strcmp(modifier, "altgr")) { | |
77 | + keymod |= KEYMOD_ALTGR; | |
78 | + } else | |
79 | + if (!strncmp(modifier, "dead_",5)) { | |
80 | + keymod |= KEYMOD_DEAD; | |
81 | + deadsym = get_keysym(table, modifier); | |
82 | + } else | |
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); | |
87 | + } | |
88 | + modifier = strtok (NULL," "); | |
89 | } | |
90 | ||
91 | /* if(keycode&0x80) | |
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; | |
99 | } else { | |
100 | if (k->extra_count >= MAX_EXTRA_COUNT) { | |
101 | fprintf(stderr, | |
102 | @@ -128,11 +170,18 @@ | |
103 | #endif | |
104 | k->keysym2keycode_extra[k->extra_count]. | |
105 | keysym = keysym; | |
106 | - k->keysym2keycode_extra[k->extra_count]. | |
107 | - keycode = keycode; | |
108 | + k->keysym2keycode_extra[k->extra_count].kdata. | |
109 | + keycode = keycode; | |
110 | + k->keysym2keycode_extra[k->extra_count].kdata. | |
111 | + keymod = keymod; | |
112 | + k->keysym2keycode_extra[k->extra_count].kdata. | |
113 | + deadsym = deadsym; | |
114 | + | |
115 | k->extra_count++; | |
116 | } | |
117 | } | |
118 | + if (upper==1) | |
119 | + goto redo; | |
120 | } | |
121 | } | |
122 | } | |
123 | @@ -148,14 +197,11 @@ | |
124 | } | |
125 | ||
126 | ||
127 | -int keysym2scancode(void *kbd_layout, int keysym) | |
128 | +keydata_t *find_keysym(void *kbd_layout, int keysym) | |
129 | { | |
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", | |
134 | - keysym); | |
135 | - return k->keysym2keycode[keysym]; | |
136 | + return &k->keysym2keycode[keysym]; | |
137 | } else { | |
138 | int i; | |
139 | #ifdef XK_ISO_Left_Tab | |
140 | @@ -163,10 +209,10 @@ | |
141 | keysym = XK_Tab; | |
142 | #endif | |
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; | |
148 | } | |
149 | - return 0; | |
150 | + return NULL; | |
151 | } | |
152 | ||
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 | |
158 | @@ -38,13 +38,26 @@ | |
159 | struct key_range *next; | |
160 | }; | |
161 | ||
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 | |
167 | + | |
168 | #define MAX_NORMAL_KEYCODE 512 | |
169 | #define MAX_EXTRA_COUNT 256 | |
170 | + | |
171 | +typedef struct { | |
172 | + uint16_t keycode; | |
173 | + uint8_t keymod; | |
174 | + int deadsym; | |
175 | +} keydata_t; | |
176 | + | |
177 | typedef struct { | |
178 | - uint16_t keysym2keycode[MAX_NORMAL_KEYCODE]; | |
179 | + keydata_t keysym2keycode[MAX_NORMAL_KEYCODE]; | |
180 | struct { | |
181 | int keysym; | |
182 | - uint16_t keycode; | |
183 | + keydata_t kdata; | |
184 | } keysym2keycode_extra[MAX_EXTRA_COUNT]; | |
185 | int extra_count; | |
186 | struct key_range *keypad_range; | |
187 | @@ -53,7 +66,7 @@ | |
188 | ||
189 | ||
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); | |
195 | ||
196 | Index: kvm-86/sdl.c | |
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 | |
200 | @@ -214,7 +214,11 @@ | |
201 | if (keysym == 92 && ev->keysym.scancode == 133) { | |
202 | keysym = 0xa5; | |
203 | } | |
204 | - return keysym2scancode(kbd_layout, keysym); | |
205 | + keydata_t *kd = find_keysym(kbd_layout, keysym); | |
206 | + if (kd==NULL) | |
207 | + return 0; | |
208 | + else | |
209 | + return kd->keycode; | |
210 | } | |
211 | ||
212 | /* specific keyboard conversions from scan codes */ | |
213 | Index: kvm-86/vnc.c | |
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()); | |
219 | } | |
220 | ||
221 | +static void do_keycode(int keycode, int down) | |
222 | +{ | |
223 | + // fprintf (stderr, "KEY: %04x %d\n", keycode, down); | |
224 | + if (keycode & 0x80) | |
225 | + kbd_put_keycode(0xe0); | |
226 | + if (down) | |
227 | + kbd_put_keycode(keycode & 0x7f); | |
228 | + else | |
229 | + kbd_put_keycode(keycode | 0x80); | |
230 | +} | |
231 | + | |
232 | +static void do_modifier(VncState *vs, int keycode, int down, int level) | |
233 | +{ | |
234 | + do_keycode(keycode, down); | |
235 | + vs->modifiers_state[level][keycode] = down; | |
236 | + if (level==0) { | |
237 | + vs->modifiers_state[1][keycode] = down; | |
238 | + } | |
239 | +} | |
240 | + | |
241 | static void reset_keys(VncState *vs) | |
242 | { | |
243 | int i; | |
244 | for(i = 0; i < 256; i++) { | |
245 | - if (vs->modifiers_state[i]) { | |
246 | - if (i & 0x80) | |
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); | |
252 | + } | |
253 | + } | |
254 | +} | |
255 | + | |
256 | +static void set_modifiers(VncState *vs, uint8_t reqstate, int down, int full) | |
257 | +{ | |
258 | + modifier_t *m; | |
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); | |
265 | + } | |
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); | |
271 | } | |
272 | } | |
273 | } | |
274 | ||
275 | +static void restore_modifiers(VncState *vs) | |
276 | +{ | |
277 | + /* Restore modifiers from reference */ | |
278 | + modifier_t *m; | |
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); | |
283 | + } | |
284 | +} | |
285 | static void press_key(VncState *vs, int keysym) | |
286 | { | |
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); | |
290 | + if (kd==NULL) | |
291 | + return; | |
292 | + | |
293 | + kbd_put_keycode(kd->keycode & 0x7f); | |
294 | + kbd_put_keycode(kd->keycode | 0x80); | |
295 | } | |
296 | ||
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) | |
299 | { | |
300 | + if (kd==NULL) | |
301 | + return; | |
302 | + | |
303 | + int keycode = kd->keycode; | |
304 | + //fprintf (stderr, "SYM: %04x SCANCODE: %04x MOD %04x\n", | |
305 | + // sym, keycode, kd->keymod); | |
306 | + | |
307 | + | |
308 | /* QEMU console switch */ | |
309 | switch(keycode) { | |
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 */ | |
315 | - if (down) | |
316 | - vs->modifiers_state[keycode] = 1; | |
317 | - else | |
318 | - vs->modifiers_state[keycode] = 0; | |
319 | - break; | |
320 | + do_modifier(vs, keycode, down, 0); | |
321 | + return; | |
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 */ | |
326 | reset_keys(vs); | |
327 | console_select(keycode - 0x02); | |
328 | return; | |
329 | } | |
330 | break; | |
331 | - case 0x3a: /* CapsLock */ | |
332 | - case 0x45: /* NumLock */ | |
333 | - if (!down) | |
334 | - vs->modifiers_state[keycode] ^= 1; | |
335 | + case 0x3a: /* CapsLock */ | |
336 | + case 0x45: /* NumLock */ | |
337 | + if (!down) { | |
338 | + if (vs->modifiers_state[0][0x45]) | |
339 | + do_modifier(vs, keycode, 0, 0); | |
340 | + else | |
341 | + do_modifier(vs, keycode, 1, 0); | |
342 | + } | |
343 | break; | |
344 | } | |
345 | ||
346 | @@ -1312,25 +1371,42 @@ | |
347 | toggles numlock away from the VNC window. | |
348 | */ | |
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); | |
355 | } | |
356 | } else { | |
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); | |
363 | } | |
364 | } | |
365 | } | |
366 | ||
367 | if (is_graphic_console()) { | |
368 | - if (keycode & 0x80) | |
369 | - kbd_put_keycode(0xe0); | |
370 | - if (down) | |
371 | - kbd_put_keycode(keycode & 0x7f); | |
372 | - else | |
373 | - kbd_put_keycode(keycode | 0x80); | |
374 | + if (down) { | |
375 | + /* Send deadkey */ | |
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); | |
384 | + } | |
385 | + } | |
386 | + set_modifiers(vs, kd->keymod, 1, 0); | |
387 | + } else | |
388 | + restore_modifiers(vs); | |
389 | + | |
390 | + do_keycode (keycode, down); | |
391 | + | |
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); | |
395 | + } | |
396 | + | |
397 | } else { | |
398 | /* QEMU console emulation */ | |
399 | if (down) { | |
400 | @@ -1388,13 +1464,9 @@ | |
401 | ||
402 | static void key_event(VncState *vs, int down, uint32_t sym) | |
403 | { | |
404 | - int keycode; | |
405 | - | |
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); | |
409 | ||
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); | |
413 | } | |
414 | ||
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 */ | |
418 | if (keyboard_layout) | |
419 | key_event(vs, down, sym); | |
420 | - else | |
421 | - do_key_event(vs, down, keycode, sym); | |
422 | + else { | |
423 | + keydata_t kd; | |
424 | + | |
425 | + kd.keycode = keycode; | |
426 | + kd.keymod = 0; | |
427 | + kd.deadsym = 0; | |
428 | + | |
429 | + do_key_event(vs, down, &kd, sym & 0xFFFF); | |
430 | + } | |
431 | } | |
432 | ||
433 | static void framebuffer_update_request(VncState *vs, int incremental, | |
434 | Index: kvm-86/vnc.h | |
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 | |
438 | @@ -49,6 +49,21 @@ | |
439 | * | |
440 | *****************************************************************************/ | |
441 | ||
442 | +typedef struct { | |
443 | + int keycode; | |
444 | + int bit; | |
445 | +} modifier_t; | |
446 | + | |
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}, | |
454 | + {0,0}, | |
455 | +}; | |
456 | + | |
457 | typedef struct Buffer | |
458 | { | |
459 | size_t capacity; | |
460 | @@ -156,7 +171,7 @@ | |
461 | VncReadEvent *read_handler; | |
462 | size_t read_handler_expect; | |
463 | /* input */ | |
464 | - uint8_t modifiers_state[256]; | |
465 | + uint8_t modifiers_state[2][256]; | |
466 | ||
467 | Buffer zlib; | |
468 | Buffer zlib_tmp; |