diff --git a/dlls/user32/sysparams.c b/dlls/user32/sysparams.c index 803c583237d..634320a1d2f 100644 --- a/dlls/user32/sysparams.c +++ b/dlls/user32/sysparams.c @@ -120,8 +120,6 @@ static BOOL notify_change = TRUE; /* System parameters storage */ static RECT work_area; static UINT system_dpi; -static DPI_AWARENESS dpi_awareness; -static DPI_AWARENESS default_awareness = DPI_AWARENESS_UNAWARE; static HKEY volatile_base_key; @@ -1374,11 +1372,7 @@ void SYSPARAMS_Init(void) /* FIXME: what do the DpiScalingVer flags mean? */ get_dword_entry( (union sysparam_all_entry *)&entry_DPISCALINGVER, 0, &dpi_scaling, 0 ); - if (!dpi_scaling) - { - default_awareness = DPI_AWARENESS_PER_MONITOR_AWARE; - dpi_awareness = 0x10 | default_awareness; - } + if (!dpi_scaling) NtUserSetProcessDpiAwarenessContext( NTUSER_DPI_PER_MONITOR_AWARE, 0 ); if (volatile_base_key && dispos == REG_CREATED_NEW_KEY) /* first process, initialize entries */ { @@ -3214,19 +3208,31 @@ RECT rect_thread_to_win_dpi( HWND hwnd, RECT rect ) */ BOOL WINAPI SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT context ) { - DPI_AWARENESS val = GetAwarenessFromDpiAwarenessContext( context ); + ULONG awareness; - if (val == DPI_AWARENESS_INVALID) + switch (GetAwarenessFromDpiAwarenessContext( context )) { + case DPI_AWARENESS_UNAWARE: + awareness = NTUSER_DPI_UNAWARE; + break; + case DPI_AWARENESS_SYSTEM_AWARE: + awareness = NTUSER_DPI_SYSTEM_AWARE; + break; + case DPI_AWARENESS_PER_MONITOR_AWARE: + awareness = context == DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 + ? NTUSER_DPI_PER_MONITOR_AWARE_V2 : NTUSER_DPI_PER_MONITOR_AWARE; + break; + default: SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; } - val |= 0x10; /* avoid 0 value */ - if (InterlockedCompareExchange( &dpi_awareness, val, 0 )) + + if (!NtUserSetProcessDpiAwarenessContext( awareness, 0 )) { SetLastError( ERROR_ACCESS_DENIED ); return FALSE; } + TRACE( "set to %p\n", context ); return TRUE; } @@ -3236,12 +3242,7 @@ BOOL WINAPI SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT context ) */ BOOL WINAPI GetProcessDpiAwarenessInternal( HANDLE process, DPI_AWARENESS *awareness ) { - if (process && process != GetCurrentProcess()) - { - WARN( "not supported on other process %p\n", process ); - *awareness = DPI_AWARENESS_UNAWARE; - } - else *awareness = dpi_awareness & 3; + *awareness = NtUserGetProcessDpiAwarenessContext( process ) & 3; return TRUE; } @@ -3309,7 +3310,7 @@ BOOL WINAPI IsValidDpiAwarenessContext( DPI_AWARENESS_CONTEXT context ) BOOL WINAPI SetProcessDPIAware(void) { TRACE("\n"); - InterlockedCompareExchange( &dpi_awareness, 0x11, 0 ); + NtUserSetProcessDpiAwarenessContext( NTUSER_DPI_SYSTEM_AWARE, 0 ); return TRUE; } @@ -3372,8 +3373,7 @@ DPI_AWARENESS_CONTEXT WINAPI GetThreadDpiAwarenessContext(void) struct user_thread_info *info = get_user_thread_info(); if (info->dpi_awareness) return ULongToHandle( info->dpi_awareness ); - if (dpi_awareness) return ULongToHandle( dpi_awareness ); - return ULongToHandle( 0x10 | default_awareness ); + return UlongToHandle( (NtUserGetProcessDpiAwarenessContext( GetCurrentProcess() ) & 3 ) | 0x10 ); } /********************************************************************** @@ -3391,9 +3391,8 @@ DPI_AWARENESS_CONTEXT WINAPI SetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT } if (!(prev = info->dpi_awareness)) { - prev = dpi_awareness; - if (!prev) prev = 0x10 | DPI_AWARENESS_UNAWARE; - prev |= 0x80000000; /* restore to process default */ + prev = NtUserGetProcessDpiAwarenessContext( GetCurrentProcess() ) & 3; + prev |= 0x80000010; /* restore to process default */ } if (((ULONG_PTR)context & ~(ULONG_PTR)0x13) == 0x80000000) info->dpi_awareness = 0; else info->dpi_awareness = val | 0x10; diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index 826bba390da..50ea40cc09d 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -120,6 +120,7 @@ static void * const syscalls[] = NtUserGetMouseMovePointsEx, NtUserGetObjectInformation, NtUserGetOpenClipboardWindow, + NtUserGetProcessDpiAwarenessContext, NtUserGetProcessWindowStation, NtUserGetProp, NtUserGetThreadDesktop, @@ -130,6 +131,7 @@ static void * const syscalls[] = NtUserRemoveProp, NtUserSetKeyboardState, NtUserSetObjectInformation, + NtUserSetProcessDpiAwarenessContext, NtUserSetProcessWindowStation, NtUserSetProp, NtUserSetThreadDesktop, diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 095a6cfe680..c0458c41797 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1657,6 +1657,44 @@ void sysparams_init(void) } } +static DPI_AWARENESS dpi_awareness; + +/*********************************************************************** + * NtUserSetProcessDpiAwarenessContext (win32u.@) + */ +BOOL WINAPI NtUserSetProcessDpiAwarenessContext( ULONG awareness, ULONG unknown ) +{ + switch (awareness) + { + 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: + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + return !InterlockedCompareExchange( &dpi_awareness, awareness, 0 ); +} + +/*********************************************************************** + * NtUserGetProcessDpiAwarenessContext (win32u.@) + */ +ULONG WINAPI NtUserGetProcessDpiAwarenessContext( HANDLE process ) +{ + if (process && process != GetCurrentProcess()) + { + WARN( "not supported on other process %p\n", process ); + return NTUSER_DPI_UNAWARE; + } + + if (!dpi_awareness) return NTUSER_DPI_UNAWARE; + return dpi_awareness; +} + /*********************************************************************** * NtUserCallOneParam (win32u.@) */ diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 786d2c47b28..97bd2844120 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -977,7 +977,7 @@ @ stub NtUserGetPointerType @ stub NtUserGetPrecisionTouchPadConfiguration @ stdcall NtUserGetPriorityClipboardFormat(ptr long) -@ stub NtUserGetProcessDpiAwarenessContext +@ stdcall -syscall NtUserGetProcessDpiAwarenessContext(long) @ stub NtUserGetProcessUIContextInformation @ stdcall -syscall NtUserGetProcessWindowStation() @ stdcall -syscall NtUserGetProp(long wstr) @@ -1216,7 +1216,7 @@ @ stdcall -syscall NtUserSetObjectInformation(long long ptr long) @ stub NtUserSetParent @ stub NtUserSetPrecisionTouchPadConfiguration -@ stub NtUserSetProcessDpiAwarenessContext +@ stdcall -syscall NtUserSetProcessDpiAwarenessContext(long long) @ stub NtUserSetProcessInteractionFlags @ stub NtUserSetProcessMousewheelRoutingMode @ stub NtUserSetProcessRestrictionExemption diff --git a/dlls/wow64win/syscall.h b/dlls/wow64win/syscall.h index 99ed465cbc3..9b459558e53 100644 --- a/dlls/wow64win/syscall.h +++ b/dlls/wow64win/syscall.h @@ -107,6 +107,7 @@ SYSCALL_ENTRY( NtUserGetMouseMovePointsEx ) \ SYSCALL_ENTRY( NtUserGetObjectInformation ) \ SYSCALL_ENTRY( NtUserGetOpenClipboardWindow ) \ + SYSCALL_ENTRY( NtUserGetProcessDpiAwarenessContext ) \ SYSCALL_ENTRY( NtUserGetProcessWindowStation ) \ SYSCALL_ENTRY( NtUserGetProp ) \ SYSCALL_ENTRY( NtUserGetThreadDesktop ) \ @@ -117,6 +118,7 @@ SYSCALL_ENTRY( NtUserRemoveProp ) \ SYSCALL_ENTRY( NtUserSetKeyboardState ) \ SYSCALL_ENTRY( NtUserSetObjectInformation ) \ + SYSCALL_ENTRY( NtUserSetProcessDpiAwarenessContext ) \ SYSCALL_ENTRY( NtUserSetProcessWindowStation ) \ SYSCALL_ENTRY( NtUserSetProp ) \ SYSCALL_ENTRY( NtUserSetThreadDesktop ) diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 9962b0b442a..c6884b026ac 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -293,3 +293,18 @@ NTSTATUS WINAPI wow64_NtUserGetMouseMovePointsEx( UINT *args ) return NtUserGetMouseMovePointsEx( size, ptin, ptout, count, resolution ); } + +NTSTATUS WINAPI wow64_NtUserSetProcessDpiAwarenessContext( UINT *args ) +{ + ULONG awareness = get_ulong( &args ); + ULONG unknown = get_ulong( &args ); + + return NtUserSetProcessDpiAwarenessContext( awareness, unknown ); +} + +NTSTATUS WINAPI wow64_NtUserGetProcessDpiAwarenessContext( UINT *args ) +{ + HANDLE process = get_handle( &args ); + + return NtUserGetProcessDpiAwarenessContext( process ); +} diff --git a/include/ntuser.h b/include/ntuser.h index 3edfeab188e..9d9859b35e1 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -39,6 +39,13 @@ struct enum_display_monitor_params 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 + /* NtUserCallOneParam codes, not compatible with Windows */ enum { @@ -123,6 +130,7 @@ HWND WINAPI NtUserGetOpenClipboardWindow(void); INT WINAPI NtUserGetPriorityClipboardFormat( UINT *list, INT count ); HWINSTA WINAPI NtUserGetProcessWindowStation(void); HANDLE WINAPI NtUserGetProp( HWND hwnd, const WCHAR *str ); +ULONG WINAPI NtUserGetProcessDpiAwarenessContext( HANDLE process ); HDESK WINAPI NtUserGetThreadDesktop( DWORD thread ); BOOL WINAPI NtUserGetUpdatedClipboardFormats( UINT *formats, UINT size, UINT *out_size ); BOOL WINAPI NtUserIsClipboardFormatAvailable( UINT format ); @@ -137,6 +145,7 @@ BOOL WINAPI NtUserScrollDC( HDC hdc, INT dx, INT dy, const RECT *scroll, cons HRGN ret_update_rgn, RECT *update_rect ); HPALETTE WINAPI NtUserSelectPalette( HDC hdc, HPALETTE palette, WORD force_background ); BOOL WINAPI NtUserSetKeyboardState( BYTE *state ); +BOOL WINAPI NtUserSetProcessDpiAwarenessContext( ULONG awareness, ULONG unknown ); BOOL WINAPI NtUserSetProcessWindowStation( HWINSTA handle ); BOOL WINAPI NtUserSetProp( HWND hwnd, const WCHAR *str, HANDLE handle ); BOOL WINAPI NtUserSetThreadDesktop( HDESK handle );