mirror of
				https://github.com/Ryujinx/SDL.git
				synced 2025-11-04 14:14:49 +00:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									14e007772a
								
							
						
					
					
						commit
						8875a4014f
					
				| 
						 | 
				
			
			@ -366,39 +366,52 @@ X11_CaptureMouse(SDL_Window *window)
 | 
			
		|||
static Uint32
 | 
			
		||||
X11_GetGlobalMouseState(int *x, int *y)
 | 
			
		||||
{
 | 
			
		||||
    SDL_VideoData *videodata = (SDL_VideoData *) SDL_GetVideoDevice()->driverdata;
 | 
			
		||||
    Display *display = GetDisplay();
 | 
			
		||||
    const int num_screens = SDL_GetNumVideoDisplays();
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    /* !!! FIXME: should we XSync() here first? */
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < num_screens; i++) {
 | 
			
		||||
        SDL_DisplayData *data = (SDL_DisplayData *) SDL_GetDisplayDriverData(i);
 | 
			
		||||
        if (data != NULL) {
 | 
			
		||||
            Window root, child;
 | 
			
		||||
            int rootx, rooty, winx, winy;
 | 
			
		||||
            unsigned int mask;
 | 
			
		||||
            if (X11_XQueryPointer(display, RootWindow(display, data->screen), &root, &child, &rootx, &rooty, &winx, &winy, &mask)) {
 | 
			
		||||
                XWindowAttributes root_attrs;
 | 
			
		||||
                Uint32 retval = 0;
 | 
			
		||||
                retval |= (mask & Button1Mask) ? SDL_BUTTON_LMASK : 0;
 | 
			
		||||
                retval |= (mask & Button2Mask) ? SDL_BUTTON_MMASK : 0;
 | 
			
		||||
                retval |= (mask & Button3Mask) ? SDL_BUTTON_RMASK : 0;
 | 
			
		||||
                /* 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);
 | 
			
		||||
                *x = root_attrs.x + rootx;
 | 
			
		||||
                *y = root_attrs.y + rooty;
 | 
			
		||||
                return retval;
 | 
			
		||||
#if !SDL_VIDEO_DRIVER_X11_XINPUT2
 | 
			
		||||
    videodata->global_mouse_changed = SDL_TRUE;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* check if we have this cached since XInput last saw the mouse move. */
 | 
			
		||||
    /* !!! FIXME: can we just calculate this from XInput's events? */
 | 
			
		||||
    if (videodata->global_mouse_changed) {
 | 
			
		||||
        for (i = 0; i < num_screens; i++) {
 | 
			
		||||
            SDL_DisplayData *data = (SDL_DisplayData *) SDL_GetDisplayDriverData(i);
 | 
			
		||||
            if (data != NULL) {
 | 
			
		||||
                Window root, child;
 | 
			
		||||
                int rootx, rooty, winx, winy;
 | 
			
		||||
                unsigned int mask;
 | 
			
		||||
                if (X11_XQueryPointer(display, RootWindow(display, data->screen), &root, &child, &rootx, &rooty, &winx, &winy, &mask)) {
 | 
			
		||||
                    XWindowAttributes root_attrs;
 | 
			
		||||
                    Uint32 buttons = 0;
 | 
			
		||||
                    buttons |= (mask & Button1Mask) ? SDL_BUTTON_LMASK : 0;
 | 
			
		||||
                    buttons |= (mask & Button2Mask) ? SDL_BUTTON_MMASK : 0;
 | 
			
		||||
                    buttons |= (mask & Button3Mask) ? SDL_BUTTON_RMASK : 0;
 | 
			
		||||
                    /* 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;
 | 
			
		||||
 | 
			
		||||
    data->global_mouse_changed = SDL_TRUE;
 | 
			
		||||
 | 
			
		||||
    /* FIXME: Do we need this?
 | 
			
		||||
       if ( (SDL_strncmp(X11_XDisplayName(display), ":", 1) == 0) ||
 | 
			
		||||
       (SDL_strncmp(X11_XDisplayName(display), "unix:", 5) == 0) ) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -118,6 +118,10 @@ typedef struct SDL_VideoData
 | 
			
		|||
    SDL_bool selection_waiting;
 | 
			
		||||
 | 
			
		||||
    Uint32 last_mode_change_deadline;
 | 
			
		||||
 | 
			
		||||
    SDL_bool global_mouse_changed;
 | 
			
		||||
    SDL_Point global_mouse_position;
 | 
			
		||||
    Uint32 global_mouse_buttons;
 | 
			
		||||
} SDL_VideoData;
 | 
			
		||||
 | 
			
		||||
extern SDL_bool X11_UseDirectColorVisuals(void);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -118,6 +118,8 @@ X11_InitXinput2(_THIS)
 | 
			
		|||
    eventmask.mask = mask;
 | 
			
		||||
 | 
			
		||||
    XISetMask(mask, XI_RawMotion);
 | 
			
		||||
    XISetMask(mask, XI_RawButtonPress);
 | 
			
		||||
    XISetMask(mask, XI_RawButtonRelease);
 | 
			
		||||
 | 
			
		||||
    if (X11_XISelectEvents(data->display,DefaultRootWindow(data->display),&eventmask,1) != Success) {
 | 
			
		||||
        return;
 | 
			
		||||
| 
						 | 
				
			
			@ -140,6 +142,8 @@ X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie)
 | 
			
		|||
            static Time prev_time = 0;
 | 
			
		||||
            static double prev_rel_coords[2];
 | 
			
		||||
 | 
			
		||||
            videodata->global_mouse_changed = SDL_TRUE;
 | 
			
		||||
 | 
			
		||||
            if (!mouse->relative_mode || mouse->relative_mode_warp) {
 | 
			
		||||
                return 0;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -158,6 +162,12 @@ X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie)
 | 
			
		|||
            return 1;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case XI_RawButtonPress:
 | 
			
		||||
        case XI_RawButtonRelease:
 | 
			
		||||
            videodata->global_mouse_changed = SDL_TRUE;
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
 | 
			
		||||
        case XI_TouchBegin: {
 | 
			
		||||
            const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue