21 #include "../../SDL_internal.h"
23 #if SDL_VIDEO_DRIVER_X11
27 #include "../../events/SDL_keyboard_c.h"
28 #include "../../events/scancodes_darwin.h"
29 #include "../../events/scancodes_xfree86.h"
31 #include <X11/keysym.h>
32 #include <X11/XKBlib.h>
36 #ifdef X_HAVE_UTF8_STRING
44 } KeySymToSDLScancode[] = {
167 X11_KeyCodeToSDLScancode(
_THIS, KeyCode keycode)
173 if (keysym == NoSymbol) {
177 if (keysym >= XK_a && keysym <= XK_z) {
180 if (keysym >= XK_A && keysym <= XK_Z) {
184 if (keysym == XK_0) {
187 if (keysym >= XK_1 && keysym <= XK_9) {
192 if (keysym == KeySymToSDLScancode[i].keysym) {
193 return KeySymToSDLScancode[
i].scancode;
200 X11_KeyCodeToUcs4(
_THIS, KeyCode keycode,
unsigned char group)
204 if (keysym == NoSymbol) {
219 int num_groups = XkbKeyNumGroups(data->xkb, keycode);
220 unsigned char info = XkbKeyGroupInfo(data->xkb, keycode);
222 if (num_groups && group >= num_groups) {
224 int action = XkbOutOfRangeGroupAction(info);
226 if (action == XkbRedirectIntoRange) {
227 if ((group = XkbOutOfRangeGroupNumber(info)) >= num_groups) {
230 }
else if (action == XkbClampIntoRange) {
231 group = num_groups - 1;
236 keysym = X11_XkbKeycodeToKeysym(data->
display, keycode, group, 0);
238 keysym = X11_XKeycodeToKeysym(data->
display, keycode, 0);
241 keysym = X11_XKeycodeToKeysym(data->
display, keycode, 0);
253 int min_keycode, max_keycode;
271 X11_XAutoRepeatOn(data->
display);
273 #if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
275 int xkb_major = XkbMajorVersion;
276 int xkb_minor = XkbMinorVersion;
279 data->xkb = X11_XkbGetMap(data->
display, XkbAllClientInfoMask, XkbUseCoreKbd);
283 X11_XkbSetDetectableAutoRepeat(data->
display, True, &xkb_repeat);
288 #ifdef X_HAVE_UTF8_STRING
289 if (SDL_X11_HAVE_UTF8) {
292 char *prev_locale = setlocale(LC_ALL,
NULL);
293 char *prev_xmods = X11_XSetLocaleModifiers(
NULL);
294 const char *new_xmods =
"";
295 const char *env_xmods =
SDL_getenv(
"XMODIFIERS");
316 if (has_dbus_ime_support || !xkb_repeat) {
317 new_xmods =
"@im=none";
320 setlocale(LC_ALL,
"");
321 X11_XSetLocaleModifiers(new_xmods);
327 setlocale(LC_ALL, prev_locale);
328 X11_XSetLocaleModifiers(prev_xmods);
342 X11_XDisplayKeycodes(data->
display, &min_keycode, &max_keycode);
344 fingerprint[
i].value =
345 X11_XKeysymToKeycode(data->
display, fingerprint[i].keysym) -
350 if ((max_keycode - min_keycode + 1) <= scancode_set[
i].table_size) {
355 if (fingerprint[
j].
value < 0
356 || fingerprint[
j].
value >= scancode_set[i].table_size) {
358 }
else if (scancode_set[i].
table[fingerprint[
j].
value] != fingerprint[
j].scancode) {
362 if (distance < best_distance) {
367 if (best_index >= 0 && best_distance <= 2) {
368 #ifdef DEBUG_KEYBOARD
369 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);
372 sizeof(
SDL_Scancode) * scancode_set[best_index].table_size);
377 (
"Keyboard layout unknown, please report the following to the SDL forums/mailing list (https://discourse.libsdl.org/):\n");
381 for (i = min_keycode; i <= max_keycode; ++
i) {
384 if (sym != NoSymbol) {
386 printf(
"code = %d, sym = 0x%X (%s) ", i - min_keycode,
387 (
unsigned int) sym, X11_XKeysymToString(sym));
388 scancode = X11_KeyCodeToSDLScancode(
_this, i);
391 printf(
"scancode not found\n");
417 unsigned char group = 0;
421 #if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
424 X11_XkbGetUpdatedMap(data->
display, XkbAllClientInfoMask, data->xkb);
426 if (X11_XkbGetState(data->
display, XkbUseCoreKbd, &state) == Success) {
443 key = X11_KeyCodeToUcs4(
_this, (KeyCode)i, group);
445 keymap[scancode] =
key;
449 switch (keyScancode) {
481 X11_XkbFreeKeyboard(data->xkb, 0, True);
494 #ifdef X_HAVE_UTF8_STRING
501 if (data && data->
ic) {
503 char *contents = X11_Xutf8ResetIC(data->
ic);
void SDL_GetDefaultKeymap(SDL_Keycode *keymap)
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[]
struct wl_display * display
void SDL_IME_UpdateTextRect(SDL_Rect *rect)
SDL_WindowData ** windowlist
void X11_StartTextInput(_THIS)
static const SDL_Scancode xfree86_scancode_table2[]
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
#define SDL_InvalidParamError(param)
Sint32 SDL_Keycode
The SDL virtual key representation.
GLsizei GLsizei GLfloat distance
static SDL_VideoDevice * _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 in i)
void SDL_SetKeymap(int start, SDL_Keycode *keys, int length)
static const SDL_Scancode darwin_scancode_table[]
KeySym X11_KeyCodeToSym(_THIS, KeyCode, unsigned char group)
unsigned int X11_KeySymToUcs4(KeySym keysym)
#define SDL_SCANCODE_TO_KEYCODE(X)
GLsizei const GLfloat * value
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)
void X11_UpdateKeymap(_THIS)
void SDL_SetScancodeName(SDL_Scancode scancode, const char *name)
void X11_StopTextInput(_THIS)
#define SDL_GetScancodeName
int X11_InitKeyboard(_THIS)
SDL_bool SDL_IME_Init(void)
#define SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
#define SDL_arraysize(array)
SDL_Scancode
The SDL keyboard scancode representation.
A rectangle, with the origin at the upper left.
static const SDL_Scancode xvnc_scancode_table[]