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
commit9702c185b235223b9004b64eb6c2f913f83a6462 (patch)
treeaf903aa7fefee375f864d08b603c2ed5fea77b75 /sdl.c
parent49cb7bcd7f7d310c04ae194a5c29c683bfb010d1 (diff)
downloadqemu-9702c185b235223b9004b64eb6c2f913f83a6462.tar.gz
qemu-9702c185b235223b9004b64eb6c2f913f83a6462.tar.bz2
qemu-9702c185b235223b9004b64eb6c2f913f83a6462.zip
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;
}