[PATCH] dxgi: Fix SetFullscreenState return values after window is destroyed

Andrew Eikum aeikum at codeweavers.com
Mon Jun 17 09:26:55 CDT 2019


Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
---
 dlls/dxgi/swapchain.c    |  3 ++-
 dlls/dxgi/tests/dxgi.c   | 34 ++++++++++++++++++++++++++++++++++
 dlls/wined3d/swapchain.c | 24 ++++++++++++++++++------
 3 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c
index e09df4862d8..69db2c32ab6 100644
--- a/dlls/dxgi/swapchain.c
+++ b/dlls/dxgi/swapchain.c
@@ -397,7 +397,8 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d11_swapchain_SetFullscreen
 
     if (target)
         IDXGIOutput_Release(target);
-    return hr;
+
+    return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE;
 }
 
 static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetFullscreenState(IDXGISwapChain1 *iface,
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c
index 79e4bc0c15c..68e49ee6e5f 100644
--- a/dlls/dxgi/tests/dxgi.c
+++ b/dlls/dxgi/tests/dxgi.c
@@ -2282,6 +2282,40 @@ static void test_set_fullscreen(void)
     ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
 
     DestroyWindow(swapchain_desc.OutputWindow);
+    swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
+    check_window_fullscreen_state(swapchain_desc.OutputWindow, &initial_state.fullscreen_state);
+    hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain);
+    ok(SUCCEEDED(hr), "CreateSwapChain failed, hr %#x.\n", hr);
+    hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
+    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+    DestroyWindow(swapchain_desc.OutputWindow);
+    hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
+    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+    hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
+    ok(hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE, "Got unexpected hr %#x.\n", hr);
+    hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
+    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+    refcount = IDXGISwapChain_Release(swapchain);
+    ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
+
+    swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
+    check_window_fullscreen_state(swapchain_desc.OutputWindow, &initial_state.fullscreen_state);
+    hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain);
+    ok(SUCCEEDED(hr), "CreateSwapChain failed, hr %#x.\n", hr);
+    hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
+    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+    DestroyWindow(swapchain_desc.OutputWindow);
+    hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
+    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+    hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
+    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+    hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
+    ok(hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE, "Got unexpected hr %#x.\n", hr);
+    hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
+    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+    refcount = IDXGISwapChain_Release(swapchain);
+    ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
+
     swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
     check_window_fullscreen_state(swapchain_desc.OutputWindow, &initial_state.fullscreen_state);
     swapchain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index dd9ec123c20..24a8c0ce527 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -1475,6 +1475,10 @@ HRESULT CDECL wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapcha
         {
             /* Switch from windowed to fullscreen */
             HWND focus_window = device->create_parms.focus_window;
+
+            if (!IsWindow(swapchain->device_window))
+                return WINED3DERR_NOTAVAILABLE;
+
             if (!focus_window)
                 focus_window = swapchain->device_window;
             if (FAILED(hr = wined3d_device_acquire_focus_window(device, focus_window)))
@@ -1485,10 +1489,15 @@ HRESULT CDECL wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapcha
 
             wined3d_device_setup_fullscreen_window(device, swapchain->device_window, width, height);
         }
-        else
+        else if (swapchain->d3d_mode.width != width ||
+                swapchain->d3d_mode.height != height)
         {
             /* Fullscreen -> fullscreen mode change */
             BOOL filter_messages = device->filter_messages;
+
+            if (!IsWindow(swapchain->device_window))
+                return WINED3DERR_NOTAVAILABLE;
+
             device->filter_messages = TRUE;
 
             MoveWindow(swapchain->device_window, 0, 0, width, height, TRUE);
@@ -1501,11 +1510,14 @@ HRESULT CDECL wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapcha
     else if (!swapchain->desc.windowed)
     {
         /* Fullscreen -> windowed switch */
-        RECT *window_rect = NULL;
-        if (swapchain->desc.flags & WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT)
-            window_rect = &swapchain->original_window_rect;
-        wined3d_device_restore_fullscreen_window(device, swapchain->device_window, window_rect);
-        wined3d_device_release_focus_window(device);
+        if (IsWindow(swapchain->device_window))
+        {
+            RECT *window_rect = NULL;
+            if (swapchain->desc.flags & WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT)
+                window_rect = &swapchain->original_window_rect;
+            wined3d_device_restore_fullscreen_window(device, swapchain->device_window, window_rect);
+            wined3d_device_release_focus_window(device);
+        }
     }
 
     swapchain->desc.windowed = swapchain_desc->windowed;
-- 
2.22.0




More information about the wine-devel mailing list