x11: Optimize SDL_GetGlobalMouseState() a little.
Use XInput2 to mark the global mouse state as dirty so we don't have to make a bunch of roundtrips to the X server when nothing has changed.
parent
14e007772a
commit
8875a4014f
|
@ -366,39 +366,52 @@ X11_CaptureMouse(SDL_Window *window)
|
||||||
static Uint32
|
static Uint32
|
||||||
X11_GetGlobalMouseState(int *x, int *y)
|
X11_GetGlobalMouseState(int *x, int *y)
|
||||||
{
|
{
|
||||||
|
SDL_VideoData *videodata = (SDL_VideoData *) SDL_GetVideoDevice()->driverdata;
|
||||||
Display *display = GetDisplay();
|
Display *display = GetDisplay();
|
||||||
const int num_screens = SDL_GetNumVideoDisplays();
|
const int num_screens = SDL_GetNumVideoDisplays();
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* !!! FIXME: should we XSync() here first? */
|
/* !!! FIXME: should we XSync() here first? */
|
||||||
|
|
||||||
for (i = 0; i < num_screens; i++) {
|
#if !SDL_VIDEO_DRIVER_X11_XINPUT2
|
||||||
SDL_DisplayData *data = (SDL_DisplayData *) SDL_GetDisplayDriverData(i);
|
videodata->global_mouse_changed = SDL_TRUE;
|
||||||
if (data != NULL) {
|
#endif
|
||||||
Window root, child;
|
|
||||||
int rootx, rooty, winx, winy;
|
/* check if we have this cached since XInput last saw the mouse move. */
|
||||||
unsigned int mask;
|
/* !!! FIXME: can we just calculate this from XInput's events? */
|
||||||
if (X11_XQueryPointer(display, RootWindow(display, data->screen), &root, &child, &rootx, &rooty, &winx, &winy, &mask)) {
|
if (videodata->global_mouse_changed) {
|
||||||
XWindowAttributes root_attrs;
|
for (i = 0; i < num_screens; i++) {
|
||||||
Uint32 retval = 0;
|
SDL_DisplayData *data = (SDL_DisplayData *) SDL_GetDisplayDriverData(i);
|
||||||
retval |= (mask & Button1Mask) ? SDL_BUTTON_LMASK : 0;
|
if (data != NULL) {
|
||||||
retval |= (mask & Button2Mask) ? SDL_BUTTON_MMASK : 0;
|
Window root, child;
|
||||||
retval |= (mask & Button3Mask) ? SDL_BUTTON_RMASK : 0;
|
int rootx, rooty, winx, winy;
|
||||||
/* SDL_DisplayData->x,y point to screen origin, and adding them to mouse coordinates relative to root window doesn't do the right thing
|
unsigned int mask;
|
||||||
* (observed on dual monitor setup with primary display being the rightmost one - mouse was offset to the right).
|
if (X11_XQueryPointer(display, RootWindow(display, data->screen), &root, &child, &rootx, &rooty, &winx, &winy, &mask)) {
|
||||||
*
|
XWindowAttributes root_attrs;
|
||||||
* Adding root position to root-relative coordinates seems to be a better way to get absolute position. */
|
Uint32 buttons = 0;
|
||||||
X11_XGetWindowAttributes(display, root, &root_attrs);
|
buttons |= (mask & Button1Mask) ? SDL_BUTTON_LMASK : 0;
|
||||||
*x = root_attrs.x + rootx;
|
buttons |= (mask & Button2Mask) ? SDL_BUTTON_MMASK : 0;
|
||||||
*y = root_attrs.y + rooty;
|
buttons |= (mask & Button3Mask) ? SDL_BUTTON_RMASK : 0;
|
||||||
return retval;
|
/* SDL_DisplayData->x,y point to screen origin, and adding them to mouse coordinates relative to root window doesn't do the right thing
|
||||||
|
* (observed on dual monitor setup with primary display being the rightmost one - mouse was offset to the right).
|
||||||
|
*
|
||||||
|
* Adding root position to root-relative coordinates seems to be a better way to get absolute position. */
|
||||||
|
X11_XGetWindowAttributes(display, root, &root_attrs);
|
||||||
|
videodata->global_mouse_position.x = root_attrs.x + rootx;
|
||||||
|
videodata->global_mouse_position.y = root_attrs.y + rooty;
|
||||||
|
videodata->global_mouse_buttons = buttons;
|
||||||
|
videodata->global_mouse_changed = SDL_FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_assert(0 && "The pointer wasn't on any X11 screen?!");
|
SDL_assert(!videodata->global_mouse_changed); /* The pointer wasn't on any X11 screen?! */
|
||||||
|
|
||||||
return 0;
|
*x = videodata->global_mouse_position.x;
|
||||||
|
*y = videodata->global_mouse_position.y;
|
||||||
|
return videodata->global_mouse_buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -175,6 +175,8 @@ X11_CreateDevice(int devindex)
|
||||||
}
|
}
|
||||||
device->driverdata = data;
|
device->driverdata = data;
|
||||||
|
|
||||||
|
data->global_mouse_changed = SDL_TRUE;
|
||||||
|
|
||||||
/* FIXME: Do we need this?
|
/* FIXME: Do we need this?
|
||||||
if ( (SDL_strncmp(X11_XDisplayName(display), ":", 1) == 0) ||
|
if ( (SDL_strncmp(X11_XDisplayName(display), ":", 1) == 0) ||
|
||||||
(SDL_strncmp(X11_XDisplayName(display), "unix:", 5) == 0) ) {
|
(SDL_strncmp(X11_XDisplayName(display), "unix:", 5) == 0) ) {
|
||||||
|
|
|
@ -118,6 +118,10 @@ typedef struct SDL_VideoData
|
||||||
SDL_bool selection_waiting;
|
SDL_bool selection_waiting;
|
||||||
|
|
||||||
Uint32 last_mode_change_deadline;
|
Uint32 last_mode_change_deadline;
|
||||||
|
|
||||||
|
SDL_bool global_mouse_changed;
|
||||||
|
SDL_Point global_mouse_position;
|
||||||
|
Uint32 global_mouse_buttons;
|
||||||
} SDL_VideoData;
|
} SDL_VideoData;
|
||||||
|
|
||||||
extern SDL_bool X11_UseDirectColorVisuals(void);
|
extern SDL_bool X11_UseDirectColorVisuals(void);
|
||||||
|
|
|
@ -118,6 +118,8 @@ X11_InitXinput2(_THIS)
|
||||||
eventmask.mask = mask;
|
eventmask.mask = mask;
|
||||||
|
|
||||||
XISetMask(mask, XI_RawMotion);
|
XISetMask(mask, XI_RawMotion);
|
||||||
|
XISetMask(mask, XI_RawButtonPress);
|
||||||
|
XISetMask(mask, XI_RawButtonRelease);
|
||||||
|
|
||||||
if (X11_XISelectEvents(data->display,DefaultRootWindow(data->display),&eventmask,1) != Success) {
|
if (X11_XISelectEvents(data->display,DefaultRootWindow(data->display),&eventmask,1) != Success) {
|
||||||
return;
|
return;
|
||||||
|
@ -140,6 +142,8 @@ X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie)
|
||||||
static Time prev_time = 0;
|
static Time prev_time = 0;
|
||||||
static double prev_rel_coords[2];
|
static double prev_rel_coords[2];
|
||||||
|
|
||||||
|
videodata->global_mouse_changed = SDL_TRUE;
|
||||||
|
|
||||||
if (!mouse->relative_mode || mouse->relative_mode_warp) {
|
if (!mouse->relative_mode || mouse->relative_mode_warp) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -158,6 +162,12 @@ X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case XI_RawButtonPress:
|
||||||
|
case XI_RawButtonRelease:
|
||||||
|
videodata->global_mouse_changed = SDL_TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
|
#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
|
||||||
case XI_TouchBegin: {
|
case XI_TouchBegin: {
|
||||||
const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data;
|
const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data;
|
||||||
|
|
Loading…
Reference in New Issue