keymap: consider modifier state when picking a mapping
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 <kraxel@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Message-id: 20180222070513.8740-6-kraxel@redhat.com
This commit is contained in:
parent
23ad24e48c
commit
abb4f2c965
@ -271,7 +271,8 @@ static void curses_refresh(DisplayChangeListener *dcl)
|
|||||||
keysym = chr;
|
keysym = chr;
|
||||||
}
|
}
|
||||||
|
|
||||||
keycode = keysym2scancode(kbd_layout, keysym & KEYSYM_MASK);
|
keycode = keysym2scancode(kbd_layout, keysym & KEYSYM_MASK,
|
||||||
|
false, false, false);
|
||||||
if (keycode == 0)
|
if (keycode == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
33
ui/keymaps.c
33
ui/keymaps.c
@ -176,8 +176,12 @@ kbd_layout_t *init_keyboard_layout(const name2keysym_t *table,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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;
|
struct keysym2code *keysym2code;
|
||||||
|
|
||||||
#ifdef XK_ISO_Left_Tab
|
#ifdef XK_ISO_Left_Tab
|
||||||
@ -193,6 +197,33 @@ int keysym2scancode(kbd_layout_t *k, int keysym)
|
|||||||
return 0;
|
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];
|
return keysym2code->keycodes[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,8 @@ typedef struct kbd_layout_t kbd_layout_t;
|
|||||||
|
|
||||||
kbd_layout_t *init_keyboard_layout(const name2keysym_t *table,
|
kbd_layout_t *init_keyboard_layout(const name2keysym_t *table,
|
||||||
const char *language);
|
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 keycode_is_keypad(kbd_layout_t *k, int keycode);
|
||||||
int keysym_is_numlock(kbd_layout_t *k, int keysym);
|
int keysym_is_numlock(kbd_layout_t *k, int keysym);
|
||||||
|
|
||||||
|
6
ui/sdl.c
6
ui/sdl.c
@ -201,6 +201,9 @@ static kbd_layout_t *kbd_layout = NULL;
|
|||||||
|
|
||||||
static uint8_t sdl_keyevent_to_keycode_generic(const SDL_KeyboardEvent *ev)
|
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;
|
int keysym;
|
||||||
/* workaround for X11+SDL bug with AltGR */
|
/* workaround for X11+SDL bug with AltGR */
|
||||||
keysym = ev->keysym.sym;
|
keysym = ev->keysym.sym;
|
||||||
@ -210,7 +213,8 @@ static uint8_t sdl_keyevent_to_keycode_generic(const SDL_KeyboardEvent *ev)
|
|||||||
if (keysym == 92 && ev->keysym.scancode == 133) {
|
if (keysym == 92 && ev->keysym.scancode == 133) {
|
||||||
keysym = 0xa5;
|
keysym = 0xa5;
|
||||||
}
|
}
|
||||||
return keysym2scancode(kbd_layout, keysym) & SCANCODE_KEYMASK;
|
return keysym2scancode(kbd_layout, keysym,
|
||||||
|
shift, altgr, ctrl) & SCANCODE_KEYMASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
9
ui/vnc.c
9
ui/vnc.c
@ -1734,7 +1734,8 @@ static void reset_keys(VncState *vs)
|
|||||||
|
|
||||||
static void press_key(VncState *vs, int keysym)
|
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_number(vs->vd->dcl.con, keycode, true);
|
||||||
qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
|
qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
|
||||||
qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
|
qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
|
||||||
@ -1993,6 +1994,9 @@ static const char *code2name(int keycode)
|
|||||||
|
|
||||||
static void key_event(VncState *vs, int down, uint32_t sym)
|
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 keycode;
|
||||||
int lsym = sym;
|
int lsym = sym;
|
||||||
|
|
||||||
@ -2000,7 +2004,8 @@ static void key_event(VncState *vs, int down, uint32_t sym)
|
|||||||
lsym = lsym - 'A' + 'a';
|
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));
|
trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
|
||||||
do_key_event(vs, down, keycode, sym);
|
do_key_event(vs, down, keycode, sym);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user