SDL: SDL_windowsvideo.c: add HIGHDPI_DEBUG ifdef, print DPI awareness at startup if defined

From 1b797957c17f71f3eb5540db1ffccfe8edf41969 Mon Sep 17 00:00:00 2001
From: Eric Wasylishen <[EMAIL REDACTED]>
Date: Sun, 5 Jun 2022 12:36:58 -0600
Subject: [PATCH] SDL_windowsvideo.c: add HIGHDPI_DEBUG ifdef, print DPI
 awareness at startup if defined

document some additional quirks
---
 src/video/windows/SDL_windowsvideo.c | 47 ++++++++++++++++++++++++++--
 1 file changed, 45 insertions(+), 2 deletions(-)

diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c
index 7d916bd7a65..203a08b0bfb 100644
--- a/src/video/windows/SDL_windowsvideo.c
+++ b/src/video/windows/SDL_windowsvideo.c
@@ -35,6 +35,8 @@
 #include "SDL_windowsshape.h"
 #include "SDL_windowsvulkan.h"
 
+/* #define HIGHDPI_DEBUG */
+
 /* Initialization/Query functions */
 static int WIN_VideoInit(_THIS);
 static void WIN_VideoQuit(_THIS);
@@ -299,12 +301,25 @@ WIN_DeclareDPIAwarePerMonitorV2(_THIS)
 {
     SDL_VideoData* data = (SDL_VideoData*)_this->driverdata;
 
-    /* Declare DPI aware(may have been done in external code or a manifest, as well) */
+    /* Declare DPI aware (may have been done in external code or a manifest, as well) */
     if (data->SetProcessDpiAwarenessContext) {
         /* Windows 10, version 1607 */
 
         /* NOTE: SetThreadDpiAwarenessContext doesn't work here with OpenGL - the OpenGL contents
-           end up still getting OS scaled. (tested on Windows 10 21H1 19043.1348, NVIDIA 496.49) */
+           end up still getting OS scaled. (tested on Windows 10 21H1 19043.1348, NVIDIA 496.49)
+
+           NOTE: Enabling DPI awareness through Windows Explorer
+           (right click .exe -> Properties -> Compatibility -> High DPI Settings -> 
+           check "Override high DPI Scaling behaviour", select Application) gives
+           a DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE context (at least on Windows 10 21H1), and
+           setting DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 will fail.
+
+           NOTE: Entering exclusive fullscreen in a DPI_AWARENESS_CONTEXT_UNAWARE process
+           appears to cause Windows to change the .exe manifest to DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE
+           on future launches. This means attempting to use DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
+           will fail in the future until you manually clear the "Override high DPI Scaling behaviour"
+           setting in Windows Explorer (tested on Windows 10 21H2).
+         */
         if (data->SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)) {
             return TRUE;
         } else {
@@ -316,6 +331,30 @@ WIN_DeclareDPIAwarePerMonitorV2(_THIS)
     }
 }
 
+static const char*
+WIN_GetDPIAwareness(_THIS)
+{
+    SDL_VideoData* data = (SDL_VideoData*)_this->driverdata;
+
+    if (data->GetThreadDpiAwarenessContext && data->AreDpiAwarenessContextsEqual) {
+        DPI_AWARENESS_CONTEXT context = data->GetThreadDpiAwarenessContext();
+
+        if (data->AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_UNAWARE)) {
+            return "unaware";
+        } else if (data->AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_SYSTEM_AWARE)) {
+            return "system";
+        } else if (data->AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE)) {
+            return "permonitor";
+        } else if (data->AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)) {
+            return "permonitorv2";
+        } else if (data->AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED)) {
+            return "unaware_gdiscaled";
+        }
+    }
+
+    return "";
+}
+
 static void
 WIN_InitDPIAwareness(_THIS)
 {
@@ -341,6 +380,10 @@ WIN_VideoInit(_THIS)
 
     WIN_InitDPIAwareness(_this);
 
+#ifdef HIGHDPI_DEBUG
+    SDL_Log("DPI awareness: %s", WIN_GetDPIAwareness(_this));
+#endif
+
     if (WIN_InitModes(_this) < 0) {
         return -1;
     }