msi/tests: Delete the temp .msi file in all failure cases.
[wine.git] / dlls / user32 / sysparams.c
bloba3f768ff66d8bb83de66d74c7f26c62d0b3d9dc5
1 /*
2 * System parameters functions
4 * Copyright 1994 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "ntstatus.h"
22 #define WIN32_NO_STATUS
23 #include "user_private.h"
24 #include "controls.h"
25 #include "wine/asm.h"
26 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(system);
31 static HDC display_dc;
32 static CRITICAL_SECTION display_dc_section;
33 static CRITICAL_SECTION_DEBUG critsect_debug =
35 0, 0, &display_dc_section,
36 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
37 0, 0, { (DWORD_PTR)(__FILE__ ": display_dc_section") }
39 static CRITICAL_SECTION display_dc_section = { &critsect_debug, -1 ,0, 0, 0, 0 };
42 /* System parameters storage */
43 static UINT system_dpi;
45 static void SYSPARAMS_LogFont32WTo32A( const LOGFONTW* font32W, LPLOGFONTA font32A )
47 font32A->lfHeight = font32W->lfHeight;
48 font32A->lfWidth = font32W->lfWidth;
49 font32A->lfEscapement = font32W->lfEscapement;
50 font32A->lfOrientation = font32W->lfOrientation;
51 font32A->lfWeight = font32W->lfWeight;
52 font32A->lfItalic = font32W->lfItalic;
53 font32A->lfUnderline = font32W->lfUnderline;
54 font32A->lfStrikeOut = font32W->lfStrikeOut;
55 font32A->lfCharSet = font32W->lfCharSet;
56 font32A->lfOutPrecision = font32W->lfOutPrecision;
57 font32A->lfClipPrecision = font32W->lfClipPrecision;
58 font32A->lfQuality = font32W->lfQuality;
59 font32A->lfPitchAndFamily = font32W->lfPitchAndFamily;
60 WideCharToMultiByte( CP_ACP, 0, font32W->lfFaceName, -1, font32A->lfFaceName, LF_FACESIZE, NULL, NULL );
61 font32A->lfFaceName[LF_FACESIZE-1] = 0;
64 static void SYSPARAMS_LogFont32ATo32W( const LOGFONTA* font32A, LPLOGFONTW font32W )
66 font32W->lfHeight = font32A->lfHeight;
67 font32W->lfWidth = font32A->lfWidth;
68 font32W->lfEscapement = font32A->lfEscapement;
69 font32W->lfOrientation = font32A->lfOrientation;
70 font32W->lfWeight = font32A->lfWeight;
71 font32W->lfItalic = font32A->lfItalic;
72 font32W->lfUnderline = font32A->lfUnderline;
73 font32W->lfStrikeOut = font32A->lfStrikeOut;
74 font32W->lfCharSet = font32A->lfCharSet;
75 font32W->lfOutPrecision = font32A->lfOutPrecision;
76 font32W->lfClipPrecision = font32A->lfClipPrecision;
77 font32W->lfQuality = font32A->lfQuality;
78 font32W->lfPitchAndFamily = font32A->lfPitchAndFamily;
79 MultiByteToWideChar( CP_ACP, 0, font32A->lfFaceName, -1, font32W->lfFaceName, LF_FACESIZE );
80 font32W->lfFaceName[LF_FACESIZE-1] = 0;
83 static void SYSPARAMS_NonClientMetrics32WTo32A( const NONCLIENTMETRICSW* lpnm32W, LPNONCLIENTMETRICSA lpnm32A )
85 lpnm32A->iBorderWidth = lpnm32W->iBorderWidth;
86 lpnm32A->iScrollWidth = lpnm32W->iScrollWidth;
87 lpnm32A->iScrollHeight = lpnm32W->iScrollHeight;
88 lpnm32A->iCaptionWidth = lpnm32W->iCaptionWidth;
89 lpnm32A->iCaptionHeight = lpnm32W->iCaptionHeight;
90 SYSPARAMS_LogFont32WTo32A( &lpnm32W->lfCaptionFont, &lpnm32A->lfCaptionFont );
91 lpnm32A->iSmCaptionWidth = lpnm32W->iSmCaptionWidth;
92 lpnm32A->iSmCaptionHeight = lpnm32W->iSmCaptionHeight;
93 SYSPARAMS_LogFont32WTo32A( &lpnm32W->lfSmCaptionFont, &lpnm32A->lfSmCaptionFont );
94 lpnm32A->iMenuWidth = lpnm32W->iMenuWidth;
95 lpnm32A->iMenuHeight = lpnm32W->iMenuHeight;
96 SYSPARAMS_LogFont32WTo32A( &lpnm32W->lfMenuFont, &lpnm32A->lfMenuFont );
97 SYSPARAMS_LogFont32WTo32A( &lpnm32W->lfStatusFont, &lpnm32A->lfStatusFont );
98 SYSPARAMS_LogFont32WTo32A( &lpnm32W->lfMessageFont, &lpnm32A->lfMessageFont );
99 if (lpnm32A->cbSize > FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth))
101 if (lpnm32W->cbSize > FIELD_OFFSET(NONCLIENTMETRICSW, iPaddedBorderWidth))
102 lpnm32A->iPaddedBorderWidth = lpnm32W->iPaddedBorderWidth;
103 else
104 lpnm32A->iPaddedBorderWidth = 0;
108 static void SYSPARAMS_NonClientMetrics32ATo32W( const NONCLIENTMETRICSA* lpnm32A, LPNONCLIENTMETRICSW lpnm32W )
110 lpnm32W->iBorderWidth = lpnm32A->iBorderWidth;
111 lpnm32W->iScrollWidth = lpnm32A->iScrollWidth;
112 lpnm32W->iScrollHeight = lpnm32A->iScrollHeight;
113 lpnm32W->iCaptionWidth = lpnm32A->iCaptionWidth;
114 lpnm32W->iCaptionHeight = lpnm32A->iCaptionHeight;
115 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfCaptionFont, &lpnm32W->lfCaptionFont );
116 lpnm32W->iSmCaptionWidth = lpnm32A->iSmCaptionWidth;
117 lpnm32W->iSmCaptionHeight = lpnm32A->iSmCaptionHeight;
118 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfSmCaptionFont, &lpnm32W->lfSmCaptionFont );
119 lpnm32W->iMenuWidth = lpnm32A->iMenuWidth;
120 lpnm32W->iMenuHeight = lpnm32A->iMenuHeight;
121 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfMenuFont, &lpnm32W->lfMenuFont );
122 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfStatusFont, &lpnm32W->lfStatusFont );
123 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfMessageFont, &lpnm32W->lfMessageFont );
124 if (lpnm32W->cbSize > FIELD_OFFSET(NONCLIENTMETRICSW, iPaddedBorderWidth))
126 if (lpnm32A->cbSize > FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth))
127 lpnm32W->iPaddedBorderWidth = lpnm32A->iPaddedBorderWidth;
128 else
129 lpnm32W->iPaddedBorderWidth = 0;
134 /* Helper functions to retrieve monitors info */
136 HDC get_display_dc(void)
138 EnterCriticalSection( &display_dc_section );
139 if (!display_dc)
141 HDC dc;
143 LeaveCriticalSection( &display_dc_section );
144 dc = CreateDCW( L"DISPLAY", NULL, NULL, NULL );
145 EnterCriticalSection( &display_dc_section );
146 if (display_dc)
147 DeleteDC(dc);
148 else
149 display_dc = dc;
151 return display_dc;
154 void release_display_dc( HDC hdc )
156 LeaveCriticalSection( &display_dc_section );
159 /***********************************************************************
160 * SYSPARAMS_Init
162 void SYSPARAMS_Init(void)
164 system_dpi = NtUserGetSystemDpiForProcess( NULL );
167 static BOOL update_desktop_wallpaper(void)
169 DWORD pid;
171 if (GetWindowThreadProcessId( GetDesktopWindow(), &pid ) && pid == GetCurrentProcessId())
173 WCHAR wallpaper[MAX_PATH], pattern[256];
175 if (NtUserSystemParametersInfo( SPI_GETDESKWALLPAPER, ARRAYSIZE(wallpaper), wallpaper, 0 ) &&
176 NtUserCallOneParam( (ULONG_PTR)pattern, NtUserGetDeskPattern ))
178 update_wallpaper( wallpaper, pattern );
181 else SendMessageW( GetDesktopWindow(), WM_SETTINGCHANGE, SPI_SETDESKWALLPAPER, 0 );
182 return TRUE;
186 /***********************************************************************
187 * SystemParametersInfoForDpi (USER32.@)
189 BOOL WINAPI SystemParametersInfoForDpi( UINT action, UINT val, PVOID ptr, UINT winini, UINT dpi )
191 BOOL ret = NtUserSystemParametersInfoForDpi( action, val, ptr, winini, dpi );
192 if (ret && (action == SPI_SETDESKWALLPAPER || action == SPI_SETDESKPATTERN))
193 ret = update_desktop_wallpaper();
194 return ret;
198 /***********************************************************************
199 * SystemParametersInfoW (USER32.@)
201 BOOL WINAPI SystemParametersInfoW( UINT action, UINT val, void *ptr, UINT winini )
203 BOOL ret = NtUserSystemParametersInfo( action, val, ptr, winini );
204 if (ret && (action == SPI_SETDESKWALLPAPER || action == SPI_SETDESKPATTERN))
205 ret = update_desktop_wallpaper();
206 return ret;
210 /***********************************************************************
211 * SystemParametersInfoA (USER32.@)
213 BOOL WINAPI SystemParametersInfoA( UINT uiAction, UINT uiParam,
214 PVOID pvParam, UINT fuWinIni )
216 BOOL ret;
218 TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fuWinIni);
220 switch (uiAction)
222 case SPI_SETDESKWALLPAPER: /* 20 */
223 case SPI_SETDESKPATTERN: /* 21 */
225 WCHAR buffer[256];
226 if (pvParam)
227 if (!MultiByteToWideChar( CP_ACP, 0, pvParam, -1, buffer, ARRAY_SIZE( buffer )))
228 buffer[ARRAY_SIZE(buffer)-1] = 0;
229 ret = SystemParametersInfoW( uiAction, uiParam, pvParam ? buffer : NULL, fuWinIni );
230 break;
233 case SPI_GETICONTITLELOGFONT: /* 31 */
235 LOGFONTW tmp;
236 ret = SystemParametersInfoW( uiAction, uiParam, pvParam ? &tmp : NULL, fuWinIni );
237 if (ret && pvParam)
238 SYSPARAMS_LogFont32WTo32A( &tmp, pvParam );
239 break;
242 case SPI_GETNONCLIENTMETRICS: /* 41 WINVER >= 0x400 */
244 NONCLIENTMETRICSW tmp;
245 LPNONCLIENTMETRICSA lpnmA = pvParam;
246 if (lpnmA && (lpnmA->cbSize == sizeof(NONCLIENTMETRICSA) ||
247 lpnmA->cbSize == FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth)))
249 tmp.cbSize = sizeof(NONCLIENTMETRICSW);
250 ret = SystemParametersInfoW( uiAction, uiParam, &tmp, fuWinIni );
251 if (ret)
252 SYSPARAMS_NonClientMetrics32WTo32A( &tmp, lpnmA );
254 else
255 ret = FALSE;
256 break;
259 case SPI_SETNONCLIENTMETRICS: /* 42 WINVER >= 0x400 */
261 NONCLIENTMETRICSW tmp;
262 LPNONCLIENTMETRICSA lpnmA = pvParam;
263 if (lpnmA && (lpnmA->cbSize == sizeof(NONCLIENTMETRICSA) ||
264 lpnmA->cbSize == FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth)))
266 tmp.cbSize = sizeof(NONCLIENTMETRICSW);
267 SYSPARAMS_NonClientMetrics32ATo32W( lpnmA, &tmp );
268 ret = SystemParametersInfoW( uiAction, uiParam, &tmp, fuWinIni );
270 else
271 ret = FALSE;
272 break;
275 case SPI_GETICONMETRICS: /* 45 WINVER >= 0x400 */
277 ICONMETRICSW tmp;
278 LPICONMETRICSA lpimA = pvParam;
279 if (lpimA && lpimA->cbSize == sizeof(ICONMETRICSA))
281 tmp.cbSize = sizeof(ICONMETRICSW);
282 ret = SystemParametersInfoW( uiAction, uiParam, &tmp, fuWinIni );
283 if (ret)
285 lpimA->iHorzSpacing = tmp.iHorzSpacing;
286 lpimA->iVertSpacing = tmp.iVertSpacing;
287 lpimA->iTitleWrap = tmp.iTitleWrap;
288 SYSPARAMS_LogFont32WTo32A( &tmp.lfFont, &lpimA->lfFont );
291 else
292 ret = FALSE;
293 break;
296 case SPI_SETICONMETRICS: /* 46 WINVER >= 0x400 */
298 ICONMETRICSW tmp;
299 LPICONMETRICSA lpimA = pvParam;
300 if (lpimA && lpimA->cbSize == sizeof(ICONMETRICSA))
302 tmp.cbSize = sizeof(ICONMETRICSW);
303 tmp.iHorzSpacing = lpimA->iHorzSpacing;
304 tmp.iVertSpacing = lpimA->iVertSpacing;
305 tmp.iTitleWrap = lpimA->iTitleWrap;
306 SYSPARAMS_LogFont32ATo32W( &lpimA->lfFont, &tmp.lfFont);
307 ret = SystemParametersInfoW( uiAction, uiParam, &tmp, fuWinIni );
309 else
310 ret = FALSE;
311 break;
314 case SPI_GETHIGHCONTRAST: /* 66 WINVER >= 0x400 */
316 HIGHCONTRASTW tmp;
317 LPHIGHCONTRASTA lphcA = pvParam;
318 if (lphcA && lphcA->cbSize == sizeof(HIGHCONTRASTA))
320 tmp.cbSize = sizeof(HIGHCONTRASTW);
321 ret = SystemParametersInfoW( uiAction, uiParam, &tmp, fuWinIni );
322 if (ret)
324 lphcA->dwFlags = tmp.dwFlags;
325 lphcA->lpszDefaultScheme = NULL; /* FIXME? */
328 else
329 ret = FALSE;
330 break;
333 case SPI_GETDESKWALLPAPER: /* 115 */
335 WCHAR buffer[MAX_PATH];
336 ret = (SystemParametersInfoW( SPI_GETDESKWALLPAPER, uiParam, buffer, fuWinIni ) &&
337 WideCharToMultiByte(CP_ACP, 0, buffer, -1, pvParam, uiParam, NULL, NULL));
338 break;
341 default:
342 ret = SystemParametersInfoW( uiAction, uiParam, pvParam, fuWinIni );
343 break;
345 return ret;
349 /***********************************************************************
350 * GetSystemMetrics (USER32.@)
352 INT WINAPI GetSystemMetrics( INT index )
354 return NtUserGetSystemMetrics( index );
358 /***********************************************************************
359 * GetSystemMetricsForDpi (USER32.@)
361 INT WINAPI GetSystemMetricsForDpi( INT index, UINT dpi )
363 return NtUserGetSystemMetricsForDpi( index, dpi );
367 /***********************************************************************
368 * SwapMouseButton (USER32.@)
369 * Reverse or restore the meaning of the left and right mouse buttons
370 * fSwap [I ] TRUE - reverse, FALSE - original
371 * RETURN
372 * previous state
374 BOOL WINAPI SwapMouseButton( BOOL fSwap )
376 BOOL prev = GetSystemMetrics(SM_SWAPBUTTON);
377 SystemParametersInfoW(SPI_SETMOUSEBUTTONSWAP, fSwap, 0, 0);
378 return prev;
382 /**********************************************************************
383 * SetDoubleClickTime (USER32.@)
385 BOOL WINAPI SetDoubleClickTime( UINT interval )
387 return SystemParametersInfoW(SPI_SETDOUBLECLICKTIME, interval, 0, 0);
391 /*************************************************************************
392 * GetSysColor (USER32.@)
394 COLORREF WINAPI DECLSPEC_HOTPATCH GetSysColor( INT index )
396 return NtUserGetSysColor( index );
400 /*************************************************************************
401 * SetSysColorsTemp (USER32.@)
403 DWORD_PTR WINAPI SetSysColorsTemp( const COLORREF *pPens, const HBRUSH *pBrushes, DWORD_PTR n)
405 FIXME( "no longer supported\n" );
406 return FALSE;
410 /***********************************************************************
411 * GetSysColorBrush (USER32.@)
413 HBRUSH WINAPI DECLSPEC_HOTPATCH GetSysColorBrush( INT index )
415 return NtUserGetSysColorBrush( index );
419 /***********************************************************************
420 * SYSCOLOR_GetPen
422 HPEN SYSCOLOR_GetPen( INT index )
424 return NtUserGetSysColorPen( index );
428 /***********************************************************************
429 * SYSCOLOR_Get55AABrush
431 HBRUSH SYSCOLOR_Get55AABrush(void)
433 return NtUserGetSysColorBrush( COLOR_55AA_BRUSH );
436 /***********************************************************************
437 * ChangeDisplaySettingsA (USER32.@)
439 LONG WINAPI ChangeDisplaySettingsA( LPDEVMODEA devmode, DWORD flags )
441 if (devmode) devmode->dmDriverExtra = 0;
443 return ChangeDisplaySettingsExA(NULL,devmode,NULL,flags,NULL);
447 /***********************************************************************
448 * ChangeDisplaySettingsW (USER32.@)
450 LONG WINAPI ChangeDisplaySettingsW( LPDEVMODEW devmode, DWORD flags )
452 if (devmode) devmode->dmDriverExtra = 0;
454 return ChangeDisplaySettingsExW(NULL,devmode,NULL,flags,NULL);
458 /***********************************************************************
459 * ChangeDisplaySettingsExA (USER32.@)
461 LONG WINAPI ChangeDisplaySettingsExA( LPCSTR devname, LPDEVMODEA devmode, HWND hwnd,
462 DWORD flags, LPVOID lparam )
464 LONG ret;
465 UNICODE_STRING nameW;
467 if (devname) RtlCreateUnicodeStringFromAsciiz(&nameW, devname);
468 else nameW.Buffer = NULL;
470 if (devmode)
472 DEVMODEW *devmodeW;
474 devmodeW = GdiConvertToDevmodeW(devmode);
475 if (devmodeW)
477 ret = ChangeDisplaySettingsExW(nameW.Buffer, devmodeW, hwnd, flags, lparam);
478 HeapFree(GetProcessHeap(), 0, devmodeW);
480 else
481 ret = DISP_CHANGE_SUCCESSFUL;
483 else
485 ret = ChangeDisplaySettingsExW(nameW.Buffer, NULL, hwnd, flags, lparam);
488 if (devname) RtlFreeUnicodeString(&nameW);
489 return ret;
493 /***********************************************************************
494 * ChangeDisplaySettingsExW (USER32.@)
496 LONG WINAPI ChangeDisplaySettingsExW( LPCWSTR devname, LPDEVMODEW devmode, HWND hwnd,
497 DWORD flags, LPVOID lparam )
499 UNICODE_STRING str;
500 RtlInitUnicodeString( &str, devname );
501 return NtUserChangeDisplaySettings( &str, devmode, hwnd, flags, lparam );
505 /***********************************************************************
506 * EnumDisplaySettingsW (USER32.@)
508 * RETURNS
509 * TRUE if nth setting exists found (described in the LPDEVMODEW struct)
510 * FALSE if we do not have the nth setting
512 BOOL WINAPI EnumDisplaySettingsW( LPCWSTR name, DWORD n, LPDEVMODEW devmode )
514 return EnumDisplaySettingsExW(name, n, devmode, 0);
518 /***********************************************************************
519 * EnumDisplaySettingsA (USER32.@)
521 BOOL WINAPI EnumDisplaySettingsA(LPCSTR name,DWORD n,LPDEVMODEA devmode)
523 return EnumDisplaySettingsExA(name, n, devmode, 0);
527 /***********************************************************************
528 * EnumDisplaySettingsExA (USER32.@)
530 BOOL WINAPI EnumDisplaySettingsExA(LPCSTR lpszDeviceName, DWORD iModeNum,
531 LPDEVMODEA lpDevMode, DWORD dwFlags)
533 DEVMODEW devmodeW;
534 BOOL ret;
535 UNICODE_STRING nameW;
537 if (lpszDeviceName) RtlCreateUnicodeStringFromAsciiz(&nameW, lpszDeviceName);
538 else nameW.Buffer = NULL;
540 memset(&devmodeW, 0, sizeof(devmodeW));
541 devmodeW.dmSize = sizeof(devmodeW);
542 ret = EnumDisplaySettingsExW(nameW.Buffer,iModeNum,&devmodeW,dwFlags);
543 if (ret)
545 lpDevMode->dmSize = FIELD_OFFSET(DEVMODEA, dmICMMethod);
546 lpDevMode->dmSpecVersion = devmodeW.dmSpecVersion;
547 lpDevMode->dmDriverVersion = devmodeW.dmDriverVersion;
548 WideCharToMultiByte(CP_ACP, 0, devmodeW.dmDeviceName, -1,
549 (LPSTR)lpDevMode->dmDeviceName, CCHDEVICENAME, NULL, NULL);
550 lpDevMode->dmDriverExtra = 0; /* FIXME */
551 lpDevMode->dmBitsPerPel = devmodeW.dmBitsPerPel;
552 lpDevMode->dmPelsHeight = devmodeW.dmPelsHeight;
553 lpDevMode->dmPelsWidth = devmodeW.dmPelsWidth;
554 lpDevMode->dmDisplayFlags = devmodeW.dmDisplayFlags;
555 lpDevMode->dmDisplayFrequency = devmodeW.dmDisplayFrequency;
556 lpDevMode->dmFields = devmodeW.dmFields;
558 lpDevMode->dmPosition.x = devmodeW.dmPosition.x;
559 lpDevMode->dmPosition.y = devmodeW.dmPosition.y;
560 lpDevMode->dmDisplayOrientation = devmodeW.dmDisplayOrientation;
561 lpDevMode->dmDisplayFixedOutput = devmodeW.dmDisplayFixedOutput;
563 if (lpszDeviceName) RtlFreeUnicodeString(&nameW);
564 return ret;
568 /***********************************************************************
569 * EnumDisplaySettingsExW (USER32.@)
571 BOOL WINAPI EnumDisplaySettingsExW( const WCHAR *device, DWORD mode,
572 DEVMODEW *dev_mode, DWORD flags )
574 UNICODE_STRING str;
575 RtlInitUnicodeString( &str, device );
576 return NtUserEnumDisplaySettings( &str, mode, dev_mode, flags );
579 /**********************************************************************
580 * SetProcessDpiAwarenessContext (USER32.@)
582 BOOL WINAPI SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT context )
584 ULONG awareness;
586 switch (GetAwarenessFromDpiAwarenessContext( context ))
588 case DPI_AWARENESS_UNAWARE:
589 awareness = NTUSER_DPI_UNAWARE;
590 break;
591 case DPI_AWARENESS_SYSTEM_AWARE:
592 awareness = NTUSER_DPI_SYSTEM_AWARE;
593 break;
594 case DPI_AWARENESS_PER_MONITOR_AWARE:
595 awareness = context == DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
596 ? NTUSER_DPI_PER_MONITOR_AWARE_V2 : NTUSER_DPI_PER_MONITOR_AWARE;
597 break;
598 default:
599 SetLastError( ERROR_INVALID_PARAMETER );
600 return FALSE;
603 if (!NtUserSetProcessDpiAwarenessContext( awareness, 0 ))
605 SetLastError( ERROR_ACCESS_DENIED );
606 return FALSE;
609 TRACE( "set to %p\n", context );
610 return TRUE;
613 /**********************************************************************
614 * GetProcessDpiAwarenessInternal (USER32.@)
616 BOOL WINAPI GetProcessDpiAwarenessInternal( HANDLE process, DPI_AWARENESS *awareness )
618 *awareness = NtUserGetProcessDpiAwarenessContext( process ) & 3;
619 return TRUE;
622 /**********************************************************************
623 * SetProcessDpiAwarenessInternal (USER32.@)
625 BOOL WINAPI SetProcessDpiAwarenessInternal( DPI_AWARENESS awareness )
627 static const DPI_AWARENESS_CONTEXT contexts[3] = { DPI_AWARENESS_CONTEXT_UNAWARE,
628 DPI_AWARENESS_CONTEXT_SYSTEM_AWARE,
629 DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE };
631 if (awareness < DPI_AWARENESS_UNAWARE || awareness > DPI_AWARENESS_PER_MONITOR_AWARE)
633 SetLastError( ERROR_INVALID_PARAMETER );
634 return FALSE;
636 return SetProcessDpiAwarenessContext( contexts[awareness] );
639 static ULONG_PTR map_awareness_context( DPI_AWARENESS_CONTEXT ctx )
641 if (ctx == DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 || ctx == (DPI_AWARENESS_CONTEXT)0x22 || ctx == (DPI_AWARENESS_CONTEXT)0x80000022)
642 return 0x22;
643 return GetAwarenessFromDpiAwarenessContext(ctx);
646 /***********************************************************************
647 * AreDpiAwarenessContextsEqual (USER32.@)
649 BOOL WINAPI AreDpiAwarenessContextsEqual( DPI_AWARENESS_CONTEXT ctx1, DPI_AWARENESS_CONTEXT ctx2 )
651 DPI_AWARENESS aware1 = map_awareness_context( ctx1 );
652 DPI_AWARENESS aware2 = map_awareness_context( ctx2 );
653 return aware1 != DPI_AWARENESS_INVALID && aware1 == aware2;
656 /***********************************************************************
657 * GetAwarenessFromDpiAwarenessContext (USER32.@)
658 * copied into win32u, make sure to keep that in sync
660 DPI_AWARENESS WINAPI GetAwarenessFromDpiAwarenessContext( DPI_AWARENESS_CONTEXT context )
662 switch ((ULONG_PTR)context)
664 case 0x10:
665 case 0x11:
666 case 0x12:
667 case 0x22:
668 case 0x80000010:
669 case 0x80000011:
670 case 0x80000012:
671 case 0x80000022:
672 return (ULONG_PTR)context & 3;
673 case (ULONG_PTR)DPI_AWARENESS_CONTEXT_UNAWARE:
674 case (ULONG_PTR)DPI_AWARENESS_CONTEXT_SYSTEM_AWARE:
675 case (ULONG_PTR)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE:
676 return ~(ULONG_PTR)context;
677 case (ULONG_PTR)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2:
678 return ~(ULONG_PTR)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE;
679 default:
680 return DPI_AWARENESS_INVALID;
684 /***********************************************************************
685 * IsValidDpiAwarenessContext (USER32.@)
687 BOOL WINAPI IsValidDpiAwarenessContext( DPI_AWARENESS_CONTEXT context )
689 return GetAwarenessFromDpiAwarenessContext( context ) != DPI_AWARENESS_INVALID;
692 /***********************************************************************
693 * SetProcessDPIAware (USER32.@)
695 BOOL WINAPI SetProcessDPIAware(void)
697 TRACE("\n");
698 NtUserSetProcessDpiAwarenessContext( NTUSER_DPI_SYSTEM_AWARE, 0 );
699 return TRUE;
702 /***********************************************************************
703 * IsProcessDPIAware (USER32.@)
705 BOOL WINAPI IsProcessDPIAware(void)
707 return GetAwarenessFromDpiAwarenessContext( GetThreadDpiAwarenessContext() ) != DPI_AWARENESS_UNAWARE;
710 /**********************************************************************
711 * EnableNonClientDpiScaling (USER32.@)
713 BOOL WINAPI EnableNonClientDpiScaling( HWND hwnd )
715 FIXME("(%p): stub\n", hwnd);
716 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
717 return FALSE;
720 /***********************************************************************
721 * GetDpiForSystem (USER32.@)
723 UINT WINAPI GetDpiForSystem(void)
725 if (!IsProcessDPIAware()) return USER_DEFAULT_SCREEN_DPI;
726 return system_dpi;
729 /**********************************************************************
730 * GetThreadDpiAwarenessContext (USER32.@)
732 DPI_AWARENESS_CONTEXT WINAPI GetThreadDpiAwarenessContext(void)
734 struct ntuser_thread_info *info = NtUserGetThreadInfo();
736 if (info->dpi_awareness) return ULongToHandle( info->dpi_awareness );
737 return UlongToHandle( (NtUserGetProcessDpiAwarenessContext( GetCurrentProcess() ) & 3 ) | 0x10 );
740 /**********************************************************************
741 * SetThreadDpiAwarenessContext (USER32.@)
742 * copied into win32u, make sure to keep that in sync
744 DPI_AWARENESS_CONTEXT WINAPI SetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT context )
746 struct ntuser_thread_info *info = NtUserGetThreadInfo();
747 DPI_AWARENESS prev, val = GetAwarenessFromDpiAwarenessContext( context );
749 if (val == DPI_AWARENESS_INVALID)
751 SetLastError( ERROR_INVALID_PARAMETER );
752 return 0;
754 if (!(prev = info->dpi_awareness))
756 prev = NtUserGetProcessDpiAwarenessContext( GetCurrentProcess() ) & 3;
757 prev |= 0x80000010; /* restore to process default */
759 if (((ULONG_PTR)context & ~(ULONG_PTR)0x33) == 0x80000000) info->dpi_awareness = 0;
760 else if (context == DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 || context == (DPI_AWARENESS_CONTEXT)0x22)
761 info->dpi_awareness = 0x22;
762 else info->dpi_awareness = val | 0x10;
763 return ULongToHandle( prev );
766 /**********************************************************************
767 * GetThreadDpiHostingBehavior (USER32.@)
769 DPI_HOSTING_BEHAVIOR WINAPI GetThreadDpiHostingBehavior( void )
771 FIXME("(): stub\n");
772 return DPI_HOSTING_BEHAVIOR_DEFAULT;
775 /**********************************************************************
776 * SetThreadDpiHostingBehavior (USER32.@)
778 DPI_HOSTING_BEHAVIOR WINAPI SetThreadDpiHostingBehavior( DPI_HOSTING_BEHAVIOR value )
780 FIXME("(%d): stub\n", value);
781 return DPI_HOSTING_BEHAVIOR_DEFAULT;
784 /***********************************************************************
785 * MonitorFromRect (USER32.@)
787 HMONITOR WINAPI MonitorFromRect( const RECT *rect, DWORD flags )
789 return NtUserMonitorFromRect( rect, flags );
792 /***********************************************************************
793 * MonitorFromPoint (USER32.@)
795 HMONITOR WINAPI MonitorFromPoint( POINT pt, DWORD flags )
797 RECT rect;
799 SetRect( &rect, pt.x, pt.y, pt.x + 1, pt.y + 1 );
800 return MonitorFromRect( &rect, flags );
803 /***********************************************************************
804 * MonitorFromWindow (USER32.@)
806 HMONITOR WINAPI MonitorFromWindow( HWND hwnd, DWORD flags )
808 return NtUserMonitorFromWindow( hwnd, flags );
811 /***********************************************************************
812 * GetMonitorInfoA (USER32.@)
814 BOOL WINAPI GetMonitorInfoA( HMONITOR monitor, LPMONITORINFO info )
816 MONITORINFOEXW miW;
817 BOOL ret;
819 if (info->cbSize == sizeof(MONITORINFO)) return GetMonitorInfoW( monitor, info );
820 if (info->cbSize != sizeof(MONITORINFOEXA)) return FALSE;
822 miW.cbSize = sizeof(miW);
823 ret = GetMonitorInfoW( monitor, (MONITORINFO *)&miW );
824 if (ret)
826 MONITORINFOEXA *miA = (MONITORINFOEXA *)info;
827 miA->rcMonitor = miW.rcMonitor;
828 miA->rcWork = miW.rcWork;
829 miA->dwFlags = miW.dwFlags;
830 WideCharToMultiByte(CP_ACP, 0, miW.szDevice, -1, miA->szDevice, sizeof(miA->szDevice), NULL, NULL);
832 return ret;
835 /***********************************************************************
836 * GetMonitorInfoW (USER32.@)
838 BOOL WINAPI GetMonitorInfoW( HMONITOR monitor, LPMONITORINFO info )
840 return NtUserGetMonitorInfo( monitor, info );
843 #ifdef __i386__
844 /* Some apps pass a non-stdcall callback to EnumDisplayMonitors,
845 * so we need a small assembly wrapper to call it.
847 extern BOOL enum_mon_callback_wrapper( void *proc, HMONITOR monitor, HDC hdc, RECT *rect, LPARAM lparam );
848 __ASM_GLOBAL_FUNC( enum_mon_callback_wrapper,
849 "pushl %ebp\n\t"
850 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
851 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
852 "movl %esp,%ebp\n\t"
853 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
854 "subl $8,%esp\n\t"
855 "pushl 24(%ebp)\n\t" /* lparam */
856 /* MJ's Help Diagnostic expects that %ecx contains the address to the rect. */
857 "movl 20(%ebp),%ecx\n\t" /* rect */
858 "pushl %ecx\n\t"
859 "pushl 16(%ebp)\n\t" /* hdc */
860 "pushl 12(%ebp)\n\t" /* monitor */
861 "movl 8(%ebp),%eax\n" /* proc */
862 "call *%eax\n\t"
863 "leave\n\t"
864 __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
865 __ASM_CFI(".cfi_same_value %ebp\n\t")
866 "ret" )
867 #endif /* __i386__ */
869 NTSTATUS WINAPI User32CallEnumDisplayMonitor( void *args, ULONG size )
871 struct enum_display_monitor_params *params = args;
872 BOOL ret;
873 #ifdef __i386__
874 ret = enum_mon_callback_wrapper( params->proc, params->monitor, params->hdc,
875 &params->rect, params->lparam );
876 #else
877 ret = params->proc( params->monitor, params->hdc, &params->rect, params->lparam );
878 #endif
879 return NtCallbackReturn( &ret, sizeof(ret), STATUS_SUCCESS );
882 /***********************************************************************
883 * EnumDisplayDevicesA (USER32.@)
885 BOOL WINAPI EnumDisplayDevicesA( LPCSTR device, DWORD index, DISPLAY_DEVICEA *info, DWORD flags )
887 UNICODE_STRING deviceW;
888 DISPLAY_DEVICEW ddW;
889 BOOL ret;
891 if (device)
892 RtlCreateUnicodeStringFromAsciiz( &deviceW, device );
893 else
894 deviceW.Buffer = NULL;
896 ddW.cb = sizeof(ddW);
897 ret = EnumDisplayDevicesW( deviceW.Buffer, index, &ddW, flags );
898 RtlFreeUnicodeString( &deviceW );
900 if (!ret)
901 return ret;
903 WideCharToMultiByte( CP_ACP, 0, ddW.DeviceName, -1, info->DeviceName, sizeof(info->DeviceName), NULL, NULL );
904 WideCharToMultiByte( CP_ACP, 0, ddW.DeviceString, -1, info->DeviceString, sizeof(info->DeviceString), NULL, NULL );
905 info->StateFlags = ddW.StateFlags;
907 if (info->cb >= offsetof(DISPLAY_DEVICEA, DeviceID) + sizeof(info->DeviceID))
908 WideCharToMultiByte( CP_ACP, 0, ddW.DeviceID, -1, info->DeviceID, sizeof(info->DeviceID), NULL, NULL );
909 if (info->cb >= offsetof(DISPLAY_DEVICEA, DeviceKey) + sizeof(info->DeviceKey))
910 WideCharToMultiByte( CP_ACP, 0, ddW.DeviceKey, -1, info->DeviceKey, sizeof(info->DeviceKey), NULL, NULL );
912 return TRUE;
915 /***********************************************************************
916 * EnumDisplayDevicesW (USER32.@)
918 BOOL WINAPI EnumDisplayDevicesW( LPCWSTR device, DWORD index, DISPLAY_DEVICEW *info, DWORD flags )
920 UNICODE_STRING str;
921 RtlInitUnicodeString( &str, device );
922 return NT_SUCCESS(NtUserEnumDisplayDevices( &str, index, info, flags ));
925 /**********************************************************************
926 * GetAutoRotationState [USER32.@]
928 BOOL WINAPI GetAutoRotationState( AR_STATE *state )
930 TRACE("(%p)\n", state);
932 if (!state)
934 SetLastError(ERROR_INVALID_PARAMETER);
935 return FALSE;
938 *state = AR_NOSENSOR;
939 return TRUE;
942 /**********************************************************************
943 * GetDisplayAutoRotationPreferences (USER32.@)
945 BOOL WINAPI GetDisplayAutoRotationPreferences( ORIENTATION_PREFERENCE *orientation )
947 FIXME("(%p): stub\n", orientation);
948 *orientation = ORIENTATION_PREFERENCE_NONE;
949 return TRUE;
952 /**********************************************************************
953 * SetDisplayAutoRotationPreferences (USER32.@)
955 BOOL WINAPI SetDisplayAutoRotationPreferences( ORIENTATION_PREFERENCE orientation )
957 FIXME("(%d): stub\n", orientation);
958 return TRUE;
961 /* physical<->logical mapping functions from win8 that are nops in later versions */
963 /***********************************************************************
964 * GetPhysicalCursorPos (USER32.@)
966 BOOL WINAPI GetPhysicalCursorPos( POINT *point )
968 return GetCursorPos( point );
971 /***********************************************************************
972 * SetPhysicalCursorPos (USER32.@)
974 BOOL WINAPI SetPhysicalCursorPos( INT x, INT y )
976 return NtUserSetCursorPos( x, y );
979 /***********************************************************************
980 * WindowFromPhysicalPoint (USER32.@)
982 HWND WINAPI WindowFromPhysicalPoint( POINT pt )
984 return WindowFromPoint( pt );
987 /***********************************************************************
988 * LogicalToPhysicalPoint (USER32.@)
990 BOOL WINAPI LogicalToPhysicalPoint( HWND hwnd, POINT *point )
992 return TRUE;
995 /***********************************************************************
996 * PhysicalToLogicalPoint (USER32.@)
998 BOOL WINAPI PhysicalToLogicalPoint( HWND hwnd, POINT *point )
1000 return TRUE;
1003 /***********************************************************************
1004 * DisplayConfigGetDeviceInfo (USER32.@)
1006 LONG WINAPI DisplayConfigGetDeviceInfo(DISPLAYCONFIG_DEVICE_INFO_HEADER *packet)
1008 return RtlNtStatusToDosError(NtUserDisplayConfigGetDeviceInfo(packet));
1011 /***********************************************************************
1012 * SetDisplayConfig (USER32.@)
1014 LONG WINAPI SetDisplayConfig(UINT32 path_info_count, DISPLAYCONFIG_PATH_INFO *path_info, UINT32 mode_info_count,
1015 DISPLAYCONFIG_MODE_INFO *mode_info, UINT32 flags)
1017 FIXME("path_info_count %u, path_info %p, mode_info_count %u, mode_info %p, flags %#x stub.\n",
1018 path_info_count, path_info, mode_info_count, mode_info, flags);
1020 return ERROR_SUCCESS;