diff -r 17723c0b042b keymaps.c --- a/keymaps.c Thu Sep 02 16:40:39 2010 +0800 +++ b/keymaps.c Thu Sep 02 17:26:53 2010 +0800 @@ -51,6 +51,7 @@ struct key_range *numlock_range; struct key_range *shift_range; struct key_range *localstate_range; + struct key_range *altgr_range; } kbd_layout_t; static void add_to_key_range(struct key_range **krp, int code) { @@ -133,7 +134,11 @@ add_to_key_range(&k->localstate_range, keycode); //fprintf(stderr, "localstate keysym %04x keycode %d\n", keysym, keycode); } - + if (rest && strstr(rest, "altgr")) { + add_to_key_range(&k->altgr_range, keysym); + //fprintf(stderr, "altgr keysym %04x keycode %d\n", keysym, keycode); + } + /* if(keycode&0x80) keycode=(keycode<<8)^0x80e0; */ if (keysym < MAX_NORMAL_KEYCODE) { @@ -233,3 +238,16 @@ return 0; return 1; } + +static inline int keysym_is_altgr(void *kbd_layout, int keysym) +{ + kbd_layout_t *k = kbd_layout; + struct key_range *kr; + + for (kr = k->altgr_range; kr; kr = kr->next) + if (keysym >= kr->start && keysym <= kr->end){ + return 1; + } + return 0; +} + diff -r 17723c0b042b vnc.c --- a/vnc.c Thu Sep 02 16:40:39 2010 +0800 +++ b/vnc.c Thu Sep 02 17:26:53 2010 +0800 @@ -1274,12 +1274,27 @@ } } +static void press_key_altgr_down(VncState *vs, int down) +{ + kbd_put_keycode(0xe0); + if (down){ + kbd_put_keycode(0xb8 & 0x7f); + vs->modifiers_state[0xb8] = 1; + } + else { + kbd_put_keycode(0xb8 | 0x80); + vs->modifiers_state[0xb8] = 0; + } +} + static void do_key_event(VncState *vs, int down, uint32_t sym) { int keycode; int shift_keys = 0; int shift = 0; int keypad = 0; + int altgr = 0; + int altgr_keys = 0; if (is_graphic_console()) { if (sym >= 'A' && sym <= 'Z') { @@ -1289,8 +1304,11 @@ else { shift = keysym_is_shift(vs->kbd_layout, sym & 0xFFFF); } + + altgr = keysym_is_altgr(vs->kbd_layout, sym & 0xFFFF); } shift_keys = vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]; + altgr_keys = vs->modifiers_state[0xb8]; keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF); if (keycode == 0) { @@ -1357,6 +1375,11 @@ } if (is_graphic_console()) { + + if (altgr && !altgr_keys) { + press_key_altgr_down(vs, down); + } + /* If the shift state needs to change then simulate an additional keypress before sending this one. Ignore for non shiftable keys. */