From: Akihiko Odaki <[email protected]> QemuInputEvent now stores Linux key codes for key events. Use those codes directly instead of translating between internal key code representations.
Signed-off-by: Akihiko Odaki <[email protected]> Reviewed-by: Marc-André Lureau <[email protected]> Message-ID: <[email protected]> --- ui/x_keymap.h | 3 ++- ui/gtk.c | 51 ++++++++++++++++++++++++++++--------------------- ui/x_keymap.c | 24 ++++++++++++----------- ui/trace-events | 2 +- 4 files changed, 45 insertions(+), 35 deletions(-) diff --git a/ui/x_keymap.h b/ui/x_keymap.h index 0395e335fff..0d58459dd21 100644 --- a/ui/x_keymap.h +++ b/ui/x_keymap.h @@ -27,6 +27,7 @@ #include <X11/Xlib.h> -const guint16 *qemu_xkeymap_mapping_table(Display *dpy, size_t *maplen); +const guint16 *qemu_xkeymap_mapping_table(Display *dpy, size_t *maplen, + bool *evdev); #endif diff --git a/ui/gtk.c b/ui/gtk.c index 757ee80fa6a..9f9b2416c8a 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -55,6 +55,7 @@ #include <math.h> #include "trace.h" +#include "standard-headers/linux/input-event-codes.h" #include "ui/input.h" #include "system/runstate.h" #include "system/system.h" @@ -120,6 +121,7 @@ static const guint16 *keycode_map; static size_t keycode_maplen; +static bool keycode_xorgevdev; struct VCChardev { Chardev parent; @@ -1211,39 +1213,42 @@ static gboolean gd_touch_event(GtkWidget *widget, GdkEventTouch *touch, return TRUE; } -static const guint16 *gd_get_keymap(size_t *maplen) +static const guint16 *gd_get_keymap(size_t *maplen, bool *xorgevdev) { GdkDisplay *dpy = gdk_display_get_default(); + *maplen = 0; + *xorgevdev = false; + #ifdef GDK_WINDOWING_X11 if (GDK_IS_X11_DISPLAY(dpy)) { trace_gd_keymap_windowing("x11"); return qemu_xkeymap_mapping_table( - gdk_x11_display_get_xdisplay(dpy), maplen); + gdk_x11_display_get_xdisplay(dpy), maplen, xorgevdev); } #endif #ifdef GDK_WINDOWING_WAYLAND if (GDK_IS_WAYLAND_DISPLAY(dpy)) { trace_gd_keymap_windowing("wayland"); - *maplen = qemu_input_map_xorgevdev_to_qcode_len; - return qemu_input_map_xorgevdev_to_qcode; + *xorgevdev = true; + return NULL; } #endif #ifdef GDK_WINDOWING_WIN32 if (GDK_IS_WIN32_DISPLAY(dpy)) { trace_gd_keymap_windowing("win32"); - *maplen = qemu_input_map_atset1_to_qcode_len; - return qemu_input_map_atset1_to_qcode; + *maplen = qemu_input_map_atset1_to_linux_len; + return qemu_input_map_atset1_to_linux; } #endif #ifdef GDK_WINDOWING_QUARTZ if (GDK_IS_QUARTZ_DISPLAY(dpy)) { trace_gd_keymap_windowing("quartz"); - *maplen = qemu_input_map_osx_to_qcode_len; - return qemu_input_map_osx_to_qcode; + *maplen = qemu_input_map_osx_to_linux_len; + return qemu_input_map_osx_to_linux; } #endif @@ -1253,8 +1258,8 @@ static const guint16 *gd_get_keymap(size_t *maplen) g_warning("experimental: using broadway, x11 virtual keysym\n" "mapping - with very limited support. See also\n" "https://bugzilla.gnome.org/show_bug.cgi?id=700105"); - *maplen = qemu_input_map_x11_to_qcode_len; - return qemu_input_map_x11_to_qcode; + *maplen = qemu_input_map_x11_to_linux_len; + return qemu_input_map_x11_to_linux; } #endif @@ -1269,8 +1274,11 @@ static const guint16 *gd_get_keymap(size_t *maplen) } -static int gd_map_keycode(int scancode) +static unsigned int gd_map_keycode(int scancode) { + if (keycode_xorgevdev) { + return scancode < 8 ? KEY_RESERVED : scancode - 8; + } if (!keycode_map) { return 0; } @@ -1307,12 +1315,12 @@ static gboolean gd_text_key_down(GtkWidget *widget, QemuTextConsole *con = QEMU_TEXT_CONSOLE(vc->gfx.dcl.con); if (key->keyval == GDK_KEY_Delete) { - qemu_text_console_put_qcode(con, Q_KEY_CODE_DELETE, false); + qemu_text_console_put_linux(con, KEY_DELETE, false); } else if (key->length) { qemu_text_console_put_string(con, key->string, key->length); } else { - int qcode = gd_map_keycode(gd_get_keycode(key)); - qemu_text_console_put_qcode(con, qcode, false); + unsigned int lnx = gd_map_keycode(gd_get_keycode(key)); + qemu_text_console_put_linux(con, lnx, false); } return TRUE; } @@ -1320,7 +1328,8 @@ static gboolean gd_text_key_down(GtkWidget *widget, static gboolean gd_key_event(GtkWidget *widget, GdkEventKey *key, void *opaque) { VirtualConsole *vc = opaque; - int keycode, qcode; + int keycode; + unsigned int lnx; #ifdef G_OS_WIN32 /* on windows, we ought to ignore the reserved key event? */ @@ -1343,20 +1352,18 @@ static gboolean gd_key_event(GtkWidget *widget, GdkEventKey *key, void *opaque) || key->hardware_keycode == VK_PAUSE #endif ) { - qkbd_state_key_event(vc->gfx.kbd, - qemu_input_map_qcode_to_linux[Q_KEY_CODE_PAUSE], + qkbd_state_key_event(vc->gfx.kbd, KEY_PAUSE, key->type == GDK_KEY_PRESS); return TRUE; } keycode = gd_get_keycode(key); - qcode = gd_map_keycode(keycode); + lnx = gd_map_keycode(keycode); - trace_gd_key_event(vc->label, keycode, qemu_input_map_qcode_to_linux[qcode], + trace_gd_key_event(vc->label, keycode, lnx, (key->type == GDK_KEY_PRESS) ? "down" : "up"); - qkbd_state_key_event(vc->gfx.kbd, qemu_input_map_qcode_to_linux[qcode], - key->type == GDK_KEY_PRESS); + qkbd_state_key_event(vc->gfx.kbd, lnx, key->type == GDK_KEY_PRESS); return TRUE; } @@ -2660,7 +2667,7 @@ static void early_gtk_display_init(DisplayOptions *opts) #endif } - keycode_map = gd_get_keymap(&keycode_maplen); + keycode_map = gd_get_keymap(&keycode_maplen, &keycode_xorgevdev); #if defined(CONFIG_VTE) type_register_static(&char_gd_vc_type_info); diff --git a/ui/x_keymap.c b/ui/x_keymap.c index 2ce7b899615..f7dc2edb91d 100644 --- a/ui/x_keymap.c +++ b/ui/x_keymap.c @@ -52,11 +52,12 @@ static gboolean check_for_xquartz(Display *dpy) return match; } -const guint16 *qemu_xkeymap_mapping_table(Display *dpy, size_t *maplen) +const guint16 *qemu_xkeymap_mapping_table(Display *dpy, size_t *maplen, + bool *evdev) { XkbDescPtr desc; const gchar *keycodes = NULL; - const guint16 *map; + const guint16 *map = NULL; /* There is no easy way to determine what X11 server * and platform & keyboard driver is in use. Thus we @@ -81,24 +82,26 @@ const guint16 *qemu_xkeymap_mapping_table(Display *dpy, size_t *maplen) XkbFreeKeyboard(desc, XkbGBN_AllComponentsMask, True); } + *maplen = 0; + *evdev = false; + if (check_for_xwin(dpy)) { trace_xkeymap_keymap("xwin"); - *maplen = qemu_input_map_xorgxwin_to_qcode_len; - map = qemu_input_map_xorgxwin_to_qcode; + *maplen = qemu_input_map_xorgxwin_to_linux_len; + map = qemu_input_map_xorgxwin_to_linux; } else if (check_for_xquartz(dpy)) { trace_xkeymap_keymap("xquartz"); - *maplen = qemu_input_map_xorgxquartz_to_qcode_len; - map = qemu_input_map_xorgxquartz_to_qcode; + *maplen = qemu_input_map_xorgxquartz_to_linux_len; + map = qemu_input_map_xorgxquartz_to_linux; } else if ((keycodes && g_str_has_prefix(keycodes, "evdev")) || (XKeysymToKeycode(dpy, XK_Page_Up) == 0x70)) { trace_xkeymap_keymap("evdev"); - *maplen = qemu_input_map_xorgevdev_to_qcode_len; - map = qemu_input_map_xorgevdev_to_qcode; + *evdev = true; } else if ((keycodes && g_str_has_prefix(keycodes, "xfree86")) || (XKeysymToKeycode(dpy, XK_Page_Up) == 0x63)) { trace_xkeymap_keymap("kbd"); - *maplen = qemu_input_map_xorgkbd_to_qcode_len; - map = qemu_input_map_xorgkbd_to_qcode; + *maplen = qemu_input_map_xorgkbd_to_linux_len; + map = qemu_input_map_xorgkbd_to_linux; } else { trace_xkeymap_keymap("NULL"); g_warning("Unknown X11 keycode mapping '%s'.\n" @@ -110,7 +113,6 @@ const guint16 *qemu_xkeymap_mapping_table(Display *dpy, size_t *maplen) " - xprop -root\n" " - xdpyinfo\n", keycodes ? keycodes : "<null>"); - map = NULL; } if (keycodes) { XFree((void *)keycodes); diff --git a/ui/trace-events b/ui/trace-events index 1c0d96a92c3..237f5a65af2 100644 --- a/ui/trace-events +++ b/ui/trace-events @@ -22,7 +22,7 @@ ppm_save(int fd, void *image) "fd=%d image=%p" # gtk.c gd_switch(const char *tab, int width, int height) "tab=%s, width=%d, height=%d" gd_update(const char *tab, int x, int y, int w, int h) "tab=%s, x=%d, y=%d, w=%d, h=%d" -gd_key_event(const char *tab, int gdk_keycode, int qkeycode, const char *action) "tab=%s, translated GDK keycode %d to QKeyCode %d (%s)" +gd_key_event(const char *tab, int gdk_keycode, unsigned int lnx, const char *action) "tab=%s, translated GDK keycode %d to Linux %u (%s)" gd_grab(const char *tab, const char *device, const char *reason) "tab=%s, dev=%s, reason=%s" gd_ungrab(const char *tab, const char *device) "tab=%s, dev=%s" gd_keymap_windowing(const char *name) "backend=%s" -- 2.54.0
