Fixed X11 mouse motion/button events - it's not actually safe to cast mouse events to device events.
authorSam Lantinga <slouken@libsdl.org>
Thu, 01 Jan 2009 07:59:08 +0000
changeset 2940 b93965a16fe0
parent 2939 084e5b4fc5be
child 2941 1d2bc7259f30
Fixed X11 mouse motion/button events - it's not actually safe to cast mouse events to device events. Fixed building SDL without XInput support Simplified the process of registering a mouse device
src/events/SDL_mouse.c
src/events/SDL_mouse_c.h
src/video/cocoa/SDL_cocoamouse.m
src/video/directfb/SDL_DirectFB_mouse.c
src/video/uikit/SDL_uikitview.m
src/video/win32/SDL_win32mouse.c
src/video/x11/SDL_x11events.c
src/video/x11/SDL_x11mouse.c
src/video/x11/SDL_x11mouse.h
src/video/x11/SDL_x11video.c
src/video/x11/SDL_x11video.h
src/video/x11/SDL_x11window.c
--- a/src/events/SDL_mouse.c	Thu Jan 01 07:58:20 2009 +0000
+++ b/src/events/SDL_mouse.c	Thu Jan 01 07:59:08 2009 +0000
@@ -31,8 +31,6 @@
 static int SDL_num_mice = 0;
 static int SDL_current_mouse = -1;
 static SDL_Mouse **SDL_mice = NULL;
-static int *SDL_IdIndex = NULL;
-static int SDL_highestId = -1;
 
 
 /* Public functions */
@@ -51,62 +49,44 @@
     return SDL_mice[index];
 }
 
-int
-SDL_SetMouseIndexId(int id, int index)
+static int
+SDL_GetMouseIndexId(int id)
 {
-    if (id < 0) {
-        SDL_SetError("Invalid Mouse ID");
-        return -1;
+    int index;
+    SDL_Mouse *mouse;
+
+    for (index = 0; index < SDL_num_mice; ++index) {
+        mouse = SDL_GetMouse(index);
+        if (mouse->id == id) {
+            return index;
+        }
     }
-    if (id > SDL_highestId) {
-        int *indexes;
-        int i;
-        indexes = (int *) SDL_realloc(SDL_IdIndex, (id + 1) * sizeof(int));
-        if (!indexes) {
-            SDL_OutOfMemory();
-            return -1;
-        }
-        SDL_IdIndex = indexes;
-        for (i = SDL_highestId + 1; i <= id; i++)
-            SDL_IdIndex[i] = -1;
-        SDL_IdIndex[id] = index;
-        SDL_highestId = id;
-    } else {
-        SDL_IdIndex[id] = index;
-    }
-    return 1;
+    return -1;
 }
 
 int
-SDL_GetMouseIndexId(int id)
-{
-    if (id < 0 || id > SDL_highestId) {
-        return -1;
-    }
-    return SDL_IdIndex[id];
-}
-
-int
-SDL_AddMouse(const SDL_Mouse * mouse, int index, char *name, int pressure_max,
+SDL_AddMouse(const SDL_Mouse * mouse, char *name, int pressure_max,
              int pressure_min, int ends)
 {
     SDL_Mouse **mice;
     int selected_mouse;
-    int length;
+    int index, length;
+
+    if (SDL_GetMouseIndexId(mouse->id) != -1) {
+        SDL_SetError("Mouse ID already in use");
+    }
 
     /* Add the mouse to the list of mice */
-    if (index < 0 || index >= SDL_num_mice || SDL_mice[index]) {
-        mice =
-            (SDL_Mouse **) SDL_realloc(SDL_mice,
-                                       (SDL_num_mice + 1) * sizeof(*mice));
-        if (!mice) {
-            SDL_OutOfMemory();
-            return -1;
-        }
+    mice = (SDL_Mouse **) SDL_realloc(SDL_mice,
+                                      (SDL_num_mice + 1) * sizeof(*mice));
+    if (!mice) {
+        SDL_OutOfMemory();
+        return -1;
+    }
 
-        SDL_mice = mice;
-        index = SDL_num_mice++;
-    }
+    SDL_mice = mice;
+    index = SDL_num_mice++;
+
     SDL_mice[index] = (SDL_Mouse *) SDL_malloc(sizeof(*SDL_mice[index]));
     if (!SDL_mice[index]) {
         SDL_OutOfMemory();
--- a/src/events/SDL_mouse_c.h	Thu Jan 01 07:58:20 2009 +0000
+++ b/src/events/SDL_mouse_c.h	Thu Jan 01 07:59:08 2009 +0000
@@ -64,6 +64,7 @@
     int current_end;
 
     /* Data common to all mice */
+    int id;
     SDL_WindowID focus;
     int which;
     int x;
@@ -89,19 +90,13 @@
 /* Initialize the mouse subsystem */
 extern int SDL_MouseInit(void);
 
-/* Assign an id to a mouse at an index */
-extern int SDL_SetMouseIndexId(int id, int index);
-
-/* Get the index of a mouse specified by id */
-extern int SDL_GetMouseIndexId(int id);
-
 /* Get the mouse at an index */
 extern SDL_Mouse *SDL_GetMouse(int index);
 
 /* Add a mouse, possibly reattaching at a particular index (or -1),
    returning the index of the mouse, or -1 if there was an error.
  */
-extern int SDL_AddMouse(const SDL_Mouse * mouse, int index, char *name,
+extern int SDL_AddMouse(const SDL_Mouse * mouse, char *name,
                         int pressure_max, int pressure_min, int ends);
 
 /* Remove a mouse at an index, clearing the slot for later */
--- a/src/video/cocoa/SDL_cocoamouse.m	Thu Jan 01 07:58:20 2009 +0000
+++ b/src/video/cocoa/SDL_cocoamouse.m	Thu Jan 01 07:59:08 2009 +0000
@@ -32,8 +32,7 @@
     SDL_Mouse mouse;
 
     SDL_zero(mouse);
-    data->mouse = SDL_AddMouse(&mouse, -1, "Mouse", 0, 0, 1);
-    SDL_SetMouseIndexId(data->mouse, data->mouse);
+    data->mouse = SDL_AddMouse(&mouse, "Mouse", 0, 0, 1);
 }
 
 void
--- a/src/video/directfb/SDL_DirectFB_mouse.c	Thu Jan 01 07:58:20 2009 +0000
+++ b/src/video/directfb/SDL_DirectFB_mouse.c	Thu Jan 01 07:59:08 2009 +0000
@@ -47,6 +47,7 @@
         SDL_Mouse mouse;
 
         SDL_zero(mouse);
+        mouse.id = device_id;
         mouse.CreateCursor = DirectFB_CreateCursor;
         mouse.ShowCursor = DirectFB_ShowCursor;
         mouse.MoveCursor = DirectFB_MoveCursor;
@@ -55,10 +56,8 @@
         mouse.FreeMouse = DirectFB_FreeMouse;
         mouse.cursor_shown = 1;
 
-        SDL_SetMouseIndexId(device_id, devdata->num_mice);
-        SDL_AddMouse(&mouse, devdata->num_mice, desc.name, 0, 0, 1);
-        devdata->mouse_id[devdata->num_mice] = device_id;
-        devdata->num_mice++;
+        SDL_AddMouse(&mouse, desc.name, 0, 0, 1);
+        devdata->mouse_id[devdata->num_mice++] = device_id;
     }
     return DFENUM_OK;
 }
@@ -91,9 +90,7 @@
         mouse.FreeMouse = DirectFB_FreeMouse;
         mouse.cursor_shown = 1;
 
-        SDL_SetMouseIndexId(0, 0);      /* ID == Index ! */
-        devdata->mouse_id[0] = 0;
-        SDL_AddMouse(&mouse, 0, "Mouse", 0, 0, 1);
+        SDL_AddMouse(&mouse, "Mouse", 0, 0, 1);
         devdata->num_mice = 1;
     }
 }
--- a/src/video/uikit/SDL_uikitview.m	Thu Jan 01 07:58:20 2009 +0000
+++ b/src/video/uikit/SDL_uikitview.m	Thu Jan 01 07:59:08 2009 +0000
@@ -49,8 +49,9 @@
 
 	int i;
 	for (i=0; i<MAX_SIMULTANEOUS_TOUCHES; i++) {
+        mice[i].id = i;
 		mice[i].driverdata = NULL;
-		SDL_AddMouse(&mice[i], i, "Mouse", 0, 0, 1);
+		SDL_AddMouse(&mice[i], "Mouse", 0, 0, 1);
 	}
 	self.multipleTouchEnabled = YES;
 			
--- a/src/video/win32/SDL_win32mouse.c	Thu Jan 01 07:58:20 2009 +0000
+++ b/src/video/win32/SDL_win32mouse.c	Thu Jan 01 07:59:08 2009 +0000
@@ -150,7 +150,7 @@
         /* we're saving the handle to the device */
         mice[index] = deviceList[i].hDevice;
         SDL_zero(mouse);
-        SDL_SetMouseIndexId(index, index);
+        mouse.id = index;
         l = SDL_strlen(device_name);
 
         /* we're checking if the device isn't by any chance a tablet */
@@ -176,10 +176,10 @@
             data->WTInfoA(WTI_DEVICES, DVC_NPRESSURE, &pressure);
             data->WTInfoA(WTI_DEVICES, DVC_NCSRTYPES, &cursors);
             data->mouse =
-                SDL_AddMouse(&mouse, index, device_name, pressure.axMax,
+                SDL_AddMouse(&mouse, device_name, pressure.axMax,
                              pressure.axMin, cursors);
         } else {
-            data->mouse = SDL_AddMouse(&mouse, index, device_name, 0, 0, 1);
+            data->mouse = SDL_AddMouse(&mouse, device_name, 0, 0, 1);
         }
         ++index;
         SDL_free(buffer);
--- a/src/video/x11/SDL_x11events.c	Thu Jan 01 07:58:20 2009 +0000
+++ b/src/video/x11/SDL_x11events.c	Thu Jan 01 07:59:08 2009 +0000
@@ -28,6 +28,7 @@
 #include "SDL_syswm.h"
 #include "SDL_x11video.h"
 #include "../../events/SDL_events_c.h"
+#include "../../events/SDL_mouse_c.h"
 
 static void
 X11_DispatchEvent(_THIS)
@@ -91,10 +92,11 @@
 #endif
             if ((xevent.xcrossing.mode != NotifyGrab) &&
                 (xevent.xcrossing.mode != NotifyUngrab)) {
-                XDeviceMotionEvent *move = (XDeviceMotionEvent *) & xevent;
-                SDL_SetMouseFocus(move->deviceid, data->windowID);
-                SDL_SendMouseMotion(move->deviceid, 0, move->x,
-                                    move->y, move->axis_data[2]);
+                /* FIXME: Should we reset data for all mice? */
+#if 0
+                SDL_SetMouseFocus(0, data->windowID);
+                SDL_SendMouseMotion(0, 0, move->x, move->y, 0);
+#endif
             }
         }
         break;
@@ -112,8 +114,10 @@
             if ((xevent.xcrossing.mode != NotifyGrab) &&
                 (xevent.xcrossing.mode != NotifyUngrab) &&
                 (xevent.xcrossing.detail != NotifyInferior)) {
-                XDeviceMotionEvent *move = (XDeviceMotionEvent *) & xevent;
-                SDL_SetMouseFocus(move->deviceid, 0);
+                /* FIXME: Should we reset data for all mice? */
+#if 0
+                SDL_SetMouseFocus(0, 0);
+#endif
             }
         }
         break;
@@ -276,39 +280,69 @@
         }
         break;
 
+    case MotionNotify:
+#ifdef DEBUG_MOTION
+        printf("X11 motion: %d,%d\n", xevent.xmotion.x, xevent.xmotion.y);
+#endif
+        SDL_SendMouseMotion(0, 0, xevent.xmotion.x, xevent.xmotion.y, 0);
+        break;
+
+    case ButtonPress:
+        SDL_SendMouseButton(0, SDL_PRESSED, xevent.xbutton.button);
+        break;
+
+    case ButtonRelease:
+        SDL_SendMouseButton(0, SDL_RELEASED, xevent.xbutton.button);
+        break;
+
     default:{
-            if (xevent.type == motion) {        /* MotionNotify */
+#if SDL_VIDEO_DRIVER_X11_XINPUT
+        for (i = 0; i < SDL_GetNumMice(); ++i) {
+            SDL_Mouse *mouse;
+            X11_MouseData *data;
+
+            mouse = SDL_GetMouse(i);
+            data = (X11_MouseData *)mouse->driverdata;
+            if (!data) {
+                continue;
+            }
+                    
+            if (xevent.type == data->motion) {          /* MotionNotify */
                 XDeviceMotionEvent *move = (XDeviceMotionEvent *) & xevent;
 #ifdef DEBUG_MOTION
                 printf("X11 motion: %d,%d\n", move->x, move->y);
 #endif
-                SDL_SendMouseMotion(move->deviceid, 0, move->x,
-                                    move->y, move->axis_data[2]);
-            } else if (xevent.type == button_pressed) { /* ButtonPress */
+                SDL_SendMouseMotion(move->deviceid, 0, move->x, move->y, move->axis_data[2]);
+                return;
+            }
+            if (xevent.type == data->button_pressed) {  /* ButtonPress */
                 XDeviceButtonPressedEvent *pressed =
                     (XDeviceButtonPressedEvent *) & xevent;
-                SDL_SendMouseButton(pressed->deviceid, SDL_PRESSED,
-                                    pressed->button);
-            } else if (xevent.type == button_released) {        /* ButtonRelease */
+                SDL_SendMouseButton(pressed->deviceid, SDL_PRESSED, pressed->button);
+                return;
+            }
+            if (xevent.type == data->button_released) { /* ButtonRelease */
                 XDeviceButtonReleasedEvent *released =
                     (XDeviceButtonReleasedEvent *) & xevent;
-                SDL_SendMouseButton(released->deviceid, SDL_RELEASED,
-                                    released->button);
-            } else if (xevent.type == proximity_in) {
+                SDL_SendMouseButton(released->deviceid, SDL_RELEASED, released->button);
+                return;
+            }
+            if (xevent.type == data->proximity_in) {
                 XProximityNotifyEvent *proximity =
                     (XProximityNotifyEvent *) & xevent;
-                SDL_SendProximity(proximity->deviceid, proximity->x,
-                                  proximity->y, SDL_PROXIMITYIN);
-            } else if (xevent.type == proximity_out) {
+                SDL_SendProximity(proximity->deviceid, proximity->x, proximity->y, SDL_PROXIMITYIN);
+                return;
+            }
+            if (xevent.type == data->proximity_out) {
                 XProximityNotifyEvent *proximity =
                     (XProximityNotifyEvent *) & xevent;
-                SDL_SendProximity(proximity->deviceid, proximity->x,
-                                  proximity->y, SDL_PROXIMITYOUT);
+                SDL_SendProximity(proximity->deviceid, proximity->x, proximity->y, SDL_PROXIMITYOUT);
+                return;
             }
+        }
+#endif
 #ifdef DEBUG_XEVENTS
-            else {
-                printf("Unhandled event %d\n", xevent.type);
-            }
+            printf("Unhandled event %d\n", xevent.type);
 #endif
         }
         break;
--- a/src/video/x11/SDL_x11mouse.c	Thu Jan 01 07:58:20 2009 +0000
+++ b/src/video/x11/SDL_x11mouse.c	Thu Jan 01 07:59:08 2009 +0000
@@ -21,32 +21,50 @@
 */
 #include "SDL_config.h"
 #include "SDL_x11video.h"
+#include "SDL_x11mouse.h"
 #include "../../events/SDL_mouse_c.h"
 
+#if SDL_VIDEO_DRIVER_X11_XINPUT
+static void
+X11_FreeMouse(SDL_Mouse *mouse)
+{
+    X11_MouseData *data = (X11_MouseData *)mouse->driverdata;
+
+    if (data) {
+        XCloseDevice(data->display, mouse->id);
+        SDL_free(data);
+    }
+}
+#endif
+
 void
 X11_InitMouse(_THIS)
 {
+    SDL_Mouse mouse;
 #if SDL_VIDEO_DRIVER_X11_XINPUT
-    XDevice **newDevices;
-    int i, j, index = 0, numOfDevices;
+    Display *display = ((SDL_VideoData *) _this->driverdata)->display;
+    X11_MouseData *data;
+    int i, j, n;
     XDeviceInfo *DevList;
     XAnyClassPtr deviceClass;
-    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+    int event_code;
+    XEventClass xEvent;
+#endif
 
-    SDL_XDevices = NULL;
-    SDL_NumOfXDevices = 0;
+    SDL_zero(mouse);
+    SDL_AddMouse(&mouse, "CorePointer", 0, 0, 1);
 
+#if SDL_VIDEO_DRIVER_X11_XINPUT
     if (!SDL_X11_HAVE_XINPUT) {
         /* should have dynamically loaded, but wasn't available. */
         return;
     }
 
     /* we're getting the list of input devices */
-    DevList = XListInputDevices(data->display, &numOfDevices);
-    SDL_XDevices = (XDevice **) SDL_malloc(sizeof(XDevice));
+    DevList = XListInputDevices(display, &n);
 
-    /* we're aquiring valuators:mices, tablets, etc. */
-    for (i = 0; i < numOfDevices; ++i) {
+    /* we're aquiring valuators: mice, tablets, etc. */
+    for (i = 0; i < n; ++i) {
         /* if it's the core pointer or core keyborard we don't want it */
         if ((DevList[i].use != IsXPointer && DevList[i].use != IsXKeyboard)) {
             /* we have to check all of the device classes */
@@ -54,36 +72,59 @@
             for (j = 0; j < DevList[i].num_classes; ++j) {
                 if (deviceClass->class == ValuatorClass) {      /* bingo ;) */
                     XValuatorInfo *valInfo;
-                    SDL_Mouse mouse;
+
+                    data = (X11_MouseData *)SDL_calloc(1, sizeof(*data));
+                    if (!data) {
+                        continue;
+                    }
+                    data->display = display;
+                    data->device = XOpenDevice(display, DevList[i].id);
+
+                    /* motion events */
+                    DeviceMotionNotify(data->device, event_code, xEvent);
+                    if (xEvent) {
+                        data->xevents[data->num_xevents++] = xEvent;
+                        data->motion = event_code;
+                    }
 
-                    newDevices =
-                        (XDevice **) SDL_realloc(SDL_XDevices,
-                                                 (index +
-                                                  1) * sizeof(*newDevices));
-                    if (!newDevices) {
-                        SDL_OutOfMemory();
-                        return;
+                    /* button events */
+                    DeviceButtonPress(data->device, event_code, xEvent);
+                    if (xEvent) {
+                        data->xevents[data->num_xevents++] = xEvent;
+                        data->button_pressed = event_code;
+                    }
+                    DeviceButtonRelease(data->device, event_code, xEvent);
+                    if (xEvent) {
+                        data->xevents[data->num_xevents++] = xEvent;
+                        data->button_released = event_code;
                     }
-                    SDL_XDevices = newDevices;
-                    SDL_XDevices[index] =
-                        XOpenDevice(data->display, DevList[i].id);
+
+                    /* proximity events */
+                    ProximityIn(data->device, event_code, xEvent);
+                    if (xEvent) {
+                        data->xevents[data->num_xevents++] = xEvent;
+                        data->proximity_in = event_code;
+                    }
+                    ProximityOut(data->device, event_code, xEvent);
+                    if (xEvent) {
+                        data->xevents[data->num_xevents++] = xEvent;
+                        data->proximity_out = event_code;
+                    }
+
                     SDL_zero(mouse);
+                    mouse.id = DevList[i].id;
+                    mouse.FreeMouse = X11_FreeMouse;
+                    mouse.driverdata = data;
 
-                    /* the id of the device differs from its index
-                     * so we're assigning the index of a device to it's id */
-                    SDL_SetMouseIndexId(DevList[i].id, index);
                     /* lets get the device parameters */
                     valInfo = (XValuatorInfo *) deviceClass;
                     /* if the device reports pressure, lets check it parameteres */
                     if (valInfo->num_axes > 2) {
-                        data->mouse =
-                            SDL_AddMouse(&mouse, index++, DevList[i].name,
+                            SDL_AddMouse(&mouse, DevList[i].name,
                                          valInfo->axes[2].max_value,
                                          valInfo->axes[2].min_value, 1);
                     } else {
-                        data->mouse =
-                            SDL_AddMouse(&mouse, index++, DevList[i].name, 0,
-                                         0, 1);
+                            SDL_AddMouse(&mouse, DevList[i].name, 0, 0, 1);
                     }
                     break;
                 }
@@ -95,8 +136,6 @@
         }
     }
     XFreeDeviceList(DevList);
-
-    SDL_NumOfXDevices = index;
 #endif
 }
 
--- a/src/video/x11/SDL_x11mouse.h	Thu Jan 01 07:58:20 2009 +0000
+++ b/src/video/x11/SDL_x11mouse.h	Thu Jan 01 07:59:08 2009 +0000
@@ -24,6 +24,21 @@
 #ifndef _SDL_x11mouse_h
 #define _SDL_x11mouse_h
 
+#if SDL_VIDEO_DRIVER_X11_XINPUT
+typedef struct X11_MouseData
+{
+    Display *display;
+    XDevice *device;
+    int motion;
+    int button_pressed;
+    int button_released;
+    int proximity_in;
+    int proximity_out;
+    int num_xevents;
+    XEventClass xevents[5];
+} X11_MouseData;
+#endif
+
 extern void X11_InitMouse(_THIS);
 extern void X11_QuitMouse(_THIS);
 
--- a/src/video/x11/SDL_x11video.c	Thu Jan 01 07:58:20 2009 +0000
+++ b/src/video/x11/SDL_x11video.c	Thu Jan 01 07:59:08 2009 +0000
@@ -28,14 +28,6 @@
 
 #include "SDL_x11video.h"
 
-#if SDL_VIDEO_DRIVER_X11_XINPUT
-XDevice **SDL_XDevices;
-int SDL_NumOfXDevices;
-XEventClass SDL_XEvents[256];
-int SDL_NumOfXEvents;
-int motion, button_pressed, button_released;    /* the definitions of the mice events */
-int proximity_in, proximity_out;
-#endif
 
 /* Initialization/Query functions */
 static int X11_VideoInit(_THIS);
@@ -218,8 +210,6 @@
 int
 X11_VideoInit(_THIS)
 {
-    int i, index = 0, event_code;
-    XEventClass xEvent;
     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
 
     /* Get the window class name, usually the name of the application */
@@ -253,49 +243,6 @@
     }
     X11_InitMouse(_this);
 
-    /* Set reasonable defaults, in case !SDL_VIDEO_DRIVER_X11_XINPUT */
-    motion = MotionNotify;
-    button_pressed = ButtonPress;
-    button_released = ButtonRelease;
-
-#if SDL_VIDEO_DRIVER_X11_XINPUT
-    /* we're generating the table of events that should be recognized */
-    for (i = 0; i < SDL_NumOfXDevices; ++i) {
-        /* button events */
-        DeviceButtonPress(SDL_XDevices[i], event_code, xEvent);
-        if (xEvent) {
-            SDL_XEvents[index++] = xEvent;
-            button_pressed = event_code;
-        }
-        DeviceButtonRelease(SDL_XDevices[i], event_code, xEvent);
-        if (xEvent) {
-            SDL_XEvents[index++] = xEvent;
-            button_released = event_code;
-        }
-
-        /* proximity events */
-        ProximityIn(SDL_XDevices[i], event_code, xEvent);
-        if (xEvent) {
-            SDL_XEvents[index++] = xEvent;
-            proximity_in = event_code;
-        }
-        ProximityOut(SDL_XDevices[i], event_code, xEvent);
-        if (xEvent) {
-            SDL_XEvents[index++] = xEvent;
-            proximity_out = event_code;
-        }
-
-        /* motion events */
-        DeviceMotionNotify(SDL_XDevices[i], event_code, xEvent);
-        if (xEvent) {
-            SDL_XEvents[index++] = xEvent;
-            motion = event_code;
-        }
-
-    }
-    SDL_NumOfXEvents = index;
-#endif
-
     return 0;
 }
 
@@ -318,10 +265,6 @@
     X11_QuitModes(_this);
     X11_QuitKeyboard(_this);
     X11_QuitMouse(_this);
-
-#if SDL_VIDEO_DRIVER_X11_XINPUT
-    free(SDL_XDevices);
-#endif
 }
 
 /* vim: set ts=4 sw=4 expandtab: */
--- a/src/video/x11/SDL_x11video.h	Thu Jan 01 07:58:20 2009 +0000
+++ b/src/video/x11/SDL_x11video.h	Thu Jan 01 07:59:08 2009 +0000
@@ -61,22 +61,6 @@
 
 /* Private display data */
 
-#if SDL_VIDEO_DRIVER_X11_XINPUT
-/* !!! FIXME: should be in SDL_VideoData, not globals. */
-extern XDevice **SDL_XDevices;
-extern int SDL_NumOfXDevices;
-extern XEventClass SDL_XEvents[256];
-extern int SDL_NumOfXEvents;
-#endif
-
-/* !!! FIXME: should be in SDL_VideoData, not globals. */
-/* !!! FIXME: change these names, too. */
-extern int motion;              /* the motion event id defined by an XInput function */
-extern int button_pressed;      /* the button_pressed event id defined by an XInput function */
-extern int button_released;     /* the button_released event id defined by an XInput function */
-extern int proximity_in;        /* the proximity in event defined by an XInput function */
-extern int proximity_out;       /* the proximity out event defined by an XInput function */
-
 typedef struct SDL_VideoData
 {
     Display *display;
@@ -87,7 +71,6 @@
     int numwindows;
     SDL_WindowData **windowlist;
     int windowlistlength;
-    int mouse;
     int keyboard;
     Atom WM_DELETE_WINDOW;
     SDL_scancode key_layout[256];
--- a/src/video/x11/SDL_x11window.c	Thu Jan 01 07:58:20 2009 +0000
+++ b/src/video/x11/SDL_x11window.c	Thu Jan 01 07:59:08 2009 +0000
@@ -24,8 +24,10 @@
 #include "SDL_syswm.h"
 #include "../SDL_sysvideo.h"
 #include "../../events/SDL_keyboard_c.h"
+#include "../../events/SDL_mouse_c.h"
 
 #include "SDL_x11video.h"
+#include "SDL_x11mouse.h"
 #include "../Xext/extensions/StdCmap.h"
 
 static void
@@ -172,8 +174,6 @@
     XSizeHints *sizehints;
     XWMHints *wmhints;
     XClassHint *classhints;
-    extern XEventClass SDL_XEvents[];
-    extern int SDL_NumOfXEvents;
 
 #if SDL_VIDEO_DRIVER_X11_XINERAMA
 /* FIXME
@@ -523,8 +523,31 @@
     }
 #endif
 
+#if SDL_VIDEO_DRIVER_X11_XINPUT
     /* we're informing the display what extension events we want to receive from it */
-    XSelectExtensionEvent(data->display, w, SDL_XEvents, SDL_NumOfXEvents);
+    {
+        int i, j, n = 0;
+        XEventClass xevents[256];
+
+        for (i = 0; i < SDL_GetNumMice(); ++i) {
+            SDL_Mouse *mouse;
+            X11_MouseData *data;
+
+            mouse = SDL_GetMouse(i);
+            data = (X11_MouseData *)mouse->driverdata;
+            if (!data) {
+                continue;
+            }
+
+            for (j = 0; j < data->num_xevents; ++j) {
+                xevents[n++] = data->xevents[j];
+            }
+        }
+        if (n > 0) {
+            XSelectExtensionEvent(data->display, w, xevents, n);
+        }
+    }
+#endif
 
     return 0;
 }