From 4f4c4b629f4960183692467f8738a135779d43b5 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 29 Sep 2016 22:52:41 -0400 Subject: [PATCH] Added SDL_SetWindowResizable(). (thanks, Ethan!) --- include/SDL_video.h | 18 +++++++++++++ src/dynapi/SDL_dynapi_overrides.h | 1 + src/dynapi/SDL_dynapi_procs.h | 1 + src/video/SDL_sysvideo.h | 1 + src/video/SDL_video.c | 18 +++++++++++++ src/video/cocoa/SDL_cocoavideo.m | 1 + src/video/cocoa/SDL_cocoawindow.h | 1 + src/video/cocoa/SDL_cocoawindow.m | 14 ++++++++++ src/video/haiku/SDL_BWin.h | 16 +++++++++++ src/video/haiku/SDL_bvideo.cc | 1 + src/video/haiku/SDL_bwindow.cc | 6 +++++ src/video/haiku/SDL_bwindow.h | 1 + src/video/mir/SDL_mirvideo.c | 1 + src/video/windows/SDL_windowsvideo.c | 1 + src/video/windows/SDL_windowswindow.c | 16 +++++++++++ src/video/windows/SDL_windowswindow.h | 1 + src/video/x11/SDL_x11video.c | 1 + src/video/x11/SDL_x11window.c | 38 +++++++++++++++++++++++++++ src/video/x11/SDL_x11window.h | 1 + 19 files changed, 138 insertions(+) diff --git a/include/SDL_video.h b/include/SDL_video.h index 0e138a780ea6c..0d5c8adfed496 100644 --- a/include/SDL_video.h +++ b/include/SDL_video.h @@ -83,6 +83,7 @@ typedef struct * \sa SDL_SetWindowPosition() * \sa SDL_SetWindowSize() * \sa SDL_SetWindowBordered() + * \sa SDL_SetWindowResizable() * \sa SDL_SetWindowTitle() * \sa SDL_ShowWindow() */ @@ -706,6 +707,23 @@ extern DECLSPEC void SDLCALL SDL_GetWindowMaximumSize(SDL_Window * window, extern DECLSPEC void SDLCALL SDL_SetWindowBordered(SDL_Window * window, SDL_bool bordered); +/** + * \brief Set the user-resizable state of a window. + * + * This will add or remove the window's SDL_WINDOW_RESIZABLE flag and + * allow/disallow user resizing of the window. This is a no-op if the + * window's resizable state already matches the requested state. + * + * \param window The window of which to change the resizable state. + * \param resizable SDL_TRUE to allow resizing, SDL_FALSE to disallow. + * + * \note You can't change the resizable state of a fullscreen window. + * + * \sa SDL_GetWindowFlags() + */ +extern DECLSPEC void SDLCALL SDL_SetWindowResizable(SDL_Window * window, + SDL_bool resizable); + /** * \brief Show a window. * diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index dfde8e732ff99..8ae86b09b77b2 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -606,3 +606,4 @@ #define SDL_RenderSetIntegerScale SDL_RenderSetIntegerScale_REAL #define SDL_RenderGetIntegerScale SDL_RenderGetIntegerScale_REAL #define SDL_DequeueAudio SDL_DequeueAudio_REAL +#define SDL_SetWindowResizable SDL_SetWindowResizable_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index dabda3de81a04..b2df0620ba1f0 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -640,3 +640,4 @@ SDL_DYNAPI_PROC(int,SDL_SetWindowModalFor,(SDL_Window *a, SDL_Window *b),(a,b),r SDL_DYNAPI_PROC(int,SDL_RenderSetIntegerScale,(SDL_Renderer *a, SDL_bool b),(a,b),return) SDL_DYNAPI_PROC(SDL_bool,SDL_RenderGetIntegerScale,(SDL_Renderer *a),(a),return) SDL_DYNAPI_PROC(Uint32,SDL_DequeueAudio,(SDL_AudioDeviceID a, void *b, Uint32 c),(a,b,c),return) +SDL_DYNAPI_PROC(void,SDL_SetWindowResizable,(SDL_Window *a, SDL_bool b),(a,b),) diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 0b1133bdbd669..cd2ed2a7e21fc 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -219,6 +219,7 @@ struct SDL_VideoDevice void (*MinimizeWindow) (_THIS, SDL_Window * window); void (*RestoreWindow) (_THIS, SDL_Window * window); void (*SetWindowBordered) (_THIS, SDL_Window * window, SDL_bool bordered); + void (*SetWindowResizable) (_THIS, SDL_Window * window, SDL_bool resizable); void (*SetWindowFullscreen) (_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); int (*SetWindowGammaRamp) (_THIS, SDL_Window * window, const Uint16 * ramp); int (*GetWindowGammaRamp) (_THIS, SDL_Window * window, Uint16 * ramp); diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 499e40038f170..c768f6ad4632e 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -1841,6 +1841,24 @@ SDL_SetWindowBordered(SDL_Window * window, SDL_bool bordered) } } +void +SDL_SetWindowResizable(SDL_Window * window, SDL_bool resizable) +{ + CHECK_WINDOW_MAGIC(window,); + if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { + const int want = (resizable != SDL_FALSE); /* normalize the flag. */ + const int have = ((window->flags & SDL_WINDOW_RESIZABLE) != 0); + if ((want != have) && (_this->SetWindowResizable)) { + if (want) { + window->flags |= SDL_WINDOW_RESIZABLE; + } else { + window->flags &= ~SDL_WINDOW_RESIZABLE; + } + _this->SetWindowResizable(_this, window, (SDL_bool) want); + } + } +} + void SDL_SetWindowSize(SDL_Window * window, int w, int h) { diff --git a/src/video/cocoa/SDL_cocoavideo.m b/src/video/cocoa/SDL_cocoavideo.m index ddf10e263e82b..76d558e532c86 100644 --- a/src/video/cocoa/SDL_cocoavideo.m +++ b/src/video/cocoa/SDL_cocoavideo.m @@ -96,6 +96,7 @@ device->MinimizeWindow = Cocoa_MinimizeWindow; device->RestoreWindow = Cocoa_RestoreWindow; device->SetWindowBordered = Cocoa_SetWindowBordered; + device->SetWindowResizable = Cocoa_SetWindowResizable; device->SetWindowFullscreen = Cocoa_SetWindowFullscreen; device->SetWindowGammaRamp = Cocoa_SetWindowGammaRamp; device->GetWindowGammaRamp = Cocoa_GetWindowGammaRamp; diff --git a/src/video/cocoa/SDL_cocoawindow.h b/src/video/cocoa/SDL_cocoawindow.h index 4e2f7ea2b408a..a32de83877f63 100644 --- a/src/video/cocoa/SDL_cocoawindow.h +++ b/src/video/cocoa/SDL_cocoawindow.h @@ -133,6 +133,7 @@ extern void Cocoa_MaximizeWindow(_THIS, SDL_Window * window); extern void Cocoa_MinimizeWindow(_THIS, SDL_Window * window); extern void Cocoa_RestoreWindow(_THIS, SDL_Window * window); extern void Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); +extern void Cocoa_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable); extern void Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); extern int Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index 37f7b7fb8a9bc..25c98a902ba19 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -1492,6 +1492,20 @@ - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent } }} +void +Cocoa_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) +{ @autoreleasepool +{ + /* Don't set this if we're in a space! + * The window will get permanently stuck if resizable is false. + * -flibit + */ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Cocoa_WindowListener *listener = data->listener; + if (![listener isInFullscreenSpace]) { + SetWindowStyle(window, GetWindowStyle(window)); + } +}} void Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) diff --git a/src/video/haiku/SDL_BWin.h b/src/video/haiku/SDL_BWin.h index dade664c3be30..b3b94dc1d2841 100644 --- a/src/video/haiku/SDL_BWin.h +++ b/src/video/haiku/SDL_BWin.h @@ -56,6 +56,7 @@ enum WinCommands { BWIN_RESTORE_WINDOW, BWIN_SET_TITLE, BWIN_SET_BORDERED, + BWIN_SET_RESIZABLE, BWIN_FULLSCREEN }; @@ -378,6 +379,9 @@ class SDL_BWin:public BDirectWindow case BWIN_SET_BORDERED: _SetBordered(message); break; + case BWIN_SET_RESIZABLE: + _SetResizable(message); + break; case BWIN_SHOW_WINDOW: Show(); break; @@ -568,6 +572,18 @@ class SDL_BWin:public BDirectWindow SetLook(bEnabled ? B_BORDERED_WINDOW_LOOK : B_NO_BORDER_WINDOW_LOOK); } + void _SetResizable(BMessage *msg) { + bool bEnabled; + if(msg->FindBool("window-resizable", &bEnabled) != B_OK) { + return; + } + if (bEnabled) { + SetFlags(GetFlags() & ~(B_NOT_RESIZABLE | B_NOT_ZOOMABLE)); + } else { + SetFlags(GetFlags() | (B_NOT_RESIZABLE | B_NOT_ZOOMABLE)); + } + } + void _Restore() { if(IsMinimized()) { Minimize(false); diff --git a/src/video/haiku/SDL_bvideo.cc b/src/video/haiku/SDL_bvideo.cc index 8c243b7a04575..8986c609c7ad7 100644 --- a/src/video/haiku/SDL_bvideo.cc +++ b/src/video/haiku/SDL_bvideo.cc @@ -81,6 +81,7 @@ BE_CreateDevice(int devindex) device->MinimizeWindow = BE_MinimizeWindow; device->RestoreWindow = BE_RestoreWindow; device->SetWindowBordered = BE_SetWindowBordered; + device->SetWindowResizable = BE_SetWindowResizable; device->SetWindowFullscreen = BE_SetWindowFullscreen; device->SetWindowGammaRamp = BE_SetWindowGammaRamp; device->GetWindowGammaRamp = BE_GetWindowGammaRamp; diff --git a/src/video/haiku/SDL_bwindow.cc b/src/video/haiku/SDL_bwindow.cc index 287eac9653635..a35471df5b4c2 100644 --- a/src/video/haiku/SDL_bwindow.cc +++ b/src/video/haiku/SDL_bwindow.cc @@ -145,6 +145,12 @@ void BE_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) { _ToBeWin(window)->PostMessage(&msg); } +void BE_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) { + BMessage msg(BWIN_SET_RESIZABLE); + msg.AddBool("window-resizable", resizable != SDL_FALSE); + _ToBeWin(window)->PostMessage(&msg); +} + void BE_ShowWindow(_THIS, SDL_Window * window) { BMessage msg(BWIN_SHOW_WINDOW); _ToBeWin(window)->PostMessage(&msg); diff --git a/src/video/haiku/SDL_bwindow.h b/src/video/haiku/SDL_bwindow.h index f64530ab7b579..388443dac5484 100644 --- a/src/video/haiku/SDL_bwindow.h +++ b/src/video/haiku/SDL_bwindow.h @@ -39,6 +39,7 @@ extern void BE_MaximizeWindow(_THIS, SDL_Window * window); extern void BE_MinimizeWindow(_THIS, SDL_Window * window); extern void BE_RestoreWindow(_THIS, SDL_Window * window); extern void BE_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); +extern void BE_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable); extern void BE_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int BE_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); extern int BE_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); diff --git a/src/video/mir/SDL_mirvideo.c b/src/video/mir/SDL_mirvideo.c index 886cee7fdd0c9..6a8f9e4824b79 100644 --- a/src/video/mir/SDL_mirvideo.c +++ b/src/video/mir/SDL_mirvideo.c @@ -186,6 +186,7 @@ MIR_CreateDevice(int device_index) device->SetWindowIcon = NULL; device->RaiseWindow = NULL; device->SetWindowBordered = NULL; + device->SetWindowResizable = NULL; device->OnWindowEnter = NULL; device->SetWindowPosition = NULL; diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c index 41100fbdafd22..21f63a018fc0b 100644 --- a/src/video/windows/SDL_windowsvideo.c +++ b/src/video/windows/SDL_windowsvideo.c @@ -145,6 +145,7 @@ WIN_CreateDevice(int devindex) device->MinimizeWindow = WIN_MinimizeWindow; device->RestoreWindow = WIN_RestoreWindow; device->SetWindowBordered = WIN_SetWindowBordered; + device->SetWindowResizable = WIN_SetWindowResizable; device->SetWindowFullscreen = WIN_SetWindowFullscreen; device->SetWindowGammaRamp = WIN_SetWindowGammaRamp; device->GetWindowGammaRamp = WIN_GetWindowGammaRamp; diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index b8f24db8a116b..fe52a54778ee1 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -519,6 +519,22 @@ WIN_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) data->in_border_change = SDL_FALSE; } +void +WIN_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + HWND hwnd = data->hwnd; + DWORD style = GetWindowLong(hwnd, GWL_STYLE); + + if (resizable) { + style |= STYLE_RESIZABLE; + } else { + style &= ~STYLE_RESIZABLE; + } + + SetWindowLong(hwnd, GWL_STYLE, style); +} + void WIN_RestoreWindow(_THIS, SDL_Window * window) { diff --git a/src/video/windows/SDL_windowswindow.h b/src/video/windows/SDL_windowswindow.h index 0f6a87e347f99..7d50ba66e8b2d 100644 --- a/src/video/windows/SDL_windowswindow.h +++ b/src/video/windows/SDL_windowswindow.h @@ -64,6 +64,7 @@ extern void WIN_MaximizeWindow(_THIS, SDL_Window * window); extern void WIN_MinimizeWindow(_THIS, SDL_Window * window); extern void WIN_RestoreWindow(_THIS, SDL_Window * window); extern void WIN_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); +extern void WIN_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable); extern void WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); extern int WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index b2136daf293bd..4be6b3797e054 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -243,6 +243,7 @@ X11_CreateDevice(int devindex) device->MinimizeWindow = X11_MinimizeWindow; device->RestoreWindow = X11_RestoreWindow; device->SetWindowBordered = X11_SetWindowBordered; + device->SetWindowResizable = X11_SetWindowResizable; device->SetWindowFullscreen = X11_SetWindowFullscreen; device->SetWindowGammaRamp = X11_SetWindowGammaRamp; device->SetWindowGrab = X11_SetWindowGrab; diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index 8659961d198d7..db10a89479628 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -981,6 +981,44 @@ X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) X11_XCheckIfEvent(display, &event, &isMapNotify, (XPointer)&data->xwindow); } +void +X11_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + + XSizeHints *sizehints = X11_XAllocSizeHints(); + long userhints; + + X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints); + + if (resizable) { + /* FIXME: Is there a better way to get max window size from X? -flibit */ + const int maxsize = 0x7FFFFFFF; + sizehints->min_width = window->min_w; + sizehints->min_height = window->min_h; + sizehints->max_width = (window->max_w == 0) ? maxsize : window->max_w; + sizehints->max_height = (window->max_h == 0) ? maxsize : window->max_h; + } else { + sizehints->min_width = window->w; + sizehints->min_height = window->h; + sizehints->max_width = window->w; + sizehints->max_height = window->h; + } + sizehints->flags |= PMinSize | PMaxSize; + + X11_XSetWMNormalHints(display, data->xwindow, sizehints); + + X11_XFree(sizehints); + + /* See comment in X11_SetWindowSize. */ + X11_XResizeWindow(display, data->xwindow, window->w, window->h); + X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top); + X11_XRaiseWindow(display, data->xwindow); + + X11_XFlush(display); +} + void X11_ShowWindow(_THIS, SDL_Window * window) { diff --git a/src/video/x11/SDL_x11window.h b/src/video/x11/SDL_x11window.h index 5c5f7d53690a9..50a739dad9fee 100644 --- a/src/video/x11/SDL_x11window.h +++ b/src/video/x11/SDL_x11window.h @@ -96,6 +96,7 @@ extern void X11_MaximizeWindow(_THIS, SDL_Window * window); extern void X11_MinimizeWindow(_THIS, SDL_Window * window); extern void X11_RestoreWindow(_THIS, SDL_Window * window); extern void X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); +extern void X11_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable); extern void X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); extern void X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);