diff options
author | Samuel Thibault <samuel.thibault@gnu.org> | 2010-02-28 21:03:00 +0100 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2010-03-06 23:15:30 +0100 |
commit | 44bb61c8d9ad5fa0045465933b1ac8f2b1b98762 (patch) | |
tree | 34784bea640f307a4dd6c1e4bedf86cc937b97f3 /curses.c | |
parent | 9d0706e44a14701e8449214c4a62a5a1ca370025 (diff) |
Fix curses interaction with keymaps
The combination of keymap support (-k option) and curses is currently
very broken. The patch below fixes it by first extending keymap support
to interpret the shift, ctrl, altgr and addupper keywords in keymaps,
and to fix curses into properly using keymaps.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Diffstat (limited to 'curses.c')
-rw-r--r-- | curses.c | 89 |
1 files changed, 44 insertions, 45 deletions
@@ -159,11 +159,10 @@ static void curses_cursor_position(DisplayState *ds, int x, int y) #include "curses_keys.h" static kbd_layout_t *kbd_layout = NULL; -static int keycode2keysym[CURSES_KEYS]; static void curses_refresh(DisplayState *ds) { - int chr, nextchr, keysym, keycode; + int chr, nextchr, keysym, keycode, keycode_alt; if (invalidate) { clear(); @@ -204,43 +203,58 @@ static void curses_refresh(DisplayState *ds) #endif keycode = curses2keycode[chr]; - if (keycode == -1) - continue; + keycode_alt = 0; /* alt key */ if (keycode == 1) { nextchr = getch(); if (nextchr != ERR) { + chr = nextchr; + keycode_alt = ALT; keycode = curses2keycode[nextchr]; nextchr = ERR; - if (keycode == -1) - continue; - keycode |= ALT; + if (keycode != -1) { + keycode |= ALT; - /* process keys reserved for qemu */ - if (keycode >= QEMU_KEY_CONSOLE0 && - keycode < QEMU_KEY_CONSOLE0 + 9) { - erase(); - wnoutrefresh(stdscr); - console_select(keycode - QEMU_KEY_CONSOLE0); + /* process keys reserved for qemu */ + if (keycode >= QEMU_KEY_CONSOLE0 && + keycode < QEMU_KEY_CONSOLE0 + 9) { + erase(); + wnoutrefresh(stdscr); + console_select(keycode - QEMU_KEY_CONSOLE0); - invalidate = 1; - continue; + invalidate = 1; + continue; + } } } } - if (kbd_layout && !(keycode & GREY)) { - keysym = keycode2keysym[keycode & KEY_MASK]; - if (keysym == -1) - keysym = chr; + if (kbd_layout) { + keysym = -1; + if (chr < CURSES_KEYS) + keysym = curses2keysym[chr]; + + if (keysym == -1) { + if (chr < ' ') + keysym = (chr + '@' - 'A' + 'a') | KEYSYM_CNTRL; + else + keysym = chr; + } - keycode &= ~KEY_MASK; - keycode |= keysym2scancode(kbd_layout, keysym); + keycode = keysym2scancode(kbd_layout, keysym & KEYSYM_MASK); + if (keycode == 0) + continue; + + keycode |= (keysym & ~KEYSYM_MASK) >> 16; + keycode |= keycode_alt; } + if (keycode == -1) + continue; + if (is_graphic_console()) { /* since terminals don't know about key press and release * events, we need to emit both for each key received */ @@ -250,12 +264,20 @@ static void curses_refresh(DisplayState *ds) kbd_put_keycode(CNTRL_CODE); if (keycode & ALT) kbd_put_keycode(ALT_CODE); + if (keycode & ALTGR) { + kbd_put_keycode(SCANCODE_EMUL0); + kbd_put_keycode(ALT_CODE); + } if (keycode & GREY) kbd_put_keycode(GREY_CODE); kbd_put_keycode(keycode & KEY_MASK); if (keycode & GREY) kbd_put_keycode(GREY_CODE); kbd_put_keycode((keycode & KEY_MASK) | KEY_RELEASE); + if (keycode & ALTGR) { + kbd_put_keycode(SCANCODE_EMUL0); + kbd_put_keycode(ALT_CODE | KEY_RELEASE); + } if (keycode & ALT) kbd_put_keycode(ALT_CODE | KEY_RELEASE); if (keycode & CNTRL) @@ -263,7 +285,7 @@ static void curses_refresh(DisplayState *ds) if (keycode & SHIFT) kbd_put_keycode(SHIFT_CODE | KEY_RELEASE); } else { - keysym = curses2keysym[chr]; + keysym = curses2qemu[chr]; if (keysym == -1) keysym = chr; @@ -301,8 +323,6 @@ static void curses_setup(void) static void curses_keyboard_setup(void) { - int i, keycode, keysym; - #if defined(__APPLE__) /* always use generic keymaps */ if (!keyboard_layout) @@ -313,27 +333,6 @@ static void curses_keyboard_setup(void) if (!kbd_layout) exit(1); } - - for (i = 0; i < CURSES_KEYS; i ++) - keycode2keysym[i] = -1; - - for (i = 0; i < CURSES_KEYS; i ++) { - if (curses2keycode[i] == -1) - continue; - - keycode = curses2keycode[i] & KEY_MASK; - if (keycode2keysym[keycode] >= 0) - continue; - - for (keysym = 0; keysym < CURSES_KEYS; keysym ++) - if (curses2keycode[keysym] == keycode) { - keycode2keysym[keycode] = keysym; - break; - } - - if (keysym >= CURSES_KEYS) - keycode2keysym[keycode] = i; - } } void curses_display_init(DisplayState *ds, int full_screen) |