summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2023-01-31 03:57:48 +0100
committerSven Gothel <[email protected]>2023-01-31 03:57:48 +0100
commitbebb7e9b078f6eaed478143ffbdeeece5ca0e037 (patch)
tree19eb9d743a7aa0ebc1128f314cd3fb535a344c9d
parente96aeb6e9acd2b1435f5fad244a1488e74a3a6d6 (diff)
GDIUtil: Add GetMonitor*() variants incl. PixelScale (Part-2, adding missing native header and code files)
Part-1 in commit e96aeb6e9acd2b1435f5fad244a1488e74a3a6d6
-rw-r--r--make/build-nativewindow.xml2
-rw-r--r--make/stub_includes/win32/WindowsSHC.h11
-rw-r--r--make/stub_includes/win32/WindowsUser.h12
-rw-r--r--src/nativewindow/native/win32/WindowsSHC.c73
-rw-r--r--src/nativewindow/native/win32/WindowsUser.c33
5 files changed, 131 insertions, 0 deletions
diff --git a/make/build-nativewindow.xml b/make/build-nativewindow.xml
index 37dfee998..594903155 100644
--- a/make/build-nativewindow.xml
+++ b/make/build-nativewindow.xml
@@ -869,7 +869,9 @@
<patternset id="c.src.files.windows">
<include name="${rootrel.generated.c}/Windows/GDI*.c"/>
<include name="${rootrel.src.c}/win32/GDImisc.c"/>
+ <include name="${rootrel.src.c}/win32/WindowsUser.c"/>
<include name="${rootrel.src.c}/win32/WindowsDWM.c"/>
+ <include name="${rootrel.src.c}/win32/WindowsSHC.c"/>
<include name="${rootrel.src.c}/NativewindowCommon.c"/>
<include name="${rootrel.src.c}/JVM_JNI8.c"/>
</patternset>
diff --git a/make/stub_includes/win32/WindowsSHC.h b/make/stub_includes/win32/WindowsSHC.h
new file mode 100644
index 000000000..f1338e8dd
--- /dev/null
+++ b/make/stub_includes/win32/WindowsSHC.h
@@ -0,0 +1,11 @@
+#include <windows.h>
+#include <stdint.h>
+
+#ifndef WIN_SHC_VERSION_X_X
+#define WIN_SHC_VERSION_X_X
+
+BOOL ShcIsExtensionAvailable();
+BOOL ShcGetMonitorPixelScale1(HMONITOR hmon, float *psXY);
+
+#endif /* WIN_SHC_VERSION_X_X */
+
diff --git a/make/stub_includes/win32/WindowsUser.h b/make/stub_includes/win32/WindowsUser.h
new file mode 100644
index 000000000..3e4a426c7
--- /dev/null
+++ b/make/stub_includes/win32/WindowsUser.h
@@ -0,0 +1,12 @@
+#include <windows.h>
+#include <stdint.h>
+
+#ifndef WIN_USER_VERSION_X_X
+#define WIN_USER_VERSION_X_X
+
+HMONITOR GetMonitorFromWindow(HWND hwnd);
+HMONITOR GetMonitorFromPoint(int x, int y);
+HMONITOR GetMonitorFromRect(int left, int top, int right, int bottom);
+
+#endif /* WIN_USER_VERSION_X_X */
+
diff --git a/src/nativewindow/native/win32/WindowsSHC.c b/src/nativewindow/native/win32/WindowsSHC.c
new file mode 100644
index 000000000..45cefb126
--- /dev/null
+++ b/src/nativewindow/native/win32/WindowsSHC.c
@@ -0,0 +1,73 @@
+
+#include <windows.h>
+#include "WindowsSHC.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+// #define VERBOSE_ON 1
+
+#ifdef VERBOSE_ON
+ #define DBG_PRINT(args...) fprintf(stderr, args);
+#else
+ #define DBG_PRINT(args...)
+#endif
+
+/* GetProcAddress doesn't exist in A/W variants under desktop Windows */
+#ifndef UNDER_CE
+#define GetProcAddressA GetProcAddress
+#endif
+
+typedef HRESULT(WINAPI *GetDpiForMonitorPROCADDR)(HMONITOR, int, UINT*, UINT*);
+#ifndef MDT_EFFECTIVE_DPI
+ #define MDT_EFFECTIVE_DPI 0
+#endif
+// See also SetProcessDpiAwareness(..) and SetThreadDpiAwarenessContext(..)
+
+#define INIT_CALLED_MASK 1 << 0
+#define INIT_HAS_SHC_EXT_MASK 1 << 1
+
+#define HAS_INIT(a) ( 0 != ( INIT_CALLED_MASK & (a) ) )
+#define HAS_SHC_EXT(a) ( 0 != ( INIT_HAS_SHC_EXT_MASK & (a) ) )
+
+static int _init = 0; // INIT_ bits, see above
+static GetDpiForMonitorPROCADDR _GetDpiForMonitor = NULL;
+
+static int initWindowsSHC() {
+ if( !HAS_INIT(_init) ) {
+ _init |= INIT_CALLED_MASK;
+ HANDLE hShcAPI = LoadLibrary(TEXT("shcore.dll"));
+ if (hShcAPI) {
+ _GetDpiForMonitor = (GetDpiForMonitorPROCADDR) GetProcAddressA (hShcAPI, "GetDpiForMonitor");
+ if(NULL != _GetDpiForMonitor ) {
+ _init |= INIT_HAS_SHC_EXT_MASK;
+ }
+ }
+ // FreeLibrary (hShcAPI);
+ DBG_PRINT("DWM - initWindowsSHC: hasSHC %d\n", HAS_SHC_EXT(_init));
+ }
+ return _init;
+}
+
+BOOL ShcIsExtensionAvailable() {
+ return HAS_SHC_EXT( initWindowsSHC() ) ? TRUE : FALSE;
+}
+
+BOOL ShcGetMonitorPixelScale1(HMONITOR hmon, float *psXY) {
+ psXY[0] = 0;
+ psXY[1] = 0;
+ if( !ShcIsExtensionAvailable() ) {
+ return FALSE;
+ }
+ if( NULL == hmon ) {
+ return FALSE;
+ }
+ UINT dpiX=0, dpiY=0;
+ if( S_OK != _GetDpiForMonitor(hmon, MDT_EFFECTIVE_DPI, &dpiX, &dpiY) ) {
+ return FALSE;
+ }
+ psXY[0] = (float)(dpiX) / 96.0f;
+ psXY[1] = (float)(dpiY) / 96.0f;
+ return TRUE;
+}
+
diff --git a/src/nativewindow/native/win32/WindowsUser.c b/src/nativewindow/native/win32/WindowsUser.c
new file mode 100644
index 000000000..43856ccb2
--- /dev/null
+++ b/src/nativewindow/native/win32/WindowsUser.c
@@ -0,0 +1,33 @@
+
+#include <windows.h>
+#include "WindowsUser.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+// #define VERBOSE_ON 1
+
+#ifdef VERBOSE_ON
+ #define DBG_PRINT(args...) fprintf(stderr, args);
+#else
+ #define DBG_PRINT(args...)
+#endif
+
+// MONITOR_DEFAULTTONULL 0x00000000
+// MONITOR_DEFAULTTOPRIMARY 0x00000001
+// MONITOR_DEFAULTTONEAREST 0x00000002
+
+HMONITOR GetMonitorFromWindow(HWND hwnd) {
+ return MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
+}
+
+HMONITOR GetMonitorFromPoint(int x, int y) {
+ POINT pt = { (LONG)x, (LONG)y };
+ return MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST);
+}
+
+HMONITOR GetMonitorFromRect(int left, int top, int right, int bottom) {
+ RECT rect = { (LONG)left, (LONG)top, (LONG)right, (LONG)bottom };
+ return MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST);
+}
+