[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