From 7d21322df1fdf1ea9deaec4cdf3250fa3d736177 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 8 Nov 2021 16:29:19 -0800 Subject: [PATCH] Implemented SDL_SetWindowMouseRect() on Windows --- src/video/SDL_sysvideo.h | 2 +- src/video/windows/SDL_windowsvideo.c | 1 + src/video/windows/SDL_windowswindow.c | 42 ++++++++++++++++++++++++--- src/video/windows/SDL_windowswindow.h | 2 ++ src/video/x11/SDL_x11window.c | 6 ---- 5 files changed, 42 insertions(+), 11 deletions(-) diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 2098053af5..ae29dd3fc0 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -235,6 +235,7 @@ struct SDL_VideoDevice int (*SetWindowGammaRamp) (_THIS, SDL_Window * window, const Uint16 * ramp); int (*GetWindowGammaRamp) (_THIS, SDL_Window * window, Uint16 * ramp); void* (*GetWindowICCProfile) (_THIS, SDL_Window * window, size_t* size); + int (*SetWindowMouseRect)(_THIS, SDL_Window * window, const SDL_Rect * rect); void (*SetWindowMouseGrab) (_THIS, SDL_Window * window, SDL_bool grabbed); void (*SetWindowKeyboardGrab) (_THIS, SDL_Window * window, SDL_bool grabbed); void (*DestroyWindow) (_THIS, SDL_Window * window); @@ -243,7 +244,6 @@ struct SDL_VideoDevice void (*DestroyWindowFramebuffer) (_THIS, SDL_Window * window); void (*OnWindowEnter) (_THIS, SDL_Window * window); int (*FlashWindow) (_THIS, SDL_Window * window, SDL_FlashOperation operation); - int (*SetWindowMouseRect)(_THIS, SDL_Window * window, const SDL_Rect * rect); /* * * */ /* diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c index 2968e91e3a..27869c0301 100644 --- a/src/video/windows/SDL_windowsvideo.c +++ b/src/video/windows/SDL_windowsvideo.c @@ -167,6 +167,7 @@ WIN_CreateDevice(int devindex) device->SetWindowGammaRamp = WIN_SetWindowGammaRamp; device->GetWindowICCProfile = WIN_GetWindowICCProfile; device->GetWindowGammaRamp = WIN_GetWindowGammaRamp; + device->SetWindowMouseRect = WIN_SetWindowMouseRect; device->SetWindowMouseGrab = WIN_SetWindowMouseGrab; device->SetWindowKeyboardGrab = WIN_SetWindowKeyboardGrab; device->DestroyWindow = WIN_DestroyWindow; diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index 892dde7b15..52159133c1 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -814,6 +814,19 @@ void WIN_UngrabKeyboard(SDL_Window *window) } } +void +WIN_SetWindowMouseRect(_THIS, SDL_Window * window, SDL_Rect * rect) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + + if (rect) { + SDL_memcpy(&data->mouse_rect, rect, sizeof(*rect)); + } else { + SDL_zero(data->mouse_rect); + } + WIN_UpdateClipCursor(window); +} + void WIN_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed) { @@ -998,7 +1011,8 @@ WIN_UpdateClipCursor(SDL_Window *window) return; } - if ((mouse->relative_mode || (window->flags & SDL_WINDOW_MOUSE_GRABBED)) && + if ((mouse->relative_mode || (window->flags & SDL_WINDOW_MOUSE_GRABBED) || + (data->mouse_rect.w > 0 && data->mouse_rect.h > 0)) && (window->flags & SDL_WINDOW_INPUT_FOCUS)) { if (mouse->relative_mode && !mouse->relative_mode_warp) { if (GetWindowRect(data->hwnd, &rect)) { @@ -1020,12 +1034,32 @@ WIN_UpdateClipCursor(SDL_Window *window) } } } else { - if (GetClientRect(data->hwnd, &rect) && !IsRectEmpty(&rect)) { + if (GetClientRect(data->hwnd, &rect)) { ClientToScreen(data->hwnd, (LPPOINT) & rect); ClientToScreen(data->hwnd, (LPPOINT) & rect + 1); + if (data->mouse_rect.w > 0 && data->mouse_rect.h > 0) { + RECT mouse_rect, intersection; + + mouse_rect.left = rect.left + data->mouse_rect.x; + mouse_rect.top = rect.top + data->mouse_rect.y; + mouse_rect.right = mouse_rect.left + data->mouse_rect.w - 1; + mouse_rect.bottom = mouse_rect.top + data->mouse_rect.h - 1; + if (IntersectRect(&intersection, &rect, &mouse_rect)) { + SDL_memcpy(&rect, &intersection, sizeof(rect)); + } else if ((window->flags & SDL_WINDOW_MOUSE_GRABBED) != 0) { + /* Mouse rect was invalid, just do the normal grab */ + } else { + SDL_zero(rect); + } + } if (SDL_memcmp(&rect, &clipped_rect, sizeof(rect)) != 0) { - if (ClipCursor(&rect)) { - data->cursor_clipped_rect = rect; + if (!IsRectEmpty(&rect)) { + if (ClipCursor(&rect)) { + data->cursor_clipped_rect = rect; + } + } else { + ClipCursor(NULL); + SDL_zero(data->cursor_clipped_rect); } } } diff --git a/src/video/windows/SDL_windowswindow.h b/src/video/windows/SDL_windowswindow.h index 66a57546ca..c292b826b1 100644 --- a/src/video/windows/SDL_windowswindow.h +++ b/src/video/windows/SDL_windowswindow.h @@ -51,6 +51,7 @@ typedef struct Uint32 last_updated_clipcursor; SDL_bool windowed_mode_was_maximized; SDL_bool in_window_deactivation; + SDL_Rect mouse_rect; RECT cursor_clipped_rect; SDL_Point last_raw_mouse_position; SDL_bool mouse_tracked; @@ -81,6 +82,7 @@ extern void WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay extern int WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); extern void* WIN_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size); extern int WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); +extern void WIN_SetWindowMouseRect(_THIS, SDL_Window * window, SDL_Rect * rect); extern void WIN_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void WIN_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void WIN_DestroyWindow(_THIS, SDL_Window * window); diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index 9cf88fb593..def7ae9b11 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -331,12 +331,6 @@ SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created) } } -#if SDL_VIDEO_DRIVER_X11_XFIXES - data->pointer_barrier_active = SDL_FALSE; - SDL_memset(&data->barrier, 0, sizeof(data->barrier)); - SDL_memset(&data->barrier_rect, 0, sizeof(SDL_Rect)); -#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ - /* All done! */ window->driverdata = data; return 0;