This replaces the legacy behavior involving window style manipulation.
If the swapchain is not a wined3d swapchain, or if the extension is not available it will fallback to the legacy implementation.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/d3d8/tests/device.c | 10 ++--- dlls/d3d9/tests/d3d9ex.c | 14 +++--- dlls/d3d9/tests/device.c | 14 +++--- dlls/wined3d/adapter_gl.c | 2 + dlls/wined3d/swapchain.c | 78 ++++++++++++++++++++++++++++++++++ dlls/wined3d/wined3d_gl.h | 1 + dlls/wined3d/wined3d_private.h | 2 + 7 files changed, 106 insertions(+), 15 deletions(-)
diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c index 008395df1a6..533bae42d12 100644 --- a/dlls/d3d8/tests/device.c +++ b/dlls/d3d8/tests/device.c @@ -3784,12 +3784,12 @@ static void test_window_style(void)
style = GetWindowLongA(device_window, GWL_STYLE); expected_style = device_style | WS_VISIBLE; - todo_wine ok(style == expected_style || broken(style == (expected_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */, + ok(style == expected_style || broken(style == (expected_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */, "Expected device window style %#x, got %#x.\n", expected_style, style); style = GetWindowLongA(device_window, GWL_EXSTYLE); expected_style = device_exstyle | WS_EX_TOPMOST; - todo_wine ok(style == expected_style || broken(style == (expected_style & ~WS_EX_OVERLAPPEDWINDOW)) /* w1064v1809 */, + ok(style == expected_style || broken(style == (expected_style & ~WS_EX_OVERLAPPEDWINDOW)) /* w1064v1809 */, "Expected device window extended style %#x, got %#x.\n", expected_style, style);
@@ -3804,7 +3804,7 @@ static void test_window_style(void) ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s.\n", wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r)); GetClientRect(device_window, &r); - todo_wine ok(!EqualRect(&r, &fullscreen_rect) || broken(!(style & WS_THICKFRAME)) /* w1064v1809 */, + ok(!EqualRect(&r, &fullscreen_rect) || broken(!(style & WS_THICKFRAME)) /* w1064v1809 */, "Client rect and window rect are equal.\n"); GetWindowRect(focus_window, &r); ok(EqualRect(&r, &focus_rect), "Expected %s, got %s.\n", wine_dbgstr_rect(&focus_rect), @@ -3838,11 +3838,11 @@ static void test_window_style(void)
style = GetWindowLongA(device_window, GWL_STYLE); expected_style = device_style | WS_MINIMIZE | WS_VISIBLE; - todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x.\n", + ok(style == expected_style, "Expected device window style %#x, got %#x.\n", expected_style, style); style = GetWindowLongA(device_window, GWL_EXSTYLE); expected_style = device_exstyle | WS_EX_TOPMOST; - todo_wine ok(style == expected_style, "Expected device window extended style %#x, got %#x.\n", + ok(style == expected_style, "Expected device window extended style %#x, got %#x.\n", expected_style, style);
style = GetWindowLongA(focus_window, GWL_STYLE); diff --git a/dlls/d3d9/tests/d3d9ex.c b/dlls/d3d9/tests/d3d9ex.c index 17dd3c5c12e..a47ec8ef917 100644 --- a/dlls/d3d9/tests/d3d9ex.c +++ b/dlls/d3d9/tests/d3d9ex.c @@ -3515,7 +3515,8 @@ static void test_window_style(void)
style = GetWindowLongA(device_window, GWL_STYLE); expected_style = device_style; - todo_wine ok(style == expected_style || broken(style == (expected_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */, + todo_wine_if (!(tests[i].style_flags & WS_VISIBLE)) + ok(style == expected_style || broken(style == (expected_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */, "Expected device window style %#x, got %#x, i=%u.\n", expected_style, style, i); style = GetWindowLongA(device_window, GWL_EXSTYLE); @@ -3539,7 +3540,7 @@ static void test_window_style(void) ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s, i=%u.\n", wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r), i); GetClientRect(device_window, &r2); - todo_wine ok(!EqualRect(&r, &r2) || broken(!(style & WS_THICKFRAME)) /* w1064v1809 */, + ok(!EqualRect(&r, &r2) || broken(!(style & WS_THICKFRAME)) /* w1064v1809 */, "Client rect and window rect are equal, i=%u.\n", i); GetWindowRect(focus_window, &r); ok(EqualRect(&r, &focus_rect), "Expected %s, got %s, i=%u.\n", @@ -3593,12 +3594,14 @@ static void test_window_style(void) ok(!!device, "Failed to create a D3D device.\n"); style = GetWindowLongA(device_window, GWL_STYLE); expected_style = device_style | tests[i].create2_style; - todo_wine ok(style == expected_style || broken(style == (expected_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */, + todo_wine_if ((tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES) && !(tests[i].style_flags & WS_VISIBLE)) + ok(style == expected_style || broken(style == (expected_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */, "Expected device window style %#x, got %#x, i=%u.\n", expected_style, style, i); style = GetWindowLongA(device_window, GWL_EXSTYLE); expected_style = device_exstyle | tests[i].create2_exstyle; - todo_wine ok(style == expected_style || broken(style == (expected_style & ~WS_EX_OVERLAPPEDWINDOW)) /* w1064v1809 */, + todo_wine_if ((tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES)) + ok(style == expected_style || broken(style == (expected_style & ~WS_EX_OVERLAPPEDWINDOW)) /* w1064v1809 */, "Expected device window extended style %#x, got %#x, i=%u.\n", expected_style, style, i);
@@ -3626,7 +3629,8 @@ static void test_window_style(void)
style = GetWindowLongA(device_window, GWL_STYLE); expected_style = device_style | tests[i].focus_loss_style; - todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n", + todo_wine_if (!(tests[i].style_flags & WS_VISIBLE)) + ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n", expected_style, style, i); style = GetWindowLongA(device_window, GWL_EXSTYLE); expected_style = device_exstyle; diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index d00a26b942c..5ce763f2494 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -4859,12 +4859,14 @@ static void test_window_style(void)
style = GetWindowLongA(device_window, GWL_STYLE); expected_style = device_style | tests[i].style; - todo_wine ok(style == expected_style || broken(style == (expected_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */, + todo_wine_if (tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES) + ok(style == expected_style || broken(style == (expected_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */, "Expected device window style %#x, got %#x, i=%u.\n", expected_style, style, i); style = GetWindowLongA(device_window, GWL_EXSTYLE); expected_style = device_exstyle | tests[i].exstyle; - todo_wine ok(style == expected_style || broken(style == (expected_style & ~WS_EX_OVERLAPPEDWINDOW)) /* w1064v1809 */, + todo_wine_if (tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES) + ok(style == expected_style || broken(style == (expected_style & ~WS_EX_OVERLAPPEDWINDOW)) /* w1064v1809 */, "Expected device window extended style %#x, got %#x, i=%u.\n", expected_style, style, i);
@@ -4883,7 +4885,7 @@ static void test_window_style(void) ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s, i=%u.\n", wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r), i); GetClientRect(device_window, &r2); - todo_wine ok(!EqualRect(&r, &r2) || broken(!(style & WS_THICKFRAME)) /* w1064v1809 */, + ok(!EqualRect(&r, &r2) || broken(!(style & WS_THICKFRAME)) /* w1064v1809 */, "Client rect and window rect are equal, i=%u.\n", i); GetWindowRect(focus_window, &r); ok(EqualRect(&r, &focus_rect), "Expected %s, got %s, i=%u.\n", @@ -4919,11 +4921,13 @@ static void test_window_style(void)
style = GetWindowLongA(device_window, GWL_STYLE); expected_style = device_style | tests[i].focus_loss_style | tests[i].style; - todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n", + todo_wine_if (tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES) + ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n", expected_style, style, i); style = GetWindowLongA(device_window, GWL_EXSTYLE); expected_style = device_exstyle | tests[i].exstyle; - todo_wine ok(style == expected_style, "Expected device window extended style %#x, got %#x, i=%u.\n", + todo_wine_if (tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES) + ok(style == expected_style, "Expected device window extended style %#x, got %#x, i=%u.\n", expected_style, style, i);
style = GetWindowLongA(focus_window, GWL_STYLE); diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c index 3ad64754ec6..38660aeeaa2 100644 --- a/dlls/wined3d/adapter_gl.c +++ b/dlls/wined3d/adapter_gl.c @@ -236,6 +236,7 @@ static const struct wined3d_extension_map wgl_extension_map[] = { {"WGL_ARB_pixel_format", WGL_ARB_PIXEL_FORMAT }, {"WGL_EXT_swap_control", WGL_EXT_SWAP_CONTROL }, + {"WGL_WINE_fullscreen_exclusive", WGL_WINE_FULLSCREEN_EXCLUSIVE }, {"WGL_WINE_pixel_format_passthrough", WGL_WINE_PIXEL_FORMAT_PASSTHROUGH}, {"WGL_WINE_query_renderer", WGL_WINE_QUERY_RENDERER }, }; @@ -2663,6 +2664,7 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) USE_GL_FUNC(wglQueryCurrentRendererStringWINE) USE_GL_FUNC(wglQueryRendererIntegerWINE) USE_GL_FUNC(wglQueryRendererStringWINE) + USE_GL_FUNC(wglSetFullscreenExclusiveWINE) USE_GL_FUNC(wglSetPixelFormatWINE) USE_GL_FUNC(wglSwapIntervalEXT)
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 4b2c42b5bc4..2996a0ffbed 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -652,10 +652,73 @@ static void swapchain_frontbuffer_updated(struct wined3d_swapchain *swapchain) SetRectEmpty(&swapchain->front_buffer_update); }
+static BOOL swapchain_gl_set_fullscreen_exclusive(struct wined3d_swapchain *swapchain, + BOOL fullscreen_exclusive, HWND window, const RECT *window_rect) +{ + const struct wined3d_output *output; + const struct wined3d_gl_info *gl_info; + DWORD window_pos_flags = SWP_FRAMECHANGED | SWP_NOACTIVATE; + HWND window_pos_after = 0; + BOOL filter; + RECT rect = {0}; + + TRACE("swapchain %p fullscreen %d window %p rect %s\n", + swapchain, fullscreen_exclusive, window, wine_dbgstr_rect(window_rect)); + + if (!(output = get_output_from_window(swapchain->device->wined3d, window)) || + !output->adapter) + { + WARN("Failed to %s fullscreen exclusive for window %p, unable to find output.\n", + fullscreen_exclusive ? "set" : "unset", window); + return FALSE; + } + + gl_info = &output->adapter->gl_info; + if (!gl_info->supported[WGL_WINE_FULLSCREEN_EXCLUSIVE]) + { + WARN("Failed to %s fullscreen exclusive for window %p," + "WGL_WINE_fullscreen_exclusive extension is not supported.\n", + fullscreen_exclusive ? "set" : "unset", window); + return FALSE; + } + + if (!GL_EXTCALL(wglSetFullscreenExclusiveWINE(window, fullscreen_exclusive))) + { + WARN("Failed to %s fullscreen exclusive for window %p, last error %#x.\n", + fullscreen_exclusive ? "set" : "unset", window, GetLastError()); + return FALSE; + } + + if (fullscreen_exclusive) + { + window_pos_after = HWND_TOPMOST; + window_pos_flags |= SWP_SHOWWINDOW; + } + else + { + window_pos_after = 0; + window_pos_flags |= SWP_NOZORDER; + } + + if (window_rect) + rect = *window_rect; + else + window_pos_flags |= (SWP_NOMOVE | SWP_NOSIZE); + + filter = wined3d_filter_messages(window, TRUE); + SetWindowPos(window, window_pos_after, rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, window_pos_flags); + wined3d_filter_messages(window, filter); + + swapchain->state.fullscreen_exclusive = fullscreen_exclusive; + return TRUE; +} + static const struct wined3d_swapchain_ops swapchain_gl_ops = { swapchain_gl_present, swapchain_frontbuffer_updated, + swapchain_gl_set_fullscreen_exclusive, };
static void swapchain_vk_present(struct wined3d_swapchain *swapchain, const RECT *src_rect, @@ -664,10 +727,18 @@ static void swapchain_vk_present(struct wined3d_swapchain *swapchain, const RECT FIXME("Not implemented.\n"); }
+static BOOL swapchain_vk_set_fullscreen_exclusive(struct wined3d_swapchain *swapchain, + BOOL fullscreen_exclusive, HWND window, const RECT *window_rect) +{ + FIXME("Not implemented.\n"); + return FALSE; +} + static const struct wined3d_swapchain_ops swapchain_vk_ops = { swapchain_vk_present, swapchain_frontbuffer_updated, + swapchain_vk_set_fullscreen_exclusive, };
static void swapchain_gdi_frontbuffer_updated(struct wined3d_swapchain *swapchain) @@ -1543,6 +1614,7 @@ HRESULT wined3d_swapchain_state_setup_fullscreen(struct wined3d_swapchain_state { LONG style, exstyle; BOOL filter; + RECT rect = {0, 0, w, h};
TRACE("Setting up window %p for fullscreen mode.\n", window);
@@ -1552,6 +1624,9 @@ HRESULT wined3d_swapchain_state_setup_fullscreen(struct wined3d_swapchain_state return WINED3DERR_NOTAVAILABLE; }
+ if (swapchain && swapchain->swapchain_ops->swapchain_set_fullscreen_exclusive(swapchain, TRUE, window, &rect)) + return WINED3D_OK; + if (state->style || state->exstyle) { ERR("Changing the window style for window %p, but another style (%08x, %08x) is already stored.\n", @@ -1586,6 +1661,9 @@ void wined3d_swapchain_state_restore_from_fullscreen(struct wined3d_swapchain_st RECT rect = {0}; BOOL filter;
+ if (swapchain && swapchain->swapchain_ops->swapchain_set_fullscreen_exclusive(swapchain, FALSE, window, window_rect)) + return; + if (!state->style && !state->exstyle) return;
diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h index 3372b4b6be3..6761c4d8387 100644 --- a/dlls/wined3d/wined3d_gl.h +++ b/dlls/wined3d/wined3d_gl.h @@ -209,6 +209,7 @@ enum wined3d_gl_extension /* WGL extensions */ WGL_ARB_PIXEL_FORMAT, WGL_EXT_SWAP_CONTROL, + WGL_WINE_FULLSCREEN_EXCLUSIVE, WGL_WINE_PIXEL_FORMAT_PASSTHROUGH, WGL_WINE_QUERY_RENDERER, /* Internally used */ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 3edfe17c87b..837dcd9a9e0 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4460,6 +4460,8 @@ struct wined3d_swapchain_ops void (*swapchain_present)(struct wined3d_swapchain *swapchain, const RECT *src_rect, const RECT *dst_rect, unsigned int swap_interval, DWORD flags); void (*swapchain_frontbuffer_updated)(struct wined3d_swapchain *swapchain); + BOOL (*swapchain_set_fullscreen_exclusive)(struct wined3d_swapchain *swapchain, BOOL fullscreen_exclusive, + HWND window, const RECT *window_rect); };
struct wined3d_swapchain