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
22 #define WIN32_NO_STATUS
23 #include "user_private.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
;
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
;
129 lpnm32W
->iPaddedBorderWidth
= 0;
134 /* Helper functions to retrieve monitors info */
136 HDC
get_display_dc(void)
138 EnterCriticalSection( &display_dc_section
);
143 LeaveCriticalSection( &display_dc_section
);
144 dc
= CreateDCW( L
"DISPLAY", NULL
, NULL
, NULL
);
145 EnterCriticalSection( &display_dc_section
);
154 void release_display_dc( HDC hdc
)
156 LeaveCriticalSection( &display_dc_section
);
159 /***********************************************************************
162 void SYSPARAMS_Init(void)
164 system_dpi
= NtUserGetSystemDpiForProcess( NULL
);
167 static BOOL
update_desktop_wallpaper(void)
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 );
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();
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();
210 /***********************************************************************
211 * SystemParametersInfoA (USER32.@)
213 BOOL WINAPI
SystemParametersInfoA( UINT uiAction
, UINT uiParam
,
214 PVOID pvParam
, UINT fuWinIni
)
218 TRACE("(%u, %u, %p, %u)\n", uiAction
, uiParam
, pvParam
, fuWinIni
);
222 case SPI_SETDESKWALLPAPER
: /* 20 */
223 case SPI_SETDESKPATTERN
: /* 21 */
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
);
233 case SPI_GETICONTITLELOGFONT
: /* 31 */
236 ret
= SystemParametersInfoW( uiAction
, uiParam
, pvParam
? &tmp
: NULL
, fuWinIni
);
238 SYSPARAMS_LogFont32WTo32A( &tmp
, pvParam
);
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
);
252 SYSPARAMS_NonClientMetrics32WTo32A( &tmp
, lpnmA
);
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
);
275 case SPI_GETICONMETRICS
: /* 45 WINVER >= 0x400 */
278 LPICONMETRICSA lpimA
= pvParam
;
279 if (lpimA
&& lpimA
->cbSize
== sizeof(ICONMETRICSA
))
281 tmp
.cbSize
= sizeof(ICONMETRICSW
);
282 ret
= SystemParametersInfoW( uiAction
, uiParam
, &tmp
, fuWinIni
);
285 lpimA
->iHorzSpacing
= tmp
.iHorzSpacing
;
286 lpimA
->iVertSpacing
= tmp
.iVertSpacing
;
287 lpimA
->iTitleWrap
= tmp
.iTitleWrap
;
288 SYSPARAMS_LogFont32WTo32A( &tmp
.lfFont
, &lpimA
->lfFont
);
296 case SPI_SETICONMETRICS
: /* 46 WINVER >= 0x400 */
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
);
314 case SPI_GETHIGHCONTRAST
: /* 66 WINVER >= 0x400 */
317 LPHIGHCONTRASTA lphcA
= pvParam
;
318 if (lphcA
&& lphcA
->cbSize
== sizeof(HIGHCONTRASTA
))
320 tmp
.cbSize
= sizeof(HIGHCONTRASTW
);
321 ret
= SystemParametersInfoW( uiAction
, uiParam
, &tmp
, fuWinIni
);
324 lphcA
->dwFlags
= tmp
.dwFlags
;
325 lphcA
->lpszDefaultScheme
= NULL
; /* FIXME? */
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
));
342 ret
= SystemParametersInfoW( uiAction
, uiParam
, pvParam
, fuWinIni
);
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
374 BOOL WINAPI
SwapMouseButton( BOOL fSwap
)
376 BOOL prev
= GetSystemMetrics(SM_SWAPBUTTON
);
377 SystemParametersInfoW(SPI_SETMOUSEBUTTONSWAP
, fSwap
, 0, 0);
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" );
410 /***********************************************************************
411 * GetSysColorBrush (USER32.@)
413 HBRUSH WINAPI DECLSPEC_HOTPATCH
GetSysColorBrush( INT index
)
415 return NtUserGetSysColorBrush( index
);
419 /***********************************************************************
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
)
465 UNICODE_STRING nameW
;
467 if (devname
) RtlCreateUnicodeStringFromAsciiz(&nameW
, devname
);
468 else nameW
.Buffer
= NULL
;
474 devmodeW
= GdiConvertToDevmodeW(devmode
);
477 ret
= ChangeDisplaySettingsExW(nameW
.Buffer
, devmodeW
, hwnd
, flags
, lparam
);
478 HeapFree(GetProcessHeap(), 0, devmodeW
);
481 ret
= DISP_CHANGE_SUCCESSFUL
;
485 ret
= ChangeDisplaySettingsExW(nameW
.Buffer
, NULL
, hwnd
, flags
, lparam
);
488 if (devname
) RtlFreeUnicodeString(&nameW
);
493 /***********************************************************************
494 * ChangeDisplaySettingsExW (USER32.@)
496 LONG WINAPI
ChangeDisplaySettingsExW( LPCWSTR devname
, LPDEVMODEW devmode
, HWND hwnd
,
497 DWORD flags
, LPVOID lparam
)
500 RtlInitUnicodeString( &str
, devname
);
501 return NtUserChangeDisplaySettings( &str
, devmode
, hwnd
, flags
, lparam
);
505 /***********************************************************************
506 * EnumDisplaySettingsW (USER32.@)
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
)
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
);
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
);
568 /***********************************************************************
569 * EnumDisplaySettingsExW (USER32.@)
571 BOOL WINAPI
EnumDisplaySettingsExW( const WCHAR
*device
, DWORD mode
,
572 DEVMODEW
*dev_mode
, DWORD flags
)
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
;
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
;
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
;
622 /* keep in sync with win32u */
623 UINT
set_thread_dpi_awareness_context( UINT context
)
625 struct ntuser_thread_info
*info
= NtUserGetThreadInfo();
628 if (!is_valid_dpi_awareness_context( context
, system_dpi
))
630 RtlSetLastWin32Error( ERROR_INVALID_PARAMETER
);
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
;
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
);
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
);
674 return SetProcessDpiAwarenessContext( contexts
[awareness
] );
677 /***********************************************************************
678 * AreDpiAwarenessContextsEqual (USER32.@)
680 BOOL WINAPI
AreDpiAwarenessContextsEqual( DPI_AWARENESS_CONTEXT ctx1
, DPI_AWARENESS_CONTEXT ctx2
)
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)
723 NtUserSetProcessDpiAwarenessContext( NTUSER_DPI_SYSTEM_AWARE
, 0 );
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
);
745 /***********************************************************************
746 * GetDpiForSystem (USER32.@)
748 UINT WINAPI
GetDpiForSystem(void)
750 if (!IsProcessDPIAware()) return USER_DEFAULT_SCREEN_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 )
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
)
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
)
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
);
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
);
842 /***********************************************************************
843 * GetMonitorInfoW (USER32.@)
845 BOOL WINAPI
GetMonitorInfoW( HMONITOR monitor
, LPMONITORINFO info
)
847 return NtUserGetMonitorInfo( monitor
, info
);
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
,
857 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
858 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
860 __ASM_CFI(".cfi_def_cfa_register %ebp\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 */
866 "pushl 16(%ebp)\n\t" /* hdc */
867 "pushl 12(%ebp)\n\t" /* monitor */
868 "movl 8(%ebp),%eax\n" /* proc */
871 __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
872 __ASM_CFI(".cfi_same_value %ebp\n\t")
874 #endif /* __i386__ */
876 NTSTATUS WINAPI
User32CallEnumDisplayMonitor( void *args
, ULONG size
)
878 struct enum_display_monitor_params
*params
= args
;
881 ret
= enum_mon_callback_wrapper( params
->proc
, params
->monitor
, params
->hdc
,
882 ¶ms
->rect
, params
->lparam
);
884 ret
= params
->proc( params
->monitor
, params
->hdc
, ¶ms
->rect
, params
->lparam
);
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
;
899 RtlCreateUnicodeStringFromAsciiz( &deviceW
, device
);
901 deviceW
.Buffer
= NULL
;
903 ddW
.cb
= sizeof(ddW
);
904 ret
= EnumDisplayDevicesW( deviceW
.Buffer
, index
, &ddW
, flags
);
905 RtlFreeUnicodeString( &deviceW
);
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
);
922 /***********************************************************************
923 * EnumDisplayDevicesW (USER32.@)
925 BOOL WINAPI
EnumDisplayDevicesW( LPCWSTR device
, DWORD index
, DISPLAY_DEVICEW
*info
, DWORD flags
)
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
);
941 SetLastError(ERROR_INVALID_PARAMETER
);
945 *state
= AR_NOSENSOR
;
949 /**********************************************************************
950 * GetDisplayAutoRotationPreferences (USER32.@)
952 BOOL WINAPI
GetDisplayAutoRotationPreferences( ORIENTATION_PREFERENCE
*orientation
)
954 FIXME("(%p): stub\n", orientation
);
955 *orientation
= ORIENTATION_PREFERENCE_NONE
;
959 /**********************************************************************
960 * SetDisplayAutoRotationPreferences (USER32.@)
962 BOOL WINAPI
SetDisplayAutoRotationPreferences( ORIENTATION_PREFERENCE orientation
)
964 FIXME("(%d): stub\n", orientation
);
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
)
1002 /***********************************************************************
1003 * PhysicalToLogicalPoint (USER32.@)
1005 BOOL WINAPI
PhysicalToLogicalPoint( HWND hwnd
, POINT
*point
)
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
);