aboutsummaryrefslogtreecommitdiff
path: root/curses.c
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@gnu.org>2010-02-28 21:03:00 +0100
committerAurelien Jarno <aurelien@aurel32.net>2010-03-06 23:15:30 +0100
commit44bb61c8d9ad5fa0045465933b1ac8f2b1b98762 (patch)
tree34784bea640f307a4dd6c1e4bedf86cc937b97f3 /curses.c
parent9d0706e44a14701e8449214c4a62a5a1ca370025 (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.c89
1 files changed, 44 insertions, 45 deletions
diff --git a/curses.c b/curses.c
index 3ce12b9237..4b5beac1dc 100644
--- a/curses.c
+++ b/curses.c
@@ -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)