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
35 #include "wine/wingdi16.h"
43 #include "user_private.h"
45 #include "wine/debug.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(system
);
50 DEFINE_DEVPROPKEY(DEVPROPKEY_MONITOR_GPU_LUID
, 0xca085853, 0x16ce, 0x48aa, 0xb1, 0x14, 0xde, 0x9c, 0x72, 0x33, 0x42, 0x23, 1);
51 DEFINE_DEVPROPKEY(DEVPROPKEY_MONITOR_OUTPUT_ID
, 0xca085853, 0x16ce, 0x48aa, 0xb1, 0x14, 0xde, 0x9c, 0x72, 0x33, 0x42, 0x23, 2);
53 /* Wine specific monitor properties */
54 DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_STATEFLAGS
, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 2);
55 DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_ADAPTERNAME
, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 5);
58 static HDC display_dc
;
59 static CRITICAL_SECTION display_dc_section
;
60 static CRITICAL_SECTION_DEBUG critsect_debug
=
62 0, 0, &display_dc_section
,
63 { &critsect_debug
.ProcessLocksList
, &critsect_debug
.ProcessLocksList
},
64 0, 0, { (DWORD_PTR
)(__FILE__
": display_dc_section") }
66 static CRITICAL_SECTION display_dc_section
= { &critsect_debug
, -1 ,0, 0, 0, 0 };
69 /* System parameters storage */
70 static UINT system_dpi
;
72 static void SYSPARAMS_LogFont32WTo32A( const LOGFONTW
* font32W
, LPLOGFONTA font32A
)
74 font32A
->lfHeight
= font32W
->lfHeight
;
75 font32A
->lfWidth
= font32W
->lfWidth
;
76 font32A
->lfEscapement
= font32W
->lfEscapement
;
77 font32A
->lfOrientation
= font32W
->lfOrientation
;
78 font32A
->lfWeight
= font32W
->lfWeight
;
79 font32A
->lfItalic
= font32W
->lfItalic
;
80 font32A
->lfUnderline
= font32W
->lfUnderline
;
81 font32A
->lfStrikeOut
= font32W
->lfStrikeOut
;
82 font32A
->lfCharSet
= font32W
->lfCharSet
;
83 font32A
->lfOutPrecision
= font32W
->lfOutPrecision
;
84 font32A
->lfClipPrecision
= font32W
->lfClipPrecision
;
85 font32A
->lfQuality
= font32W
->lfQuality
;
86 font32A
->lfPitchAndFamily
= font32W
->lfPitchAndFamily
;
87 WideCharToMultiByte( CP_ACP
, 0, font32W
->lfFaceName
, -1, font32A
->lfFaceName
, LF_FACESIZE
, NULL
, NULL
);
88 font32A
->lfFaceName
[LF_FACESIZE
-1] = 0;
91 static void SYSPARAMS_LogFont32ATo32W( const LOGFONTA
* font32A
, LPLOGFONTW font32W
)
93 font32W
->lfHeight
= font32A
->lfHeight
;
94 font32W
->lfWidth
= font32A
->lfWidth
;
95 font32W
->lfEscapement
= font32A
->lfEscapement
;
96 font32W
->lfOrientation
= font32A
->lfOrientation
;
97 font32W
->lfWeight
= font32A
->lfWeight
;
98 font32W
->lfItalic
= font32A
->lfItalic
;
99 font32W
->lfUnderline
= font32A
->lfUnderline
;
100 font32W
->lfStrikeOut
= font32A
->lfStrikeOut
;
101 font32W
->lfCharSet
= font32A
->lfCharSet
;
102 font32W
->lfOutPrecision
= font32A
->lfOutPrecision
;
103 font32W
->lfClipPrecision
= font32A
->lfClipPrecision
;
104 font32W
->lfQuality
= font32A
->lfQuality
;
105 font32W
->lfPitchAndFamily
= font32A
->lfPitchAndFamily
;
106 MultiByteToWideChar( CP_ACP
, 0, font32A
->lfFaceName
, -1, font32W
->lfFaceName
, LF_FACESIZE
);
107 font32W
->lfFaceName
[LF_FACESIZE
-1] = 0;
110 static void SYSPARAMS_NonClientMetrics32WTo32A( const NONCLIENTMETRICSW
* lpnm32W
, LPNONCLIENTMETRICSA lpnm32A
)
112 lpnm32A
->iBorderWidth
= lpnm32W
->iBorderWidth
;
113 lpnm32A
->iScrollWidth
= lpnm32W
->iScrollWidth
;
114 lpnm32A
->iScrollHeight
= lpnm32W
->iScrollHeight
;
115 lpnm32A
->iCaptionWidth
= lpnm32W
->iCaptionWidth
;
116 lpnm32A
->iCaptionHeight
= lpnm32W
->iCaptionHeight
;
117 SYSPARAMS_LogFont32WTo32A( &lpnm32W
->lfCaptionFont
, &lpnm32A
->lfCaptionFont
);
118 lpnm32A
->iSmCaptionWidth
= lpnm32W
->iSmCaptionWidth
;
119 lpnm32A
->iSmCaptionHeight
= lpnm32W
->iSmCaptionHeight
;
120 SYSPARAMS_LogFont32WTo32A( &lpnm32W
->lfSmCaptionFont
, &lpnm32A
->lfSmCaptionFont
);
121 lpnm32A
->iMenuWidth
= lpnm32W
->iMenuWidth
;
122 lpnm32A
->iMenuHeight
= lpnm32W
->iMenuHeight
;
123 SYSPARAMS_LogFont32WTo32A( &lpnm32W
->lfMenuFont
, &lpnm32A
->lfMenuFont
);
124 SYSPARAMS_LogFont32WTo32A( &lpnm32W
->lfStatusFont
, &lpnm32A
->lfStatusFont
);
125 SYSPARAMS_LogFont32WTo32A( &lpnm32W
->lfMessageFont
, &lpnm32A
->lfMessageFont
);
126 if (lpnm32A
->cbSize
> FIELD_OFFSET(NONCLIENTMETRICSA
, iPaddedBorderWidth
))
128 if (lpnm32W
->cbSize
> FIELD_OFFSET(NONCLIENTMETRICSW
, iPaddedBorderWidth
))
129 lpnm32A
->iPaddedBorderWidth
= lpnm32W
->iPaddedBorderWidth
;
131 lpnm32A
->iPaddedBorderWidth
= 0;
135 static void SYSPARAMS_NonClientMetrics32ATo32W( const NONCLIENTMETRICSA
* lpnm32A
, LPNONCLIENTMETRICSW lpnm32W
)
137 lpnm32W
->iBorderWidth
= lpnm32A
->iBorderWidth
;
138 lpnm32W
->iScrollWidth
= lpnm32A
->iScrollWidth
;
139 lpnm32W
->iScrollHeight
= lpnm32A
->iScrollHeight
;
140 lpnm32W
->iCaptionWidth
= lpnm32A
->iCaptionWidth
;
141 lpnm32W
->iCaptionHeight
= lpnm32A
->iCaptionHeight
;
142 SYSPARAMS_LogFont32ATo32W( &lpnm32A
->lfCaptionFont
, &lpnm32W
->lfCaptionFont
);
143 lpnm32W
->iSmCaptionWidth
= lpnm32A
->iSmCaptionWidth
;
144 lpnm32W
->iSmCaptionHeight
= lpnm32A
->iSmCaptionHeight
;
145 SYSPARAMS_LogFont32ATo32W( &lpnm32A
->lfSmCaptionFont
, &lpnm32W
->lfSmCaptionFont
);
146 lpnm32W
->iMenuWidth
= lpnm32A
->iMenuWidth
;
147 lpnm32W
->iMenuHeight
= lpnm32A
->iMenuHeight
;
148 SYSPARAMS_LogFont32ATo32W( &lpnm32A
->lfMenuFont
, &lpnm32W
->lfMenuFont
);
149 SYSPARAMS_LogFont32ATo32W( &lpnm32A
->lfStatusFont
, &lpnm32W
->lfStatusFont
);
150 SYSPARAMS_LogFont32ATo32W( &lpnm32A
->lfMessageFont
, &lpnm32W
->lfMessageFont
);
151 if (lpnm32W
->cbSize
> FIELD_OFFSET(NONCLIENTMETRICSW
, iPaddedBorderWidth
))
153 if (lpnm32A
->cbSize
> FIELD_OFFSET(NONCLIENTMETRICSA
, iPaddedBorderWidth
))
154 lpnm32W
->iPaddedBorderWidth
= lpnm32A
->iPaddedBorderWidth
;
156 lpnm32W
->iPaddedBorderWidth
= 0;
161 /* Helper functions to retrieve monitors info */
163 HDC
get_display_dc(void)
165 EnterCriticalSection( &display_dc_section
);
170 LeaveCriticalSection( &display_dc_section
);
171 dc
= CreateDCW( L
"DISPLAY", NULL
, NULL
, NULL
);
172 EnterCriticalSection( &display_dc_section
);
181 void release_display_dc( HDC hdc
)
183 LeaveCriticalSection( &display_dc_section
);
186 static HANDLE
get_display_device_init_mutex( void )
188 HANDLE mutex
= CreateMutexW( NULL
, FALSE
, L
"display_device_init" );
190 WaitForSingleObject( mutex
, INFINITE
);
194 static void release_display_device_init_mutex( HANDLE mutex
)
196 ReleaseMutex( mutex
);
197 CloseHandle( mutex
);
200 /* Wait until graphics driver is loaded by explorer */
201 static void wait_graphics_driver_ready(void)
203 static BOOL ready
= FALSE
;
207 SendMessageW( GetDesktopWindow(), WM_NULL
, 0, 0 );
212 /***********************************************************************
215 void SYSPARAMS_Init(void)
217 system_dpi
= NtUserGetSystemDpiForProcess( NULL
);
220 static BOOL
update_desktop_wallpaper(void)
224 if (GetWindowThreadProcessId( GetDesktopWindow(), &pid
) && pid
== GetCurrentProcessId())
226 WCHAR wallpaper
[MAX_PATH
], pattern
[256];
228 if (NtUserSystemParametersInfo( SPI_GETDESKWALLPAPER
, ARRAYSIZE(wallpaper
), wallpaper
, 0 ) &&
229 NtUserCallOneParam( (ULONG_PTR
)pattern
, NtUserGetDeskPattern
))
231 update_wallpaper( wallpaper
, pattern
);
234 else SendMessageW( GetDesktopWindow(), WM_SETTINGCHANGE
, SPI_SETDESKWALLPAPER
, 0 );
239 /***********************************************************************
240 * SystemParametersInfoForDpi (USER32.@)
242 BOOL WINAPI
SystemParametersInfoForDpi( UINT action
, UINT val
, PVOID ptr
, UINT winini
, UINT dpi
)
244 BOOL ret
= NtUserSystemParametersInfoForDpi( action
, val
, ptr
, winini
, dpi
);
245 if (ret
&& (action
== SPI_SETDESKWALLPAPER
|| action
== SPI_SETDESKPATTERN
))
246 ret
= update_desktop_wallpaper();
251 /***********************************************************************
252 * SystemParametersInfoW (USER32.@)
254 BOOL WINAPI
SystemParametersInfoW( UINT action
, UINT val
, void *ptr
, UINT winini
)
256 BOOL ret
= NtUserSystemParametersInfo( action
, val
, ptr
, winini
);
257 if (ret
&& (action
== SPI_SETDESKWALLPAPER
|| action
== SPI_SETDESKPATTERN
))
258 ret
= update_desktop_wallpaper();
263 /***********************************************************************
264 * SystemParametersInfoA (USER32.@)
266 BOOL WINAPI
SystemParametersInfoA( UINT uiAction
, UINT uiParam
,
267 PVOID pvParam
, UINT fuWinIni
)
271 TRACE("(%u, %u, %p, %u)\n", uiAction
, uiParam
, pvParam
, fuWinIni
);
275 case SPI_SETDESKWALLPAPER
: /* 20 */
276 case SPI_SETDESKPATTERN
: /* 21 */
280 if (!MultiByteToWideChar( CP_ACP
, 0, pvParam
, -1, buffer
, ARRAY_SIZE( buffer
)))
281 buffer
[ARRAY_SIZE(buffer
)-1] = 0;
282 ret
= SystemParametersInfoW( uiAction
, uiParam
, pvParam
? buffer
: NULL
, fuWinIni
);
286 case SPI_GETICONTITLELOGFONT
: /* 31 */
289 ret
= SystemParametersInfoW( uiAction
, uiParam
, pvParam
? &tmp
: NULL
, fuWinIni
);
291 SYSPARAMS_LogFont32WTo32A( &tmp
, pvParam
);
295 case SPI_GETNONCLIENTMETRICS
: /* 41 WINVER >= 0x400 */
297 NONCLIENTMETRICSW tmp
;
298 LPNONCLIENTMETRICSA lpnmA
= pvParam
;
299 if (lpnmA
&& (lpnmA
->cbSize
== sizeof(NONCLIENTMETRICSA
) ||
300 lpnmA
->cbSize
== FIELD_OFFSET(NONCLIENTMETRICSA
, iPaddedBorderWidth
)))
302 tmp
.cbSize
= sizeof(NONCLIENTMETRICSW
);
303 ret
= SystemParametersInfoW( uiAction
, uiParam
, &tmp
, fuWinIni
);
305 SYSPARAMS_NonClientMetrics32WTo32A( &tmp
, lpnmA
);
312 case SPI_SETNONCLIENTMETRICS
: /* 42 WINVER >= 0x400 */
314 NONCLIENTMETRICSW tmp
;
315 LPNONCLIENTMETRICSA lpnmA
= pvParam
;
316 if (lpnmA
&& (lpnmA
->cbSize
== sizeof(NONCLIENTMETRICSA
) ||
317 lpnmA
->cbSize
== FIELD_OFFSET(NONCLIENTMETRICSA
, iPaddedBorderWidth
)))
319 tmp
.cbSize
= sizeof(NONCLIENTMETRICSW
);
320 SYSPARAMS_NonClientMetrics32ATo32W( lpnmA
, &tmp
);
321 ret
= SystemParametersInfoW( uiAction
, uiParam
, &tmp
, fuWinIni
);
328 case SPI_GETICONMETRICS
: /* 45 WINVER >= 0x400 */
331 LPICONMETRICSA lpimA
= pvParam
;
332 if (lpimA
&& lpimA
->cbSize
== sizeof(ICONMETRICSA
))
334 tmp
.cbSize
= sizeof(ICONMETRICSW
);
335 ret
= SystemParametersInfoW( uiAction
, uiParam
, &tmp
, fuWinIni
);
338 lpimA
->iHorzSpacing
= tmp
.iHorzSpacing
;
339 lpimA
->iVertSpacing
= tmp
.iVertSpacing
;
340 lpimA
->iTitleWrap
= tmp
.iTitleWrap
;
341 SYSPARAMS_LogFont32WTo32A( &tmp
.lfFont
, &lpimA
->lfFont
);
349 case SPI_SETICONMETRICS
: /* 46 WINVER >= 0x400 */
352 LPICONMETRICSA lpimA
= pvParam
;
353 if (lpimA
&& lpimA
->cbSize
== sizeof(ICONMETRICSA
))
355 tmp
.cbSize
= sizeof(ICONMETRICSW
);
356 tmp
.iHorzSpacing
= lpimA
->iHorzSpacing
;
357 tmp
.iVertSpacing
= lpimA
->iVertSpacing
;
358 tmp
.iTitleWrap
= lpimA
->iTitleWrap
;
359 SYSPARAMS_LogFont32ATo32W( &lpimA
->lfFont
, &tmp
.lfFont
);
360 ret
= SystemParametersInfoW( uiAction
, uiParam
, &tmp
, fuWinIni
);
367 case SPI_GETHIGHCONTRAST
: /* 66 WINVER >= 0x400 */
370 LPHIGHCONTRASTA lphcA
= pvParam
;
371 if (lphcA
&& lphcA
->cbSize
== sizeof(HIGHCONTRASTA
))
373 tmp
.cbSize
= sizeof(HIGHCONTRASTW
);
374 ret
= SystemParametersInfoW( uiAction
, uiParam
, &tmp
, fuWinIni
);
377 lphcA
->dwFlags
= tmp
.dwFlags
;
378 lphcA
->lpszDefaultScheme
= NULL
; /* FIXME? */
386 case SPI_GETDESKWALLPAPER
: /* 115 */
388 WCHAR buffer
[MAX_PATH
];
389 ret
= (SystemParametersInfoW( SPI_GETDESKWALLPAPER
, uiParam
, buffer
, fuWinIni
) &&
390 WideCharToMultiByte(CP_ACP
, 0, buffer
, -1, pvParam
, uiParam
, NULL
, NULL
));
395 ret
= SystemParametersInfoW( uiAction
, uiParam
, pvParam
, fuWinIni
);
402 /***********************************************************************
403 * GetSystemMetrics (USER32.@)
405 INT WINAPI
GetSystemMetrics( INT index
)
407 return NtUserGetSystemMetrics( index
);
411 /***********************************************************************
412 * GetSystemMetricsForDpi (USER32.@)
414 INT WINAPI
GetSystemMetricsForDpi( INT index
, UINT dpi
)
416 return NtUserGetSystemMetricsForDpi( index
, dpi
);
420 /***********************************************************************
421 * SwapMouseButton (USER32.@)
422 * Reverse or restore the meaning of the left and right mouse buttons
423 * fSwap [I ] TRUE - reverse, FALSE - original
427 BOOL WINAPI
SwapMouseButton( BOOL fSwap
)
429 BOOL prev
= GetSystemMetrics(SM_SWAPBUTTON
);
430 SystemParametersInfoW(SPI_SETMOUSEBUTTONSWAP
, fSwap
, 0, 0);
435 /**********************************************************************
436 * SetDoubleClickTime (USER32.@)
438 BOOL WINAPI
SetDoubleClickTime( UINT interval
)
440 return SystemParametersInfoW(SPI_SETDOUBLECLICKTIME
, interval
, 0, 0);
444 /*************************************************************************
445 * GetSysColor (USER32.@)
447 COLORREF WINAPI DECLSPEC_HOTPATCH
GetSysColor( INT index
)
449 return NtUserGetSysColor( index
);
453 /*************************************************************************
454 * SetSysColorsTemp (USER32.@)
456 DWORD_PTR WINAPI
SetSysColorsTemp( const COLORREF
*pPens
, const HBRUSH
*pBrushes
, DWORD_PTR n
)
458 FIXME( "no longer supported\n" );
463 /***********************************************************************
464 * GetSysColorBrush (USER32.@)
466 HBRUSH WINAPI DECLSPEC_HOTPATCH
GetSysColorBrush( INT index
)
468 return NtUserGetSysColorBrush( index
);
472 /***********************************************************************
475 HPEN
SYSCOLOR_GetPen( INT index
)
477 return NtUserGetSysColorPen( index
);
481 /***********************************************************************
482 * SYSCOLOR_Get55AABrush
484 HBRUSH
SYSCOLOR_Get55AABrush(void)
486 return NtUserGetSysColorBrush( COLOR_55AA_BRUSH
);
489 /***********************************************************************
490 * ChangeDisplaySettingsA (USER32.@)
492 LONG WINAPI
ChangeDisplaySettingsA( LPDEVMODEA devmode
, DWORD flags
)
494 if (devmode
) devmode
->dmDriverExtra
= 0;
496 return ChangeDisplaySettingsExA(NULL
,devmode
,NULL
,flags
,NULL
);
500 /***********************************************************************
501 * ChangeDisplaySettingsW (USER32.@)
503 LONG WINAPI
ChangeDisplaySettingsW( LPDEVMODEW devmode
, DWORD flags
)
505 if (devmode
) devmode
->dmDriverExtra
= 0;
507 return ChangeDisplaySettingsExW(NULL
,devmode
,NULL
,flags
,NULL
);
511 /***********************************************************************
512 * ChangeDisplaySettingsExA (USER32.@)
514 LONG WINAPI
ChangeDisplaySettingsExA( LPCSTR devname
, LPDEVMODEA devmode
, HWND hwnd
,
515 DWORD flags
, LPVOID lparam
)
518 UNICODE_STRING nameW
;
520 if (devname
) RtlCreateUnicodeStringFromAsciiz(&nameW
, devname
);
521 else nameW
.Buffer
= NULL
;
527 devmodeW
= GdiConvertToDevmodeW(devmode
);
530 ret
= ChangeDisplaySettingsExW(nameW
.Buffer
, devmodeW
, hwnd
, flags
, lparam
);
531 HeapFree(GetProcessHeap(), 0, devmodeW
);
534 ret
= DISP_CHANGE_SUCCESSFUL
;
538 ret
= ChangeDisplaySettingsExW(nameW
.Buffer
, NULL
, hwnd
, flags
, lparam
);
541 if (devname
) RtlFreeUnicodeString(&nameW
);
546 /***********************************************************************
547 * ChangeDisplaySettingsExW (USER32.@)
549 LONG WINAPI
ChangeDisplaySettingsExW( LPCWSTR devname
, LPDEVMODEW devmode
, HWND hwnd
,
550 DWORD flags
, LPVOID lparam
)
553 RtlInitUnicodeString( &str
, devname
);
554 return NtUserChangeDisplaySettings( &str
, devmode
, hwnd
, flags
, lparam
);
558 /***********************************************************************
559 * EnumDisplaySettingsW (USER32.@)
562 * TRUE if nth setting exists found (described in the LPDEVMODEW struct)
563 * FALSE if we do not have the nth setting
565 BOOL WINAPI
EnumDisplaySettingsW( LPCWSTR name
, DWORD n
, LPDEVMODEW devmode
)
567 return EnumDisplaySettingsExW(name
, n
, devmode
, 0);
571 /***********************************************************************
572 * EnumDisplaySettingsA (USER32.@)
574 BOOL WINAPI
EnumDisplaySettingsA(LPCSTR name
,DWORD n
,LPDEVMODEA devmode
)
576 return EnumDisplaySettingsExA(name
, n
, devmode
, 0);
580 /***********************************************************************
581 * EnumDisplaySettingsExA (USER32.@)
583 BOOL WINAPI
EnumDisplaySettingsExA(LPCSTR lpszDeviceName
, DWORD iModeNum
,
584 LPDEVMODEA lpDevMode
, DWORD dwFlags
)
588 UNICODE_STRING nameW
;
590 if (lpszDeviceName
) RtlCreateUnicodeStringFromAsciiz(&nameW
, lpszDeviceName
);
591 else nameW
.Buffer
= NULL
;
593 memset(&devmodeW
, 0, sizeof(devmodeW
));
594 devmodeW
.dmSize
= sizeof(devmodeW
);
595 ret
= EnumDisplaySettingsExW(nameW
.Buffer
,iModeNum
,&devmodeW
,dwFlags
);
598 lpDevMode
->dmSize
= FIELD_OFFSET(DEVMODEA
, dmICMMethod
);
599 lpDevMode
->dmSpecVersion
= devmodeW
.dmSpecVersion
;
600 lpDevMode
->dmDriverVersion
= devmodeW
.dmDriverVersion
;
601 WideCharToMultiByte(CP_ACP
, 0, devmodeW
.dmDeviceName
, -1,
602 (LPSTR
)lpDevMode
->dmDeviceName
, CCHDEVICENAME
, NULL
, NULL
);
603 lpDevMode
->dmDriverExtra
= 0; /* FIXME */
604 lpDevMode
->dmBitsPerPel
= devmodeW
.dmBitsPerPel
;
605 lpDevMode
->dmPelsHeight
= devmodeW
.dmPelsHeight
;
606 lpDevMode
->dmPelsWidth
= devmodeW
.dmPelsWidth
;
607 lpDevMode
->dmDisplayFlags
= devmodeW
.dmDisplayFlags
;
608 lpDevMode
->dmDisplayFrequency
= devmodeW
.dmDisplayFrequency
;
609 lpDevMode
->dmFields
= devmodeW
.dmFields
;
611 lpDevMode
->dmPosition
.x
= devmodeW
.dmPosition
.x
;
612 lpDevMode
->dmPosition
.y
= devmodeW
.dmPosition
.y
;
613 lpDevMode
->dmDisplayOrientation
= devmodeW
.dmDisplayOrientation
;
614 lpDevMode
->dmDisplayFixedOutput
= devmodeW
.dmDisplayFixedOutput
;
616 if (lpszDeviceName
) RtlFreeUnicodeString(&nameW
);
621 /***********************************************************************
622 * EnumDisplaySettingsExW (USER32.@)
624 BOOL WINAPI
EnumDisplaySettingsExW( const WCHAR
*device
, DWORD mode
,
625 DEVMODEW
*dev_mode
, DWORD flags
)
628 RtlInitUnicodeString( &str
, device
);
629 return NtUserEnumDisplaySettings( &str
, mode
, dev_mode
, flags
);
632 /**********************************************************************
633 * SetProcessDpiAwarenessContext (USER32.@)
635 BOOL WINAPI
SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT context
)
639 switch (GetAwarenessFromDpiAwarenessContext( context
))
641 case DPI_AWARENESS_UNAWARE
:
642 awareness
= NTUSER_DPI_UNAWARE
;
644 case DPI_AWARENESS_SYSTEM_AWARE
:
645 awareness
= NTUSER_DPI_SYSTEM_AWARE
;
647 case DPI_AWARENESS_PER_MONITOR_AWARE
:
648 awareness
= context
== DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
649 ? NTUSER_DPI_PER_MONITOR_AWARE_V2
: NTUSER_DPI_PER_MONITOR_AWARE
;
652 SetLastError( ERROR_INVALID_PARAMETER
);
656 if (!NtUserSetProcessDpiAwarenessContext( awareness
, 0 ))
658 SetLastError( ERROR_ACCESS_DENIED
);
662 TRACE( "set to %p\n", context
);
666 /**********************************************************************
667 * GetProcessDpiAwarenessInternal (USER32.@)
669 BOOL WINAPI
GetProcessDpiAwarenessInternal( HANDLE process
, DPI_AWARENESS
*awareness
)
671 *awareness
= NtUserGetProcessDpiAwarenessContext( process
) & 3;
675 /**********************************************************************
676 * SetProcessDpiAwarenessInternal (USER32.@)
678 BOOL WINAPI
SetProcessDpiAwarenessInternal( DPI_AWARENESS awareness
)
680 static const DPI_AWARENESS_CONTEXT contexts
[3] = { DPI_AWARENESS_CONTEXT_UNAWARE
,
681 DPI_AWARENESS_CONTEXT_SYSTEM_AWARE
,
682 DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE
};
684 if (awareness
< DPI_AWARENESS_UNAWARE
|| awareness
> DPI_AWARENESS_PER_MONITOR_AWARE
)
686 SetLastError( ERROR_INVALID_PARAMETER
);
689 return SetProcessDpiAwarenessContext( contexts
[awareness
] );
692 /***********************************************************************
693 * AreDpiAwarenessContextsEqual (USER32.@)
695 BOOL WINAPI
AreDpiAwarenessContextsEqual( DPI_AWARENESS_CONTEXT ctx1
, DPI_AWARENESS_CONTEXT ctx2
)
697 DPI_AWARENESS aware1
= GetAwarenessFromDpiAwarenessContext( ctx1
);
698 DPI_AWARENESS aware2
= GetAwarenessFromDpiAwarenessContext( ctx2
);
699 return aware1
!= DPI_AWARENESS_INVALID
&& aware1
== aware2
;
702 /***********************************************************************
703 * GetAwarenessFromDpiAwarenessContext (USER32.@)
705 DPI_AWARENESS WINAPI
GetAwarenessFromDpiAwarenessContext( DPI_AWARENESS_CONTEXT context
)
707 switch ((ULONG_PTR
)context
)
715 return (ULONG_PTR
)context
& 3;
716 case (ULONG_PTR
)DPI_AWARENESS_CONTEXT_UNAWARE
:
717 case (ULONG_PTR
)DPI_AWARENESS_CONTEXT_SYSTEM_AWARE
:
718 case (ULONG_PTR
)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE
:
719 return ~(ULONG_PTR
)context
;
721 return DPI_AWARENESS_INVALID
;
725 /***********************************************************************
726 * IsValidDpiAwarenessContext (USER32.@)
728 BOOL WINAPI
IsValidDpiAwarenessContext( DPI_AWARENESS_CONTEXT context
)
730 return GetAwarenessFromDpiAwarenessContext( context
) != DPI_AWARENESS_INVALID
;
733 /***********************************************************************
734 * SetProcessDPIAware (USER32.@)
736 BOOL WINAPI
SetProcessDPIAware(void)
739 NtUserSetProcessDpiAwarenessContext( NTUSER_DPI_SYSTEM_AWARE
, 0 );
743 /***********************************************************************
744 * IsProcessDPIAware (USER32.@)
746 BOOL WINAPI
IsProcessDPIAware(void)
748 return GetAwarenessFromDpiAwarenessContext( GetThreadDpiAwarenessContext() ) != DPI_AWARENESS_UNAWARE
;
751 /**********************************************************************
752 * EnableNonClientDpiScaling (USER32.@)
754 BOOL WINAPI
EnableNonClientDpiScaling( HWND hwnd
)
756 FIXME("(%p): stub\n", hwnd
);
757 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
761 /***********************************************************************
762 * GetDpiForSystem (USER32.@)
764 UINT WINAPI
GetDpiForSystem(void)
766 if (!IsProcessDPIAware()) return USER_DEFAULT_SCREEN_DPI
;
770 /**********************************************************************
771 * GetThreadDpiAwarenessContext (USER32.@)
773 DPI_AWARENESS_CONTEXT WINAPI
GetThreadDpiAwarenessContext(void)
775 struct ntuser_thread_info
*info
= NtUserGetThreadInfo();
777 if (info
->dpi_awareness
) return ULongToHandle( info
->dpi_awareness
);
778 return UlongToHandle( (NtUserGetProcessDpiAwarenessContext( GetCurrentProcess() ) & 3 ) | 0x10 );
781 /**********************************************************************
782 * SetThreadDpiAwarenessContext (USER32.@)
784 DPI_AWARENESS_CONTEXT WINAPI
SetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT context
)
786 struct ntuser_thread_info
*info
= NtUserGetThreadInfo();
787 DPI_AWARENESS prev
, val
= GetAwarenessFromDpiAwarenessContext( context
);
789 if (val
== DPI_AWARENESS_INVALID
)
791 SetLastError( ERROR_INVALID_PARAMETER
);
794 if (!(prev
= info
->dpi_awareness
))
796 prev
= NtUserGetProcessDpiAwarenessContext( GetCurrentProcess() ) & 3;
797 prev
|= 0x80000010; /* restore to process default */
799 if (((ULONG_PTR
)context
& ~(ULONG_PTR
)0x13) == 0x80000000) info
->dpi_awareness
= 0;
800 else info
->dpi_awareness
= val
| 0x10;
801 return ULongToHandle( prev
);
804 /***********************************************************************
805 * MonitorFromRect (USER32.@)
807 HMONITOR WINAPI
MonitorFromRect( const RECT
*rect
, DWORD flags
)
809 return NtUserMonitorFromRect( rect
, flags
);
812 /***********************************************************************
813 * MonitorFromPoint (USER32.@)
815 HMONITOR WINAPI
MonitorFromPoint( POINT pt
, DWORD flags
)
819 SetRect( &rect
, pt
.x
, pt
.y
, pt
.x
+ 1, pt
.y
+ 1 );
820 return MonitorFromRect( &rect
, flags
);
823 /***********************************************************************
824 * MonitorFromWindow (USER32.@)
826 HMONITOR WINAPI
MonitorFromWindow( HWND hwnd
, DWORD flags
)
828 return NtUserMonitorFromWindow( hwnd
, flags
);
831 /***********************************************************************
832 * GetMonitorInfoA (USER32.@)
834 BOOL WINAPI
GetMonitorInfoA( HMONITOR monitor
, LPMONITORINFO info
)
839 if (info
->cbSize
== sizeof(MONITORINFO
)) return GetMonitorInfoW( monitor
, info
);
840 if (info
->cbSize
!= sizeof(MONITORINFOEXA
)) return FALSE
;
842 miW
.cbSize
= sizeof(miW
);
843 ret
= GetMonitorInfoW( monitor
, (MONITORINFO
*)&miW
);
846 MONITORINFOEXA
*miA
= (MONITORINFOEXA
*)info
;
847 miA
->rcMonitor
= miW
.rcMonitor
;
848 miA
->rcWork
= miW
.rcWork
;
849 miA
->dwFlags
= miW
.dwFlags
;
850 WideCharToMultiByte(CP_ACP
, 0, miW
.szDevice
, -1, miA
->szDevice
, sizeof(miA
->szDevice
), NULL
, NULL
);
855 /***********************************************************************
856 * GetMonitorInfoW (USER32.@)
858 BOOL WINAPI
GetMonitorInfoW( HMONITOR monitor
, LPMONITORINFO info
)
860 return NtUserGetMonitorInfo( monitor
, info
);
864 /* Some apps pass a non-stdcall callback to EnumDisplayMonitors,
865 * so we need a small assembly wrapper to call it.
867 extern BOOL
enum_mon_callback_wrapper( void *proc
, HMONITOR monitor
, HDC hdc
, RECT
*rect
, LPARAM lparam
);
868 __ASM_GLOBAL_FUNC( enum_mon_callback_wrapper
,
870 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
871 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
873 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
875 "pushl 24(%ebp)\n\t" /* lparam */
876 /* MJ's Help Diagnostic expects that %ecx contains the address to the rect. */
877 "movl 20(%ebp),%ecx\n\t" /* rect */
879 "pushl 16(%ebp)\n\t" /* hdc */
880 "pushl 12(%ebp)\n\t" /* monitor */
881 "movl 8(%ebp),%eax\n" /* proc */
884 __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
885 __ASM_CFI(".cfi_same_value %ebp\n\t")
887 #endif /* __i386__ */
889 BOOL WINAPI
User32CallEnumDisplayMonitor( struct enum_display_monitor_params
*params
, ULONG size
)
892 return enum_mon_callback_wrapper( params
->proc
, params
->monitor
, params
->hdc
,
893 ¶ms
->rect
, params
->lparam
);
895 return params
->proc( params
->monitor
, params
->hdc
, ¶ms
->rect
, params
->lparam
);
899 /***********************************************************************
900 * EnumDisplayDevicesA (USER32.@)
902 BOOL WINAPI
EnumDisplayDevicesA( LPCSTR device
, DWORD index
, DISPLAY_DEVICEA
*info
, DWORD flags
)
904 UNICODE_STRING deviceW
;
909 RtlCreateUnicodeStringFromAsciiz( &deviceW
, device
);
911 deviceW
.Buffer
= NULL
;
913 ddW
.cb
= sizeof(ddW
);
914 ret
= EnumDisplayDevicesW( deviceW
.Buffer
, index
, &ddW
, flags
);
915 RtlFreeUnicodeString( &deviceW
);
920 WideCharToMultiByte( CP_ACP
, 0, ddW
.DeviceName
, -1, info
->DeviceName
, sizeof(info
->DeviceName
), NULL
, NULL
);
921 WideCharToMultiByte( CP_ACP
, 0, ddW
.DeviceString
, -1, info
->DeviceString
, sizeof(info
->DeviceString
), NULL
, NULL
);
922 info
->StateFlags
= ddW
.StateFlags
;
924 if (info
->cb
>= offsetof(DISPLAY_DEVICEA
, DeviceID
) + sizeof(info
->DeviceID
))
925 WideCharToMultiByte( CP_ACP
, 0, ddW
.DeviceID
, -1, info
->DeviceID
, sizeof(info
->DeviceID
), NULL
, NULL
);
926 if (info
->cb
>= offsetof(DISPLAY_DEVICEA
, DeviceKey
) + sizeof(info
->DeviceKey
))
927 WideCharToMultiByte( CP_ACP
, 0, ddW
.DeviceKey
, -1, info
->DeviceKey
, sizeof(info
->DeviceKey
), NULL
, NULL
);
932 /***********************************************************************
933 * EnumDisplayDevicesW (USER32.@)
935 BOOL WINAPI
EnumDisplayDevicesW( LPCWSTR device
, DWORD index
, DISPLAY_DEVICEW
*info
, DWORD flags
)
938 RtlInitUnicodeString( &str
, device
);
939 return NT_SUCCESS(NtUserEnumDisplayDevices( &str
, index
, info
, flags
));
942 /**********************************************************************
943 * GetAutoRotationState [USER32.@]
945 BOOL WINAPI
GetAutoRotationState( AR_STATE
*state
)
947 TRACE("(%p)\n", state
);
951 SetLastError(ERROR_INVALID_PARAMETER
);
955 *state
= AR_NOSENSOR
;
959 /**********************************************************************
960 * GetDisplayAutoRotationPreferences [USER32.@]
962 BOOL WINAPI
GetDisplayAutoRotationPreferences( ORIENTATION_PREFERENCE
*orientation
)
964 FIXME("(%p): stub\n", orientation
);
965 *orientation
= ORIENTATION_PREFERENCE_NONE
;
969 /* physical<->logical mapping functions from win8 that are nops in later versions */
971 /***********************************************************************
972 * GetPhysicalCursorPos (USER32.@)
974 BOOL WINAPI
GetPhysicalCursorPos( POINT
*point
)
976 return GetCursorPos( point
);
979 /***********************************************************************
980 * SetPhysicalCursorPos (USER32.@)
982 BOOL WINAPI
SetPhysicalCursorPos( INT x
, INT y
)
984 return NtUserSetCursorPos( x
, y
);
987 /***********************************************************************
988 * WindowFromPhysicalPoint (USER32.@)
990 HWND WINAPI
WindowFromPhysicalPoint( POINT pt
)
992 return WindowFromPoint( pt
);
995 /***********************************************************************
996 * LogicalToPhysicalPoint (USER32.@)
998 BOOL WINAPI
LogicalToPhysicalPoint( HWND hwnd
, POINT
*point
)
1003 /***********************************************************************
1004 * PhysicalToLogicalPoint (USER32.@)
1006 BOOL WINAPI
PhysicalToLogicalPoint( HWND hwnd
, POINT
*point
)
1011 static DISPLAYCONFIG_ROTATION
get_dc_rotation(const DEVMODEW
*devmode
)
1013 if (devmode
->dmFields
& DM_DISPLAYORIENTATION
)
1014 return devmode
->dmDisplayOrientation
+ 1;
1016 return DISPLAYCONFIG_ROTATION_IDENTITY
;
1019 static DISPLAYCONFIG_SCANLINE_ORDERING
get_dc_scanline_ordering(const DEVMODEW
*devmode
)
1021 if (!(devmode
->dmFields
& DM_DISPLAYFLAGS
))
1022 return DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED
;
1023 else if (devmode
->dmDisplayFlags
& DM_INTERLACED
)
1024 return DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED
;
1026 return DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE
;
1029 static DISPLAYCONFIG_PIXELFORMAT
get_dc_pixelformat(DWORD dmBitsPerPel
)
1031 if ((dmBitsPerPel
== 8) || (dmBitsPerPel
== 16) ||
1032 (dmBitsPerPel
== 24) || (dmBitsPerPel
== 32))
1033 return dmBitsPerPel
/ 8;
1035 return DISPLAYCONFIG_PIXELFORMAT_NONGDI
;
1038 static void set_mode_target_info(DISPLAYCONFIG_MODE_INFO
*info
, const LUID
*gpu_luid
, UINT32 target_id
,
1039 UINT32 flags
, const DEVMODEW
*devmode
)
1041 DISPLAYCONFIG_TARGET_MODE
*mode
= &info
->targetMode
;
1043 info
->infoType
= DISPLAYCONFIG_MODE_INFO_TYPE_TARGET
;
1044 info
->adapterId
= *gpu_luid
;
1045 info
->id
= target_id
;
1047 /* FIXME: Populate pixelRate/hSyncFreq/totalSize with real data */
1048 mode
->targetVideoSignalInfo
.pixelRate
= devmode
->dmDisplayFrequency
* devmode
->dmPelsWidth
* devmode
->dmPelsHeight
;
1049 mode
->targetVideoSignalInfo
.hSyncFreq
.Numerator
= devmode
->dmDisplayFrequency
* devmode
->dmPelsWidth
;
1050 mode
->targetVideoSignalInfo
.hSyncFreq
.Denominator
= 1;
1051 mode
->targetVideoSignalInfo
.vSyncFreq
.Numerator
= devmode
->dmDisplayFrequency
;
1052 mode
->targetVideoSignalInfo
.vSyncFreq
.Denominator
= 1;
1053 mode
->targetVideoSignalInfo
.activeSize
.cx
= devmode
->dmPelsWidth
;
1054 mode
->targetVideoSignalInfo
.activeSize
.cy
= devmode
->dmPelsHeight
;
1055 if (flags
& QDC_DATABASE_CURRENT
)
1057 mode
->targetVideoSignalInfo
.totalSize
.cx
= 0;
1058 mode
->targetVideoSignalInfo
.totalSize
.cy
= 0;
1062 mode
->targetVideoSignalInfo
.totalSize
.cx
= devmode
->dmPelsWidth
;
1063 mode
->targetVideoSignalInfo
.totalSize
.cy
= devmode
->dmPelsHeight
;
1065 mode
->targetVideoSignalInfo
.videoStandard
= D3DKMDT_VSS_OTHER
;
1066 mode
->targetVideoSignalInfo
.scanLineOrdering
= get_dc_scanline_ordering(devmode
);
1069 static void set_path_target_info(DISPLAYCONFIG_PATH_TARGET_INFO
*info
, const LUID
*gpu_luid
,
1070 UINT32 target_id
, UINT32 mode_index
, const DEVMODEW
*devmode
)
1072 info
->adapterId
= *gpu_luid
;
1073 info
->id
= target_id
;
1074 info
->modeInfoIdx
= mode_index
;
1075 info
->outputTechnology
= DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EXTERNAL
;
1076 info
->rotation
= get_dc_rotation(devmode
);
1077 info
->scaling
= DISPLAYCONFIG_SCALING_IDENTITY
;
1078 info
->refreshRate
.Numerator
= devmode
->dmDisplayFrequency
;
1079 info
->refreshRate
.Denominator
= 1;
1080 info
->scanLineOrdering
= get_dc_scanline_ordering(devmode
);
1081 info
->targetAvailable
= TRUE
;
1082 info
->statusFlags
= DISPLAYCONFIG_TARGET_IN_USE
;
1085 static void set_mode_source_info(DISPLAYCONFIG_MODE_INFO
*info
, const LUID
*gpu_luid
,
1086 UINT32 source_id
, const DEVMODEW
*devmode
)
1088 DISPLAYCONFIG_SOURCE_MODE
*mode
= &(info
->sourceMode
);
1090 info
->infoType
= DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE
;
1091 info
->adapterId
= *gpu_luid
;
1092 info
->id
= source_id
;
1094 mode
->width
= devmode
->dmPelsWidth
;
1095 mode
->height
= devmode
->dmPelsHeight
;
1096 mode
->pixelFormat
= get_dc_pixelformat(devmode
->dmBitsPerPel
);
1097 if (devmode
->dmFields
& DM_POSITION
)
1099 mode
->position
= devmode
->dmPosition
;
1103 mode
->position
.x
= 0;
1104 mode
->position
.y
= 0;
1108 static void set_path_source_info(DISPLAYCONFIG_PATH_SOURCE_INFO
*info
, const LUID
*gpu_luid
,
1109 UINT32 source_id
, UINT32 mode_index
)
1111 info
->adapterId
= *gpu_luid
;
1112 info
->id
= source_id
;
1113 info
->modeInfoIdx
= mode_index
;
1114 info
->statusFlags
= DISPLAYCONFIG_SOURCE_IN_USE
;
1117 static BOOL
source_mode_exists(const DISPLAYCONFIG_MODE_INFO
*modeinfo
, UINT32 num_modes
,
1118 UINT32 source_id
, UINT32
*found_mode_index
)
1122 for (i
= 0; i
< num_modes
; i
++)
1124 if (modeinfo
[i
].infoType
== DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE
&&
1125 modeinfo
[i
].id
== source_id
)
1127 *found_mode_index
= i
;
1134 /***********************************************************************
1135 * QueryDisplayConfig (USER32.@)
1137 LONG WINAPI
QueryDisplayConfig(UINT32 flags
, UINT32
*numpathelements
, DISPLAYCONFIG_PATH_INFO
*pathinfo
,
1138 UINT32
*numinfoelements
, DISPLAYCONFIG_MODE_INFO
*modeinfo
,
1139 DISPLAYCONFIG_TOPOLOGY_ID
*topologyid
)
1141 LONG adapter_index
, ret
;
1144 SP_DEVINFO_DATA device_data
= {sizeof(device_data
)};
1145 DWORD monitor_index
= 0, state_flags
, type
;
1146 UINT32 output_id
, source_mode_index
, path_index
= 0, mode_index
= 0;
1148 WCHAR device_name
[CCHDEVICENAME
];
1151 FIXME("(%08x %p %p %p %p %p): semi-stub\n", flags
, numpathelements
, pathinfo
, numinfoelements
, modeinfo
, topologyid
);
1153 if (!numpathelements
|| !numinfoelements
)
1154 return ERROR_INVALID_PARAMETER
;
1156 if (!*numpathelements
|| !*numinfoelements
)
1157 return ERROR_INVALID_PARAMETER
;
1159 if (flags
!= QDC_ALL_PATHS
&&
1160 flags
!= QDC_ONLY_ACTIVE_PATHS
&&
1161 flags
!= QDC_DATABASE_CURRENT
)
1162 return ERROR_INVALID_PARAMETER
;
1164 if (((flags
== QDC_DATABASE_CURRENT
) && !topologyid
) ||
1165 ((flags
!= QDC_DATABASE_CURRENT
) && topologyid
))
1166 return ERROR_INVALID_PARAMETER
;
1168 if (flags
!= QDC_ONLY_ACTIVE_PATHS
)
1169 FIXME("only returning active paths\n");
1173 FIXME("setting toplogyid to DISPLAYCONFIG_TOPOLOGY_INTERNAL\n");
1174 *topologyid
= DISPLAYCONFIG_TOPOLOGY_INTERNAL
;
1177 wait_graphics_driver_ready();
1178 mutex
= get_display_device_init_mutex();
1180 /* Iterate through "targets"/monitors.
1181 * Each target corresponds to a path, and each path corresponds to one or two unique modes.
1183 devinfo
= SetupDiGetClassDevsW(&GUID_DEVCLASS_MONITOR
, L
"DISPLAY", NULL
, DIGCF_PRESENT
);
1184 if (devinfo
== INVALID_HANDLE_VALUE
)
1186 ret
= ERROR_GEN_FAILURE
;
1190 ret
= ERROR_GEN_FAILURE
;
1191 while (SetupDiEnumDeviceInfo(devinfo
, monitor_index
++, &device_data
))
1193 /* Only count active monitors */
1194 if (!SetupDiGetDevicePropertyW(devinfo
, &device_data
, &WINE_DEVPROPKEY_MONITOR_STATEFLAGS
,
1195 &type
, (BYTE
*)&state_flags
, sizeof(state_flags
), NULL
, 0))
1197 if (!(state_flags
& DISPLAY_DEVICE_ACTIVE
))
1200 if (!SetupDiGetDevicePropertyW(devinfo
, &device_data
, &DEVPROPKEY_MONITOR_GPU_LUID
,
1201 &type
, (BYTE
*)&gpu_luid
, sizeof(gpu_luid
), NULL
, 0))
1204 if (!SetupDiGetDevicePropertyW(devinfo
, &device_data
, &DEVPROPKEY_MONITOR_OUTPUT_ID
,
1205 &type
, (BYTE
*)&output_id
, sizeof(output_id
), NULL
, 0))
1208 if (!SetupDiGetDevicePropertyW(devinfo
, &device_data
, &WINE_DEVPROPKEY_MONITOR_ADAPTERNAME
,
1209 &type
, (BYTE
*)device_name
, sizeof(device_name
), NULL
, 0))
1212 memset(&devmode
, 0, sizeof(devmode
));
1213 devmode
.dmSize
= sizeof(devmode
);
1214 if (!EnumDisplaySettingsW(device_name
, ENUM_CURRENT_SETTINGS
, &devmode
))
1217 /* Extract the adapter index from device_name to use as the source ID */
1218 adapter_index
= wcstol(device_name
+ lstrlenW(L
"\\\\.\\DISPLAY"), NULL
, 10);
1221 if (path_index
== *numpathelements
|| mode_index
== *numinfoelements
)
1223 ret
= ERROR_INSUFFICIENT_BUFFER
;
1227 pathinfo
[path_index
].flags
= DISPLAYCONFIG_PATH_ACTIVE
;
1228 set_mode_target_info(&modeinfo
[mode_index
], &gpu_luid
, output_id
, flags
, &devmode
);
1229 set_path_target_info(&(pathinfo
[path_index
].targetInfo
), &gpu_luid
, output_id
, mode_index
, &devmode
);
1232 if (mode_index
== *numinfoelements
)
1234 ret
= ERROR_INSUFFICIENT_BUFFER
;
1238 /* Multiple targets can be driven by the same source, ensure a mode
1239 * hasn't already been added for this source.
1241 if (!source_mode_exists(modeinfo
, mode_index
, adapter_index
, &source_mode_index
))
1243 set_mode_source_info(&modeinfo
[mode_index
], &gpu_luid
, adapter_index
, &devmode
);
1244 source_mode_index
= mode_index
;
1247 set_path_source_info(&(pathinfo
[path_index
].sourceInfo
), &gpu_luid
, adapter_index
, source_mode_index
);
1251 *numpathelements
= path_index
;
1252 *numinfoelements
= mode_index
;
1253 ret
= ERROR_SUCCESS
;
1256 SetupDiDestroyDeviceInfoList(devinfo
);
1257 release_display_device_init_mutex(mutex
);
1261 /***********************************************************************
1262 * DisplayConfigGetDeviceInfo (USER32.@)
1264 LONG WINAPI
DisplayConfigGetDeviceInfo(DISPLAYCONFIG_DEVICE_INFO_HEADER
*packet
)
1266 return RtlNtStatusToDosError(NtUserDisplayConfigGetDeviceInfo(packet
));
1269 /***********************************************************************
1270 * SetDisplayConfig (USER32.@)
1272 LONG WINAPI
SetDisplayConfig(UINT32 path_info_count
, DISPLAYCONFIG_PATH_INFO
*path_info
, UINT32 mode_info_count
,
1273 DISPLAYCONFIG_MODE_INFO
*mode_info
, UINT32 flags
)
1275 FIXME("path_info_count %u, path_info %p, mode_info_count %u, mode_info %p, flags %#x stub.\n",
1276 path_info_count
, path_info
, mode_info_count
, mode_info
, flags
);
1278 return ERROR_SUCCESS
;