From 1a92f1838155e519b30915429631201092e73132 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 31 Dec 2012 12:15:25 -0800 Subject: [PATCH] Added SDL_SetWindowMaximumSize() and SDL_GetWindowMaximumSize() Also fixed Cocoa implementation so that it affects client area, not the whole window area. --- include/SDL_test_common.h | 4 +++ include/SDL_video.h | 23 ++++++++++++++ src/test/SDL_test_common.c | 46 ++++++++++++++++++++++++++- src/video/SDL_sysvideo.h | 2 ++ src/video/SDL_video.c | 39 +++++++++++++++++++++++ src/video/cocoa/SDL_cocoamodes.m | 4 +-- src/video/cocoa/SDL_cocoavideo.m | 1 + src/video/cocoa/SDL_cocoawindow.h | 1 + src/video/cocoa/SDL_cocoawindow.m | 17 +++++++++- src/video/windows/SDL_windowsevents.c | 6 ++++ test/testwm2.c | 9 ++++++ 11 files changed, 148 insertions(+), 4 deletions(-) diff --git a/include/SDL_test_common.h b/include/SDL_test_common.h index 5ccb1bf3f..91ff45678 100644 --- a/include/SDL_test_common.h +++ b/include/SDL_test_common.h @@ -65,6 +65,10 @@ typedef struct int window_y; int window_w; int window_h; + int window_minW; + int window_minH; + int window_maxW; + int window_maxH; int depth; int refresh_rate; int num_windows; diff --git a/include/SDL_video.h b/include/SDL_video.h index a625275ed..361e05134 100644 --- a/include/SDL_video.h +++ b/include/SDL_video.h @@ -535,6 +535,7 @@ extern DECLSPEC void SDLCALL SDL_GetWindowSize(SDL_Window * window, int *w, * automatically matches the size of the display mode. * * \sa SDL_GetWindowMinimumSize() + * \sa SDL_SetWindowMaximumSize() */ extern DECLSPEC void SDLCALL SDL_SetWindowMinimumSize(SDL_Window * window, int min_w, int min_h); @@ -542,11 +543,33 @@ extern DECLSPEC void SDLCALL SDL_SetWindowMinimumSize(SDL_Window * window, /** * \brief Get the minimum size of a window's client area. * + * \sa SDL_GetWindowMaximumSize() * \sa SDL_SetWindowMinimumSize() */ extern DECLSPEC void SDLCALL SDL_GetWindowMinimumSize(SDL_Window * window, int *w, int *h); +/** + * \brief Set the maximum size of a window's client area. + * + * \note You can't change the maximum size of a fullscreen window, it + * automatically matches the size of the display mode. + * + * \sa SDL_GetWindowMaximumSize() + * \sa SDL_SetWindowMinimumSize() + */ +extern DECLSPEC void SDLCALL SDL_SetWindowMaximumSize(SDL_Window * window, + int max_w, int max_h); + +/** + * \brief Get the maximum size of a window's client area. + * + * \sa SDL_GetWindowMinimumSize() + * \sa SDL_SetWindowMaximumSize() + */ +extern DECLSPEC void SDLCALL SDL_GetWindowMaximumSize(SDL_Window * window, + int *w, int *h); + /** * \brief Set the border state of a window. * diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c index 6be4e0fb2..e7ac9435b 100644 --- a/src/test/SDL_test_common.c +++ b/src/test/SDL_test_common.c @@ -27,7 +27,7 @@ #include #define VIDEO_USAGE \ -"[--video driver] [--renderer driver] [--info all|video|modes|render|event] [--log all|error|system|audio|video|render|input] [--display N] [--fullscreen | --fullscreen-desktop | --windows N] [--title title] [--icon icon.bmp] [--center | --position X,Y] [--geometry WxH] [--depth N] [--refresh R] [--vsync] [--noframe] [--resize] [--minimize] [--maximize] [--grab]" +"[--video driver] [--renderer driver] [--info all|video|modes|render|event] [--log all|error|system|audio|video|render|input] [--display N] [--fullscreen | --fullscreen-desktop | --windows N] [--title title] [--icon icon.bmp] [--center | --position X,Y] [--geometry WxH] [--min-geometry WxH] [--max-geometry WxH] [--depth N] [--refresh R] [--vsync] [--noframe] [--resize] [--minimize] [--maximize] [--grab]" #define AUDIO_USAGE \ "[--rate N] [--format U8|S8|U16|U16LE|U16BE|S16|S16LE|S16BE] [--channels N] [--samples N]" @@ -266,6 +266,44 @@ SDLTest_CommonArg(SDLTest_CommonState * state, int index) state->window_h = SDL_atoi(h); return 2; } + if (SDL_strcasecmp(argv[index], "--min-geometry") == 0) { + char *w, *h; + ++index; + if (!argv[index]) { + return -1; + } + w = argv[index]; + h = argv[index]; + while (*h && *h != 'x') { + ++h; + } + if (!*h) { + return -1; + } + *h++ = '\0'; + state->window_minW = SDL_atoi(w); + state->window_minH = SDL_atoi(h); + return 2; + } + if (SDL_strcasecmp(argv[index], "--max-geometry") == 0) { + char *w, *h; + ++index; + if (!argv[index]) { + return -1; + } + w = argv[index]; + h = argv[index]; + while (*h && *h != 'x') { + ++h; + } + if (!*h) { + return -1; + } + *h++ = '\0'; + state->window_maxW = SDL_atoi(w); + state->window_maxH = SDL_atoi(h); + return 2; + } if (SDL_strcasecmp(argv[index], "--depth") == 0) { ++index; if (!argv[index]) { @@ -751,6 +789,12 @@ SDLTest_CommonInit(SDLTest_CommonState * state) SDL_GetError()); return SDL_FALSE; } + if (state->window_minW || state->window_minH) { + SDL_SetWindowMinimumSize(state->windows[i], state->window_minW, state->window_minH); + } + if (state->window_maxW || state->window_maxH) { + SDL_SetWindowMaximumSize(state->windows[i], state->window_maxW, state->window_maxH); + } SDL_GetWindowSize(state->windows[i], &w, &h); if (!(state->window_flags & SDL_WINDOW_RESIZABLE) && (w != state->window_w || h != state->window_h)) { diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 4827cf4fd..36e642ba4 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -75,6 +75,7 @@ struct SDL_Window int x, y; int w, h; int min_w, min_h; + int max_w, max_h; Uint32 flags; /* Stored position and size for windowed mode */ @@ -184,6 +185,7 @@ struct SDL_VideoDevice void (*SetWindowPosition) (_THIS, SDL_Window * window); void (*SetWindowSize) (_THIS, SDL_Window * window); void (*SetWindowMinimumSize) (_THIS, SDL_Window * window); + void (*SetWindowMaximumSize) (_THIS, SDL_Window * window); void (*ShowWindow) (_THIS, SDL_Window * window); void (*HideWindow) (_THIS, SDL_Window * window); void (*RaiseWindow) (_THIS, SDL_Window * window); diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index dfa63d09a..a8590bea2 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -1640,6 +1640,45 @@ SDL_GetWindowMinimumSize(SDL_Window * window, int *min_w, int *min_h) } } +void +SDL_SetWindowMaximumSize(SDL_Window * window, int max_w, int max_h) +{ + CHECK_WINDOW_MAGIC(window, ); + + if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { + window->max_w = max_w; + window->max_h = max_h; + if (_this->SetWindowMaximumSize) { + _this->SetWindowMaximumSize(_this, window); + } + /* Ensure that window is not larger than maximal size */ + SDL_SetWindowSize(window, SDL_min(window->w, window->max_w), SDL_min(window->h, window->max_h)); + } +} + +void +SDL_GetWindowMaximumSize(SDL_Window * window, int *max_w, int *max_h) +{ + int dummy; + + if (!max_w) { + max_w = &dummy; + } + if (!max_h) { + max_h = &dummy; + } + + *max_w = 0; + *max_h = 0; + + CHECK_WINDOW_MAGIC(window, ); + + if (_this && window && window->magic == &_this->window_magic) { + *max_w = window->max_w; + *max_h = window->max_h; + } +} + void SDL_ShowWindow(SDL_Window * window) { diff --git a/src/video/cocoa/SDL_cocoamodes.m b/src/video/cocoa/SDL_cocoamodes.m index 2459b494c..0c87e78bf 100644 --- a/src/video/cocoa/SDL_cocoamodes.m +++ b/src/video/cocoa/SDL_cocoamodes.m @@ -220,7 +220,7 @@ Cocoa_ReleaseDisplayModeList(_THIS, CFArrayRef modelist) #endif } -static char * +static const char * Cocoa_GetDisplayName(CGDirectDisplayID displayID) { NSDictionary *deviceInfo = (NSDictionary *)IODisplayCreateInfoDictionary(CGDisplayIOServicePort(displayID), kIODisplayOnlyPreferredName); @@ -299,7 +299,7 @@ Cocoa_InitModes(_THIS) displaydata->display = displays[i]; SDL_zero(display); - display.name = Cocoa_GetDisplayName(displays[i]); + display.name = (char *)Cocoa_GetDisplayName(displays[i]); if (!GetDisplayMode (_this, moderef, &mode)) { Cocoa_ReleaseDisplayMode(_this, moderef); SDL_free(displaydata); diff --git a/src/video/cocoa/SDL_cocoavideo.m b/src/video/cocoa/SDL_cocoavideo.m index aa832bdad..72de695f8 100644 --- a/src/video/cocoa/SDL_cocoavideo.m +++ b/src/video/cocoa/SDL_cocoavideo.m @@ -96,6 +96,7 @@ Cocoa_CreateDevice(int devindex) device->SetWindowPosition = Cocoa_SetWindowPosition; device->SetWindowSize = Cocoa_SetWindowSize; device->SetWindowMinimumSize = Cocoa_SetWindowMinimumSize; + device->SetWindowMaximumSize = Cocoa_SetWindowMaximumSize; device->ShowWindow = Cocoa_ShowWindow; device->HideWindow = Cocoa_HideWindow; device->RaiseWindow = Cocoa_RaiseWindow; diff --git a/src/video/cocoa/SDL_cocoawindow.h b/src/video/cocoa/SDL_cocoawindow.h index 9c8149ef5..ec4d28444 100644 --- a/src/video/cocoa/SDL_cocoawindow.h +++ b/src/video/cocoa/SDL_cocoawindow.h @@ -95,6 +95,7 @@ extern void Cocoa_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon); extern void Cocoa_SetWindowPosition(_THIS, SDL_Window * window); extern void Cocoa_SetWindowSize(_THIS, SDL_Window * window); extern void Cocoa_SetWindowMinimumSize(_THIS, SDL_Window * window); +extern void Cocoa_SetWindowMaximumSize(_THIS, SDL_Window * window); extern void Cocoa_ShowWindow(_THIS, SDL_Window * window); extern void Cocoa_HideWindow(_THIS, SDL_Window * window); extern void Cocoa_RaiseWindow(_THIS, SDL_Window * window); diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index f391bdf35..a7d201eda 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -740,7 +740,22 @@ Cocoa_SetWindowMinimumSize(_THIS, SDL_Window * window) minSize.width = window->min_w; minSize.height = window->min_h; - [windata->nswindow setMinSize:minSize]; + [windata->nswindow setContentMinSize:minSize]; + + [pool release]; +} + +void +Cocoa_SetWindowMaximumSize(_THIS, SDL_Window * window) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + SDL_WindowData *windata = (SDL_WindowData *) window->driverdata; + + NSSize maxSize; + maxSize.width = window->max_w; + maxSize.height = window->max_h; + + [windata->nswindow setContentMaxSize:maxSize]; [pool release]; } diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index 9cd2fb144..e63d7b51c 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -447,6 +447,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) int x, y; int w, h; int min_w, min_h; + int max_w, max_h; int style; BOOL menu; @@ -462,11 +463,14 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) /* Calculate current size of our window */ SDL_GetWindowSize(data->window, &w, &h); SDL_GetWindowMinimumSize(data->window, &min_w, &min_h); + SDL_GetWindowMaximumSize(data->window, &max_w, &max_h); /* Store in min_w and min_h difference between current size and minimal size so we don't need to call AdjustWindowRectEx twice */ min_w -= w; min_h -= h; + max_w -= w; + max_h -= h; size.top = 0; size.left = 0; @@ -489,6 +493,8 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) if (SDL_GetWindowFlags(data->window) & SDL_WINDOW_RESIZABLE) { info->ptMinTrackSize.x = w + min_w; info->ptMinTrackSize.y = h + min_h; + info->ptMaxTrackSize.x = w + max_w; + info->ptMaxTrackSize.y = h + max_h; } else { info->ptMaxSize.x = w; info->ptMaxSize.y = h; diff --git a/test/testwm2.c b/test/testwm2.c index 850b97a79..8f1897403 100644 --- a/test/testwm2.c +++ b/test/testwm2.c @@ -80,6 +80,15 @@ main(int argc, char *argv[]) SDLTest_CommonEvent(state, &event, &done); if (event.type == SDL_WINDOWEVENT) { + if (event.window.event == SDL_WINDOWEVENT_RESIZED) { + SDL_Window *window = SDL_GetWindowFromID(event.window.windowID); + if (window) { + printf("Window %d resized to %dx%d\n", + event.window.windowID, + event.window.data1, + event.window.data2); + } + } if (event.window.event == SDL_WINDOWEVENT_MOVED) { SDL_Window *window = SDL_GetWindowFromID(event.window.windowID); if (window) {