Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/ghost/intern')
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp6
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp78
-rw-r--r--intern/ghost/intern/GHOST_Window.h9
-rw-r--r--intern/ghost/intern/GHOST_WindowSDL.cpp16
-rw-r--r--intern/ghost/intern/GHOST_WindowSDL.h2
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp18
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h11
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp45
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.h2
9 files changed, 187 insertions, 0 deletions
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 41bc735e1e2..ce653188760 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -914,6 +914,12 @@ float GHOST_GetNativePixelSize(GHOST_WindowHandle windowhandle)
return 1.0f;
}
+GHOST_TUns16 GHOST_GetDPIHint(GHOST_WindowHandle windowhandle)
+{
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
+ return window->getDPIHint();
+}
+
#ifdef WITH_INPUT_IME
void GHOST_BeginIME(GHOST_WindowHandle windowhandle,
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 7d55a973f91..240d7ccd2fe 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -111,6 +111,11 @@
#define VK_MEDIA_PLAY_PAUSE 0xB3
#endif // VK_MEDIA_PLAY_PAUSE
+// Window message newer than Windows 7
+#ifndef WM_DPICHANGED
+#define WM_DPICHANGED 0x02E0
+#endif // WM_DPICHANGED
+
/* Workaround for some laptop touchpads, some of which seems to
* have driver issues which makes it so window function receives
* the message, but PeekMessage doesn't pick those messages for
@@ -152,6 +157,27 @@ static void initRawInput()
#undef DEVICE_COUNT
}
+#ifndef DPI_ENUMS_DECLARED
+typedef enum PROCESS_DPI_AWARENESS {
+ PROCESS_DPI_UNAWARE = 0,
+ PROCESS_SYSTEM_DPI_AWARE = 1,
+ PROCESS_PER_MONITOR_DPI_AWARE = 2
+} PROCESS_DPI_AWARENESS;
+
+typedef enum MONITOR_DPI_TYPE {
+ MDT_EFFECTIVE_DPI = 0,
+ MDT_ANGULAR_DPI = 1,
+ MDT_RAW_DPI = 2,
+ MDT_DEFAULT = MDT_EFFECTIVE_DPI
+} MONITOR_DPI_TYPE;
+
+#define USER_DEFAULT_SCREEN_DPI 96
+
+#define DPI_ENUMS_DECLARED
+#endif
+typedef HRESULT(API * GHOST_WIN32_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
+typedef BOOL(API * GHOST_WIN32_EnableNonClientDpiScaling)(HWND);
+
GHOST_SystemWin32::GHOST_SystemWin32()
: m_hasPerformanceCounter(false), m_freq(0), m_start(0)
{
@@ -161,6 +187,18 @@ GHOST_SystemWin32::GHOST_SystemWin32()
m_consoleStatus = 1;
+ // Tell Windows we are per monitor DPI aware. This disables the default
+ // blurry scaling and enables WM_DPICHANGED to allow us to draw at proper DPI.
+ HMODULE m_shcore = ::LoadLibrary("Shcore.dll");
+ if (m_shcore) {
+ GHOST_WIN32_SetProcessDpiAwareness fpSetProcessDpiAwareness =
+ (GHOST_WIN32_SetProcessDpiAwareness) ::GetProcAddress(m_shcore, "SetProcessDpiAwareness");
+
+ if (fpSetProcessDpiAwareness) {
+ fpSetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
+ }
+ }
+
// Check if current keyboard layout uses AltGr and save keylayout ID for
// specialized handling if keys like VK_OEM_*. I.e. french keylayout
// generates VK_OEM_8 for their exclamation key (key left of right shift)
@@ -922,6 +960,20 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
GHOST_ASSERT(system, "GHOST_SystemWin32::s_wndProc(): system not initialized");
if (hwnd) {
+ if(msg == WM_NCCREATE) {
+ // Tell Windows to automatically handle scaling of non-client areas
+ // such as the caption bar. EnableNonClientDpiScaling was introduced in Windows 10
+ HMODULE m_user32 = ::LoadLibrary("User32.dll");
+ if (m_user32) {
+ GHOST_WIN32_EnableNonClientDpiScaling fpEnableNonClientDpiScaling =
+ (GHOST_WIN32_EnableNonClientDpiScaling) ::GetProcAddress(m_user32, "EnableNonClientDpiScaling");
+
+ if (fpEnableNonClientDpiScaling) {
+ fpEnableNonClientDpiScaling(hwnd);
+ }
+ }
+ }
+
GHOST_WindowWin32 *window = (GHOST_WindowWin32 *)::GetWindowLongPtr(hwnd, GWLP_USERDATA);
if (window) {
switch (msg) {
@@ -1294,6 +1346,32 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
}
break;
+ case WM_DPICHANGED:
+ /* The WM_DPICHANGED message is sent when the effective dots per inch (dpi) for a window has changed.
+ * The DPI is the scale factor for a window. There are multiple events that can cause the DPI to
+ * change such as when the window is moved to a monitor with a different DPI.
+ */
+ {
+ WORD newYAxisDPI = HIWORD(wParam);
+ WORD newXAxisDPI = LOWORD(wParam);
+ // The suggested new size and position of the window.
+ RECT* const suggestedWindowRect = (RECT*)lParam;
+
+ // Push DPI change event first
+ system->pushEvent(processWindowEvent(GHOST_kEventWindowDPIHintChanged, window));
+ system->dispatchEvents();
+ eventHandled = true;
+
+ // Then move and resize window
+ SetWindowPos(hwnd,
+ NULL,
+ suggestedWindowRect->left,
+ suggestedWindowRect->top,
+ suggestedWindowRect->right - suggestedWindowRect->left,
+ suggestedWindowRect->bottom - suggestedWindowRect->top,
+ SWP_NOZORDER | SWP_NOACTIVATE);
+ }
+ break;
////////////////////////////////////////////////////////////////////////
// Window events, ignored
////////////////////////////////////////////////////////////////////////
diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h
index d778628ea37..2798bdf72f3 100644
--- a/intern/ghost/intern/GHOST_Window.h
+++ b/intern/ghost/intern/GHOST_Window.h
@@ -295,6 +295,15 @@ public:
return 1.0f;
}
+ /**
+ * Returns the recommended DPI for this window.
+ * \return The recommended DPI for this window.
+ */
+ virtual inline GHOST_TUns16 getDPIHint()
+ {
+ return 96;
+ }
+
#ifdef WITH_INPUT_IME
virtual void beginIME(GHOST_TInt32 x,
GHOST_TInt32 y,
diff --git a/intern/ghost/intern/GHOST_WindowSDL.cpp b/intern/ghost/intern/GHOST_WindowSDL.cpp
index 1335c38d977..aeb6188daef 100644
--- a/intern/ghost/intern/GHOST_WindowSDL.cpp
+++ b/intern/ghost/intern/GHOST_WindowSDL.cpp
@@ -563,3 +563,19 @@ GHOST_WindowSDL::setWindowCursorVisibility(bool visible)
SDL_ShowCursor(visible);
return GHOST_kSuccess;
}
+
+GHOST_TUns16
+GHOST_WindowSDL::getDPIHint()
+{
+ int displayIndex = SDL_GetWindowDisplayIndex(m_sdl_win);
+ if (displayIndex < 0) {
+ return 96;
+ }
+
+ float ddpi;
+ if (SDL_GetDisplayDPI(displayIndex, &ddpi, NULL, NULL) != 0) {
+ return 96;
+ }
+
+ return (int)ddpi;
+}
diff --git a/intern/ghost/intern/GHOST_WindowSDL.h b/intern/ghost/intern/GHOST_WindowSDL.h
index 5f658e8ad01..96104ec28b4 100644
--- a/intern/ghost/intern/GHOST_WindowSDL.h
+++ b/intern/ghost/intern/GHOST_WindowSDL.h
@@ -168,6 +168,8 @@ protected:
GHOST_TSuccess beginFullScreen() const { return GHOST_kFailure; }
GHOST_TSuccess endFullScreen() const { return GHOST_kFailure; }
+
+ GHOST_TUns16 getDPIHint();
};
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index 7d80aa43a40..fc46164c135 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -92,6 +92,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
m_tablet(0),
m_maxPressure(0),
m_normal_state(GHOST_kWindowStateNormal),
+ m_user32(NULL),
m_parentWindowHwnd(parentwindowhwnd),
m_debug_context(is_debug)
{
@@ -965,6 +966,23 @@ void GHOST_WindowWin32::bringTabletContextToFront()
}
}
+GHOST_TUns16 GHOST_WindowWin32::getDPIHint()
+{
+ if (!m_user32) {
+ m_user32 = ::LoadLibrary("user32.dll");
+ }
+
+ if (m_user32) {
+ GHOST_WIN32_GetDpiForWindow fpGetDpiForWindow = (GHOST_WIN32_GetDpiForWindow) ::GetProcAddress(m_user32, "GetDpiForWindow");
+
+ if (fpGetDpiForWindow) {
+ return fpGetDpiForWindow(this->m_hWnd);
+ }
+ }
+
+ return USER_DEFAULT_SCREEN_DPI;
+}
+
/** Reverse the bits in a GHOST_TUns8 */
static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch)
{
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index a1cf58c9ceb..75a33951ff4 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -58,6 +58,12 @@ typedef BOOL (API * GHOST_WIN32_WTClose)(HCTX);
typedef BOOL (API * GHOST_WIN32_WTPacket)(HCTX, UINT, LPVOID);
typedef BOOL (API * GHOST_WIN32_WTOverlap)(HCTX, BOOL);
+// typedefs for user32 functions to allow dynamic loading of Windows 10 DPI scaling functions
+typedef UINT(API * GHOST_WIN32_GetDpiForWindow)(HWND);
+#ifndef USER_DEFAULT_SCREEN_DPI
+#define USER_DEFAULT_SCREEN_DPI 96
+#endif // USER_DEFAULT_SCREEN_DPI
+
/**
* GHOST window on M$ Windows OSs.
* \author Maarten Gribnau
@@ -251,6 +257,8 @@ public:
GHOST_TSuccess endFullScreen() const {return GHOST_kFailure;}
+ GHOST_TUns16 getDPIHint() override;
+
/** if the window currently resizing */
bool m_inLiveResize;
@@ -351,6 +359,9 @@ private:
GHOST_TWindowState m_normal_state;
+ /** user32 dll handle*/
+ HMODULE m_user32;
+
/** Hwnd to parent window */
GHOST_TEmbedderWindowID m_parentWindowHwnd;
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index 47fbe1256b1..2019f58251f 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -56,6 +56,9 @@
# include <X11/extensions/XInput2.h>
#endif
+//For DPI value
+#include <X11/Xresource.h>
+
#if defined(__sun__) || defined(__sun) || defined(__sparc) || defined(__sparc__) || defined(_AIX)
# include <strings.h>
#endif
@@ -68,6 +71,7 @@
#include <algorithm>
#include <string>
+#include <math.h>
/* For obscure full screen mode stuff
* lifted verbatim from blut. */
@@ -1672,3 +1676,44 @@ endFullScreen() const
return GHOST_kSuccess;
}
+
+GHOST_TUns16
+GHOST_WindowX11::
+getDPIHint()
+{
+ /* Try to read DPI setting set using xrdb */
+ char* resMan = XResourceManagerString(m_display);
+ if (resMan) {
+ XrmDatabase xrdb = XrmGetStringDatabase(resMan);
+ if (xrdb) {
+ char* type = NULL;
+ XrmValue val;
+
+ int success = XrmGetResource(xrdb, "Xft.dpi", "Xft.Dpi", &type, &val);
+ if (success && type) {
+ if (strcmp(type, "String") == 0) {
+ return atoi((char*)val.addr);
+ }
+ }
+ }
+ }
+
+ /* Fallback to calculating DPI using X reported DPI, set using xrandr --dpi */
+ XWindowAttributes attr;
+ if (!XGetWindowAttributes(m_display, m_window, &attr)) {
+ /* Failed to get window attributes, return X11 default DPI */
+ return 96;
+ }
+
+ Screen* screen = attr.screen;
+ int pixelWidth = WidthOfScreen(screen);
+ int pixelHeight = HeightOfScreen(screen);
+ int mmWidth = WidthMMOfScreen(screen);
+ int mmHeight = HeightMMOfScreen(screen);
+
+ double pixelDiagonal = sqrt((pixelWidth * pixelWidth) + (pixelHeight * pixelHeight));
+ double mmDiagonal = sqrt((mmWidth * mmWidth) + (mmHeight * mmHeight));
+ float inchDiagonal = mmDiagonal * 0.039f;
+ int dpi = pixelDiagonal / inchDiagonal;
+ return dpi;
+}
diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h
index 9380aa9d631..5c54c1e8162 100644
--- a/intern/ghost/intern/GHOST_WindowX11.h
+++ b/intern/ghost/intern/GHOST_WindowX11.h
@@ -235,6 +235,8 @@ public:
GHOST_TSuccess endFullScreen() const;
+ GHOST_TUns16 getDPIHint();
+
protected:
/**
* \param type The type of rendering context create.