Fixed bug 3130 - Spacebar not responding
authorSam Lantinga <slouken@libsdl.org>
Sat, 01 Oct 2016 14:22:10 -0700
changeset 104390426a82e291d
parent 10438 f7d8e9d871c5
child 10440 d97ef52b492b
Fixed bug 3130 - Spacebar not responding

Alex Baines

Make sure group is valid before passing it to XkbKeysymToKeycode.
src/video/x11/SDL_x11keyboard.c
src/video/x11/SDL_x11sym.h
src/video/x11/SDL_x11video.h
     1.1 --- a/src/video/x11/SDL_x11keyboard.c	Sat Oct 01 14:18:29 2016 -0700
     1.2 +++ b/src/video/x11/SDL_x11keyboard.c	Sat Oct 01 14:22:10 2016 -0700
     1.3 @@ -179,14 +179,36 @@
     1.4  }
     1.5  
     1.6  static Uint32
     1.7 -X11_KeyCodeToUcs4(Display *display, KeyCode keycode, unsigned char group)
     1.8 +X11_KeyCodeToUcs4(SDL_VideoData *data, KeyCode keycode, unsigned char group)
     1.9  {
    1.10      KeySym keysym;
    1.11  
    1.12  #if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
    1.13 -    keysym = X11_XkbKeycodeToKeysym(display, keycode, group, 0);
    1.14 +    if (data->xkb) {
    1.15 +        int num_groups     = XkbKeyNumGroups(data->xkb, keycode);
    1.16 +        unsigned char info = XkbKeyGroupInfo(data->xkb, keycode);
    1.17 +        
    1.18 +        if (num_groups && group >= num_groups) {
    1.19 +        
    1.20 +            int action = XkbOutOfRangeGroupAction(info);
    1.21 +            
    1.22 +            if (action == XkbRedirectIntoRange) {
    1.23 +                if ((group = XkbOutOfRangeGroupNumber(info)) >= num_groups) {
    1.24 +                    group = 0;
    1.25 +                }
    1.26 +            } else if (action == XkbClampIntoRange) {
    1.27 +                group = num_groups - 1;
    1.28 +            } else {
    1.29 +                group %= num_groups;
    1.30 +            }
    1.31 +        }
    1.32 +    } else {
    1.33 +        group = 0;
    1.34 +    }
    1.35 +
    1.36 +    keysym = X11_XkbKeycodeToKeysym(data->display, keycode, group, 0);
    1.37  #else
    1.38 -    keysym = X11_XKeycodeToKeysym(display, keycode, 0);
    1.39 +    keysym = X11_XKeycodeToKeysym(data->display, keycode, 0);
    1.40  #endif
    1.41      if (keysym == NoSymbol) {
    1.42          return 0;
    1.43 @@ -308,6 +330,12 @@
    1.44      
    1.45  #if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
    1.46      {
    1.47 +        if (data->xkb) {
    1.48 +            X11_XkbGetUpdatedMap(data->display, XkbAllClientInfoMask, data->xkb);
    1.49 +        } else {
    1.50 +            data->xkb = X11_XkbGetMap(data->display, XkbAllClientInfoMask, XkbUseCoreKbd);
    1.51 +        }
    1.52 +
    1.53          XkbStateRec state;
    1.54          if (X11_XkbGetState(data->display, XkbUseCoreKbd, &state) == Success) {
    1.55              group = state.group;
    1.56 @@ -326,7 +354,7 @@
    1.57          }
    1.58  
    1.59          /* See if there is a UCS keycode for this scancode */
    1.60 -        key = X11_KeyCodeToUcs4(data->display, (KeyCode)i, group);
    1.61 +        key = X11_KeyCodeToUcs4(data, (KeyCode)i, group);
    1.62          if (key) {
    1.63              keymap[scancode] = key;
    1.64          } else {
    1.65 @@ -360,6 +388,14 @@
    1.66  void
    1.67  X11_QuitKeyboard(_THIS)
    1.68  {
    1.69 +    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
    1.70 +
    1.71 +#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
    1.72 +    if (data->xkb) {
    1.73 +        X11_XkbFreeClientMap(data->xkb, 0, True);
    1.74 +    }
    1.75 +#endif
    1.76 +
    1.77  #ifdef SDL_USE_IBUS
    1.78      SDL_IBus_Quit();
    1.79  #endif
     2.1 --- a/src/video/x11/SDL_x11sym.h	Sat Oct 01 14:18:29 2016 -0700
     2.2 +++ b/src/video/x11/SDL_x11sym.h	Sat Oct 01 14:22:10 2016 -0700
     2.3 @@ -175,6 +175,9 @@
     2.4  SDL_X11_SYM(KeySym,XkbKeycodeToKeysym,(Display* a,KeyCode b,int c,int d),(a,b,c,d),return)
     2.5  #endif
     2.6  SDL_X11_SYM(Status,XkbGetState,(Display* a,unsigned int b,XkbStatePtr c),(a,b,c),return)
     2.7 +SDL_X11_SYM(Status,XkbGetUpdatedMap,(Display* a,unsigned int b,XkbDescPtr c),(a,b,c),return)
     2.8 +SDL_X11_SYM(XkbDescPtr,XkbGetMap,(Display* a,unsigned int b,unsigned int c),(a,b,c),return)
     2.9 +SDL_X11_SYM(void,XkbFreeClientMap,(XkbDescPtr a,unsigned int b, Bool c),(a,b,c),)
    2.10  #endif
    2.11  
    2.12  #if NeedWidePrototypes
     3.1 --- a/src/video/x11/SDL_x11video.h	Sat Oct 01 14:18:29 2016 -0700
     3.2 +++ b/src/video/x11/SDL_x11video.h	Sat Oct 01 14:22:10 2016 -0700
     3.3 @@ -129,6 +129,10 @@
     3.4      SDL_bool global_mouse_changed;
     3.5      SDL_Point global_mouse_position;
     3.6      Uint32 global_mouse_buttons;
     3.7 +
     3.8 +#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
     3.9 +    XkbDescPtr xkb;
    3.10 +#endif
    3.11  } SDL_VideoData;
    3.12  
    3.13  extern SDL_bool X11_UseDirectColorVisuals(void);