[PATCH 5/5] dxgi/tests: Test detaching outputs.

Zhiyi Zhang zzhang at codeweavers.com
Tue Mar 24 02:52:54 CDT 2020


Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/dxgi/tests/dxgi.c | 160 ++++++++++++++++++++++++++++++++++++-----
 1 file changed, 141 insertions(+), 19 deletions(-)

diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c
index e2b5df7b27..cc49c7b2ae 100644
--- a/dlls/dxgi/tests/dxgi.c
+++ b/dlls/dxgi/tests/dxgi.c
@@ -4940,15 +4940,17 @@ static void test_multi_adapter(void)
 {
     unsigned int output_count = 0, expected_output_count = 0;
     unsigned int adapter_index, output_index, device_index;
+    DXGI_OUTPUT_DESC old_output_desc, output_desc;
     DISPLAY_DEVICEW display_device;
-    DXGI_OUTPUT_DESC output_desc;
     MONITORINFO monitor_info;
+    DEVMODEW old_mode, mode;
     IDXGIFactory *factory;
     IDXGIAdapter *adapter;
     IDXGIOutput *output;
     HMONITOR monitor;
     BOOL found;
     HRESULT hr;
+    LONG ret;
 
     if (FAILED(hr = CreateDXGIFactory(&IID_IDXGIFactory, (void **)&factory)))
     {
@@ -4973,7 +4975,8 @@ static void test_multi_adapter(void)
         for (output_index = 0; SUCCEEDED(IDXGIAdapter_EnumOutputs(adapter, output_index, &output)); ++output_index)
         {
             hr = IDXGIOutput_GetDesc(output, &output_desc);
-            ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+            ok(hr == S_OK, "Adapter %u output %u: Got unexpected hr %#x.\n", adapter_index,
+                    output_index, hr);
 
             found = FALSE;
             display_device.cb = sizeof(display_device);
@@ -4985,39 +4988,158 @@ static void test_multi_adapter(void)
                     break;
                 }
             }
-            ok(found, "Failed to find device %s for adapter %u, output %u.\n",
-                    wine_dbgstr_w(output_desc.DeviceName), adapter_index, output_index);
+            ok(found, "Adapter %u output %u: Failed to find device %s.\n",
+                    adapter_index, output_index, wine_dbgstr_w(output_desc.DeviceName));
 
             ok(display_device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP,
-                    "Got unexpected state flags %#x for adapter %u, output %u.\n",
-                    display_device.StateFlags, adapter_index, output_index);
+                    "Adapter %u output %u: Got unexpected state flags %#x.\n", adapter_index,
+                    output_index, display_device.StateFlags);
             if (!adapter_index && !output_index)
                 ok(display_device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE,
-                        "Got unexpected state flags %#x for adapter %u, output %u.\n",
-                        display_device.StateFlags, adapter_index, output_index);
+                        "Adapter %u output %u: Got unexpected state flags %#x.\n", adapter_index,
+                        output_index, display_device.StateFlags);
             else
                 ok(!(display_device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE),
-                        "Got unexpected state flags %#x for adapter %u, output %u.\n",
-                        display_device.StateFlags, adapter_index, output_index);
+                        "Adapter %u output %u: Got unexpected state flags %#x.\n", adapter_index,
+                        output_index, display_device.StateFlags);
 
             /* Should have the same monitor handle. */
             monitor = get_monitor(display_device.DeviceName);
-            ok(!!monitor, "Failed to find monitor %s.\n", wine_dbgstr_w(display_device.DeviceName));
-            ok(monitor == output_desc.Monitor, "Got unexpected monitor %p, expected %p.\n",
-                    monitor, output_desc.Monitor);
+            ok(!!monitor, "Adapter %u output %u: Failed to find monitor %s.\n", adapter_index,
+                    output_index, wine_dbgstr_w(display_device.DeviceName));
+            ok(monitor == output_desc.Monitor,
+                    "Adapter %u output %u: Got unexpected monitor %p, expected %p.\n",
+                    adapter_index, output_index, monitor, output_desc.Monitor);
 
             /* Should have the same monitor rectangle. */
             monitor_info.cbSize = sizeof(monitor_info);
             ok(GetMonitorInfoA(monitor, &monitor_info),
-                    "Failed to get monitor info for adapter %u, output %u, error %#x.\n",
-                    adapter_index, output_index, GetLastError());
+                    "Adapter %u output %u: Failed to get monitor info, error %#x.\n", adapter_index,
+                    output_index, GetLastError());
             ok(EqualRect(&monitor_info.rcMonitor, &output_desc.DesktopCoordinates),
-                    "Got unexpected output rect %s, expected %s for adapter %u, output %u.\n",
-                    wine_dbgstr_rect(&monitor_info.rcMonitor), wine_dbgstr_rect(&output_desc.DesktopCoordinates),
-                    adapter_index, output_index);
+                    "Adapter %u output %u: Got unexpected output rect %s, expected %s.\n",
+                    adapter_index, output_index, wine_dbgstr_rect(&monitor_info.rcMonitor),
+                    wine_dbgstr_rect(&output_desc.DesktopCoordinates));
+
+            ++output_count;
+
+            /* Test output description after it got detached */
+            if (display_device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
+            {
+                IDXGIOutput_Release(output);
+                continue;
+            }
+
+            old_output_desc = output_desc;
+
+            /* Save current display settings */
+            memset(&old_mode, 0, sizeof(old_mode));
+            old_mode.dmSize = sizeof(old_mode);
+            ret = EnumDisplaySettingsW(display_device.DeviceName, ENUM_CURRENT_SETTINGS, &old_mode);
+            /* Win10 TestBots may return FALSE but it's actually successful */
+            ok(ret || broken(!ret),
+                    "Adapter %u output %u: EnumDisplaySettingsW failed for %s, error %#x.\n",
+                    adapter_index, output_index, wine_dbgstr_w(display_device.DeviceName),
+                    GetLastError());
+
+            /* Detach */
+            memset(&mode, 0, sizeof(mode));
+            mode.dmSize = sizeof(mode);
+            mode.dmFields = DM_POSITION | DM_PELSWIDTH | DM_PELSHEIGHT;
+            mode.dmPosition = old_mode.dmPosition;
+            ret = ChangeDisplaySettingsExW(display_device.DeviceName, &mode, NULL,
+                    CDS_UPDATEREGISTRY | CDS_NORESET, NULL);
+            ok(ret == DISP_CHANGE_SUCCESSFUL,
+                    "Adapter %u output %u: ChangeDisplaySettingsExW %s returned unexpected %d.\n",
+                    adapter_index, output_index, wine_dbgstr_w(display_device.DeviceName), ret);
+            ret = ChangeDisplaySettingsExW(display_device.DeviceName, NULL, NULL, 0, NULL);
+            ok(ret == DISP_CHANGE_SUCCESSFUL,
+                    "Adapter %u output %u: ChangeDisplaySettingsExW %s returned unexpected %d.\n",
+                    adapter_index, output_index, wine_dbgstr_w(display_device.DeviceName), ret);
+
+            /* Check if it is really detached */
+            memset(&mode, 0, sizeof(mode));
+            mode.dmSize = sizeof(mode);
+            ret = EnumDisplaySettingsW(display_device.DeviceName, ENUM_CURRENT_SETTINGS, &mode);
+            /* Win10 TestBots may return FALSE but it's actually successful */
+            ok(ret || broken(!ret) ,
+                    "Adapter %u output %u: EnumDisplaySettingsW failed for %s, error %#x.\n",
+                    adapter_index, output_index, wine_dbgstr_w(display_device.DeviceName),
+                    GetLastError());
+            if (mode.dmPelsWidth && mode.dmPelsHeight)
+            {
+                skip("Adapter %u output %u: Failed to detach device %s.\n", adapter_index,
+                        output_index, wine_dbgstr_w(display_device.DeviceName));
+                IDXGIOutput_Release(output);
+                continue;
+            }
+
+            /* Only the AttachedToDesktop field is updated after an output is detached.
+             * IDXGIAdapter_EnumOutputs() has to be called again to get other fields updated.
+             * But resolution changes are reflected right away. This weird behaviour is currently
+             * unimplemented in Wine */
+            memset(&output_desc, 0, sizeof(output_desc));
+            hr = IDXGIOutput_GetDesc(output, &output_desc);
+            ok(hr == S_OK, "Adapter %u output %u: Got unexpected hr %#x.\n", adapter_index,
+                    output_index, hr);
+            ok(!lstrcmpiW(output_desc.DeviceName, old_output_desc.DeviceName),
+                    "Adapter %u output %u: Expect device name %s, got %s.\n", adapter_index,
+                    output_index, wine_dbgstr_w(old_output_desc.DeviceName),
+                    wine_dbgstr_w(output_desc.DeviceName));
+            todo_wine
+            ok(EqualRect(&output_desc.DesktopCoordinates, &old_output_desc.DesktopCoordinates),
+                    "Adapter %u output %u: Expect desktop coordinates %s, got %s.\n",
+                    adapter_index, output_index,
+                    wine_dbgstr_rect(&old_output_desc.DesktopCoordinates),
+                    wine_dbgstr_rect(&output_desc.DesktopCoordinates));
+            ok(!output_desc.AttachedToDesktop,
+                    "Adapter %u output %u: Expect output not attached to desktop.\n", adapter_index,
+                    output_index);
+            ok(output_desc.Rotation == old_output_desc.Rotation,
+                    "Adapter %u output %u: Expect rotation %#x, got %#x.\n", adapter_index,
+                    output_index, old_output_desc.Rotation, output_desc.Rotation);
+            todo_wine
+            ok(output_desc.Monitor == old_output_desc.Monitor,
+                    "Adapter %u output %u: Expect monitor %p, got %p.\n", adapter_index,
+                    output_index, old_output_desc.Monitor, output_desc.Monitor);
+            IDXGIOutput_Release(output);
+
+            /* Call IDXGIAdapter_EnumOutputs() again to get up-to-date output description */
+            hr = IDXGIAdapter_EnumOutputs(adapter, output_index, &output);
+            ok(hr == S_OK, "Adapter %u output %u: Got unexpected hr %#x.\n", adapter_index,
+                    output_index, hr);
+            memset(&output_desc, 0, sizeof(output_desc));
+            hr = IDXGIOutput_GetDesc(output, &output_desc);
+            ok(hr == S_OK, "Adapter %u output %u: Got unexpected hr %#x.\n", adapter_index,
+                    output_index, hr);
+            ok(!lstrcmpiW(output_desc.DeviceName, display_device.DeviceName),
+                    "Adapter %u output %u: Expect device name %s, got %s.\n", adapter_index,
+                    output_index, wine_dbgstr_w(display_device.DeviceName),
+                    wine_dbgstr_w(output_desc.DeviceName));
+            ok(IsRectEmpty(&output_desc.DesktopCoordinates),
+                    "Adapter %u output %u: Expect desktop rect empty, got %s.\n", adapter_index,
+                    output_index, wine_dbgstr_rect(&output_desc.DesktopCoordinates));
+            ok(!output_desc.AttachedToDesktop,
+                    "Adapter %u output %u: Expect output not attached to desktop.\n", adapter_index,
+                    output_index);
+            ok(output_desc.Rotation == DXGI_MODE_ROTATION_IDENTITY,
+                    "Adapter %u output %u: Expect rotation %#x, got %#x.\n", adapter_index,
+                    output_index, DXGI_MODE_ROTATION_IDENTITY, output_desc.Rotation);
+            ok(!output_desc.Monitor, "Adapter %u output %u: Expect monitor NULL.\n", adapter_index,
+                    output_index);
+
+            /* Restore settings */
+            ret = ChangeDisplaySettingsExW(display_device.DeviceName, &old_mode, NULL,
+                    CDS_UPDATEREGISTRY | CDS_NORESET, NULL);
+            ok(ret == DISP_CHANGE_SUCCESSFUL,
+                    "Adapter %u output %u: ChangeDisplaySettingsExW %s returned unexpected %d.\n",
+                    adapter_index, output_index, wine_dbgstr_w(display_device.DeviceName), ret);
+            ret = ChangeDisplaySettingsExW(display_device.DeviceName, NULL, NULL, 0, NULL);
+            ok(ret == DISP_CHANGE_SUCCESSFUL,
+                    "Adapter %u output %u: ChangeDisplaySettingsExW %s returned unexpected %d.\n",
+                    adapter_index, output_index, wine_dbgstr_w(display_device.DeviceName), ret);
 
             IDXGIOutput_Release(output);
-            ++output_count;
         }
 
         IDXGIAdapter_Release(adapter);
-- 
2.20.1



More information about the wine-devel mailing list