From 304e345a79e117477fa13117156a889795eeadc9 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 5 Dec 2020 18:19:52 +0100 Subject: [PATCH] Platform/Win32/Win32Display: Implementing true fullscreen with enterFullscreen() and exitFullscreen() --- source/Platform/Win32/Win32Display.cpp | 88 +++++++++++++++++++++++++- source/Platform/Win32/Win32Display.h | 7 ++ 2 files changed, 92 insertions(+), 3 deletions(-) diff --git a/source/Platform/Win32/Win32Display.cpp b/source/Platform/Win32/Win32Display.cpp index c38004c..18e50e6 100644 --- a/source/Platform/Win32/Win32Display.cpp +++ b/source/Platform/Win32/Win32Display.cpp @@ -36,7 +36,7 @@ Win32Display::~Win32Display() bool Win32Display::create(DisplayDescription description) { - DWORD flags = getWin32Flags(description.decoration); + DWORD flags; Vector2i pos; if (firstTime) { @@ -44,7 +44,18 @@ bool Win32Display::create(DisplayDescription description) firstTime = false; } - pos = centerWindow(description.mode.width, description.mode.height); + if (description.decoration & DisplayDecorate::Fullscreen) { + m_fs_mode = description.mode; + } + + if (m_fs_mode.empty() == false) { + // Only set these flags for fullscreen (borderless) + flags = WS_VISIBLE | WS_POPUP; + } else { + // Set window to center and set decorator flags for windowed displays. + pos = centerWindow(description.mode.width, description.mode.height); + flags = getWin32Flags(description.decoration); + } // Create window. m_handle = CreateWindowExA(0, WND_CLASSNAME, "", flags, @@ -56,7 +67,11 @@ bool Win32Display::create(DisplayDescription description) return false; } - setSize(description.mode.width, description.mode.height); + if (m_fs_mode.empty() == false) { + enterFullscreen(m_fs_mode); + } else { + setSize(description.mode.width, description.mode.height); + } // Store the size for use later. m_size = getSize(); @@ -277,6 +292,60 @@ Vector2i Win32Display::centerWindow(int width, int height) return v; } +void Win32Display::enterFullscreen(DisplayMode mode) +{ + LONG rc; + ::DEVMODEW dev; + dev.dmSize = sizeof(dev); + dev.dmPelsWidth = mode.width; + dev.dmPelsHeight = mode.height; + dev.dmBitsPerPel = mode.bpp; + dev.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL; + + rc = ::ChangeDisplaySettingsW(&dev, CDS_FULLSCREEN); + if (rc != DISP_CHANGE_SUCCESSFUL) { + const char *msg; + + switch(rc) { + case DISP_CHANGE_BADDUALVIEW : + msg = "The system is DualView capable"; break; + case DISP_CHANGE_BADFLAGS : + msg = "Invalid flags given"; break; + case DISP_CHANGE_BADPARAM : + msg = "Invalid parameter"; break; + case DISP_CHANGE_BADMODE : + msg = "Resolution not supported"; break; + case DISP_CHANGE_FAILED : + msg = "Display driver failed to set mode"; break; + case DISP_CHANGE_NOTUPDATED : + msg = "Unable to write settings to the registry"; break; + case DISP_CHANGE_RESTART : + msg = "System restart required"; break; + default : + msg = "Unkown error"; + } + + sp::Log::error("Win32: Failed to switch to fullscreen mode: %s.", msg); + return; + } + + ::SetWindowLong(m_handle, GWL_STYLE, WS_VISIBLE | WS_POPUP); + ::SetWindowPos(m_handle, HWND_TOP, 0, 0, mode.width, mode.height, SWP_FRAMECHANGED | SWP_SHOWWINDOW); + + grabCursor(true); + + m_fs_mode = mode; +} + +void Win32Display::exitFullscreen() +{ + if (!m_fs_mode.empty()) { + // Restore to previous mode. + ::ChangeDisplaySettingsW(NULL, 0); + m_fs_mode = DisplayMode(); + } +} + void Win32Display::processResizeMessage(const Vector2u& new_size) { // Check if the size has actually changed. @@ -301,9 +370,22 @@ void Win32Display::processMessage(UINT message, WPARAM wParam, LPARAM lParam) break; case WM_SETFOCUS : Log::debug("WM_SETFOCUS"); + if (m_fs_mode.empty() == false) { + enterFullscreen(m_fs_mode); + } break; case WM_KILLFOCUS : Log::debug("WM_KILLFOCUS"); + // If in fullscreen mode. + if (m_fs_mode.empty() == false) { + // Switch to window mode. + ::ChangeDisplaySettingsW(NULL, 0); + + // also minimize the window to get it out of the way. + minimize(); + } + + grabCursor(false); break; case WM_SIZE : diff --git a/source/Platform/Win32/Win32Display.h b/source/Platform/Win32/Win32Display.h index ccdaecc..510c275 100644 --- a/source/Platform/Win32/Win32Display.h +++ b/source/Platform/Win32/Win32Display.h @@ -35,6 +35,10 @@ public : virtual void setDecoration(unsigned decoration); + virtual void enterFullscreen(DisplayMode mode); + + virtual void exitFullscreen(); + virtual void minimize(); virtual void maximize(); @@ -76,6 +80,9 @@ protected : Vector2u m_size; Vector2u m_minSize; + + // Fullscreen mode. + DisplayMode m_fs_mode; }; } // namespace sp