sdl12-compat: Scale coordinates used in SDL_WarpMouse()

From dfa6cc2f0376c4cd7acc7759716c431bb22d884b Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 25 Oct 2025 17:07:08 -0700
Subject: [PATCH] Scale coordinates used in SDL_WarpMouse()

Fixes https://github.com/libsdl-org/sdl12-compat/issues/367
---
 src/SDL12_compat.c | 25 +++++++++++++++++++++++++
 src/SDL20_syms.h   |  3 +++
 2 files changed, 28 insertions(+)

diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c
index 1b82aa1ca..cedc803e0 100644
--- a/src/SDL12_compat.c
+++ b/src/SDL12_compat.c
@@ -7706,6 +7706,31 @@ SDL_WarpMouse(Uint16 x, Uint16 y)
         MousePosition.y = (int) y;
     } else {
         if (VideoWindow20) {
+            SDL_Rect viewport;
+            float scale_x, scale_y;
+
+            if (OpenGLLogicalScalingFBO) {
+                int physical_w, physical_h;
+
+                /* we want to scale into the window size, which is dpi-scaled */
+                SDL20_GetWindowSize(VideoWindow20, &physical_w, &physical_h);
+
+                viewport = GetOpenGLLogicalScalingViewport(physical_w, physical_h);
+
+                scale_x = (float)viewport.w / OpenGLLogicalScalingWidth;
+                scale_y = (float)viewport.h / OpenGLLogicalScalingHeight;
+            } else {
+                SDL20_RenderGetViewport(VideoRenderer20, &viewport);
+                SDL20_RenderGetScale(VideoRenderer20, &scale_x, &scale_y);
+                viewport.x = (int)SDL20_lroundf(viewport.x * scale_x);
+                viewport.y = (int)SDL20_lroundf(viewport.y * scale_y);
+                viewport.w = (int)SDL20_lroundf(viewport.w * scale_x);
+                viewport.h = (int)SDL20_lroundf(viewport.h * scale_y);
+            }
+
+            x = (int)SDL20_lroundf(viewport.x + (x * scale_x));
+            y = (int)SDL20_lroundf(viewport.y + (y * scale_y));
+
             SDL20_WarpMouseInWindow(VideoWindow20, x, y);
         }
     }
diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h
index 36af4bca7..1fc50b0f9 100644
--- a/src/SDL20_syms.h
+++ b/src/SDL20_syms.h
@@ -313,6 +313,7 @@ SDL20_SYM_PASSTHROUGH(int,iconv_close,(SDL_iconv_t a),(a),return)
 SDL20_SYM_PASSTHROUGH(size_t,iconv,(SDL_iconv_t a, const char **b, size_t *c, char **d, size_t *e),(a,b,c,d,e),return)
 SDL20_SYM_PASSTHROUGH(char *,iconv_string,(const char *a, const char *b, const char *c, size_t d),(a,b,c,d),return)
 SDL20_SYM(int,setenv,(const char *a, const char *b, int c),(a,b,c),return)
+SDL20_SYM(long,lroundf,(float a),(a),return)
 
 SDL20_SYM(double,fabs,(double a),(a),return)
 SDL20_SYM(double,ceil,(double a),(a),return)
@@ -320,6 +321,8 @@ SDL20_SYM(double,floor,(double a),(a),return)
 
 SDL20_SYM(SDL_Renderer *,CreateRenderer,(SDL_Window *a, int b, Uint32 c),(a,b,c),return)
 SDL20_SYM(int,GetRendererInfo,(SDL_Renderer *a, SDL_RendererInfo *b),(a,b),return)
+SDL20_SYM(void,RenderGetScale,(SDL_Renderer *a, float *b, float *c),(a,b,c),return)
+SDL20_SYM(void,RenderGetViewport,(SDL_Renderer *a, SDL_Rect *b),(a,b),return)
 SDL20_SYM(SDL_Texture *,CreateTexture,(SDL_Renderer *a, Uint32 b, int c, int d, int e),(a,b,c,d,e),return)
 SDL20_SYM(int,LockTexture,(SDL_Texture *a, const SDL_Rect *b, void **c, int *d),(a,b,c,d),return)
 SDL20_SYM(void,UnlockTexture,(SDL_Texture *a),(a),)