mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-12-11 16:00:50 -07:00
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>
This commit is contained in:
parent
9d0706e44a
commit
44bb61c8d9
6 changed files with 149 additions and 94 deletions
89
curses.c
89
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];
|
||||
|
||||
keycode &= ~KEY_MASK;
|
||||
keycode |= keysym2scancode(kbd_layout, keysym);
|
||||
if (keysym == -1) {
|
||||
if (chr < ' ')
|
||||
keysym = (chr + '@' - 'A' + 'a') | KEYSYM_CNTRL;
|
||||
else
|
||||
keysym = chr;
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue