Commit 5368a4228ff5dd5ec95d0416f23bcfc9e556f37b

Authored by aliguori
1 parent 71d0770c

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
configure
@@ -187,6 +187,7 @@ kerneldir=&quot;&quot; @@ -187,6 +187,7 @@ kerneldir=&quot;&quot;
187 aix="no" 187 aix="no"
188 blobs="yes" 188 blobs="yes"
189 fdt="yes" 189 fdt="yes"
  190 +sdl_x11="no"
190 191
191 # OS specific 192 # OS specific
192 if check_define __linux__ ; then 193 if check_define __linux__ ; then
@@ -805,6 +806,21 @@ else @@ -805,6 +806,21 @@ else
805 fi 806 fi
806 fi # -z $sdl 807 fi # -z $sdl
807 808
  809 +if test "$sdl" = "yes" ; then
  810 +cat > $TMPC <<EOF
  811 +#include <SDL.h>
  812 +#if defined(SDL_VIDEO_DRIVER_X11)
  813 +#include <X11/XKBlib.h>
  814 +#else
  815 +#error No x11 support
  816 +#endif
  817 +int main(void) { return 0; }
  818 +EOF
  819 + if $cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} `$sdl_config --cflags 2> /dev/null` $TMPC `$sdl_config --libs 2> /dev/null` > /dev/null 2>&1 ; then
  820 + sdl_x11="yes"
  821 + fi
  822 +fi
  823 +
808 ########################################## 824 ##########################################
809 # VNC TLS detection 825 # VNC TLS detection
810 if test "$vnc_tls" = "yes" ; then 826 if test "$vnc_tls" = "yes" ; then
@@ -1393,6 +1409,8 @@ if test &quot;$sdl1&quot; = &quot;yes&quot; ; then @@ -1393,6 +1409,8 @@ if test &quot;$sdl1&quot; = &quot;yes&quot; ; then
1393 echo "CONFIG_SDL=yes" >> $config_mak 1409 echo "CONFIG_SDL=yes" >> $config_mak
1394 if test "$target_softmmu" = "no" -o "$static" = "yes"; then 1410 if test "$target_softmmu" = "no" -o "$static" = "yes"; then
1395 echo "SDL_LIBS=$sdl_static_libs" >> $config_mak 1411 echo "SDL_LIBS=$sdl_static_libs" >> $config_mak
  1412 + elif test "$sdl_x11" = "yes" ; then
  1413 + echo "SDL_LIBS=`$sdl_config --libs` -lX11" >> $config_mak
1396 else 1414 else
1397 echo "SDL_LIBS=`$sdl_config --libs`" >> $config_mak 1415 echo "SDL_LIBS=`$sdl_config --libs`" >> $config_mak
1398 fi 1416 fi
console.h
@@ -292,9 +292,6 @@ void do_info_vnc(void); @@ -292,9 +292,6 @@ void do_info_vnc(void);
292 /* curses.c */ 292 /* curses.c */
293 void curses_display_init(DisplayState *ds, int full_screen); 293 void curses_display_init(DisplayState *ds, int full_screen);
294 294
295 -/* x_keymap.c */  
296 -extern uint8_t _translate_keycode(const int key);  
297 -  
298 /* FIXME: term_printf et al should probably go elsewhere so everything 295 /* FIXME: term_printf et al should probably go elsewhere so everything
299 does not need to include console.h */ 296 does not need to include console.h */
300 /* monitor.c */ 297 /* monitor.c */
@@ -24,8 +24,10 @@ @@ -24,8 +24,10 @@
24 #include "qemu-common.h" 24 #include "qemu-common.h"
25 #include "console.h" 25 #include "console.h"
26 #include "sysemu.h" 26 #include "sysemu.h"
  27 +#include "x_keymap.h"
27 28
28 #include <SDL.h> 29 #include <SDL.h>
  30 +#include <SDL/SDL_syswm.h>
29 31
30 #ifndef _WIN32 32 #ifndef _WIN32
31 #include <signal.h> 33 #include <signal.h>
@@ -136,9 +138,54 @@ static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev) @@ -136,9 +138,54 @@ static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
136 138
137 #else 139 #else
138 140
  141 +#if defined(SDL_VIDEO_DRIVER_X11)
  142 +#include <X11/XKBlib.h>
  143 +
  144 +static int check_for_evdev(void)
  145 +{
  146 + SDL_SysWMinfo info;
  147 + XkbDescPtr desc;
  148 + int has_evdev = 0;
  149 + const char *keycodes;
  150 +
  151 + SDL_VERSION(&info.version);
  152 + if (!SDL_GetWMInfo(&info))
  153 + return 0;
  154 +
  155 + desc = XkbGetKeyboard(info.info.x11.display,
  156 + XkbGBN_AllComponentsMask,
  157 + XkbUseCoreKbd);
  158 + if (desc == NULL || desc->names == NULL)
  159 + return 0;
  160 +
  161 + keycodes = XGetAtomName(info.info.x11.display, desc->names->keycodes);
  162 + if (keycodes == NULL)
  163 + fprintf(stderr, "could not lookup keycode name\n");
  164 + else if (strstart(keycodes, "evdev_", NULL))
  165 + has_evdev = 1;
  166 + else if (!strstart(keycodes, "xfree86_", NULL))
  167 + fprintf(stderr,
  168 + "unknown keycodes `%s', please report to qemu-devel@nongnu.org\n",
  169 + keycodes);
  170 +
  171 + XkbFreeClientMap(desc, XkbGBN_AllComponentsMask, True);
  172 +
  173 + return has_evdev;
  174 +}
  175 +#else
  176 +static int check_for_evdev(void)
  177 +{
  178 + return 0;
  179 +}
  180 +#endif
  181 +
139 static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev) 182 static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
140 { 183 {
141 int keycode; 184 int keycode;
  185 + static int has_evdev = -1;
  186 +
  187 + if (has_evdev == -1)
  188 + has_evdev = check_for_evdev();
142 189
143 keycode = ev->keysym.scancode; 190 keycode = ev->keysym.scancode;
144 191
@@ -146,9 +193,16 @@ static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev) @@ -146,9 +193,16 @@ static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
146 keycode = 0; 193 keycode = 0;
147 } else if (keycode < 97) { 194 } else if (keycode < 97) {
148 keycode -= 8; /* just an offset */ 195 keycode -= 8; /* just an offset */
149 - } else if (keycode < 212) { 196 + } else if (keycode < 158) {
150 /* use conversion table */ 197 /* use conversion table */
151 - keycode = _translate_keycode(keycode - 97); 198 + if (has_evdev)
  199 + keycode = translate_evdev_keycode(keycode - 97);
  200 + else
  201 + keycode = translate_xfree86_keycode(keycode - 97);
  202 + } else if (keycode == 208) { /* Hiragana_Katakana */
  203 + keycode = 0x70;
  204 + } else if (keycode == 211) { /* backslash */
  205 + keycode = 0x73;
152 } else { 206 } else {
153 keycode = 0; 207 keycode = 0;
154 } 208 }
x_keymap.c
@@ -22,7 +22,7 @@ @@ -22,7 +22,7 @@
22 * THE SOFTWARE. 22 * THE SOFTWARE.
23 */ 23 */
24 #include "qemu-common.h" 24 #include "qemu-common.h"
25 -#include "console.h" 25 +#include "x_keymap.h"
26 26
27 static const uint8_t x_keycode_to_pc_keycode[115] = { 27 static const uint8_t x_keycode_to_pc_keycode[115] = {
28 0xc7, /* 97 Home */ 28 0xc7, /* 97 Home */
@@ -86,27 +86,83 @@ static const uint8_t x_keycode_to_pc_keycode[115] = { @@ -86,27 +86,83 @@ static const uint8_t x_keycode_to_pc_keycode[115] = {
86 0x51, /* 155 KP_PgDn */ 86 0x51, /* 155 KP_PgDn */
87 0x52, /* 156 KP_Ins */ 87 0x52, /* 156 KP_Ins */
88 0x53, /* 157 KP_Del */ 88 0x53, /* 157 KP_Del */
89 - 0x0, /* 158 */  
90 - 0x0, /* 159 */  
91 - 0x0, /* 160 */  
92 - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* 170 */  
93 - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* 180 */  
94 - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* 190 */  
95 - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* 200 */  
96 - 0x0, /* 201 */  
97 - 0x0, /* 202 */  
98 - 0x0, /* 203 */  
99 - 0x0, /* 204 */  
100 - 0x0, /* 205 */  
101 - 0x0, /* 206 */  
102 - 0x0, /* 207 */  
103 - 0x70, /* 208 Hiragana_Katakana */  
104 - 0x0, /* 209 */  
105 - 0x0, /* 210 */  
106 - 0x73, /* 211 backslash */  
107 }; 89 };
108 90
109 -uint8_t _translate_keycode(const int key) 91 +/* This table is generated based off the xfree86 -> scancode mapping above
  92 + * and the keycode mappings in /usr/share/X11/xkb/keycodes/evdev
  93 + * and /usr/share/X11/xkb/keycodes/xfree86
  94 + */
  95 +
  96 +static const uint8_t evdev_keycode_to_pc_keycode[61] = {
  97 + 0, /* 97 EVDEV - RO ("Internet" Keyboards) */
  98 + 0, /* 98 EVDEV - KATA (Katakana) */
  99 + 0, /* 99 EVDEV - HIRA (Hiragana) */
  100 + 0x79, /* 100 EVDEV - HENK (Henkan) */
  101 + 0x70, /* 101 EVDEV - HKTG (Hiragana/Katakana toggle) */
  102 + 0x7b, /* 102 EVDEV - MUHE (Muhenkan) */
  103 + 0, /* 103 EVDEV - JPCM (KPJPComma) */
  104 + 0x9c, /* 104 KPEN */
  105 + 0x9d, /* 105 RCTL */
  106 + 0xb5, /* 106 KPDV */
  107 + 0xb7, /* 107 PRSC */
  108 + 0xb8, /* 108 RALT */
  109 + 0, /* 109 EVDEV - LNFD ("Internet" Keyboards) */
  110 + 0xc7, /* 110 HOME */
  111 + 0xc8, /* 111 UP */
  112 + 0xc9, /* 112 PGUP */
  113 + 0xcb, /* 113 LEFT */
  114 + 0xcd, /* 114 RGHT */
  115 + 0xcf, /* 115 END */
  116 + 0xd0, /* 116 DOWN */
  117 + 0xd1, /* 117 PGDN */
  118 + 0xd2, /* 118 INS */
  119 + 0xd3, /* 119 DELE */
  120 + 0, /* 120 EVDEV - I120 ("Internet" Keyboards) */
  121 + 0, /* 121 EVDEV - MUTE */
  122 + 0, /* 122 EVDEV - VOL- */
  123 + 0, /* 123 EVDEV - VOL+ */
  124 + 0, /* 124 EVDEV - POWR */
  125 + 0, /* 125 EVDEV - KPEQ */
  126 + 0, /* 126 EVDEV - I126 ("Internet" Keyboards) */
  127 + 0, /* 127 EVDEV - PAUS */
  128 + 0, /* 128 EVDEV - ???? */
  129 + 0, /* 129 EVDEV - I129 ("Internet" Keyboards) */
  130 + 0xf1, /* 130 EVDEV - HNGL (Korean Hangul Latin toggle) */
  131 + 0xf2, /* 131 EVDEV - HJCV (Korean Hangul Hanja toggle) */
  132 + 0x7d, /* 132 AE13 (Yen)*/
  133 + 0xdb, /* 133 EVDEV - LWIN */
  134 + 0xdc, /* 134 EVDEV - RWIN */
  135 + 0xdd, /* 135 EVDEV - MENU */
  136 + 0, /* 136 EVDEV - STOP */
  137 + 0, /* 137 EVDEV - AGAI */
  138 + 0, /* 138 EVDEV - PROP */
  139 + 0, /* 139 EVDEV - UNDO */
  140 + 0, /* 140 EVDEV - FRNT */
  141 + 0, /* 141 EVDEV - COPY */
  142 + 0, /* 142 EVDEV - OPEN */
  143 + 0, /* 143 EVDEV - PAST */
  144 + 0, /* 144 EVDEV - FIND */
  145 + 0, /* 145 EVDEV - CUT */
  146 + 0, /* 146 EVDEV - HELP */
  147 + 0, /* 147 EVDEV - I147 */
  148 + 0, /* 148 EVDEV - I148 */
  149 + 0, /* 149 EVDEV - I149 */
  150 + 0, /* 150 EVDEV - I150 */
  151 + 0, /* 151 EVDEV - I151 */
  152 + 0, /* 152 EVDEV - I152 */
  153 + 0, /* 153 EVDEV - I153 */
  154 + 0, /* 154 EVDEV - I154 */
  155 + 0, /* 155 EVDEV - I156 */
  156 + 0, /* 156 EVDEV - I157 */
  157 + 0, /* 157 EVDEV - I158 */
  158 +};
  159 +
  160 +uint8_t translate_xfree86_keycode(const int key)
  161 +{
  162 + return x_keycode_to_pc_keycode[key];
  163 +}
  164 +
  165 +uint8_t translate_evdev_keycode(const int key)
110 { 166 {
111 - return x_keycode_to_pc_keycode[key]; 167 + return evdev_keycode_to_pc_keycode[key];
112 } 168 }
x_keymap.h 0 → 100644
  1 +/*
  2 + * QEMU SDL display driver
  3 + *
  4 + * Copyright (c) 2003 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +
  25 +#ifndef QEMU_X_KEYMAP_H
  26 +#define QEMU_X_KEYMAP_H
  27 +
  28 +extern uint8_t translate_xfree86_keycode(const int key);
  29 +
  30 +extern uint8_t translate_evdev_keycode(const int key);
  31 +
  32 +#endif