diff --git a/docs/README-migration.md b/docs/README-migration.md index 6bf247b3e9..3e19018179 100644 --- a/docs/README-migration.md +++ b/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); } } ``` diff --git a/include/SDL3/SDL_video.h b/include/SDL3/SDL_video.h index 65720549f3..c548bee6cc 100644 --- a/include/SDL3/SDL_video.h +++ b/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. diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 9190df4a50..25c0d944b7 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/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) diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c index 0b96b7fbbd..307b3b03e6 100644 --- a/src/test/SDL_test_common.c +++ b/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 */ diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 9105f59968..6122230155 100644 --- a/src/video/SDL_video.c +++ b/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; } diff --git a/test/testautomation_video.c b/test/testautomation_video.c index 7d842819a0..26620a5cc2 100644 --- a/test/testautomation_video.c +++ b/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); } } diff --git a/test/testdisplayinfo.c b/test/testdisplayinfo.c index 2ce13d86f9..86b9173f9d 100644 --- a/test/testdisplayinfo.c +++ b/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"); } diff --git a/test/testwm.c b/test/testwm.c index fa3a003e8a..f0838cccf2 100644 --- a/test/testwm.c +++ b/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); } } }