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


Reply via email to