[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 5/5] keymap: consider modifier state when picking a
From: |
Gerd Hoffmann |
Subject: |
[Qemu-devel] [PATCH 5/5] keymap: consider modifier state when picking a mapping |
Date: |
Fri, 16 Feb 2018 15:44:18 +0100 |
Pass the modifier state to the keymap lookup function. In case multiple
keysym -> keycode mappings exist look at the modifier state and prefer
the mapping where the modifier state matches.
Signed-off-by: Gerd Hoffmann <address@hidden>
---
ui/keymaps.h | 3 ++-
ui/curses.c | 3 ++-
ui/keymaps.c | 33 ++++++++++++++++++++++++++++++++-
ui/sdl.c | 6 +++++-
ui/vnc.c | 9 +++++++--
5 files changed, 48 insertions(+), 6 deletions(-)
diff --git a/ui/keymaps.h b/ui/keymaps.h
index 5c0898bfcf..142e40a2a4 100644
--- a/ui/keymaps.h
+++ b/ui/keymaps.h
@@ -53,7 +53,8 @@ typedef struct {
typedef struct kbd_layout_t kbd_layout_t;
kbd_layout_t* init_keyboard_layout(const name2keysym_t *table, const char
*language);
-int keysym2scancode(kbd_layout_t *k, int keysym);
+int keysym2scancode(kbd_layout_t *k, int keysym,
+ bool shift, bool altgr, bool ctrl);
int keycode_is_keypad(kbd_layout_t *k, int keycode);
int keysym_is_numlock(kbd_layout_t *k, int keysym);
diff --git a/ui/curses.c b/ui/curses.c
index 85503876c0..31cd43e73c 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -271,7 +271,8 @@ static void curses_refresh(DisplayChangeListener *dcl)
keysym = chr;
}
- keycode = keysym2scancode(kbd_layout, keysym & KEYSYM_MASK);
+ keycode = keysym2scancode(kbd_layout, keysym & KEYSYM_MASK,
+ false, false, false);
if (keycode == 0)
continue;
diff --git a/ui/keymaps.c b/ui/keymaps.c
index d22b3555dd..eb6c15b61f 100644
--- a/ui/keymaps.c
+++ b/ui/keymaps.c
@@ -181,8 +181,12 @@ kbd_layout_t* init_keyboard_layout(const name2keysym_t
*table, const char *langu
}
-int keysym2scancode(kbd_layout_t *k, int keysym)
+int keysym2scancode(kbd_layout_t *k, int keysym,
+ bool shift, bool altgr, bool ctrl)
{
+ static const uint32_t mask =
+ SCANCODE_SHIFT | SCANCODE_ALTGR | SCANCODE_CTRL;
+ uint32_t mods, i;
struct keysym2code *keysym2code;
#ifdef XK_ISO_Left_Tab
@@ -198,6 +202,33 @@ int keysym2scancode(kbd_layout_t *k, int keysym)
return 0;
}
+ if (keysym2code->count == 1) {
+ return keysym2code->keycodes[0];
+ }
+
+ /*
+ * We have multiple keysym -> keycode mappings.
+ *
+ * Check whenever we find one mapping where the modifier state of
+ * the mapping matches the current user interface modifier state.
+ * If so, prefer that one.
+ */
+ mods = 0;
+ if (shift) {
+ mods |= SCANCODE_SHIFT;
+ }
+ if (altgr) {
+ mods |= SCANCODE_ALTGR;
+ }
+ if (ctrl) {
+ mods |= SCANCODE_CTRL;
+ }
+
+ for (i = 0; i < keysym2code->count; i++) {
+ if ((keysym2code->keycodes[i] & mask) == mods) {
+ return keysym2code->keycodes[i];
+ }
+ }
return keysym2code->keycodes[0];
}
diff --git a/ui/sdl.c b/ui/sdl.c
index a6bff301eb..4c46c40a7f 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -200,6 +200,9 @@ static kbd_layout_t *kbd_layout = NULL;
static uint8_t sdl_keyevent_to_keycode_generic(const SDL_KeyboardEvent *ev)
{
+ bool shift = modifiers_state[0x2a] || modifiers_state[0x36];
+ bool altgr = modifiers_state[0xb8];
+ bool ctrl = modifiers_state[0x1d] || modifiers_state[0x9d];
int keysym;
/* workaround for X11+SDL bug with AltGR */
keysym = ev->keysym.sym;
@@ -209,7 +212,8 @@ static uint8_t sdl_keyevent_to_keycode_generic(const
SDL_KeyboardEvent *ev)
if (keysym == 92 && ev->keysym.scancode == 133) {
keysym = 0xa5;
}
- return keysym2scancode(kbd_layout, keysym) & SCANCODE_KEYMASK;
+ return keysym2scancode(kbd_layout, keysym,
+ shift, altgr, ctrl) & SCANCODE_KEYMASK;
}
diff --git a/ui/vnc.c b/ui/vnc.c
index c715bae1cf..52762f3e99 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -1728,7 +1728,8 @@ static void reset_keys(VncState *vs)
static void press_key(VncState *vs, int keysym)
{
- int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) &
SCANCODE_KEYMASK;
+ int keycode = keysym2scancode(vs->vd->kbd_layout, keysym,
+ false, false, false) & SCANCODE_KEYMASK;
qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
@@ -1987,6 +1988,9 @@ static const char *code2name(int keycode)
static void key_event(VncState *vs, int down, uint32_t sym)
{
+ bool shift = vs->modifiers_state[0x2a] || vs->modifiers_state[0x36];
+ bool altgr = vs->modifiers_state[0xb8];
+ bool ctrl = vs->modifiers_state[0x1d] || vs->modifiers_state[0x9d];
int keycode;
int lsym = sym;
@@ -1994,7 +1998,8 @@ static void key_event(VncState *vs, int down, uint32_t
sym)
lsym = lsym - 'A' + 'a';
}
- keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) &
SCANCODE_KEYMASK;
+ keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF,
+ shift, altgr, ctrl) & SCANCODE_KEYMASK;
trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
do_key_event(vs, down, keycode, sym);
}
--
2.9.3