SDL  2.0
SDL_x11keyboard.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2018 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_internal.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 #include <X11/XKBlib.h>
33 
34 #include "imKStoUCS.h"
35 
36 #ifdef X_HAVE_UTF8_STRING
37 #include <locale.h>
38 #endif
39 
40 /* *INDENT-OFF* */
41 static const struct {
42  KeySym keysym;
43  SDL_Scancode scancode;
44 } KeySymToSDLScancode[] = {
45  { XK_Return, SDL_SCANCODE_RETURN },
46  { XK_Escape, SDL_SCANCODE_ESCAPE },
47  { XK_BackSpace, SDL_SCANCODE_BACKSPACE },
48  { XK_Tab, SDL_SCANCODE_TAB },
49  { XK_Caps_Lock, SDL_SCANCODE_CAPSLOCK },
50  { XK_F1, SDL_SCANCODE_F1 },
51  { XK_F2, SDL_SCANCODE_F2 },
52  { XK_F3, SDL_SCANCODE_F3 },
53  { XK_F4, SDL_SCANCODE_F4 },
54  { XK_F5, SDL_SCANCODE_F5 },
55  { XK_F6, SDL_SCANCODE_F6 },
56  { XK_F7, SDL_SCANCODE_F7 },
57  { XK_F8, SDL_SCANCODE_F8 },
58  { XK_F9, SDL_SCANCODE_F9 },
59  { XK_F10, SDL_SCANCODE_F10 },
60  { XK_F11, SDL_SCANCODE_F11 },
61  { XK_F12, SDL_SCANCODE_F12 },
62  { XK_Print, SDL_SCANCODE_PRINTSCREEN },
63  { XK_Scroll_Lock, SDL_SCANCODE_SCROLLLOCK },
64  { XK_Pause, SDL_SCANCODE_PAUSE },
65  { XK_Insert, SDL_SCANCODE_INSERT },
66  { XK_Home, SDL_SCANCODE_HOME },
67  { XK_Prior, SDL_SCANCODE_PAGEUP },
68  { XK_Delete, SDL_SCANCODE_DELETE },
69  { XK_End, SDL_SCANCODE_END },
70  { XK_Next, SDL_SCANCODE_PAGEDOWN },
71  { XK_Right, SDL_SCANCODE_RIGHT },
72  { XK_Left, SDL_SCANCODE_LEFT },
73  { XK_Down, SDL_SCANCODE_DOWN },
74  { XK_Up, SDL_SCANCODE_UP },
75  { XK_Num_Lock, SDL_SCANCODE_NUMLOCKCLEAR },
76  { XK_KP_Divide, SDL_SCANCODE_KP_DIVIDE },
77  { XK_KP_Multiply, SDL_SCANCODE_KP_MULTIPLY },
78  { XK_KP_Subtract, SDL_SCANCODE_KP_MINUS },
79  { XK_KP_Add, SDL_SCANCODE_KP_PLUS },
80  { XK_KP_Enter, SDL_SCANCODE_KP_ENTER },
81  { XK_KP_Delete, SDL_SCANCODE_KP_PERIOD },
82  { XK_KP_End, SDL_SCANCODE_KP_1 },
83  { XK_KP_Down, SDL_SCANCODE_KP_2 },
84  { XK_KP_Next, SDL_SCANCODE_KP_3 },
85  { XK_KP_Left, SDL_SCANCODE_KP_4 },
86  { XK_KP_Begin, SDL_SCANCODE_KP_5 },
87  { XK_KP_Right, SDL_SCANCODE_KP_6 },
88  { XK_KP_Home, SDL_SCANCODE_KP_7 },
89  { XK_KP_Up, SDL_SCANCODE_KP_8 },
90  { XK_KP_Prior, SDL_SCANCODE_KP_9 },
91  { XK_KP_Insert, SDL_SCANCODE_KP_0 },
92  { XK_KP_Decimal, SDL_SCANCODE_KP_PERIOD },
93  { XK_KP_1, SDL_SCANCODE_KP_1 },
94  { XK_KP_2, SDL_SCANCODE_KP_2 },
95  { XK_KP_3, SDL_SCANCODE_KP_3 },
96  { XK_KP_4, SDL_SCANCODE_KP_4 },
97  { XK_KP_5, SDL_SCANCODE_KP_5 },
98  { XK_KP_6, SDL_SCANCODE_KP_6 },
99  { XK_KP_7, SDL_SCANCODE_KP_7 },
100  { XK_KP_8, SDL_SCANCODE_KP_8 },
101  { XK_KP_9, SDL_SCANCODE_KP_9 },
102  { XK_KP_0, SDL_SCANCODE_KP_0 },
103  { XK_KP_Decimal, SDL_SCANCODE_KP_PERIOD },
104  { XK_Hyper_R, SDL_SCANCODE_APPLICATION },
105  { XK_KP_Equal, SDL_SCANCODE_KP_EQUALS },
106  { XK_F13, SDL_SCANCODE_F13 },
107  { XK_F14, SDL_SCANCODE_F14 },
108  { XK_F15, SDL_SCANCODE_F15 },
109  { XK_F16, SDL_SCANCODE_F16 },
110  { XK_F17, SDL_SCANCODE_F17 },
111  { XK_F18, SDL_SCANCODE_F18 },
112  { XK_F19, SDL_SCANCODE_F19 },
113  { XK_F20, SDL_SCANCODE_F20 },
114  { XK_F21, SDL_SCANCODE_F21 },
115  { XK_F22, SDL_SCANCODE_F22 },
116  { XK_F23, SDL_SCANCODE_F23 },
117  { XK_F24, SDL_SCANCODE_F24 },
118  { XK_Execute, SDL_SCANCODE_EXECUTE },
119  { XK_Help, SDL_SCANCODE_HELP },
120  { XK_Menu, SDL_SCANCODE_MENU },
121  { XK_Select, SDL_SCANCODE_SELECT },
122  { XK_Cancel, SDL_SCANCODE_STOP },
123  { XK_Redo, SDL_SCANCODE_AGAIN },
124  { XK_Undo, SDL_SCANCODE_UNDO },
125  { XK_Find, SDL_SCANCODE_FIND },
126  { XK_KP_Separator, SDL_SCANCODE_KP_COMMA },
127  { XK_Sys_Req, SDL_SCANCODE_SYSREQ },
128  { XK_Control_L, SDL_SCANCODE_LCTRL },
129  { XK_Shift_L, SDL_SCANCODE_LSHIFT },
130  { XK_Alt_L, SDL_SCANCODE_LALT },
131  { XK_Meta_L, SDL_SCANCODE_LGUI },
132  { XK_Super_L, SDL_SCANCODE_LGUI },
133  { XK_Control_R, SDL_SCANCODE_RCTRL },
134  { XK_Shift_R, SDL_SCANCODE_RSHIFT },
135  { XK_Alt_R, SDL_SCANCODE_RALT },
136  { XK_ISO_Level3_Shift, SDL_SCANCODE_RALT },
137  { XK_Meta_R, SDL_SCANCODE_RGUI },
138  { XK_Super_R, SDL_SCANCODE_RGUI },
139  { XK_Mode_switch, SDL_SCANCODE_MODE },
140  { XK_period, SDL_SCANCODE_PERIOD },
141  { XK_comma, SDL_SCANCODE_COMMA },
142  { XK_slash, SDL_SCANCODE_SLASH },
143  { XK_backslash, SDL_SCANCODE_BACKSLASH },
144  { XK_minus, SDL_SCANCODE_MINUS },
145  { XK_equal, SDL_SCANCODE_EQUALS },
146  { XK_space, SDL_SCANCODE_SPACE },
147  { XK_grave, SDL_SCANCODE_GRAVE },
148  { XK_apostrophe, SDL_SCANCODE_APOSTROPHE },
149  { XK_bracketleft, SDL_SCANCODE_LEFTBRACKET },
150  { XK_bracketright, SDL_SCANCODE_RIGHTBRACKET },
151 };
152 
153 static const struct
154 {
155  SDL_Scancode const *table;
156  int table_size;
157 } scancode_set[] = {
162 };
163 /* *INDENT-OFF* */
164 
165 /* This function only works for keyboards in US QWERTY layout */
166 static SDL_Scancode
167 X11_KeyCodeToSDLScancode(_THIS, KeyCode keycode)
168 {
169  KeySym keysym;
170  int i;
171 
172  keysym = X11_KeyCodeToSym(_this, keycode, 0);
173  if (keysym == NoSymbol) {
174  return SDL_SCANCODE_UNKNOWN;
175  }
176 
177  if (keysym >= XK_a && keysym <= XK_z) {
178  return SDL_SCANCODE_A + (keysym - XK_a);
179  }
180  if (keysym >= XK_A && keysym <= XK_Z) {
181  return SDL_SCANCODE_A + (keysym - XK_A);
182  }
183 
184  if (keysym == XK_0) {
185  return SDL_SCANCODE_0;
186  }
187  if (keysym >= XK_1 && keysym <= XK_9) {
188  return SDL_SCANCODE_1 + (keysym - XK_1);
189  }
190 
191  for (i = 0; i < SDL_arraysize(KeySymToSDLScancode); ++i) {
192  if (keysym == KeySymToSDLScancode[i].keysym) {
193  return KeySymToSDLScancode[i].scancode;
194  }
195  }
196  return SDL_SCANCODE_UNKNOWN;
197 }
198 
199 static Uint32
200 X11_KeyCodeToUcs4(_THIS, KeyCode keycode, unsigned char group)
201 {
202  KeySym keysym = X11_KeyCodeToSym(_this, keycode, group);
203 
204  if (keysym == NoSymbol) {
205  return 0;
206  }
207 
208  return X11_KeySymToUcs4(keysym);
209 }
210 
211 KeySym
212 X11_KeyCodeToSym(_THIS, KeyCode keycode, unsigned char group)
213 {
215  KeySym keysym;
216 
218  if (data->xkb) {
219  int num_groups = XkbKeyNumGroups(data->xkb, keycode);
220  unsigned char info = XkbKeyGroupInfo(data->xkb, keycode);
221 
222  if (num_groups && group >= num_groups) {
223 
224  int action = XkbOutOfRangeGroupAction(info);
225 
226  if (action == XkbRedirectIntoRange) {
227  if ((group = XkbOutOfRangeGroupNumber(info)) >= num_groups) {
228  group = 0;
229  }
230  } else if (action == XkbClampIntoRange) {
231  group = num_groups - 1;
232  } else {
233  group %= num_groups;
234  }
235  }
236  keysym = X11_XkbKeycodeToKeysym(data->display, keycode, group, 0);
237  } else {
238  keysym = X11_XKeycodeToKeysym(data->display, keycode, 0);
239  }
240 #else
241  keysym = X11_XKeycodeToKeysym(data->display, keycode, 0);
242 #endif
243 
244  return keysym;
245 }
246 
247 int
249 {
251  int i = 0;
252  int j = 0;
253  int min_keycode, max_keycode;
254  struct {
255  SDL_Scancode scancode;
256  KeySym keysym;
257  int value;
258  } fingerprint[] = {
259  { SDL_SCANCODE_HOME, XK_Home, 0 },
260  { SDL_SCANCODE_PAGEUP, XK_Prior, 0 },
261  { SDL_SCANCODE_UP, XK_Up, 0 },
262  { SDL_SCANCODE_LEFT, XK_Left, 0 },
263  { SDL_SCANCODE_DELETE, XK_Delete, 0 },
264  { SDL_SCANCODE_KP_ENTER, XK_KP_Enter, 0 },
265  };
266  int best_distance;
267  int best_index;
268  int distance;
269  BOOL xkb_repeat = 0;
270 
271  X11_XAutoRepeatOn(data->display);
272 
273 #if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
274  {
275  int xkb_major = XkbMajorVersion;
276  int xkb_minor = XkbMinorVersion;
277 
278  if (X11_XkbQueryExtension(data->display, NULL, NULL, NULL, &xkb_major, &xkb_minor)) {
279  data->xkb = X11_XkbGetMap(data->display, XkbAllClientInfoMask, XkbUseCoreKbd);
280  }
281 
282  /* This will remove KeyRelease events for held keys */
283  X11_XkbSetDetectableAutoRepeat(data->display, True, &xkb_repeat);
284  }
285 #endif
286 
287  /* Open a connection to the X input manager */
288 #ifdef X_HAVE_UTF8_STRING
289  if (SDL_X11_HAVE_UTF8) {
290  /* Set the locale, and call XSetLocaleModifiers before XOpenIM so that
291  Compose keys will work correctly. */
292  char *prev_locale = setlocale(LC_ALL, NULL);
293  char *prev_xmods = X11_XSetLocaleModifiers(NULL);
294  const char *new_xmods = "";
295 #if defined(HAVE_IBUS_IBUS_H) || defined(HAVE_FCITX_FRONTEND_H)
296  const char *env_xmods = SDL_getenv("XMODIFIERS");
297 #endif
298  SDL_bool has_dbus_ime_support = SDL_FALSE;
299 
300  if (prev_locale) {
301  prev_locale = SDL_strdup(prev_locale);
302  }
303 
304  if (prev_xmods) {
305  prev_xmods = SDL_strdup(prev_xmods);
306  }
307 
308  /* IBus resends some key events that were filtered by XFilterEvents
309  when it is used via XIM which causes issues. Prevent this by forcing
310  @im=none if XMODIFIERS contains @im=ibus. IBus can still be used via
311  the DBus implementation, which also has support for pre-editing. */
312 #ifdef HAVE_IBUS_IBUS_H
313  if (env_xmods && SDL_strstr(env_xmods, "@im=ibus") != NULL) {
314  has_dbus_ime_support = SDL_TRUE;
315  }
316 #endif
317 #ifdef HAVE_FCITX_FRONTEND_H
318  if (env_xmods && SDL_strstr(env_xmods, "@im=fcitx") != NULL) {
319  has_dbus_ime_support = SDL_TRUE;
320  }
321 #endif
322  if (has_dbus_ime_support || !xkb_repeat) {
323  new_xmods = "@im=none";
324  }
325 
326  setlocale(LC_ALL, "");
327  X11_XSetLocaleModifiers(new_xmods);
328 
329  data->im = X11_XOpenIM(data->display, NULL, data->classname, data->classname);
330 
331  /* Reset the locale + X locale modifiers back to how they were,
332  locale first because the X locale modifiers depend on it. */
333  setlocale(LC_ALL, prev_locale);
334  X11_XSetLocaleModifiers(prev_xmods);
335 
336  if (prev_locale) {
337  SDL_free(prev_locale);
338  }
339 
340  if (prev_xmods) {
341  SDL_free(prev_xmods);
342  }
343  }
344 #endif
345  /* Try to determine which scancodes are being used based on fingerprint */
346  best_distance = SDL_arraysize(fingerprint) + 1;
347  best_index = -1;
348  X11_XDisplayKeycodes(data->display, &min_keycode, &max_keycode);
349  for (i = 0; i < SDL_arraysize(fingerprint); ++i) {
350  fingerprint[i].value =
351  X11_XKeysymToKeycode(data->display, fingerprint[i].keysym) -
352  min_keycode;
353  }
354  for (i = 0; i < SDL_arraysize(scancode_set); ++i) {
355  /* Make sure the scancode set isn't too big */
356  if ((max_keycode - min_keycode + 1) <= scancode_set[i].table_size) {
357  continue;
358  }
359  distance = 0;
360  for (j = 0; j < SDL_arraysize(fingerprint); ++j) {
361  if (fingerprint[j].value < 0
362  || fingerprint[j].value >= scancode_set[i].table_size) {
363  distance += 1;
364  } else if (scancode_set[i].table[fingerprint[j].value] != fingerprint[j].scancode) {
365  distance += 1;
366  }
367  }
368  if (distance < best_distance) {
369  best_distance = distance;
370  best_index = i;
371  }
372  }
373  if (best_index >= 0 && best_distance <= 2) {
374 #ifdef DEBUG_KEYBOARD
375  printf("Using scancode set %d, min_keycode = %d, max_keycode = %d, table_size = %d\n", best_index, min_keycode, max_keycode, scancode_set[best_index].table_size);
376 #endif
377  SDL_memcpy(&data->key_layout[min_keycode], scancode_set[best_index].table,
378  sizeof(SDL_Scancode) * scancode_set[best_index].table_size);
379  } else {
381 
382  printf
383  ("Keyboard layout unknown, please report the following to the SDL forums/mailing list (https://discourse.libsdl.org/):\n");
384 
385  /* Determine key_layout - only works on US QWERTY layout */
386  SDL_GetDefaultKeymap(keymap);
387  for (i = min_keycode; i <= max_keycode; ++i) {
388  KeySym sym;
389  sym = X11_KeyCodeToSym(_this, (KeyCode) i, 0);
390  if (sym != NoSymbol) {
391  SDL_Scancode scancode;
392  printf("code = %d, sym = 0x%X (%s) ", i - min_keycode,
393  (unsigned int) sym, X11_XKeysymToString(sym));
394  scancode = X11_KeyCodeToSDLScancode(_this, i);
395  data->key_layout[i] = scancode;
396  if (scancode == SDL_SCANCODE_UNKNOWN) {
397  printf("scancode not found\n");
398  } else {
399  printf("scancode = %d (%s)\n", scancode, SDL_GetScancodeName(scancode));
400  }
401  }
402  }
403  }
404 
406 
408 
409 #ifdef SDL_USE_IME
410  SDL_IME_Init();
411 #endif
412 
413  return 0;
414 }
415 
416 void
418 {
420  int i;
421  SDL_Scancode scancode;
423  unsigned char group = 0;
424 
425  SDL_GetDefaultKeymap(keymap);
426 
427 #if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
428  if (data->xkb) {
429  XkbStateRec state;
430  X11_XkbGetUpdatedMap(data->display, XkbAllClientInfoMask, data->xkb);
431 
432  if (X11_XkbGetState(data->display, XkbUseCoreKbd, &state) == Success) {
433  group = state.group;
434  }
435  }
436 #endif
437 
438 
439  for (i = 0; i < SDL_arraysize(data->key_layout); i++) {
440  Uint32 key;
441 
442  /* Make sure this is a valid scancode */
443  scancode = data->key_layout[i];
444  if (scancode == SDL_SCANCODE_UNKNOWN) {
445  continue;
446  }
447 
448  /* See if there is a UCS keycode for this scancode */
449  key = X11_KeyCodeToUcs4(_this, (KeyCode)i, group);
450  if (key) {
451  keymap[scancode] = key;
452  } else {
453  SDL_Scancode keyScancode = X11_KeyCodeToSDLScancode(_this, (KeyCode)i);
454 
455  switch (keyScancode) {
456  case SDL_SCANCODE_RETURN:
457  keymap[scancode] = SDLK_RETURN;
458  break;
459  case SDL_SCANCODE_ESCAPE:
460  keymap[scancode] = SDLK_ESCAPE;
461  break;
463  keymap[scancode] = SDLK_BACKSPACE;
464  break;
465  case SDL_SCANCODE_TAB:
466  keymap[scancode] = SDLK_TAB;
467  break;
468  case SDL_SCANCODE_DELETE:
469  keymap[scancode] = SDLK_DELETE;
470  break;
471  default:
472  keymap[scancode] = SDL_SCANCODE_TO_KEYCODE(keyScancode);
473  break;
474  }
475  }
476  }
477  SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES);
478 }
479 
480 void
482 {
484 
486  if (data->xkb) {
487  X11_XkbFreeKeyboard(data->xkb, 0, True);
488  data->xkb = NULL;
489  }
490 #endif
491 
492 #ifdef SDL_USE_IME
493  SDL_IME_Quit();
494 #endif
495 }
496 
497 static void
498 X11_ResetXIM(_THIS)
499 {
500 #ifdef X_HAVE_UTF8_STRING
501  SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
502  int i;
503 
504  if (videodata && videodata->windowlist) {
505  for (i = 0; i < videodata->numwindows; ++i) {
506  SDL_WindowData *data = videodata->windowlist[i];
507  if (data && data->ic) {
508  /* Clear any partially entered dead keys */
509  char *contents = X11_Xutf8ResetIC(data->ic);
510  if (contents) {
511  X11_XFree(contents);
512  }
513  }
514  }
515  }
516 #endif
517 }
518 
519 void
521 {
522  X11_ResetXIM(_this);
523 }
524 
525 void
527 {
528  X11_ResetXIM(_this);
529 #ifdef SDL_USE_IME
530  SDL_IME_Reset();
531 #endif
532 }
533 
534 void
536 {
537  if (!rect) {
538  SDL_InvalidParamError("rect");
539  return;
540  }
541 
542 #ifdef SDL_USE_IME
544 #endif
545 }
546 
547 #endif /* SDL_VIDEO_DRIVER_X11 */
548 
549 /* vi: set ts=4 sw=4 expandtab: */
void SDL_GetDefaultKeymap(SDL_Keycode *keymap)
Definition: SDL_keyboard.c:588
GLboolean GLuint group
GLenum GLsizei GLenum GLenum const void * table
void X11_QuitKeyboard(_THIS)
void X11_SetTextInputRect(_THIS, SDL_Rect *rect)
static const SDL_Scancode xfree86_scancode_table[]
void SDL_IME_Quit(void)
Definition: SDL_ime.c:109
SDL_Rect rect
Definition: testrelative.c:27
struct wl_display * display
struct xkb_state * state
void SDL_IME_UpdateTextRect(SDL_Rect *rect)
Definition: SDL_ime.c:139
SDL_WindowData ** windowlist
Definition: SDL_x11video.h:83
void X11_StartTextInput(_THIS)
static const SDL_Scancode xfree86_scancode_table2[]
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
uint32_t Uint32
Definition: SDL_stdinc.h:181
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
Sint32 SDL_Keycode
The SDL virtual key representation.
Definition: SDL_keycode.h:45
GLsizei GLsizei GLfloat distance
static SDL_VideoDevice * _this
Definition: SDL_video.c:121
void SDL_SetKeymap(int start, SDL_Keycode *keys, int length)
Definition: SDL_keyboard.c:594
static const SDL_Scancode darwin_scancode_table[]
#define SDL_memcpy
GLuint64 key
Definition: gl2ext.h:2192
KeySym X11_KeyCodeToSym(_THIS, KeyCode, unsigned char group)
#define _THIS
#define SDL_free
unsigned int X11_KeySymToUcs4(KeySym keysym)
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 in j)
Definition: SDL_x11sym.h:50
#define SDL_SCANCODE_TO_KEYCODE(X)
Definition: SDL_keycode.h:48
GLsizei const GLfloat * value
void X11_UpdateKeymap(_THIS)
void SDL_SetScancodeName(SDL_Scancode scancode, const char *name)
Definition: SDL_keyboard.c:616
#define SDL_getenv
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 in i)
Definition: SDL_x11sym.h:50
#define NULL
Definition: begin_code.h:164
SDL_bool
Definition: SDL_stdinc.h:139
void X11_StopTextInput(_THIS)
#define SDL_GetScancodeName
int X11_InitKeyboard(_THIS)
void SDL_IME_Reset(void)
Definition: SDL_ime.c:123
#define SDL_strdup
SDL_bool SDL_IME_Init(void)
Definition: SDL_ime.c:86
#define SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
Definition: SDL_config.h:349
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:93
SDL_Scancode
The SDL keyboard scancode representation.
Definition: SDL_scancode.h:43
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:64
#define SDL_strstr
static const SDL_Scancode xvnc_scancode_table[]