-- v8: 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 | 307 +++++++++++++++++++++++++++++++++--- 1 file changed, 289 insertions(+), 18 deletions(-)
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c index e93a84242c4..e732e83016f 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)); @@ -1162,7 +1223,170 @@ 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); + + 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()); + + memset(&dm, 0, sizeof(dm)); + dm.dmSize = sizeof(dm); + dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; + + /* 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) + { + res = ChangeDisplaySettingsExA(devices[device].name, &devices[device].original_mode, NULL, + CDS_UPDATEREGISTRY | CDS_NORESET, NULL); + ok(res == DISP_CHANGE_SUCCESSFUL || + broken(res == DISP_CHANGE_FAILED), /* win8 TestBot */ + "ChangeDisplaySettingsExA %s returned unexpected %ld\n", devices[device].name, res); + } + 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); + for (device = 0; device < device_count; ++device) + expect_dm(&devices[device].original_mode, devices[device].name, 0, FALSE);
free(devices); } @@ -2663,6 +2887,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 +2933,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 e732e83016f..6d2640e0761 100644 --- a/dlls/user32/tests/monitor.c +++ b/dlls/user32/tests/monitor.c @@ -1258,7 +1258,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); @@ -1300,7 +1300,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); @@ -1310,7 +1310,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); @@ -1328,7 +1328,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); @@ -1338,7 +1338,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 26a3e8b2e64..3d9457c9b23 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -682,6 +682,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 5d4ed065fb5..dbe79f00267 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -694,6 +694,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 | 52 +++++++++--------- dlls/win32u/sysparams.c | 15 ++++++ programs/explorer/desktop.c | 105 +++++++++++++++++++++++++++++++++--- 3 files changed, 139 insertions(+), 33 deletions(-)
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c index 6d2640e0761..f86e198497e 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)); @@ -1223,7 +1223,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);
exit_event0 = CreateEventA(NULL, FALSE, FALSE, exit_event0_name); ok(!!exit_event0, "CreateEventA failed, error %#lx\n", GetLastError()); @@ -1258,13 +1258,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); @@ -1278,7 +1278,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); @@ -1300,7 +1300,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); @@ -1310,7 +1310,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); @@ -1328,7 +1328,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); @@ -1338,7 +1338,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); @@ -1363,8 +1363,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); } @@ -1386,7 +1386,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 d5ad97a2c33..35fbdf67d74 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -3176,11 +3176,20 @@ 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; + DWORD restorer_thread_id; + HWND restorer_window; LONG ret;
+ restorer_window = NtUserFindWindowEx( NULL, NULL, &restoter_str, NULL, 0 ); + restorer_thread_id = NtUserGetWindowThread( restorer_window, NULL ); + if (!lock_display_devices()) return DISP_CHANGE_FAILED; if (!(displays = get_display_settings( target, devmode ))) { @@ -3227,6 +3236,12 @@ static LONG apply_display_settings( struct adapter *target, const DEVMODEW *devm free( displays ); if (ret) return ret;
+ if ( restorer_thread_id != 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=144370
Your paranoid android.
=== w8 (32 bit report) ===
user32: monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:1250: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned -1. monitor.c:1261: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsWidth 640, got 1024 monitor.c:1261: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsHeight 480, got 768 monitor.c:1267: Test failed: Device \.\DISPLAY1 expect dmPelsWidth 800, got 1024 monitor.c:1267: Test failed: Device \.\DISPLAY1 expect dmPelsHeight 600, got 768 monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:1281: Test failed: Device \.\DISPLAY1 expect dmPelsWidth 800, got 1024 monitor.c:1281: Test failed: Device \.\DISPLAY1 expect dmPelsHeight 600, got 768 monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:1303: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsWidth 640, got 1024 monitor.c:1303: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsHeight 480, got 768 monitor.c:1313: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsWidth 640, got 1024 monitor.c:1313: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsHeight 480, got 768 monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:1331: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsWidth 640, got 1024 monitor.c:1331: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsHeight 480, got 768 monitor.c:1341: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsWidth 640, got 1024 monitor.c:1341: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsHeight 480, got 768
=== w8adm (32 bit report) ===
user32: monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:1250: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned -1. monitor.c:1261: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsWidth 640, got 1024 monitor.c:1261: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsHeight 480, got 768 monitor.c:1267: Test failed: Device \.\DISPLAY1 expect dmPelsWidth 800, got 1024 monitor.c:1267: Test failed: Device \.\DISPLAY1 expect dmPelsHeight 600, got 768 monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:1281: Test failed: Device \.\DISPLAY1 expect dmPelsWidth 800, got 1024 monitor.c:1281: Test failed: Device \.\DISPLAY1 expect dmPelsHeight 600, got 768 monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:1303: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsWidth 640, got 1024 monitor.c:1303: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsHeight 480, got 768 monitor.c:1313: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsWidth 640, got 1024 monitor.c:1313: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsHeight 480, got 768 monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:1331: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsWidth 640, got 1024 monitor.c:1331: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsHeight 480, got 768 monitor.c:1341: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsWidth 640, got 1024 monitor.c:1341: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsHeight 480, got 768
=== w864 (32 bit report) ===
user32: monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:1250: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned -1. monitor.c:1261: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsWidth 640, got 1024 monitor.c:1261: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsHeight 480, got 768 monitor.c:1267: Test failed: Device \.\DISPLAY1 expect dmPelsWidth 800, got 1024 monitor.c:1267: Test failed: Device \.\DISPLAY1 expect dmPelsHeight 600, got 768 monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:1281: Test failed: Device \.\DISPLAY1 expect dmPelsWidth 800, got 1024 monitor.c:1281: Test failed: Device \.\DISPLAY1 expect dmPelsHeight 600, got 768 monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:1303: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsWidth 640, got 1024 monitor.c:1303: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsHeight 480, got 768 monitor.c:1313: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsWidth 640, got 1024 monitor.c:1313: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsHeight 480, got 768 monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:1331: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsWidth 640, got 1024 monitor.c:1331: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsHeight 480, got 768 monitor.c:1341: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsWidth 640, got 1024 monitor.c:1341: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsHeight 480, got 768
=== w864 (64 bit report) ===
user32: monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:1250: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned -1. monitor.c:1261: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsWidth 640, got 1024 monitor.c:1261: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsHeight 480, got 768 monitor.c:1267: Test failed: Device \.\DISPLAY1 expect dmPelsWidth 800, got 1024 monitor.c:1267: Test failed: Device \.\DISPLAY1 expect dmPelsHeight 600, got 768 monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:1281: Test failed: Device \.\DISPLAY1 expect dmPelsWidth 800, got 1024 monitor.c:1281: Test failed: Device \.\DISPLAY1 expect dmPelsHeight 600, got 768 monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:1303: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsWidth 640, got 1024 monitor.c:1303: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsHeight 480, got 768 monitor.c:1313: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsWidth 640, got 1024 monitor.c:1313: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsHeight 480, got 768 monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:2918: Test failed: ChangeDisplaySettingsExA \.\DISPLAY1 returned unexpected -1. monitor.c:1331: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsWidth 640, got 1024 monitor.c:1331: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsHeight 480, got 768 monitor.c:1341: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsWidth 640, got 1024 monitor.c:1341: Test failed: Device \.\DISPLAY1 test 0 expect dmPelsHeight 480, got 768
=== w11pro64_amd (64 bit report) ===
user32: monitor.c:2900: Test failed: too few arguments. monitor.c:376: Test failed: WaitForSingleObject returned 102. monitor.c:2900: Test failed: too few arguments. monitor.c:376: Test failed: WaitForSingleObject returned 102. monitor.c:1261: Test failed: Device test 0 EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1261: Test failed: Device test 0 expect dmFields to contain 0x180000, got 0 monitor.c:1261: Test failed: Device test 0 expect dmPelsWidth 640, got 0 monitor.c:1261: Test failed: Device test 0 expect dmPelsHeight 480, got 0 monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1267: Test failed: Device expect dmPelsWidth 800, got 0 monitor.c:1267: Test failed: Device expect dmPelsHeight 600, got 0 monitor.c:2900: Test failed: too few arguments. monitor.c:376: Test failed: WaitForSingleObject returned 102. monitor.c:2900: Test failed: too few arguments. monitor.c:376: Test failed: WaitForSingleObject returned 102. monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1281: Test failed: Device expect dmPelsWidth 800, got 0 monitor.c:1281: Test failed: Device expect dmPelsHeight 600, got 0 monitor.c:2900: Test failed: too few arguments. monitor.c:376: Test failed: WaitForSingleObject returned 102. monitor.c:2900: Test failed: too few arguments. monitor.c:376: Test failed: WaitForSingleObject returned 102. monitor.c:1303: Test failed: Device test 0 EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1303: Test failed: Device test 0 expect dmFields to contain 0x180000, got 0 monitor.c:1303: Test failed: Device test 0 expect dmPelsWidth 640, got 0 monitor.c:1303: Test failed: Device test 0 expect dmPelsHeight 480, got 0 monitor.c:1313: Test failed: Device test 0 EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1313: Test failed: Device test 0 expect dmFields to contain 0x180000, got 0 monitor.c:1313: Test failed: Device test 0 expect dmPelsWidth 640, got 0 monitor.c:1313: Test failed: Device test 0 expect dmPelsHeight 480, got 0 monitor.c:2900: Test failed: too few arguments. monitor.c:376: Test failed: WaitForSingleObject returned 102. monitor.c:2900: Test failed: too few arguments. monitor.c:376: Test failed: WaitForSingleObject returned 102. monitor.c:1331: Test failed: Device test 0 EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1331: Test failed: Device test 0 expect dmFields to contain 0x180000, got 0 monitor.c:1331: Test failed: Device test 0 expect dmPelsWidth 640, got 0 monitor.c:1331: Test failed: Device test 0 expect dmPelsHeight 480, got 0 monitor.c:1341: Test failed: Device test 0 EnumDisplaySettingsA failed, error 0xdeadbeef monitor.c:1341: Test failed: Device test 0 expect dmFields to contain 0x180000, got 0 monitor.c:1341: Test failed: Device test 0 expect dmPelsWidth 640, got 0 monitor.c:1341: Test failed: Device test 0 expect dmPelsHeight 480, got 0
=== debian11b (64 bit WoW report) ===
user32: input.c:3875: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 00000000008200EE, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032
On Mon Mar 25 12:55:42 2024 +0000, Anton Baskanov wrote:
changed this line in [version 8 of the diff](/wine/wine/-/merge_requests/5060/diffs?diff_id=107034&start_sha=55c702be7628aea383af0e6af3c2a2c22408dfdc#1a2fc38375b48458ba2fb34a2716bf76579d9527_1289_1287)
Done.
On Mon Mar 25 12:55:42 2024 +0000, Anton Baskanov wrote:
changed this line in [version 8 of the diff](/wine/wine/-/merge_requests/5060/diffs?diff_id=107034&start_sha=55c702be7628aea383af0e6af3c2a2c22408dfdc#1a2fc38375b48458ba2fb34a2716bf76579d9527_1262_1261)
Done.
v7: - Remove redundant mode check after the second process exit. - Remove repeated `dm` initialization.
Zhiyi Zhang (@zhiyi) commented about dlls/user32/tests/monitor.c:
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 */
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.
Zhiyi Zhang (@zhiyi) commented about dlls/win32u/sysparams.c:
free( displays ); if (ret) return ret;
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.
Also, there are some TestBot failures after this MR. Please see https://testbot.winehq.org/JobDetails.pl?Key=144370#k204