diff --git a/src/posix/sdl/gl_sysfb.h b/src/posix/sdl/gl_sysfb.h index 6972dd4492..c9c1e81927 100644 --- a/src/posix/sdl/gl_sysfb.h +++ b/src/posix/sdl/gl_sysfb.h @@ -26,8 +26,10 @@ public: int GetClientWidth() override; int GetClientHeight() override; void ToggleFullscreen(bool yes) override; + void SetWindowSize(int client_w, int client_h); SDL_Window *GetSDLWindow() { return Screen; } + void GetWindowBordersSize(int &top, int &left); protected: void SetGammaTable(uint16_t *tbl); @@ -45,6 +47,14 @@ protected: Uint16 m_origGamma[3][256]; bool m_supportsGamma; + + static const int MIN_WIDTH = 320; + static const int MIN_HEIGHT = 200; + + typedef DECLSPEC int SDLCALL (*SDL_GetWindowBordersSizePtr)(SDL_Window *, int *, int *, int *, int *); + + SDL_GetWindowBordersSizePtr SDL_GetWindowBordersSize_; + void *sdl_lib; }; #endif // __POSIX_SDL_GL_SYSFB_H__ diff --git a/src/posix/sdl/sdlglvideo.cpp b/src/posix/sdl/sdlglvideo.cpp index df5e51c611..7eb389ae1c 100644 --- a/src/posix/sdl/sdlglvideo.cpp +++ b/src/posix/sdl/sdlglvideo.cpp @@ -88,6 +88,7 @@ CVAR(Int, win_x, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Int, win_y, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Int, win_w, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Int, win_h, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CVAR(Bool, win_maximized, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) CVAR(Bool, i_soundinbackground, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) @@ -181,6 +182,15 @@ IVideo *gl_CreateVideo() SystemGLFrameBuffer::SystemGLFrameBuffer (void *, bool fullscreen) : DFrameBuffer (vid_defwidth, vid_defheight) { + // SDL_GetWindowBorderSize() is only available since 2.0.5, but because + // GZDoom supports platforms with older SDL2 versions, this function + // has to be dynamically loaded + sdl_lib = SDL_LoadObject("libSDL2.so"); + if (sdl_lib != nullptr) + { + SDL_GetWindowBordersSize_ = (SDL_GetWindowBordersSizePtr)SDL_LoadFunction(sdl_lib,"SDL_GetWindowBordersSize"); + } + // NOTE: Core profiles were added with GL 3.2, so there's no sense trying // to set core 3.1 or 3.0. We could try a forward-compatible context // instead, but that would be too restrictive (w.r.t. shaders). @@ -227,6 +237,9 @@ SystemGLFrameBuffer::SystemGLFrameBuffer (void *, bool fullscreen) ); if (Screen != NULL) { + // enforce minimum size limit + SDL_SetWindowMinimumSize(Screen, MIN_WIDTH, MIN_HEIGHT); + GLContext = SDL_GL_CreateContext(Screen); if (GLContext != NULL) { @@ -236,15 +249,16 @@ SystemGLFrameBuffer::SystemGLFrameBuffer (void *, bool fullscreen) if (!fullscreen) { + if (win_w >= MIN_WIDTH && win_h >= MIN_HEIGHT) + { + SDL_SetWindowSize(Screen, win_w, win_h); + } + if (win_x >= 0 && win_y >= 0) { SDL_SetWindowPosition(Screen, win_x, win_y); } - if (win_h > 320 && win_w > 200) - { - SDL_SetWindowSize(Screen, win_w, win_h); - } } return; @@ -258,6 +272,11 @@ SystemGLFrameBuffer::SystemGLFrameBuffer (void *, bool fullscreen) SystemGLFrameBuffer::~SystemGLFrameBuffer () { + if (sdl_lib != nullptr) + { + SDL_UnloadObject(sdl_lib); + } + if (Screen) { ResetGammaTable(); @@ -326,6 +345,11 @@ void SystemGLFrameBuffer::SwapBuffers() void SystemGLFrameBuffer::ToggleFullscreen(bool yes) { SDL_SetWindowFullscreen(Screen, yes ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); + if ( !yes ) + { + fullscreen = false; + SetWindowSize(win_w, win_h); + } } int SystemGLFrameBuffer::GetClientWidth() @@ -342,6 +366,39 @@ int SystemGLFrameBuffer::GetClientHeight() return height; } +void SystemGLFrameBuffer::SetWindowSize(int w, int h) +{ + if (w < MIN_WIDTH || h < MIN_HEIGHT) + { + w = MIN_WIDTH; + h = MIN_HEIGHT; + } + win_w = w; + win_h = h; + if ( fullscreen ) + { + fullscreen = false; + } + else + { + win_maximized = false; + SDL_SetWindowSize(Screen, w, h); + SDL_SetWindowPosition(Screen, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); + SetSize(GetClientWidth(), GetClientHeight()); + int x, y; + SDL_GetWindowPosition(Screen, &x, &y); + win_x = x; + win_y = y; + } +} + +void SystemGLFrameBuffer::GetWindowBordersSize(int &top, int &left) +{ + if (SDL_GetWindowBordersSize_ != nullptr) + { + SDL_GetWindowBordersSize_(Screen, &top, &left, nullptr, nullptr); + } +} void ProcessSDLWindowEvent(const SDL_WindowEvent &event) { @@ -362,8 +419,10 @@ void ProcessSDLWindowEvent(const SDL_WindowEvent &event) case SDL_WINDOWEVENT_MOVED: if (!fullscreen) { - win_x = event.data1; - win_y = event.data2; + int top = 0, left = 0; + static_cast(screen)->GetWindowBordersSize(top,left); + win_x = event.data1-left; + win_y = event.data2-top; } break; @@ -374,6 +433,14 @@ void ProcessSDLWindowEvent(const SDL_WindowEvent &event) win_h = event.data2; } break; + + case SDL_WINDOWEVENT_MAXIMIZED: + win_maximized = true; + break; + + case SDL_WINDOWEVENT_RESTORED: + win_maximized = false; + break; } } @@ -391,3 +458,4 @@ void I_SetWindowTitle(const char* caption) SDL_SetWindowTitle(window, default_caption); } } +