From 314ff74c6d2d409c7d4adaa129ae588286c5bd3b Mon Sep 17 00:00:00 2001 From: Szymon Wilczek Date: Fri, 6 Jun 2008 15:23:29 +0000 Subject: [PATCH] http://wilku.ravenlord.ws/doku.php?id=documentation for information how things work. Currently implemented: detecting many pointing devices and pressure detection. Still a bug. Each program has to be comipled with a flag -lXi --- configure.in | 2 +- include/SDL_events.h | 1 + include/SDL_keysym.h | 2 +- include/SDL_mouse.h | 5 +++ src/events/SDL_mouse.c | 82 ++++++++++++++++++++++++++++++----- src/events/SDL_mouse_c.h | 17 +++++++- src/video/x11/SDL_x11dyn.h | 2 +- src/video/x11/SDL_x11events.c | 41 +++++++++++------- src/video/x11/SDL_x11mouse.c | 42 ++++++++++++++++-- src/video/x11/SDL_x11sym.h | 5 +++ src/video/x11/SDL_x11video.c | 78 ++++++++++++++++++++++++++++++++- src/video/x11/SDL_x11video.h | 3 +- src/video/x11/SDL_x11window.c | 6 +++ 13 files changed, 247 insertions(+), 39 deletions(-) diff --git a/configure.in b/configure.in index 8cfa63c98..33f9b1b42 100644 --- a/configure.in +++ b/configure.in @@ -1055,7 +1055,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 diff --git a/include/SDL_events.h b/include/SDL_events.h index d26cf09d3..5792cd569 100644 --- a/include/SDL_events.h +++ b/include/SDL_events.h @@ -170,6 +170,7 @@ 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; 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 */ diff --git a/include/SDL_keysym.h b/include/SDL_keysym.h index 60fdea860..63174ac6f 100644 --- a/include/SDL_keysym.h +++ b/include/SDL_keysym.h @@ -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) }; /** diff --git a/include/SDL_mouse.h b/include/SDL_mouse.h index 567abccda..b777717ef 100644 --- a/include/SDL_mouse.h +++ b/include/SDL_mouse.h @@ -203,6 +203,11 @@ extern DECLSPEC int SDLCALL SDL_ShowCursor(int toggle); Button 2: Middle mouse button Button 3: Right mouse button */ + +extern DECLSPEC int SDLCALL SDL_GetNumOfMice(void); + +extern DECLSPEC char* SDLCALL SDL_GetMouseName(int index); + #define SDL_BUTTON(X) (1 << ((X)-1)) #define SDL_BUTTON_LEFT 1 #define SDL_BUTTON_MIDDLE 2 diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index b2579dc0f..05acacf3e 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -31,6 +31,8 @@ static int SDL_num_mice; static int SDL_current_mouse; static SDL_Mouse **SDL_mice; +int *SDL_IdIndex; +int SDL_highestId; /* Public functions */ @@ -50,11 +52,11 @@ SDL_GetMouse(int index) } int -SDL_AddMouse(const SDL_Mouse * mouse, int index) +SDL_AddMouse(const SDL_Mouse * mouse, int index, char* name) { SDL_Mouse **mice; int selected_mouse; - + char* temp_name; /* Add the mouse to the list of mice */ if (index < 0 || index >= SDL_num_mice || SDL_mice[index]) { mice = @@ -74,8 +76,8 @@ SDL_AddMouse(const SDL_Mouse * mouse, int index) return -1; } *SDL_mice[index] = *mouse; - - /* Create the default cursor for the mouse */ + SDL_mice[index]->name=SDL_malloc(strlen(name)*sizeof(char)); + strcpy(SDL_mice[index]->name,name); SDL_mice[index]->cursor_shown = SDL_TRUE; selected_mouse = SDL_SelectMouse(index); SDL_mice[index]->cur_cursor = NULL; @@ -98,6 +100,7 @@ SDL_DelMouse(int index) } mouse->def_cursor = NULL; + SDL_free(mouse->name); while (mouse->cursors) { SDL_FreeCursor(mouse->cursors); } @@ -266,8 +269,9 @@ SDL_GetRelativeMouseState(int *x, int *y) } void -SDL_SetMouseFocus(int index, SDL_WindowID windowID) +SDL_SetMouseFocus(int id, SDL_WindowID windowID) { + int index = SDL_GetIndexById(id); SDL_Mouse *mouse = SDL_GetMouse(index); int i; SDL_bool focus; @@ -315,8 +319,9 @@ SDL_SetMouseFocus(int index, SDL_WindowID windowID) } int -SDL_SendMouseMotion(int index, int relative, int x, int y) +SDL_SendMouseMotion(int id, int relative, int x, int y,int z) { + int index=SDL_GetIndexById(id); SDL_Mouse *mouse = SDL_GetMouse(index); int posted; int xrel; @@ -352,6 +357,7 @@ SDL_SendMouseMotion(int index, int relative, int x, int y) } mouse->xdelta += xrel; mouse->ydelta += yrel; + mouse->z=z; /* Move the mouse cursor, if needed */ if (mouse->cursor_shown && !mouse->relative_mode && @@ -368,6 +374,7 @@ SDL_SendMouseMotion(int index, int relative, int x, int y) event.motion.state = mouse->buttonstate; event.motion.x = mouse->x; event.motion.y = mouse->y; + event.motion.z = mouse->z; event.motion.xrel = xrel; event.motion.yrel = yrel; event.motion.windowID = mouse->focus; @@ -377,8 +384,9 @@ SDL_SendMouseMotion(int index, int relative, int x, int y) } int -SDL_SendMouseButton(int index, Uint8 state, Uint8 button) +SDL_SendMouseButton(int id, Uint8 state, Uint8 button) { + int index=SDL_GetIndexById(id); SDL_Mouse *mouse = SDL_GetMouse(index); int posted; Uint8 type; @@ -398,10 +406,10 @@ SDL_SendMouseButton(int index, Uint8 state, Uint8 button) mouse->buttonstate |= SDL_BUTTON(button); break; case SDL_RELEASED: - if (!(mouse->buttonstate & SDL_BUTTON(button))) { - /* Ignore this event, no state change */ - return 0; - } + //if (!(mouse->buttonstate & SDL_BUTTON(button))) { + // /* Ignore this event, no state change */ + // return 0; + //}*/ type = SDL_MOUSEBUTTONUP; mouse->buttonstate &= ~SDL_BUTTON(button); break; @@ -463,7 +471,7 @@ SDL_WarpMouseInWindow(SDL_WindowID windowID, int x, int y) mouse->WarpMouse(mouse, windowID, x, y); } else { SDL_SetMouseFocus(SDL_current_mouse, windowID); - SDL_SendMouseMotion(SDL_current_mouse, 0, x, y); + SDL_SendMouseMotion(SDL_current_mouse, 0, x, y,0); } } @@ -649,4 +657,54 @@ SDL_ShowCursor(int toggle) return shown; } +void SDL_SetIndexId(int id, int index) +{ + if(id>SDL_highestId) + { + int *indexes; + indexes = + (int*) SDL_realloc(SDL_IdIndex, + (id + 1) * sizeof(int)); + if (!indexes) { + SDL_OutOfMemory(); + return -1; + } + SDL_IdIndex=indexes; + SDL_IdIndex[id]=index; + SDL_highestId=id; + } + else + { + SDL_IdIndex[id]=index; + } +} + +int SDL_GetIndexById(int id) +{ + if(id>SDL_highestId) + { + return -1; + } + else + { + return SDL_IdIndex[id]; + } +} + +int SDL_GetNumOfMice(void) +{ + return SDL_num_mice; +} + +char* SDL_GetMouseName(int index) +{ + SDL_Mouse* mouse = SDL_GetMouse(index); + if(!mouse) + { + return NULL; + } + return mouse->name; +} + + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/events/SDL_mouse_c.h b/src/events/SDL_mouse_c.h index 530e38106..3346bf52b 100644 --- a/src/events/SDL_mouse_c.h +++ b/src/events/SDL_mouse_c.h @@ -58,10 +58,13 @@ struct SDL_Mouse /* Data common to all mice */ SDL_WindowID focus; + int which; int x; int y; + int z; int xdelta; int ydelta; + char* name; Uint8 buttonstate; SDL_bool relative_mode; SDL_bool flush_motion; @@ -84,7 +87,7 @@ 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); +extern int SDL_AddMouse(const SDL_Mouse * mouse, int index, char* name); /* Remove a mouse at an index, clearing the slot for later */ extern void SDL_DelMouse(int index); @@ -96,7 +99,7 @@ extern void SDL_ResetMouse(int index); extern void SDL_SetMouseFocus(int index, 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 index, 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); @@ -107,6 +110,16 @@ extern int SDL_SendMouseWheel(int index, int x, int y); /* Shutdown the mouse subsystem */ extern void SDL_MouseQuit(void); +extern int SDL_GetIndexById(int id); + +extern void SDL_SetIndexId(int id, int index); + +extern int SDL_GetNumOfMice(void); + +extern char* SDL_GetMouseName(int index); + + + #endif /* _SDL_mouse_c_h */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/x11/SDL_x11dyn.h b/src/video/x11/SDL_x11dyn.h index fc99073d0..4078a0a0a 100644 --- a/src/video/x11/SDL_x11dyn.h +++ b/src/video/x11/SDL_x11dyn.h @@ -29,7 +29,7 @@ #include #include #include - +//#include #include "../Xext/extensions/Xext.h" #include "../Xext/extensions/extutil.h" diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index 382c9373d..4e31c7bfa 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -29,13 +29,16 @@ #include "SDL_x11video.h" #include "../../events/SDL_events_c.h" +//XEventClass *SDL_XEvents; +//int SDL_numOfEvents; + static void X11_DispatchEvent(_THIS) { SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; SDL_WindowData *data; XEvent xevent; - int i; + int i,z; SDL_zero(xevent); /* valgrind fix. --ryan. */ XNextEvent(videodata->display, &xevent); @@ -91,9 +94,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 +115,10 @@ 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_SendMouseMotion(move->deviceid, 0, + move->x, move->y,move->axis_data[2]); + SDL_SetMouseFocus(move->deviceid, 0); } } break; @@ -167,26 +172,30 @@ X11_DispatchEvent(_THIS) break; /* Mouse motion? */ - case MotionNotify:{ + case 103:{ //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); + XDeviceMotionEvent* move=(XDeviceMotionEvent*)&xevent; + SDL_SendMouseMotion(move->deviceid, 0, move->x, + move->y,move->axis_data[2]); } break; + /*case MotionNotify:{ /* Mouse button press? */ - case ButtonPress:{ - SDL_SendMouseButton(videodata->mouse, SDL_PRESSED, - xevent.xbutton.button); + case 101:{//ButtonPress + XDeviceButtonPressedEvent* pressed=(XDeviceButtonPressedEvent*)&xevent; + SDL_SendMouseButton(pressed->deviceid, SDL_PRESSED, + pressed->button); } break; /* Mouse button release? */ - case ButtonRelease:{ - SDL_SendMouseButton(videodata->mouse, SDL_RELEASED, - xevent.xbutton.button); + case 102:{//ButtonRelease + XDeviceButtonReleasedEvent* released=(XDeviceButtonReleasedEvent*)&xevent; + SDL_SendMouseButton(released->deviceid, SDL_RELEASED, + released->button); } break; diff --git a/src/video/x11/SDL_x11mouse.c b/src/video/x11/SDL_x11mouse.c index e5ad6c969..c20bc04d3 100644 --- a/src/video/x11/SDL_x11mouse.c +++ b/src/video/x11/SDL_x11mouse.c @@ -28,11 +28,45 @@ 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; - SDL_Mouse mouse; + + DevList=XListInputDevices(data->display, &numOfDevices); - SDL_zero(mouse); - data->mouse = SDL_AddMouse(&mouse, -1); + for(i=0;iclass==ValuatorClass) + { + newDevices= (XDevice**) SDL_realloc(SDL_XDevices, (index+1)*sizeof(*newDevices)); + if(!newDevices) + { + SDL_OutOfMemory(); + return -1; + } + SDL_XDevices=newDevices; + SDL_XDevices[index]=XOpenDevice(data->display,DevList[i].id); + SDL_Mouse mouse; + SDL_zero(mouse); + SDL_SetIndexId(DevList[i].id,index); + data->mouse = SDL_AddMouse(&mouse, index++,DevList[i].name); + break; + } + deviceClass=(XAnyClassPtr)((char*)deviceClass + deviceClass->length); + } + } + } + XFreeDeviceList(DevList); + SDL_NumOfXDevices=index; } void @@ -40,7 +74,7 @@ X11_QuitMouse(_THIS) { SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; - SDL_DelMouse(data->mouse); + SDL_MouseQuit(); } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/x11/SDL_x11sym.h b/src/video/x11/SDL_x11sym.h index be881ab18..6004e6cc6 100644 --- a/src/video/x11/SDL_x11sym.h +++ b/src/video/x11/SDL_x11sym.h @@ -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 diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index bec97f1a8..90f489f51 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -30,6 +30,11 @@ //#include "SDL_d3drender.h" //#include "SDL_gdirender.h" +XDevice **SDL_XDevices; +int SDL_NumOfXDevices; +XEventClass SDL_XEvents[256]; +int SDL_NumOfXEvents; + /* Initialization/Query functions */ static int X11_VideoInit(_THIS); static void X11_VideoQuit(_THIS); @@ -96,8 +101,8 @@ X11_Available(void) static void X11_DeleteDevice(SDL_VideoDevice * device) { + int i; 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,c_not_needed; + XEventClass xEvent; SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; /* Get the window class name, usually the name of the application */ @@ -240,6 +247,72 @@ X11_VideoInit(_THIS) return -1; } X11_InitMouse(_this); + for(i=0;idriverdata; if (data->classname) { @@ -263,6 +338,7 @@ X11_VideoQuit(_THIS) X11_QuitModes(_this); X11_QuitKeyboard(_this); X11_QuitMouse(_this); + free(SDL_XDevices); } /* vim: set ts=4 sw=4 expandtab: */ diff --git a/src/video/x11/SDL_x11video.h b/src/video/x11/SDL_x11video.h index bbc6a1205..6526f707c 100644 --- a/src/video/x11/SDL_x11video.h +++ b/src/video/x11/SDL_x11video.h @@ -29,6 +29,7 @@ #include #include #include +#include #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]; diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index 9de82581c..10c19c71f 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -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,20 +483,24 @@ 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 | PointerMotionMask | KeyPressMask | KeyReleaseMask | PropertyChangeMask | StructureNotifyMask | KeymapStateMask | fevent)); + XSelectExtensionEvent(data->display, w, SDL_XEvents, SDL_NumOfXEvents); } #else + XMapWindow(data->display,w); XSelectInput(data->display, w, (FocusChangeMask | EnterWindowMask | LeaveWindowMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask | KeyReleaseMask | PropertyChangeMask | StructureNotifyMask | KeymapStateMask)); + XSelectExtensionEvent(data->display, w, SDL_XEvents, SDL_NumOfXEvents); #endif return 0;