# This code was ported from gtk-vnc, to handle evdev keycode mapping by # Dustin Kirkland , 24 September 2008. --- kvm-72+dfsg/qemu/configure 2008-07-27 08:20:10.000000000 -0500 +++ kvm-72+dfsg/qemu/configure 2008-09-24 16:04:28.036791147 -0500 @@ -1198,9 +1198,9 @@ if test "$sdl1" = "yes" ; then echo "#define CONFIG_SDL 1" >> $config_h echo "CONFIG_SDL=yes" >> $config_mak if test "$target_softmmu" = "no" -o "$static" = "yes"; then - echo "SDL_LIBS=$sdl_static_libs" >> $config_mak + echo "SDL_LIBS=-lX11 $sdl_static_libs" >> $config_mak else - echo "SDL_LIBS=`$sdl_config --libs`" >> $config_mak + echo "SDL_LIBS=-lX11 `$sdl_config --libs`" >> $config_mak fi if [ "${aa}" = "yes" ] ; then echo "SDL_CFLAGS=`$sdl_config --cflags` `aalib-config --cflags`" >> $config_mak --- kvm-72+dfsg/qemu/sdl.c 2008-07-27 05:08:56.000000000 -0500 +++ kvm-72+dfsg/qemu/sdl.c 2008-09-24 16:39:19.713788782 -0500 @@ -132,21 +132,7 @@ static uint8_t sdl_keyevent_to_keycode(c static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev) { - int keycode; - - keycode = ev->keysym.scancode; - - if (keycode < 9) { - keycode = 0; - } else if (keycode < 97) { - keycode -= 8; /* just an offset */ - } else if (keycode < 212) { - /* use conversion table */ - keycode = _translate_keycode(keycode - 97); - } else { - keycode = 0; - } - return keycode; + return _translate_keycode(ev->keysym.scancode); } #endif --- kvm-72+dfsg/qemu/x_keymap.c 2008-07-27 05:08:56.000000000 -0500 +++ kvm-72+dfsg/qemu/x_keymap.c 2008-09-24 16:52:27.262129702 -0500 @@ -24,7 +24,15 @@ #include "qemu-common.h" #include "console.h" -static const uint8_t x_keycode_to_pc_keycode[115] = { +#include +#include +#include +#include + +#define TRUE 1 +#define FALSE 0 + +static const uint8_t x_keycode_to_pc_keycode[61] = { 0xc7, /* 97 Home */ 0xc8, /* 98 Up */ 0xc9, /* 99 PgUp */ @@ -86,27 +94,136 @@ static const uint8_t x_keycode_to_pc_key 0x51, /* 155 KP_PgDn */ 0x52, /* 156 KP_Ins */ 0x53, /* 157 KP_Del */ - 0x0, /* 158 */ - 0x0, /* 159 */ - 0x0, /* 160 */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* 170 */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* 180 */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* 190 */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* 200 */ - 0x0, /* 201 */ - 0x0, /* 202 */ - 0x0, /* 203 */ - 0x0, /* 204 */ - 0x0, /* 205 */ - 0x0, /* 206 */ - 0x0, /* 207 */ - 0x70, /* 208 Hiragana_Katakana */ - 0x0, /* 209 */ - 0x0, /* 210 */ - 0x73, /* 211 backslash */ }; -uint8_t _translate_keycode(const int key) +/* This code was ported from gtk-vnc, to handle evdev keycode mapping by + * Dustin Kirkland , 24 September 2008. + * + * This table was put together by VirtualBox. It's based on the information in + * /usr/share/X11/xkb/keycodes/evdev using the x_keycode_to_pc_keycode table + * to get the pc keycodes. + */ + +static const uint8_t evdev_keycode_to_pc_keycode[61] = { + 0x0, /* 97 EVDEV - RO ("Internet" Keyboards) */ + 0x0, /* 98 EVDEV - KATA (Katakana) */ + 0x0, /* 99 EVDEV - HIRA (Hiragana) */ + 0x79, /* 100 EVDEV - HENK (Henkan) */ + 0x70, /* 101 EVDEV - HKTG (Hiragana/Katakana toggle) */ + 0x7b, /* 102 EVDEV - MUHE (Muhenkan) */ + 0x0, /* 103 EVDEV - JPCM (KPJPComma) */ + 0x9c, /* 104 EVDEV - KPEN */ + 0x9d, /* 105 EVDEV - RCTL */ + 0xb5, /* 106 EVDEV - KPDV */ + 0xb7, /* 107 EVDEV - PRSC ***FIXME*** */ + 0xb8, /* 108 EVDEV - RALT */ + 0x0, /* 109 EVDEV - LNFD ("Internet" Keyboards) */ + 0xc7, /* 110 EVDEV - HOME ***FIXME*** */ + 0xc8, /* 111 EVDEV - UP */ + 0xc9, /* 112 EVDEV - PGUP */ + 0xcb, /* 113 EVDEV - LEFT */ + 0xcd, /* 114 EVDEV - RGHT */ + 0xcf, /* 115 EVDEV - END */ + 0xd0, /* 116 EVDEV - DOWN */ + 0xd1, /* 117 EVDEV - PGDN */ + 0xd2, /* 118 EVDEV - INS */ + 0xd3, /* 119 EVDEV - DELE */ + 0x0, /* 120 EVDEV - I120 ("Internet" Keyboards) */ + 0x0, /* 121 EVDEV - MUTE */ + 0x0, /* 122 EVDEV - VOL- */ + 0x0, /* 123 EVDEV - VOL+ */ + 0x0, /* 124 EVDEV - POWR */ + 0x0, /* 125 EVDEV - KPEQ */ + 0x0, /* 126 EVDEV - I126 ("Internet" Keyboards) */ + 0x0, /* 127 EVDEV - PAUS */ + 0x0, /* 128 EVDEV - ???? */ + 0x0, /* 129 EVDEV - I129 ("Internet" Keyboards) */ + 0xf1, /* 130 EVDEV - HNGL (Korean Hangul Latin toggle) */ + 0xf2, /* 131 EVDEV - HJCV (Korean Hangul Hanja toggle) */ + 0x7d, /* 132 EVDEV - AE13 (Yen) */ + 0xdb, /* 133 EVDEV - LWIN */ + 0xdc, /* 134 EVDEV - RWIN */ + 0xdd, /* 135 EVDEV - MENU */ + 0x0, /* 136 EVDEV - STOP */ + 0x0, /* 137 EVDEV - AGAI */ + 0x0, /* 138 EVDEV - PROP */ + 0x0, /* 139 EVDEV - UNDO */ + 0x0, /* 140 EVDEV - FRNT */ + 0x0, /* 141 EVDEV - COPY */ + 0x0, /* 142 EVDEV - OPEN */ + 0x0, /* 143 EVDEV - PAST */ + 0x0, /* 144 EVDEV - FIND */ + 0x0, /* 145 EVDEV - CUT */ + 0x0, /* 146 EVDEV - HELP */ + 0x0, /* 147 EVDEV - I147 */ + 0x0, /* 148 EVDEV - I148 */ + 0x0, /* 149 EVDEV - I149 */ + 0x0, /* 150 EVDEV - I150 */ + 0x0, /* 151 EVDEV - I151 */ + 0x0, /* 152 EVDEV - I152 */ + 0x0, /* 153 EVDEV - I153 */ + 0x0, /* 154 EVDEV - I154 */ + 0x0, /* 155 EVDEV - I156 */ + 0x0, /* 156 EVDEV - I157 */ + 0x0, /* 157 EVDEV - I158 */ +}; + +static bool strstarts(const char *lhs, const char *rhs) +{ + if (strlen(lhs) < strlen(rhs)) + return false; + return memcmp(lhs, rhs, strlen(rhs)) == 0; +} + +static bool check_for_evdev(void) +{ + SDL_SysWMinfo info; + XkbDescPtr desc = NULL; + bool has_evdev = FALSE; + const char *keycodes; + + SDL_VERSION(&info.version); + if (!SDL_GetWMInfo(&info)) + goto out; + + desc = XkbGetKeyboard (info.info.x11.display, + XkbAllComponentsMask, + XkbUseCoreKbd); + if (!desc) + goto out; + + keycodes = XGetAtomName(info.info.x11.display, desc->names->keycodes); + if (keycodes == NULL) + fprintf(stderr, "qemu: warning: could not lookup keycode name\n"); + else if (strstarts(keycodes, "evdev_")) + has_evdev = TRUE; + else if (!strstarts(keycodes, "xfree86_")) + fprintf(stderr, "qemu: warning: unknown keycodes `%s'\n", keycodes); + + XkbFreeClientMap(desc, XkbGBN_AllComponentsMask, True); + +out: + return has_evdev; +} + + +uint8_t _translate_keycode(int keycode) { - return x_keycode_to_pc_keycode[key]; + if (keycode < 9) + keycode = 0; + else if (keycode < 97) + keycode -= 8; /* just an offset */ + else if (keycode < 158) { + if (check_for_evdev()) + keycode = evdev_keycode_to_pc_keycode[keycode - 97]; + else + keycode = x_keycode_to_pc_keycode[keycode - 97]; + } else if (keycode == 208) /* Hiragana_Katakana */ + keycode = 0x70; + else if (keycode == 211) /* backslash */ + keycode = 0x73; + else + keycode = 0; + + return keycode; }