src/video/x11/SDL_x11keyboard.c
changeset 10562 b48d8a98e261
parent 10548 aea47b61c640
child 10569 9429d331668e
equal deleted inserted replaced
10561:35fee69e84df 10562:b48d8a98e261
    30 
    30 
    31 #include <X11/keysym.h>
    31 #include <X11/keysym.h>
    32 #include <X11/XKBlib.h>
    32 #include <X11/XKBlib.h>
    33 
    33 
    34 #include "imKStoUCS.h"
    34 #include "imKStoUCS.h"
       
    35 
       
    36 #ifdef X_HAVE_UTF8_STRING
       
    37 #include <locale.h>
       
    38 #endif
    35 
    39 
    36 /* *INDENT-OFF* */
    40 /* *INDENT-OFF* */
    37 static const struct {
    41 static const struct {
    38     KeySym keysym;
    42     KeySym keysym;
    39     SDL_Scancode scancode;
    43     SDL_Scancode scancode;
   260         { SDL_SCANCODE_KP_ENTER, XK_KP_Enter, 0 },
   264         { SDL_SCANCODE_KP_ENTER, XK_KP_Enter, 0 },
   261     };
   265     };
   262     int best_distance;
   266     int best_distance;
   263     int best_index;
   267     int best_index;
   264     int distance;
   268     int distance;
   265 
   269     BOOL xkb_repeat = 0;
       
   270     
   266     X11_XAutoRepeatOn(data->display);
   271     X11_XAutoRepeatOn(data->display);
   267 
   272 
   268 #if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
   273 #if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
   269     {
   274     {
   270 	    int xkb_major = XkbMajorVersion;
   275         int xkb_major = XkbMajorVersion;
   271 	    int xkb_minor = XkbMinorVersion;
   276         int xkb_minor = XkbMinorVersion;
   272 	    if (X11_XkbQueryExtension(data->display, NULL, NULL, NULL, &xkb_major, &xkb_minor)) {
   277 
   273 	        data->xkb = X11_XkbGetMap(data->display, XkbAllClientInfoMask, XkbUseCoreKbd);
   278         if (X11_XkbQueryExtension(data->display, NULL, NULL, NULL, &xkb_major, &xkb_minor)) {
   274 	    }
   279             data->xkb = X11_XkbGetMap(data->display, XkbAllClientInfoMask, XkbUseCoreKbd);
   275 	}
   280         }
   276 #endif
   281 
   277 
   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
   278     /* Try to determine which scancodes are being used based on fingerprint */
   345     /* Try to determine which scancodes are being used based on fingerprint */
   279     best_distance = SDL_arraysize(fingerprint) + 1;
   346     best_distance = SDL_arraysize(fingerprint) + 1;
   280     best_index = -1;
   347     best_index = -1;
   281     X11_XDisplayKeycodes(data->display, &min_keycode, &max_keycode);
   348     X11_XDisplayKeycodes(data->display, &min_keycode, &max_keycode);
   282     for (i = 0; i < SDL_arraysize(fingerprint); ++i) {
   349     for (i = 0; i < SDL_arraysize(fingerprint); ++i) {