瀏覽代碼

SDL_GetFullscreenDisplayModes() follows the SDL_GetStringRule

Sam Lantinga 9 月之前
父節點
當前提交
9de8cb888a

+ 1 - 2
docs/README-migration.md

@@ -2015,14 +2015,13 @@ Rather than iterating over display modes using an index, there is a new function
 {
     SDL_DisplayID display = SDL_GetPrimaryDisplay();
     int num_modes = 0;
-    SDL_DisplayMode **modes = SDL_GetFullscreenDisplayModes(display, &num_modes);
+    const SDL_DisplayMode * const *modes = SDL_GetFullscreenDisplayModes(display, &num_modes);
     if (modes) {
         for (i = 0; i < num_modes; ++i) {
             SDL_DisplayMode *mode = modes[i];
             SDL_Log("Display %" SDL_PRIu32 " mode %d: %dx%d@%gx %gHz\n",
                     display, i, mode->w, mode->h, mode->pixel_density, mode->refresh_rate);
         }
-        SDL_free(modes);
     }
 }
 ```

+ 5 - 4
include/SDL3/SDL_video.h

@@ -555,17 +555,18 @@ extern SDL_DECLSPEC float SDLCALL SDL_GetDisplayContentScale(SDL_DisplayID displ
  * - refresh rate -> highest to lowest
  * - pixel density -> lowest to highest
  *
+ * The returned array follows the SDL_GetStringRule, and will be automatically freed later.
+ *
  * \param displayID the instance ID of the display to query.
- * \param count a pointer filled in with the number of display modes returned.
- * \returns a NULL terminated array of display mode pointers which should be
- *          freed with SDL_free(), or NULL on failure; call SDL_GetError() for
+ * \param count a pointer filled in with the number of display modes returned, may be NULL.
+ * \returns a NULL terminated array of display mode pointers or NULL on failure; call SDL_GetError() for
  *          more information.
  *
  * \since This function is available since SDL 3.0.0.
  *
  * \sa SDL_GetDisplays
  */
-extern SDL_DECLSPEC const SDL_DisplayMode ** SDLCALL SDL_GetFullscreenDisplayModes(SDL_DisplayID displayID, int *count);
+extern SDL_DECLSPEC const SDL_DisplayMode * const * SDLCALL SDL_GetFullscreenDisplayModes(SDL_DisplayID displayID, int *count);
 
 /**
  * Get the closest match to the requested display mode.

+ 1 - 1
src/dynapi/SDL_dynapi_procs.h

@@ -269,7 +269,7 @@ SDL_DYNAPI_PROC(const SDL_DisplayID*,SDL_GetDisplays,(int *a),(a),return)
 SDL_DYNAPI_PROC(const char*,SDL_GetError,(void),(),return)
 SDL_DYNAPI_PROC(SDL_bool,SDL_GetEventFilter,(SDL_EventFilter *a, void **b),(a,b),return)
 SDL_DYNAPI_PROC(float,SDL_GetFloatProperty,(SDL_PropertiesID a, const char *b, float c),(a,b,c),return)
-SDL_DYNAPI_PROC(const SDL_DisplayMode**,SDL_GetFullscreenDisplayModes,(SDL_DisplayID a, int *b),(a,b),return)
+SDL_DYNAPI_PROC(const SDL_DisplayMode* const*,SDL_GetFullscreenDisplayModes,(SDL_DisplayID a, int *b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_GetGDKDefaultUser,(XUserHandle *a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_GetGDKTaskQueue,(XTaskQueueHandle *a),(a),return)
 SDL_DYNAPI_PROC(const char*,SDL_GetGamepadAppleSFSymbolsNameForAxis,(SDL_Gamepad *a, SDL_GamepadAxis b),(a,b),return)

+ 1 - 2
src/test/SDL_test_common.c

@@ -1194,7 +1194,7 @@ SDL_bool SDLTest_CommonInit(SDLTest_CommonState *state)
         if (state->verbose & VERBOSE_MODES) {
             const SDL_DisplayID *displays;
             SDL_Rect bounds, usablebounds;
-            const SDL_DisplayMode **modes;
+            const SDL_DisplayMode * const *modes;
             const SDL_DisplayMode *mode;
             int bpp;
             Uint32 Rmask, Gmask, Bmask, Amask;
@@ -1258,7 +1258,6 @@ SDL_bool SDLTest_CommonInit(SDLTest_CommonState *state)
                         }
                     }
                 }
-                SDL_free((void *)modes);
 
 #if defined(SDL_VIDEO_DRIVER_WINDOWS) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
                 /* Print the D3D9 adapter index */

+ 16 - 15
src/video/SDL_video.c

@@ -1111,7 +1111,7 @@ void SDL_SetDisplayHDRProperties(SDL_VideoDisplay *display, const SDL_HDROutputP
 
 static const SDL_DisplayMode *SDL_GetFullscreenModeMatch(const SDL_DisplayMode *mode)
 {
-    const SDL_DisplayMode **modes;
+    const SDL_DisplayMode * const *modes;
     SDL_DisplayMode fullscreen_mode;
 
     if (mode->w <= 0 || mode->h <= 0) {
@@ -1150,8 +1150,6 @@ static const SDL_DisplayMode *SDL_GetFullscreenModeMatch(const SDL_DisplayMode *
                 }
             }
         }
-
-        SDL_free((void *)modes);
     }
     return mode;
 }
@@ -1222,10 +1220,11 @@ void SDL_ResetFullscreenDisplayModes(SDL_VideoDisplay *display)
     display->current_mode = &display->desktop_mode;
 }
 
-const SDL_DisplayMode **SDL_GetFullscreenDisplayModes(SDL_DisplayID displayID, int *count)
+const SDL_DisplayMode * const *SDL_GetFullscreenDisplayModes(SDL_DisplayID displayID, int *count)
 {
     int i;
-    const SDL_DisplayMode **modes;
+    int num_modes;
+    const SDL_DisplayMode **retval;
     SDL_VideoDisplay *display = SDL_GetVideoDisplay(displayID);
 
     if (count) {
@@ -1238,27 +1237,30 @@ const SDL_DisplayMode **SDL_GetFullscreenDisplayModes(SDL_DisplayID displayID, i
         _this->GetDisplayModes(_this, display);
     }
 
-    modes = (const SDL_DisplayMode **)SDL_malloc((display->num_fullscreen_modes + 1) * sizeof(*modes));
-    if (modes) {
-        if (count) {
-            *count = display->num_fullscreen_modes;
+    num_modes = display->num_fullscreen_modes;
+    retval = (const SDL_DisplayMode **)SDL_malloc((num_modes + 1) * sizeof(*retval) + num_modes * sizeof(**retval));
+    if (retval) {
+        SDL_DisplayMode *modes = (SDL_DisplayMode *)((Uint8 *)retval + ((num_modes + 1) * sizeof(*retval)));
+        SDL_memcpy(modes, display->fullscreen_modes, num_modes * sizeof(*modes));
+        for (i = 0; i < num_modes; ++i) {
+            retval[i] = modes++;
         }
+        retval[i] = NULL;
 
-        for (i = 0; i < display->num_fullscreen_modes; ++i) {
-            modes[i] = &display->fullscreen_modes[i];
+        if (count) {
+            *count = num_modes;
         }
-        modes[i] = NULL;
     } else {
         if (count) {
             *count = 0;
         }
     }
-    return modes;
+    return SDL_FreeLater(retval);
 }
 
 const SDL_DisplayMode *SDL_GetClosestFullscreenDisplayMode(SDL_DisplayID displayID, int w, int h, float refresh_rate, SDL_bool include_high_density_modes)
 {
-    const SDL_DisplayMode **modes;
+    const SDL_DisplayMode * const *modes;
     const SDL_DisplayMode *mode, *closest = NULL;
     float aspect_ratio;
     int i;
@@ -1311,7 +1313,6 @@ const SDL_DisplayMode *SDL_GetClosestFullscreenDisplayMode(SDL_DisplayID display
 
             closest = mode;
         }
-        SDL_free((void *)modes);
     }
     return closest;
 }

+ 2 - 4
test/testautomation_video.c

@@ -306,7 +306,7 @@ static int video_getWindowFlags(void *arg)
 static int video_getFullscreenDisplayModes(void *arg)
 {
     const SDL_DisplayID *displays;
-    const SDL_DisplayMode **modes;
+    const SDL_DisplayMode * const *modes;
     int count;
     int i;
 
@@ -321,7 +321,6 @@ static int video_getFullscreenDisplayModes(void *arg)
             SDLTest_AssertPass("Call to SDL_GetFullscreenDisplayModes(%" SDL_PRIu32 ")", displays[i]);
             SDLTest_AssertCheck(modes != NULL, "Validate returned value from function; expected != NULL; got: %p", modes);
             SDLTest_AssertCheck(count >= 0, "Validate number of modes; expected: >= 0; got: %d", count);
-            SDL_free((void *)modes);
         }
     }
 
@@ -334,7 +333,7 @@ static int video_getFullscreenDisplayModes(void *arg)
 static int video_getClosestDisplayModeCurrentResolution(void *arg)
 {
     const SDL_DisplayID *displays;
-    const SDL_DisplayMode **modes;
+    const SDL_DisplayMode * const *modes;
     SDL_DisplayMode current;
     const SDL_DisplayMode *closest;
     int i, num_modes;
@@ -370,7 +369,6 @@ static int video_getClosestDisplayModeCurrentResolution(void *arg)
                                         current.h, closest->h);
                 }
             }
-            SDL_free((void *)modes);
         }
     }
 

+ 1 - 2
test/testdisplayinfo.c

@@ -34,7 +34,7 @@ print_mode(const char *prefix, const SDL_DisplayMode *mode)
 int main(int argc, char *argv[])
 {
     const SDL_DisplayID *displays;
-    const SDL_DisplayMode **modes;
+    const SDL_DisplayMode * const *modes;
     const SDL_DisplayMode *mode;
     int num_displays, i;
     SDLTest_CommonState *state;
@@ -94,7 +94,6 @@ int main(int argc, char *argv[])
             (void)SDL_snprintf(prefix, sizeof(prefix), "    MODE %d", m);
             print_mode(prefix, modes[m]);
         }
-        SDL_free((void*)modes);
 
         SDL_Log("\n");
     }

+ 1 - 2
test/testwm.c

@@ -53,7 +53,7 @@ static const SDL_DisplayMode *highlighted_mode = NULL;
 static void
 draw_modes_menu(SDL_Window *window, SDL_Renderer *renderer, SDL_FRect viewport)
 {
-    const SDL_DisplayMode **modes;
+    const SDL_DisplayMode * const *modes;
     char text[1024];
     const int lineHeight = 10;
     int i, j;
@@ -143,7 +143,6 @@ draw_modes_menu(SDL_Window *window, SDL_Renderer *renderer, SDL_FRect viewport)
                     column_chars = 0;
                 }
             }
-            SDL_free((void *)modes);
         }
     }
 }