-- v9: explorer: Restore display settings on process exit. winex11.drv: Process RRNotify events in xrandr14_get_id. user32/tests: Test that display settings are restored on process exit.
From: Anton Baskanov baskanov@gmail.com
--- dlls/user32/tests/monitor.c | 304 +++++++++++++++++++++++++++++++++--- 1 file changed, 286 insertions(+), 18 deletions(-)
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c index e93a84242c4..eda9fc74379 100644 --- a/dlls/user32/tests/monitor.c +++ b/dlls/user32/tests/monitor.c @@ -291,8 +291,8 @@ struct device_info DEVMODEA original_mode; };
-#define expect_dm(a, b, c) _expect_dm(__LINE__, a, b, c) -static void _expect_dm(INT line, const DEVMODEA *expected, const CHAR *device, DWORD test) +#define expect_dm(a, b, c, d) _expect_dm(__LINE__, a, b, c, d) +static void _expect_dm(INT line, const DEVMODEA *expected, const CHAR *device, DWORD test, BOOL todo) { DEVMODEA dm; BOOL ret; @@ -307,9 +307,9 @@ static void _expect_dm(INT line, const DEVMODEA *expected, const CHAR *device, D "Device %s test %ld expect dmFields to contain %#lx, got %#lx\n", device, test, expected->dmFields, dm.dmFields); ok_(__FILE__, line)(!(expected->dmFields & DM_BITSPERPEL) || dm.dmBitsPerPel == expected->dmBitsPerPel, "Device %s test %ld expect dmBitsPerPel %lu, got %lu\n", device, test, expected->dmBitsPerPel, dm.dmBitsPerPel); - ok_(__FILE__, line)(!(expected->dmFields & DM_PELSWIDTH) || dm.dmPelsWidth == expected->dmPelsWidth, + todo_wine_if(todo) ok_(__FILE__, line)(!(expected->dmFields & DM_PELSWIDTH) || dm.dmPelsWidth == expected->dmPelsWidth, "Device %s test %ld expect dmPelsWidth %lu, got %lu\n", device, test, expected->dmPelsWidth, dm.dmPelsWidth); - ok_(__FILE__, line)(!(expected->dmFields & DM_PELSHEIGHT) || dm.dmPelsHeight == expected->dmPelsHeight, + todo_wine_if(todo) ok_(__FILE__, line)(!(expected->dmFields & DM_PELSHEIGHT) || dm.dmPelsHeight == expected->dmPelsHeight, "Device %s test %ld expect dmPelsHeight %lu, got %lu\n", device, test, expected->dmPelsHeight, dm.dmPelsHeight); ok_(__FILE__, line)(!(expected->dmFields & DM_POSITION) || dm.dmPosition.x == expected->dmPosition.x, "Device %s test %ld expect dmPosition.x %ld, got %ld\n", device, test, expected->dmPosition.x, dm.dmPosition.x); @@ -325,18 +325,79 @@ static void _expect_dm(INT line, const DEVMODEA *expected, const CHAR *device, D dm.dmDisplayOrientation); }
-static void test_ChangeDisplaySettingsEx(void) +#define wait_for_dm(a, b, c, d) wait_for_dm_(__LINE__, a, b, c, d) +static void wait_for_dm_(int line, const char *device, DWORD expected_width, DWORD expected_height, BOOL todo) +{ + DEVMODEA dm; + BOOL ret; + int i; + + for (i = 0; i < 50; ++i) + { + memset(&dm, 0, sizeof(dm)); + dm.dmSize = sizeof(dm); + SetLastError(0xdeadbeef); + ret = EnumDisplaySettingsA(device, ENUM_CURRENT_SETTINGS, &dm); + ok_(__FILE__, line)(ret, "Device %s EnumDisplaySettingsA failed, error %#lx\n", device, GetLastError()); + + if (dm.dmPelsWidth == expected_width && dm.dmPelsHeight == expected_height) + break; + + Sleep(100); + } + + todo_wine_if(todo) ok_(__FILE__, line)(dm.dmPelsWidth == expected_width, + "Device %s expect dmPelsWidth %lu, got %lu\n", device, expected_width, dm.dmPelsWidth); + todo_wine_if(todo) ok_(__FILE__, line)(dm.dmPelsHeight == expected_height, + "Device %s expect dmPelsHeight %lu, got %lu\n", device, expected_height, dm.dmPelsHeight); +} + +static HANDLE test_child_process_ChangeDisplaySettingsEx(const char *argv0, const char *device, DWORD flags, const char *exit_event_name) +{ + static const char *cds_event_name = "test_child_process_cds_event"; + PROCESS_INFORMATION info; + char buffer[MAX_PATH]; + STARTUPINFOA startup; + DWORD wait_result; + HANDLE cds_event; + LONG res; + + cds_event = CreateEventA(NULL, FALSE, FALSE, cds_event_name); + ok(!!cds_event, "CreateEventA failed, error %#lx\n", GetLastError()); + + memset(&startup, 0, sizeof(startup)); + startup.cb = sizeof(startup); + + snprintf(buffer, sizeof(buffer), "%s monitor fullscreen %s %#lx %s %s", argv0, device, flags, + cds_event_name, exit_event_name); + res = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info); + ok(res, "CreateProcessA returned unexpected %ld\n", res); + wait_result = WaitForSingleObject(cds_event, 5000); + ok(wait_result == WAIT_OBJECT_0, "WaitForSingleObject returned %lx.\n", wait_result); + + CloseHandle(cds_event); + CloseHandle(info.hThread); + + return info.hProcess; +} + +static void test_ChangeDisplaySettingsEx(int argc, char **argv) { static const DWORD registry_fields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY | DM_POSITION; + static const char *exit_event0_name = "test_cds_exit_event0"; + static const char *exit_event1_name = "test_cds_exit_event1"; static const DWORD depths[] = {8, 16, 32}; DPI_AWARENESS_CONTEXT context = NULL; UINT primary, device, test, mode; + HANDLE exit_event0, exit_event1; UINT device_size, device_count; struct device_info *devices; + HANDLE process0, process1; DEVMODEA dm, dm2, dm3; INT count, old_count; DISPLAY_DEVICEA dd; + DWORD wait_result; POINTL position; DEVMODEW dmW; BOOL found; @@ -668,7 +729,7 @@ static void test_ChangeDisplaySettingsEx(void) continue; } flush_events(); - expect_dm(&dm3, devices[device].name, test); + expect_dm(&dm3, devices[device].name, test, FALSE);
/* Change the registry mode to the second mode */ res = ChangeDisplaySettingsExA(devices[device].name, &dm2, NULL, CDS_UPDATEREGISTRY | CDS_NORESET, NULL); @@ -802,7 +863,7 @@ static void test_ChangeDisplaySettingsEx(void) }
flush_events(); - expect_dm(&dm, devices[device].name, mode); + expect_dm(&dm, devices[device].name, mode, FALSE); }
/* Restore settings */ @@ -875,7 +936,7 @@ static void test_ChangeDisplaySettingsEx(void) }
flush_events(); - expect_dm(&dm, devices[device].name, 0); + expect_dm(&dm, devices[device].name, 0, FALSE);
/* Test specifying only position, width and height */ memset(&dm, 0, sizeof(dm)); @@ -920,7 +981,7 @@ static void test_ChangeDisplaySettingsEx(void) ok(dm.dmBitsPerPel, "Expected dmBitsPerPel not zero.\n"); ok(dm.dmDisplayFrequency, "Expected dmDisplayFrequency not zero.\n");
- expect_dm(&dm, devices[device].name, 0); + expect_dm(&dm, devices[device].name, 0, FALSE); }
/* Test dmPosition */ @@ -992,7 +1053,7 @@ static void test_ChangeDisplaySettingsEx(void) ok(res == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsExA %s returned unexpected %ld\n", devices[1].name, res);
dm2.dmPosition.x = dm.dmPosition.x + dm.dmPelsWidth; - expect_dm(&dm2, devices[1].name, 0); + expect_dm(&dm2, devices[1].name, 0, FALSE);
/* Test placing the secondary adapter to all sides of the primary adapter */ for (test = 0; test < 8; ++test) @@ -1051,7 +1112,7 @@ static void test_ChangeDisplaySettingsEx(void) }
flush_events(); - expect_dm(&dm2, devices[1].name, test); + expect_dm(&dm2, devices[1].name, test, FALSE); }
/* Test automatic position update when other adapters change resolution */ @@ -1116,7 +1177,7 @@ static void test_ChangeDisplaySettingsEx(void) ok(res == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsExA %s mode %d returned unexpected %ld.\n", devices[device].name, mode, res); flush_events(); - expect_dm(&dm2, devices[device].name, mode); + expect_dm(&dm2, devices[device].name, mode, FALSE);
/* EnumDisplaySettingsEx without EDS_ROTATEDMODE reports modes with current orientation */ memset(&dm3, 0, sizeof(dm3)); @@ -1148,6 +1209,166 @@ static void test_ChangeDisplaySettingsEx(void) ok(mode > 0, "Expected at least one display mode found.\n"); }
+ /* Restore all adapters to the current registry settings */ + res = ChangeDisplaySettingsExA(NULL, NULL, NULL, 0, NULL); + ok(res == DISP_CHANGE_SUCCESSFUL || + broken(res == DISP_CHANGE_FAILED), /* win8 TestBot */ + "ChangeDisplaySettingsExA returned unexpected %ld\n", res); + + if (res == DISP_CHANGE_FAILED) + { + win_skip("Failed restore dispay mode.\n"); + } + else + { + memset(&dm, 0, sizeof(dm)); + dm.dmSize = sizeof(dm); + dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; + + exit_event0 = CreateEventA(NULL, FALSE, FALSE, exit_event0_name); + ok(!!exit_event0, "CreateEventA failed, error %#lx\n", GetLastError()); + exit_event1 = CreateEventA(NULL, FALSE, FALSE, exit_event1_name); + ok(!!exit_event1, "CreateEventA failed, error %#lx\n", GetLastError()); + + /* Test that if the most recent ChangeDisplaySettingsEx call had + * CDS_FULLSCREEN set, then the settings are restored when the caller + * process exits */ + + process0 = test_child_process_ChangeDisplaySettingsEx(argv[0], devices[0].name, CDS_FULLSCREEN, exit_event0_name); + process1 = test_child_process_ChangeDisplaySettingsEx(argv[0], devices[0].name, CDS_FULLSCREEN, exit_event1_name); + + /* Verify that the settings are restored to the current registry settings */ + for (device = 0; device < device_count; ++device) + { + dm.dmPelsWidth = 800; + dm.dmPelsHeight = 600; + res = ChangeDisplaySettingsExA(devices[device].name, &dm, NULL, CDS_UPDATEREGISTRY | CDS_NORESET, NULL); + ok(res == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsExA %s returned %ld.\n", devices[device].name, res); + } + + SetEvent(exit_event0); + wait_result = WaitForSingleObject(process0, 5000); + ok(wait_result == WAIT_OBJECT_0, "WaitForSingleObject returned %lx.\n", wait_result); + + Sleep(100); + + dm.dmPelsWidth = 640; + dm.dmPelsHeight = 480; + expect_dm(&dm, devices[0].name, 0, TRUE); + + SetEvent(exit_event1); + wait_result = WaitForSingleObject(process1, 5000); + ok(wait_result == WAIT_OBJECT_0, "WaitForSingleObject returned %lx.\n", wait_result); + + wait_for_dm(devices[0].name, 800, 600, TRUE); + + CloseHandle(process1); + CloseHandle(process0); + + /* Test processes exiting in reverse order */ + + process0 = test_child_process_ChangeDisplaySettingsEx(argv[0], devices[0].name, CDS_FULLSCREEN, exit_event0_name); + process1 = test_child_process_ChangeDisplaySettingsEx(argv[0], devices[0].name, CDS_FULLSCREEN, exit_event1_name); + + SetEvent(exit_event1); + wait_result = WaitForSingleObject(process1, 5000); + ok(wait_result == WAIT_OBJECT_0, "WaitForSingleObject returned %lx.\n", wait_result); + + wait_for_dm(devices[0].name, 800, 600, TRUE); + + SetEvent(exit_event0); + wait_result = WaitForSingleObject(process0, 5000); + ok(wait_result == WAIT_OBJECT_0, "WaitForSingleObject returned %lx.\n", wait_result); + + CloseHandle(process1); + CloseHandle(process0); + + /* Test that ChangeDisplaySettingsEx without CDS_FULLSCREEN cancels the restoration */ + + process0 = test_child_process_ChangeDisplaySettingsEx(argv[0], devices[0].name, CDS_FULLSCREEN, exit_event0_name); + process1 = test_child_process_ChangeDisplaySettingsEx(argv[0], devices[0].name, 0, exit_event1_name); + + SetEvent(exit_event0); + wait_result = WaitForSingleObject(process0, 5000); + ok(wait_result == WAIT_OBJECT_0, "WaitForSingleObject returned %lx.\n", wait_result); + + Sleep(100); + + dm.dmPelsWidth = 640; + dm.dmPelsHeight = 480; + expect_dm(&dm, devices[0].name, 0, TRUE); + + SetEvent(exit_event1); + wait_result = WaitForSingleObject(process1, 5000); + ok(wait_result == WAIT_OBJECT_0, "WaitForSingleObject returned %lx.\n", wait_result); + + Sleep(100); + + dm.dmPelsWidth = 640; + dm.dmPelsHeight = 480; + expect_dm(&dm, devices[0].name, 0, TRUE); + + CloseHandle(process1); + CloseHandle(process0); + + /* Test processes exiting in reverse order */ + + process0 = test_child_process_ChangeDisplaySettingsEx(argv[0], devices[0].name, CDS_FULLSCREEN, exit_event0_name); + process1 = test_child_process_ChangeDisplaySettingsEx(argv[0], devices[0].name, 0, exit_event1_name); + + SetEvent(exit_event1); + wait_result = WaitForSingleObject(process1, 5000); + ok(wait_result == WAIT_OBJECT_0, "WaitForSingleObject returned %lx.\n", wait_result); + + Sleep(100); + + dm.dmPelsWidth = 640; + dm.dmPelsHeight = 480; + expect_dm(&dm, devices[0].name, 0, TRUE); + + SetEvent(exit_event0); + wait_result = WaitForSingleObject(process0, 5000); + ok(wait_result == WAIT_OBJECT_0, "WaitForSingleObject returned %lx.\n", wait_result); + + Sleep(100); + + dm.dmPelsWidth = 640; + dm.dmPelsHeight = 480; + expect_dm(&dm, devices[0].name, 0, TRUE); + + CloseHandle(process1); + CloseHandle(process0); + + if (device_count < 2) + { + skip("Only one device found.\n"); + } + else + { + /* Test that the settings are restored for all devices, regardless of + * the process that changed them */ + + dm.dmPelsWidth = 640; + dm.dmPelsHeight = 480; + res = ChangeDisplaySettingsExA(devices[1].name, &dm, NULL, CDS_FULLSCREEN, NULL); + ok(res == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsExA %s returned %ld.\n", devices[1].name, res); + + process0 = test_child_process_ChangeDisplaySettingsEx(argv[0], devices[0].name, CDS_FULLSCREEN, exit_event0_name); + + SetEvent(exit_event0); + wait_result = WaitForSingleObject(process0, 5000); + ok(wait_result == WAIT_OBJECT_0, "WaitForSingleObject returned %lx.\n", wait_result); + + wait_for_dm(devices[0].name, 800, 600, TRUE); + wait_for_dm(devices[1].name, 800, 600, TRUE); + + CloseHandle(process0); + } + + CloseHandle(exit_event1); + CloseHandle(exit_event0); + } + /* Restore all adapters to their original settings */ for (device = 0; device < device_count; ++device) { @@ -1162,7 +1383,7 @@ static void test_ChangeDisplaySettingsEx(void) broken(res == DISP_CHANGE_FAILED), /* win8 TestBot */ "ChangeDisplaySettingsExA returned unexpected %ld\n", res); for (device = 0; device < device_count; ++device) - expect_dm(&devices[device].original_mode, devices[device].name, 0); + expect_dm(&devices[device].original_mode, devices[device].name, 0, FALSE);
free(devices); } @@ -2663,6 +2884,45 @@ BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, return TRUE; }
+static void test_fullscreen(int argc, char **argv) +{ + HANDLE event0, event1; + DWORD wait_result; + DWORD flags = 0; + DEVMODEA dm; + LONG res; + + if (argc < 7) + { + ok(0, "too few arguments.\n"); + return; + } + + res = sscanf(argv[4], "%lx", &flags); + ok(res == 1, "sscanf returned unexpected %ld.\n", res); + + event0 = OpenEventA(EVENT_MODIFY_STATE, FALSE, argv[5]); + ok(!!event0, "OpenEventA failed, error %#lx\n", GetLastError()); + event1 = OpenEventA(SYNCHRONIZE, FALSE, argv[6]); + ok(!!event1, "OpenEventA failed, error %#lx\n", GetLastError()); + + memset(&dm, 0, sizeof(dm)); + dm.dmSize = sizeof(dm); + dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; + dm.dmPelsWidth = 640; + dm.dmPelsHeight = 480; + res = ChangeDisplaySettingsExA(argv[3], &dm, NULL, flags, NULL); + ok(res == DISP_CHANGE_SUCCESSFUL, + "ChangeDisplaySettingsExA %s returned unexpected %ld.\n", argv[3], res); + + SetEvent(event0); + CloseHandle(event0); + + wait_result = WaitForSingleObject(event1, 7000); + ok(wait_result == WAIT_OBJECT_0, "WaitForSingleObject returned %lx.\n", wait_result); + CloseHandle(event1); +} + START_TEST(monitor) { char** myARGV; @@ -2670,15 +2930,23 @@ START_TEST(monitor)
init_function_pointers();
- if (myARGC >= 3 && strcmp(myARGV[2], "info") == 0) + if (myARGC >= 3) { - printf("Monitor information:\n"); - EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, 0); - return; + if (strcmp(myARGV[2], "info") == 0) + { + printf("Monitor information:\n"); + EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, 0); + return; + } + else if (strcmp(myARGV[2], "fullscreen") == 0) + { + test_fullscreen(myARGC, myARGV); + return; + } }
test_enumdisplaydevices(); - test_ChangeDisplaySettingsEx(); + test_ChangeDisplaySettingsEx(myARGC, myARGV); test_DisplayConfigSetDeviceInfo(); test_EnumDisplayMonitors(); test_monitors();
From: Anton Baskanov baskanov@gmail.com
We have to invalidate the current mode cache if there are pending RRNotify events. The performance hit on EnumDisplaySettingsExW is around 7%.
Also call X11DRV_DisplayDevices_RegisterEventHandlers in x11drv_init. Otherwise, RRNotify events will only be handled in the explorer process. --- dlls/user32/tests/monitor.c | 10 +++++----- dlls/winex11.drv/event.c | 2 +- dlls/winex11.drv/window.c | 1 - dlls/winex11.drv/x11drv.h | 1 + dlls/winex11.drv/x11drv_main.c | 1 + dlls/winex11.drv/xrandr.c | 28 ++++++++++++++++++++++++++++ 6 files changed, 36 insertions(+), 7 deletions(-)
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c index eda9fc74379..bcc1ae857fc 100644 --- a/dlls/user32/tests/monitor.c +++ b/dlls/user32/tests/monitor.c @@ -1254,7 +1254,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
dm.dmPelsWidth = 640; dm.dmPelsHeight = 480; - expect_dm(&dm, devices[0].name, 0, TRUE); + expect_dm(&dm, devices[0].name, 0, FALSE);
SetEvent(exit_event1); wait_result = WaitForSingleObject(process1, 5000); @@ -1296,7 +1296,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
dm.dmPelsWidth = 640; dm.dmPelsHeight = 480; - expect_dm(&dm, devices[0].name, 0, TRUE); + expect_dm(&dm, devices[0].name, 0, FALSE);
SetEvent(exit_event1); wait_result = WaitForSingleObject(process1, 5000); @@ -1306,7 +1306,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
dm.dmPelsWidth = 640; dm.dmPelsHeight = 480; - expect_dm(&dm, devices[0].name, 0, TRUE); + expect_dm(&dm, devices[0].name, 0, FALSE);
CloseHandle(process1); CloseHandle(process0); @@ -1324,7 +1324,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
dm.dmPelsWidth = 640; dm.dmPelsHeight = 480; - expect_dm(&dm, devices[0].name, 0, TRUE); + expect_dm(&dm, devices[0].name, 0, FALSE);
SetEvent(exit_event0); wait_result = WaitForSingleObject(process0, 5000); @@ -1334,7 +1334,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
dm.dmPelsWidth = 640; dm.dmPelsHeight = 480; - expect_dm(&dm, devices[0].name, 0, TRUE); + expect_dm(&dm, devices[0].name, 0, FALSE);
CloseHandle(process1); CloseHandle(process0); diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 379b27b3f70..2070d942056 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -405,7 +405,7 @@ static inline BOOL call_event_handler( Display *display, XEvent *event ) /*********************************************************************** * process_events */ -static BOOL process_events( Display *display, Bool (*filter)(Display*, XEvent*,XPointer), ULONG_PTR arg ) +BOOL process_events( Display *display, Bool (*filter)(Display*, XEvent*,XPointer), ULONG_PTR arg ) { XEvent event, prev_event; int count = 0; diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 5a014c9080d..19daac04203 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2048,7 +2048,6 @@ BOOL X11DRV_CreateWindow( HWND hwnd ) CWOverrideRedirect | CWEventMask, &attr ); XFlush( data->display ); NtUserSetProp( hwnd, clip_window_prop, (HANDLE)data->clip_window ); - X11DRV_DisplayDevices_RegisterEventHandlers(); } return TRUE; } diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index dc8e4d6f402..36fd4418a5f 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -679,6 +679,7 @@ extern void retry_grab_clipping_window(void); extern void ungrab_clipping_window(void); extern void move_resize_window( HWND hwnd, int dir ); extern void X11DRV_InitKeyboard( Display *display ); +extern BOOL process_events( Display *display, Bool (*filter)(Display*, XEvent*, XPointer), ULONG_PTR arg ); extern BOOL X11DRV_ProcessEvents( DWORD mask ); extern HWND *build_hwnd_list(void);
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 4c8fd943ffd..f8e56702d8c 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -683,6 +683,7 @@ static NTSTATUS x11drv_init( void *arg )
init_user_driver(); X11DRV_DisplayDevices_Init(FALSE); + X11DRV_DisplayDevices_RegisterEventHandlers(); return STATUS_SUCCESS; }
diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c index b829c677ff1..f0e36222911 100644 --- a/dlls/winex11.drv/xrandr.c +++ b/dlls/winex11.drv/xrandr.c @@ -1213,6 +1213,32 @@ static void xrandr14_register_event_handlers(void) "XRandR ProviderChange" ); }
+static Bool filter_rrnotify_event( Display *display, XEvent *event, char *arg ) +{ + ULONG_PTR event_base = (ULONG_PTR)arg; + + if (event->type == event_base + RRNotify_CrtcChange + || event->type == event_base + RRNotify_OutputChange + || event->type == event_base + RRNotify_ProviderChange) + return 1; + + return 0; +} + +static void process_rrnotify_events(void) +{ + struct x11drv_thread_data *data = x11drv_thread_data(); + int event_base, error_base; + + if (!data) return; + if (data->current_event) return; /* don't process nested events */ + + if (!pXRRQueryExtension( data->display, &event_base, &error_base )) + return; + + process_events( data->display, filter_rrnotify_event, event_base ); +} + /* XRandR 1.4 display settings handler */ static BOOL xrandr14_get_id( const WCHAR *device_name, BOOL is_primary, x11drv_settings_id *id ) { @@ -1228,6 +1254,8 @@ static BOOL xrandr14_get_id( const WCHAR *device_name, BOOL is_primary, x11drv_s if (*end) return FALSE;
+ process_rrnotify_events(); + /* Update cache */ pthread_mutex_lock( &xrandr_mutex ); if (!current_modes)
From: Anton Baskanov baskanov@gmail.com
Restore display settings to the ones in the registry when CDS_FULLSCREEN is used in ChangeDisplaySettings().
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49674 --- dlls/user32/tests/monitor.c | 50 ++++++++--------- dlls/win32u/sysparams.c | 14 +++++ programs/explorer/desktop.c | 105 +++++++++++++++++++++++++++++++++--- 3 files changed, 137 insertions(+), 32 deletions(-)
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c index bcc1ae857fc..4e6f8ac938a 100644 --- a/dlls/user32/tests/monitor.c +++ b/dlls/user32/tests/monitor.c @@ -291,8 +291,8 @@ struct device_info DEVMODEA original_mode; };
-#define expect_dm(a, b, c, d) _expect_dm(__LINE__, a, b, c, d) -static void _expect_dm(INT line, const DEVMODEA *expected, const CHAR *device, DWORD test, BOOL todo) +#define expect_dm(a, b, c) _expect_dm(__LINE__, a, b, c) +static void _expect_dm(INT line, const DEVMODEA *expected, const CHAR *device, DWORD test) { DEVMODEA dm; BOOL ret; @@ -307,9 +307,9 @@ static void _expect_dm(INT line, const DEVMODEA *expected, const CHAR *device, D "Device %s test %ld expect dmFields to contain %#lx, got %#lx\n", device, test, expected->dmFields, dm.dmFields); ok_(__FILE__, line)(!(expected->dmFields & DM_BITSPERPEL) || dm.dmBitsPerPel == expected->dmBitsPerPel, "Device %s test %ld expect dmBitsPerPel %lu, got %lu\n", device, test, expected->dmBitsPerPel, dm.dmBitsPerPel); - todo_wine_if(todo) ok_(__FILE__, line)(!(expected->dmFields & DM_PELSWIDTH) || dm.dmPelsWidth == expected->dmPelsWidth, + ok_(__FILE__, line)(!(expected->dmFields & DM_PELSWIDTH) || dm.dmPelsWidth == expected->dmPelsWidth, "Device %s test %ld expect dmPelsWidth %lu, got %lu\n", device, test, expected->dmPelsWidth, dm.dmPelsWidth); - todo_wine_if(todo) ok_(__FILE__, line)(!(expected->dmFields & DM_PELSHEIGHT) || dm.dmPelsHeight == expected->dmPelsHeight, + ok_(__FILE__, line)(!(expected->dmFields & DM_PELSHEIGHT) || dm.dmPelsHeight == expected->dmPelsHeight, "Device %s test %ld expect dmPelsHeight %lu, got %lu\n", device, test, expected->dmPelsHeight, dm.dmPelsHeight); ok_(__FILE__, line)(!(expected->dmFields & DM_POSITION) || dm.dmPosition.x == expected->dmPosition.x, "Device %s test %ld expect dmPosition.x %ld, got %ld\n", device, test, expected->dmPosition.x, dm.dmPosition.x); @@ -325,8 +325,8 @@ static void _expect_dm(INT line, const DEVMODEA *expected, const CHAR *device, D dm.dmDisplayOrientation); }
-#define wait_for_dm(a, b, c, d) wait_for_dm_(__LINE__, a, b, c, d) -static void wait_for_dm_(int line, const char *device, DWORD expected_width, DWORD expected_height, BOOL todo) +#define wait_for_dm(a, b, c) wait_for_dm_(__LINE__, a, b, c) +static void wait_for_dm_(int line, const char *device, DWORD expected_width, DWORD expected_height) { DEVMODEA dm; BOOL ret; @@ -346,9 +346,9 @@ static void wait_for_dm_(int line, const char *device, DWORD expected_width, DWO Sleep(100); }
- todo_wine_if(todo) ok_(__FILE__, line)(dm.dmPelsWidth == expected_width, + ok_(__FILE__, line)(dm.dmPelsWidth == expected_width, "Device %s expect dmPelsWidth %lu, got %lu\n", device, expected_width, dm.dmPelsWidth); - todo_wine_if(todo) ok_(__FILE__, line)(dm.dmPelsHeight == expected_height, + ok_(__FILE__, line)(dm.dmPelsHeight == expected_height, "Device %s expect dmPelsHeight %lu, got %lu\n", device, expected_height, dm.dmPelsHeight); }
@@ -729,7 +729,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv) continue; } flush_events(); - expect_dm(&dm3, devices[device].name, test, FALSE); + expect_dm(&dm3, devices[device].name, test);
/* Change the registry mode to the second mode */ res = ChangeDisplaySettingsExA(devices[device].name, &dm2, NULL, CDS_UPDATEREGISTRY | CDS_NORESET, NULL); @@ -863,7 +863,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv) }
flush_events(); - expect_dm(&dm, devices[device].name, mode, FALSE); + expect_dm(&dm, devices[device].name, mode); }
/* Restore settings */ @@ -936,7 +936,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv) }
flush_events(); - expect_dm(&dm, devices[device].name, 0, FALSE); + expect_dm(&dm, devices[device].name, 0);
/* Test specifying only position, width and height */ memset(&dm, 0, sizeof(dm)); @@ -981,7 +981,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv) ok(dm.dmBitsPerPel, "Expected dmBitsPerPel not zero.\n"); ok(dm.dmDisplayFrequency, "Expected dmDisplayFrequency not zero.\n");
- expect_dm(&dm, devices[device].name, 0, FALSE); + expect_dm(&dm, devices[device].name, 0); }
/* Test dmPosition */ @@ -1053,7 +1053,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv) ok(res == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsExA %s returned unexpected %ld\n", devices[1].name, res);
dm2.dmPosition.x = dm.dmPosition.x + dm.dmPelsWidth; - expect_dm(&dm2, devices[1].name, 0, FALSE); + expect_dm(&dm2, devices[1].name, 0);
/* Test placing the secondary adapter to all sides of the primary adapter */ for (test = 0; test < 8; ++test) @@ -1112,7 +1112,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv) }
flush_events(); - expect_dm(&dm2, devices[1].name, test, FALSE); + expect_dm(&dm2, devices[1].name, test); }
/* Test automatic position update when other adapters change resolution */ @@ -1177,7 +1177,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv) ok(res == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsExA %s mode %d returned unexpected %ld.\n", devices[device].name, mode, res); flush_events(); - expect_dm(&dm2, devices[device].name, mode, FALSE); + expect_dm(&dm2, devices[device].name, mode);
/* EnumDisplaySettingsEx without EDS_ROTATEDMODE reports modes with current orientation */ memset(&dm3, 0, sizeof(dm3)); @@ -1254,13 +1254,13 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
dm.dmPelsWidth = 640; dm.dmPelsHeight = 480; - expect_dm(&dm, devices[0].name, 0, FALSE); + expect_dm(&dm, devices[0].name, 0);
SetEvent(exit_event1); wait_result = WaitForSingleObject(process1, 5000); ok(wait_result == WAIT_OBJECT_0, "WaitForSingleObject returned %lx.\n", wait_result);
- wait_for_dm(devices[0].name, 800, 600, TRUE); + wait_for_dm(devices[0].name, 800, 600);
CloseHandle(process1); CloseHandle(process0); @@ -1274,7 +1274,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv) wait_result = WaitForSingleObject(process1, 5000); ok(wait_result == WAIT_OBJECT_0, "WaitForSingleObject returned %lx.\n", wait_result);
- wait_for_dm(devices[0].name, 800, 600, TRUE); + wait_for_dm(devices[0].name, 800, 600);
SetEvent(exit_event0); wait_result = WaitForSingleObject(process0, 5000); @@ -1296,7 +1296,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
dm.dmPelsWidth = 640; dm.dmPelsHeight = 480; - expect_dm(&dm, devices[0].name, 0, FALSE); + expect_dm(&dm, devices[0].name, 0);
SetEvent(exit_event1); wait_result = WaitForSingleObject(process1, 5000); @@ -1306,7 +1306,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
dm.dmPelsWidth = 640; dm.dmPelsHeight = 480; - expect_dm(&dm, devices[0].name, 0, FALSE); + expect_dm(&dm, devices[0].name, 0);
CloseHandle(process1); CloseHandle(process0); @@ -1324,7 +1324,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
dm.dmPelsWidth = 640; dm.dmPelsHeight = 480; - expect_dm(&dm, devices[0].name, 0, FALSE); + expect_dm(&dm, devices[0].name, 0);
SetEvent(exit_event0); wait_result = WaitForSingleObject(process0, 5000); @@ -1334,7 +1334,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv)
dm.dmPelsWidth = 640; dm.dmPelsHeight = 480; - expect_dm(&dm, devices[0].name, 0, FALSE); + expect_dm(&dm, devices[0].name, 0);
CloseHandle(process1); CloseHandle(process0); @@ -1359,8 +1359,8 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv) wait_result = WaitForSingleObject(process0, 5000); ok(wait_result == WAIT_OBJECT_0, "WaitForSingleObject returned %lx.\n", wait_result);
- wait_for_dm(devices[0].name, 800, 600, TRUE); - wait_for_dm(devices[1].name, 800, 600, TRUE); + wait_for_dm(devices[0].name, 800, 600); + wait_for_dm(devices[1].name, 800, 600);
CloseHandle(process0); } @@ -1383,7 +1383,7 @@ static void test_ChangeDisplaySettingsEx(int argc, char **argv) broken(res == DISP_CHANGE_FAILED), /* win8 TestBot */ "ChangeDisplaySettingsExA returned unexpected %ld\n", res); for (device = 0; device < device_count; ++device) - expect_dm(&devices[device].original_mode, devices[device].name, 0, FALSE); + expect_dm(&devices[device].original_mode, devices[device].name, 0);
free(devices); } diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 0122c8b0b13..d50f21bc0b9 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -3176,9 +3176,14 @@ static BOOL all_detached_settings( const DEVMODEW *displays ) static LONG apply_display_settings( struct adapter *target, const DEVMODEW *devmode, HWND hwnd, DWORD flags, void *lparam ) { + static const WCHAR restorerW[] = {'_','_','w','i','n','e','_','d','i','s','p','l','a','y','_', + 's','e','t','t','i','n','g','s','_','r','e','s','t','o','r','e','r',0}; + UNICODE_STRING restoter_str = RTL_CONSTANT_STRING( restorerW ); WCHAR primary_name[CCHDEVICENAME]; struct adapter *primary, *adapter; + DWORD fullscreen_process_id; DEVMODEW *mode, *displays; + HWND restorer_window; LONG ret;
if (!lock_display_devices()) return DISP_CHANGE_FAILED; @@ -3227,6 +3232,15 @@ static LONG apply_display_settings( struct adapter *target, const DEVMODEW *devm free( displays ); if (ret) return ret;
+ if ((restorer_window = NtUserFindWindowEx( NULL, NULL, &restoter_str, NULL, 0 ))) + { + if (NtUserGetWindowThread( restorer_window, NULL ) != GetCurrentThreadId()) + { + fullscreen_process_id = (flags & CDS_FULLSCREEN) ? GetCurrentProcessId() : 0; + send_message( restorer_window, WM_USER + 0, 0, fullscreen_process_id ); + } + } + if (!update_display_cache( TRUE )) WARN( "Failed to update display cache after mode change.\n" );
diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c index 25bba7cb7cb..ad00751537d 100644 --- a/programs/explorer/desktop.c +++ b/programs/explorer/desktop.c @@ -611,6 +611,18 @@ static void initialize_launchers( HWND hwnd ) } }
+static void wait_named_mutex( const WCHAR *name ) +{ + HANDLE mutex; + + mutex = CreateMutexW( NULL, TRUE, name ); + if (GetLastError() == ERROR_ALREADY_EXISTS) + { + TRACE( "waiting for mutex %s\n", debugstr_w( name )); + WaitForSingleObject( mutex, INFINITE ); + } +} + /************************************************************************** * wait_clipboard_mutex * @@ -620,7 +632,6 @@ static BOOL wait_clipboard_mutex(void) { static const WCHAR prefix[] = L"__wine_clipboard_"; WCHAR buffer[MAX_PATH + ARRAY_SIZE( prefix )]; - HANDLE mutex;
memcpy( buffer, prefix, sizeof(prefix) ); if (!GetUserObjectInformationW( GetProcessWindowStation(), UOI_NAME, @@ -630,12 +641,7 @@ static BOOL wait_clipboard_mutex(void) ERR( "failed to get winstation name\n" ); return FALSE; } - mutex = CreateMutexW( NULL, TRUE, buffer ); - if (GetLastError() == ERROR_ALREADY_EXISTS) - { - TRACE( "waiting for mutex %s\n", debugstr_w( buffer )); - WaitForSingleObject( mutex, INFINITE ); - } + wait_named_mutex( buffer ); return TRUE; }
@@ -696,6 +702,87 @@ static DWORD WINAPI clipboard_thread( void *arg ) return 0; }
+static HANDLE fullscreen_process; + +static LRESULT WINAPI display_settings_restorer_wndproc( HWND hwnd, UINT message, WPARAM wp, LPARAM lp ) +{ + TRACE( "got msg %04x wp %Ix lp %Ix\n", message, wp, lp ); + + switch(message) + { + case WM_USER + 0: + TRACE( "fullscreen process id %Iu.\n", lp ); + + if (fullscreen_process) + { + CloseHandle( fullscreen_process ); + fullscreen_process = NULL; + } + + if (lp) + fullscreen_process = OpenProcess( SYNCHRONIZE, FALSE, lp ); + + return 0; + } + + return DefWindowProcW( hwnd, message, wp, lp ); +} + +static DWORD WINAPI display_settings_restorer_thread( void *param ) +{ + static const WCHAR *display_settings_restorer_classname = L"__wine_display_settings_restorer"; + DWORD wait_result; + WNDCLASSW class; + MSG msg; + + SetThreadDescription( GetCurrentThread(), L"wine_explorer_display_settings_restorer" ); + + wait_named_mutex( L"__wine_display_settings_restorer_mutex" ); + + memset( &class, 0, sizeof(class) ); + class.lpfnWndProc = display_settings_restorer_wndproc; + class.lpszClassName = display_settings_restorer_classname; + + if (!RegisterClassW( &class ) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) + { + ERR( "could not register display settings restorer window class err %lu\n", GetLastError() ); + return 0; + } + if (!CreateWindowW( display_settings_restorer_classname, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, NULL )) + { + TRACE( "failed to create display settings restorer window err %lu\n", GetLastError() ); + UnregisterClassW( display_settings_restorer_classname, NULL ); + return 0; + } + + for (;;) + { + if (PeekMessageW( &msg, NULL, 0, 0, PM_REMOVE )) + { + if (msg.message == WM_QUIT) + break; + DispatchMessageW( &msg ); + continue; + } + + wait_result = MsgWaitForMultipleObjects( fullscreen_process ? 1 : 0, &fullscreen_process, + FALSE, INFINITE, QS_ALLINPUT ); + if (wait_result == WAIT_FAILED) + break; + if (!fullscreen_process || wait_result != WAIT_OBJECT_0) + continue; + + WARN( "restoring display settings on process exit\n" ); + + ChangeDisplaySettingsExW( NULL, NULL, NULL, 0, NULL ); + + CloseHandle( fullscreen_process ); + fullscreen_process = NULL; + } + + return 0; +} + static WNDPROC desktop_orig_wndproc;
/* window procedure for the desktop window */ @@ -968,6 +1055,7 @@ static void initialize_display_settings( unsigned int width, unsigned int height { DISPLAY_DEVICEW device = {.cb = sizeof(DISPLAY_DEVICEW)}; DWORD i = 0, flags = CDS_GLOBAL | CDS_UPDATEREGISTRY; + HANDLE thread;
/* Store current display mode in the registry */ while (EnumDisplayDevicesW( NULL, i++, &device, 0 )) @@ -1000,6 +1088,9 @@ static void initialize_display_settings( unsigned int width, unsigned int height if (ChangeDisplaySettingsExW( NULL, &devmode, 0, flags, NULL )) ERR( "Failed to set primary display settings.\n" ); } + + thread = CreateThread( NULL, 0, display_settings_restorer_thread, NULL, 0, NULL ); + if (thread) CloseHandle( thread ); }
static void set_desktop_window_title( HWND hwnd, const WCHAR *name )
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=144437
Your paranoid android.
=== w11pro64_amd (64 bit report) ===
user32: monitor.c:2897: Test failed: too few arguments. monitor.c:376: Test failed: WaitForSingleObject returned 102. monitor.c:2897: Test failed: too few arguments. monitor.c:376: Test failed: WaitForSingleObject returned 102. monitor.c:1257: Test failed: Device test 0 EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1257: Test failed: Device test 0 expect dmFields to contain 0x180000, got 0 monitor.c:1257: Test failed: Device test 0 expect dmPelsWidth 640, got 0 monitor.c:1257: Test failed: Device test 0 expect dmPelsHeight 480, got 0 monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1263: Test failed: Device expect dmPelsWidth 800, got 0 monitor.c:1263: Test failed: Device expect dmPelsHeight 600, got 0 monitor.c:2897: Test failed: too few arguments. monitor.c:376: Test failed: WaitForSingleObject returned 102. monitor.c:2897: Test failed: too few arguments. monitor.c:376: Test failed: WaitForSingleObject returned 102. monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1277: Test failed: Device expect dmPelsWidth 800, got 0 monitor.c:1277: Test failed: Device expect dmPelsHeight 600, got 0 monitor.c:2897: Test failed: too few arguments. monitor.c:376: Test failed: WaitForSingleObject returned 102. monitor.c:2897: Test failed: too few arguments. monitor.c:376: Test failed: WaitForSingleObject returned 102. monitor.c:1299: Test failed: Device test 0 EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1299: Test failed: Device test 0 expect dmFields to contain 0x180000, got 0 monitor.c:1299: Test failed: Device test 0 expect dmPelsWidth 640, got 0 monitor.c:1299: Test failed: Device test 0 expect dmPelsHeight 480, got 0 monitor.c:1309: Test failed: Device test 0 EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1309: Test failed: Device test 0 expect dmFields to contain 0x180000, got 0 monitor.c:1309: Test failed: Device test 0 expect dmPelsWidth 640, got 0 monitor.c:1309: Test failed: Device test 0 expect dmPelsHeight 480, got 0 monitor.c:2897: Test failed: too few arguments. monitor.c:376: Test failed: WaitForSingleObject returned 102. monitor.c:2897: Test failed: too few arguments. monitor.c:376: Test failed: WaitForSingleObject returned 102. monitor.c:1327: Test failed: Device test 0 EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1327: Test failed: Device test 0 expect dmFields to contain 0x180000, got 0 monitor.c:1327: Test failed: Device test 0 expect dmPelsWidth 640, got 0 monitor.c:1327: Test failed: Device test 0 expect dmPelsHeight 480, got 0 monitor.c:1337: Test failed: Device test 0 EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1337: Test failed: Device test 0 expect dmFields to contain 0x180000, got 0 monitor.c:1337: Test failed: Device test 0 expect dmPelsWidth 640, got 0 monitor.c:1337: Test failed: Device test 0 expect dmPelsHeight 480, got 0
On Tue Mar 26 07:42:13 2024 +0000, Zhiyi Zhang wrote:
Let's move these codes here
restorer_window = NtUserFindWindowEx( NULL, NULL, &restoter_str, NULL, 0 ); restorer_thread_id = NtUserGetWindowThread( restorer_window, NULL );
Also check if restorer_window is found before sending a message because explorer.exe might not be running.
Done.
On Tue Mar 26 07:36:40 2024 +0000, Zhiyi Zhang wrote:
You're duplicating this part of the display setting restoration code. Usually, a ChangeDisplaySettingsExA(NULL, NULL, NULL, 0, NULL); is enough for getting rid of test failures. Could you try and see if that's enough? If it still doesn't work, then we could keep it.
Done.
v8: - Use `ChangeDisplaySettingsExA(NULL, NULL, NULL, 0, NULL)` to restore the mode before tests. - Skip the tests if the mode restoration failed (in an attempt to fix TestBot failures). - Check that `restorer_window` is not NULL.
On Wed Mar 27 10:06:42 2024 +0000, Zhiyi Zhang wrote:
Also, there are some TestBot failures after this MR. Please see https://testbot.winehq.org/JobDetails.pl?Key=144370#k204
Looks like `ChangeDisplaySettingsExA` fails with Basic Display Adapter. Added some logic to skip the tests, will see if this helps.
On Wed Mar 27 10:06:42 2024 +0000, Anton Baskanov wrote:
Looks like `ChangeDisplaySettingsExA` fails with Basic Display Adapter. Added some logic to skip the tests, will see if this helps.
Well, the Windows 8.1 failures are gone, but the Windows 11 ones are still there. Looks like the device name is empty for some reason, haven't figured it out yet.
On Wed Mar 27 16:54:03 2024 +0000, Anton Baskanov wrote:
Well, the Windows 8.1 failures are gone, but the Windows 11 ones are still there. Looks like the device name is empty for some reason, haven't figured it out yet.
These new win11 test failures seem like they were introduced by this MR. So you will need to address them as well. Try submitting the MR to the TestBot first.