diff --git a/dlls/user32/sysparams.c b/dlls/user32/sysparams.c index a3f768ff66d..f5f6bf2eec9 100644 --- a/dlls/user32/sysparams.c +++ b/dlls/user32/sysparams.c @@ -615,7 +615,8 @@ BOOL WINAPI SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT context ) */ BOOL WINAPI GetProcessDpiAwarenessInternal( HANDLE process, DPI_AWARENESS *awareness ) { - *awareness = NtUserGetProcessDpiAwarenessContext( process ) & 3; + ULONG context = NtUserGetProcessDpiAwarenessContext( process ); + *awareness = NTUSER_DPI_CONTEXT_GET_AWARENESS( context ); return TRUE; } @@ -732,9 +733,12 @@ UINT WINAPI GetDpiForSystem(void) DPI_AWARENESS_CONTEXT WINAPI GetThreadDpiAwarenessContext(void) { struct ntuser_thread_info *info = NtUserGetThreadInfo(); + ULONG context; if (info->dpi_awareness) return ULongToHandle( info->dpi_awareness ); - return UlongToHandle( (NtUserGetProcessDpiAwarenessContext( GetCurrentProcess() ) & 3 ) | 0x10 ); + + context = NtUserGetProcessDpiAwarenessContext( GetCurrentProcess() ); + return UlongToHandle( NTUSER_DPI_CONTEXT_GET_AWARENESS( context ) | 0x10 ); } /********************************************************************** @@ -753,8 +757,8 @@ DPI_AWARENESS_CONTEXT WINAPI SetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT } if (!(prev = info->dpi_awareness)) { - prev = NtUserGetProcessDpiAwarenessContext( GetCurrentProcess() ) & 3; - prev |= 0x80000010; /* restore to process default */ + ULONG process_ctx = NtUserGetProcessDpiAwarenessContext( GetCurrentProcess() ); + prev = NTUSER_DPI_CONTEXT_GET_AWARENESS( process_ctx ) | 0x80000010; /* restore to process default */ } if (((ULONG_PTR)context & ~(ULONG_PTR)0x33) == 0x80000000) info->dpi_awareness = 0; else if (context == DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 || context == (DPI_AWARENESS_CONTEXT)0x22) diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index c6eb09c4268..c51275a294f 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2107,6 +2107,35 @@ UINT get_win_monitor_dpi( HWND hwnd ) return system_dpi; } +/* keep in sync with user32 */ +static BOOL is_valid_dpi_awareness_context( UINT context, UINT dpi ) +{ + switch (NTUSER_DPI_CONTEXT_GET_AWARENESS( context )) + { + case DPI_AWARENESS_UNAWARE: + if (NTUSER_DPI_CONTEXT_GET_FLAGS( context ) & ~NTUSER_DPI_CONTEXT_FLAG_VALID_MASK) return FALSE; + if (NTUSER_DPI_CONTEXT_GET_VERSION( context ) != 1) return FALSE; + if (NTUSER_DPI_CONTEXT_GET_DPI( context ) != USER_DEFAULT_SCREEN_DPI) return FALSE; + return TRUE; + + case DPI_AWARENESS_SYSTEM_AWARE: + if (NTUSER_DPI_CONTEXT_GET_FLAGS( context ) & ~NTUSER_DPI_CONTEXT_FLAG_VALID_MASK) return FALSE; + if (NTUSER_DPI_CONTEXT_GET_FLAGS( context ) & NTUSER_DPI_CONTEXT_FLAG_GDISCALED) return FALSE; + if (NTUSER_DPI_CONTEXT_GET_VERSION( context ) != 1) return FALSE; + if (dpi && NTUSER_DPI_CONTEXT_GET_DPI( context ) != dpi) return FALSE; + return TRUE; + + case DPI_AWARENESS_PER_MONITOR_AWARE: + if (NTUSER_DPI_CONTEXT_GET_FLAGS( context ) & ~NTUSER_DPI_CONTEXT_FLAG_VALID_MASK) return FALSE; + if (NTUSER_DPI_CONTEXT_GET_FLAGS( context ) & NTUSER_DPI_CONTEXT_FLAG_GDISCALED) return FALSE; + if (NTUSER_DPI_CONTEXT_GET_VERSION( context ) != 1 && NTUSER_DPI_CONTEXT_GET_VERSION( context ) != 2) return FALSE; + if (NTUSER_DPI_CONTEXT_GET_DPI( context )) return FALSE; + return TRUE; + } + + return FALSE; +} + /* copied from user32 GetAwarenessFromDpiAwarenessContext, make sure to keep that in sync */ static DPI_AWARENESS get_awareness_from_dpi_awareness_context( DPI_AWARENESS_CONTEXT context ) { @@ -6202,27 +6231,27 @@ BOOL WINAPI NtUserSetSysColors( INT count, const INT *colors, const COLORREF *va } -static LONG dpi_awareness; +static LONG dpi_context; /*********************************************************************** * NtUserSetProcessDpiAwarenessContext (win32u.@) */ -BOOL WINAPI NtUserSetProcessDpiAwarenessContext( ULONG awareness, ULONG unknown ) +BOOL WINAPI NtUserSetProcessDpiAwarenessContext( ULONG context, ULONG unknown ) { - switch (awareness) + if (!is_valid_dpi_awareness_context( context, system_dpi )) { - case NTUSER_DPI_UNAWARE: - case NTUSER_DPI_SYSTEM_AWARE: - case NTUSER_DPI_PER_MONITOR_AWARE: - case NTUSER_DPI_PER_MONITOR_AWARE_V2: - case NTUSER_DPI_PER_UNAWARE_GDISCALED: - break; - default: RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); return FALSE; } - return !InterlockedCompareExchange( &dpi_awareness, awareness, 0 ); + if (InterlockedCompareExchange( &dpi_context, context, 0 )) + { + RtlSetLastWin32Error( ERROR_ACCESS_DENIED ); + return FALSE; + } + + TRACE( "set to %#x\n", (UINT)context ); + return TRUE; } /*********************************************************************** @@ -6230,7 +6259,7 @@ BOOL WINAPI NtUserSetProcessDpiAwarenessContext( ULONG awareness, ULONG unknown */ ULONG WINAPI NtUserGetProcessDpiAwarenessContext( HANDLE process ) { - DPI_AWARENESS val; + ULONG context; if (process && process != GetCurrentProcess()) { @@ -6238,9 +6267,9 @@ ULONG WINAPI NtUserGetProcessDpiAwarenessContext( HANDLE process ) return NTUSER_DPI_UNAWARE; } - val = ReadNoFence( &dpi_awareness ); - if (!val) return NTUSER_DPI_UNAWARE; - return val; + context = ReadNoFence( &dpi_context ); + if (!context) return NTUSER_DPI_UNAWARE; + return context; } BOOL message_beep( UINT i ) diff --git a/include/ntuser.h b/include/ntuser.h index f947fec7fea..419ba2e86c3 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -281,12 +281,21 @@ struct unpack_dde_message_result LPARAM lparam; }; -/* process DPI awareness contexts */ -#define NTUSER_DPI_UNAWARE 0x00006010 -#define NTUSER_DPI_SYSTEM_AWARE 0x00006011 -#define NTUSER_DPI_PER_MONITOR_AWARE 0x00000012 -#define NTUSER_DPI_PER_MONITOR_AWARE_V2 0x00000022 -#define NTUSER_DPI_PER_UNAWARE_GDISCALED 0x40006010 +/* DPI awareness contexts */ +#define MAKE_NTUSER_DPI_CONTEXT( awareness, version, dpi, flags ) ((awareness) | ((version) << 4) | ((dpi) << 8) | (flags)) +#define NTUSER_DPI_CONTEXT_GET_AWARENESS( ctx ) ((ctx) & 0x0f) +#define NTUSER_DPI_CONTEXT_GET_VERSION( ctx ) (((ctx) & 0xf0) >> 4) +#define NTUSER_DPI_CONTEXT_GET_DPI( ctx ) ((((ctx) & 0x1ff00) >> 8)) +#define NTUSER_DPI_CONTEXT_GET_FLAGS( ctx ) ((ctx) & 0xfffe0000) +#define NTUSER_DPI_CONTEXT_FLAG_GDISCALED 0x40000000 +#define NTUSER_DPI_CONTEXT_FLAG_PROCESS 0x80000000 +#define NTUSER_DPI_CONTEXT_FLAG_VALID_MASK (NTUSER_DPI_CONTEXT_FLAG_PROCESS | NTUSER_DPI_CONTEXT_FLAG_GDISCALED) + +#define NTUSER_DPI_UNAWARE MAKE_NTUSER_DPI_CONTEXT( DPI_AWARENESS_UNAWARE, 1, USER_DEFAULT_SCREEN_DPI, 0 ) +#define NTUSER_DPI_SYSTEM_AWARE MAKE_NTUSER_DPI_CONTEXT( DPI_AWARENESS_SYSTEM_AWARE, 1, system_dpi, 0 ) +#define NTUSER_DPI_PER_MONITOR_AWARE MAKE_NTUSER_DPI_CONTEXT( DPI_AWARENESS_PER_MONITOR_AWARE, 1, 0, 0 ) +#define NTUSER_DPI_PER_MONITOR_AWARE_V2 MAKE_NTUSER_DPI_CONTEXT( DPI_AWARENESS_PER_MONITOR_AWARE, 2, 0, 0 ) +#define NTUSER_DPI_PER_UNAWARE_GDISCALED MAKE_NTUSER_DPI_CONTEXT( DPI_AWARENESS_UNAWARE, 1, USER_DEFAULT_SCREEN_DPI, NTUSER_DPI_CONTEXT_FLAG_GDISCALED ) /* message spy definitions */ #define SPY_DISPATCHMESSAGE 0x0100