From cf93c1c81d35d79279bb9ddc7445afac09f3d57f Mon Sep 17 00:00:00 2001 From: pavelkproductengine Date: Thu, 18 Aug 2016 19:43:48 +0300 Subject: MAINT-5992 Second Life unusable on Windows 10 with 4k monitor SL forcibly overrides DPI compatibility option --- indra/llwindow/llwindowcallbacks.cpp | 5 ++ indra/llwindow/llwindowcallbacks.h | 1 + indra/llwindow/llwindowwin32.cpp | 103 ++++++++++++++++++++++++++++++----- indra/llwindow/llwindowwin32.h | 2 +- 4 files changed, 95 insertions(+), 16 deletions(-) (limited to 'indra/llwindow') diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp index d2afb3f91b..474953d3a4 100644 --- a/indra/llwindow/llwindowcallbacks.cpp +++ b/indra/llwindow/llwindowcallbacks.cpp @@ -175,6 +175,11 @@ BOOL LLWindowCallbacks::handleDeviceChange(LLWindow *window) return FALSE; } +void LLWindowCallbacks::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height) +{ + +} + void LLWindowCallbacks::handlePingWatchdog(LLWindow *window, const char * msg) { diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h index 6a7137e593..de789a71d9 100644 --- a/indra/llwindow/llwindowcallbacks.h +++ b/indra/llwindow/llwindowcallbacks.h @@ -65,6 +65,7 @@ public: virtual void handleDataCopy(LLWindow *window, S32 data_type, void *data); virtual BOOL handleTimerEvent(LLWindow *window); virtual BOOL handleDeviceChange(LLWindow *window); + virtual void handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height); enum DragNDropAction { DNDA_START_TRACKING = 0,// Start tracking an incoming drag diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 2a39029eee..f14cf26ce9 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -71,6 +71,11 @@ const S32 MAX_MESSAGE_PER_UPDATE = 20; const S32 BITS_PER_PIXEL = 32; const S32 MAX_NUM_RESOLUTIONS = 32; const F32 ICON_FLASH_TIME = 0.5f; +const F32 DEFAULT_DPI = 96.0f; + +#ifndef WM_DPICHANGED +const S32 WM_DPICHANGED = 0x02E0; +#endif extern BOOL gDebugWindowProc; @@ -97,6 +102,10 @@ typedef enum MONITOR_DPI_TYPE { typedef HRESULT(STDAPICALLTYPE *SetProcessDpiAwarenessType)(_In_ PROCESS_DPI_AWARENESS value); +typedef HRESULT(STDAPICALLTYPE *GetProcessDpiAwarenessType)( + _In_ HANDLE hprocess, + _Out_ PROCESS_DPI_AWARENESS *value); + typedef HRESULT(STDAPICALLTYPE *GetDpiForMonitorType)( _In_ HMONITOR hmonitor, _In_ MONITOR_DPI_TYPE dpiType, @@ -2618,6 +2627,24 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ return 0; } + + case WM_DPICHANGED: + { + LPRECT lprc_new_scale; + F32 new_scale = LOWORD(w_param) / 96.0f; + lprc_new_scale = (LPRECT)l_param; + S32 new_width = lprc_new_scale->right - lprc_new_scale->left; + S32 new_height = lprc_new_scale->bottom - lprc_new_scale->top; + window_imp->mCallbacks->handleDPIChanged(window_imp, new_scale, new_width, new_height); + SetWindowPos(h_wnd, + HWND_TOP, + lprc_new_scale->left, + lprc_new_scale->top, + new_width, + new_height, + SWP_NOZORDER | SWP_NOACTIVATE); + return 0; + } case WM_SETFOCUS: window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SETFOCUS"); @@ -3903,40 +3930,86 @@ BOOL LLWindowWin32::handleImeRequests(U32 request, U32 param, LRESULT *result) return FALSE; } +//static +void LLWindowWin32::setDPIAwareness() +{ + HMODULE hShcore = LoadLibrary(L"shcore.dll"); + if (hShcore != NULL) + { + SetProcessDpiAwarenessType pSPDA; + pSPDA = (SetProcessDpiAwarenessType)GetProcAddress(hShcore, "SetProcessDpiAwareness"); + if (pSPDA) + { + + HRESULT hr = pSPDA(PROCESS_PER_MONITOR_DPI_AWARE); + if (hr != S_OK) + { + LL_WARNS() << "SetProcessDpiAwareness() function returned an error. Will use legacy DPI awareness API of Win XP/7" << LL_ENDL; + } + } + FreeLibrary(hShcore); + } + else + { + LL_WARNS() << "Could not load shcore.dll library (included by from Win 8.1 SDK. Will use legacy DPI awareness API of Win XP/7" << LL_ENDL; + } +} + F32 LLWindowWin32::getSystemUISize() { float scale_value = 0; HWND hWnd = (HWND)getPlatformWindow(); HDC hdc = GetDC(hWnd); HMONITOR hMonitor; + HANDLE hProcess = GetCurrentProcess(); + PROCESS_DPI_AWARENESS dpi_awareness; HMODULE hShcore = LoadLibrary(L"shcore.dll"); if (hShcore != NULL) { - SetProcessDpiAwarenessType pSPDA; - pSPDA = (SetProcessDpiAwarenessType)GetProcAddress(hShcore, "SetProcessDpiAwareness"); + GetProcessDpiAwarenessType pGPDA; + pGPDA = (GetProcessDpiAwarenessType)GetProcAddress(hShcore, "GetProcessDpiAwareness"); GetDpiForMonitorType pGDFM; pGDFM = (GetDpiForMonitorType)GetProcAddress(hShcore, "GetDpiForMonitor"); - if (pSPDA != NULL && pGDFM != NULL) + if (pGPDA != NULL && pGDFM != NULL) { - pSPDA(PROCESS_PER_MONITOR_DPI_AWARE); - POINT pt; - UINT dpix = 0, dpiy = 0; - HRESULT hr = E_FAIL; - - // Get the DPI for the main monitor, and set the scaling factor - pt.x = 1; - pt.y = 1; - hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); - hr = pGDFM(hMonitor, MDT_EFFECTIVE_DPI, &dpix, &dpiy); - scale_value = dpix / 96.0f; + pGPDA(hProcess, &dpi_awareness); + if (dpi_awareness == PROCESS_PER_MONITOR_DPI_AWARE) + { + POINT pt; + UINT dpix = 0, dpiy = 0; + HRESULT hr = E_FAIL; + RECT rect; + + GetWindowRect(hWnd, &rect); + // Get the DPI for the monitor, on which the center of window is displayed and set the scaling factor + pt.x = (rect.left + rect.right) / 2; + pt.y = (rect.top + rect.bottom) / 2; + hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); + hr = pGDFM(hMonitor, MDT_EFFECTIVE_DPI, &dpix, &dpiy); + if (hr == S_OK) + { + scale_value = dpix / DEFAULT_DPI; + } + else + { + LL_WARNS() << "Could not determine DPI for monitor. Setting scale to default 100 %" << LL_ENDL; + scale_value = 1.0f; + } + } + else + { + LL_WARNS() << "Process is not per-monitor DPI-aware. Setting scale to default 100 %" << LL_ENDL; + scale_value = 1.0f; + } } + FreeLibrary(hShcore); } else { LL_WARNS() << "Could not load shcore.dll library (included by from Win 8.1 SDK). Using legacy DPI awareness API of Win XP/7" << LL_ENDL; - scale_value = GetDeviceCaps(hdc, LOGPIXELSX) / 96.0f; + scale_value = GetDeviceCaps(hdc, LOGPIXELSX) / DEFAULT_DPI; } ReleaseDC(hWnd, hdc); diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 1386321912..39ef9b31a4 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -115,7 +115,7 @@ public: LLWindowCallbacks::DragNDropResult completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url ); static std::vector getDynamicFallbackFontList(); - + static void setDPIAwareness(); protected: LLWindowWin32(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, -- cgit v1.2.3 From ea4b5e60d92b0b1349115e2722f028cd0cf2da18 Mon Sep 17 00:00:00 2001 From: AndreyL ProductEngine Date: Sat, 20 Aug 2016 14:28:03 +0300 Subject: Fixed line endings in llwindowwin32.cpp --- indra/llwindow/llwindowwin32.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'indra/llwindow') diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index f14cf26ce9..26bc819aab 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -3976,7 +3976,7 @@ F32 LLWindowWin32::getSystemUISize() { pGPDA(hProcess, &dpi_awareness); if (dpi_awareness == PROCESS_PER_MONITOR_DPI_AWARE) - { + { POINT pt; UINT dpix = 0, dpiy = 0; HRESULT hr = E_FAIL; @@ -3988,19 +3988,19 @@ F32 LLWindowWin32::getSystemUISize() pt.y = (rect.top + rect.bottom) / 2; hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); hr = pGDFM(hMonitor, MDT_EFFECTIVE_DPI, &dpix, &dpiy); - if (hr == S_OK) - { - scale_value = dpix / DEFAULT_DPI; - } - else - { - LL_WARNS() << "Could not determine DPI for monitor. Setting scale to default 100 %" << LL_ENDL; - scale_value = 1.0f; + if (hr == S_OK) + { + scale_value = dpix / DEFAULT_DPI; + } + else + { + LL_WARNS() << "Could not determine DPI for monitor. Setting scale to default 100 %" << LL_ENDL; + scale_value = 1.0f; } } else { - LL_WARNS() << "Process is not per-monitor DPI-aware. Setting scale to default 100 %" << LL_ENDL; + LL_WARNS() << "Process is not per-monitor DPI-aware. Setting scale to default 100 %" << LL_ENDL; scale_value = 1.0f; } } -- cgit v1.2.3 From bb7cbe7cff43bec7061a7a0ccabaf2755e7376ee Mon Sep 17 00:00:00 2001 From: Ansariel Date: Tue, 20 Sep 2016 21:16:39 +0200 Subject: Small improvements to UI DPI scaling on Windows: * Use USER_DEFAULT_SCREEN_DPI define from WinUser.h * Change Win32 SDK target version to Windows Vista or greater * Define WM_DPICHANGED as preprocessor definition as in WinUser.h * Cull manual definitions of WM_MOUSEWHEEL and WHEEL_DELTA which are part of the Win32 SDK since Windows NT 4.0 --- indra/llwindow/llwindowwin32.cpp | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'indra/llwindow') diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 26bc819aab..4086db8e52 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -60,21 +60,13 @@ #include #include -// culled from winuser.h -#ifndef WM_MOUSEWHEEL /* Added to be compatible with later SDK's */ -const S32 WM_MOUSEWHEEL = 0x020A; -#endif -#ifndef WHEEL_DELTA /* Added to be compatible with later SDK's */ -const S32 WHEEL_DELTA = 120; /* Value for rolling one detent */ -#endif const S32 MAX_MESSAGE_PER_UPDATE = 20; const S32 BITS_PER_PIXEL = 32; const S32 MAX_NUM_RESOLUTIONS = 32; const F32 ICON_FLASH_TIME = 0.5f; -const F32 DEFAULT_DPI = 96.0f; -#ifndef WM_DPICHANGED -const S32 WM_DPICHANGED = 0x02E0; +#ifndef WM_DPICHANGED +#define WM_DPICHANGED 0x02E0 #endif extern BOOL gDebugWindowProc; @@ -2631,7 +2623,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ case WM_DPICHANGED: { LPRECT lprc_new_scale; - F32 new_scale = LOWORD(w_param) / 96.0f; + F32 new_scale = LOWORD(w_param) / USER_DEFAULT_SCREEN_DPI; lprc_new_scale = (LPRECT)l_param; S32 new_width = lprc_new_scale->right - lprc_new_scale->left; S32 new_height = lprc_new_scale->bottom - lprc_new_scale->top; @@ -3990,7 +3982,7 @@ F32 LLWindowWin32::getSystemUISize() hr = pGDFM(hMonitor, MDT_EFFECTIVE_DPI, &dpix, &dpiy); if (hr == S_OK) { - scale_value = dpix / DEFAULT_DPI; + scale_value = dpix / USER_DEFAULT_SCREEN_DPI; } else { @@ -4009,7 +4001,7 @@ F32 LLWindowWin32::getSystemUISize() else { LL_WARNS() << "Could not load shcore.dll library (included by from Win 8.1 SDK). Using legacy DPI awareness API of Win XP/7" << LL_ENDL; - scale_value = GetDeviceCaps(hdc, LOGPIXELSX) / DEFAULT_DPI; + scale_value = GetDeviceCaps(hdc, LOGPIXELSX) / USER_DEFAULT_SCREEN_DPI; } ReleaseDC(hWnd, hdc); -- cgit v1.2.3