Workaround crash bug in libXi <= 1.4.1 (thanks, Steve!).
authorRyan C. Gordon <icculus@icculus.org>
Sat, 20 Jul 2013 13:11:40 -0400
changeset 7475c244bc85fb84
parent 7474 ed6d4d3beba1
child 7476 61b9a4c4ca43
Workaround crash bug in libXi <= 1.4.1 (thanks, Steve!).

Fixes Bugzilla #1812.
src/video/x11/SDL_x11events.c
     1.1 --- a/src/video/x11/SDL_x11events.c	Sat Jul 20 11:16:50 2013 +0200
     1.2 +++ b/src/video/x11/SDL_x11events.c	Sat Jul 20 13:11:40 2013 -0400
     1.3 @@ -99,37 +99,60 @@
     1.4  }
     1.5  /*#define DEBUG_XEVENTS*/
     1.6  
     1.7 +struct KeyRepeatCheckData
     1.8 +{
     1.9 +    XEvent *event;
    1.10 +    SDL_bool found;
    1.11 +};
    1.12 +
    1.13 +static Bool X11_KeyRepeatCheckIfEvent(Display *display, XEvent *chkev,
    1.14 +    XPointer arg)
    1.15 +{
    1.16 +    struct KeyRepeatCheckData *d = (struct KeyRepeatCheckData *) arg;
    1.17 +    if (chkev->type == KeyPress &&
    1.18 +        chkev->xkey.keycode == d->event->xkey.keycode &&
    1.19 +        chkev->xkey.time - d->event->xkey.time < 2)
    1.20 +        d->found = SDL_TRUE;
    1.21 +    return False;
    1.22 +}
    1.23 +
    1.24  /* Check to see if this is a repeated key.
    1.25     (idea shamelessly lifted from GII -- thanks guys! :)
    1.26   */
    1.27  static SDL_bool X11_KeyRepeat(Display *display, XEvent *event)
    1.28  {
    1.29 -    XEvent peekevent;
    1.30 +    XEvent dummyev;
    1.31 +    struct KeyRepeatCheckData d;
    1.32 +    d.event = event;
    1.33 +    d.found = SDL_FALSE;
    1.34 +    if (XPending(display))
    1.35 +        XCheckIfEvent(display, &dummyev, X11_KeyRepeatCheckIfEvent,
    1.36 +            (XPointer) &d);
    1.37 +    return d.found;
    1.38 +}
    1.39  
    1.40 -    if (XPending(display)) {
    1.41 -        XPeekEvent(display, &peekevent);
    1.42 -        if ((peekevent.type == KeyPress) &&
    1.43 -            (peekevent.xkey.keycode == event->xkey.keycode) &&
    1.44 -            ((peekevent.xkey.time-event->xkey.time) < 2)) {
    1.45 -            return SDL_TRUE;
    1.46 -        }
    1.47 -    }
    1.48 -    return SDL_FALSE;
    1.49 +static Bool X11_IsWheelCheckIfEvent(Display *display, XEvent *chkev,
    1.50 +    XPointer arg)
    1.51 +{
    1.52 +    XEvent *event = (XEvent *) arg;
    1.53 +    if (chkev->type == ButtonRelease &&
    1.54 +        chkev->xbutton.button == event->xbutton.button &&
    1.55 +        chkev->xbutton.time == event->xbutton.time)
    1.56 +        return True;
    1.57 +    return False;
    1.58  }
    1.59  
    1.60  static SDL_bool X11_IsWheelEvent(Display * display,XEvent * event,int * ticks)
    1.61  {
    1.62 -    XEvent peekevent;
    1.63 +    XEvent relevent;
    1.64      if (XPending(display)) {
    1.65          /* according to the xlib docs, no specific mouse wheel events exist.
    1.66             however, mouse wheel events trigger a button press and a button release
    1.67             immediately. thus, checking if the same button was released at the same
    1.68             time as it was pressed, should be an adequate hack to derive a mouse
    1.69             wheel event. */
    1.70 -        XPeekEvent(display,&peekevent);
    1.71 -        if ((peekevent.type           == ButtonRelease) &&
    1.72 -            (peekevent.xbutton.button == event->xbutton.button) &&
    1.73 -            (peekevent.xbutton.time   == event->xbutton.time)) {
    1.74 +        if (XCheckIfEvent(display, &relevent, X11_IsWheelCheckIfEvent,
    1.75 +            (XPointer) event)) {
    1.76  
    1.77              /* by default, X11 only knows 5 buttons. on most 3 button + wheel mouse,
    1.78                 Button4 maps to wheel up, Button5 maps to wheel down. */
    1.79 @@ -139,9 +162,6 @@
    1.80              else if (event->xbutton.button == Button5) {
    1.81                  *ticks = -1;
    1.82              }
    1.83 -
    1.84 -            /* remove the following release event, as this is now a wheel event */
    1.85 -            XNextEvent(display,&peekevent);
    1.86              return SDL_TRUE;
    1.87          }
    1.88      }