sdl2-compat: SDL_DisplayMode->refresh_rate is now a float (#16)

From 5c4501ed3b8b26f0387b14c5606e3441abdd86f8 Mon Sep 17 00:00:00 2001
From: Sylvain Becker <[EMAIL REDACTED]>
Date: Wed, 4 Jan 2023 13:48:43 +0100
Subject: [PATCH] SDL_DisplayMode->refresh_rate is now a float (#16)

---
 src/sdl2_compat.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++
 src/sdl3_syms.h   | 12 +++----
 2 files changed, 92 insertions(+), 6 deletions(-)

diff --git a/src/sdl2_compat.c b/src/sdl2_compat.c
index 853a909..6942952 100644
--- a/src/sdl2_compat.c
+++ b/src/sdl2_compat.c
@@ -2870,6 +2870,92 @@ SDL_UnlockSensors(void)
     // FIXME    
 }
 
+typedef struct
+{
+    Uint32 format;              /**< pixel format */
+    int w;                      /**< width, in screen coordinates */
+    int h;                      /**< height, in screen coordinates */
+    int refresh_rate;           /**< refresh rate (or zero for unspecified) */
+    void *driverdata;           /**< driver-specific data, initialize to 0 */
+} SDL2_DisplayMode;
+
+static void DisplayMode_2to3(const SDL2_DisplayMode *in, SDL_DisplayMode *out) {
+    if (in && out) {
+        out->format = in->format;
+        out->w = in->w;
+        out->h = in->h;
+        out->refresh_rate = (float) in->refresh_rate;
+        out->driverdata = in->driverdata;
+    }
+}
+
+static void DisplayMode_3to2(const SDL_DisplayMode *in, SDL2_DisplayMode *out) {
+    if (in && out) {
+        out->format = in->format;
+        out->w = in->w;
+        out->h = in->h;
+        out->refresh_rate = (int) SDL_ceil(in->refresh_rate);
+        out->driverdata = in->driverdata;
+    }
+}
+
+DECLSPEC int SDLCALL
+SDL_GetDisplayMode(int displayIndex, int modeIndex, SDL2_DisplayMode *mode)
+{
+    SDL_DisplayMode dp;
+    int ret = SDL3_GetDisplayMode(displayIndex, modeIndex, mode ? &dp : NULL);
+    DisplayMode_3to2(&dp, mode);
+    return ret;
+}
+
+DECLSPEC int SDLCALL
+SDL_GetCurrentDisplayMode(int displayIndex, SDL2_DisplayMode *mode)
+{
+    SDL_DisplayMode dp;
+    int ret = SDL3_GetCurrentDisplayMode(displayIndex, mode ? &dp : NULL);
+    DisplayMode_3to2(&dp, mode);
+    return ret;
+}
+
+DECLSPEC int SDLCALL
+SDL_GetDesktopDisplayMode(int displayIndex, SDL2_DisplayMode *mode)
+{
+    SDL_DisplayMode dp;
+    int ret = SDL3_GetDesktopDisplayMode(displayIndex, mode ? &dp : NULL);
+    DisplayMode_3to2(&dp, mode);
+    return ret;
+}
+
+DECLSPEC int SDLCALL
+SDL_GetWindowDisplayMode(SDL_Window * window, SDL2_DisplayMode * mode)
+{
+    SDL_DisplayMode dp;
+    int ret = SDL3_GetWindowDisplayMode(window, mode ? &dp : NULL);
+    DisplayMode_3to2(&dp, mode);
+    return ret;
+}
+
+DECLSPEC SDL2_DisplayMode * SDLCALL
+SDL_GetClosestDisplayMode(int displayIndex, const SDL2_DisplayMode * mode, SDL2_DisplayMode * closest)
+{
+    SDL_DisplayMode dp;
+    SDL_DisplayMode closest3;
+    SDL_DisplayMode *ret;
+    static SDL2_DisplayMode ret2; // FIXME alloc ??
+    DisplayMode_2to3(closest, &closest3);
+    ret = SDL3_GetClosestDisplayMode(displayIndex, mode ? &dp : NULL, closest ? &closest3 : NULL);
+    DisplayMode_3to2(ret, &ret2);
+    return &ret2;
+}
+
+DECLSPEC int SDLCALL
+SDL_SetWindowDisplayMode(SDL_Window * window, const SDL2_DisplayMode * mode)
+{
+    SDL_DisplayMode dp;
+    DisplayMode_2to3(mode, &dp);
+    return SDL3_SetWindowDisplayMode(window, mode ? &dp : NULL);
+}
+
 DECLSPEC int SDLCALL
 SDL_RenderDrawPoint(SDL_Renderer *renderer, int x, int y)
 {
diff --git a/src/sdl3_syms.h b/src/sdl3_syms.h
index 0506514..a924d66 100644
--- a/src/sdl3_syms.h
+++ b/src/sdl3_syms.h
@@ -492,13 +492,13 @@ SDL3_SYM_PASSTHROUGH(int,GetNumVideoDisplays,(void),(),return)
 SDL3_SYM_PASSTHROUGH(const char*,GetDisplayName,(int a),(a),return)
 SDL3_SYM_PASSTHROUGH(int,GetDisplayBounds,(int a, SDL_Rect *b),(a,b),return)
 SDL3_SYM_PASSTHROUGH(int,GetNumDisplayModes,(int a),(a),return)
-SDL3_SYM_PASSTHROUGH(int,GetDisplayMode,(int a, int b, SDL_DisplayMode *c),(a,b,c),return)
-SDL3_SYM_PASSTHROUGH(int,GetDesktopDisplayMode,(int a, SDL_DisplayMode *b),(a,b),return)
-SDL3_SYM_PASSTHROUGH(int,GetCurrentDisplayMode,(int a, SDL_DisplayMode *b),(a,b),return)
-SDL3_SYM_PASSTHROUGH(SDL_DisplayMode*,GetClosestDisplayMode,(int a, const SDL_DisplayMode *b, SDL_DisplayMode *c),(a,b,c),return)
+SDL3_SYM(int,GetDisplayMode,(int a, int b, SDL_DisplayMode *c),(a,b,c),return)
+SDL3_SYM(int,GetDesktopDisplayMode,(int a, SDL_DisplayMode *b),(a,b),return)
+SDL3_SYM(int,GetCurrentDisplayMode,(int a, SDL_DisplayMode *b),(a,b),return)
+SDL3_SYM(SDL_DisplayMode*,GetClosestDisplayMode,(int a, const SDL_DisplayMode *b, SDL_DisplayMode *c),(a,b,c),return)
 SDL3_SYM_PASSTHROUGH(int,GetWindowDisplayIndex,(SDL_Window *a),(a),return)
-SDL3_SYM_PASSTHROUGH(int,SetWindowDisplayMode,(SDL_Window *a, const SDL_DisplayMode *b),(a,b),return)
-SDL3_SYM_PASSTHROUGH(int,GetWindowDisplayMode,(SDL_Window *a, SDL_DisplayMode *b),(a,b),return)
+SDL3_SYM(int,SetWindowDisplayMode,(SDL_Window *a, const SDL_DisplayMode *b),(a,b),return)
+SDL3_SYM(int,GetWindowDisplayMode,(SDL_Window *a, SDL_DisplayMode *b),(a,b),return)
 SDL3_SYM_PASSTHROUGH(Uint32,GetWindowPixelFormat,(SDL_Window *a),(a),return)
 SDL3_SYM_PASSTHROUGH(SDL_Window*,CreateWindow,(const char *a, int b, int c, int d, int e, Uint32 f),(a,b,c,d,e,f),return)
 SDL3_SYM_PASSTHROUGH(SDL_Window*,CreateWindowFrom,(const void *a),(a),return)