[PATCH 7/7] wined3d: Use WGL_WINE_fullscreen_exclusive extension.
Rémi Bernon
rbernon at codeweavers.com
Sat Mar 7 04:29:26 CST 2020
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 at 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
--
2.25.0
More information about the wine-devel
mailing list