ucrtbase: Store exception record in ExceptionInformation[6] during unwinding.
[wine.git] / dlls / user32 / sysparams.c
blob273dccc6930cac3674f5f30589817c22dd0218f9
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 static UINT get_ntuser_dpi_context( DPI_AWARENESS_CONTEXT context )
581 switch ((UINT_PTR)context)
583 case (UINT_PTR)DPI_AWARENESS_CONTEXT_UNAWARE: return NTUSER_DPI_UNAWARE;
584 case (UINT_PTR)DPI_AWARENESS_CONTEXT_SYSTEM_AWARE: return NTUSER_DPI_SYSTEM_AWARE;
585 case (UINT_PTR)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE: return NTUSER_DPI_PER_MONITOR_AWARE;
586 case (UINT_PTR)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2: return NTUSER_DPI_PER_MONITOR_AWARE_V2;
587 case (UINT_PTR)DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED: return NTUSER_DPI_PER_UNAWARE_GDISCALED;
590 return (UINT_PTR)context;
593 /* keep in sync with win32u */
594 static BOOL is_valid_dpi_awareness_context( UINT context, UINT dpi )
596 switch (NTUSER_DPI_CONTEXT_GET_AWARENESS( context ))
598 case DPI_AWARENESS_UNAWARE:
599 if (NTUSER_DPI_CONTEXT_GET_FLAGS( context ) & ~NTUSER_DPI_CONTEXT_FLAG_VALID_MASK) return FALSE;
600 if (NTUSER_DPI_CONTEXT_GET_VERSION( context ) != 1) return FALSE;
601 if (NTUSER_DPI_CONTEXT_GET_DPI( context ) != USER_DEFAULT_SCREEN_DPI) return FALSE;
602 return TRUE;
604 case DPI_AWARENESS_SYSTEM_AWARE:
605 if (NTUSER_DPI_CONTEXT_GET_FLAGS( context ) & ~NTUSER_DPI_CONTEXT_FLAG_VALID_MASK) return FALSE;
606 if (NTUSER_DPI_CONTEXT_GET_FLAGS( context ) & NTUSER_DPI_CONTEXT_FLAG_GDISCALED) return FALSE;
607 if (NTUSER_DPI_CONTEXT_GET_VERSION( context ) != 1) return FALSE;
608 if (dpi && NTUSER_DPI_CONTEXT_GET_DPI( context ) != dpi) return FALSE;
609 return TRUE;
611 case DPI_AWARENESS_PER_MONITOR_AWARE:
612 if (NTUSER_DPI_CONTEXT_GET_FLAGS( context ) & ~NTUSER_DPI_CONTEXT_FLAG_VALID_MASK) return FALSE;
613 if (NTUSER_DPI_CONTEXT_GET_FLAGS( context ) & NTUSER_DPI_CONTEXT_FLAG_GDISCALED) return FALSE;
614 if (NTUSER_DPI_CONTEXT_GET_VERSION( context ) != 1 && NTUSER_DPI_CONTEXT_GET_VERSION( context ) != 2) return FALSE;
615 if (NTUSER_DPI_CONTEXT_GET_DPI( context )) return FALSE;
616 return TRUE;
619 return FALSE;
622 /* keep in sync with win32u */
623 UINT set_thread_dpi_awareness_context( UINT context )
625 struct ntuser_thread_info *info = NtUserGetThreadInfo();
626 UINT prev;
628 if (!is_valid_dpi_awareness_context( context, system_dpi ))
630 RtlSetLastWin32Error( ERROR_INVALID_PARAMETER );
631 return 0;
634 if (!(prev = info->dpi_context)) prev = NtUserGetProcessDpiAwarenessContext( GetCurrentProcess() ) | NTUSER_DPI_CONTEXT_FLAG_PROCESS;
635 if (NTUSER_DPI_CONTEXT_GET_FLAGS( context ) & NTUSER_DPI_CONTEXT_FLAG_PROCESS) info->dpi_context = 0;
636 else info->dpi_context = context;
638 return prev;
641 /**********************************************************************
642 * SetProcessDpiAwarenessContext (USER32.@)
644 BOOL WINAPI SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT context )
646 UINT value = get_ntuser_dpi_context( context );
647 return NtUserSetProcessDpiAwarenessContext( value, 0 );
650 /**********************************************************************
651 * GetProcessDpiAwarenessInternal (USER32.@)
653 BOOL WINAPI GetProcessDpiAwarenessInternal( HANDLE process, DPI_AWARENESS *awareness )
655 ULONG context = NtUserGetProcessDpiAwarenessContext( process );
656 *awareness = NTUSER_DPI_CONTEXT_GET_AWARENESS( context );
657 return TRUE;
660 /**********************************************************************
661 * SetProcessDpiAwarenessInternal (USER32.@)
663 BOOL WINAPI SetProcessDpiAwarenessInternal( DPI_AWARENESS awareness )
665 static const DPI_AWARENESS_CONTEXT contexts[3] = { DPI_AWARENESS_CONTEXT_UNAWARE,
666 DPI_AWARENESS_CONTEXT_SYSTEM_AWARE,
667 DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE };
669 if (awareness < DPI_AWARENESS_UNAWARE || awareness > DPI_AWARENESS_PER_MONITOR_AWARE)
671 SetLastError( ERROR_INVALID_PARAMETER );
672 return FALSE;
674 return SetProcessDpiAwarenessContext( contexts[awareness] );
677 /***********************************************************************
678 * AreDpiAwarenessContextsEqual (USER32.@)
680 BOOL WINAPI AreDpiAwarenessContextsEqual( DPI_AWARENESS_CONTEXT ctx1, DPI_AWARENESS_CONTEXT ctx2 )
682 UINT value1, value2;
683 if (!(value1 = get_ntuser_dpi_context( ctx1 ))) return FALSE;
684 if (!(value2 = get_ntuser_dpi_context( ctx2 ))) return FALSE;
685 return (value1 & ~NTUSER_DPI_CONTEXT_FLAG_PROCESS) == (value2 & ~NTUSER_DPI_CONTEXT_FLAG_PROCESS);
688 /***********************************************************************
689 * GetAwarenessFromDpiAwarenessContext (USER32.@)
690 * copied into win32u, make sure to keep that in sync
692 DPI_AWARENESS WINAPI GetAwarenessFromDpiAwarenessContext( DPI_AWARENESS_CONTEXT context )
694 UINT value = get_ntuser_dpi_context( context );
695 if (!is_valid_dpi_awareness_context( value, 0 )) return DPI_AWARENESS_INVALID;
696 return NTUSER_DPI_CONTEXT_GET_AWARENESS( value );
699 /***********************************************************************
700 * GetDpiFromDpiAwarenessContext (USER32.@)
702 UINT WINAPI GetDpiFromDpiAwarenessContext( DPI_AWARENESS_CONTEXT handle )
704 UINT context = get_ntuser_dpi_context( handle );
705 return NTUSER_DPI_CONTEXT_GET_DPI( context );
708 /***********************************************************************
709 * IsValidDpiAwarenessContext (USER32.@)
711 BOOL WINAPI IsValidDpiAwarenessContext( DPI_AWARENESS_CONTEXT context )
713 UINT value = get_ntuser_dpi_context( context );
714 return is_valid_dpi_awareness_context( value, 0 );
717 /***********************************************************************
718 * SetProcessDPIAware (USER32.@)
720 BOOL WINAPI SetProcessDPIAware(void)
722 TRACE("\n");
723 NtUserSetProcessDpiAwarenessContext( NTUSER_DPI_SYSTEM_AWARE, 0 );
724 return TRUE;
727 /***********************************************************************
728 * IsProcessDPIAware (USER32.@)
730 BOOL WINAPI IsProcessDPIAware(void)
732 return GetAwarenessFromDpiAwarenessContext( GetThreadDpiAwarenessContext() ) != DPI_AWARENESS_UNAWARE;
735 /**********************************************************************
736 * EnableNonClientDpiScaling (USER32.@)
738 BOOL WINAPI EnableNonClientDpiScaling( HWND hwnd )
740 FIXME("(%p): stub\n", hwnd);
741 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
742 return FALSE;
745 /***********************************************************************
746 * GetDpiForSystem (USER32.@)
748 UINT WINAPI GetDpiForSystem(void)
750 if (!IsProcessDPIAware()) return USER_DEFAULT_SCREEN_DPI;
751 return system_dpi;
754 /**********************************************************************
755 * GetThreadDpiAwarenessContext (USER32.@)
757 DPI_AWARENESS_CONTEXT WINAPI GetThreadDpiAwarenessContext(void)
759 struct ntuser_thread_info *info = NtUserGetThreadInfo();
761 if (info->dpi_context) return ULongToHandle( info->dpi_context );
762 return ULongToHandle( NtUserGetProcessDpiAwarenessContext( GetCurrentProcess() ) );
765 /**********************************************************************
766 * SetThreadDpiAwarenessContext (USER32.@)
768 DPI_AWARENESS_CONTEXT WINAPI SetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT context )
770 return ULongToHandle( set_thread_dpi_awareness_context( get_ntuser_dpi_context( context ) ) );
773 /**********************************************************************
774 * GetThreadDpiHostingBehavior (USER32.@)
776 DPI_HOSTING_BEHAVIOR WINAPI GetThreadDpiHostingBehavior( void )
778 FIXME("(): stub\n");
779 return DPI_HOSTING_BEHAVIOR_DEFAULT;
782 /**********************************************************************
783 * SetThreadDpiHostingBehavior (USER32.@)
785 DPI_HOSTING_BEHAVIOR WINAPI SetThreadDpiHostingBehavior( DPI_HOSTING_BEHAVIOR value )
787 FIXME("(%d): stub\n", value);
788 return DPI_HOSTING_BEHAVIOR_DEFAULT;
791 /***********************************************************************
792 * MonitorFromRect (USER32.@)
794 HMONITOR WINAPI MonitorFromRect( const RECT *rect, DWORD flags )
796 return NtUserMonitorFromRect( rect, flags );
799 /***********************************************************************
800 * MonitorFromPoint (USER32.@)
802 HMONITOR WINAPI MonitorFromPoint( POINT pt, DWORD flags )
804 RECT rect;
806 SetRect( &rect, pt.x, pt.y, pt.x + 1, pt.y + 1 );
807 return MonitorFromRect( &rect, flags );
810 /***********************************************************************
811 * MonitorFromWindow (USER32.@)
813 HMONITOR WINAPI MonitorFromWindow( HWND hwnd, DWORD flags )
815 return NtUserMonitorFromWindow( hwnd, flags );
818 /***********************************************************************
819 * GetMonitorInfoA (USER32.@)
821 BOOL WINAPI GetMonitorInfoA( HMONITOR monitor, LPMONITORINFO info )
823 MONITORINFOEXW miW;
824 BOOL ret;
826 if (info->cbSize == sizeof(MONITORINFO)) return GetMonitorInfoW( monitor, info );
827 if (info->cbSize != sizeof(MONITORINFOEXA)) return FALSE;
829 miW.cbSize = sizeof(miW);
830 ret = GetMonitorInfoW( monitor, (MONITORINFO *)&miW );
831 if (ret)
833 MONITORINFOEXA *miA = (MONITORINFOEXA *)info;
834 miA->rcMonitor = miW.rcMonitor;
835 miA->rcWork = miW.rcWork;
836 miA->dwFlags = miW.dwFlags;
837 WideCharToMultiByte(CP_ACP, 0, miW.szDevice, -1, miA->szDevice, sizeof(miA->szDevice), NULL, NULL);
839 return ret;
842 /***********************************************************************
843 * GetMonitorInfoW (USER32.@)
845 BOOL WINAPI GetMonitorInfoW( HMONITOR monitor, LPMONITORINFO info )
847 return NtUserGetMonitorInfo( monitor, info );
850 #ifdef __i386__
851 /* Some apps pass a non-stdcall callback to EnumDisplayMonitors,
852 * so we need a small assembly wrapper to call it.
854 extern BOOL enum_mon_callback_wrapper( void *proc, HMONITOR monitor, HDC hdc, RECT *rect, LPARAM lparam );
855 __ASM_GLOBAL_FUNC( enum_mon_callback_wrapper,
856 "pushl %ebp\n\t"
857 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
858 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
859 "movl %esp,%ebp\n\t"
860 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
861 "subl $8,%esp\n\t"
862 "pushl 24(%ebp)\n\t" /* lparam */
863 /* MJ's Help Diagnostic expects that %ecx contains the address to the rect. */
864 "movl 20(%ebp),%ecx\n\t" /* rect */
865 "pushl %ecx\n\t"
866 "pushl 16(%ebp)\n\t" /* hdc */
867 "pushl 12(%ebp)\n\t" /* monitor */
868 "movl 8(%ebp),%eax\n" /* proc */
869 "call *%eax\n\t"
870 "leave\n\t"
871 __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
872 __ASM_CFI(".cfi_same_value %ebp\n\t")
873 "ret" )
874 #endif /* __i386__ */
876 NTSTATUS WINAPI User32CallEnumDisplayMonitor( void *args, ULONG size )
878 struct enum_display_monitor_params *params = args;
879 BOOL ret;
880 #ifdef __i386__
881 ret = enum_mon_callback_wrapper( params->proc, params->monitor, params->hdc,
882 &params->rect, params->lparam );
883 #else
884 ret = params->proc( params->monitor, params->hdc, &params->rect, params->lparam );
885 #endif
886 return NtCallbackReturn( &ret, sizeof(ret), STATUS_SUCCESS );
889 /***********************************************************************
890 * EnumDisplayDevicesA (USER32.@)
892 BOOL WINAPI EnumDisplayDevicesA( LPCSTR device, DWORD index, DISPLAY_DEVICEA *info, DWORD flags )
894 UNICODE_STRING deviceW;
895 DISPLAY_DEVICEW ddW;
896 BOOL ret;
898 if (device)
899 RtlCreateUnicodeStringFromAsciiz( &deviceW, device );
900 else
901 deviceW.Buffer = NULL;
903 ddW.cb = sizeof(ddW);
904 ret = EnumDisplayDevicesW( deviceW.Buffer, index, &ddW, flags );
905 RtlFreeUnicodeString( &deviceW );
907 if (!ret)
908 return ret;
910 WideCharToMultiByte( CP_ACP, 0, ddW.DeviceName, -1, info->DeviceName, sizeof(info->DeviceName), NULL, NULL );
911 WideCharToMultiByte( CP_ACP, 0, ddW.DeviceString, -1, info->DeviceString, sizeof(info->DeviceString), NULL, NULL );
912 info->StateFlags = ddW.StateFlags;
914 if (info->cb >= offsetof(DISPLAY_DEVICEA, DeviceID) + sizeof(info->DeviceID))
915 WideCharToMultiByte( CP_ACP, 0, ddW.DeviceID, -1, info->DeviceID, sizeof(info->DeviceID), NULL, NULL );
916 if (info->cb >= offsetof(DISPLAY_DEVICEA, DeviceKey) + sizeof(info->DeviceKey))
917 WideCharToMultiByte( CP_ACP, 0, ddW.DeviceKey, -1, info->DeviceKey, sizeof(info->DeviceKey), NULL, NULL );
919 return TRUE;
922 /***********************************************************************
923 * EnumDisplayDevicesW (USER32.@)
925 BOOL WINAPI EnumDisplayDevicesW( LPCWSTR device, DWORD index, DISPLAY_DEVICEW *info, DWORD flags )
927 UNICODE_STRING str;
928 RtlInitUnicodeString( &str, device );
929 return NT_SUCCESS(NtUserEnumDisplayDevices( &str, index, info, flags ));
932 /**********************************************************************
933 * GetAutoRotationState [USER32.@]
935 BOOL WINAPI GetAutoRotationState( AR_STATE *state )
937 TRACE("(%p)\n", state);
939 if (!state)
941 SetLastError(ERROR_INVALID_PARAMETER);
942 return FALSE;
945 *state = AR_NOSENSOR;
946 return TRUE;
949 /**********************************************************************
950 * GetDisplayAutoRotationPreferences (USER32.@)
952 BOOL WINAPI GetDisplayAutoRotationPreferences( ORIENTATION_PREFERENCE *orientation )
954 FIXME("(%p): stub\n", orientation);
955 *orientation = ORIENTATION_PREFERENCE_NONE;
956 return TRUE;
959 /**********************************************************************
960 * SetDisplayAutoRotationPreferences (USER32.@)
962 BOOL WINAPI SetDisplayAutoRotationPreferences( ORIENTATION_PREFERENCE orientation )
964 FIXME("(%d): stub\n", orientation);
965 return TRUE;
968 /* physical<->logical mapping functions from win8 that are nops in later versions */
970 /***********************************************************************
971 * GetPhysicalCursorPos (USER32.@)
973 BOOL WINAPI GetPhysicalCursorPos( POINT *point )
975 return GetCursorPos( point );
978 /***********************************************************************
979 * SetPhysicalCursorPos (USER32.@)
981 BOOL WINAPI SetPhysicalCursorPos( INT x, INT y )
983 return NtUserSetCursorPos( x, y );
986 /***********************************************************************
987 * WindowFromPhysicalPoint (USER32.@)
989 HWND WINAPI WindowFromPhysicalPoint( POINT pt )
991 return WindowFromPoint( pt );
994 /***********************************************************************
995 * LogicalToPhysicalPoint (USER32.@)
997 BOOL WINAPI LogicalToPhysicalPoint( HWND hwnd, POINT *point )
999 return TRUE;
1002 /***********************************************************************
1003 * PhysicalToLogicalPoint (USER32.@)
1005 BOOL WINAPI PhysicalToLogicalPoint( HWND hwnd, POINT *point )
1007 return TRUE;
1010 /***********************************************************************
1011 * DisplayConfigGetDeviceInfo (USER32.@)
1013 LONG WINAPI DisplayConfigGetDeviceInfo(DISPLAYCONFIG_DEVICE_INFO_HEADER *packet)
1015 return RtlNtStatusToDosError(NtUserDisplayConfigGetDeviceInfo(packet));
1018 /***********************************************************************
1019 * SetDisplayConfig (USER32.@)
1021 LONG WINAPI SetDisplayConfig(UINT32 path_info_count, DISPLAYCONFIG_PATH_INFO *path_info, UINT32 mode_info_count,
1022 DISPLAYCONFIG_MODE_INFO *mode_info, UINT32 flags)
1024 FIXME("path_info_count %u, path_info %p, mode_info_count %u, mode_info %p, flags %#x stub.\n",
1025 path_info_count, path_info, mode_info_count, mode_info, flags);
1027 return ERROR_SUCCESS;
1031 /***********************************************************************
1032 * AdjustWindowRect (USER32.@)
1034 BOOL WINAPI DECLSPEC_HOTPATCH AdjustWindowRect( RECT *rect, DWORD style, BOOL menu )
1036 TRACE( "(%s) %08lx %d\n", wine_dbgstr_rect( rect ), style, menu );
1037 return NtUserAdjustWindowRect( rect, style, menu, 0, system_dpi );
1041 /***********************************************************************
1042 * AdjustWindowRectEx (USER32.@)
1044 BOOL WINAPI DECLSPEC_HOTPATCH AdjustWindowRectEx( RECT *rect, DWORD style, BOOL menu, DWORD ex_style )
1046 TRACE( "(%s) %08lx %d %08lx\n", wine_dbgstr_rect( rect ), style, menu, ex_style );
1047 return NtUserAdjustWindowRect( rect, style, menu, ex_style, system_dpi );
1051 /***********************************************************************
1052 * AdjustWindowRectExForDpi (USER32.@)
1054 BOOL WINAPI DECLSPEC_HOTPATCH AdjustWindowRectExForDpi( RECT *rect, DWORD style, BOOL menu, DWORD ex_style, UINT dpi )
1056 TRACE( "(%s) %08lx %d %08lx %u\n", wine_dbgstr_rect( rect ), style, menu, ex_style, dpi );
1057 return NtUserAdjustWindowRect( rect, style, menu, ex_style, dpi );