Commit b19b6266 authored by Jon Turney's avatar Jon Turney
Browse files

Allow DPI to change on WM_DISPLAYCHANGED

Update the 'monitorResolution' global on WM_DISPLAYCHANGED, unless a
fixed DPI was specified by '-dpi' option or in .XWinrc file.

Handle WM_GETDPISCALEDSIZE to avoid DPI-scaling of our Windows when
moving between monitors with different DPI values.
parent 5557b030
......@@ -938,6 +938,8 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[])
winConfigFiles();
#endif
winUpdateDpi();
/* Load preferences from XWinrc file */
LoadPreferences();
......
......@@ -15,7 +15,10 @@
</dependency>
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
<dpiAware>true/pm</dpiAware>
</asmv3:windowsSettings>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
<dpiAwareness>PerMonitorV2,PerMonitor</dpiAwareness>
</asmv3:windowsSettings>
</asmv3:application>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
......
......@@ -57,7 +57,6 @@
#define WIN_DEFAULT_BLACKPIXEL 0
#define WIN_DEFAULT_LINEBIAS 0
#define WIN_DEFAULT_E3B_TIME 50 /* milliseconds */
#define WIN_DEFAULT_DPI 96
#define WIN_DEFAULT_REFRESH 0
#define WIN_DEFAULT_WIN_KILL TRUE
#define WIN_DEFAULT_UNIX_KILL FALSE
......@@ -1032,6 +1031,8 @@ winDoRandRScreenSetSize(ScreenPtr pScreen,
CARD16 width,
CARD16 height, CARD32 mmWidth, CARD32 mmHeight);
void winUpdateDpi(void);
/*
* winmsgwindow.c
*/
......
......@@ -80,6 +80,7 @@ Bool g_fSilentDupError = FALSE;
Bool g_fNativeGl = TRUE;
Bool g_fHostInTitle = TRUE;
pthread_mutex_t g_pmTerminating = PTHREAD_MUTEX_INITIALIZER;
Bool g_fixedDPI = FALSE;
/*
* Wrapped DIX functions
......
......@@ -82,4 +82,6 @@ extern Bool g_fButton[3];
extern pthread_mutex_t g_pmTerminating;
extern Bool g_fixedDPI;
#endif /* WINGLOBALS_H */
......@@ -48,6 +48,10 @@
#define WM_DWMCOMPOSITIONCHANGED 0x031e
#endif
#ifndef WM_GETDPISCALEDSIZE
#define WM_GETDPISCALEDSIZE 0x02E4
#endif
extern void winUpdateWindowPosition(HWND hWnd, HWND * zstyle);
/*
......@@ -1262,13 +1266,18 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
}
break;
case WM_DWMCOMPOSITIONCHANGED:
/* This message is only sent on Vista/W7 */
CheckForAlpha(hwnd, pWin, s_pScreenInfo);
return 0;
case WM_GETDPISCALEDSIZE:
winDebug("winTopLevelWindowProc - WM_GETDPISCALEDSIZE\n");
// We don't change the lParam SIZE, so the Window retains the same size
// in pixels (rather than getting linearly scaled by the dpi value)
return TRUE;
case WM_ASYNCMOVE:
winAdjustWindowsWindow(pWin, hwnd);
break;
......
......@@ -318,7 +318,10 @@ static void
SetDPI (char *dpi)
{
if (!g_cmdline.customDPI)
monitorResolution = atoi (dpi);
{
monitorResolution = atoi (dpi);
g_fixedDPI = TRUE;
}
}
static void
......
......@@ -86,29 +86,6 @@ winInitializeScreenDefaults(void)
"winInitializeScreenDefaults - primary monitor w %d h %d\n",
(int) dwWidth, (int) dwHeight);
/* Set a default DPI, if no '-dpi' option was used */
if (monitorResolution == 0) {
HDC hdc = GetDC(NULL);
if (hdc) {
int dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
int dpiY = GetDeviceCaps(hdc, LOGPIXELSY);
winErrorFVerb(2,
"winInitializeScreenDefaults - native DPI x %d y %d\n",
dpiX, dpiY);
monitorResolution = dpiY;
ReleaseDC(NULL, hdc);
}
else {
winErrorFVerb(1,
"winInitializeScreenDefaults - Failed to retrieve native DPI, falling back to default of %d DPI\n",
WIN_DEFAULT_DPI);
monitorResolution = WIN_DEFAULT_DPI;
}
}
defaultScreenInfo.iMonitor = 1;
defaultScreenInfo.hMonitor = MonitorFromWindow(NULL, MONITOR_DEFAULTTOPRIMARY);
defaultScreenInfo.dwWidth = dwWidth;
......@@ -942,6 +919,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
*/
if (IS_OPTION("-dpi")) {
g_cmdline.customDPI = TRUE;
g_fixedDPI = TRUE;
return 0; /* Let DIX parse this again */
}
......
......@@ -302,3 +302,82 @@ winRandRInit(ScreenPtr pScreen)
return TRUE;
}
/*
Update the DPI value
(or do nothing, if it's fixed)
*/
#define WIN_DEFAULT_DPI 96
typedef enum MONITOR_DPI_TYPE {
MDT_EFFECTIVE_DPI = 0,
} MONITOR_DPI_TYPE;
typedef HRESULT WINAPI (*PFNGETDPIFORMONITOR)(HMONITOR, MONITOR_DPI_TYPE, UINT *, UINT *);
void
winUpdateDpi(void)
{
/* If no '-dpi' option was used */
if (!g_fixedDPI)
{
// It seems that GetDeviceCaps reports the DPI when the Windows
// session started (or the process, if "Fix scaling for apps" is
// on), so instead use GetDpiForMonitor on the primary monitor, if
// that is available
static Bool tryLoad = TRUE;
if (tryLoad)
{
LoadLibrary("shcore.dll");
tryLoad = FALSE;
}
PFNGETDPIFORMONITOR pGDFM = (PFNGETDPIFORMONITOR) GetProcAddress(GetModuleHandle("shcore.dll"), "GetDpiForMonitor");
if (pGDFM)
{
// Get HMONITOR of primary monitor
// (by definition the primary monitor contains the point (0,0))
const POINT ptZero = { 0, 0 };
HMONITOR hPriMon = MonitorFromPoint(ptZero, MONITOR_DEFAULTTOPRIMARY);
// Get DPI of primary monitor
unsigned int dpiX, dpiY;
HRESULT res = pGDFM(hPriMon, MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
if (res == S_OK)
{
ErrorF("winUpdateDpi - primary monitor native DPI x %u y %u\n", dpiX, dpiY);
monitorResolution = dpiY;
}
else
{
ErrorF("winUpdateDpi - Failed to retrieve native DPI for primary monitor, falling back to default of %d DPI\n", WIN_DEFAULT_DPI);
monitorResolution = WIN_DEFAULT_DPI;
}
}
else
{
HDC hdc = GetDC(NULL);
if (hdc) {
int dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
int dpiY = GetDeviceCaps(hdc, LOGPIXELSY);
ErrorF("winUpdateDpi - native DPI x %d y %d\n", dpiX, dpiY);
monitorResolution = dpiY;
ReleaseDC(NULL, hdc);
}
else {
ErrorF("winUpdateDpi - Failed to retrieve native DPI, falling back to default of %d DPI\n", WIN_DEFAULT_DPI);
monitorResolution = WIN_DEFAULT_DPI;
}
}
}
else
{
ErrorF("winUpdateDpi - Using fixed %d DPI\n", monitorResolution);
}
}
......@@ -44,6 +44,10 @@
#include "inputstr.h"
#include "winclipboard/winclipboard.h"
#ifndef WM_GETDPISCALEDSIZE
#define WM_GETDPISCALEDSIZE 0x02E4
#endif
/*
* Global variables
*/
......@@ -140,6 +144,12 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
}
return 0;
case WM_GETDPISCALEDSIZE:
winDebug("winTopLevelWindowProc - WM_GETDPISCALEDSIZE\n");
// We don't change the lParam SIZE, so the Window retains the same size
// in pixels (rather than getting linearly scaled by the dpi value)
return TRUE;
case WM_DISPLAYCHANGE:
/*
WM_DISPLAYCHANGE seems to be sent when the monitor layout or
......@@ -253,6 +263,8 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
}
}
winUpdateDpi();
/*
XXX: probably a small bug here: we don't compute the work area
and allow for task bar
......@@ -261,10 +273,8 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
the server is started
*/
/* Set screen size to match new size, if it is different to current */
if (((dwWidth != 0) && (dwHeight != 0)) &&
((s_pScreenInfo->dwWidth != dwWidth) ||
(s_pScreenInfo->dwHeight != dwHeight))) {
/* Set screen size to match new size */
if ((dwWidth != 0) && (dwHeight != 0)) {
winDoRandRScreenSetSize(s_pScreen,
dwWidth,
dwHeight,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment