Signed-off-by: Andrew Eikum aeikum@codeweavers.com --- The main point here is that calling SetFullscreenState with the state that is already set succeeds, even if the window is destroyed. Unreal Engine 4 games depend on this, and Wine already passes this test.
The code changes are for the failure case, when trying to change the state on a destroyed window. I don't have a game that depends on this, so if you'd prefer a todo_wine and no code changes, I'm fine with that, too.
v2: Fix problems spotted by Józef
dlls/dxgi/swapchain.c | 2 ++ dlls/dxgi/tests/dxgi.c | 6 +++++- dlls/wined3d/swapchain.c | 12 ++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 83e0f25674..ac40eb78f6 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -254,6 +254,8 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d11_swapchain_SetFullscreen swapchain->target = target; return S_OK; } + else + hr = DXGI_ERROR_NOT_CURRENTLY_AVAILABLE;
if (target) IDXGIOutput_Release(target); diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 56065456eb..fc008ccdd7 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -2162,10 +2162,14 @@ static void test_set_fullscreen(void) } 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); refcount = IDXGISwapChain_Release(swapchain); 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); diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 8200bdd5e0..dc7bb641b3 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -1400,6 +1400,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))) @@ -1414,6 +1418,10 @@ HRESULT CDECL wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapcha { /* 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); @@ -1427,6 +1435,10 @@ HRESULT CDECL wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapcha { /* Fullscreen -> windowed switch */ RECT *window_rect = NULL; + + if (!IsWindow(swapchain->device_window)) + return WINED3DERR_NOTAVAILABLE; + 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);