From: R��mi Bernon rbernon@codeweavers.com
--- dlls/win32u/driver.c | 2 +- dlls/win32u/sysparams.c | 73 +++++++++++++++++++++++++++++++---------- 2 files changed, 56 insertions(+), 19 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 3d29453c2bf..d7bc5ebc17d 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -756,7 +756,7 @@ static void nulldrv_UpdateClipboard(void) static LONG nulldrv_ChangeDisplaySettingsEx( LPCWSTR name, LPDEVMODEW mode, HWND hwnd, DWORD flags, LPVOID lparam ) { - return DISP_CHANGE_FAILED; + return E_NOTIMPL; }
static BOOL nulldrv_EnumDisplaySettingsEx( LPCWSTR name, DWORD num, LPDEVMODEW mode, DWORD flags ) diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 80f18244049..335d414169a 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -530,7 +530,7 @@ static BOOL read_registry_settings( const WCHAR *adapter_path, DEVMODEW *mode ) return ret; }
-static BOOL write_registry_settings( const WCHAR *adapter_path, const DEVMODEW *mode ) +static BOOL write_registry_settings( const WCHAR *adapter_path, DWORD index, const DEVMODEW *mode ) { HANDLE mutex; HKEY hkey; @@ -542,7 +542,7 @@ static BOOL write_registry_settings( const WCHAR *adapter_path, const DEVMODEW * if (!(hkey = reg_open_key( config_key, adapter_path, lstrlenW( adapter_path ) * sizeof(WCHAR) ))) ret = FALSE; else { - ret = write_adapter_mode( hkey, ENUM_REGISTRY_SETTINGS, mode ); + ret = write_adapter_mode( hkey, index, mode ); NtClose( hkey ); }
@@ -1478,7 +1478,7 @@ static BOOL update_display_cache_from_registry(void) return ret; }
-static BOOL update_display_cache(void) +static BOOL update_display_cache( BOOL force ) { HWINSTA winstation = NtUserGetProcessWindowStation(); struct device_manager_ctx ctx = {0}; @@ -1495,14 +1495,17 @@ static BOOL update_display_cache(void) return TRUE; }
- user_driver->pUpdateDisplayDevices( &device_manager, FALSE, &ctx ); - release_display_manager_ctx( &ctx ); - - if (update_display_cache_from_registry()) return TRUE; - if (ctx.gpu_count) + if (!force) { - ERR( "driver reported devices, but we failed to read them\n" ); - return FALSE; + user_driver->pUpdateDisplayDevices( &device_manager, FALSE, &ctx ); + release_display_manager_ctx( &ctx ); + + if (update_display_cache_from_registry()) return TRUE; + if (ctx.gpu_count) + { + ERR( "driver reported devices, but we failed to read them\n" ); + return FALSE; + } }
if (!user_driver->pUpdateDisplayDevices( &device_manager, TRUE, &ctx )) @@ -1530,13 +1533,20 @@ static BOOL update_display_cache(void) struct gdi_monitor monitor = { .state_flags = DISPLAY_DEVICE_ACTIVE | DISPLAY_DEVICE_ATTACHED, - .rc_monitor = {.right = modes[2].dmPelsWidth, .bottom = modes[2].dmPelsHeight}, - .rc_work = {.right = modes[2].dmPelsWidth, .bottom = modes[2].dmPelsHeight}, }; + DEVMODEW mode = {0}; UINT i;
add_gpu( &gpu, &ctx ); add_adapter( &adapter, &ctx ); + + if (!read_adapter_mode( ctx.adapter_key, ENUM_CURRENT_SETTINGS, &mode )) mode = modes[2]; + write_adapter_mode( ctx.adapter_key, ENUM_CURRENT_SETTINGS, &mode ); + monitor.rc_monitor.right = mode.dmPelsWidth; + monitor.rc_monitor.bottom = mode.dmPelsHeight; + monitor.rc_work.right = mode.dmPelsWidth; + monitor.rc_work.bottom = mode.dmPelsHeight; + add_monitor( &monitor, &ctx ); for (i = 0; i < ARRAY_SIZE(modes); ++i) add_mode( modes + i, &ctx ); } @@ -1552,7 +1562,7 @@ static BOOL update_display_cache(void)
static BOOL lock_display_devices(void) { - if (!update_display_cache()) return FALSE; + if (!update_display_cache( FALSE )) return FALSE; pthread_mutex_lock( &display_lock ); return TRUE; } @@ -2107,9 +2117,10 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm { DEVMODEW *modes, default_mode = {.dmSize = sizeof(DEVMODEW)}, current_mode = {.dmSize = sizeof(DEVMODEW)}; WCHAR device_name[CCHDEVICENAME], adapter_path[MAX_PATH]; + DISPLAY_DEVICEW info = {.cb = sizeof(DISPLAY_DEVICEW)}; LONG ret = DISP_CHANGE_SUCCESSFUL; struct adapter *adapter; - SIZE_T size; + SIZE_T i, size;
TRACE( "%s %p %p %#x %p\n", debugstr_us(devname), devmode, hwnd, flags, lparam ); TRACE( "flags=%s\n", _CDS_flags(flags) ); @@ -2117,8 +2128,19 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm if ((!devname || !devname->Length) && !devmode) { ret = user_driver->pChangeDisplaySettingsEx( NULL, NULL, hwnd, flags, lparam ); - if (ret != DISP_CHANGE_SUCCESSFUL) - ERR( "Restoring all displays to their registry settings returned %d.\n", ret ); + if (ret != E_NOTIMPL) + { + if (ret) ERR( "Restoring all displays to their registry settings returned %d.\n", ret ); + return ret; + } + + for (i = 0; !NtUserEnumDisplayDevices( NULL, i, &info, 0 ); ++i) + { + UNICODE_STRING str; + RtlInitUnicodeString( &str, info.DeviceName ); + if ((ret = NtUserChangeDisplaySettings( &str, NULL, hwnd, flags, lparam ))) break; + } + return ret; }
@@ -2143,9 +2165,24 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm if (!NtUserEnumDisplaySettings( devname, ENUM_CURRENT_SETTINGS, ¤t_mode, 0 )) current_mode.dmSize = 0;
if (!(devmode = validate_display_settings( modes, &default_mode, ¤t_mode, devmode ))) ret = DISP_CHANGE_BADMODE; - else if ((flags & CDS_UPDATEREGISTRY) && !write_registry_settings( adapter_path, devmode )) ret = DISP_CHANGE_NOTUPDATED; + else if ((flags & CDS_UPDATEREGISTRY) && !write_registry_settings( adapter_path, ENUM_REGISTRY_SETTINGS, devmode )) ret = DISP_CHANGE_NOTUPDATED; else if (flags & (CDS_TEST | CDS_NORESET)) ret = DISP_CHANGE_SUCCESSFUL; - else ret = user_driver->pChangeDisplaySettingsEx( device_name, devmode, hwnd, flags, lparam ); + else if ((ret = user_driver->pChangeDisplaySettingsEx( device_name, devmode, hwnd, flags, lparam )) == E_NOTIMPL) + { + if (!write_registry_settings( adapter_path, ENUM_CURRENT_SETTINGS, devmode )) ret = DISP_CHANGE_FAILED; + else if (!update_display_cache( TRUE )) ret = DISP_CHANGE_FAILED; + else + { + NtUserSetWindowPos( NtUserGetDesktopWindow(), 0, devmode->dmPosition.x, devmode->dmPosition.y, + devmode->dmPelsWidth, devmode->dmPelsHeight, + SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERERASE ); + NtUserClipCursor( NULL ); + send_message_timeout( HWND_BROADCAST, WM_DISPLAYCHANGE, devmode->dmBitsPerPel, + MAKELPARAM( devmode->dmPelsWidth, devmode->dmPelsHeight ), + SMTO_ABORTIFHUNG, 2000, NULL, FALSE ); + ret = DISP_CHANGE_SUCCESSFUL; + } + } free( modes );
if (ret) ERR( "Changing %s display settings returned %d.\n", debugstr_us(devname), ret );