summaryrefslogtreecommitdiff
path: root/sdl.c
diff options
context:
space:
mode:
authoraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2009-03-03 17:37:21 +0000
committeraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2009-03-03 17:37:21 +0000
commit5368a4228ff5dd5ec95d0416f23bcfc9e556f37b (patch)
treeaf903aa7fefee375f864d08b603c2ed5fea77b75 /sdl.c
parent71d0770c4cec9f1dc04f4dadcbf7fd6c335030a9 (diff)
downloadqemu-5368a4228ff5dd5ec95d0416f23bcfc9e556f37b.tar.gz
Fix SDL on evdev hosts (Anthony Liguori)
This patch corrects SDL support on X11 hosts using evdev. It's losely based on the previous patch by Dustin Kirkland and the evdev support code in gtk-vnc written by Daniel Berrange. Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6678 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'sdl.c')
-rw-r--r--sdl.c58
1 files changed, 56 insertions, 2 deletions
diff --git a/sdl.c b/sdl.c
index 266fbcc8c5..c685b81f6f 100644
--- a/sdl.c
+++ b/sdl.c
@@ -24,8 +24,10 @@
#include "qemu-common.h"
#include "console.h"
#include "sysemu.h"
+#include "x_keymap.h"
#include <SDL.h>
+#include <SDL/SDL_syswm.h>
#ifndef _WIN32
#include <signal.h>
@@ -136,9 +138,54 @@ static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
#else
+#if defined(SDL_VIDEO_DRIVER_X11)
+#include <X11/XKBlib.h>
+
+static int check_for_evdev(void)
+{
+ SDL_SysWMinfo info;
+ XkbDescPtr desc;
+ int has_evdev = 0;
+ const char *keycodes;
+
+ SDL_VERSION(&info.version);
+ if (!SDL_GetWMInfo(&info))
+ return 0;
+
+ desc = XkbGetKeyboard(info.info.x11.display,
+ XkbGBN_AllComponentsMask,
+ XkbUseCoreKbd);
+ if (desc == NULL || desc->names == NULL)
+ return 0;
+
+ 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);
+
+ XkbFreeClientMap(desc, XkbGBN_AllComponentsMask, True);
+
+ return has_evdev;
+}
+#else
+static int check_for_evdev(void)
+{
+ return 0;
+}
+#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;
@@ -146,9 +193,16 @@ static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
keycode = 0;
} else if (keycode < 97) {
keycode -= 8; /* just an offset */
- } else if (keycode < 212) {
+ } else if (keycode < 158) {
/* use conversion table */
- keycode = _translate_keycode(keycode - 97);
+ 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;
}