sdl2-compat: Updated for SDL3 hint changes

From 413241d29c4da59ede1366f4fa36d131b8d62c7b Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 12 Feb 2024 19:16:51 -0800
Subject: [PATCH] Updated for SDL3 hint changes

---
 src/sdl2_compat.c | 116 ++++++++++++++++++++++++++++++++++++----------
 src/sdl3_syms.h   |  10 ++--
 2 files changed, 95 insertions(+), 31 deletions(-)

diff --git a/src/sdl2_compat.c b/src/sdl2_compat.c
index 5e38933..76b01f1 100644
--- a/src/sdl2_compat.c
+++ b/src/sdl2_compat.c
@@ -431,23 +431,36 @@ SDL2Compat_GetHintBoolean(const char *name, SDL_bool default_value)
 }
 
 
-/* if you change this, update also SDL2Compat_ApplyQuirks() */
+static struct {
+    const char *old_hint;
+    const char *new_hint;
+} renamed_hints[] = {
+    { "SDL_AUDIODRIVER", "SDL_AUDIO_DRIVER" },
+    { "SDL_ALLOW_TOPMOST", "SDL_WINDOW_ALLOW_TOPMOST" },
+    { "SDL_DIRECTINPUT_ENABLED", "SDL_JOYSTICK_DIRECTINPUT" },
+    { "SDL_GDK_TEXTINPUT_DEFAULT", "SDL_GDK_TEXTINPUT_DEFAULT_TEXT" },
+    { "SDL_JOYSTICK_GAMECUBE_RUMBLE_BRAKE", "SDL_JOYSTICK_HIDAPI_GAMECUBE_RUMBLE_BRAKE" },
+    { "SDL_LINUX_DIGITAL_HATS", "SDL_JOYSTICK_LINUX_DIGITAL_HATS" },
+    { "SDL_LINUX_HAT_DEADZONES", "SDL_JOYSTICK_LINUX_HAT_DEADZONES" },
+    { "SDL_LINUX_JOYSTICK_CLASSIC", "SDL_JOYSTICK_LINUX_CLASSIC" },
+    { "SDL_LINUX_JOYSTICK_DEADZONES", "SDL_JOYSTICK_LINUX_DEADZONES" },
+    { "SDL_PS2_DYNAMIC_VSYNC", "SDL_RENDER_PS2_DYNAMIC_VSYNC" },
+    { "SDL_VIDEODRIVER", "SDL_VIDEO_DRIVER" },
+    { "SDL_VIDEO_WAYLAND_WMCLASS", "SDL_APP_ID" },
+    { "SDL_VIDEO_X11_FORCE_EGL", "SDL_VIDEO_FORCE_EGL" },
+    { "SDL_VIDEO_X11_WMCLASS", "SDL_APP_ID" },
+};
+
 static const char *
 SDL2_to_SDL3_hint(const char *name)
 {
-    if (SDL3_strcmp(name, "SDL_VIDEODRIVER") == 0) {
-        return "SDL_VIDEO_DRIVER";
-    }
-    else if (SDL3_strcmp(name, "SDL_AUDIODRIVER") == 0) {
-        return "SDL_AUDIO_DRIVER";
-    }
-    else if (SDL3_strcmp(name, "SDL_VIDEO_X11_WMCLASS") == 0) {
-        return "SDL_APP_ID";
-    }
-    else if (SDL3_strcmp(name, "SDL_VIDEO_WAYLAND_WMCLASS") == 0) {
-        return "SDL_APP_ID";
-    }
+    unsigned int i;
 
+    for (i = 0; i < SDL_arraysize(renamed_hints); ++i) {
+        if (SDL3_strcmp(name, renamed_hints[i].old_hint) == 0) {
+            return renamed_hints[i].new_hint;
+        }
+    }
     return name;
 }
 
@@ -499,7 +512,7 @@ static void
 SDL2Compat_ApplyQuirks(SDL_bool force_x11)
 {
     const char *exe_name = SDL2Compat_GetExeName();
-    int i;
+    unsigned int i;
 
     if (WantDebugLogging) {
         SDL3_Log("This app appears to be named '%s'", exe_name);
@@ -509,10 +522,9 @@ SDL2Compat_ApplyQuirks(SDL_bool force_x11)
     { const char *old_env = SDL3_getenv(old); if (old_env) { SDL3_setenv(new, old_env, 1); } }
 
     /* if you change this, update also SDL2_to_SDL3_hint() */
-    UpdateHintName("SDL_VIDEODRIVER", "SDL_VIDEO_DRIVER");
-    UpdateHintName("SDL_AUDIODRIVER", "SDL_AUDIO_DRIVER");
-    UpdateHintName("SDL_VIDEO_X11_WMCLASS", "SDL_APP_ID");
-    UpdateHintName("SDL_VIDEO_WAYLAND_WMCLASS", "SDL_APP_ID");
+    for (i = 0; i < SDL_arraysize(renamed_hints); ++i) {
+        UpdateHintName(renamed_hints[i].old_hint, renamed_hints[i].new_hint);
+    }
 #undef UpdateHintName
 
     #ifdef __linux__
@@ -534,7 +546,7 @@ SDL2Compat_ApplyQuirks(SDL_bool force_x11)
     if (*exe_name == '\0') {
         return;
     }
-    for (i = 0; i < (int) SDL_arraysize(quirks); i++) {
+    for (i = 0; i < SDL_arraysize(quirks); i++) {
         if (!SDL3_strcmp(exe_name, quirks[i].exe_name)) {
             if (!SDL3_getenv(quirks[i].hint_name)) {
                 if (WantDebugLogging) {
@@ -4285,16 +4297,39 @@ SDL_RenderPresent(SDL_Renderer *renderer)
     SDL3_RenderPresent(renderer);
 }
 
-DECLSPEC void SDLCALL
-SDL_DestroyTexture(SDL_Texture *texture)
+static SDL_ScaleMode SDL_GetScaleMode(void)
 {
-    SDL3_DestroyTexture(texture);
+    const char *hint = SDL3_GetHint("SDL_RENDER_SCALE_QUALITY");
+
+    if (!hint || SDL3_strcasecmp(hint, "nearest") == 0) {
+        return SDL_SCALEMODE_NEAREST;
+    } else if (SDL3_strcasecmp(hint, "linear") == 0) {
+        return SDL_SCALEMODE_LINEAR;
+    } else if (SDL3_strcasecmp(hint, "best") == 0) {
+        return SDL_SCALEMODE_BEST;
+    } else {
+        return (SDL_ScaleMode)SDL3_atoi(hint);
+    }
 }
 
-DECLSPEC void SDLCALL
-SDL_DestroyRenderer(SDL_Renderer *renderer)
+DECLSPEC SDL_Texture * SDLCALL
+SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int h)
+{
+    SDL_Texture *texture = SDL3_CreateTexture(renderer, format, access, w, h);
+    if (texture) {
+        SDL_SetTextureScaleMode(texture, SDL_GetScaleMode());
+    }
+    return texture;
+}
+
+DECLSPEC SDL_Texture * SDLCALL
+SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface)
 {
-    SDL3_DestroyRenderer(renderer);
+    SDL_Texture *texture = SDL3_CreateTextureFromSurface(renderer, surface);
+    if (texture) {
+        SDL_SetTextureScaleMode(texture, SDL_GetScaleMode());
+    }
+    return texture;
 }
 
 
@@ -6057,6 +6092,7 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
         SDL3_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, w);
         SDL3_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, h);
         SDL3_SetNumberProperty(props, "flags", flags);
+        SDL3_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_EXTERNAL_GRAPHICS_CONTEXT_BOOLEAN, SDL3_GetHintBoolean("SDL_VIDEO_EXTERNAL_CONTEXT", SDL_FALSE));
 
         window = SDL3_CreateWindowWithProperties(props);
         SDL3_DestroyProperties(props);
@@ -7757,6 +7793,36 @@ SDL_hid_enumerate(unsigned short vendor_id, unsigned short product_id)
     return retval;
 }
 
+#if (defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_GDK)) && !defined(SDL_PLATFORM_WINRT)
+
+DECLSPEC SDL_Thread *SDLCALL
+SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
+                 pfnSDL_CurrentBeginThread pfnBeginThread,
+                 pfnSDL_CurrentEndThread pfnEndThread)
+{
+    size_t stacksize = 0;
+    const char *hint = SDL3_GetHint("SDL_THREAD_STACK_SIZE");
+    if (hint) {
+        stacksize = (size_t)SDL_strtoul(hint, NULL, 0);
+    }
+    return SDL_CreateThreadWithStackSize(fn, name, stacksize, data, pfnBeginThread, pfnEndThread);
+}
+
+#else
+
+DECLSPEC SDL_Thread *SDLCALL
+SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data)
+{
+    size_t stacksize = 0;
+    const char *hint = SDL3_GetHint("SDL_THREAD_STACK_SIZE");
+    if (hint) {
+        stacksize = (size_t)SDL_strtoul(hint, NULL, 0);
+    }
+    return SDL_CreateThreadWithStackSize(fn, name, stacksize, data);
+}
+
+#endif /* (SDL_PLATFORM_WIN32 || SDL_PLATFORM_GDK) && !SDL_PLATFORM_WINRT */
+
 DECLSPEC unsigned long SDLCALL
 SDL_ThreadID(void)
 {
diff --git a/src/sdl3_syms.h b/src/sdl3_syms.h
index e69bd22..19325a3 100644
--- a/src/sdl3_syms.h
+++ b/src/sdl3_syms.h
@@ -50,10 +50,8 @@ SDL3_SYM_VARARGS(int,sscanf,(const char *a, SDL_SCANF_FORMAT_STRING const char *
 SDL3_SYM_VARARGS(int,snprintf,(SDL_OUT_Z_CAP(b) char *a, size_t b, SDL_PRINTF_FORMAT_STRING const char *c, ...))
 
 #if (defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_GDK)) && !defined(SDL_PLATFORM_WINRT)
-SDL3_SYM_PASSTHROUGH(SDL_Thread*,CreateThread,(SDL_ThreadFunction a, const char *b, void *c, pfnSDL_CurrentBeginThread d, pfnSDL_CurrentEndThread e),(a,b,c,d,e),return)
 SDL3_SYM_PASSTHROUGH(SDL_Thread*,CreateThreadWithStackSize,(SDL_ThreadFunction a, const char *b, const size_t c, void *d, pfnSDL_CurrentBeginThread e, pfnSDL_CurrentEndThread f),(a,b,c,d,e,f),return)
 #else
-SDL3_SYM_PASSTHROUGH(SDL_Thread*,CreateThread,(SDL_ThreadFunction a, const char *b, void *c),(a,b,c),return)
 SDL3_SYM_PASSTHROUGH(SDL_Thread*,CreateThreadWithStackSize,(SDL_ThreadFunction a, const char *b, const size_t c, void *d),(a,b,c,d),return)
 #endif
 
@@ -311,8 +309,8 @@ SDL3_SYM_PASSTHROUGH(SDL_Renderer*,CreateSoftwareRenderer,(SDL_Surface *a),(a),r
 SDL3_SYM_PASSTHROUGH(SDL_Renderer*,GetRenderer,(SDL_Window *a),(a),return)
 SDL3_SYM_PASSTHROUGH(int,GetRendererInfo,(SDL_Renderer *a, SDL_RendererInfo *b),(a,b),return)
 SDL3_SYM_RENAMED(int,GetRendererOutputSize,GetRenderOutputSize,(SDL_Renderer *a, int *b, int *c),(a,b,c),return)
-SDL3_SYM_PASSTHROUGH(SDL_Texture*,CreateTexture,(SDL_Renderer *a, Uint32 b, int c, int d, int e),(a,b,c,d,e),return)
-SDL3_SYM_PASSTHROUGH(SDL_Texture*,CreateTextureFromSurface,(SDL_Renderer *a, SDL_Surface *b),(a,b),return)
+SDL3_SYM(SDL_Texture*,CreateTexture,(SDL_Renderer *a, Uint32 b, int c, int d, int e),(a,b,c,d,e),return)
+SDL3_SYM(SDL_Texture*,CreateTextureFromSurface,(SDL_Renderer *a, SDL_Surface *b),(a,b),return)
 SDL3_SYM_PASSTHROUGH(int,QueryTexture,(SDL_Texture *a, Uint32 *b, int *c, int *d, int *e),(a,b,c,d,e),return)
 SDL3_SYM_PASSTHROUGH(int,SetTextureColorMod,(SDL_Texture *a, Uint8 b, Uint8 c, Uint8 d),(a,b,c,d),return)
 SDL3_SYM_PASSTHROUGH(int,GetTextureColorMod,(SDL_Texture *a, Uint8 *b, Uint8 *c, Uint8 *d),(a,b,c,d),return)
@@ -340,8 +338,8 @@ SDL3_SYM_PASSTHROUGH(int,GetRenderDrawBlendMode,(SDL_Renderer *a, SDL_BlendMode
 SDL3_SYM(int,RenderClear,(SDL_Renderer *a),(a),return)
 SDL3_SYM(SDL_Surface *,RenderReadPixels,(SDL_Renderer *a, const SDL_Rect *b),(a,b),return)
 SDL3_SYM(int,RenderPresent,(SDL_Renderer *a),(a),return)
-SDL3_SYM(void,DestroyTexture,(SDL_Texture *a),(a),)
-SDL3_SYM(void,DestroyRenderer,(SDL_Renderer *a),(a),)
+SDL3_SYM_PASSTHROUGH(void,DestroyTexture,(SDL_Texture *a),(a),)
+SDL3_SYM_PASSTHROUGH(void,DestroyRenderer,(SDL_Renderer *a),(a),)
 SDL3_SYM(SDL_RWops*,RWFromFile,(const char *a, const char *b),(a,b),return)
 SDL3_SYM(SDL_RWops*,RWFromMem,(void *a, size_t b),(a,b),return)
 SDL3_SYM(SDL_RWops*,RWFromConstMem,(const void *a, size_t b),(a,b),return)