From: R��mi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 39 +++++++++++++++++++++++++++++++++----- dlls/winemac.drv/display.c | 3 +-- dlls/winex11.drv/display.c | 29 +--------------------------- 3 files changed, 36 insertions(+), 35 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 78bf77400b1..846119872b5 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2037,8 +2037,11 @@ static BOOL is_detached_mode( const DEVMODEW *mode ) mode->dmPelsHeight == 0; }
-static DEVMODEW *validate_display_settings( DEVMODEW *default_mode, DEVMODEW *current_mode, DEVMODEW *devmode ) +static DEVMODEW *validate_display_settings( DEVMODEW *modes, DEVMODEW *default_mode, + DEVMODEW *current_mode, DEVMODEW *devmode ) { + DEVMODEW *mode; + if (devmode) { trace_devmode( devmode ); @@ -2072,7 +2075,28 @@ static DEVMODEW *validate_display_settings( DEVMODEW *default_mode, DEVMODEW *cu if (!devmode->dmPelsHeight) devmode->dmPelsHeight = current_mode->dmPelsHeight; }
- return devmode; + if (is_detached_mode( devmode )) return devmode; + + for (mode = modes; mode && mode->dmSize; mode = NEXT_DEVMODEW(mode)) + { + if ((devmode->dmFields & DM_BITSPERPEL) && devmode->dmBitsPerPel && devmode->dmBitsPerPel != mode->dmBitsPerPel) + continue; + if ((devmode->dmFields & DM_PELSWIDTH) && devmode->dmPelsWidth != mode->dmPelsWidth) + continue; + if ((devmode->dmFields & DM_PELSHEIGHT) && devmode->dmPelsHeight != mode->dmPelsHeight) + continue; + if ((devmode->dmFields & DM_DISPLAYFREQUENCY) && devmode->dmDisplayFrequency && mode->dmDisplayFrequency && + devmode->dmDisplayFrequency != 1 && devmode->dmDisplayFrequency != mode->dmDisplayFrequency) + continue; + if ((devmode->dmFields & DM_DISPLAYORIENTATION) && devmode->dmDisplayOrientation != mode->dmDisplayOrientation) + continue; + + mode->dmFields |= DM_POSITION; + mode->dmPosition = devmode->dmPosition; + return mode; + } + + return NULL; }
/*********************************************************************** @@ -2081,10 +2105,11 @@ static DEVMODEW *validate_display_settings( DEVMODEW *default_mode, DEVMODEW *cu LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devmode, HWND hwnd, DWORD flags, void *lparam ) { - DEVMODEW default_mode = {.dmSize = sizeof(DEVMODEW)}, current_mode = {.dmSize = sizeof(DEVMODEW)}; + DEVMODEW *modes, default_mode = {.dmSize = sizeof(DEVMODEW)}, current_mode = {.dmSize = sizeof(DEVMODEW)}; WCHAR device_name[CCHDEVICENAME], adapter_path[MAX_PATH]; LONG ret = DISP_CHANGE_SUCCESSFUL; struct adapter *adapter; + SIZE_T size;
TRACE( "%s %p %p %#x %p\n", debugstr_us(devname), devmode, hwnd, flags, lparam ); TRACE( "flags=%s\n", _CDS_flags(flags) ); @@ -2102,6 +2127,10 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm { lstrcpyW( device_name, adapter->dev.device_name ); lstrcpyW( adapter_path, adapter->config_key ); + size = sizeof(DEVMODEW) + adapter->modes[0].dmDriverExtra; + /* allocate an extra mode to make iteration easier */ + modes = calloc( adapter->mode_count + 1, size ); + if (modes) memcpy( modes, adapter->modes, adapter->mode_count * size ); } unlock_display_devices(); if (!adapter) @@ -2113,11 +2142,11 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm if (!read_registry_settings( adapter_path, &default_mode )) default_mode.dmSize = 0; if (!NtUserEnumDisplaySettings( devname, ENUM_CURRENT_SETTINGS, ¤t_mode, 0 )) current_mode.dmSize = 0;
- if (!(devmode = validate_display_settings( &default_mode, ¤t_mode, devmode ))) ret = DISP_CHANGE_BADMODE; - else if (user_driver->pChangeDisplaySettingsEx( device_name, devmode, hwnd, flags | CDS_TEST, lparam )) ret = DISP_CHANGE_BADMODE; + 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_TEST | CDS_NORESET)) ret = DISP_CHANGE_SUCCESSFUL; else ret = user_driver->pChangeDisplaySettingsEx( device_name, devmode, hwnd, flags, lparam ); + free( modes );
if (ret) ERR( "Changing %s display settings returned %d.\n", debugstr_us(devname), ret ); return ret; diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index 1350ffcede9..cfff9ee0e74 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -874,8 +874,7 @@ better: /* we have a valid mode */ TRACE("Requested display settings match mode %ld\n", best);
- if (flags & (CDS_TEST | CDS_NORESET)) ret = DISP_CHANGE_SUCCESSFUL; - else if (wcsicmp(primary_adapter, devname)) + if (wcsicmp(primary_adapter, devname)) { FIXME("Changing non-primary adapter settings is currently unsupported.\n"); ret = DISP_CHANGE_SUCCESSFUL; diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index 174411c7915..d296c0ab932 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -779,40 +779,13 @@ LONG X11DRV_ChangeDisplaySettingsEx( LPCWSTR devname, LPDEVMODEW devmode, HWND hwnd, DWORD flags, LPVOID lpvoid ) { struct x11drv_display_setting *displays; - INT display_idx, display_count; - DEVMODEW *full_mode; + INT display_count; LONG ret;
ret = get_display_settings(&displays, &display_count, devname, devmode); if (ret != DISP_CHANGE_SUCCESSFUL) return ret;
- if (flags & CDS_UPDATEREGISTRY && devname && devmode) - { - for (display_idx = 0; display_idx < display_count; ++display_idx) - { - if (!wcsicmp(displays[display_idx].desired_mode.dmDeviceName, devname)) - { - full_mode = get_full_mode(displays[display_idx].id, &displays[display_idx].desired_mode); - if (!full_mode) - { - free(displays); - return DISP_CHANGE_BADMODE; - } - - memcpy( &devmode->dmFields, &full_mode->dmFields, devmode->dmSize - offsetof(DEVMODEW, dmFields) ); - free_full_mode(full_mode); - break; - } - } - } - - if (flags & (CDS_TEST | CDS_NORESET)) - { - free(displays); - return DISP_CHANGE_SUCCESSFUL; - } - if (all_detached_settings(displays, display_count)) { WARN("Detaching all displays is not permitted.\n");