Split from https://gitlab.winehq.org/wine/wine/-/merge_requests/551.
-- v2: win32u: Broadcast WM_DISPLAYCHANGE message on display settings change. win32u: Lock display devices mutex in find_adapter. win32u: Use find_adapter_device_by_(name|id) helpers in find_adapter. win32u: Factor out display_device lookup in separate helpers. winemac.drv: Move and lock cache static variables within get_default_bpp. win32u: Move enumeration of available modes out of graphics drivers. user32/tests: Cleanup sysparams WM_DISPLAYCHANGE tests.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/user32/tests/sysparams.c | 126 ++++++++++++++++++---------------- 1 file changed, 67 insertions(+), 59 deletions(-)
diff --git a/dlls/user32/tests/sysparams.c b/dlls/user32/tests/sysparams.c index 4f2709094e9..6d630ab1ead 100644 --- a/dlls/user32/tests/sysparams.c +++ b/dlls/user32/tests/sysparams.c @@ -30,7 +30,6 @@ #include "winuser.h" #include "winnls.h"
-static LONG (WINAPI *pChangeDisplaySettingsExA)(LPCSTR, LPDEVMODEA, HWND, DWORD, LPVOID); static BOOL (WINAPI *pIsProcessDPIAware)(void); static BOOL (WINAPI *pSetProcessDPIAware)(void); static BOOL (WINAPI *pSetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); @@ -2447,78 +2446,88 @@ static void test_SPI_SETWALLPAPER( void ) /* 115 */
static void test_WM_DISPLAYCHANGE(void) { - DEVMODEA mode, startmode; - int start_bpp, last_set_bpp = 0; - int test_bpps[] = {8, 16, 24, 32}, i; - LONG change_ret; - DWORD wait_ret; - - if (!pChangeDisplaySettingsExA) - { - win_skip("ChangeDisplaySettingsExA is not available\n"); - return; - } + UINT test_bpps[] = {8, 16, 24}, default_bpp, i; + DEVMODEW settings; + DWORD res; + BOOL ret;
displaychange_test_active = TRUE; + displaychange_sem = CreateSemaphoreW( NULL, 0, 1, NULL );
- memset(&startmode, 0, sizeof(startmode)); - startmode.dmSize = sizeof(startmode); - EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &startmode); - start_bpp = startmode.dmBitsPerPel; + memset( &settings, 0, sizeof(DEVMODEW) ); + settings.dmSize = sizeof(DEVMODEW); + ret = EnumDisplaySettingsW( NULL, ENUM_CURRENT_SETTINGS, &settings ); + ok( ret, "EnumDisplaySettingsW failed, error %#lx\n", GetLastError() );
- displaychange_sem = CreateSemaphoreW(NULL, 0, 1, NULL); + ok( settings.dmFields & DM_BITSPERPEL, "got dmFields %#lx\n", settings.dmFields ); + ok( settings.dmBitsPerPel == 32, "got dmBitsPerPel %lu\n", settings.dmBitsPerPel ); + default_bpp = settings.dmBitsPerPel;
- for(i = 0; i < ARRAY_SIZE(test_bpps); i++) { - last_bpp = -1; + /* setting the default mode here sends a WM_DISPLAYCHANGE */ + + last_bpp = -1; + change_counter = 0; + displaychange_ok = TRUE; + res = ChangeDisplaySettingsExW( NULL, &settings, NULL, 0, NULL ); + ok( !res, "ChangeDisplaySettingsExW returned %ld\n", res ); + res = WaitForSingleObject( displaychange_sem, 10000 ); + ok( !res, "WaitForSingleObject returned %#lx\n", res ); + ok( last_bpp == default_bpp, "got WM_DISPLAYCHANGE bpp %u\n", last_bpp ); + displaychange_ok = FALSE; + + for (i = 0; i < ARRAY_SIZE(test_bpps); i++) + { + UINT bpp = test_bpps[i];
- memset(&mode, 0, sizeof(mode)); - mode.dmSize = sizeof(mode); - mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - mode.dmBitsPerPel = test_bpps[i]; - mode.dmPelsWidth = GetSystemMetrics(SM_CXSCREEN); - mode.dmPelsHeight = GetSystemMetrics(SM_CYSCREEN); + winetest_push_context( "bpp %u", bpp );
- change_counter = 0; /* This sends a SETTINGSCHANGE message as well in which we aren't interested */ + settings.dmBitsPerPel = bpp; + settings.dmFields |= DM_BITSPERPEL; + + last_bpp = -1; + change_counter = 0; displaychange_ok = TRUE; - change_ret = pChangeDisplaySettingsExA(NULL, &mode, NULL, 0, NULL); - /* Wait quite long for the message, screen setting changes can take some time */ - if(change_ret == DISP_CHANGE_SUCCESSFUL) { - wait_ret = WaitForSingleObject(displaychange_sem, 10000); - /* we may not get a notification if nothing changed */ - if (wait_ret == WAIT_TIMEOUT && !last_set_bpp && start_bpp == test_bpps[i]) - continue; - ok(wait_ret == WAIT_OBJECT_0, "Waiting for the WM_DISPLAYCHANGE message timed out\n"); + res = ChangeDisplaySettingsExW( NULL, &settings, NULL, 0, NULL ); + if (!res) + { + /* Wait quite long for the message, screen setting changes can take some time */ + res = WaitForSingleObject( displaychange_sem, 10000 ); + ok( !res, "WaitForSingleObject returned %#lx\n", res ); + todo_wine + ok( last_bpp == bpp, "got WM_DISPLAYCHANGE bpp %u\n", last_bpp ); } - displaychange_ok = FALSE; - - if(change_ret != DISP_CHANGE_SUCCESSFUL) { - skip("Setting depth %d failed(ret = %ld)\n", test_bpps[i], change_ret); - ok(last_bpp == -1, "WM_DISPLAYCHANGE was sent with wParam %d despite mode change failure\n", last_bpp); - continue; + else + { + todo_wine + win_skip( "ChangeDisplaySettingsExW returned %ld\n", res ); + ok( res == DISP_CHANGE_BADMODE || broken( DISP_CHANGE_FAILED && bpp == 8 ), + "ChangeDisplaySettingsExW returned %ld\n", res ); + ok( last_bpp == -1, "got WM_DISPLAYCHANGE bpp %u\n", last_bpp ); } + displaychange_ok = FALSE;
- 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); - } - last_set_bpp = test_bpps[i]; + winetest_pop_context(); }
- if(start_bpp != last_set_bpp && last_set_bpp != 0) { - memset(&mode, 0, sizeof(mode)); - mode.dmSize = sizeof(mode); - mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - mode.dmBitsPerPel = start_bpp; - mode.dmPelsWidth = GetSystemMetrics(SM_CXSCREEN); - mode.dmPelsHeight = GetSystemMetrics(SM_CYSCREEN); + /* restoring default mode most of the time doesn't send WM_DISPLAYCHANGE */
- displaychange_ok = TRUE; - change_ret = pChangeDisplaySettingsExA(NULL, &mode, NULL, 0, NULL); - WaitForSingleObject(displaychange_sem, 10000); - displaychange_ok = FALSE; - CloseHandle(displaychange_sem); - displaychange_sem = 0; - } + settings.dmBitsPerPel = default_bpp; + settings.dmFields |= DM_BITSPERPEL; + + last_bpp = -1; + change_counter = 0; + displaychange_ok = TRUE; + res = ChangeDisplaySettingsExW( NULL, &settings, NULL, 0, NULL ); + ok( !res, "ChangeDisplaySettingsExW returned %ld\n", res ); + res = WaitForSingleObject( displaychange_sem, 1000 ); + todo_wine + ok( res == WAIT_TIMEOUT || broken( !res ), "WaitForSingleObject returned %#lx\n", res ); + todo_wine + ok( last_bpp == -1 || broken( last_bpp == default_bpp ), "got WM_DISPLAYCHANGE bpp %u\n", last_bpp ); + displaychange_ok = FALSE;
+ CloseHandle( displaychange_sem ); + displaychange_sem = 0; displaychange_test_active = FALSE; }
@@ -4136,7 +4145,6 @@ START_TEST(sysparams) HANDLE hInstance, hdll;
hdll = GetModuleHandleA("user32.dll"); - pChangeDisplaySettingsExA = (void*)GetProcAddress(hdll, "ChangeDisplaySettingsExA"); pIsProcessDPIAware = (void*)GetProcAddress(hdll, "IsProcessDPIAware"); pSetProcessDPIAware = (void*)GetProcAddress(hdll, "SetProcessDPIAware"); pGetDpiForSystem = (void*)GetProcAddress(hdll, "GetDpiForSystem");
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/driver.c | 12 --- dlls/win32u/sysparams.c | 41 +++++++-- dlls/wineandroid.drv/init.c | 31 ------- dlls/winemac.drv/display.c | 162 ------------------------------------ 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, 36 insertions(+), 316 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 f06be99f936..3c47205cc32 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2498,6 +2498,39 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm return ret; }
+static BOOL adapter_enum_display_settings( const struct adapter *adapter, DWORD index, DEVMODEW *devmode, DWORD flags ) +{ + DEVMODEW current_mode = {.dmSize = sizeof(DEVMODEW)}; + const DEVMODEW *adapter_mode; + + if (!(flags & EDS_ROTATEDMODE) && !user_driver->pGetCurrentDisplaySettings( adapter->dev.device_name, ¤t_mode )) + { + WARN( "Failed to query current display mode for EDS_ROTATEDMODE flag.\n" ); + return FALSE; + } + + for (adapter_mode = adapter->modes; adapter_mode->dmSize; adapter_mode = NEXT_DEVMODEW(adapter_mode)) + { + if (!(flags & EDS_ROTATEDMODE) && (adapter_mode->dmFields & DM_DISPLAYORIENTATION) && + adapter_mode->dmDisplayOrientation != current_mode.dmDisplayOrientation) + continue; + if (!(flags & EDS_RAWMODE) && (adapter_mode->dmFields & DM_DISPLAYFLAGS) && + (adapter_mode->dmDisplayFlags & WINE_DM_UNSUPPORTED)) + continue; + if (!index--) + { + memcpy( &devmode->dmFields, &adapter_mode->dmFields, devmode->dmSize - FIELD_OFFSET(DEVMODEW, dmFields) ); + devmode->dmDisplayFlags &= ~WINE_DM_UNSUPPORTED; + return TRUE; + } + } + + WARN( "device %s, index %#x, flags %#x display mode not found.\n", + debugstr_w( adapter->dev.device_name ), index, flags ); + RtlSetLastWin32Error( ERROR_NO_MORE_FILES ); + return FALSE; +} + /*********************************************************************** * NtUserEnumDisplaySettings (win32u.@) */ @@ -2522,15 +2555,13 @@ BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD index, DEVM devmode->dmSpecVersion = DM_SPECVERSION; devmode->dmDriverVersion = DM_SPECVERSION; devmode->dmSize = offsetof(DEVMODEW, dmICMMethod); - memset( &devmode->dmDriverExtra, 0, devmode->dmSize - offsetof(DEVMODEW, dmDriverExtra) ); + devmode->dmDriverExtra = 0;
if (index == ENUM_REGISTRY_SETTINGS) ret = adapter_get_registry_settings( adapter, devmode ); - else if (index != ENUM_CURRENT_SETTINGS) ret = user_driver->pEnumDisplaySettingsEx( adapter->dev.device_name, index, devmode, flags ); - else ret = user_driver->pGetCurrentDisplaySettings( adapter->dev.device_name, devmode ); + else if (index == ENUM_CURRENT_SETTINGS) ret = user_driver->pGetCurrentDisplaySettings( adapter->dev.device_name, devmode ); + else ret = adapter_enum_display_settings( adapter, index, devmode, flags ); adapter_release( adapter );
- devmode->dmDisplayFlags &= ~WINE_DM_UNSUPPORTED; - if (!ret) WARN( "Failed to query %s display settings.\n", debugstr_us(device) ); 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 2cd01bd3f50..6011e20c8ce 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 def291508be..b981aa12e35 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -51,10 +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;
@@ -936,164 +932,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 9863a4a36ea..596d27156af 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -298,7 +298,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/winemac.drv/display.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index b981aa12e35..b731e50d187 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -51,9 +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 int cached_default_mode_bpp; -static pthread_mutex_t cached_modes_mutex = PTHREAD_MUTEX_INITIALIZER; - static BOOL inited_original_display_mode;
@@ -400,22 +397,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; @@ -800,9 +801,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);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 68 +++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 27 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 3c47205cc32..eaeb3d72cc7 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1973,6 +1973,45 @@ LONG WINAPI NtUserGetDisplayConfigBufferSizes( UINT32 flags, UINT32 *num_path_in return ERROR_SUCCESS; }
+/* display_lock mutex must be held */ +static struct display_device *find_monitor_device( struct display_device *adapter, DWORD index ) +{ + struct monitor *monitor; + + LIST_FOR_EACH_ENTRY(monitor, &monitors, struct monitor, entry) + if (&monitor->adapter->dev == adapter && index == monitor->id) + return &monitor->dev; + + WARN( "Failed to find adapter %s monitor with id %u.\n", debugstr_w(adapter->device_name), index ); + return NULL; +} + +/* display_lock mutex must be held */ +static struct display_device *find_adapter_device_by_id( DWORD index ) +{ + struct adapter *adapter; + + LIST_FOR_EACH_ENTRY(adapter, &adapters, struct adapter, entry) + if (index == adapter->id) return &adapter->dev; + + WARN( "Failed to find adapter with id %u.\n", index ); + return NULL; +} + +/* display_lock mutex must be held */ +static struct display_device *find_adapter_device_by_name( UNICODE_STRING *name ) +{ + SIZE_T len = name->Length / sizeof(WCHAR); + struct adapter *adapter; + + LIST_FOR_EACH_ENTRY(adapter, &adapters, struct adapter, entry) + if (!wcsnicmp( name->Buffer, adapter->dev.device_name, len ) && !adapter->dev.device_name[len]) + return &adapter->dev; + + WARN( "Failed to find adapter with name %s.\n", debugstr_us(name) ); + return NULL; +} + /* Find and acquire the adapter matching name, or primary adapter if name is NULL. * If not NULL, the returned adapter needs to be released with adapter_release. */ @@ -1997,8 +2036,6 @@ NTSTATUS WINAPI NtUserEnumDisplayDevices( UNICODE_STRING *device, DWORD index, DISPLAY_DEVICEW *info, DWORD flags ) { struct display_device *found = NULL; - struct adapter *adapter; - struct monitor *monitor;
TRACE( "%s %u %p %#x\n", debugstr_us( device ), index, info, flags );
@@ -2006,31 +2043,8 @@ NTSTATUS WINAPI NtUserEnumDisplayDevices( UNICODE_STRING *device, DWORD index,
if (!lock_display_devices()) return STATUS_UNSUCCESSFUL;
- if (!device || !device->Length) - { - /* Enumerate adapters */ - LIST_FOR_EACH_ENTRY(adapter, &adapters, struct adapter, entry) - { - if (index == adapter->id) - { - found = &adapter->dev; - break; - } - } - } - else if ((adapter = find_adapter( device ))) - { - /* Enumerate monitors */ - LIST_FOR_EACH_ENTRY(monitor, &monitors, struct monitor, entry) - { - if (monitor->adapter == adapter && index == monitor->id) - { - found = &monitor->dev; - break; - } - } - adapter_release( adapter ); - } + if (!device || !device->Length) found = find_adapter_device_by_id( index ); + else if ((found = find_adapter_device_by_name( device ))) found = find_monitor_device( found, index );
if (found) {
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index eaeb3d72cc7..2927c94f2a7 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2017,16 +2017,16 @@ static struct display_device *find_adapter_device_by_name( UNICODE_STRING *name */ static struct adapter *find_adapter( UNICODE_STRING *name ) { + struct display_device *device; struct adapter *adapter;
- LIST_FOR_EACH_ENTRY(adapter, &adapters, struct adapter, entry) - { - if (!name || !name->Length) return adapter_acquire( adapter ); /* use primary adapter */ - if (!wcsnicmp( name->Buffer, adapter->dev.device_name, name->Length / sizeof(WCHAR) ) && - !adapter->dev.device_name[name->Length / sizeof(WCHAR)]) - return adapter_acquire( adapter ); - } - return NULL; + if (name && name->Length) device = find_adapter_device_by_name( name ); + else device = find_adapter_device_by_id( 0 ); /* use primary adapter */ + + if (!device) adapter = NULL; + else adapter = adapter_acquire( CONTAINING_RECORD( device, struct adapter, dev ) ); + + return adapter; }
/*********************************************************************** @@ -2496,11 +2496,7 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm if (!lock_display_devices()) return DISP_CHANGE_FAILED; adapter = find_adapter( devname ); unlock_display_devices(); - if (!adapter) - { - WARN( "Invalid device name %s.\n", debugstr_us(devname) ); - return DISP_CHANGE_BADPARAM; - } + if (!adapter) return DISP_CHANGE_BADPARAM;
if (!adapter_get_full_mode( adapter, devmode, &full_mode )) ret = DISP_CHANGE_BADMODE; else if ((flags & CDS_UPDATEREGISTRY) && !adapter_set_registry_settings( adapter, &full_mode )) ret = DISP_CHANGE_NOTUPDATED; @@ -2559,11 +2555,7 @@ BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD index, DEVM if (!lock_display_devices()) return FALSE; adapter = find_adapter( device ); unlock_display_devices(); - if (!adapter) - { - WARN( "Invalid device name %s.\n", debugstr_us(device) ); - return FALSE; - } + if (!adapter) return FALSE;
lstrcpynW( devmode->dmDeviceName, wine_display_driverW, ARRAY_SIZE(devmode->dmDeviceName) ); devmode->dmSpecVersion = DM_SPECVERSION;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 2927c94f2a7..867332624d1 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2020,12 +2020,15 @@ static struct adapter *find_adapter( UNICODE_STRING *name ) struct display_device *device; struct adapter *adapter;
+ if (!lock_display_devices()) return NULL; + if (name && name->Length) device = find_adapter_device_by_name( name ); else device = find_adapter_device_by_id( 0 ); /* use primary adapter */
if (!device) adapter = NULL; else adapter = adapter_acquire( CONTAINING_RECORD( device, struct adapter, dev ) );
+ unlock_display_devices(); return adapter; }
@@ -2493,10 +2496,7 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm
if ((!devname || !devname->Length) && !devmode) return apply_display_settings( NULL, NULL, hwnd, flags, lparam );
- if (!lock_display_devices()) return DISP_CHANGE_FAILED; - adapter = find_adapter( devname ); - unlock_display_devices(); - if (!adapter) return DISP_CHANGE_BADPARAM; + if (!(adapter = find_adapter( devname ))) return DISP_CHANGE_BADPARAM;
if (!adapter_get_full_mode( adapter, devmode, &full_mode )) ret = DISP_CHANGE_BADMODE; else if ((flags & CDS_UPDATEREGISTRY) && !adapter_set_registry_settings( adapter, &full_mode )) ret = DISP_CHANGE_NOTUPDATED; @@ -2552,10 +2552,7 @@ BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD index, DEVM
TRACE( "device %s, index %#x, devmode %p, flags %#x\n", debugstr_us(device), index, devmode, flags );
- if (!lock_display_devices()) return FALSE; - adapter = find_adapter( device ); - unlock_display_devices(); - if (!adapter) return FALSE; + if (!(adapter = find_adapter( device ))) return FALSE;
lstrcpynW( devmode->dmDeviceName, wine_display_driverW, ARRAY_SIZE(devmode->dmDeviceName) ); devmode->dmSpecVersion = DM_SPECVERSION;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/user32/tests/sysparams.c | 1 - dlls/win32u/sysparams.c | 14 ++++++++++++++ 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, 26 insertions(+), 55 deletions(-)
diff --git a/dlls/user32/tests/sysparams.c b/dlls/user32/tests/sysparams.c index 6d630ab1ead..a53c43b391a 100644 --- a/dlls/user32/tests/sysparams.c +++ b/dlls/user32/tests/sysparams.c @@ -2493,7 +2493,6 @@ static void test_WM_DISPLAYCHANGE(void) /* Wait quite long for the message, screen setting changes can take some time */ res = WaitForSingleObject( displaychange_sem, 10000 ); ok( !res, "WaitForSingleObject returned %#lx\n", res ); - todo_wine ok( last_bpp == bpp, "got WM_DISPLAYCHANGE bpp %u\n", last_bpp ); } else diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 867332624d1..494bb94c7f1 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2460,6 +2460,7 @@ 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 ) { + struct adapter *adapter; DEVMODEW *displays; LONG ret;
@@ -2478,6 +2479,19 @@ static LONG apply_display_settings( const WCHAR *devname, const DEVMODEW *devmod ret = user_driver->pChangeDisplaySettings( displays, hwnd, flags, lparam );
free( displays ); + if (ret) return ret; + + if ((adapter = find_adapter( NULL ))) + { + DEVMODEW current_mode = {.dmSize = sizeof(DEVMODEW)}; + user_driver->pGetCurrentDisplaySettings( adapter->dev.device_name, ¤t_mode ); + adapter_release( adapter ); + + send_message_timeout( HWND_BROADCAST, WM_DISPLAYCHANGE, current_mode.dmBitsPerPel, + MAKELPARAM( current_mode.dmPelsWidth, current_mode.dmPelsHeight ), + SMTO_ABORTIFHUNG, 2000, FALSE ); + } + return ret; }
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index b731e50d187..0ab0e97f920 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -835,20 +835,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 { @@ -1185,28 +1173,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;
On Thu Sep 15 10:06:09 2022 +0000, Zhiyi Zhang wrote:
How did you test it? And what's the Windows version and GPU? I used the following code to change the resolution. And I setup spy++ beforehand to monitor WM_DISPLAYCHANGE. I tried the test on Windows 10 21H2 and Windows 11 in VirtualBox, also Windows 10 on a real machine with an AMD Vega GPU. `
DEVMODEW devmode;
memset(&devmode, 0, sizeof(devmode)); devmode.dmSize = sizeof(devmode); devmode.dmPelsWidth = 1024; devmode.dmPelsHeight = 768; devmode.dmBitsPerPel = 16; devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; ChangeDisplaySettingsExW(NULL, &devmode, 0, CDS_RESET, NULL); memset(&devmode, 0, sizeof(devmode)); devmode.dmSize = sizeof(devmode); EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &devmode, 0); printf("depth %d\n", devmode.dmBitsPerPel); ` Anyway, this seems like the opportunity to make the tests more reliable if you're going to change the code.
I cleaned up the tests a bit, but they mostly work in the same way as before, and on all the testbot VMs where changing to 8, 16 or 24 bit bpp (there's a w7 where it works), the `WM_DISPLAYCHANGE` message has the requested bpp.
Then, when changing back to the default 32bpp, most of the time no `WM_DISPLAYCHANGE` message is received, though it's a bit inconsistent there.
Zhiyi Zhang (@zhiyi) commented about dlls/user32/tests/sysparams.c:
{
/* Wait quite long for the message, screen setting changes can take some time */
res = WaitForSingleObject( displaychange_sem, 10000 );
ok( !res, "WaitForSingleObject returned %#lx\n", res );
todo_wine
ok( last_bpp == bpp, "got WM_DISPLAYCHANGE bpp %u\n", last_bpp ); }
displaychange_ok = FALSE;
if(change_ret != DISP_CHANGE_SUCCESSFUL) {
skip("Setting depth %d failed(ret = %ld)\n", test_bpps[i], change_ret);
ok(last_bpp == -1, "WM_DISPLAYCHANGE was sent with wParam %d despite mode change failure\n", last_bpp);
continue;
else
{
todo_wine
This todo_wine here seems redundant because you're using win_skip already.
Zhiyi Zhang (@zhiyi) commented about dlls/user32/tests/sysparams.c:
displaychange_ok = TRUE;
change_ret = pChangeDisplaySettingsExA(NULL, &mode, NULL, 0, NULL);
WaitForSingleObject(displaychange_sem, 10000);
displaychange_ok = FALSE;
CloseHandle(displaychange_sem);
displaychange_sem = 0;
- }
- settings.dmBitsPerPel = default_bpp;
- settings.dmFields |= DM_BITSPERPEL;
- last_bpp = -1;
- change_counter = 0;
- displaychange_ok = TRUE;
- res = ChangeDisplaySettingsExW( NULL, &settings, NULL, 0, NULL );
- ok( !res, "ChangeDisplaySettingsExW returned %ld\n", res );
- res = WaitForSingleObject( displaychange_sem, 1000 );
I noticed that the timeout here is 1000ms while previous timeouts are 10000ms. Is it possible that the timeout is not enough? Also, when setting identical modes, you might need CDS_RESET. Same for the preceding ChangeDisplaySettingsExW() calls.
On Fri Sep 23 04:08:38 2022 +0000, Zhiyi Zhang wrote:
This todo_wine here seems redundant because you're using win_skip already.
Well no, win_skip is equivalent to `ok(0, ...)` on Wine. The test considers that although some Windows versions are failing to change bpp, we'd like Wine to implement it nonetheless.
On Fri Sep 23 04:08:54 2022 +0000, Zhiyi Zhang wrote:
I noticed that the timeout here is 1000ms while previous timeouts are 10000ms. Is it possible that the timeout is not enough? Also, when setting identical modes, you might need CDS_RESET. Same for the preceding ChangeDisplaySettingsExW() calls.
I can add the `CDS_RESET` flag but as far as I could see it doesn't force it to re-send the `WM_DISPLAYCHANGE` message, including with a very high timeout. It's a bit inconsistent but see here for instance: https://testbot.winehq.org/JobDetails.pl?Key=124072
As I understand it, the first `ChangeDisplaySettingsExW` sends the message because the current enumerated mode doesn't exactly match some internal state. But a second `ChangeDisplaySettingsExW` with the exact same full mode doesn't, because there's truly no changes this time.
Then, non 32bit modes are indeed emulated, and although they cause a `WM_DISPLAYCHANGE` message, they don't actually change that internal state, or the actual current mode. So when asking back for the 32bit mode, no change is needed either, and no message is sent.
So I used a 1000ms timeout here to avoid causing unnecessary waits when we actually expect it to timeout.
Zhiyi Zhang (@zhiyi) commented about dlls/winemac.drv/display.c:
static int get_default_bpp(void) {
- static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
Actually, I doubt we need to protect 'cached' with a mutex. The worst case is that get_default_bpp() may try to get the default bpp multiple times.