mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-30 05:18:13 +08:00
Functions that return display modes return temporary memory.
Also use the real pointer to display modes for internal mode processing Fixes https://github.com/libsdl-org/SDL/issues/10353
This commit is contained in:
@@ -584,6 +584,9 @@ extern SDL_DECLSPEC const SDL_DisplayMode * const * SDLCALL SDL_GetFullscreenDis
|
|||||||
* and finally checking the refresh rate. If all the available modes are too
|
* and finally checking the refresh rate. If all the available modes are too
|
||||||
* small, then NULL is returned.
|
* small, then NULL is returned.
|
||||||
*
|
*
|
||||||
|
* This returns temporary memory which will be automatically freed later, and
|
||||||
|
* can be claimed with SDL_ClaimTemporaryMemory().
|
||||||
|
*
|
||||||
* \param displayID the instance ID of the display to query.
|
* \param displayID the instance ID of the display to query.
|
||||||
* \param w the width in pixels of the desired display mode.
|
* \param w the width in pixels of the desired display mode.
|
||||||
* \param h the height in pixels of the desired display mode.
|
* \param h the height in pixels of the desired display mode.
|
||||||
@@ -610,6 +613,9 @@ extern SDL_DECLSPEC const SDL_DisplayMode * SDLCALL SDL_GetClosestFullscreenDisp
|
|||||||
* function will return the previous native display mode, and not the current
|
* function will return the previous native display mode, and not the current
|
||||||
* display mode.
|
* display mode.
|
||||||
*
|
*
|
||||||
|
* This returns temporary memory which will be automatically freed later, and
|
||||||
|
* can be claimed with SDL_ClaimTemporaryMemory().
|
||||||
|
*
|
||||||
* \param displayID the instance ID of the display to query.
|
* \param displayID the instance ID of the display to query.
|
||||||
* \returns a pointer to the desktop display mode or NULL on failure; call
|
* \returns a pointer to the desktop display mode or NULL on failure; call
|
||||||
* SDL_GetError() for more information.
|
* SDL_GetError() for more information.
|
||||||
@@ -629,6 +635,9 @@ extern SDL_DECLSPEC const SDL_DisplayMode * SDLCALL SDL_GetDesktopDisplayMode(SD
|
|||||||
* function will return the current display mode, and not the previous native
|
* function will return the current display mode, and not the previous native
|
||||||
* display mode.
|
* display mode.
|
||||||
*
|
*
|
||||||
|
* This returns temporary memory which will be automatically freed later, and
|
||||||
|
* can be claimed with SDL_ClaimTemporaryMemory().
|
||||||
|
*
|
||||||
* \param displayID the instance ID of the display to query.
|
* \param displayID the instance ID of the display to query.
|
||||||
* \returns a pointer to the desktop display mode or NULL on failure; call
|
* \returns a pointer to the desktop display mode or NULL on failure; call
|
||||||
* SDL_GetError() for more information.
|
* SDL_GetError() for more information.
|
||||||
@@ -759,6 +768,9 @@ extern SDL_DECLSPEC int SDLCALL SDL_SetWindowFullscreenMode(SDL_Window *window,
|
|||||||
/**
|
/**
|
||||||
* Query the display mode to use when a window is visible at fullscreen.
|
* Query the display mode to use when a window is visible at fullscreen.
|
||||||
*
|
*
|
||||||
|
* This returns temporary memory which will be automatically freed later, and
|
||||||
|
* can be claimed with SDL_ClaimTemporaryMemory().
|
||||||
|
*
|
||||||
* \param window the window to query.
|
* \param window the window to query.
|
||||||
* \returns a pointer to the exclusive fullscreen mode to use or NULL for
|
* \returns a pointer to the exclusive fullscreen mode to use or NULL for
|
||||||
* borderless fullscreen desktop mode.
|
* borderless fullscreen desktop mode.
|
||||||
|
|||||||
+88
-63
@@ -1108,9 +1108,30 @@ void SDL_SetDisplayHDRProperties(SDL_VideoDisplay *display, const SDL_HDROutputP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void SDL_UpdateFullscreenDisplayModes(SDL_VideoDisplay *display)
|
||||||
|
{
|
||||||
|
if (display->num_fullscreen_modes == 0 && _this->GetDisplayModes) {
|
||||||
|
_this->GetDisplayModes(_this, display);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const SDL_DisplayMode *SDL_CreateTemporaryDisplayMode(const SDL_DisplayMode *mode)
|
||||||
|
{
|
||||||
|
SDL_DisplayMode *retval = NULL;
|
||||||
|
|
||||||
|
if (mode) {
|
||||||
|
retval = (SDL_DisplayMode *)SDL_malloc(sizeof(*retval));
|
||||||
|
if (retval) {
|
||||||
|
SDL_copyp(retval, mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SDL_FreeLater(retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the matching mode as a pointer into our current mode list
|
||||||
static const SDL_DisplayMode *SDL_GetFullscreenModeMatch(const SDL_DisplayMode *mode)
|
static const SDL_DisplayMode *SDL_GetFullscreenModeMatch(const SDL_DisplayMode *mode)
|
||||||
{
|
{
|
||||||
const SDL_DisplayMode * const *modes;
|
SDL_VideoDisplay *display;
|
||||||
SDL_DisplayMode fullscreen_mode;
|
SDL_DisplayMode fullscreen_mode;
|
||||||
|
|
||||||
if (mode->w <= 0 || mode->h <= 0) {
|
if (mode->w <= 0 || mode->h <= 0) {
|
||||||
@@ -1126,15 +1147,15 @@ static const SDL_DisplayMode *SDL_GetFullscreenModeMatch(const SDL_DisplayMode *
|
|||||||
|
|
||||||
mode = NULL;
|
mode = NULL;
|
||||||
|
|
||||||
modes = SDL_GetFullscreenDisplayModes(fullscreen_mode.displayID, NULL);
|
display = SDL_GetVideoDisplay(fullscreen_mode.displayID);
|
||||||
if (modes) {
|
if (display) {
|
||||||
int i;
|
SDL_UpdateFullscreenDisplayModes(display);
|
||||||
|
|
||||||
/* Search for an exact match */
|
/* Search for an exact match */
|
||||||
if (!mode) {
|
if (!mode) {
|
||||||
for (i = 0; modes[i]; ++i) {
|
for (int i = 0; display->num_fullscreen_modes; ++i) {
|
||||||
if (SDL_memcmp(&fullscreen_mode, modes[i], sizeof(fullscreen_mode)) == 0) {
|
if (SDL_memcmp(&fullscreen_mode, &display->fullscreen_modes[i], sizeof(fullscreen_mode)) == 0) {
|
||||||
mode = modes[i];
|
mode = &display->fullscreen_modes[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1142,9 +1163,9 @@ static const SDL_DisplayMode *SDL_GetFullscreenModeMatch(const SDL_DisplayMode *
|
|||||||
|
|
||||||
/* Search for a mode with the same characteristics */
|
/* Search for a mode with the same characteristics */
|
||||||
if (!mode) {
|
if (!mode) {
|
||||||
for (i = 0; modes[i]; ++i) {
|
for (int i = 0; display->num_fullscreen_modes; ++i) {
|
||||||
if (cmpmodes(&fullscreen_mode, modes[i]) == 0) {
|
if (cmpmodes(&fullscreen_mode, &display->fullscreen_modes[i]) == 0) {
|
||||||
mode = modes[i];
|
mode = &display->fullscreen_modes[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1153,6 +1174,16 @@ static const SDL_DisplayMode *SDL_GetFullscreenModeMatch(const SDL_DisplayMode *
|
|||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the window's fullscreen mode as a pointer into our current mode list
|
||||||
|
static const SDL_DisplayMode *SDL_GetWindowFullscreenModeInternal(SDL_Window *window)
|
||||||
|
{
|
||||||
|
if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
||||||
|
return SDL_GetFullscreenModeMatch(&window->current_fullscreen_mode);
|
||||||
|
} else {
|
||||||
|
return SDL_GetFullscreenModeMatch(&window->requested_fullscreen_mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SDL_bool SDL_AddFullscreenDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
|
SDL_bool SDL_AddFullscreenDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
|
||||||
{
|
{
|
||||||
SDL_DisplayMode *modes;
|
SDL_DisplayMode *modes;
|
||||||
@@ -1232,9 +1263,7 @@ const SDL_DisplayMode * const *SDL_GetFullscreenDisplayModes(SDL_DisplayID displ
|
|||||||
|
|
||||||
CHECK_DISPLAY_MAGIC(display, NULL);
|
CHECK_DISPLAY_MAGIC(display, NULL);
|
||||||
|
|
||||||
if (display->num_fullscreen_modes == 0 && _this->GetDisplayModes) {
|
SDL_UpdateFullscreenDisplayModes(display);
|
||||||
_this->GetDisplayModes(_this, display);
|
|
||||||
}
|
|
||||||
|
|
||||||
num_modes = display->num_fullscreen_modes;
|
num_modes = display->num_fullscreen_modes;
|
||||||
retval = (SDL_DisplayMode **)SDL_malloc((num_modes + 1) * sizeof(*retval) + num_modes * sizeof(**retval));
|
retval = (SDL_DisplayMode **)SDL_malloc((num_modes + 1) * sizeof(*retval) + num_modes * sizeof(**retval));
|
||||||
@@ -1259,10 +1288,12 @@ const SDL_DisplayMode * const *SDL_GetFullscreenDisplayModes(SDL_DisplayID displ
|
|||||||
|
|
||||||
const SDL_DisplayMode *SDL_GetClosestFullscreenDisplayMode(SDL_DisplayID displayID, int w, int h, float refresh_rate, SDL_bool include_high_density_modes)
|
const SDL_DisplayMode *SDL_GetClosestFullscreenDisplayMode(SDL_DisplayID displayID, int w, int h, float refresh_rate, SDL_bool include_high_density_modes)
|
||||||
{
|
{
|
||||||
const SDL_DisplayMode * const *modes;
|
|
||||||
const SDL_DisplayMode *mode, *closest = NULL;
|
const SDL_DisplayMode *mode, *closest = NULL;
|
||||||
float aspect_ratio;
|
float aspect_ratio;
|
||||||
int i;
|
int i;
|
||||||
|
SDL_VideoDisplay *display = SDL_GetVideoDisplay(displayID);
|
||||||
|
|
||||||
|
CHECK_DISPLAY_MAGIC(display, NULL);
|
||||||
|
|
||||||
if (h > 0) {
|
if (h > 0) {
|
||||||
aspect_ratio = (float)w / h;
|
aspect_ratio = (float)w / h;
|
||||||
@@ -1271,49 +1302,45 @@ const SDL_DisplayMode *SDL_GetClosestFullscreenDisplayMode(SDL_DisplayID display
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (refresh_rate == 0.0f) {
|
if (refresh_rate == 0.0f) {
|
||||||
mode = SDL_GetDesktopDisplayMode(displayID);
|
refresh_rate = display->desktop_mode.refresh_rate;
|
||||||
if (mode) {
|
|
||||||
refresh_rate = mode->refresh_rate;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
modes = SDL_GetFullscreenDisplayModes(displayID, NULL);
|
SDL_UpdateFullscreenDisplayModes(display);
|
||||||
if (modes) {
|
|
||||||
for (i = 0; modes[i]; ++i) {
|
|
||||||
mode = modes[i];
|
|
||||||
|
|
||||||
if (w > mode->w) {
|
for (i = 0; i < display->num_fullscreen_modes; ++i) {
|
||||||
/* Out of sorted modes large enough here */
|
mode = &display->fullscreen_modes[i];
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (h > mode->h) {
|
|
||||||
/* Wider, but not tall enough, due to a different aspect ratio.
|
|
||||||
* This mode must be skipped, but closer modes may still follow */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (mode->pixel_density > 1.0f && !include_high_density_modes) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (closest) {
|
|
||||||
float current_aspect_ratio = (float)mode->w / mode->h;
|
|
||||||
float closest_aspect_ratio = (float)closest->w / closest->h;
|
|
||||||
if (SDL_fabsf(aspect_ratio - closest_aspect_ratio) < SDL_fabsf(aspect_ratio - current_aspect_ratio)) {
|
|
||||||
/* The mode we already found has a better aspect ratio match */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode->w == closest->w && mode->h == closest->h &&
|
if (w > mode->w) {
|
||||||
SDL_fabsf(closest->refresh_rate - refresh_rate) < SDL_fabsf(mode->refresh_rate - refresh_rate)) {
|
/* Out of sorted modes large enough here */
|
||||||
/* We already found a mode and the new mode is further from our
|
break;
|
||||||
* refresh rate target */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
closest = mode;
|
|
||||||
}
|
}
|
||||||
|
if (h > mode->h) {
|
||||||
|
/* Wider, but not tall enough, due to a different aspect ratio.
|
||||||
|
* This mode must be skipped, but closer modes may still follow */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (mode->pixel_density > 1.0f && !include_high_density_modes) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (closest) {
|
||||||
|
float current_aspect_ratio = (float)mode->w / mode->h;
|
||||||
|
float closest_aspect_ratio = (float)closest->w / closest->h;
|
||||||
|
if (SDL_fabsf(aspect_ratio - closest_aspect_ratio) < SDL_fabsf(aspect_ratio - current_aspect_ratio)) {
|
||||||
|
/* The mode we already found has a better aspect ratio match */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode->w == closest->w && mode->h == closest->h &&
|
||||||
|
SDL_fabsf(closest->refresh_rate - refresh_rate) < SDL_fabsf(mode->refresh_rate - refresh_rate)) {
|
||||||
|
/* We already found a mode and the new mode is further from our
|
||||||
|
* refresh rate target */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closest = mode;
|
||||||
}
|
}
|
||||||
return closest;
|
return SDL_CreateTemporaryDisplayMode(closest);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool DisplayModeChanged(const SDL_DisplayMode *old, const SDL_DisplayMode *new)
|
static SDL_bool DisplayModeChanged(const SDL_DisplayMode *old, const SDL_DisplayMode *new)
|
||||||
@@ -1352,7 +1379,7 @@ const SDL_DisplayMode *SDL_GetDesktopDisplayMode(SDL_DisplayID displayID)
|
|||||||
|
|
||||||
CHECK_DISPLAY_MAGIC(display, NULL);
|
CHECK_DISPLAY_MAGIC(display, NULL);
|
||||||
|
|
||||||
return &display->desktop_mode;
|
return SDL_CreateTemporaryDisplayMode(&display->desktop_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL_SetCurrentDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
|
void SDL_SetCurrentDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
|
||||||
@@ -1379,11 +1406,9 @@ const SDL_DisplayMode *SDL_GetCurrentDisplayMode(SDL_DisplayID displayID)
|
|||||||
CHECK_DISPLAY_MAGIC(display, NULL);
|
CHECK_DISPLAY_MAGIC(display, NULL);
|
||||||
|
|
||||||
/* Make sure our mode list is updated */
|
/* Make sure our mode list is updated */
|
||||||
if (display->num_fullscreen_modes == 0 && _this->GetDisplayModes) {
|
SDL_UpdateFullscreenDisplayModes(display);
|
||||||
_this->GetDisplayModes(_this, display);
|
|
||||||
}
|
|
||||||
|
|
||||||
return display->current_mode;
|
return SDL_CreateTemporaryDisplayMode(display->current_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_SetDisplayModeForDisplay(SDL_VideoDisplay *display, SDL_DisplayMode *mode)
|
int SDL_SetDisplayModeForDisplay(SDL_VideoDisplay *display, SDL_DisplayMode *mode)
|
||||||
@@ -1746,7 +1771,7 @@ int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_FullscreenOp fullscreen, SD
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fullscreen) {
|
if (fullscreen) {
|
||||||
mode = (SDL_DisplayMode *)SDL_GetWindowFullscreenMode(window);
|
mode = (SDL_DisplayMode *)SDL_GetWindowFullscreenModeInternal(window);
|
||||||
if (mode) {
|
if (mode) {
|
||||||
window->fullscreen_exclusive = SDL_TRUE;
|
window->fullscreen_exclusive = SDL_TRUE;
|
||||||
} else {
|
} else {
|
||||||
@@ -1989,14 +2014,14 @@ int SDL_SetWindowFullscreenMode(SDL_Window *window, const SDL_DisplayMode *mode)
|
|||||||
|
|
||||||
const SDL_DisplayMode *SDL_GetWindowFullscreenMode(SDL_Window *window)
|
const SDL_DisplayMode *SDL_GetWindowFullscreenMode(SDL_Window *window)
|
||||||
{
|
{
|
||||||
|
const SDL_DisplayMode *retval;
|
||||||
|
|
||||||
CHECK_WINDOW_MAGIC(window, NULL);
|
CHECK_WINDOW_MAGIC(window, NULL);
|
||||||
CHECK_WINDOW_NOT_POPUP(window, NULL);
|
CHECK_WINDOW_NOT_POPUP(window, NULL);
|
||||||
|
|
||||||
if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
retval = SDL_GetWindowFullscreenModeInternal(window);
|
||||||
return SDL_GetFullscreenModeMatch(&window->current_fullscreen_mode);
|
|
||||||
} else {
|
return SDL_CreateTemporaryDisplayMode(retval);
|
||||||
return SDL_GetFullscreenModeMatch(&window->requested_fullscreen_mode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const void *SDL_GetWindowICCProfile(SDL_Window *window, size_t *size)
|
const void *SDL_GetWindowICCProfile(SDL_Window *window, size_t *size)
|
||||||
@@ -3003,7 +3028,7 @@ int SDL_GetWindowSizeInPixels(SDL_Window *window, int *w, int *h)
|
|||||||
|
|
||||||
SDL_GetWindowSize(window, w, h);
|
SDL_GetWindowSize(window, w, h);
|
||||||
|
|
||||||
if (SDL_GetWindowFullscreenMode(window)) {
|
if (SDL_GetWindowFullscreenModeInternal(window)) {
|
||||||
mode = SDL_GetCurrentDisplayMode(displayID);
|
mode = SDL_GetCurrentDisplayMode(displayID);
|
||||||
} else {
|
} else {
|
||||||
mode = SDL_GetDesktopDisplayMode(displayID);
|
mode = SDL_GetDesktopDisplayMode(displayID);
|
||||||
|
|||||||
Reference in New Issue
Block a user