SDL: Hook up Android_ScreenDensity to convert pixels to screen coordinates on Android

From a37f2aed7e9b53a7e09a6f619344ca6afdc63881 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Wed, 25 Jan 2023 10:22:43 -0800
Subject: [PATCH] Hook up Android_ScreenDensity to convert pixels to screen
 coordinates on Android

Fixes https://github.com/libsdl-org/SDL/issues/7149
---
 src/video/android/SDL_androidmouse.c  |  3 +++
 src/video/android/SDL_androidvideo.c  | 13 +++++++++----
 src/video/android/SDL_androidvideo.h  |  1 +
 src/video/android/SDL_androidwindow.c |  8 ++++----
 4 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/src/video/android/SDL_androidmouse.c b/src/video/android/SDL_androidmouse.c
index f88577aed989..d2e8f277cfbe 100644
--- a/src/video/android/SDL_androidmouse.c
+++ b/src/video/android/SDL_androidmouse.c
@@ -219,6 +219,9 @@ void Android_OnMouse(SDL_Window *window, int state, int action, float x, float y
         return;
     }
 
+    x /= Android_ScreenDensity;
+    y /= Android_ScreenDensity;
+
     switch (action) {
     case ACTION_DOWN:
         changes = state & ~last_state;
diff --git a/src/video/android/SDL_androidvideo.c b/src/video/android/SDL_androidvideo.c
index 44d628255fa4..ca1969fa2f2e 100644
--- a/src/video/android/SDL_androidvideo.c
+++ b/src/video/android/SDL_androidvideo.c
@@ -61,8 +61,8 @@ int Android_SurfaceHeight = 0;
 static int Android_DeviceWidth = 0;
 static int Android_DeviceHeight = 0;
 static Uint32 Android_ScreenFormat = SDL_PIXELFORMAT_RGB565; /* Default SurfaceView format, in case this is queried before being filled */
+float Android_ScreenDensity = 1.0f;
 static float Android_ScreenRate = 0.0f;
-static float Android_ScreenDensity = 1.0f;
 SDL_sem *Android_PauseSem = NULL;
 SDL_sem *Android_ResumeSem = NULL;
 SDL_mutex *Android_ActivityMutex = NULL;
@@ -182,7 +182,7 @@ int Android_VideoInit(_THIS)
     mode.format = Android_ScreenFormat;
     mode.w = Android_DeviceWidth;
     mode.h = Android_DeviceHeight;
-    mode.display_scale = 1.0f; /* FIXME */
+    mode.display_scale = Android_ScreenDensity;
     mode.refresh_rate = Android_ScreenRate;
     mode.driverdata = NULL;
 
@@ -220,8 +220,8 @@ void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int device
     Android_SurfaceHeight = surfaceHeight;
     Android_DeviceWidth = deviceWidth;
     Android_DeviceHeight = deviceHeight;
+    Android_ScreenDensity = (density > 0.0f) ? density : 1.0f;
     Android_ScreenRate = rate;
-    Android_ScreenDensity = density;
 }
 
 static Uint32 format_to_pixelFormat(int format)
@@ -279,20 +279,25 @@ void Android_SendResize(SDL_Window *window)
         display->desktop_mode.format = Android_ScreenFormat;
         display->desktop_mode.w = Android_DeviceWidth;
         display->desktop_mode.h = Android_DeviceHeight;
+        display->desktop_mode.display_scale = Android_ScreenDensity;
         display->desktop_mode.refresh_rate = Android_ScreenRate;
     }
 
     if (window) {
         /* Force the current mode to match the resize otherwise the SDL_EVENT_WINDOW_RESTORED event
          * will fall back to the old mode */
+        int w, h;
         SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
         display->display_modes[0].format = Android_ScreenFormat;
         display->display_modes[0].w = Android_DeviceWidth;
         display->display_modes[0].h = Android_DeviceHeight;
+        display->display_modes[0].display_scale = Android_ScreenDensity;
         display->display_modes[0].refresh_rate = Android_ScreenRate;
         display->current_mode = display->display_modes[0];
 
-        SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, Android_SurfaceWidth, Android_SurfaceHeight);
+        w = (int)SDL_ceilf(Android_SurfaceWidth / Android_ScreenDensity);
+        h = (int)SDL_ceilf(Android_SurfaceHeight / Android_ScreenDensity);
+        SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, w, h);
     }
 }
 
diff --git a/src/video/android/SDL_androidvideo.h b/src/video/android/SDL_androidvideo.h
index 81d5c4a27b5e..74aba209b2fa 100644
--- a/src/video/android/SDL_androidvideo.h
+++ b/src/video/android/SDL_androidvideo.h
@@ -42,6 +42,7 @@ typedef struct SDL_VideoData
 
 extern int Android_SurfaceWidth;
 extern int Android_SurfaceHeight;
+extern float Android_ScreenDensity;
 extern SDL_sem *Android_PauseSem, *Android_ResumeSem;
 extern SDL_mutex *Android_ActivityMutex;
 
diff --git a/src/video/android/SDL_androidwindow.c b/src/video/android/SDL_androidwindow.c
index 2252fddfe0e2..68bbd25c9ac1 100644
--- a/src/video/android/SDL_androidwindow.c
+++ b/src/video/android/SDL_androidwindow.c
@@ -54,8 +54,8 @@ int Android_CreateWindow(_THIS, SDL_Window *window)
     /* Adjust the window data to match the screen */
     window->x = 0;
     window->y = 0;
-    window->w = Android_SurfaceWidth;
-    window->h = Android_SurfaceHeight;
+    window->w = (int)SDL_ceilf(Android_SurfaceWidth / Android_ScreenDensity);
+    window->h = (int)SDL_ceilf(Android_SurfaceHeight / Android_ScreenDensity);
 
     /* One window, it always has focus */
     SDL_SetMouseFocus(window);
@@ -139,8 +139,8 @@ void Android_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *di
         old_w = window->w;
         old_h = window->h;
 
-        new_w = ANativeWindow_getWidth(data->native_window);
-        new_h = ANativeWindow_getHeight(data->native_window);
+        new_w = (int)SDL_ceilf(ANativeWindow_getWidth(data->native_window) / Android_ScreenDensity);
+        new_h = (int)SDL_ceilf(ANativeWindow_getHeight(data->native_window) / Android_ScreenDensity);
 
         if (new_w < 0 || new_h < 0) {
             SDL_SetError("ANativeWindow_getWidth/Height() fails");