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;
278 if (X11_XkbQueryExtension(
data->display,
NULL,
NULL,
NULL, &xkb_major, &xkb_minor)) {
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) {
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);
371 SDL_memcpy(&
data->key_layout[min_keycode], scancode_set[best_index].table,
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);
389 data->key_layout[
i] = scancode;
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) {
437 scancode =
data->key_layout[
i];
445 keymap[scancode] =
key;
449 switch (keyScancode) {
481 X11_XkbFreeKeyboard(
data->xkb, 0, True);
494 #ifdef X_HAVE_UTF8_STRING
503 char *contents = X11_Xutf8ResetIC(
data->ic);