Commit e7d72614 authored by Sam Lantinga's avatar Sam Lantinga

Final merge of Google Summer of Code 2008 work...

Many-mouse and tablet support
by Szymon Wilczek, mentored by Ryan C. Gordon

Everything concerning the project is noted on the wiki:
http://wilku.ravenlord.ws/doku.php?id=start

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%403155
parent 95134b6d
......@@ -1033,6 +1033,9 @@ AC_HELP_STRING([--enable-x11-shared], [dynamically load X11 support [[default=ma
SOURCES="$SOURCES $srcdir/src/video/Xext/XmuStdCmap/*.c"
EXTRA_CFLAGS="$EXTRA_CFLAGS $X_CFLAGS"
echo "FIXME: Need to get dynamic loading of XInput working"
enable_x11_shared=no
if test x$enable_x11_shared = xmaybe; then
enable_x11_shared=$x11_symbols_private
fi
......@@ -1055,7 +1058,7 @@ AC_HELP_STRING([--enable-x11-shared], [dynamically load X11 support [[default=ma
AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT, "$x11ext_lib")
else
enable_x11_shared=no
EXTRA_LDFLAGS="$EXTRA_LDFLAGS $X_LIBS -lX11 -lXext"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS $X_LIBS -lX11 -lXext -lXi"
fi
have_video=yes
......
......@@ -72,9 +72,11 @@ typedef enum
SDL_JOYBUTTONUP, /**< Joystick button released */
SDL_QUIT, /**< User-requested quit */
SDL_SYSWMEVENT, /**< System specific event */
SDL_PROXIMITYIN, /**< Proximity In event */
SDL_PROXIMITYOUT, /**< Proximity Out event */
SDL_EVENT_RESERVED1, /**< Reserved for future use... */
SDL_EVENT_RESERVED2, /**< Reserved for future use... */
SDL_EVENT_RESERVED3, /**< Reserved for future use... */
SDL_EVENT_RESERVED2,
SDL_EVENT_RESERVED3,
/* Events SDL_USEREVENT through SDL_MAXEVENTS-1 are for your use */
SDL_USEREVENT = 24,
/* This last event is only for bounding internal arrays
......@@ -112,7 +114,9 @@ typedef enum
SDL_EVENTMASK(SDL_JOYHATMOTION) |
SDL_EVENTMASK(SDL_JOYBUTTONDOWN) | SDL_EVENTMASK(SDL_JOYBUTTONUP),
SDL_QUITMASK = SDL_EVENTMASK(SDL_QUIT),
SDL_SYSWMEVENTMASK = SDL_EVENTMASK(SDL_SYSWMEVENT)
SDL_SYSWMEVENTMASK = SDL_EVENTMASK(SDL_SYSWMEVENT),
SDL_PROXIMITYINMASK = SDL_EVENTMASK(SDL_PROXIMITYIN),
SDL_PROXIMITYOUTMASK = SDL_EVENTMASK(SDL_PROXIMITYOUT)
} SDL_EventMask;
#define SDL_ALLEVENTS 0xFFFFFFFF
......@@ -170,6 +174,13 @@ typedef struct SDL_MouseMotionEvent
Uint8 state; /**< The current button state */
int x; /**< X coordinate, relative to window */
int y; /**< Y coordinate, relative to window */
int z; /**< Z coordinate, for future use */
int pressure; /**< Pressure reported by tablets */
int pressure_max; /**< Maximum value of the pressure reported by the device */
int pressure_min; /**< Minimum value of the pressure reported by the device */
int rotation; /**< For future use */
int tilt; /**< For future use */
int cursor; /**< The cursor being used in the event */
int xrel; /**< The relative motion in the X direction */
int yrel; /**< The relative motion in the Y direction */
SDL_WindowID windowID; /**< The window with mouse focus, if any */
......@@ -316,6 +327,15 @@ typedef struct SDL_ResizeEvent
int h;
} SDL_ResizeEvent;
typedef struct SDL_ProximityEvent
{
Uint8 type;
Uint8 which;
int cursor;
int x;
int y;
} SDL_ProximityEvent;
/**
* \union SDL_Event
*
......@@ -337,6 +357,7 @@ typedef union SDL_Event
SDL_QuitEvent quit; /**< Quit request event data */
SDL_UserEvent user; /**< Custom event data */
SDL_SysWMEvent syswm; /**< System dependent window event data */
SDL_ProximityEvent proximity; /**< Proximity In or Out event */
/* Temporarily here for backwards compatibility */
SDL_ActiveEvent active;
......
......@@ -242,7 +242,7 @@ enum
SDLK_KBDILLUMDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMDOWN),
SDLK_KBDILLUMUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMUP),
SDLK_EJECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EJECT),
SDLK_SLEEP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SLEEP),
SDLK_SLEEP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SLEEP)
};
/**
......
......@@ -72,7 +72,7 @@ extern DECLSPEC int SDLCALL SDL_SelectMouse(int index);
*
* \brief Get the window which currently has focus for the currently selected mouse.
*/
extern DECLSPEC SDL_WindowID SDLCALL SDL_GetMouseFocusWindow(void);
extern DECLSPEC SDL_WindowID SDLCALL SDL_GetMouseFocusWindow(int index);
/**
* \fn int SDL_SetRelativeMouseMode(SDL_bool enabled)
......@@ -92,7 +92,8 @@ extern DECLSPEC SDL_WindowID SDLCALL SDL_GetMouseFocusWindow(void);
*
* \sa SDL_GetRelativeMouseMode()
*/
extern DECLSPEC int SDLCALL SDL_SetRelativeMouseMode(SDL_bool enabled);
extern DECLSPEC int SDLCALL SDL_SetRelativeMouseMode(int index,
SDL_bool enabled);
/**
* \fn SDL_bool SDL_GetRelativeMouseMode()
......@@ -101,7 +102,7 @@ extern DECLSPEC int SDLCALL SDL_SetRelativeMouseMode(SDL_bool enabled);
*
* \sa SDL_SetRelativeMouseMode()
*/
extern DECLSPEC SDL_bool SDLCALL SDL_GetRelativeMouseMode(void);
extern DECLSPEC SDL_bool SDLCALL SDL_GetRelativeMouseMode(int index);
/**
* \fn Uint8 SDL_GetMouseState(int *x, int *y)
......@@ -113,7 +114,7 @@ extern DECLSPEC SDL_bool SDLCALL SDL_GetRelativeMouseMode(void);
* mouse cursor position relative to the focus window for the currently
* selected mouse. You can pass NULL for either x or y.
*/
extern DECLSPEC Uint8 SDLCALL SDL_GetMouseState(int *x, int *y);
extern DECLSPEC Uint8 SDLCALL SDL_GetMouseState(int index, int *x, int *y);
/**
* \fn Uint8 SDL_GetRelativeMouseState(int *x, int *y)
......@@ -124,7 +125,8 @@ extern DECLSPEC Uint8 SDLCALL SDL_GetMouseState(int *x, int *y);
* be tested using the SDL_BUTTON(X) macros, and x and y are set to the
* mouse deltas since the last call to SDL_GetRelativeMouseState().
*/
extern DECLSPEC Uint8 SDLCALL SDL_GetRelativeMouseState(int *x, int *y);
extern DECLSPEC Uint8 SDLCALL SDL_GetRelativeMouseState(int index, int *x,
int *y);
/**
* \fn void SDL_WarpMouseInWindow(SDL_WindowID windowID, int x, int y)
......@@ -203,6 +205,16 @@ extern DECLSPEC int SDLCALL SDL_ShowCursor(int toggle);
Button 2: Middle mouse button
Button 3: Right mouse button
*/
/* FIXME: Where do these functions go in this header?
Also, add doxygen documentation for these...
*/
extern DECLSPEC char *SDLCALL SDL_GetMouseName(int index);
extern DECLSPEC int SDLCALL SDL_GetCursorsNumber(int index);
extern DECLSPEC int SDLCALL SDL_GetCurrentCursor(int index);
#define SDL_BUTTON(X) (1 << ((X)-1))
#define SDL_BUTTON_LEFT 1
#define SDL_BUTTON_MIDDLE 2
......
......@@ -256,7 +256,7 @@ SDL_CompatEventFilter(void *userdata, SDL_Event * event)
}
selected = SDL_SelectMouse(event->wheel.which);
SDL_GetMouseState(&x, &y);
SDL_GetMouseState(selected, &x, &y);
SDL_SelectMouse(selected);
if (event->wheel.y > 0) {
......
This diff is collapsed.
......@@ -29,9 +29,7 @@ typedef struct SDL_Mouse SDL_Mouse;
struct SDL_Cursor
{
SDL_Mouse *mouse;
SDL_Cursor *next;
void *driverdata;
};
......@@ -56,14 +54,27 @@ struct SDL_Mouse
/* Free the mouse when it's time */
void (*FreeMouse) (SDL_Mouse * mouse);
/* data common for tablets */
int pressure;
int pressure_max;
int pressure_min;
int tilt; /* for future use */
int rotation; /* for future use */
int total_ends;
int current_end;
/* Data common to all mice */
SDL_WindowID focus;
int which;
int x;
int y;
int z; /* for future use */
int xdelta;
int ydelta;
char *name;
Uint8 buttonstate;
SDL_bool relative_mode;
SDL_bool proximity;
SDL_bool flush_motion;
SDL_Cursor *cursors;
......@@ -74,17 +85,23 @@ struct SDL_Mouse
void *driverdata;
};
/* Initialize the mouse subsystem */
extern int SDL_MouseInit(void);
/* Get the mouse at an index */
extern SDL_Mouse *SDL_GetMouse(int index);
/* Assign an id to a mouse at an index */
extern int SDL_SetMouseIndexId(int id, int index);
/* Get the mouse by id */
extern SDL_Mouse *SDL_GetMouseByID(int id);
/* 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);
extern int SDL_AddMouse(const SDL_Mouse * mouse, int index, char *name,
int pressure_max, int pressure_min, int ends);
/* Remove a mouse at an index, clearing the slot for later */
extern void SDL_DelMouse(int index);
......@@ -93,20 +110,24 @@ extern void SDL_DelMouse(int index);
extern void SDL_ResetMouse(int index);
/* Set the mouse focus window */
extern void SDL_SetMouseFocus(int index, SDL_WindowID windowID);
extern void SDL_SetMouseFocus(int id, SDL_WindowID windowID);
/* Send a mouse motion event for a mouse at an index */
extern int SDL_SendMouseMotion(int index, int relative, int x, int y);
extern int SDL_SendMouseMotion(int id, int relative, int x, int y, int z);
/* Send a mouse button event for a mouse at an index */
extern int SDL_SendMouseButton(int index, Uint8 state, Uint8 button);
extern int SDL_SendMouseButton(int id, Uint8 state, Uint8 button);
/* Send a mouse wheel event for a mouse at an index */
extern int SDL_SendMouseWheel(int index, int x, int y);
extern int SDL_SendMouseWheel(int id, int x, int y);
/* Shutdown the mouse subsystem */
extern void SDL_MouseQuit(void);
/* FIXME: Where do these functions go in this header? */
extern void SDL_UpdateCoordinates(int x, int y);
extern void SDL_ChangeEnd(int id, int end);
#endif /* _SDL_mouse_c_h */
/* vi: set ts=4 sw=4 expandtab: */
......@@ -32,7 +32,8 @@ Cocoa_InitMouse(_THIS)
SDL_Mouse mouse;
SDL_zero(mouse);
data->mouse = SDL_AddMouse(&mouse, -1);
data->mouse = SDL_AddMouse(&mouse, -1, "Mouse", 0, 0, 1);
SDL_SetMouseIndexId(data->mouse, data->mouse);
}
void
......
......@@ -250,7 +250,7 @@ static __inline__ void ConvertNSRect(NSRect *r)
if (mouse->focus != _data->windowID) {
SDL_SetMouseFocus(index, _data->windowID);
}
SDL_SendMouseMotion(index, 0, (int)point.x, (int)point.y);
SDL_SendMouseMotion(index, 0, (int)point.x, (int)point.y, 0);
}
}
......
This diff is collapsed.
......@@ -19,20 +19,179 @@
Sam Lantinga
slouken@libsdl.org
*/
/* we need to define it, so that raw input is included*/
#if (_WIN32_WINNT < 0x0501)
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#include "SDL_config.h"
#include "SDL_win32video.h"
#include "../../events/SDL_mouse_c.h"
#include <wintab.h>
#define PACKETDATA ( PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_CURSOR)
#define PACKETMODE 0
#include <pktdef.h>
extern HANDLE *mice;
extern int total_mice;
extern int tablet;
void
WIN_InitMouse(_THIS)
{
int index = 0;
RAWINPUTDEVICELIST *deviceList = NULL;
int devCount = 0;
int i;
int tmp = 0;
char *buffer = NULL;
char *tab = "wacom"; /* since windows does't give us handles to tablets, we have to detect a tablet by it's name */
const char *rdp = "rdp_mou";
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
/* we're checking for the number of rawinput devices */
if (GetRawInputDeviceList(NULL, &devCount, sizeof(RAWINPUTDEVICELIST))) {
return;
}
deviceList = SDL_malloc(sizeof(RAWINPUTDEVICELIST) * devCount);
/* we're getting the raw input device list */
GetRawInputDeviceList(deviceList, &devCount, sizeof(RAWINPUTDEVICELIST));
mice = SDL_malloc(devCount * sizeof(HANDLE));
/* we're getting the details of the devices */
for (i = 0; i < devCount; ++i) {
int is_rdp = 0;
int j;
int k;
char *default_device_name = "Pointing device xx";
const char *reg_key_root = "System\\CurrentControlSet\\Enum\\";
char *device_name = SDL_malloc(256 * sizeof(char));
char *key_name = NULL;
char *tmp_name = NULL;
LONG rc = 0;
HKEY hkey;
DWORD regtype = REG_SZ;
DWORD out = 256 * sizeof(char);
SDL_Mouse mouse;
int l;
if (deviceList[i].dwType != RIM_TYPEMOUSE) { /* if a device isn't a mouse type we don't want it */
continue;
}
if (GetRawInputDeviceInfoA
(deviceList[i].hDevice, RIDI_DEVICENAME, NULL, &tmp) < 0) {
continue;
}
buffer = SDL_malloc((tmp + 1) * sizeof(char));
key_name = SDL_malloc(tmp + sizeof(reg_key_root) * sizeof(char));
/* we're getting the device registry path and polishing it to get it's name,
surely there must be an easier way, but we haven't found it yet */
if (GetRawInputDeviceInfoA
(deviceList[i].hDevice, RIDI_DEVICENAME, buffer, &tmp) < 0) {
continue;
}
buffer += 4;
tmp -= 4;
tmp_name = buffer;
for (j = 0; j < tmp; ++j) {
if (*tmp_name == '#') {
*tmp_name = '\\';
}
else if (*tmp_name == '{') {
break;
}
++tmp_name;
}
*tmp_name = '\0';
SDL_memcpy(key_name, reg_key_root, SDL_strlen(reg_key_root));
SDL_memcpy(key_name + (SDL_strlen(reg_key_root)), buffer, j + 1);
l = SDL_strlen(key_name);
is_rdp = 0;
if (l >= 7) {
for (j = 0; j < l - 7; ++j) {
for (k = 0; k < 7; ++k) {
if (rdp[k] !=
SDL_tolower((unsigned char) key_name[j + k])) {
break;
}
}
if (k == 7) {
is_rdp = 1;
break;
}
}
}
if (is_rdp == 1) {
SDL_free(buffer);
SDL_free(key_name);
SDL_free(device_name);
is_rdp = 0;
continue;
}
/* we're opening the registry key to get the mouse name */
rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE, key_name, 0, KEY_READ, &hkey);
if (rc != ERROR_SUCCESS) {
SDL_memcpy(device_name, default_device_name,
SDL_strlen(default_device_name));
}
rc = RegQueryValueExA(hkey, "DeviceDesc", NULL, &regtype, device_name,
&out);
RegCloseKey(hkey);
if (rc != ERROR_SUCCESS) {
SDL_memcpy(device_name, default_device_name,
SDL_strlen(default_device_name));
}
/* we're saving the handle to the device */
mice[index] = deviceList[i].hDevice;
SDL_zero(mouse);
data->mouse = SDL_AddMouse(&mouse, -1);
SDL_SetMouseIndexId(index, index);
l = SDL_strlen(device_name);
/* we're checking if the device isn't by any chance a tablet */
if (tablet == -1) {
for (j = 0; j < l - 5; ++j) {
for (k = 0; k < 5; ++k) {
if (tab[k] !=
SDL_tolower((unsigned char) device_name[j + k])) {
break;
}
}
if (k == 5) {
tablet = index;
break;
}
}
}
/* if it's a tablet, let's read it's maximum and minimum pressure */
if (tablet == index) {
AXIS pressure;
int cursors;
WTInfo(WTI_DEVICES, DVC_NPRESSURE, &pressure);
WTInfo(WTI_DEVICES, DVC_NCSRTYPES, &cursors);
data->mouse =
SDL_AddMouse(&mouse, index, device_name, pressure.axMax,
pressure.axMin, cursors);
} else {
data->mouse = SDL_AddMouse(&mouse, index, device_name, 0, 0, 1);
}
++index;
SDL_free(buffer);
SDL_free(key_name);
}
total_mice = index;
SDL_free(deviceList);
}
void
......@@ -40,7 +199,8 @@ WIN_QuitMouse(_THIS)
{
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
SDL_DelMouse(data->mouse);
/* let's delete all of the mice */
SDL_MouseQuit();
}
/* vi: set ts=4 sw=4 expandtab: */
......@@ -31,10 +31,17 @@
#include "SDL_d3drender.h"
#include "SDL_gdirender.h"
#include <wintab.h>
/* Initialization/Query functions */
static int WIN_VideoInit(_THIS);
static void WIN_VideoQuit(_THIS);
int total_mice = 0; /* total mouse count */
HANDLE *mice = NULL; /* the handles to the detected mice */
HCTX *g_hCtx = NULL; /* handles to tablet contexts */
int tablet = -1; /* we're assuming that there is no tablet */
/* WIN32 driver bootstrap functions */
static int
......@@ -140,8 +147,7 @@ WIN_CreateDevice(int devindex)
}
VideoBootStrap WIN32_bootstrap = {
"win32", "SDL Win32/64 video driver",
WIN_Available, WIN_CreateDevice
"win32", "SDL Win32/64 video driver", WIN_Available, WIN_CreateDevice
};
......@@ -157,6 +163,7 @@ WIN_VideoInit(_THIS)
GDI_AddRenderDriver(_this);
#endif
g_hCtx = SDL_malloc(sizeof(HCTX));
WIN_InitKeyboard(_this);
WIN_InitMouse(_this);
......@@ -169,6 +176,7 @@ WIN_VideoQuit(_THIS)
WIN_QuitModes(_this);
WIN_QuitKeyboard(_this);
WIN_QuitMouse(_this);
SDL_free(g_hCtx);
}
/* vim: set ts=4 sw=4 expandtab: */
......@@ -19,6 +19,14 @@
Sam Lantinga
slouken@libsdl.org
*/
/* we need to define it, so that raw input is included */
#if (_WIN32_WINNT < 0x0501)
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#include "SDL_config.h"
#include "../SDL_sysvideo.h"
......@@ -29,6 +37,15 @@
/* This is included after SDL_win32video.h, which includes windows.h */
#include "SDL_syswm.h"
#include <wintab.h>
/* we're telling wintab that we want to receive movement, button events and pressure information in packets */
#define PACKETDATA ( PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_CURSOR)
#define PACKETMODE 0
#include <pktdef.h>
extern HCTX *g_hCtx; /* the table of tablet event contexts, each windows has to have it's own tablet context */
int highestId = 0; /* the highest id of the tablet context */
static int
SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created)
......@@ -132,6 +149,9 @@ SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created)
int
WIN_CreateWindow(_THIS, SDL_Window * window)
{
RAWINPUTDEVICE Rid;
AXIS TabX, TabY;
LOGCONTEXT lc;
HWND hwnd;
HWND top;
RECT rect;
......@@ -180,13 +200,53 @@ WIN_CreateWindow(_THIS, SDL_Window * window)
hwnd =
CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, NULL, NULL,
SDL_Instance, NULL);
WIN_PumpEvents(_this);
if (!hwnd) {
WIN_SetError("Couldn't create window");
return -1;
}
/* we're configuring the tablet data. See Wintab reference for more info */
if (WTInfo(WTI_DEFSYSCTX, 0, &lc) != 0) {
lc.lcPktData = PACKETDATA;
lc.lcPktMode = PACKETMODE;
lc.lcOptions |= CXO_MESSAGES;
lc.lcOptions |= CXO_SYSTEM;
lc.lcMoveMask = PACKETDATA;
lc.lcBtnDnMask = lc.lcBtnUpMask = PACKETDATA;
WTInfo(WTI_DEVICES, DVC_X, &TabX);
WTInfo(WTI_DEVICES, DVC_Y, &TabY);
lc.lcInOrgX = 0;
lc.lcInOrgY = 0;
lc.lcInExtX = TabX.axMax;
lc.lcInExtY = TabY.axMax;
lc.lcOutOrgX = 0;
lc.lcOutOrgY = 0;
lc.lcOutExtX = GetSystemMetrics(SM_CXSCREEN);
lc.lcOutExtY = -GetSystemMetrics(SM_CYSCREEN);
if (window->id > highestId) {
HCTX *tmp_hctx;
highestId = window->id;
tmp_hctx =
(HCTX *) SDL_realloc(g_hCtx, (highestId + 1) * sizeof(HCTX));
if (!tmp_hctx) {
SDL_OutOfMemory();
DestroyWindow(hwnd);
return -1;
}
g_hCtx = tmp_hctx;
}
g_hCtx[window->id] = WTOpen(hwnd, &lc, TRUE);
}
/* we're telling the window, we want it to report raw input events from mice */
Rid.usUsagePage = 0x01;
Rid.usUsage = 0x02;
Rid.dwFlags = RIDEV_INPUTSINK;
Rid.hwndTarget = hwnd;
RegisterRawInputDevices(&Rid, 1, sizeof(Rid));
WIN_PumpEvents(_this);
if (SetupWindowData(_this, window, hwnd, SDL_TRUE) < 0) {
DestroyWindow(hwnd);
return -1;
......@@ -389,6 +449,7 @@ WIN_DestroyWindow(_THIS, SDL_Window * window)
#endif
ReleaseDC(data->hwnd, data->hdc);
if (data->created) {
WTClose(g_hCtx[window->id]);
DestroyWindow(data->hwnd);
}
SDL_free(data);
......
......@@ -29,7 +29,7 @@
#include <X11/Xatom.h>
#include <X11/Xlibint.h>
#include <X11/Xproto.h>
//#include <X11/extensions/XInput.h>
#include "../Xext/extensions/Xext.h"
#include "../Xext/extensions/extutil.h"
......
......@@ -29,6 +29,12 @@
#include "SDL_x11video.h"
#include "../../events/SDL_events_c.h"
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 */
static void
X11_DispatchEvent(_THIS)
{
......@@ -91,9 +97,10 @@ X11_DispatchEvent(_THIS)
#endif
if ((xevent.xcrossing.mode != NotifyGrab) &&
(xevent.xcrossing.mode != NotifyUngrab)) {
SDL_SetMouseFocus(videodata->mouse, data->windowID);
SDL_SendMouseMotion(videodata->mouse, 0, xevent.xcrossing.x,
xevent.xcrossing.y);
XDeviceMotionEvent *move = (XDeviceMotionEvent *) & xevent;
SDL_SetMouseFocus(move->deviceid, data->windowID);
SDL_SendMouseMotion(move->deviceid, 0, move->x,
move->y, move->axis_data[2]);
}
}
break;
......@@ -111,9 +118,8 @@ X11_DispatchEvent(_THIS)
if ((xevent.xcrossing.mode != NotifyGrab) &&
(xevent.xcrossing.mode != NotifyUngrab) &&
(xevent.xcrossing.detail != NotifyInferior)) {
SDL_SendMouseMotion(videodata->mouse, 0,
xevent.xcrossing.x, xevent.xcrossing.y);
SDL_SetMouseFocus(videodata->mouse, 0);
XDeviceMotionEvent *move = (XDeviceMotionEvent *) & xevent;
SDL_SetMouseFocus(move->deviceid, 0);
}
}
break;
......@@ -166,30 +172,6 @@ X11_DispatchEvent(_THIS)
}
break;
/* Mouse motion? */
case MotionNotify:{
#ifdef DEBUG_MOTION
printf("X11 motion: %d,%d\n", xevent.xmotion.x, xevent.xmotion.y);
#endif
SDL_SendMouseMotion(videodata->mouse, 0, xevent.xmotion.x,
xevent.xmotion.y);
}
break;
/* Mouse button press? */
case ButtonPress:{
SDL_SendMouseButton(videodata->mouse, SDL_PRESSED,
xevent.xbutton.button);
}
break;
/* Mouse button release? */
case ButtonRelease:{
SDL_SendMouseButton(videodata->mouse, SDL_RELEASED,
xevent.xbutton.button);
}
break;
/* Key press? */
case KeyPress:{
KeyCode keycode = xevent.xkey.keycode;
......@@ -301,8 +283,44 @@ X11_DispatchEvent(_THIS)
break;
default:{
if (xevent.type == motion) { /* MotionNotify */
#ifdef DEBUG_MOTION
printf("X11 motion: %d,%d\n", xevent.xmotion.x,
xevent.xmotion.y);
#endif
XWindowAttributes attrib;
XGetWindowAttributes(videodata->display,
((XAnyEvent *) & xevent)->window,
&attrib);
SDL_UpdateCoordinates(attrib.width, attrib.height);
XDeviceMotionEvent *move = (XDeviceMotionEvent *) & xevent;
SDL_SendMouseMotion(move->deviceid, 0, move->x,
move->y, move->axis_data[2]);
} else if (xevent.type == button_pressed) { /* ButtonPress */
XDeviceButtonPressedEvent *pressed =
(XDeviceButtonPressedEvent *) & xevent;
SDL_SendMouseButton(pressed->deviceid, SDL_PRESSED,
pressed->button);
} else if (xevent.type == button_released) { /* ButtonRelease */
XDeviceButtonReleasedEvent *released =
(XDeviceButtonReleasedEvent *) & xevent;
SDL_SendMouseButton(released->deviceid, SDL_RELEASED,
released->button);
} else if (xevent.type == proximity_in) {
XProximityNotifyEvent *proximity =
(XProximityNotifyEvent *) & xevent;
SDL_SendProximity(proximity->deviceid, proximity->x,
proximity->y, SDL_PROXIMITYIN);
} else if (xevent.type == proximity_out) {
XProximityNotifyEvent *proximity =
(XProximityNotifyEvent *) & xevent;
SDL_SendProximity(proximity->deviceid, proximity->x,
proximity->y, SDL_PROXIMITYOUT);
}
#ifdef DEBUG_XEVENTS
else {
printf("Unhandled event %d\n", xevent.type);
}
#endif
}
break;
......
......@@ -28,11 +28,70 @@
void
X11_InitMouse(_THIS)
{
extern XDevice **SDL_XDevices;
XDevice **newDevices;
int i, j, index = 0, numOfDevices;
extern int SDL_NumOfXDevices;
XDeviceInfo *DevList;
XAnyClassPtr deviceClass;
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
/* we're getting the list of input devices */
DevList = XListInputDevices(data->display, &numOfDevices);
SDL_XDevices = (XDevice **) SDL_malloc(sizeof(XDevice));
/* we're aquiring valuators:mices, tablets, etc. */
for (i = 0; i < numOfDevices; ++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 */
deviceClass = DevList[i].inputclassinfo;
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;
}
SDL_XDevices = newDevices;
SDL_XDevices[index] =
XOpenDevice(data->display, DevList[i].id);
SDL_zero(mouse);
data->mouse = SDL_AddMouse(&mouse, -1);
/* 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,
valInfo->axes[2].max_value,
valInfo->axes[2].min_value, 1);
} else {
data->mouse =
SDL_AddMouse(&mouse, index++, DevList[i].name, 0,
0, 1);
}
break;
}
/* if it's not class we're interested in, lets go further */
deviceClass =
(XAnyClassPtr) ((char *) deviceClass +
deviceClass->length);
}
}
}
XFreeDeviceList(DevList);
SDL_NumOfXDevices = index;
}
void
......@@ -40,7 +99,8 @@ X11_QuitMouse(_THIS)
{
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
SDL_DelMouse(data->mouse);
/* let's delete all of the mice */
SDL_MouseQuit();
}
/* vi: set ts=4 sw=4 expandtab: */
......@@ -144,6 +144,11 @@ SDL_X11_SYM(SDL_X11_XESetWireToEventRetType,XESetWireToEvent,(Display* a,int b,S
SDL_X11_SYM(SDL_X11_XESetEventToWireRetType,XESetEventToWire,(Display* a,int b,SDL_X11_XESetEventToWireRetType c),(a,b,c),return)
SDL_X11_SYM(XExtensionErrorHandler,XSetExtensionErrorHandler,(XExtensionErrorHandler a),(a),return)
/*SDL_X11_SYM(XDeviceInfo* , XListInputDevices, (Display* a, int* b), (a,b),return)
SDL_X11_SYM(void, XFreeDeviceList, (XDeviceInfo* a), (a),)
SDL_X11_SYM(int, XSelectExtensionEvent,(Display* a, Window b, XEventClass* c, int d),(a,b,c,d),return)
SDL_X11_SYM(XDevice* ,XOpenDevice,(Display* a, XID b), (a,b),return)*/
#if NeedWidePrototypes
SDL_X11_SYM(KeySym,XKeycodeToKeysym,(Display* a,unsigned int b,int c),(a,b,c),return)
#else
......
......@@ -27,8 +27,14 @@
#include "../SDL_pixels_c.h"
#include "SDL_x11video.h"
//#include "SDL_d3drender.h"
//#include "SDL_gdirender.h"
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;
/* Initialization/Query functions */
static int X11_VideoInit(_THIS);
......@@ -97,7 +103,6 @@ static void
X11_DeleteDevice(SDL_VideoDevice * device)
{
SDL_VideoData *data = (SDL_VideoData *) device->driverdata;
if (data->display) {
XCloseDisplay(data->display);
}
......@@ -212,6 +217,8 @@ 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 */
......@@ -241,6 +248,42 @@ X11_VideoInit(_THIS)
}
X11_InitMouse(_this);
/* 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;
return 0;
}
......@@ -263,6 +306,7 @@ X11_VideoQuit(_THIS)
X11_QuitModes(_this);
X11_QuitKeyboard(_this);
X11_QuitMouse(_this);
free(SDL_XDevices);
}
/* vim: set ts=4 sw=4 expandtab: */
......@@ -29,6 +29,7 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/extensions/XInput.h>
#if SDL_VIDEO_DRIVER_X11_XINERAMA
#include "../Xext/extensions/Xinerama.h"
......@@ -68,7 +69,7 @@ typedef struct SDL_VideoData
int numwindows;
SDL_WindowData **windowlist;
int windowlistlength;
int mouse;
int *mouse;
int keyboard;
Atom WM_DELETE_WINDOW;
SDL_scancode key_layout[256];
......
......@@ -153,6 +153,8 @@ 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
......@@ -481,6 +483,7 @@ X11_CreateWindow(_THIS, SDL_Window * window)
Uint32 fevent = 0;
pXGetICValues(((SDL_WindowData *) window->driverdata)->ic,
XNFilterEvents, &fevent, NULL);
XMapWindow(data->display, w);
XSelectInput(data->display, w,
(FocusChangeMask | EnterWindowMask | LeaveWindowMask |
ExposureMask | ButtonPressMask | ButtonReleaseMask |
......@@ -489,6 +492,7 @@ X11_CreateWindow(_THIS, SDL_Window * window)
KeymapStateMask | fevent));
}
#else
XMapWindow(data->display, w);
XSelectInput(data->display, w,
(FocusChangeMask | EnterWindowMask | LeaveWindowMask |
ExposureMask | ButtonPressMask | ButtonReleaseMask |
......@@ -497,6 +501,9 @@ X11_CreateWindow(_THIS, SDL_Window * window)
KeymapStateMask));
#endif
/* we're informing the display what extension events we want to receive from it */
XSelectExtensionEvent(data->display, w, SDL_XEvents, SDL_NumOfXEvents);
return 0;
}
......
......@@ -273,7 +273,7 @@ MoveSprite(SDL_Surface * screen, SDL_Surface * light)
if (light != NULL) {
int x, y;
SDL_GetMouseState(&x, &y);
SDL_GetMouseState(0, &x, &y);
FlashLight(screen, light, x, y);
}
......
......@@ -270,7 +270,7 @@ DrawLogoCursor(void)
}
/* Move the image around */
SDL_GetMouseState(&x, &y);
SDL_GetMouseState(0, &x, &y);
x -= w / 2;
y -= h / 2;
......
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