summary refs log tree commit diff stats
path: root/ui/sdl.c
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2018-01-17 16:47:15 +0000
committerGerd Hoffmann <kraxel@redhat.com>2018-01-25 15:02:00 +0100
commit2ec78706d188df7d3dab43d07b19b05ef7800a44 (patch)
tree1c569f88ce17ab70fc1bf5f4940719705438b2fc /ui/sdl.c
parented7b2624f241b58ca9e5437470339d60bf87e231 (diff)
downloadfocaccia-qemu-2ec78706d188df7d3dab43d07b19b05ef7800a44.tar.gz
focaccia-qemu-2ec78706d188df7d3dab43d07b19b05ef7800a44.zip
ui: convert GTK and SDL1 frontends to keycodemapdb
The x_keycode_to_pc_keycode and evdev_keycode_to_pc_keycode
tables are replaced with automatically generated tables.
In addition the X11 heuristics are improved to detect running
on XQuartz and XWin X11 servers, to activate the correct OS-X
and Win32 keycode maps.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Message-id: 20180117164717.15855-3-berrange@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'ui/sdl.c')
-rw-r--r--ui/sdl.c105
1 files changed, 31 insertions, 74 deletions
diff --git a/ui/sdl.c b/ui/sdl.c
index 7b71a9ac58..afb4992da2 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -34,7 +34,9 @@
 #include "ui/console.h"
 #include "ui/input.h"
 #include "sysemu/sysemu.h"
+#ifndef WIN32
 #include "x_keymap.h"
+#endif
 #include "sdl_zoom.h"
 
 static DisplayChangeListener *dcl;
@@ -63,6 +65,8 @@ static SDL_PixelFormat host_format;
 static int scaling_active = 0;
 static Notifier mouse_mode_notifier;
 static int idle_counter;
+static const guint16 *keycode_map;
+static size_t keycode_maplen;
 
 #define SDL_REFRESH_INTERVAL_BUSY 10
 #define SDL_MAX_IDLE_COUNT (2 * GUI_REFRESH_INTERVAL_DEFAULT \
@@ -208,94 +212,45 @@ static uint8_t sdl_keyevent_to_keycode_generic(const SDL_KeyboardEvent *ev)
     return keysym2scancode(kbd_layout, keysym) & SCANCODE_KEYMASK;
 }
 
-/* specific keyboard conversions from scan codes */
-
-#if defined(_WIN32)
 
-static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
+static const guint16 *sdl_get_keymap(size_t *maplen)
 {
-    return ev->keysym.scancode;
-}
-
+#if defined(WIN32)
+    *maplen = qemu_input_map_atset1_to_qcode_len;
+    return qemu_input_map_atset1_to_qcode;
 #else
-
 #if defined(SDL_VIDEO_DRIVER_X11)
-#include <X11/XKBlib.h>
-
-static int check_for_evdev(void)
-{
     SDL_SysWMinfo info;
-    XkbDescPtr desc = NULL;
-    int has_evdev = 0;
-    char *keycodes = NULL;
 
     SDL_VERSION(&info.version);
-    if (!SDL_GetWMInfo(&info)) {
-        return 0;
+    if (SDL_GetWMInfo(&info) > 0) {
+        return qemu_xkeymap_mapping_table(
+            info.info.x11.display, maplen);
     }
-    desc = XkbGetMap(info.info.x11.display,
-                     XkbGBN_AllComponentsMask,
-                     XkbUseCoreKbd);
-    if (desc &&
-        (XkbGetNames(info.info.x11.display,
-                     XkbKeycodesNameMask, desc) == Success)) {
-        keycodes = XGetAtomName(info.info.x11.display, desc->names->keycodes);
-        if (keycodes == NULL) {
-            fprintf(stderr, "could not lookup keycode name\n");
-        } else if (strstart(keycodes, "evdev", NULL)) {
-            has_evdev = 1;
-        } else if (!strstart(keycodes, "xfree86", NULL)) {
-            fprintf(stderr, "unknown keycodes `%s', please report to "
-                    "qemu-devel@nongnu.org\n", keycodes);
-        }
-    }
-
-    if (desc) {
-        XkbFreeKeyboard(desc, XkbGBN_AllComponentsMask, True);
-    }
-    if (keycodes) {
-        XFree(keycodes);
-    }
-    return has_evdev;
-}
-#else
-static int check_for_evdev(void)
-{
-	return 0;
-}
 #endif
+    g_warning("Unsupported SDL video driver / platform.\n"
+              "Assuming Linux KBD scancodes, but probably wrong.\n"
+              "Please report to qemu-devel@nongnu.org\n"
+              "including the following information:\n"
+              "\n"
+              "  - Operating system\n"
+              "  - SDL video driver\n");
+    *maplen = qemu_input_map_xorgkbd_to_qcode_len;
+    return qemu_input_map_xorgkbd_to_qcode;
+#endif
+}
 
 static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
 {
-    int keycode;
-    static int has_evdev = -1;
-
-    if (has_evdev == -1)
-        has_evdev = check_for_evdev();
-
-    keycode = ev->keysym.scancode;
-
-    if (keycode < 9) {
-        keycode = 0;
-    } else if (keycode < 97) {
-        keycode -= 8; /* just an offset */
-    } else if (keycode < 158) {
-        /* use conversion table */
-        if (has_evdev)
-            keycode = translate_evdev_keycode(keycode - 97);
-        else
-            keycode = translate_xfree86_keycode(keycode - 97);
-    } else if (keycode == 208) { /* Hiragana_Katakana */
-        keycode = 0x70;
-    } else if (keycode == 211) { /* backslash */
-        keycode = 0x73;
-    } else {
-        keycode = 0;
+    if (!keycode_map) {
+        return 0;
+    }
+    if (ev->keysym.scancode > keycode_maplen) {
+        return 0;
     }
-    return keycode;
-}
 
-#endif
+    return keycode_map[ev->keysym.scancode];
+}
 
 static void reset_keys(void)
 {
@@ -995,6 +950,8 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
     vi = SDL_GetVideoInfo();
     host_format = *(vi->vfmt);
 
+    keycode_map = sdl_get_keymap(&keycode_maplen);
+
     /* Load a 32x32x4 image. White pixels are transparent. */
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "qemu-icon.bmp");
     if (filename) {