Commit 57fa80fc authored by Sam Lantinga's avatar Sam Lantinga

Fixed X11 mouse motion/button events - it's not actually safe to cast mouse...

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

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%403402
parent 30768ab2
......@@ -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 @@ SDL_GetMouse(int index)
return SDL_mice[index];
}
int
SDL_SetMouseIndexId(int id, int index)
{
if (id < 0) {
SDL_SetError("Invalid Mouse ID");
return -1;
}
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;
}
int
static int
SDL_GetMouseIndexId(int id)
{
if (id < 0 || id > SDL_highestId) {
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;
}
}
return SDL_IdIndex[id];
return -1;
}
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;
/* 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;
}
if (SDL_GetMouseIndexId(mouse->id) != -1) {
SDL_SetError("Mouse ID already in use");
}
SDL_mice = mice;
index = SDL_num_mice++;
/* Add the mouse to the list of mice */
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[index] = (SDL_Mouse *) SDL_malloc(sizeof(*SDL_mice[index]));
if (!SDL_mice[index]) {
SDL_OutOfMemory();
......
......@@ -64,6 +64,7 @@ struct SDL_Mouse
int current_end;
/* Data common to all mice */
int id;
SDL_WindowID focus;
int which;
int x;
......@@ -89,19 +90,13 @@ struct SDL_Mouse
/* 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 */
......
......@@ -32,8 +32,7 @@ Cocoa_InitMouse(_THIS)
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
......
......@@ -47,6 +47,7 @@ EnumMice(DFBInputDeviceID device_id,
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 @@ EnumMice(DFBInputDeviceID device_id,
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 @@ DirectFB_InitMouse(_THIS)
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;
}
}
......
......@@ -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;
......
......@@ -150,7 +150,7 @@ WIN_InitMouse(_THIS)
/* 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 @@ WIN_InitMouse(_THIS)
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);
......
......@@ -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 @@ X11_DispatchEvent(_THIS)
#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 @@ X11_DispatchEvent(_THIS)
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 @@ X11_DispatchEvent(_THIS)
}
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;
......
......@@ -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 @@ X11_InitMouse(_THIS)
for (j = 0; j < DevList[i].num_classes; ++j) {
if (deviceClass->class == ValuatorClass) { /* bingo ;) */
XValuatorInfo *valInfo;
SDL_Mouse mouse;
newDevices =
(XDevice **) SDL_realloc(SDL_XDevices,
(index +
1) * sizeof(*newDevices));
if (!newDevices) {
SDL_OutOfMemory();
return;
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;
}
/* 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 @@ X11_InitMouse(_THIS)
}
}
XFreeDeviceList(DevList);
SDL_NumOfXDevices = index;
#endif
}
......
......@@ -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);
......
......@@ -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 @@ VideoBootStrap X11_bootstrap = {
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_VideoInit(_THIS)
}
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_VideoQuit(_THIS)
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: */
......@@ -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 @@ typedef struct SDL_VideoData
int numwindows;
SDL_WindowData **windowlist;
int windowlistlength;
int mouse;
int keyboard;
Atom WM_DELETE_WINDOW;
SDL_scancode key_layout[256];
......
......@@ -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 @@ X11_CreateWindow(_THIS, SDL_Window * window)
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 @@ X11_CreateWindow(_THIS, SDL_Window * window)
}
#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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment