aboutsummaryrefslogtreecommitdiffstats
path: root/src/win.c
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2022-05-21 21:28:08 -0400
committerDavid Robillard <d@drobilla.net>2022-05-21 22:03:22 -0400
commitfdd6de0d12ea17f713ec3e73e7968198339b7b6d (patch)
tree800b75e676f8320c2e22b3590751a63be3741fc5 /src/win.c
parenta88b470d9c954073fcfcfeca2242809532eaf048 (diff)
downloadpugl-fdd6de0d12ea17f713ec3e73e7968198339b7b6d.tar.gz
pugl-fdd6de0d12ea17f713ec3e73e7968198339b7b6d.tar.bz2
pugl-fdd6de0d12ea17f713ec3e73e7968198339b7b6d.zip
Add puglGetScaleFactor()
Diffstat (limited to 'src/win.c')
-rw-r--r--src/win.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/src/win.c b/src/win.c
index 8f2a26b..5e70b6f 100644
--- a/src/win.c
+++ b/src/win.c
@@ -35,6 +35,8 @@
#define PUGL_USER_TIMER_MIN 9470
typedef BOOL(WINAPI* PFN_SetProcessDPIAware)(void);
+typedef HRESULT(WINAPI* PFN_GetProcessDpiAwareness)(HANDLE, DWORD*);
+typedef HRESULT(WINAPI* PFN_GetScaleFactorForMonitor)(HMONITOR, DWORD*);
LRESULT CALLBACK
wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
@@ -112,6 +114,35 @@ puglWinGetWindowExFlags(const PuglView* const view)
return WS_EX_NOINHERITLAYOUT | (view->parent ? 0u : WS_EX_APPWINDOW);
}
+static double
+puglWinGetViewScaleFactor(const PuglView* const view)
+{
+ const HMODULE shcore = LoadLibrary("Shcore.dll");
+ if (!shcore) {
+ return 1.0;
+ }
+
+ const PFN_GetProcessDpiAwareness GetProcessDpiAwareness =
+ (PFN_GetProcessDpiAwareness)GetProcAddress(shcore,
+ "GetProcessDpiAwareness");
+
+ const PFN_GetScaleFactorForMonitor GetScaleFactorForMonitor =
+ (PFN_GetScaleFactorForMonitor)GetProcAddress(shcore,
+ "GetScaleFactorForMonitor");
+
+ DWORD dpiAware = 0;
+ DWORD scaleFactor = 100;
+ if (GetProcessDpiAwareness && GetScaleFactorForMonitor &&
+ !GetProcessDpiAwareness(NULL, &dpiAware) && dpiAware) {
+ GetScaleFactorForMonitor(
+ MonitorFromWindow(view->impl->hwnd, MONITOR_DEFAULTTOPRIMARY),
+ &scaleFactor);
+ }
+
+ FreeLibrary(shcore);
+ return (double)scaleFactor / 100.0;
+}
+
PuglWorldInternals*
puglInitWorldInternals(PuglWorldType type, PuglWorldFlags PUGL_UNUSED(flags))
{
@@ -214,7 +245,8 @@ puglRealize(PuglView* view)
puglSetWindowTitle(view, view->title);
}
- view->impl->cursor = LoadCursor(NULL, IDC_ARROW);
+ view->impl->scaleFactor = puglWinGetViewScaleFactor(view);
+ view->impl->cursor = LoadCursor(NULL, IDC_ARROW);
puglSetFrame(view, view->frame);
SetWindowLongPtr(impl->hwnd, GWLP_USERDATA, (LONG_PTR)view);
@@ -604,6 +636,9 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
InvalidateRect(view->impl->hwnd, NULL, false);
}
break;
+ case WM_DISPLAYCHANGE:
+ view->impl->scaleFactor = puglWinGetViewScaleFactor(view);
+ break;
case WM_WINDOWPOSCHANGED:
handleConfigure(view, &event);
break;
@@ -1002,6 +1037,12 @@ adjustedWindowRect(PuglView* const view,
return rect;
}
+double
+puglGetScaleFactor(const PuglView* const view)
+{
+ return view->impl->scaleFactor;
+}
+
PuglStatus
puglSetFrame(PuglView* view, const PuglRect frame)
{