Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/dxgi/swapchain.c | 21 ++++++++++++++++++++- dlls/dxgi/tests/dxgi.c | 4 ++-- dlls/wined3d/swapchain.c | 4 ++++ dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_main.c | 6 +++++- dlls/wined3d/wined3d_private.h | 3 +++ include/wine/wined3d.h | 8 +++++++- 7 files changed, 42 insertions(+), 6 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 9d6ec0246ce..aa889bbe236 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -807,6 +807,24 @@ static const struct wined3d_parent_ops d3d11_swapchain_wined3d_parent_ops = d3d11_swapchain_wined3d_object_released, };
+static void STDMETHODCALLTYPE d3d11_swapchain_windowed_state_changed(void *parent, BOOL windowed) +{ + struct d3d11_swapchain *swapchain = parent; + + TRACE("parent %p, windowed %d.\n", parent, windowed); + + if (windowed && swapchain->target) + { + IDXGIOutput_Release(swapchain->target); + swapchain->target = NULL; + } +} + +static const struct wined3d_swapchain_state_parent_ops d3d11_swapchain_state_parent_ops = +{ + d3d11_swapchain_windowed_state_changed, +}; + HRESULT d3d11_swapchain_init(struct d3d11_swapchain *swapchain, struct dxgi_device *device, struct wined3d_swapchain_desc *desc) { @@ -855,7 +873,8 @@ HRESULT d3d11_swapchain_init(struct d3d11_swapchain *swapchain, struct dxgi_devi
swapchain->state = wined3d_swapchain_get_state(swapchain->wined3d_swapchain); wined3d = wined3d_device_get_wined3d(device->wined3d_device); - wined3d_swapchain_state_register(swapchain->state, wined3d); + wined3d_swapchain_state_register(swapchain->state, wined3d, swapchain, + &d3d11_swapchain_state_parent_ops);
swapchain->target = NULL; if (fullscreen) diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index f747e236f31..5830426f756 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -2453,7 +2453,7 @@ static void test_get_containing_output(IUnknown *device, BOOL is_d3d12) ok(hr == S_OK, "GetDesc failed, hr %#x.\n", hr); hr = IDXGIOutput_GetDesc(output2, &output_desc2); ok(hr == S_OK, "GetDesc failed, hr %#x.\n", hr); - todo_wine ok(!lstrcmpW(output_desc.DeviceName, output_desc2.DeviceName), + todo_wine_if(is_d3d12) ok(!lstrcmpW(output_desc.DeviceName, output_desc2.DeviceName), "Expect device name %s, got %s.\n", wine_dbgstr_w(output_desc2.DeviceName), wine_dbgstr_w(output_desc.DeviceName)); IDXGIOutput_Release(output); @@ -2465,7 +2465,7 @@ static void test_get_containing_output(IUnknown *device, BOOL is_d3d12) ok(hr == S_OK, "GetDesc failed, hr %#x.\n", hr); hr = IDXGIOutput_GetDesc(output2, &output_desc2); ok(hr == S_OK, "GetDesc failed, hr %#x.\n", hr); - todo_wine ok(!lstrcmpW(output_desc.DeviceName, output_desc2.DeviceName), + todo_wine_if(is_d3d12) ok(!lstrcmpW(output_desc.DeviceName, output_desc2.DeviceName), "Expect device name %s, got %s.\n", wine_dbgstr_w(output_desc2.DeviceName), wine_dbgstr_w(output_desc.DeviceName));
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 2cf36d189cb..a36946cc620 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -2171,6 +2171,7 @@ HRESULT CDECL wined3d_swapchain_state_set_fullscreen(struct wined3d_swapchain_st { struct wined3d_display_mode actual_mode; struct wined3d_output_desc output_desc; + BOOL windowed = state->desc.windowed; HRESULT hr;
TRACE("state %p, swapchain_desc %p, mode %p.\n", state, swapchain_desc, mode); @@ -2259,6 +2260,9 @@ HRESULT CDECL wined3d_swapchain_state_set_fullscreen(struct wined3d_swapchain_st state->desc.output = swapchain_desc->output; state->desc.windowed = swapchain_desc->windowed;
+ if (state->parent_ops && windowed != state->desc.windowed) + state->parent_ops->windowed_state_changed(state->parent, state->desc.windowed); + return WINED3D_OK; }
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 816108e8b3b..4c42b0854e1 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -292,7 +292,7 @@ @ cdecl wined3d_swapchain_state_create(ptr ptr ptr) @ cdecl wined3d_swapchain_state_destroy(ptr) @ cdecl wined3d_swapchain_state_is_windowed(ptr) -@ cdecl wined3d_swapchain_state_register(ptr ptr) +@ cdecl wined3d_swapchain_state_register(ptr ptr ptr ptr) @ cdecl wined3d_swapchain_state_resize_target(ptr ptr) @ cdecl wined3d_swapchain_state_set_fullscreen(ptr ptr ptr) @ cdecl wined3d_swapchain_state_unregister(ptr) diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c index bb3ad7ffa51..09d741ac87f 100644 --- a/dlls/wined3d/wined3d_main.c +++ b/dlls/wined3d/wined3d_main.c @@ -775,7 +775,8 @@ static struct wined3d_window_hook *wined3d_find_hook(DWORD thread_id) }
void CDECL wined3d_swapchain_state_register(struct wined3d_swapchain_state *state, - struct wined3d *wined3d) + struct wined3d *wined3d, void *parent, + const struct wined3d_swapchain_state_parent_ops *parent_ops) { struct wined3d_registered_swapchain_state *state_entry; struct wined3d_window_hook *hook; @@ -789,6 +790,9 @@ void CDECL wined3d_swapchain_state_register(struct wined3d_swapchain_state *stat return; }
+ state->parent = parent; + state->parent_ops = parent_ops; + state_entry = &swapchain_state_table.states[swapchain_state_table.state_count++]; state_entry->state = state; state_entry->wined3d = wined3d; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 7c88e04f5e7..0d14f1e2860 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -5062,6 +5062,9 @@ struct wined3d_swapchain_state LONG style; LONG exstyle; HWND device_window; + + void *parent; + const struct wined3d_swapchain_state_parent_ops *parent_ops; };
void wined3d_swapchain_state_restore_from_fullscreen(struct wined3d_swapchain_state *state, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 3f2361e55a5..9d2d37c4856 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2208,6 +2208,11 @@ struct wined3d_parent_ops void (__stdcall *wined3d_object_destroyed)(void *parent); };
+struct wined3d_swapchain_state_parent_ops +{ + void (__stdcall *windowed_state_changed)(void *parent, BOOL windowed); +}; + struct wined3d; struct wined3d_adapter; struct wined3d_blend_state; @@ -2807,7 +2812,8 @@ HRESULT __cdecl wined3d_swapchain_state_create(const struct wined3d_swapchain_de void __cdecl wined3d_swapchain_state_destroy(struct wined3d_swapchain_state *state); BOOL __cdecl wined3d_swapchain_state_is_windowed(const struct wined3d_swapchain_state *state); void __cdecl wined3d_swapchain_state_register(struct wined3d_swapchain_state *state, - struct wined3d *wined3d); + struct wined3d *wined3d, void *context, + const struct wined3d_swapchain_state_parent_ops *parent_ops); HRESULT __cdecl wined3d_swapchain_state_resize_target(struct wined3d_swapchain_state *state, const struct wined3d_display_mode *mode); HRESULT __cdecl wined3d_swapchain_state_set_fullscreen(struct wined3d_swapchain_state *state,
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=79956
Your paranoid android.
=== w1064v1507 (32 bit report) ===
dxgi: dxgi.c:5617: Test failed: Got unexpected message 0x31f, hwnd 000301D8, wparam 0x1, lparam 0.