zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_x11keyboard.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "SDL_config.h"
22 
23 #if SDL_VIDEO_DRIVER_X11
24 
25 #include "SDL_x11video.h"
26 
27 #include "../../events/SDL_keyboard_c.h"
28 #include "../../events/scancodes_darwin.h"
29 #include "../../events/scancodes_xfree86.h"
30 
31 #include <X11/keysym.h>
32 
33 #include "imKStoUCS.h"
34 
35 /* *INDENT-OFF* */
36 static const struct {
37  KeySym keysym;
38  SDL_Scancode scancode;
39 } KeySymToSDLScancode[] = {
42  { XK_BackSpace, SDL_SCANCODE_BACKSPACE },
43  { XK_Tab, SDL_SCANCODE_TAB },
44  { XK_Caps_Lock, SDL_SCANCODE_CAPSLOCK },
45  { XK_F1, SDL_SCANCODE_F1 },
46  { XK_F2, SDL_SCANCODE_F2 },
47  { XK_F3, SDL_SCANCODE_F3 },
48  { XK_F4, SDL_SCANCODE_F4 },
49  { XK_F5, SDL_SCANCODE_F5 },
50  { XK_F6, SDL_SCANCODE_F6 },
51  { XK_F7, SDL_SCANCODE_F7 },
52  { XK_F8, SDL_SCANCODE_F8 },
53  { XK_F9, SDL_SCANCODE_F9 },
54  { XK_F10, SDL_SCANCODE_F10 },
55  { XK_F11, SDL_SCANCODE_F11 },
56  { XK_F12, SDL_SCANCODE_F12 },
57  { XK_Print, SDL_SCANCODE_PRINTSCREEN },
58  { XK_Scroll_Lock, SDL_SCANCODE_SCROLLLOCK },
59  { XK_Pause, SDL_SCANCODE_PAUSE },
60  { XK_Insert, SDL_SCANCODE_INSERT },
61  { XK_Home, SDL_SCANCODE_HOME },
62  { XK_Prior, SDL_SCANCODE_PAGEUP },
63  { XK_Delete, SDL_SCANCODE_DELETE },
64  { XK_End, SDL_SCANCODE_END },
65  { XK_Next, SDL_SCANCODE_PAGEDOWN },
66  { XK_Right, SDL_SCANCODE_RIGHT },
67  { XK_Left, SDL_SCANCODE_LEFT },
68  { XK_Down, SDL_SCANCODE_DOWN },
69  { XK_Up, SDL_SCANCODE_UP },
70  { XK_Num_Lock, SDL_SCANCODE_NUMLOCKCLEAR },
71  { XK_KP_Divide, SDL_SCANCODE_KP_DIVIDE },
72  { XK_KP_Multiply, SDL_SCANCODE_KP_MULTIPLY },
73  { XK_KP_Subtract, SDL_SCANCODE_KP_MINUS },
74  { XK_KP_Add, SDL_SCANCODE_KP_PLUS },
76  { XK_KP_Delete, SDL_SCANCODE_KP_PERIOD },
77  { XK_KP_End, SDL_SCANCODE_KP_1 },
78  { XK_KP_Down, SDL_SCANCODE_KP_2 },
79  { XK_KP_Next, SDL_SCANCODE_KP_3 },
80  { XK_KP_Left, SDL_SCANCODE_KP_4 },
81  { XK_KP_Begin, SDL_SCANCODE_KP_5 },
82  { XK_KP_Right, SDL_SCANCODE_KP_6 },
83  { XK_KP_Home, SDL_SCANCODE_KP_7 },
84  { XK_KP_Up, SDL_SCANCODE_KP_8 },
85  { XK_KP_Prior, SDL_SCANCODE_KP_9 },
86  { XK_KP_Insert, SDL_SCANCODE_KP_0 },
87  { XK_KP_Decimal, SDL_SCANCODE_KP_PERIOD },
88  { XK_KP_1, SDL_SCANCODE_KP_1 },
89  { XK_KP_2, SDL_SCANCODE_KP_2 },
90  { XK_KP_3, SDL_SCANCODE_KP_3 },
91  { XK_KP_4, SDL_SCANCODE_KP_4 },
92  { XK_KP_5, SDL_SCANCODE_KP_5 },
93  { XK_KP_6, SDL_SCANCODE_KP_6 },
94  { XK_KP_7, SDL_SCANCODE_KP_7 },
95  { XK_KP_8, SDL_SCANCODE_KP_8 },
96  { XK_KP_9, SDL_SCANCODE_KP_9 },
97  { XK_KP_0, SDL_SCANCODE_KP_0 },
98  { XK_KP_Decimal, SDL_SCANCODE_KP_PERIOD },
99  { XK_Hyper_R, SDL_SCANCODE_APPLICATION },
100  { XK_KP_Equal, SDL_SCANCODE_KP_EQUALS },
101  { XK_F13, SDL_SCANCODE_F13 },
102  { XK_F14, SDL_SCANCODE_F14 },
103  { XK_F15, SDL_SCANCODE_F15 },
104  { XK_F16, SDL_SCANCODE_F16 },
105  { XK_F17, SDL_SCANCODE_F17 },
106  { XK_F18, SDL_SCANCODE_F18 },
107  { XK_F19, SDL_SCANCODE_F19 },
108  { XK_F20, SDL_SCANCODE_F20 },
109  { XK_F21, SDL_SCANCODE_F21 },
110  { XK_F22, SDL_SCANCODE_F22 },
111  { XK_F23, SDL_SCANCODE_F23 },
112  { XK_F24, SDL_SCANCODE_F24 },
113  { XK_Execute, SDL_SCANCODE_EXECUTE },
114  { XK_Help, SDL_SCANCODE_HELP },
115  { XK_Menu, SDL_SCANCODE_MENU },
116  { XK_Select, SDL_SCANCODE_SELECT },
117  { XK_Cancel, SDL_SCANCODE_STOP },
118  { XK_Redo, SDL_SCANCODE_AGAIN },
119  { XK_Undo, SDL_SCANCODE_UNDO },
120  { XK_Find, SDL_SCANCODE_FIND },
121  { XK_KP_Separator, SDL_SCANCODE_KP_COMMA },
122  { XK_Sys_Req, SDL_SCANCODE_SYSREQ },
123  { XK_Control_L, SDL_SCANCODE_LCTRL },
124  { XK_Shift_L, SDL_SCANCODE_LSHIFT },
125  { XK_Alt_L, SDL_SCANCODE_LALT },
126  { XK_Meta_L, SDL_SCANCODE_LGUI },
127  { XK_Super_L, SDL_SCANCODE_LGUI },
128  { XK_Control_R, SDL_SCANCODE_RCTRL },
129  { XK_Shift_R, SDL_SCANCODE_RSHIFT },
130  { XK_Alt_R, SDL_SCANCODE_RALT },
131  { XK_Meta_R, SDL_SCANCODE_RGUI },
132  { XK_Super_R, SDL_SCANCODE_RGUI },
133  { XK_Mode_switch, SDL_SCANCODE_MODE },
134 };
135 
136 static const struct
137 {
138  const SDL_Scancode const *table;
139  int table_size;
140 } scancode_set[] = {
144 };
145 /* *INDENT-OFF* */
146 
147 /* This function only works for keyboards in US QWERTY layout */
148 static SDL_Scancode
149 X11_KeyCodeToSDLScancode(Display *display, KeyCode keycode)
150 {
151  KeySym keysym;
152  int i;
153 
154 #if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
155  keysym = XkbKeycodeToKeysym(display, keycode, 0, 0);
156 #else
157  keysym = XKeycodeToKeysym(display, keycode, 0);
158 #endif
159  if (keysym == NoSymbol) {
160  return SDL_SCANCODE_UNKNOWN;
161  }
162 
163  if (keysym >= XK_A && keysym <= XK_Z) {
164  return SDL_SCANCODE_A + (keysym - XK_A);
165  }
166 
167  if (keysym >= XK_0 && keysym <= XK_9) {
168  return SDL_SCANCODE_0 + (keysym - XK_0);
169  }
170 
171  for (i = 0; i < SDL_arraysize(KeySymToSDLScancode); ++i) {
172  if (keysym == KeySymToSDLScancode[i].keysym) {
173  return KeySymToSDLScancode[i].scancode;
174  }
175  }
176  return SDL_SCANCODE_UNKNOWN;
177 }
178 
179 static Uint32
180 X11_KeyCodeToUcs4(Display *display, KeyCode keycode)
181 {
182  KeySym keysym;
183 
184 #if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
185  keysym = XkbKeycodeToKeysym(display, keycode, 0, 0);
186 #else
187  keysym = XKeycodeToKeysym(display, keycode, 0);
188 #endif
189  if (keysym == NoSymbol) {
190  return 0;
191  }
192 
193  return X11_KeySymToUcs4(keysym);
194 }
195 
196 int
198 {
200  int i = 0;
201  int j = 0;
202  int min_keycode, max_keycode;
203  struct {
204  SDL_Scancode scancode;
205  KeySym keysym;
206  int value;
207  } fingerprint[] = {
208  { SDL_SCANCODE_HOME, XK_Home, 0 },
209  { SDL_SCANCODE_PAGEUP, XK_Prior, 0 },
210  { SDL_SCANCODE_PAGEDOWN, XK_Next, 0 },
211  };
212  SDL_bool fingerprint_detected;
213 
214  XAutoRepeatOn(data->display);
215 
216  /* Try to determine which scancodes are being used based on fingerprint */
217  fingerprint_detected = SDL_FALSE;
218  XDisplayKeycodes(data->display, &min_keycode, &max_keycode);
219  for (i = 0; i < SDL_arraysize(fingerprint); ++i) {
220  fingerprint[i].value =
221  XKeysymToKeycode(data->display, fingerprint[i].keysym) -
222  min_keycode;
223  }
224  for (i = 0; i < SDL_arraysize(scancode_set); ++i) {
225  /* Make sure the scancode set isn't too big */
226  if ((max_keycode - min_keycode + 1) <= scancode_set[i].table_size) {
227  continue;
228  }
229  for (j = 0; j < SDL_arraysize(fingerprint); ++j) {
230  if (fingerprint[j].value < 0
231  || fingerprint[j].value >= scancode_set[i].table_size) {
232  break;
233  }
234  if (scancode_set[i].table[fingerprint[j].value] !=
235  fingerprint[j].scancode) {
236  break;
237  }
238  }
239  if (j == SDL_arraysize(fingerprint)) {
240 #ifdef DEBUG_KEYBOARD
241  printf("Using scancode set %d, min_keycode = %d, max_keycode = %d, table_size = %d\n", i, min_keycode, max_keycode, scancode_set[i].table_size);
242 #endif
243  SDL_memcpy(&data->key_layout[min_keycode], scancode_set[i].table,
244  sizeof(SDL_Scancode) * scancode_set[i].table_size);
245  fingerprint_detected = SDL_TRUE;
246  break;
247  }
248  }
249 
250  if (!fingerprint_detected) {
252 
253  printf
254  ("Keyboard layout unknown, please send the following to the SDL mailing list (sdl@libsdl.org):\n");
255 
256  /* Determine key_layout - only works on US QWERTY layout */
257  SDL_GetDefaultKeymap(keymap);
258  for (i = min_keycode; i <= max_keycode; ++i) {
259  KeySym sym;
260 #if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
261  sym = XkbKeycodeToKeysym(data->display, i, 0, 0);
262 #else
263  sym = XKeycodeToKeysym(data->display, i, 0);
264 #endif
265  if (sym != NoSymbol) {
266  SDL_Scancode scancode;
267  printf("code = %d, sym = 0x%X (%s) ", i - min_keycode,
268  (unsigned int) sym, XKeysymToString(sym));
269  scancode = X11_KeyCodeToSDLScancode(data->display, i);
270  data->key_layout[i] = scancode;
271  if (scancode == SDL_SCANCODE_UNKNOWN) {
272  printf("scancode not found\n");
273  } else {
274  printf("scancode = %d (%s)\n", j, SDL_GetScancodeName(j));
275  }
276  }
277  }
278  }
279 
281 
283 
284  return 0;
285 }
286 
287 void
289 {
291  int i;
292  SDL_Scancode scancode;
294 
295  SDL_GetDefaultKeymap(keymap);
296  for (i = 0; i < SDL_arraysize(data->key_layout); i++) {
297  Uint32 key;
298 
299  /* Make sure this is a valid scancode */
300  scancode = data->key_layout[i];
301  if (scancode == SDL_SCANCODE_UNKNOWN) {
302  continue;
303  }
304 
305  /* See if there is a UCS keycode for this scancode */
306  key = X11_KeyCodeToUcs4(data->display, (KeyCode)i);
307  if (key) {
308  keymap[scancode] = key;
309  }
310  }
311  SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES);
312 }
313 
314 void
316 {
317 }
318 
319 #endif /* SDL_VIDEO_DRIVER_X11 */
320 
321 /* vi: set ts=4 sw=4 expandtab: */
GLenum GLsizei GLenum GLenum const GLvoid * table
Definition: glew.h:4422
void SDL_GetDefaultKeymap(SDL_Keycode *keymap)
Definition: SDL_keyboard.c:579
Display * display
Definition: SDL_x11video.h:75
void X11_QuitKeyboard(_THIS)
static const SDL_Scancode xfree86_scancode_table[]
SDL_bool
Definition: SDL_stdinc.h:116
SDL_Keycode sym
Definition: SDL_pspevents.c:51
int32_t j
Definition: e_log.c:102
static const SDL_Scancode xfree86_scancode_table2[]
return XAutoRepeatOn
Definition: SDL_x11sym.h:28
char * display
Definition: visualinfo.c:85
Sint32 SDL_Keycode
The SDL virtual key representation.
Definition: SDL_keycode.h:42
static SDL_VideoDevice * _this
Definition: SDL_video.c:92
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
void SDL_SetKeymap(int start, SDL_Keycode *keys, int length)
Definition: SDL_keyboard.c:585
static const SDL_Scancode darwin_scancode_table[]
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
#define _THIS
unsigned int X11_KeySymToUcs4(KeySym keysym)
#define XK_Escape
void X11_UpdateKeymap(_THIS)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor return Display GC return XModifierKeymap return char Display Window int return Display return Display Atom return Display Window XWindowAttributes return Display Window return Display XEvent Bool(*) XPointer return Display Window Bool unsigned int int int Window Cursor Time return Display Window int retur XKeysymToString)
Definition: SDL_x11sym.h:80
void SDL_SetScancodeName(SDL_Scancode scancode, const char *name)
Definition: SDL_keyboard.c:597
DECLSPEC const char *SDLCALL SDL_GetScancodeName(SDL_Scancode scancode)
Get a human-readable name for a scancode.
Definition: SDL_keyboard.c:887
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:83
EGLSurface EGLint void ** value
Definition: eglext.h:301
DECLSPEC void *SDLCALL SDL_memcpy(void *dst, const void *src, size_t len)
Definition: SDL_string.c:293
int X11_InitKeyboard(_THIS)
int i
Definition: pngrutil.c:1377
#define XK_KP_Enter
#define XK_Return
SDL_Scancode
The SDL keyboard scancode representation.
Definition: SDL_scancode.h:43