From cefbeb582f4b41f5e4e0eca0ae6d7b652c92e1d1 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 29 Dec 2022 19:31:12 -0800
Subject: [PATCH] Mouse coordinates are floating point
You can get sub-pixel mouse coordinates and motion depending on the platform and display scaling.
Fixes https://github.com/libsdl-org/SDL/issues/2999
---
docs/README-migration.md | 6 +
include/SDL3/SDL_events.h | 30 ++--
include/SDL3/SDL_mouse.h | 10 +-
include/SDL3/SDL_render.h | 14 +-
src/core/haiku/SDL_BApp.h | 4 +-
src/core/linux/SDL_evdev.c | 2 +-
src/core/openbsd/SDL_wscons_mouse.c | 4 +-
src/core/winrt/SDL_winrtapp_direct3d.cpp | 2 +-
src/dynapi/SDL_dynapi_procs.h | 14 +-
src/events/SDL_events.c | 15 +-
src/events/SDL_mouse.c | 179 +++++++-------------
src/events/SDL_mouse_c.h | 26 ++-
src/events/SDL_touch.c | 36 ++--
src/joystick/apple/SDL_mfijoystick.m | 2 +-
src/render/SDL_render.c | 56 +++---
src/render/SDL_sysrender.h | 4 -
src/test/SDL_test_common.c | 23 +--
src/video/SDL_video.c | 4 +-
src/video/android/SDL_androidmouse.c | 6 +-
src/video/cocoa/SDL_cocoamouse.m | 22 +--
src/video/cocoa/SDL_cocoawindow.h | 4 +-
src/video/cocoa/SDL_cocoawindow.m | 56 +++---
src/video/emscripten/SDL_emscriptenevents.c | 22 +--
src/video/emscripten/SDL_emscriptenmouse.c | 6 -
src/video/haiku/SDL_BApp.h | 4 +-
src/video/kmsdrm/SDL_kmsdrmmouse.c | 20 +--
src/video/raspberry/SDL_rpimouse.c | 67 ++------
src/video/riscos/SDL_riscosevents.c | 2 +-
src/video/uikit/SDL_uikitevents.m | 2 +-
src/video/uikit/SDL_uikitview.m | 2 +-
src/video/vita/SDL_vitamouse.c | 2 +-
src/video/wayland/SDL_waylandevents.c | 23 +--
src/video/wayland/SDL_waylandevents_c.h | 3 -
src/video/wayland/SDL_waylandmouse.c | 8 +-
src/video/windows/SDL_windowsevents.c | 29 ++--
src/video/windows/SDL_windowsmodes.c | 62 ++++---
src/video/windows/SDL_windowsmodes.h | 2 +
src/video/windows/SDL_windowsmouse.c | 17 +-
src/video/windows/SDL_windowswindow.c | 28 +++
src/video/windows/SDL_windowswindow.h | 2 +
src/video/winrt/SDL_winrtpointerinput.cpp | 6 +-
src/video/x11/SDL_x11events.c | 6 +-
src/video/x11/SDL_x11mouse.c | 16 +-
src/video/x11/SDL_x11xinput2.c | 4 +-
test/testautomation_mouse.c | 96 ++++++-----
test/testgamepad.c | 54 +++---
test/testgeometry.c | 6 +-
test/testintersections.c | 50 +++---
test/testmouse.c | 23 ++-
test/testoverlay2.c | 16 +-
test/testrelative.c | 13 +-
test/testwm2.c | 20 +--
52 files changed, 520 insertions(+), 610 deletions(-)
diff --git a/docs/README-migration.md b/docs/README-migration.md
index 2f377d34e6f1..56417441b6b4 100644
--- a/docs/README-migration.md
+++ b/docs/README-migration.md
@@ -82,6 +82,8 @@ The timestamp_us member of the sensor events has been renamed sensor_timestamp a
You should set the event.common.timestamp field before passing an event to SDL_PushEvent(). If the timestamp is 0 it will be filled in with SDL_GetTicksNS().
+Mouse events use floating point values for mouse coordinates and relative motion values. You can get sub-pixel motion depending on the platform and display scaling.
+
The SDL_DISPLAYEVENT_* events have been moved to top level events, and SDL_DISPLAYEVENT has been removed. In general, handling this change just means checking for the individual events instead of first checking for SDL_DISPLAYEVENT and then checking for display events. You can compare the event >= SDL_DISPLAYEVENT_FIRST and <= SDL_DISPLAYEVENT_LAST if you need to see whether it's a display event.
The SDL_WINDOWEVENT_* events have been moved to top level events, and SDL_WINDOWEVENT has been removed. In general, handling this change just means checking for the individual events instead of first checking for SDL_WINDOWEVENT and then checking for window events. You can compare the event >= SDL_WINDOWEVENT_FIRST and <= SDL_WINDOWEVENT_LAST if you need to see whether it's a window event.
@@ -411,6 +413,8 @@ used by additional platforms that didn't have a SDL_RunApp-like function before)
SDL_ShowCursor() has been split into three functions: SDL_ShowCursor(), SDL_HideCursor(), and SDL_CursorVisible()
+SDL_GetMouseState(), SDL_GetGlobalMouseState(), SDL_GetRelativeMouseState(), SDL_WarpMouseInWindow(), and SDL_WarpMouseGlobal() all use floating point mouse positions, to provide sub-pixel precision on platforms that support it.
+
The following functions have been renamed:
* SDL_FreeCursor() => SDL_DestroyCursor()
@@ -463,6 +467,8 @@ which index is the "opengl" or whatnot driver, you can just pass that string dir
here, now. Passing NULL is the same as passing -1 here in SDL2, to signify you want SDL
to decide for you.
+SDL_RenderWindowToLogical() and SDL_RenderLogicalToWindow() take floating point coordinates in both directions.
+
The following functions have been renamed:
* SDL_RenderCopy() => SDL_RenderTexture()
* SDL_RenderCopyEx() => SDL_RenderTextureRotated()
diff --git a/include/SDL3/SDL_events.h b/include/SDL3/SDL_events.h
index 6e068ff40c43..736c94e93c6e 100644
--- a/include/SDL3/SDL_events.h
+++ b/include/SDL3/SDL_events.h
@@ -297,12 +297,12 @@ typedef struct SDL_MouseMotionEvent
Uint32 type; /**< ::SDL_MOUSEMOTION */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The window with mouse focus, if any */
- SDL_MouseID which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
+ SDL_MouseID which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
Uint32 state; /**< The current button state */
- Sint32 x; /**< X coordinate, relative to window */
- Sint32 y; /**< Y coordinate, relative to window */
- Sint32 xrel; /**< The relative motion in the X direction */
- Sint32 yrel; /**< The relative motion in the Y direction */
+ float x; /**< X coordinate, relative to window */
+ float y; /**< Y coordinate, relative to window */
+ float xrel; /**< The relative motion in the X direction */
+ float yrel; /**< The relative motion in the Y direction */
} SDL_MouseMotionEvent;
/**
@@ -313,13 +313,13 @@ typedef struct SDL_MouseButtonEvent
Uint32 type; /**< ::SDL_MOUSEBUTTONDOWN or ::SDL_MOUSEBUTTONUP */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The window with mouse focus, if any */
- SDL_MouseID which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
+ SDL_MouseID which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
Uint8 button; /**< The mouse button index */
Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */
Uint8 clicks; /**< 1 for single-click, 2 for double-click, etc. */
- Uint8 padding1;
- Sint32 x; /**< X coordinate, relative to window */
- Sint32 y; /**< Y coordinate, relative to window */
+ Uint8 padding;
+ float x; /**< X coordinate, relative to window */
+ float y; /**< Y coordinate, relative to window */
} SDL_MouseButtonEvent;
/**
@@ -330,14 +330,12 @@ typedef struct SDL_MouseWheelEvent
Uint32 type; /**< ::SDL_MOUSEWHEEL */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The window with mouse focus, if any */
- SDL_MouseID which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
- Sint32 x; /**< The amount scrolled horizontally, positive to the right and negative to the left */
- Sint32 y; /**< The amount scrolled vertically, positive away from the user and negative toward the user */
+ SDL_MouseID which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
+ float x; /**< The amount scrolled horizontally, positive to the right and negative to the left */
+ float y; /**< The amount scrolled vertically, positive away from the user and negative toward the user */
Uint32 direction; /**< Set to one of the SDL_MOUSEWHEEL_* defines. When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back */
- float preciseX; /**< The amount scrolled horizontally, positive to the right and negative to the left, with float precision (added in 2.0.18) */
- float preciseY; /**< The amount scrolled vertically, positive away from the user and negative toward the user, with float precision (added in 2.0.18) */
- Sint32 mouseX; /**< X coordinate, relative to window (added in 2.26.0) */
- Sint32 mouseY; /**< Y coordinate, relative to window (added in 2.26.0) */
+ float mouseX; /**< X coordinate, relative to window */
+ float mouseY; /**< Y coordinate, relative to window */
} SDL_MouseWheelEvent;
/**
diff --git a/include/SDL3/SDL_mouse.h b/include/SDL3/SDL_mouse.h
index ed58a76a77f1..836ef513e88b 100644
--- a/include/SDL3/SDL_mouse.h
+++ b/include/SDL3/SDL_mouse.h
@@ -103,7 +103,7 @@ extern DECLSPEC SDL_Window * SDLCALL SDL_GetMouseFocus(void);
* \sa SDL_GetRelativeMouseState
* \sa SDL_PumpEvents
*/
-extern DECLSPEC Uint32 SDLCALL SDL_GetMouseState(int *x, int *y);
+extern DECLSPEC Uint32 SDLCALL SDL_GetMouseState(float *x, float *y);
/**
* Get the current state of the mouse in relation to the desktop.
@@ -132,7 +132,7 @@ extern DECLSPEC Uint32 SDLCALL SDL_GetMouseState(int *x, int *y);
*
* \sa SDL_CaptureMouse
*/
-extern DECLSPEC Uint32 SDLCALL SDL_GetGlobalMouseState(int *x, int *y);
+extern DECLSPEC Uint32 SDLCALL SDL_GetGlobalMouseState(float *x, float *y);
/**
* Retrieve the relative state of the mouse.
@@ -151,7 +151,7 @@ extern DECLSPEC Uint32 SDLCALL SDL_GetGlobalMouseState(int *x, int *y);
*
* \sa SDL_GetMouseState
*/
-extern DECLSPEC Uint32 SDLCALL SDL_GetRelativeMouseState(int *x, int *y);
+extern DECLSPEC Uint32 SDLCALL SDL_GetRelativeMouseState(float *x, float *y);
/**
* Move the mouse cursor to the given position within the window.
@@ -173,7 +173,7 @@ extern DECLSPEC Uint32 SDLCALL SDL_GetRelativeMouseState(int *x, int *y);
* \sa SDL_WarpMouseGlobal
*/
extern DECLSPEC void SDLCALL SDL_WarpMouseInWindow(SDL_Window * window,
- int x, int y);
+ float x, float y);
/**
* Move the mouse to the given position in global screen space.
@@ -195,7 +195,7 @@ extern DECLSPEC void SDLCALL SDL_WarpMouseInWindow(SDL_Window * window,
*
* \sa SDL_WarpMouseInWindow
*/
-extern DECLSPEC int SDLCALL SDL_WarpMouseGlobal(int x, int y);
+extern DECLSPEC int SDLCALL SDL_WarpMouseGlobal(float x, float y);
/**
* Set relative mouse mode.
diff --git a/include/SDL3/SDL_render.h b/include/SDL3/SDL_render.h
index ef2a9c520fc1..3eda734b1242 100644
--- a/include/SDL3/SDL_render.h
+++ b/include/SDL3/SDL_render.h
@@ -1034,10 +1034,10 @@ extern DECLSPEC void SDLCALL SDL_GetRenderScale(SDL_Renderer * renderer,
* \sa SDL_GetRenderLogicalSize
* \sa SDL_SetRenderLogicalSize
*/
-extern DECLSPEC void SDLCALL SDL_RenderWindowToLogical(SDL_Renderer * renderer,
- int windowX, int windowY,
- float *logicalX, float *logicalY);
-
+extern DECLSPEC void SDLCALL SDL_RenderWindowToLogical(SDL_Renderer *renderer,
+ float windowX, float windowY,
+ float *logicalX, float *logicalY);
+
/**
* Get real coordinates of point in window when given logical coordinates of
@@ -1060,9 +1060,9 @@ extern DECLSPEC void SDLCALL SDL_RenderWindowToLogical(SDL_Renderer * renderer,
* \sa SDL_GetRenderLogicalSize
* \sa SDL_SetRenderLogicalSize
*/
-extern DECLSPEC void SDLCALL SDL_RenderLogicalToWindow(SDL_Renderer * renderer,
- float logicalX, float logicalY,
- int *windowX, int *windowY);
+extern DECLSPEC void SDLCALL SDL_RenderLogicalToWindow(SDL_Renderer *renderer,
+ float logicalX, float logicalY,
+ float *windowX, float *windowY);
/**
* Set the color used for drawing operations (Rect, Line and Clear).
diff --git a/src/core/haiku/SDL_BApp.h b/src/core/haiku/SDL_BApp.h
index fa108a5c4da0..d635c648ec24 100644
--- a/src/core/haiku/SDL_BApp.h
+++ b/src/core/haiku/SDL_BApp.h
@@ -254,12 +254,12 @@ class SDL_BApp : public BApplication
SDL_GetWindowPosition(win, &winPosX, &winPosY);
int dx = x - (winWidth / 2);
int dy = y - (winHeight / 2);
- SDL_SendMouseMotion(0, win, 0, SDL_GetMouse()->relative_mode, dx, dy);
+ SDL_SendMouseMotion(0, win, 0, SDL_GetMouse()->relative_mode, (float)dx, (float)dy);
set_mouse_position((winPosX + winWidth / 2), (winPosY + winHeight / 2));
if (!be_app->IsCursorHidden())
be_app->HideCursor();
} else {
- SDL_SendMouseMotion(0, win, 0, 0, x, y);
+ SDL_SendMouseMotion(0, win, 0, 0, (float)x, (float)y);
if (SDL_CursorVisible() && be_app->IsCursorHidden())
be_app->ShowCursor();
}
diff --git a/src/core/linux/SDL_evdev.c b/src/core/linux/SDL_evdev.c
index 05303604fdfb..df8fcb479839 100644
--- a/src/core/linux/SDL_evdev.c
+++ b/src/core/linux/SDL_evdev.c
@@ -448,7 +448,7 @@ void SDL_EVDEV_Poll(void)
case SYN_REPORT:
/* Send mouse axis changes together to ensure consistency and reduce event processing overhead */
if (item->mouse_x != 0 || item->mouse_y != 0) {
- SDL_SendMouseMotion(SDL_EVDEV_GetEventTimestamp(event), mouse->focus, (SDL_MouseID)item->fd, item->relative_mouse, item->mouse_x, item->mouse_y);
+ SDL_SendMouseMotion(SDL_EVDEV_GetEventTimestamp(event), mouse->focus, (SDL_MouseID)item->fd, item->relative_mouse, (float)item->mouse_x, (float)item->mouse_y);
item->mouse_x = item->mouse_y = 0;
}
if (item->mouse_wheel != 0 || item->mouse_hwheel != 0) {
diff --git a/src/core/openbsd/SDL_wscons_mouse.c b/src/core/openbsd/SDL_wscons_mouse.c
index 58d2ab58b7d0..de3ab8ec8e7a 100644
--- a/src/core/openbsd/SDL_wscons_mouse.c
+++ b/src/core/openbsd/SDL_wscons_mouse.c
@@ -100,12 +100,12 @@ void updateMouse(SDL_WSCONS_mouse_input_data *inputData)
} break;
case WSCONS_EVENT_MOUSE_DELTA_X:
{
- SDL_SendMouseMotion(0, mouse->focus, mouse->mouseID, 1, events[i].value, 0);
+ SDL_SendMouseMotion(0, mouse->focus, mouse->mouseID, 1, (float)events[i].value, 0.0f);
break;
}
case WSCONS_EVENT_MOUSE_DELTA_Y:
{
- SDL_SendMouseMotion(0, mouse->focus, mouse->mouseID, 1, 0, -events[i].value);
+ SDL_SendMouseMotion(0, mouse->focus, mouse->mouseID, 1, 0.0f, -(float)events[i].value);
break;
}
case WSCONS_EVENT_MOUSE_DELTA_W:
diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp
index e70e132ab66f..bed939c48734 100644
--- a/src/core/winrt/SDL_winrtapp_direct3d.cpp
+++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp
@@ -547,7 +547,7 @@ void SDL_WinRTApp::OnWindowActivated(CoreWindow ^ sender, WindowActivatedEventAr
*/
#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION >= NTDDI_WINBLUE)
Point cursorPos = WINRT_TransformCursorPosition(window, sender->PointerPosition, TransformToSDLWindowSize);
- SDL_SendMouseMotion(0, window, 0, 0, (int)cursorPos.X, (int)cursorPos.Y);
+ SDL_SendMouseMotion(0, window, 0, 0, cursorPos.X, cursorPos.Y);
#endif
/* TODO, WinRT: see if the Win32 bugfix from https://hg.libsdl.org/SDL/rev/d278747da408 needs to be applied (on window activation) */
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index be0d18a6bc5c..f4cf4b731170 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -317,7 +317,7 @@ SDL_DYNAPI_PROC(int,SDL_GetGamepadTouchpadFinger,(SDL_Gamepad *a, int b, int c,
SDL_DYNAPI_PROC(SDL_GamepadType,SDL_GetGamepadType,(SDL_Gamepad *a),(a),return)
SDL_DYNAPI_PROC(Uint16,SDL_GetGamepadVendor,(SDL_Gamepad *a),(a),return)
SDL_DYNAPI_PROC(SDL_JoystickID*,SDL_GetGamepads,(int *a),(a),return)
-SDL_DYNAPI_PROC(Uint32,SDL_GetGlobalMouseState,(int *a, int *b),(a,b),return)
+SDL_DYNAPI_PROC(Uint32,SDL_GetGlobalMouseState,(float *a, float *b),(a,b),return)
SDL_DYNAPI_PROC(SDL_Window*,SDL_GetGrabbedWindow,(void),(),return)
SDL_DYNAPI_PROC(const char*,SDL_GetHint,(const char *a),(a),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_GetHintBoolean,(const char *a, SDL_bool b),(a,b),return)
@@ -360,7 +360,7 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_GetMasksForPixelFormatEnum,(Uint32 a, int *b, Uint3
SDL_DYNAPI_PROC(void,SDL_GetMemoryFunctions,(SDL_malloc_func *a, SDL_calloc_func *b, SDL_realloc_func *c, SDL_free_func *d),(a,b,c,d),)
SDL_DYNAPI_PROC(SDL_Keymod,SDL_GetModState,(void),(),return)
SDL_DYNAPI_PROC(SDL_Window*,SDL_GetMouseFocus,(void),(),return)
-SDL_DYNAPI_PROC(Uint32,SDL_GetMouseState,(int *a, int *b),(a,b),return)
+SDL_DYNAPI_PROC(Uint32,SDL_GetMouseState,(float *a, float *b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_GetNumAllocations,(void),(),return)
SDL_DYNAPI_PROC(int,SDL_GetNumAudioDevices,(int a),(a),return)
SDL_DYNAPI_PROC(int,SDL_GetNumAudioDrivers,(void),(),return)
@@ -396,7 +396,7 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_GetRectIntersectionFloat,(const SDL_FRect *a, const
SDL_DYNAPI_PROC(void,SDL_GetRectUnion,(const SDL_Rect *a, const SDL_Rect *b, SDL_Rect *c),(a,b,c),)
SDL_DYNAPI_PROC(void,SDL_GetRectUnionFloat,(const SDL_FRect *a, const SDL_FRect *b, SDL_FRect *c),(a,b,c),)
SDL_DYNAPI_PROC(SDL_bool,SDL_GetRelativeMouseMode,(void),(),return)
-SDL_DYNAPI_PROC(Uint32,SDL_GetRelativeMouseState,(int *a, int *b),(a,b),return)
+SDL_DYNAPI_PROC(Uint32,SDL_GetRelativeMouseState,(float *a, float *b),(a,b),return)
SDL_DYNAPI_PROC(void,SDL_GetRenderClipRect,(SDL_Renderer *a, SDL_Rect *b),(a,b),)
SDL_DYNAPI_PROC(int,SDL_GetRenderDrawBlendMode,(SDL_Renderer *a, SDL_BlendMode *b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_GetRenderDrawColor,(SDL_Renderer *a, Uint8 *b, Uint8 *c, Uint8 *d, Uint8 *e),(a,b,c,d,e),return)
@@ -628,7 +628,7 @@ SDL_DYNAPI_PROC(int,SDL_RenderLine,(SDL_Renderer *a, int b, int c, int d, int e)
SDL_DYNAPI_PROC(int,SDL_RenderLineFloat,(SDL_Renderer *a, float b, float c, float d, float e),(a,b,c,d,e),return)
SDL_DYNAPI_PROC(int,SDL_RenderLines,(SDL_Renderer *a, const SDL_Point *b, int c),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_RenderLinesFloat,(SDL_Renderer *a, const SDL_FPoint *b, int c),(a,b,c),return)
-SDL_DYNAPI_PROC(void,SDL_RenderLogicalToWindow,(SDL_Renderer *a, float b, float c, int *d, int *e),(a,b,c,d,e),)
+SDL_DYNAPI_PROC(void,SDL_RenderLogicalToWindow,(SDL_Renderer *a, float b, float c, float *d, float *e),(a,b,c,d,e),)
SDL_DYNAPI_PROC(int,SDL_RenderPoint,(SDL_Renderer *a, int b, int c),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_RenderPointFloat,(SDL_Renderer *a, float b, float c),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_RenderPoints,(SDL_Renderer *a, const SDL_Point *b, int c),(a,b,c),return)
@@ -644,7 +644,7 @@ SDL_DYNAPI_PROC(int,SDL_RenderTexture,(SDL_Renderer *a, SDL_Texture *b, const SD
SDL_DYNAPI_PROC(int,SDL_RenderTextureFloat,(SDL_Renderer *a, SDL_Texture *b, const SDL_Rect *c, const SDL_FRect *d),(a,b,c,d),return)
SDL_DYNAPI_PROC(int,SDL_RenderTextureRotated,(SDL_Renderer *a, SDL_Texture *b, const SDL_Rect *c, const SDL_Rect *d, const double e, const SDL_Point *f, const SDL_RendererFlip g),(a,b,c,d,e,f,g),return)
SDL_DYNAPI_PROC(int,SDL_RenderTextureRotatedFloat,(SDL_Renderer *a, SDL_Texture *b, const SDL_Rect *c, const SDL_FRect *d, const double e, const SDL_FPoint *f, const SDL_RendererFlip g),(a,b,c,d,e,f,g),return)
-SDL_DYNAPI_PROC(void,SDL_RenderWindowToLogical,(SDL_Renderer *a, int b, int c, float *d, float *e),(a,b,c,d,e),)
+SDL_DYNAPI_PROC(void,SDL_RenderWindowToLogical,(SDL_Renderer *a, float b, float c, float *d, float *e),(a,b,c,d,e),)
SDL_DYNAPI_PROC(SDL_AssertState,SDL_ReportAssertion,(SDL_AssertData *a, const char *b, const char *c, int d),(a,b,c,d),return)
SDL_DYNAPI_PROC(void,SDL_ResetAssertionReport,(void),(),)
SDL_DYNAPI_PROC(SDL_bool,SDL_ResetHint,(const char *a),(a),return)
@@ -781,8 +781,8 @@ SDL_DYNAPI_PROC(void,SDL_Vulkan_UnloadLibrary,(void),(),)
SDL_DYNAPI_PROC(int,SDL_WaitEvent,(SDL_Event *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_WaitEventTimeout,(SDL_Event *a, Sint32 b),(a,b),return)
SDL_DYNAPI_PROC(void,SDL_WaitThread,(SDL_Thread *a, int *b),(a,b),)
-SDL_DYNAPI_PROC(int,SDL_WarpMouseGlobal,(int a, int b),(a,b),return)
-SDL_DYNAPI_PROC(void,SDL_WarpMouseInWindow,(SDL_Window *a, int b, int c),(a,b,c),)
+SDL_DYNAPI_PROC(int,SDL_WarpMouseGlobal,(float a, float b),(a,b),return)
+SDL_DYNAPI_PROC(void,SDL_WarpMouseInWindow,(SDL_Window *a, float b, float c),(a,b,c),)
SDL_DYNAPI_PROC(Uint32,SDL_WasInit,(Uint32 a),(a),return)
SDL_DYNAPI_PROC(size_t,SDL_WriteBE16,(SDL_RWops *a, Uint16 b),(a,b),return)
SDL_DYNAPI_PROC(size_t,SDL_WriteBE32,(SDL_RWops *a, Uint32 b),(a,b),return)
diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c
index 4ca6fd09b4df..7090168171b0 100644
--- a/src/events/SDL_events.c
+++ b/src/events/SDL_events.c
@@ -300,19 +300,19 @@ static void SDL_LogEvent(const SDL_Event *event)
break;
SDL_EVENT_CASE(SDL_MOUSEMOTION)
- (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u state=%u x=%d y=%d xrel=%d yrel=%d)",
+ (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u state=%u x=%g y=%g xrel=%g yrel=%g)",
(uint)event->motion.timestamp, (uint)event->motion.windowID,
(uint)event->motion.which, (uint)event->motion.state,
- (int)event->motion.x, (int)event->motion.y,
- (int)event->motion.xrel, (int)event->motion.yrel);
+ event->motion.x, event->motion.y,
+ event->motion.xrel, event->motion.yrel);
break;
#define PRINT_MBUTTON_EVENT(event) \
- (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u button=%u state=%s clicks=%u x=%d y=%d)", \
+ (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u button=%u state=%s clicks=%u x=%g y=%g)", \
(uint)event->button.timestamp, (uint)event->button.windowID, \
(uint)event->button.which, (uint)event->button.button, \
event->button.state == SDL_PRESSED ? "pressed" : "released", \
- (uint)event->button.clicks, (int)event->button.x, (int)event->button.y)
+ (uint)event->button.clicks, event->button.x, event->button.y)
SDL_EVENT_CASE(SDL_MOUSEBUTTONDOWN)
PRINT_MBUTTON_EVENT(event);
break;
@@ -322,10 +322,9 @@ static void SDL_LogEvent(const SDL_Event *event)
#undef PRINT_MBUTTON_EVENT
SDL_EVENT_CASE(SDL_MOUSEWHEEL)
- (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u x=%d y=%d preciseX=%f preciseY=%f direction=%s)",
+ (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u x=%g y=%g direction=%s)",
(uint)event->wheel.timestamp, (uint)event->wheel.windowID,
- (uint)event->wheel.which, (int)event->wheel.x, (int)event->wheel.y,
- event->wheel.preciseX, event->wheel.preciseY,
+ (uint)event->wheel.which, event->wheel.x, event->wheel.y,
event->wheel.direction == SDL_MOUSEWHEEL_NORMAL ? "normal" : "flipped");
break;
diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c
index b6e47ce96301..247f577a51db 100644
--- a/src/events/SDL_mouse.c
+++ b/src/events/SDL_mouse.c
@@ -37,7 +37,7 @@ static SDL_Mouse SDL_mouse;
/* for mapping mouse events to touch */
static SDL_bool track_mouse_down = SDL_FALSE;
-static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y);
+static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, int relative, float x, float y);
static void SDLCALL SDL_MouseDoubleClickTimeChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
@@ -305,15 +305,13 @@ void SDL_SetMouseFocus(SDL_Window *window)
}
/* Check to see if we need to synthesize focus events */
-static SDL_bool SDL_UpdateMouseFocus(SDL_Window *window, int x, int y, Uint32 buttonstate, SDL_bool send_mouse_motion)
+static SDL_bool SDL_UpdateMouseFocus(SDL_Window *window, float x, float y, Uint32 buttonstate, SDL_bool send_mouse_motion)
{
SDL_Mouse *mouse = SDL_GetMouse();
SDL_bool inWindow = SDL_TRUE;
if (window && ((window->flags & SDL_WINDOW_MOUSE_CAPTURE) == 0)) {
- int w, h;
- SDL_GetWindowSize(window, &w, &h);
- if (x < 0 || y < 0 || x >= w || y >= h) {
+ if (x < 0.0f || y < 0.0f || x >= (float)window->w || y >= (float)window->h) {
inWindow = SDL_FALSE;
}
}
@@ -343,7 +341,7 @@ static SDL_bool SDL_UpdateMouseFocus(SDL_Window *window, int x, int y, Uint32 bu
return SDL_TRUE;
}
-int SDL_SendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
+int SDL_SendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, int relative, float x, float y)
{
if (window && !relative) {
SDL_Mouse *mouse = SDL_GetMouse();
@@ -355,24 +353,7 @@ int SDL_SendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseI
return SDL_PrivateSendMouseMotion(timestamp, window, mouseID, relative, x, y);
}
-static int GetScaledMouseDelta(float scale, int value, float *accum)
-{
- if (value && scale != 1.0f) {
- if ((value > 0) != (*accum > 0)) {
- *accum = 0.0f;
- }
- *accum += scale * value;
- if (*accum >= 0.0f) {
- value = (int)SDL_floor(*accum);
- } else {
- value = (int)SDL_ceil(*accum);
- }
- *accum -= value;
- }
- return value;
-}
-
-static float CalculateSystemScale(SDL_Mouse *mouse, const int *x, const int *y)
+static float CalculateSystemScale(SDL_Mouse *mouse, const float *x, const float *y)
{
int i;
int n = mouse->num_system_scale_values;
@@ -384,7 +365,7 @@ static float CalculateSystemScale(SDL_Mouse *mouse, const int *x, const int *y)
return v[0];
}
- speed = SDL_sqrtf((float)(*x * *x) + (*y * *y));
+ speed = SDL_sqrtf((*x * *x) + (*y * *y));
for (i = 0; i < (n - 2); i += 2) {
if (speed < v[i + 2]) {
break;
@@ -398,7 +379,6 @@ static float CalculateSystemScale(SDL_Mouse *mouse, const int *x, const int *y)
coef = (speed - v[i]) / (v[i + 2] - v[i]);
scale = v[i + 1] + (coef * (v[i + 3] - v[i + 1]));
}
- SDL_Log("speed = %.2f, scale = %.2f\n", speed, scale);
return scale;
}
@@ -444,39 +424,39 @@ int SDL_SetMouseSystemScale(int num_values, const float *values)
return 0;
}
-static void GetScaledMouseDeltas(SDL_Mouse *mouse, int *x, int *y)
+static void GetScaledMouseDeltas(SDL_Mouse *mouse, float *x, float *y)
{
if (mouse->relative_mode) {
if (mouse->enable_relative_speed_scale) {
- *x = GetScaledMouseDelta(mouse->relative_speed_scale, *x, &mouse->scale_accum_x);
- *y = GetScaledMouseDelta(mouse->relative_speed_scale, *y, &mouse->scale_accum_y);
+ *x *= mouse->relative_speed_scale;
+ *y *= mouse->relative_speed_scale;
} else if (mouse->enable_relative_system_scale && mouse->num_system_scale_values > 0) {
float relative_system_scale = CalculateSystemScale(mouse, x, y);
- *x = GetScaledMouseDelta(relative_system_scale, *x, &mouse->scale_accum_x);
- *y = GetScaledMouseDelta(relative_system_scale, *y, &mouse->scale_accum_y);
+ *x *= relative_system_scale;
+ *y *= relative_system_scale;
}
} else {
if (mouse->enable_normal_speed_scale) {
- *x = GetScaledMouseDelta(mouse->normal_speed_scale, *x, &mouse->scale_accum_x);
- *y = GetScaledMouseDelta(mouse->normal_speed_scale, *y, &mouse->scale_accum_y);
+ *x *= mouse->normal_speed_scale;
+ *y *= mouse->normal_speed_scale;
}
}
}
-static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
+static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, int relative, float x, float y)
{
SDL_Mouse *mouse = SDL_GetMouse();
int posted;
- int xrel = 0;
- int yrel = 0;
+ float xrel = 0.0f;
+ float yrel = 0.0f;
/* SDL_HINT_MOUSE_TOUCH_EVENTS: controlling whether mouse events should generate synthetic touch events */
if (mouse->mouse_touch_events) {
if (mouseID != SDL_TOUCH_MOUSEID && !relative && track_mouse_down) {
if (window) {
- float fx = (float)x / (float)window->w;
- float fy = (float)y / (float)window->h;
- SDL_SendTouchMotion(timestamp, SDL_MOUSE_TOUCHID, 0, window, fx, fy, 1.0f);
+ float normalized_x = x / (float)window->w;
+ float normalized_y = y / (float)window->h;
+ SDL_SendTouchMotion(timestamp, SDL_MOUSE_TOUCHID, 0, window, normalized_x, normalized_y, 1.0f);
}
}
}
@@ -489,11 +469,13 @@ static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_
}
if (mouseID != SDL_TOUCH_MOUSEID && mouse->relative_mode_warp) {
- int center_x = 0, center_y = 0;
- SDL_GetWindowSize(window, ¢er_x, ¢er_y);
- center_x /= 2;
- center_y /= 2;
- if (x == center_x && y == center_y) {
+ int w = 0, h = 0;
+ float center_x, cente
(Patch may be truncated, please check the link at the top of this post.)