From f175e38666e2f21f5873e95ca52f5aa321e8d3bf Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Fri, 8 Jan 2021 22:17:04 +0100 Subject: Add: [Win32] Automatic zoom level suggestion for Win32 video driver. The zoom level suggestion is based on the DPI scaling set in Windows. We use 150% scaling as the threshold for 2X zoom and 300% scaling as the threshold for 4X zoom. --- src/video/win32_v.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ src/video/win32_v.h | 2 ++ 2 files changed, 42 insertions(+) diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp index c1b31d14a..68e6572ba 100644 --- a/src/video/win32_v.cpp +++ b/src/video/win32_v.cpp @@ -1316,3 +1316,43 @@ Dimension VideoDriver_Win32::GetScreenSize() const { return { static_cast(GetSystemMetrics(SM_CXSCREEN)), static_cast(GetSystemMetrics(SM_CYSCREEN)) }; } + +float VideoDriver_Win32::GetDPIScale() +{ + typedef UINT (WINAPI *PFNGETDPIFORWINDOW)(HWND hwnd); + typedef UINT (WINAPI *PFNGETDPIFORSYSTEM)(VOID); + typedef HRESULT (WINAPI *PFNGETDPIFORMONITOR)(HMONITOR hMonitor, int dpiType, UINT *dpiX, UINT *dpiY); + + static PFNGETDPIFORWINDOW _GetDpiForWindow = nullptr; + static PFNGETDPIFORSYSTEM _GetDpiForSystem = nullptr; + static PFNGETDPIFORMONITOR _GetDpiForMonitor = nullptr; + + static bool init_done = false; + if (!init_done) { + init_done = true; + + _GetDpiForWindow = (PFNGETDPIFORWINDOW)GetProcAddress(GetModuleHandle(_T("User32")), "GetDpiForWindow"); + _GetDpiForSystem = (PFNGETDPIFORSYSTEM)GetProcAddress(GetModuleHandle(_T("User32")), "GetDpiForSystem"); + _GetDpiForMonitor = (PFNGETDPIFORMONITOR)GetProcAddress(LoadLibrary(_T("Shcore.dll")), "GetDpiForMonitor"); + } + + UINT cur_dpi = 0; + + if (cur_dpi == 0 && _GetDpiForWindow != nullptr && _wnd.main_wnd != nullptr) { + /* Per window DPI is supported since Windows 10 Ver 1607. */ + cur_dpi = _GetDpiForWindow(_wnd.main_wnd); + } + if (cur_dpi == 0 && _GetDpiForMonitor != nullptr && _wnd.main_wnd != nullptr) { + /* Per monitor is supported since Windows 8.1. */ + UINT dpiX, dpiY; + if (SUCCEEDED(_GetDpiForMonitor(MonitorFromWindow(_wnd.main_wnd, MONITOR_DEFAULTTOPRIMARY), 0 /* MDT_EFFECTIVE_DPI */, &dpiX, &dpiY))) { + cur_dpi = dpiX; // X and Y are always identical. + } + } + if (cur_dpi == 0 && _GetDpiForSystem != nullptr) { + /* Fall back to system DPI. */ + cur_dpi = _GetDpiForSystem(); + } + + return cur_dpi > 0 ? cur_dpi / 96.0f : 1.0f; // Default Windows DPI value is 96. +} diff --git a/src/video/win32_v.h b/src/video/win32_v.h index ef02e132e..1849a9ebc 100644 --- a/src/video/win32_v.h +++ b/src/video/win32_v.h @@ -43,6 +43,8 @@ public: protected: Dimension GetScreenSize() const override; + + float GetDPIScale() override; }; /** The factory for Windows' video driver. */ -- cgit v1.2.3-54-g00ecf