From: R��mi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 46 +++++++++++++++++++--- dlls/winemac.drv/display.c | 78 ++++++++++---------------------------- dlls/winex11.drv/display.c | 47 +++-------------------- 3 files changed, 66 insertions(+), 105 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index edf094cd1e7..5c152c20280 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2026,7 +2026,34 @@ static BOOL is_detached_mode( const DEVMODEW *mode ) mode->dmPelsHeight == 0; }
-static DEVMODEW *validate_display_settings( const WCHAR *adapter_path, const WCHAR *device_name, DEVMODEW *devmode, DEVMODEW *temp_mode ) +static DEVMODEW *find_display_mode( DEVMODEW *modes, DEVMODEW *devmode ) +{ + DEVMODEW *mode; + + 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 && mode->dmDisplayFrequency) + continue; + if ((devmode->dmFields & DM_DISPLAYORIENTATION) && devmode->dmDisplayOrientation != mode->dmDisplayOrientation) + continue; + + return mode; + } + + return NULL; +} + +static DEVMODEW *get_full_mode( const WCHAR *adapter_path, const WCHAR *device_name, DEVMODEW *modes, + DEVMODEW *devmode, DEVMODEW *temp_mode ) { if (devmode) { @@ -2068,6 +2095,12 @@ static DEVMODEW *validate_display_settings( const WCHAR *adapter_path, const WCH } }
+ if ((devmode = find_display_mode( modes, devmode )) && devmode != temp_mode) + { + devmode->dmFields |= DM_POSITION; + devmode->dmPosition = temp_mode->dmPosition; + } + return devmode; }
@@ -2077,8 +2110,8 @@ static DEVMODEW *validate_display_settings( const WCHAR *adapter_path, const WCH LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devmode, HWND hwnd, DWORD flags, void *lparam ) { + DEVMODEW *modes, temp_mode = {.dmSize = sizeof(DEVMODEW)}; WCHAR device_name[CCHDEVICENAME], adapter_path[MAX_PATH]; - DEVMODEW temp_mode = {.dmSize = sizeof(DEVMODEW)}; LONG ret = DISP_CHANGE_SUCCESSFUL; struct adapter *adapter;
@@ -2098,19 +2131,22 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm { lstrcpyW( device_name, adapter->dev.device_name ); lstrcpyW( adapter_path, adapter->config_key ); + /* allocate an extra mode to make iteration easier */ + modes = calloc( adapter->mode_count + 1, sizeof(DEVMODEW) ); + if (modes) memcpy( modes, adapter->modes, adapter->mode_count * sizeof(DEVMODEW) ); } unlock_display_devices(); - if (!adapter) + if (!adapter || !modes) { WARN( "Invalid device name %s.\n", debugstr_us(devname) ); return DISP_CHANGE_BADPARAM; }
- if (!(devmode = validate_display_settings( adapter_path, device_name, devmode, &temp_mode ))) ret = DISP_CHANGE_BADMODE; - else if (user_driver->pChangeDisplaySettingsEx( device_name, devmode, hwnd, flags | CDS_TEST, lparam )) ret = DISP_CHANGE_BADMODE; + if (!(devmode = get_full_mode( adapter_path, device_name, modes, devmode, &temp_mode ))) 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 2d7b9656103..d68bc205591 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -720,7 +720,6 @@ static CGDisplayModeRef find_best_display_mode(DEVMODEW *devmode, CFArrayRef dis { CFIndex count, i, best; CGDisplayModeRef best_display_mode; - uint32_t best_io_flags;
best_display_mode = NULL;
@@ -733,6 +732,9 @@ static CGDisplayModeRef find_best_display_mode(DEVMODEW *devmode, CFArrayRef dis int mode_bpp = display_mode_bits_per_pixel(display_mode); size_t width = CGDisplayModeGetWidth(display_mode); size_t height = CGDisplayModeGetHeight(display_mode); + double refresh_rate = CGDisplayModeGetRefreshRate(display_mode); + if (!refresh_rate) + refresh_rate = 60;
if (is_original && retina_enabled) { @@ -743,58 +745,22 @@ static CGDisplayModeRef find_best_display_mode(DEVMODEW *devmode, CFArrayRef dis if (bpp != mode_bpp) continue;
- if (devmode->dmFields & DM_PELSWIDTH) - { - if (devmode->dmPelsWidth != width) - continue; - } - if (devmode->dmFields & DM_PELSHEIGHT) - { - if (devmode->dmPelsHeight != height) - continue; - } - if ((devmode->dmFields & DM_DISPLAYFREQUENCY) && - devmode->dmDisplayFrequency != 0 && - devmode->dmDisplayFrequency != 1) - { - double refresh_rate = CGDisplayModeGetRefreshRate(display_mode); - if (!refresh_rate) - refresh_rate = 60; - if (devmode->dmDisplayFrequency != (DWORD)refresh_rate) - continue; - } - if (devmode->dmFields & DM_DISPLAYFLAGS) - { - if (!(devmode->dmDisplayFlags & DM_INTERLACED) != !(io_flags & kDisplayModeInterlacedFlag)) - continue; - } - else if (best_display_mode) - { - if (io_flags & kDisplayModeInterlacedFlag && !(best_io_flags & kDisplayModeInterlacedFlag)) - continue; - else if (!(io_flags & kDisplayModeInterlacedFlag) && best_io_flags & kDisplayModeInterlacedFlag) - goto better; - } - if (devmode->dmFields & DM_DISPLAYFIXEDOUTPUT) - { - if (!(devmode->dmDisplayFixedOutput == DMDFO_STRETCH) != !(io_flags & kDisplayModeStretchedFlag)) - continue; - } - else if (best_display_mode) - { - if (io_flags & kDisplayModeStretchedFlag && !(best_io_flags & kDisplayModeStretchedFlag)) - continue; - else if (!(io_flags & kDisplayModeStretchedFlag) && best_io_flags & kDisplayModeStretchedFlag) - goto better; - } + if (devmode->dmPelsWidth != width) + continue; + if (devmode->dmPelsHeight != height) + continue; + if (devmode->dmDisplayFrequency != (DWORD)refresh_rate) + continue; + if (!(devmode->dmDisplayFlags & DM_INTERLACED) != !(io_flags & kDisplayModeInterlacedFlag)) + continue; + if (!(devmode->dmDisplayFixedOutput == DMDFO_STRETCH) != !(io_flags & kDisplayModeStretchedFlag)) + continue;
if (best_display_mode) continue;
-better: best_display_mode = display_mode; best = i; - best_io_flags = io_flags; }
if (best_display_mode) @@ -862,18 +828,13 @@ LONG macdrv_ChangeDisplaySettingsEx(LPCWSTR devname, LPDEVMODEW devmode, pthread_mutex_lock(&modes_mutex); bpp = get_default_bpp(); pthread_mutex_unlock(&modes_mutex); - if ((devmode->dmFields & DM_BITSPERPEL) && devmode->dmBitsPerPel != bpp) + if (devmode->dmBitsPerPel != bpp) TRACE("using default %d bpp instead of caller's request %d bpp\n", bpp, devmode->dmBitsPerPel);
- TRACE("looking for %dx%dx%dbpp @%d Hz", - (devmode->dmFields & DM_PELSWIDTH ? devmode->dmPelsWidth : 0), - (devmode->dmFields & DM_PELSHEIGHT ? devmode->dmPelsHeight : 0), - bpp, - (devmode->dmFields & DM_DISPLAYFREQUENCY ? devmode->dmDisplayFrequency : 0)); - if (devmode->dmFields & DM_DISPLAYFIXEDOUTPUT) - TRACE(" %sstretched", devmode->dmDisplayFixedOutput == DMDFO_STRETCH ? "" : "un"); - if (devmode->dmFields & DM_DISPLAYFLAGS) - TRACE(" %sinterlaced", devmode->dmDisplayFlags & DM_INTERLACED ? "" : "non-"); + TRACE("looking for %dx%dx%dbpp @%d Hz", devmode->dmPelsWidth, devmode->dmPelsHeight, + bpp, devmode->dmDisplayFrequency); + TRACE(" %sstretched", devmode->dmDisplayFixedOutput == DMDFO_STRETCH ? "" : "un"); + TRACE(" %sinterlaced", devmode->dmDisplayFlags & DM_INTERLACED ? "" : "non-"); TRACE("\n");
desc = create_original_display_mode_descriptor(displays[0].displayID); @@ -881,8 +842,7 @@ LONG macdrv_ChangeDisplaySettingsEx(LPCWSTR devname, LPDEVMODEW devmode,
if (best_display_mode) { - 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 c9f2da7e163..a3b93c3a7ca 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -408,22 +408,15 @@ static DEVMODEW *get_full_mode(ULONG_PTR id, DEVMODEW *dev_mode) { found_mode = (DEVMODEW *)((BYTE *)modes + (sizeof(*modes) + modes[0].dmDriverExtra) * mode_idx);
- if (dev_mode->dmFields & DM_BITSPERPEL && - dev_mode->dmBitsPerPel && - found_mode->dmBitsPerPel != dev_mode->dmBitsPerPel) + if (found_mode->dmBitsPerPel != dev_mode->dmBitsPerPel) continue; - if (dev_mode->dmFields & DM_PELSWIDTH && found_mode->dmPelsWidth != dev_mode->dmPelsWidth) + if (found_mode->dmPelsWidth != dev_mode->dmPelsWidth) continue; - if (dev_mode->dmFields & DM_PELSHEIGHT && found_mode->dmPelsHeight != dev_mode->dmPelsHeight) + if (found_mode->dmPelsHeight != dev_mode->dmPelsHeight) continue; - if (dev_mode->dmFields & DM_DISPLAYFREQUENCY && - dev_mode->dmDisplayFrequency && - found_mode->dmDisplayFrequency && - dev_mode->dmDisplayFrequency != 1 && - dev_mode->dmDisplayFrequency != found_mode->dmDisplayFrequency) + if (found_mode->dmDisplayFrequency != dev_mode->dmDisplayFrequency) continue; - if (dev_mode->dmFields & DM_DISPLAYORIENTATION && - found_mode->dmDisplayOrientation != dev_mode->dmDisplayOrientation) + if (found_mode->dmDisplayOrientation != dev_mode->dmDisplayOrientation) continue;
break; @@ -774,41 +767,13 @@ static BOOL all_detached_settings(const DEVMODEW *displays) LONG X11DRV_ChangeDisplaySettingsEx( LPCWSTR devname, LPDEVMODEW devmode, HWND hwnd, DWORD flags, LPVOID lpvoid ) { - DEVMODEW *displays, *mode, *full_mode; + DEVMODEW *displays; LONG ret;
ret = get_display_settings( &displays, devname, devmode ); if (ret != DISP_CHANGE_SUCCESSFUL) return ret;
- if (flags & CDS_UPDATEREGISTRY && devname && devmode) - { - for (mode = displays; mode->dmSize; mode = NEXT_DEVMODEW(mode)) - { - ULONG_PTR *id = (ULONG_PTR *)(mode + 1); - - if (!wcsicmp(mode->dmDeviceName, devname)) - { - full_mode = get_full_mode(*id, 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 )) { WARN("Detaching all displays is not permitted.\n");