ui: fix keymap detection under Xwayland

The X11 code currently detects the keymap by looking for the keycode
name property. Unfortunately due to the way Xwayland handles keyboards,
this property gets unset almost immediately after the first application
starts using Xwayland resulting in

  ** (qemu-system-x86_64:19644): WARNING **: Unknown X11 keycode mapping '(unnamed)'.
  Please report to qemu-devel@nongnu.org
  including the following information:

    - Operating system
    - X11 Server
    - xprop -root
    - xdpyinfo

Fortunately people will only see this problem if they built QEMU with
GTK2, or have told GTK3 to prefer X11 by setting the GDK_BACKEND=x11
env variable.

To workaround the problem, we add a heuristic that looks at what
scancode the XK_Page_Up keysymbol maps to, to determine if we've
likely got the X11 kbd or evdev driver.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20180313104235.20725-1-berrange@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2018-03-13 10:42:35 +00:00 committed by Gerd Hoffmann
parent 915d34c5f9
commit 1e70de679d

View File

@ -17,6 +17,7 @@
#include "ui/input.h" #include "ui/input.h"
#include <X11/XKBlib.h> #include <X11/XKBlib.h>
#include <X11/Xutil.h>
static gboolean check_for_xwin(Display *dpy) static gboolean check_for_xwin(Display *dpy)
{ {
@ -87,11 +88,13 @@ const guint16 *qemu_xkeymap_mapping_table(Display *dpy, size_t *maplen)
trace_xkeymap_keymap("xquartz"); trace_xkeymap_keymap("xquartz");
*maplen = qemu_input_map_xorgxquartz_to_qcode_len; *maplen = qemu_input_map_xorgxquartz_to_qcode_len;
return qemu_input_map_xorgxquartz_to_qcode; return qemu_input_map_xorgxquartz_to_qcode;
} else if (keycodes && g_str_has_prefix(keycodes, "evdev")) { } else if ((keycodes && g_str_has_prefix(keycodes, "evdev")) ||
(XKeysymToKeycode(dpy, XK_Page_Up) == 0x70)) {
trace_xkeymap_keymap("evdev"); trace_xkeymap_keymap("evdev");
*maplen = qemu_input_map_xorgevdev_to_qcode_len; *maplen = qemu_input_map_xorgevdev_to_qcode_len;
return qemu_input_map_xorgevdev_to_qcode; return qemu_input_map_xorgevdev_to_qcode;
} else if (keycodes && g_str_has_prefix(keycodes, "xfree86")) { } else if ((keycodes && g_str_has_prefix(keycodes, "xfree86")) ||
(XKeysymToKeycode(dpy, XK_Page_Up) == 0x63)) {
trace_xkeymap_keymap("kbd"); trace_xkeymap_keymap("kbd");
*maplen = qemu_input_map_xorgkbd_to_qcode_len; *maplen = qemu_input_map_xorgkbd_to_qcode_len;
return qemu_input_map_xorgkbd_to_qcode; return qemu_input_map_xorgkbd_to_qcode;