From 4e16d65bb8b06c61c029e25984963cc1adfa02ac Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 4 Mar 2020 11:15:10 +0100 Subject: [PATCH] [util] Introduce common functions to set, get and restore display modes --- src/util/util_monitor.cpp | 62 +++++++++++++++++++++++++++++++++++++++ src/util/util_monitor.h | 34 +++++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/src/util/util_monitor.cpp b/src/util/util_monitor.cpp index b7769cf2..28767760 100644 --- a/src/util/util_monitor.cpp +++ b/src/util/util_monitor.cpp @@ -1,4 +1,5 @@ #include "util_monitor.h" +#include "util_string.h" #include "./log/log.h" @@ -9,6 +10,67 @@ namespace dxvk { } + BOOL SetMonitorDisplayMode( + HMONITOR hMonitor, + DEVMODEW* pMode) { + ::MONITORINFOEXW monInfo; + monInfo.cbSize = sizeof(monInfo); + + if (!::GetMonitorInfoW(hMonitor, reinterpret_cast(&monInfo))) { + Logger::err("Failed to query monitor info"); + return E_FAIL; + } + + Logger::info(str::format("Setting display mode: ", + pMode->dmPelsWidth, "x", pMode->dmPelsHeight, "@", + pMode->dmDisplayFrequency)); + + LONG status = ::ChangeDisplaySettingsExW(monInfo.szDevice, + pMode, nullptr, CDS_FULLSCREEN, nullptr); + + if (status != DISP_CHANGE_SUCCESSFUL) { + pMode->dmFields &= ~DM_DISPLAYFREQUENCY; + + status = ::ChangeDisplaySettingsExW(monInfo.szDevice, + pMode, nullptr, CDS_FULLSCREEN, nullptr); + } + + return status == DISP_CHANGE_SUCCESSFUL; + } + + + BOOL GetMonitorDisplayMode( + HMONITOR hMonitor, + DWORD modeNum, + DEVMODEW* pMode) { + ::MONITORINFOEXW monInfo; + monInfo.cbSize = sizeof(monInfo); + + if (!::GetMonitorInfoW(hMonitor, reinterpret_cast(&monInfo))) { + Logger::err("Failed to query monitor info"); + return false; + } + + return ::EnumDisplaySettingsW(monInfo.szDevice, modeNum, pMode); + } + + + BOOL RestoreMonitorDisplayMode( + HMONITOR hMonitor) { + DEVMODEW devMode = { }; + devMode.dmSize = sizeof(devMode); + + if (!GetMonitorDisplayMode(hMonitor, ENUM_REGISTRY_SETTINGS, &devMode)) + return false; + + Logger::info(str::format("Restoring display mode: ", + devMode.dmPelsWidth, "x", devMode.dmPelsHeight, "@", + devMode.dmDisplayFrequency)); + + return SetMonitorDisplayMode(hMonitor, &devMode); + } + + void GetWindowClientSize( HWND hWnd, UINT* pWidth, diff --git a/src/util/util_monitor.h b/src/util/util_monitor.h index 81d0a587..c89520a9 100644 --- a/src/util/util_monitor.h +++ b/src/util/util_monitor.h @@ -10,6 +10,40 @@ namespace dxvk { */ HMONITOR GetDefaultMonitor(); + /** + * \brief Sets monitor display mode + * + * Note that \c pMode may be altered by this function. + * \param [in] hMonitor The monitor to change + * \param [in] pMode The desired display mode + * \returns \c true on success + */ + BOOL SetMonitorDisplayMode( + HMONITOR hMonitor, + DEVMODEW* pMode); + + /** + * \brief Enumerates monitor display modes + * + * \param [in] hMonitor The monitor to query + * \param [in] modeNum Mode number or enum + * \param [in] pMode The display mode + * \returns \c true on success + */ + BOOL GetMonitorDisplayMode( + HMONITOR hMonitor, + DWORD modeNum, + DEVMODEW* pMode); + + /** + * \brief Change display mode to registry settings + * + * \param [in] hMonitor The monitor to change + * \returns \c true on success + */ + BOOL RestoreMonitorDisplayMode( + HMONITOR hMonitor); + /** * \brief Queries window client size *