With this series it's now possible to run and pass `user32:monitor` and `user32:sysparams` tests with nulldrv, and so most `user32` tests (except for a few desktop cursor position tests). This still requires some prefix configuration to enable the nulldrv driver, or a change like https://gitlab.winehq.org/rbernon/wine/-/commit/753368ad0ec52f03f8d6e78ca794... to enable it when `DISPLAY` environment variable is unset.
This then shows that some of the user32 tests are failing with winex11 but passing with nulldrv, as in https://gitlab.winehq.org/rbernon/wine/-/commit/6d5f4109a514a0dc266899fcacfa....
-- v3: win32u: Return DISP_CHANGE_SUCCESSFUL from nulldrv_ChangeDisplaySettingsEx. win32u: Read current display settings from the registry if GetCurrentDisplaySettings fails. win32u: Write current display settings to the registry in apply_display_settings. win32u: Force update display cache after NtUserChangeDisplaySettingsEx. win32u: Introduce a new VirtualScreenRectChanged display driver callback. win32u: Broadcast WM_DISPLAYCHANGE message on display settings change. win32u: Move enumeration of available modes out of graphics drivers.
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/win32u/driver.c | 12 --- dlls/win32u/sysparams.c | 21 ++++- dlls/wineandroid.drv/init.c | 31 ------ dlls/winemac.drv/display.c | 181 ++---------------------------------- dlls/winemac.drv/gdi.c | 1 - dlls/winemac.drv/macdrv.h | 2 - dlls/winex11.drv/display.c | 99 -------------------- dlls/winex11.drv/init.c | 1 - dlls/winex11.drv/x11drv.h | 2 - include/wine/gdi_driver.h | 1 - 10 files changed, 28 insertions(+), 323 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index b4ed3f8cb4e..ee4a6534b50 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -759,11 +759,6 @@ static LONG nulldrv_ChangeDisplaySettings( LPDEVMODEW displays, HWND hwnd, return DISP_CHANGE_FAILED; }
-static BOOL nulldrv_EnumDisplaySettingsEx( LPCWSTR name, DWORD num, LPDEVMODEW mode, DWORD flags ) -{ - return FALSE; -} - static BOOL nulldrv_GetCurrentDisplaySettings( LPCWSTR name, LPDEVMODEW mode ) { return FALSE; @@ -1077,11 +1072,6 @@ static LONG loaderdrv_ChangeDisplaySettings( LPDEVMODEW displays, HWND hwnd, return load_driver()->pChangeDisplaySettings( displays, hwnd, flags, lparam ); }
-static BOOL loaderdrv_EnumDisplaySettingsEx( LPCWSTR name, DWORD num, LPDEVMODEW mode, DWORD flags ) -{ - return load_driver()->pEnumDisplaySettingsEx( name, num, mode, flags ); -} - static BOOL loaderdrv_GetCurrentDisplaySettings( LPCWSTR name, LPDEVMODEW mode ) { return load_driver()->pGetCurrentDisplaySettings( name, mode ); @@ -1188,7 +1178,6 @@ static const struct user_driver_funcs lazy_load_driver = loaderdrv_UpdateClipboard, /* display modes */ loaderdrv_ChangeDisplaySettings, - loaderdrv_EnumDisplaySettingsEx, loaderdrv_GetCurrentDisplaySettings, loaderdrv_UpdateDisplayDevices, /* windowing functions */ @@ -1264,7 +1253,6 @@ void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version SET_USER_FUNC(ClipboardWindowProc); SET_USER_FUNC(UpdateClipboard); SET_USER_FUNC(ChangeDisplaySettings); - SET_USER_FUNC(EnumDisplaySettingsEx); SET_USER_FUNC(GetCurrentDisplaySettings); SET_USER_FUNC(UpdateDisplayDevices); SET_USER_FUNC(CreateDesktopWindow); diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 981a11ab05f..202d6d79200 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2490,6 +2490,8 @@ BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD index, DEVM static const WCHAR wine_display_driverW[] = {'W','i','n','e',' ','D','i','s','p','l','a','y',' ','D','r','i','v','e','r',0}; WCHAR device_name[CCHDEVICENAME], adapter_path[MAX_PATH]; struct adapter *adapter; + DEVMODEW *mode, *modes; + SIZE_T size; BOOL ret;
TRACE( "device %s, index %#x, devmode %p, flags %#x\n", debugstr_us(device), index, devmode, flags ); @@ -2499,9 +2501,13 @@ BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD index, 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 for easier iteration */ + modes = calloc( adapter->mode_count + 1, size ); + if (modes) memcpy( modes, adapter->modes, adapter->mode_count * size ); } unlock_display_devices(); - if (!adapter) + if (!adapter || !modes) { WARN( "Invalid device name %s.\n", debugstr_us(device) ); return FALSE; @@ -2514,9 +2520,20 @@ BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD index, DEVM memset( &devmode->dmDriverExtra, 0, devmode->dmSize - offsetof(DEVMODEW, dmDriverExtra) );
if (index == ENUM_REGISTRY_SETTINGS) ret = read_registry_settings( adapter_path, devmode ); - else if (index != ENUM_CURRENT_SETTINGS) ret = user_driver->pEnumDisplaySettingsEx( device_name, index, devmode, flags ); + /* if EDS_ROTATEDMODE is not specified, enumerate modes with the same display orientation as current */ + else if (index != ENUM_CURRENT_SETTINGS && (flags & EDS_ROTATEDMODE)) ret = TRUE; else ret = user_driver->pGetCurrentDisplaySettings( device_name, devmode );
+ if (ret && index != ENUM_REGISTRY_SETTINGS && index != ENUM_CURRENT_SETTINGS) + { + for (ret = FALSE, mode = modes; mode && mode->dmSize && !ret; mode = NEXT_DEVMODEW(mode)) + { + if (!(flags & EDS_ROTATEDMODE) && mode->dmDisplayOrientation != devmode->dmDisplayOrientation) continue; + if ((ret = !index--)) memcpy( &devmode->dmFields, &mode->dmFields, devmode->dmSize - FIELD_OFFSET(DEVMODEW, dmFields) ); + } + } + free( modes ); + if (!ret) WARN( "Failed to query %s display settings.\n", debugstr_w(device_name) ); else TRACE( "position %dx%d, resolution %ux%u, frequency %u, depth %u, orientation %#x.\n", devmode->dmPosition.x, devmode->dmPosition.y, devmode->dmPelsWidth, devmode->dmPelsHeight, diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c index aba642d1c5d..98e24ae4c9d 100644 --- a/dlls/wineandroid.drv/init.c +++ b/dlls/wineandroid.drv/init.c @@ -303,36 +303,6 @@ BOOL ANDROID_UpdateDisplayDevices( const struct gdi_device_manager *device_manag }
-/*********************************************************************** - * ANDROID_EnumDisplaySettingsEx - */ -BOOL ANDROID_EnumDisplaySettingsEx( LPCWSTR name, DWORD n, LPDEVMODEW devmode, DWORD flags ) -{ - if (n > 0) - { - TRACE( "mode %d -- not present\n", n ); - RtlSetLastWin32Error( ERROR_NO_MORE_FILES ); - return FALSE; - } - - devmode->u2.dmDisplayFlags = 0; - devmode->u1.s2.dmPosition.x = 0; - devmode->u1.s2.dmPosition.y = 0; - devmode->u1.s2.dmDisplayOrientation = 0; - devmode->u1.s2.dmDisplayFixedOutput = 0; - devmode->dmPelsWidth = screen_width; - devmode->dmPelsHeight = screen_height; - devmode->dmBitsPerPel = screen_bpp; - devmode->dmDisplayFrequency = 60; - devmode->dmFields = DM_DISPLAYORIENTATION | DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | - DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY; - TRACE( "mode %d -- %dx%d %d bpp @%d Hz\n", n, - devmode->dmPelsWidth, devmode->dmPelsHeight, - devmode->dmBitsPerPel, devmode->dmDisplayFrequency ); - return TRUE; -} - - /*********************************************************************** * ANDROID_GetCurrentDisplaySettings */ @@ -377,7 +347,6 @@ static const struct user_driver_funcs android_drv_funcs = .pVkKeyScanEx = ANDROID_VkKeyScanEx, .pSetCursor = ANDROID_SetCursor, .pChangeDisplaySettings = ANDROID_ChangeDisplaySettings, - .pEnumDisplaySettingsEx = ANDROID_EnumDisplaySettingsEx, .pGetCurrentDisplaySettings = ANDROID_GetCurrentDisplaySettings, .pUpdateDisplayDevices = ANDROID_UpdateDisplayDevices, .pCreateWindow = ANDROID_CreateWindow, diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index 1cebcdfce2f..26c175941a9 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -51,13 +51,6 @@ static const WCHAR initial_mode_keyW[] = {'I','n','i','t','i','a','l',' ','D','i ' ','M','o','d','e'}; static const WCHAR pixelencodingW[] = {'P','i','x','e','l','E','n','c','o','d','i','n','g',0};
-static CFArrayRef cached_modes; -static DWORD cached_modes_flags; -static CGDirectDisplayID cached_modes_display_id; -static BOOL cached_modes_has_8bpp, cached_modes_has_16bpp; -static int cached_default_mode_bpp; -static pthread_mutex_t cached_modes_mutex = PTHREAD_MUTEX_INITIALIZER; - static BOOL inited_original_display_mode;
@@ -395,22 +388,26 @@ static BOOL display_mode_matches_descriptor(CGDisplayModeRef mode, const struct
static int get_default_bpp(void) { + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + static int cached; int ret;
- if (!cached_default_mode_bpp) + pthread_mutex_lock(&mutex); + if (!cached) { CGDisplayModeRef mode = CGDisplayCopyDisplayMode(kCGDirectMainDisplay); if (mode) { - cached_default_mode_bpp = display_mode_bits_per_pixel(mode); + cached = display_mode_bits_per_pixel(mode); CFRelease(mode); }
- if (!cached_default_mode_bpp) - cached_default_mode_bpp = 32; + if (!cached) + cached = 32; } + pthread_mutex_unlock(&mutex);
- ret = cached_default_mode_bpp; + ret = cached;
TRACE(" -> %d\n", ret); return ret; @@ -802,9 +799,7 @@ LONG macdrv_ChangeDisplaySettings(LPDEVMODEW displays, HWND hwnd, DWORD flags, L return DISP_CHANGE_FAILED; }
- pthread_mutex_lock(&cached_modes_mutex); bpp = get_default_bpp(); - pthread_mutex_unlock(&cached_modes_mutex);
desc = create_original_display_mode_descriptor(macdrv_displays[0].displayID);
@@ -934,164 +929,6 @@ static DEVMODEW *display_get_modes(CGDirectDisplayID display_id, int *modes_coun return devmodes; }
-/*********************************************************************** - * EnumDisplaySettingsEx (MACDRV.@) - * - */ -BOOL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, LPDEVMODEW devmode, DWORD flags) -{ - struct macdrv_display *displays = NULL; - int num_displays; - CGDisplayModeRef display_mode; - int display_mode_bpp, display_idx; - BOOL synthesized = FALSE; - CGDirectDisplayID display_id; - DWORD count, i; - WCHAR *end; - - TRACE("%s, %u, %p + %hu, %08x\n", debugstr_w(devname), mode, devmode, devmode->dmSize, flags); - - init_original_display_mode(); - - if (macdrv_get_displays(&displays, &num_displays)) - goto failed; - - display_idx = wcstol(devname + 11, &end, 10) - 1; - if (display_idx >= num_displays) - { - macdrv_free_displays(displays); - return FALSE; - } - - display_id = displays[display_idx].displayID; - - pthread_mutex_lock(&cached_modes_mutex); - - if (mode == 0 || !cached_modes || flags != cached_modes_flags || display_id != cached_modes_display_id) - { - if (cached_modes) CFRelease(cached_modes); - cached_modes = copy_display_modes(display_id, (flags & EDS_RAWMODE) != 0); - cached_modes_has_8bpp = cached_modes_has_16bpp = FALSE; - cached_modes_display_id = display_id; - cached_modes_flags = flags; - - if (cached_modes) - { - count = CFArrayGetCount(cached_modes); - for (i = 0; i < count && !(cached_modes_has_8bpp && cached_modes_has_16bpp); i++) - { - CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(cached_modes, i); - int bpp = display_mode_bits_per_pixel(mode); - if (bpp == 8) - cached_modes_has_8bpp = TRUE; - else if (bpp == 16) - cached_modes_has_16bpp = TRUE; - } - } - } - - display_mode = NULL; - if (cached_modes) - { - int default_bpp; - DWORD seen_modes = 0; - - count = CFArrayGetCount(cached_modes); - for (i = 0; i < count; i++) - { - CGDisplayModeRef candidate = (CGDisplayModeRef)CFArrayGetValueAtIndex(cached_modes, i); - - seen_modes++; - if (seen_modes > mode) - { - display_mode = (CGDisplayModeRef)CFRetain(candidate); - display_mode_bpp = display_mode_bits_per_pixel(display_mode); - break; - } - } - - default_bpp = get_default_bpp(); - - /* If all the real modes are exhausted, synthesize lower bpp modes. */ - if (!display_mode && (!cached_modes_has_16bpp || !cached_modes_has_8bpp)) - { - /* We want to synthesize higher depths first. */ - int synth_bpps[] = { cached_modes_has_16bpp ? 0 : 16, cached_modes_has_8bpp ? 0 : 8 }; - size_t synth_bpp_idx; - for (synth_bpp_idx = 0; synth_bpp_idx < 2; synth_bpp_idx++) - { - int synth_bpp = synth_bpps[synth_bpp_idx]; - if (synth_bpp == 0) - continue; - - for (i = 0; i < count; i++) - { - CGDisplayModeRef candidate = (CGDisplayModeRef)CFArrayGetValueAtIndex(cached_modes, i); - /* We only synthesize modes from those having the default bpp. */ - if (display_mode_bits_per_pixel(candidate) != default_bpp) - continue; - - seen_modes++; - if (seen_modes > mode) - { - display_mode = (CGDisplayModeRef)CFRetain(candidate); - display_mode_bpp = synth_bpp; - synthesized = TRUE; - break; - } - } - - if (display_mode) - break; - } - } - } - - pthread_mutex_unlock(&cached_modes_mutex); - - if (!display_mode) - goto failed; - - display_mode_to_devmode(display_id, display_mode, devmode); - devmode->dmBitsPerPel = display_mode_bpp; - if (devmode->dmBitsPerPel) - devmode->dmFields |= DM_BITSPERPEL; - if (retina_enabled) - { - struct display_mode_descriptor* desc = create_original_display_mode_descriptor(display_id); - if (display_mode_matches_descriptor(display_mode, desc)) - { - devmode->dmPelsWidth *= 2; - devmode->dmPelsHeight *= 2; - } - free_display_mode_descriptor(desc); - } - - CFRelease(display_mode); - macdrv_free_displays(displays); - - TRACE("mode %d -- %dx%dx%dbpp @%d Hz", mode, - devmode->dmPelsWidth, devmode->dmPelsHeight, devmode->dmBitsPerPel, - devmode->dmDisplayFrequency); - if (devmode->dmDisplayOrientation) - TRACE(" rotated %u degrees", devmode->dmDisplayOrientation * 90); - if (devmode->dmDisplayFixedOutput == DMDFO_STRETCH) - TRACE(" stretched"); - if (devmode->dmDisplayFlags & DM_INTERLACED) - TRACE(" interlaced"); - if (synthesized) - TRACE(" (synthesized)"); - TRACE("\n"); - - return TRUE; - -failed: - TRACE("mode %d -- not present\n", mode); - if (displays) macdrv_free_displays(displays); - RtlSetLastWin32Error(ERROR_NO_MORE_FILES); - return FALSE; -} - /*********************************************************************** * GetCurrentDisplaySettings (MACDRV.@) * diff --git a/dlls/winemac.drv/gdi.c b/dlls/winemac.drv/gdi.c index c3e3fa6cdb7..193a3f4bbd2 100644 --- a/dlls/winemac.drv/gdi.c +++ b/dlls/winemac.drv/gdi.c @@ -275,7 +275,6 @@ static const struct user_driver_funcs macdrv_funcs = .pDesktopWindowProc = macdrv_DesktopWindowProc, .pDestroyCursorIcon = macdrv_DestroyCursorIcon, .pDestroyWindow = macdrv_DestroyWindow, - .pEnumDisplaySettingsEx = macdrv_EnumDisplaySettingsEx, .pGetCurrentDisplaySettings = macdrv_GetCurrentDisplaySettings, .pUpdateDisplayDevices = macdrv_UpdateDisplayDevices, .pGetCursorPos = macdrv_GetCursorPos, diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 1b7e6318f1a..7a6588e02c7 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -124,8 +124,6 @@ static inline struct macdrv_thread_data *macdrv_thread_data(void) extern BOOL macdrv_ActivateKeyboardLayout(HKL hkl, UINT flags) DECLSPEC_HIDDEN; extern void macdrv_Beep(void) DECLSPEC_HIDDEN; extern LONG macdrv_ChangeDisplaySettings(LPDEVMODEW displays, HWND hwnd, DWORD flags, LPVOID lpvoid) DECLSPEC_HIDDEN; -extern BOOL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, - LPDEVMODEW devmode, DWORD flags) DECLSPEC_HIDDEN; extern BOOL macdrv_GetCurrentDisplaySettings(LPCWSTR name, LPDEVMODEW devmode) DECLSPEC_HIDDEN; extern LRESULT macdrv_ClipboardWindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) DECLSPEC_HIDDEN; extern BOOL macdrv_UpdateDisplayDevices( const struct gdi_device_manager *device_manager, diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index 55dfcceb6e3..534615f64c8 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -51,12 +51,6 @@ static const unsigned int depths_24[] = {8, 16, 24}; static const unsigned int depths_32[] = {8, 16, 32}; const unsigned int *depths;
-/* Cached display modes for a device, protected by modes_section */ -static WCHAR cached_device_name[CCHDEVICENAME]; -static DWORD cached_flags; -static DEVMODEW *cached_modes; -static UINT cached_mode_count; - static pthread_mutex_t settings_mutex = PTHREAD_MUTEX_INITIALIZER;
void X11DRV_Settings_SetHandler(const struct x11drv_settings_handler *new_handler) @@ -220,54 +214,6 @@ BOOL get_primary_adapter(WCHAR *name) return FALSE; }
-static int mode_compare(const void *p1, const void *p2) -{ - DWORD a_width, a_height, b_width, b_height; - const DEVMODEW *a = p1, *b = p2; - - /* Use the width and height in landscape mode for comparison */ - if (a->dmDisplayOrientation == DMDO_DEFAULT || a->dmDisplayOrientation == DMDO_180) - { - a_width = a->dmPelsWidth; - a_height = a->dmPelsHeight; - } - else - { - a_width = a->dmPelsHeight; - a_height = a->dmPelsWidth; - } - - if (b->dmDisplayOrientation == DMDO_DEFAULT || b->dmDisplayOrientation == DMDO_180) - { - b_width = b->dmPelsWidth; - b_height = b->dmPelsHeight; - } - else - { - b_width = b->dmPelsHeight; - b_height = b->dmPelsWidth; - } - - /* Depth in descending order */ - if (a->dmBitsPerPel != b->dmBitsPerPel) - return b->dmBitsPerPel - a->dmBitsPerPel; - - /* Width in ascending order */ - if (a_width != b_width) - return a_width - b_width; - - /* Height in ascending order */ - if (a_height != b_height) - return a_height - b_height; - - /* Frequency in descending order */ - if (a->dmDisplayFrequency != b->dmDisplayFrequency) - return b->dmDisplayFrequency - a->dmDisplayFrequency; - - /* Orientation in ascending order */ - return a->dmDisplayOrientation - b->dmDisplayOrientation; -} - static void set_display_depth(ULONG_PTR display_id, DWORD depth) { struct x11drv_display_depth *display_depth; @@ -316,51 +262,6 @@ static DWORD get_display_depth(ULONG_PTR display_id) return screen_bpp; }
-/*********************************************************************** - * EnumDisplaySettingsEx (X11DRV.@) - * - */ -BOOL X11DRV_EnumDisplaySettingsEx( LPCWSTR name, DWORD n, LPDEVMODEW devmode, DWORD flags) -{ - DEVMODEW *modes, mode; - UINT mode_count; - ULONG_PTR id; - - pthread_mutex_lock( &settings_mutex ); - if (n == 0 || wcsicmp(cached_device_name, name) || cached_flags != flags) - { - if (!settings_handler.get_id(name, &id) || !settings_handler.get_modes(id, flags, &modes, &mode_count)) - { - ERR("Failed to get %s supported display modes.\n", wine_dbgstr_w(name)); - pthread_mutex_unlock( &settings_mutex ); - return FALSE; - } - - qsort(modes, mode_count, sizeof(*modes) + modes[0].dmDriverExtra, mode_compare); - - if (cached_modes) - settings_handler.free_modes(cached_modes); - lstrcpyW(cached_device_name, name); - cached_flags = flags; - cached_modes = modes; - cached_mode_count = mode_count; - } - - if (n >= cached_mode_count) - { - pthread_mutex_unlock( &settings_mutex ); - WARN("handler:%s device:%s mode index:%#x not found.\n", settings_handler.name, wine_dbgstr_w(name), n); - RtlSetLastWin32Error( ERROR_NO_MORE_FILES ); - return FALSE; - } - - mode = *(DEVMODEW *)((BYTE *)cached_modes + (sizeof(*cached_modes) + cached_modes[0].dmDriverExtra) * n); - pthread_mutex_unlock( &settings_mutex ); - - memcpy( &devmode->dmFields, &mode.dmFields, devmode->dmSize - offsetof(DEVMODEW, dmFields) ); - return TRUE; -} - /*********************************************************************** * GetCurrentDisplaySettings (X11DRV.@) * diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 5d688c27114..4ebe3a16367 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -404,7 +404,6 @@ static const struct user_driver_funcs x11drv_funcs = .pSetCursorPos = X11DRV_SetCursorPos, .pClipCursor = X11DRV_ClipCursor, .pChangeDisplaySettings = X11DRV_ChangeDisplaySettings, - .pEnumDisplaySettingsEx = X11DRV_EnumDisplaySettingsEx, .pGetCurrentDisplaySettings = X11DRV_GetCurrentDisplaySettings, .pUpdateDisplayDevices = X11DRV_UpdateDisplayDevices, .pCreateDesktopWindow = X11DRV_CreateDesktopWindow, diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 07bdd7610d5..90118fea5c1 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -214,8 +214,6 @@ extern BOOL X11DRV_SetCursorPos( INT x, INT y ) DECLSPEC_HIDDEN; extern BOOL X11DRV_GetCursorPos( LPPOINT pos ) DECLSPEC_HIDDEN; extern BOOL X11DRV_ClipCursor( LPCRECT clip ) DECLSPEC_HIDDEN; extern LONG X11DRV_ChangeDisplaySettings( LPDEVMODEW displays, HWND hwnd, DWORD flags, LPVOID lpvoid ) DECLSPEC_HIDDEN; -extern BOOL X11DRV_EnumDisplaySettingsEx( LPCWSTR name, DWORD n, LPDEVMODEW devmode, - DWORD flags ) DECLSPEC_HIDDEN; extern BOOL X11DRV_GetCurrentDisplaySettings( LPCWSTR name, LPDEVMODEW devmode ) DECLSPEC_HIDDEN; extern BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manager, BOOL force, void *param ) DECLSPEC_HIDDEN; diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index e1d8998d812..8c63d13b66a 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -296,7 +296,6 @@ struct user_driver_funcs void (*pUpdateClipboard)(void); /* display modes */ LONG (*pChangeDisplaySettings)(LPDEVMODEW,HWND,DWORD,LPVOID); - BOOL (*pEnumDisplaySettingsEx)(LPCWSTR,DWORD,LPDEVMODEW,DWORD); BOOL (*pGetCurrentDisplaySettings)(LPCWSTR,LPDEVMODEW); BOOL (*pUpdateDisplayDevices)(const struct gdi_device_manager *,BOOL,void*); /* windowing functions */
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/user32/tests/sysparams.c | 4 +--- dlls/win32u/sysparams.c | 5 ++++- dlls/winemac.drv/display.c | 35 ++--------------------------------- dlls/winemac.drv/window.c | 3 +-- dlls/winex11.drv/desktop.c | 10 ++-------- dlls/winex11.drv/display.c | 6 +++--- dlls/winex11.drv/window.c | 2 +- dlls/winex11.drv/x11drv.h | 4 ++-- dlls/winex11.drv/xrandr.c | 6 +----- 9 files changed, 17 insertions(+), 58 deletions(-)
diff --git a/dlls/user32/tests/sysparams.c b/dlls/user32/tests/sysparams.c index 4f2709094e9..da8b66fbc12 100644 --- a/dlls/user32/tests/sysparams.c +++ b/dlls/user32/tests/sysparams.c @@ -2497,9 +2497,7 @@ static void test_WM_DISPLAYCHANGE(void) continue; }
- todo_wine_if(start_bpp != test_bpps[i]) { - ok(last_bpp == test_bpps[i], "Set bpp %d, but WM_DISPLAYCHANGE reported bpp %d\n", test_bpps[i], last_bpp); - } + ok(last_bpp == test_bpps[i], "Set bpp %d, but WM_DISPLAYCHANGE reported bpp %d\n", test_bpps[i], last_bpp); last_set_bpp = test_bpps[i]; }
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 202d6d79200..2766e105c68 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2434,7 +2434,10 @@ static LONG apply_display_settings( const WCHAR *devname, const DEVMODEW *devmod
place_all_displays( displays );
- ret = user_driver->pChangeDisplaySettings( displays, hwnd, flags, lparam ); + if (!(ret = user_driver->pChangeDisplaySettings( displays, hwnd, flags, lparam ))) + send_message_timeout( HWND_BROADCAST, WM_DISPLAYCHANGE, displays->dmBitsPerPel, + MAKELPARAM( displays->dmPelsWidth, displays->dmPelsHeight ), + SMTO_ABORTIFHUNG, 2000, FALSE );
free( displays ); return ret; diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index 26c175941a9..7da902c649f 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -833,20 +833,8 @@ LONG macdrv_ChangeDisplaySettings(LPDEVMODEW displays, HWND hwnd, DWORD flags, L } else if (macdrv_set_display_mode(&macdrv_displays[0], best_display_mode)) { - int mode_bpp = display_mode_bits_per_pixel(best_display_mode); - size_t width = CGDisplayModeGetWidth(best_display_mode); - size_t height = CGDisplayModeGetHeight(best_display_mode); - macdrv_init_display_devices(TRUE); - - if (retina_enabled && display_mode_matches_descriptor(best_display_mode, desc)) - { - width *= 2; - height *= 2; - } - - send_message(NtUserGetDesktopWindow(), WM_MACDRV_UPDATE_DESKTOP_RECT, mode_bpp, - MAKELPARAM(width, height)); + send_message(NtUserGetDesktopWindow(), WM_MACDRV_UPDATE_DESKTOP_RECT, 0, 0); } else { @@ -1183,28 +1171,9 @@ void macdrv_displays_changed(const macdrv_event *event) if (event->displays_changed.activating || NtUserGetWindowThread(hwnd, NULL) == GetCurrentThreadId()) { - CGDirectDisplayID mainDisplay = CGMainDisplayID(); - CGDisplayModeRef mode = CGDisplayCopyDisplayMode(mainDisplay); - size_t width = CGDisplayModeGetWidth(mode); - size_t height = CGDisplayModeGetHeight(mode); - int mode_bpp = display_mode_bits_per_pixel(mode); - struct display_mode_descriptor* desc = create_original_display_mode_descriptor(mainDisplay); - BOOL is_original = display_mode_matches_descriptor(mode, desc); - - free_display_mode_descriptor(desc); - CGDisplayModeRelease(mode); - macdrv_init_display_devices(TRUE); init_registry_display_settings(); - - if (is_original && retina_enabled) - { - width *= 2; - height *= 2; - } - - send_message(hwnd, WM_MACDRV_UPDATE_DESKTOP_RECT, mode_bpp, - MAKELPARAM(width, height)); + send_message(hwnd, WM_MACDRV_UPDATE_DESKTOP_RECT, 0, 0); } }
diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index 22c250c1d18..7a0f6df6449 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -2003,7 +2003,7 @@ LRESULT macdrv_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) NtUserSetWindowPos(hwnd, 0, CGRectGetMinX(new_desktop_rect), CGRectGetMinY(new_desktop_rect), CGRectGetWidth(new_desktop_rect), CGRectGetHeight(new_desktop_rect), SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERERASE); - send_message_timeout(HWND_BROADCAST, WM_MACDRV_DISPLAYCHANGE, wp, lp, + send_message_timeout(HWND_BROADCAST, WM_MACDRV_DISPLAYCHANGE, 0, 0, SMTO_ABORTIFHUNG, 2000, NULL); } } @@ -2013,7 +2013,6 @@ LRESULT macdrv_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) return 0; case WM_MACDRV_DISPLAYCHANGE: macdrv_reassert_window_position(hwnd); - send_message(hwnd, WM_DISPLAYCHANGE, wp, lp); return 0; case WM_MACDRV_ACTIVATE_ON_FOLLOWING_FOCUS: activate_on_following_focus(); diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c index 88bc40f7dfd..3da8f92978d 100644 --- a/dlls/winex11.drv/desktop.c +++ b/dlls/winex11.drv/desktop.c @@ -454,7 +454,7 @@ static void update_desktop_fullscreen( unsigned int width, unsigned int height) /*********************************************************************** * X11DRV_resize_desktop */ -void X11DRV_resize_desktop( BOOL send_display_change ) +void X11DRV_resize_desktop(void) { RECT primary_rect, virtual_rect; HWND hwnd = NtUserGetDesktopWindow(); @@ -467,7 +467,7 @@ void X11DRV_resize_desktop( BOOL send_display_change )
if (NtUserGetWindowThread( hwnd, NULL ) != GetCurrentThreadId()) { - send_message( hwnd, WM_X11DRV_RESIZE_DESKTOP, 0, (LPARAM)send_display_change ); + send_message( hwnd, WM_X11DRV_RESIZE_DESKTOP, 0, 0 ); } else { @@ -477,11 +477,5 @@ void X11DRV_resize_desktop( BOOL send_display_change ) virtual_rect.right - virtual_rect.left, virtual_rect.bottom - virtual_rect.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERERASE ); ungrab_clipping_window(); - - if (send_display_change) - { - send_message_timeout( HWND_BROADCAST, WM_DISPLAYCHANGE, screen_bpp, MAKELPARAM( width, height ), - SMTO_ABORTIFHUNG, 2000, NULL ); - } } } diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index 534615f64c8..76defa7f0e8 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -419,7 +419,7 @@ LONG X11DRV_ChangeDisplaySettings( LPDEVMODEW displays, HWND hwnd, DWORD flags, if (ret == DISP_CHANGE_SUCCESSFUL) ret = apply_display_settings( displays, ids, TRUE ); if (ret == DISP_CHANGE_SUCCESSFUL) - X11DRV_DisplayDevices_Update(TRUE); + X11DRV_DisplayDevices_Update();
done: free( ids ); @@ -558,7 +558,7 @@ void X11DRV_DisplayDevices_RegisterEventHandlers(void) handler->register_event_handlers(); }
-void X11DRV_DisplayDevices_Update(BOOL send_display_change) +void X11DRV_DisplayDevices_Update(void) { RECT old_virtual_rect, new_virtual_rect; DWORD tid, pid; @@ -576,7 +576,7 @@ void X11DRV_DisplayDevices_Update(BOOL send_display_change) if (old_virtual_rect.top != new_virtual_rect.top) mask |= CWY;
- X11DRV_resize_desktop(send_display_change); + X11DRV_resize_desktop();
list = build_hwnd_list(); for (i = 0; list && list[i] != HWND_BOTTOM; i++) diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 118604b0ae0..a7030f69759 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2993,7 +2993,7 @@ LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) } return 0; case WM_X11DRV_RESIZE_DESKTOP: - X11DRV_resize_desktop( (BOOL)lp ); + X11DRV_resize_desktop(); return 0; case WM_X11DRV_SET_CURSOR: { diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 90118fea5c1..2c5104025a5 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -745,7 +745,7 @@ struct x11drv_settings_handler extern void X11DRV_Settings_SetHandler(const struct x11drv_settings_handler *handler) DECLSPEC_HIDDEN;
extern void X11DRV_init_desktop( Window win, unsigned int width, unsigned int height ) DECLSPEC_HIDDEN; -extern void X11DRV_resize_desktop(BOOL) DECLSPEC_HIDDEN; +extern void X11DRV_resize_desktop(void) DECLSPEC_HIDDEN; extern void init_registry_display_settings(void) DECLSPEC_HIDDEN; extern BOOL is_virtual_desktop(void) DECLSPEC_HIDDEN; extern BOOL is_desktop_fullscreen(void) DECLSPEC_HIDDEN; @@ -804,7 +804,7 @@ extern BOOL get_host_primary_gpu(struct gdi_gpu *gpu) DECLSPEC_HIDDEN; extern void X11DRV_DisplayDevices_SetHandler(const struct x11drv_display_device_handler *handler) DECLSPEC_HIDDEN; extern void X11DRV_DisplayDevices_Init(BOOL force) DECLSPEC_HIDDEN; extern void X11DRV_DisplayDevices_RegisterEventHandlers(void) DECLSPEC_HIDDEN; -extern void X11DRV_DisplayDevices_Update(BOOL) DECLSPEC_HIDDEN; +extern void X11DRV_DisplayDevices_Update(void) DECLSPEC_HIDDEN; /* Display device handler used in virtual desktop mode */ extern struct x11drv_display_device_handler desktop_handler DECLSPEC_HIDDEN;
diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c index 2fb71cff9ef..a0ac2cb5ec1 100644 --- a/dlls/winex11.drv/xrandr.c +++ b/dlls/winex11.drv/xrandr.c @@ -1198,11 +1198,7 @@ static BOOL xrandr14_device_change_handler( HWND hwnd, XEvent *event ) xrandr14_invalidate_current_mode_cache(); if (hwnd == NtUserGetDesktopWindow() && NtUserGetWindowThread( hwnd, NULL ) == GetCurrentThreadId()) { - /* Don't send a WM_DISPLAYCHANGE message here because this event may be a result from - * ChangeDisplaySettings(). Otherwise, ChangeDisplaySettings() would send multiple - * WM_DISPLAYCHANGE messages instead of just one */ - X11DRV_DisplayDevices_Update( FALSE ); - + X11DRV_DisplayDevices_Update(); init_registry_display_settings(); } return FALSE;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=122754
Your paranoid android.
=== w8 (32 bit report) ===
user32: sysparams.c:2490: Test failed: Waiting for the WM_DISPLAYCHANGE message timed out sysparams.c:2500: Test failed: Set bpp 32, but WM_DISPLAYCHANGE reported bpp -1
=== w8adm (32 bit report) ===
user32: sysparams.c:2490: Test failed: Waiting for the WM_DISPLAYCHANGE message timed out sysparams.c:2500: Test failed: Set bpp 32, but WM_DISPLAYCHANGE reported bpp -1
=== w864 (32 bit report) ===
user32: sysparams.c:2490: Test failed: Waiting for the WM_DISPLAYCHANGE message timed out sysparams.c:2500: Test failed: Set bpp 32, but WM_DISPLAYCHANGE reported bpp -1
=== w1064v1809 (32 bit report) ===
user32: sysparams.c:2490: Test failed: Waiting for the WM_DISPLAYCHANGE message timed out sysparams.c:2500: Test failed: Set bpp 32, but WM_DISPLAYCHANGE reported bpp -1
=== w1064 (32 bit report) ===
user32: sysparams.c:2490: Test failed: Waiting for the WM_DISPLAYCHANGE message timed out sysparams.c:2500: Test failed: Set bpp 32, but WM_DISPLAYCHANGE reported bpp -1
=== w1064_tsign (32 bit report) ===
user32: sysparams.c:2490: Test failed: Waiting for the WM_DISPLAYCHANGE message timed out sysparams.c:2500: Test failed: Set bpp 32, but WM_DISPLAYCHANGE reported bpp -1
=== w10pro64 (32 bit report) ===
user32: sysparams.c:2490: Test failed: Waiting for the WM_DISPLAYCHANGE message timed out sysparams.c:2500: Test failed: Set bpp 32, but WM_DISPLAYCHANGE reported bpp -1
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/win32u/driver.c | 11 +++++++++++ dlls/win32u/sysparams.c | 15 ++++++++++++++- dlls/winex11.drv/display.c | 13 +++++-------- dlls/winex11.drv/init.c | 1 + dlls/winex11.drv/x11drv.h | 2 +- dlls/winex11.drv/xrandr.c | 2 +- include/wine/gdi_driver.h | 1 + 7 files changed, 34 insertions(+), 11 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index ee4a6534b50..d9c1f0d6f6d 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -769,6 +769,10 @@ static BOOL nulldrv_UpdateDisplayDevices( const struct gdi_device_manager *manag return FALSE; }
+static void nulldrv_VirtualScreenRectChanged( RECT *old_rect, RECT *new_rect ) +{ +} + static BOOL nulldrv_CreateDesktopWindow( HWND hwnd ) { return TRUE; @@ -1112,6 +1116,11 @@ static BOOL loaderdrv_UpdateDisplayDevices( const struct gdi_device_manager *man return load_driver()->pUpdateDisplayDevices( manager, force, param ); }
+static void loaderdrv_VirtualScreenRectChanged( RECT *old_rect, RECT *new_rect ) +{ + return load_driver()->pVirtualScreenRectChanged( old_rect, new_rect ); +} + static BOOL loaderdrv_CreateDesktopWindow( HWND hwnd ) { return load_driver()->pCreateDesktopWindow( hwnd ); @@ -1180,6 +1189,7 @@ static const struct user_driver_funcs lazy_load_driver = loaderdrv_ChangeDisplaySettings, loaderdrv_GetCurrentDisplaySettings, loaderdrv_UpdateDisplayDevices, + loaderdrv_VirtualScreenRectChanged, /* windowing functions */ loaderdrv_CreateDesktopWindow, loaderdrv_CreateWindow, @@ -1255,6 +1265,7 @@ void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version SET_USER_FUNC(ChangeDisplaySettings); SET_USER_FUNC(GetCurrentDisplaySettings); SET_USER_FUNC(UpdateDisplayDevices); + SET_USER_FUNC(VirtualScreenRectChanged); SET_USER_FUNC(CreateDesktopWindow); SET_USER_FUNC(CreateWindow); SET_USER_FUNC(DesktopWindowProc); diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 2766e105c68..0a7a852cf12 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1539,7 +1539,9 @@ static BOOL update_display_cache_from_registry(void) static BOOL update_display_cache(void) { HWINSTA winstation = NtUserGetProcessWindowStation(); + RECT old_virtual_rect = {0}, new_virtual_rect = {0}; struct device_manager_ctx ctx = {0}; + struct monitor *monitor; USEROBJECTFLAGS flags;
/* services do not have any adapters, only a virtual monitor */ @@ -1553,10 +1555,13 @@ static BOOL update_display_cache(void) return TRUE; }
+ LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) + union_rect( &old_virtual_rect, &old_virtual_rect, &monitor->rc_monitor ); + user_driver->pUpdateDisplayDevices( &device_manager, FALSE, &ctx ); release_display_manager_ctx( &ctx );
- if (update_display_cache_from_registry()) return TRUE; + if (update_display_cache_from_registry()) goto done; if (ctx.gpu_count) { ERR( "driver reported devices, but we failed to read them\n" ); @@ -1605,6 +1610,14 @@ static BOOL update_display_cache(void) ERR( "failed to read display config\n" ); return FALSE; } + +done: + LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) + union_rect( &new_virtual_rect, &new_virtual_rect, &monitor->rc_monitor ); + + if (!IsRectEmpty( &old_virtual_rect ) && !EqualRect( &old_virtual_rect, &new_virtual_rect )) + user_driver->pVirtualScreenRectChanged( &old_virtual_rect, &new_virtual_rect ); + return TRUE; }
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index 76defa7f0e8..b80ec825980 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -419,7 +419,7 @@ LONG X11DRV_ChangeDisplaySettings( LPDEVMODEW displays, HWND hwnd, DWORD flags, if (ret == DISP_CHANGE_SUCCESSFUL) ret = apply_display_settings( displays, ids, TRUE ); if (ret == DISP_CHANGE_SUCCESSFUL) - X11DRV_DisplayDevices_Update(); + X11DRV_DisplayDevices_Init(TRUE);
done: free( ids ); @@ -558,22 +558,19 @@ void X11DRV_DisplayDevices_RegisterEventHandlers(void) handler->register_event_handlers(); }
-void X11DRV_DisplayDevices_Update(void) +void X11DRV_VirtualScreenRectChanged( RECT *old_rect, RECT *new_rect ) { - RECT old_virtual_rect, new_virtual_rect; DWORD tid, pid; HWND foreground; UINT mask = 0, i; HWND *list;
- old_virtual_rect = NtUserGetVirtualScreenRect(); - X11DRV_DisplayDevices_Init(TRUE); - new_virtual_rect = NtUserGetVirtualScreenRect(); + TRACE( "old_rect %s, new_rect %s.\n", wine_dbgstr_rect(old_rect), wine_dbgstr_rect(new_rect) );
/* Calculate XReconfigureWMWindow() mask */ - if (old_virtual_rect.left != new_virtual_rect.left) + if (old_rect->left != new_rect->left) mask |= CWX; - if (old_virtual_rect.top != new_virtual_rect.top) + if (old_rect->top != new_rect->top) mask |= CWY;
X11DRV_resize_desktop(); diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 4ebe3a16367..6d7614a45da 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -406,6 +406,7 @@ static const struct user_driver_funcs x11drv_funcs = .pChangeDisplaySettings = X11DRV_ChangeDisplaySettings, .pGetCurrentDisplaySettings = X11DRV_GetCurrentDisplaySettings, .pUpdateDisplayDevices = X11DRV_UpdateDisplayDevices, + .pVirtualScreenRectChanged = X11DRV_VirtualScreenRectChanged, .pCreateDesktopWindow = X11DRV_CreateDesktopWindow, .pCreateWindow = X11DRV_CreateWindow, .pDesktopWindowProc = X11DRV_DesktopWindowProc, diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 2c5104025a5..4cbacea7acc 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -215,6 +215,7 @@ extern BOOL X11DRV_GetCursorPos( LPPOINT pos ) DECLSPEC_HIDDEN; extern BOOL X11DRV_ClipCursor( LPCRECT clip ) DECLSPEC_HIDDEN; extern LONG X11DRV_ChangeDisplaySettings( LPDEVMODEW displays, HWND hwnd, DWORD flags, LPVOID lpvoid ) DECLSPEC_HIDDEN; extern BOOL X11DRV_GetCurrentDisplaySettings( LPCWSTR name, LPDEVMODEW devmode ) DECLSPEC_HIDDEN; +extern void X11DRV_VirtualScreenRectChanged( RECT *old_rect, RECT *new_rect ) DECLSPEC_HIDDEN; extern BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manager, BOOL force, void *param ) DECLSPEC_HIDDEN; extern BOOL X11DRV_CreateDesktopWindow( HWND hwnd ) DECLSPEC_HIDDEN; @@ -804,7 +805,6 @@ extern BOOL get_host_primary_gpu(struct gdi_gpu *gpu) DECLSPEC_HIDDEN; extern void X11DRV_DisplayDevices_SetHandler(const struct x11drv_display_device_handler *handler) DECLSPEC_HIDDEN; extern void X11DRV_DisplayDevices_Init(BOOL force) DECLSPEC_HIDDEN; extern void X11DRV_DisplayDevices_RegisterEventHandlers(void) DECLSPEC_HIDDEN; -extern void X11DRV_DisplayDevices_Update(void) DECLSPEC_HIDDEN; /* Display device handler used in virtual desktop mode */ extern struct x11drv_display_device_handler desktop_handler DECLSPEC_HIDDEN;
diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c index a0ac2cb5ec1..3d1b6a917cf 100644 --- a/dlls/winex11.drv/xrandr.c +++ b/dlls/winex11.drv/xrandr.c @@ -1198,7 +1198,7 @@ static BOOL xrandr14_device_change_handler( HWND hwnd, XEvent *event ) xrandr14_invalidate_current_mode_cache(); if (hwnd == NtUserGetDesktopWindow() && NtUserGetWindowThread( hwnd, NULL ) == GetCurrentThreadId()) { - X11DRV_DisplayDevices_Update(); + X11DRV_DisplayDevices_Init(TRUE); init_registry_display_settings(); } return FALSE; diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 8c63d13b66a..a6a3857f0f3 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -298,6 +298,7 @@ struct user_driver_funcs LONG (*pChangeDisplaySettings)(LPDEVMODEW,HWND,DWORD,LPVOID); BOOL (*pGetCurrentDisplaySettings)(LPCWSTR,LPDEVMODEW); BOOL (*pUpdateDisplayDevices)(const struct gdi_device_manager *,BOOL,void*); + void (*pVirtualScreenRectChanged)(RECT*,RECT*); /* windowing functions */ BOOL (*pCreateDesktopWindow)(HWND); BOOL (*pCreateWindow)(HWND);
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 22 +++++++++++++--------- dlls/winemac.drv/display.c | 3 --- dlls/winex11.drv/display.c | 2 -- 3 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 0a7a852cf12..a3abc8948de 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1536,7 +1536,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(); RECT old_virtual_rect = {0}, new_virtual_rect = {0}; @@ -1558,14 +1558,17 @@ static BOOL update_display_cache(void) LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) union_rect( &old_virtual_rect, &old_virtual_rect, &monitor->rc_monitor );
- user_driver->pUpdateDisplayDevices( &device_manager, FALSE, &ctx ); - release_display_manager_ctx( &ctx ); - - if (update_display_cache_from_registry()) goto done; - 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()) goto done; + 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 )) @@ -1623,7 +1626,7 @@ done:
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; } @@ -2453,6 +2456,7 @@ static LONG apply_display_settings( const WCHAR *devname, const DEVMODEW *devmod SMTO_ABORTIFHUNG, 2000, FALSE );
free( displays ); + if (!ret && !update_display_cache( TRUE )) WARN( "Failed to update display cache after mode change.\n" ); return ret; }
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index 7da902c649f..768a0a3587a 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -832,10 +832,7 @@ LONG macdrv_ChangeDisplaySettings(LPDEVMODEW displays, HWND hwnd, DWORD flags, L ret = DISP_CHANGE_BADMODE; } else if (macdrv_set_display_mode(&macdrv_displays[0], best_display_mode)) - { - macdrv_init_display_devices(TRUE); send_message(NtUserGetDesktopWindow(), WM_MACDRV_UPDATE_DESKTOP_RECT, 0, 0); - } else { WARN("Failed to set display mode\n"); diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index b80ec825980..78ab5dcf8be 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -418,8 +418,6 @@ LONG X11DRV_ChangeDisplaySettings( LPDEVMODEW displays, HWND hwnd, DWORD flags, ret = apply_display_settings( displays, ids, FALSE ); if (ret == DISP_CHANGE_SUCCESSFUL) ret = apply_display_settings( displays, ids, TRUE ); - if (ret == DISP_CHANGE_SUCCESSFUL) - X11DRV_DisplayDevices_Init(TRUE);
done: free( ids );
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 50 ++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 13 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index a3abc8948de..452f1c706b0 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -526,7 +526,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; @@ -538,7 +538,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 ); }
@@ -1596,13 +1596,24 @@ static BOOL update_display_cache( BOOL force ) 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]; + mode.dmFields |= DM_POSITION; + } + 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 ); } @@ -2214,10 +2225,8 @@ static DEVMODEW *get_display_settings( const WCHAR *devname, const DEVMODEW *dev struct adapter *adapter; BOOL ret;
- if (!lock_display_devices()) return NULL; - /* allocate an extra mode for easier iteration */ - if (!(displays = calloc( list_count( &adapters ) + 1, sizeof(DEVMODEW) ))) goto done; + if (!(displays = calloc( list_count( &adapters ) + 1, sizeof(DEVMODEW) ))) return NULL; mode = displays;
LIST_FOR_EACH_ENTRY( adapter, &adapters, struct adapter, entry ) @@ -2236,11 +2245,9 @@ static DEVMODEW *get_display_settings( const WCHAR *devname, const DEVMODEW *dev mode = NEXT_DEVMODEW(mode); }
- unlock_display_devices(); return displays;
done: - unlock_display_devices(); free( displays ); return NULL; } @@ -2435,15 +2442,21 @@ static BOOL all_detached_settings( const DEVMODEW *displays ) static LONG apply_display_settings( const WCHAR *devname, const DEVMODEW *devmode, HWND hwnd, DWORD flags, void *lparam ) { - DEVMODEW *displays; + DEVMODEW *mode, *displays; + struct adapter *adapter; LONG ret;
- displays = get_display_settings( devname, devmode ); - if (!displays) return DISP_CHANGE_FAILED; + if (!lock_display_devices()) return DISP_CHANGE_FAILED; + if (!(displays = get_display_settings( devname, devmode ))) + { + unlock_display_devices(); + return DISP_CHANGE_FAILED; + }
if (all_detached_settings( displays )) { WARN( "Detaching all modes is not permitted.\n" ); + unlock_display_devices(); free( displays ); return DISP_CHANGE_SUCCESSFUL; } @@ -2451,9 +2464,20 @@ static LONG apply_display_settings( const WCHAR *devname, const DEVMODEW *devmod place_all_displays( displays );
if (!(ret = user_driver->pChangeDisplaySettings( displays, hwnd, flags, lparam ))) + { + mode = displays; + LIST_FOR_EACH_ENTRY( adapter, &adapters, struct adapter, entry ) + { + if (!write_registry_settings( adapter->config_key, ENUM_CURRENT_SETTINGS, mode )) + WARN( "Failed to write adapter %s current mode.\n", debugstr_w(mode->dmDeviceName) ); + mode = NEXT_DEVMODEW(mode); + } + send_message_timeout( HWND_BROADCAST, WM_DISPLAYCHANGE, displays->dmBitsPerPel, MAKELPARAM( displays->dmPelsWidth, displays->dmPelsHeight ), SMTO_ABORTIFHUNG, 2000, FALSE ); + } + unlock_display_devices();
free( displays ); if (!ret && !update_display_cache( TRUE )) WARN( "Failed to update display cache after mode change.\n" ); @@ -2493,7 +2517,7 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm }
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_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 = apply_display_settings( device_name, devmode, hwnd, flags, lparam ); free( modes );
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 452f1c706b0..3fe41ecf145 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -506,7 +506,7 @@ static BOOL read_adapter_mode( HKEY adapter_key, DWORD index, DEVMODEW *mode ) return TRUE; }
-static BOOL read_registry_settings( const WCHAR *adapter_path, DEVMODEW *mode ) +static BOOL read_registry_settings( const WCHAR *adapter_path, DWORD index, DEVMODEW *mode ) { BOOL ret = FALSE; HANDLE mutex; @@ -518,7 +518,7 @@ static BOOL read_registry_settings( const WCHAR *adapter_path, DEVMODEW *mode ) else if (!(hkey = reg_open_key( config_key, adapter_path, lstrlenW( adapter_path ) * sizeof(WCHAR) ))) ret = FALSE; else { - ret = read_adapter_mode( hkey, ENUM_REGISTRY_SETTINGS, mode ); + ret = read_adapter_mode( hkey, index, mode ); NtClose( hkey ); }
@@ -2186,7 +2186,7 @@ static DEVMODEW *get_full_mode( const WCHAR *adapter_path, const WCHAR *device_n if (devmode) memcpy( temp_mode, devmode, devmode->dmSize ); else { - if (!read_registry_settings( adapter_path, temp_mode )) return NULL; + if (!read_registry_settings( adapter_path, ENUM_REGISTRY_SETTINGS, temp_mode )) return NULL; TRACE( "Return to original display mode\n" ); } devmode = temp_mode; @@ -2200,7 +2200,9 @@ static DEVMODEW *get_full_mode( const WCHAR *adapter_path, const WCHAR *device_n if (!is_detached_mode( devmode ) && (!devmode->dmPelsWidth || !devmode->dmPelsHeight || !(devmode->dmFields & DM_POSITION))) { DEVMODEW current_mode = {.dmSize = sizeof(DEVMODEW)}; - if (!user_driver->pGetCurrentDisplaySettings( device_name, ¤t_mode )) return NULL; + if (!user_driver->pGetCurrentDisplaySettings( device_name, ¤t_mode ) && + !read_registry_settings( adapter_path, ENUM_CURRENT_SETTINGS, ¤t_mode )) + return NULL; if (!devmode->dmPelsWidth) devmode->dmPelsWidth = current_mode.dmPelsWidth; if (!devmode->dmPelsHeight) devmode->dmPelsHeight = current_mode.dmPelsHeight; if (!(devmode->dmFields & DM_POSITION)) @@ -2236,8 +2238,12 @@ static DEVMODEW *get_display_settings( const WCHAR *devname, const DEVMODEW *dev memcpy( &mode->dmFields, &devmode->dmFields, devmode->dmSize - offsetof(DEVMODEW, dmFields) ); else { - if (!devname) ret = read_registry_settings( adapter->config_key, mode ); - else ret = user_driver->pGetCurrentDisplaySettings( adapter->dev.device_name, mode ); + if (!devname) ret = read_registry_settings( adapter->config_key, ENUM_REGISTRY_SETTINGS, mode ); + else + { + ret = user_driver->pGetCurrentDisplaySettings( adapter->dev.device_name, mode ); + if (!ret) ret = read_registry_settings( adapter->config_key, ENUM_CURRENT_SETTINGS, mode ); + } if (!ret) goto done; }
@@ -2563,10 +2569,14 @@ BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD index, DEVM devmode->dmSize = offsetof(DEVMODEW, dmICMMethod); memset( &devmode->dmDriverExtra, 0, devmode->dmSize - offsetof(DEVMODEW, dmDriverExtra) );
- if (index == ENUM_REGISTRY_SETTINGS) ret = read_registry_settings( adapter_path, devmode ); + if (index == ENUM_REGISTRY_SETTINGS) ret = read_registry_settings( adapter_path, ENUM_REGISTRY_SETTINGS, devmode ); /* if EDS_ROTATEDMODE is not specified, enumerate modes with the same display orientation as current */ else if (index != ENUM_CURRENT_SETTINGS && (flags & EDS_ROTATEDMODE)) ret = TRUE; - else ret = user_driver->pGetCurrentDisplaySettings( device_name, devmode ); + else + { + ret = user_driver->pGetCurrentDisplaySettings( device_name, devmode ); + if (!ret) ret = read_registry_settings( adapter_path, ENUM_CURRENT_SETTINGS, devmode ); + }
if (ret && index != ENUM_REGISTRY_SETTINGS && index != ENUM_CURRENT_SETTINGS) {
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/win32u/driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index d9c1f0d6f6d..d3a0eef09b3 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -756,7 +756,7 @@ static void nulldrv_UpdateClipboard(void) static LONG nulldrv_ChangeDisplaySettings( LPDEVMODEW displays, HWND hwnd, DWORD flags, LPVOID lparam ) { - return DISP_CHANGE_FAILED; + return DISP_CHANGE_SUCCESSFUL; }
static BOOL nulldrv_GetCurrentDisplaySettings( LPCWSTR name, LPDEVMODEW mode )
On Tue Sep 6 11:52:03 2022 +0000, **** wrote:
Marvin replied on the mailing list:
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details: The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=122754 Your paranoid android. === w8 (32 bit report) === user32: sysparams.c:2490: Test failed: Waiting for the WM_DISPLAYCHANGE message timed out sysparams.c:2500: Test failed: Set bpp 32, but WM_DISPLAYCHANGE reported bpp -1 === w8adm (32 bit report) === user32: sysparams.c:2490: Test failed: Waiting for the WM_DISPLAYCHANGE message timed out sysparams.c:2500: Test failed: Set bpp 32, but WM_DISPLAYCHANGE reported bpp -1 === w864 (32 bit report) === user32: sysparams.c:2490: Test failed: Waiting for the WM_DISPLAYCHANGE message timed out sysparams.c:2500: Test failed: Set bpp 32, but WM_DISPLAYCHANGE reported bpp -1 === w1064v1809 (32 bit report) === user32: sysparams.c:2490: Test failed: Waiting for the WM_DISPLAYCHANGE message timed out sysparams.c:2500: Test failed: Set bpp 32, but WM_DISPLAYCHANGE reported bpp -1 === w1064 (32 bit report) === user32: sysparams.c:2490: Test failed: Waiting for the WM_DISPLAYCHANGE message timed out sysparams.c:2500: Test failed: Set bpp 32, but WM_DISPLAYCHANGE reported bpp -1 === w1064_tsign (32 bit report) === user32: sysparams.c:2490: Test failed: Waiting for the WM_DISPLAYCHANGE message timed out sysparams.c:2500: Test failed: Set bpp 32, but WM_DISPLAYCHANGE reported bpp -1 === w10pro64 (32 bit report) === user32: sysparams.c:2490: Test failed: Waiting for the WM_DISPLAYCHANGE message timed out sysparams.c:2500: Test failed: Set bpp 32, but WM_DISPLAYCHANGE reported bpp -1
Eh... how could that todo_wine removal break the tests windows??
There's a few things I'm not completely sure about, mostly regarding the calls within the display devices locks.
I feel like it's required to make sure the display settings change is atomic, but sending a message there is maybe not a good idea. If we don't, then I think it's getting racy and WM_DISPLAYCHANGE may be received in incorrect order (but maybe that doesn't matter).
On Tue Sep 6 11:58:43 2022 +0000, R��mi Bernon wrote:
Eh... how could that todo_wine removal break the tests windows??
It's most likely that the color depth is already 32bit, so changing to the same display mode doesn't send WM_DISPLAYCHANGE.
On Tue Sep 6 13:30:45 2022 +0000, Zhiyi Zhang wrote:
It's most likely that the color depth is already 32bit, so changing to the same display mode doesn't send WM_DISPLAYCHANGE.
Okay but it looks like a new failure and the only thing I did in that patch was remove the `todo_wine`, which should have no effect on windows?
On Tue Sep 6 13:56:27 2022 +0000, R��mi Bernon wrote:
Okay but it looks like a new failure and the only thing I did in that patch was remove the `todo_wine`, which should have no effect on windows?
It's not related to your patches. An empty patch can also trigger these failures. See https://testbot.winehq.org/JobDetails.pl?Key=122770. I don't know what's going on either. Probably some TestBot hiccup.
Zhiyi Zhang (@zhiyi) commented about dlls/win32u/sysparams.c:
{ lstrcpyW( device_name, adapter->dev.device_name ); lstrcpyW( adapter_path, adapter->config_key );
size = sizeof(DEVMODEW) + adapter->modes[0].dmDriverExtra;
/* allocate an extra mode for easier iteration */
modes = calloc( adapter->mode_count + 1, size );
This memory copy could be avoided when index is ENUM_CURRENT_SETTINGS or ENUM_REGISTRY_SETTINGS.
Zhiyi Zhang (@zhiyi) commented about dlls/win32u/sysparams.c:
memset( &devmode->dmDriverExtra, 0, devmode->dmSize - offsetof(DEVMODEW, dmDriverExtra) ); if (index == ENUM_REGISTRY_SETTINGS) ret = read_registry_settings( adapter_path, devmode );
- else if (index != ENUM_CURRENT_SETTINGS) ret = user_driver->pEnumDisplaySettingsEx( device_name, index, devmode, flags );
- /* if EDS_ROTATEDMODE is not specified, enumerate modes with the same display orientation as current */
- else if (index != ENUM_CURRENT_SETTINGS && (flags & EDS_ROTATEDMODE)) ret = TRUE; else ret = user_driver->pGetCurrentDisplaySettings( device_name, devmode );
It's probably alright, but with this patch, we're touching the user-specified devmode when index > available modes. And maybe it's time to change devmode to be some thing more appropriate, like a current_mode/registry_mode pointer instead of devmode or mode everywhere.
Zhiyi Zhang (@zhiyi) commented about dlls/win32u/sysparams.c:
memset( &devmode->dmDriverExtra, 0, devmode->dmSize - offsetof(DEVMODEW, dmDriverExtra) ); if (index == ENUM_REGISTRY_SETTINGS) ret = read_registry_settings( adapter_path, devmode );
- else if (index != ENUM_CURRENT_SETTINGS) ret = user_driver->pEnumDisplaySettingsEx( device_name, index, devmode, flags );
/* if EDS_ROTATEDMODE is not specified, enumerate modes with the same display orientation as current */
else if (index != ENUM_CURRENT_SETTINGS && (flags & EDS_ROTATEDMODE)) ret = TRUE; else ret = user_driver->pGetCurrentDisplaySettings( device_name, devmode );
if (ret && index != ENUM_REGISTRY_SETTINGS && index != ENUM_CURRENT_SETTINGS)
{
for (ret = FALSE, mode = modes; mode && mode->dmSize && !ret; mode = NEXT_DEVMODEW(mode))
{
if (!(flags & EDS_ROTATEDMODE) && mode->dmDisplayOrientation != devmode->dmDisplayOrientation) continue;
While this is correct, I prefer using indexed array access when EDS_ROTATEDMODE is present to avoid iterating the display mode list.
Zhiyi Zhang (@zhiyi) commented about dlls/win32u/sysparams.c:
else ret = user_driver->pGetCurrentDisplaySettings( device_name, devmode );
- if (ret && index != ENUM_REGISTRY_SETTINGS && index != ENUM_CURRENT_SETTINGS)
- {
for (ret = FALSE, mode = modes; mode && mode->dmSize && !ret; mode = NEXT_DEVMODEW(mode))
{
if (!(flags & EDS_ROTATEDMODE) && mode->dmDisplayOrientation != devmode->dmDisplayOrientation) continue;
if ((ret = !index--)) memcpy( &devmode->dmFields, &mode->dmFields, devmode->dmSize - FIELD_OFFSET(DEVMODEW, dmFields) );
}
- }
- free( modes );
- if (!ret) WARN( "Failed to query %s display settings.\n", debugstr_w(device_name) ); else TRACE( "position %dx%d, resolution %ux%u, frequency %u, depth %u, orientation %#x.\n", devmode->dmPosition.x, devmode->dmPosition.y, devmode->dmPelsWidth, devmode->dmPelsHeight, devmode->dmDisplayFrequency, devmode->dmBitsPerPel, devmode->dmDisplayOrientation );
This patch introduced a behavior change which is that now the last error is not set when index is larger than available modes. I haven't checked if Windows sets the error code but this looks worthy of a recheck.
Zhiyi Zhang (@zhiyi) commented about dlls/wineandroid.drv/init.c:
- {
TRACE( "mode %d -- not present\n", n );
RtlSetLastWin32Error( ERROR_NO_MORE_FILES );
return FALSE;
- }
- devmode->u2.dmDisplayFlags = 0;
- devmode->u1.s2.dmPosition.x = 0;
- devmode->u1.s2.dmPosition.y = 0;
- devmode->u1.s2.dmDisplayOrientation = 0;
- devmode->u1.s2.dmDisplayFixedOutput = 0;
- devmode->dmPelsWidth = screen_width;
- devmode->dmPelsHeight = screen_height;
- devmode->dmBitsPerPel = screen_bpp;
- devmode->dmDisplayFrequency = 60;
- devmode->dmFields = DM_DISPLAYORIENTATION | DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL |
I missed it in MR406, you forgot DM_DISPLAYORIENTATION in ANDROID_UpdateDisplayDevices(). So with this patch, the enumerated modes will be missing the flag.
Zhiyi Zhang (@zhiyi) commented about dlls/winemac.drv/display.c:
- display_idx = wcstol(devname + 11, &end, 10) - 1;
- if (display_idx >= num_displays)
- {
macdrv_free_displays(displays);
return FALSE;
- }
- display_id = displays[display_idx].displayID;
- pthread_mutex_lock(&cached_modes_mutex);
- if (mode == 0 || !cached_modes || flags != cached_modes_flags || display_id != cached_modes_display_id)
- {
if (cached_modes) CFRelease(cached_modes);
cached_modes = copy_display_modes(display_id, (flags & EDS_RAWMODE) != 0);
Now you're including unsupported modes even if EDS_RAWMODE is not specified because display_get_modes() uses copy_display_modes(display_id, TRUE).
Zhiyi Zhang (@zhiyi) commented about dlls/winemac.drv/display.c:
static int get_default_bpp(void) {
- static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
The changes for get_default_bpp() can be put into a separate patch for easier review.
Zhiyi Zhang (@zhiyi) commented about dlls/win32u/sysparams.c:
place_all_displays( displays );
- ret = user_driver->pChangeDisplaySettings( displays, hwnd, flags, lparam );
- if (!(ret = user_driver->pChangeDisplaySettings( displays, hwnd, flags, lparam )))
send_message_timeout( HWND_BROADCAST, WM_DISPLAYCHANGE, displays->dmBitsPerPel,
First, displays->dmBitsPerPel is from ChangeDisplaySettings() and maybe 8bit and 16bit. But in winex11.drv, screen_bpp is always used and is always 32bit or 24bit. On Windows, 8bit and 16bit display modes are emulated. If I remember correctly, Windows sends WM_DISPLAYCHANGE with 32bit depth even if you're changing to an 8bit display mode.
Second, the primary monitor may change after you detach the first monitor. So you can't just use the first monitor as the primary monitor. Instead, you should query for the primary monitor dimension after display changes and use that to use the WM_DISPLAYCHANGE message.
Zhiyi Zhang (@zhiyi) commented about dlls/win32u/sysparams.c:
ERR( "failed to read display config\n" ); return FALSE; }
+done:
The done label is used once. Probably best not to use goto in this case.
Zhiyi Zhang (@zhiyi) commented about dlls/win32u/sysparams.c:
if (!(ret = user_driver->pChangeDisplaySettings( displays, hwnd, flags, lparam )))
- {
mode = displays;
LIST_FOR_EACH_ENTRY( adapter, &adapters, struct adapter, entry )
{
if (!write_registry_settings( adapter->config_key, ENUM_CURRENT_SETTINGS, mode ))
WARN( "Failed to write adapter %s current mode.\n", debugstr_w(mode->dmDeviceName) );
mode = NEXT_DEVMODEW(mode);
}
send_message_timeout( HWND_BROADCAST, WM_DISPLAYCHANGE, displays->dmBitsPerPel, MAKELPARAM( displays->dmPelsWidth, displays->dmPelsHeight ), SMTO_ABORTIFHUNG, 2000, FALSE );
- }
- unlock_display_devices();
Right, it's probably best not to hold the display device lock while sending WM_DISPLAYCHANGE. The current behavior also doesn't guarantee WM_DISPLAYCHANGE ordering.
Zhiyi Zhang (@zhiyi) commented about dlls/win32u/sysparams.c:
devmode->dmSize = offsetof(DEVMODEW, dmICMMethod); memset( &devmode->dmDriverExtra, 0, devmode->dmSize - offsetof(DEVMODEW, dmDriverExtra) );
- if (index == ENUM_REGISTRY_SETTINGS) ret = read_registry_settings( adapter_path, devmode );
- if (index == ENUM_REGISTRY_SETTINGS) ret = read_registry_settings( adapter_path, ENUM_REGISTRY_SETTINGS, devmode ); /* if EDS_ROTATEDMODE is not specified, enumerate modes with the same display orientation as current */ else if (index != ENUM_CURRENT_SETTINGS && (flags & EDS_ROTATEDMODE)) ret = TRUE;
- else ret = user_driver->pGetCurrentDisplaySettings( device_name, devmode );
- else
- {
ret = user_driver->pGetCurrentDisplaySettings( device_name, devmode );
if (!ret) ret = read_registry_settings( adapter_path, ENUM_CURRENT_SETTINGS, devmode );
It seems better to make this into a get_current_display_settings() function