[PATCH 4/5] wined3d: Track windows styles per-swapchain.

Henri Verbeet hverbeet at codeweavers.com
Mon Jul 29 06:30:54 CDT 2019


From: Conor McCarthy <cmccarthy at codeweavers.com>

Instead of per-device.

Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
This supersedes patch 167242.

 dlls/wined3d/device.c          | 134 ++++-------------------------------------
 dlls/wined3d/swapchain.c       | 122 +++++++++++++++++++++++++++++++++++--
 dlls/wined3d/wined3d_private.h |  21 ++++---
 3 files changed, 141 insertions(+), 136 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 71242bba111..8502b967905 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -910,115 +910,6 @@ static void destroy_default_samplers(struct wined3d_device *device, struct wined
     device->null_sampler = NULL;
 }
 
-static LONG fullscreen_style(LONG style)
-{
-    /* Make sure the window is managed, otherwise we won't get keyboard input. */
-    style |= WS_POPUP | WS_SYSMENU;
-    style &= ~(WS_CAPTION | WS_THICKFRAME);
-
-    return style;
-}
-
-static LONG fullscreen_exstyle(LONG exstyle)
-{
-    /* Filter out window decorations. */
-    exstyle &= ~(WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE);
-
-    return exstyle;
-}
-
-HRESULT wined3d_device_setup_fullscreen_window(struct wined3d_device *device,
-        HWND window, unsigned int w, unsigned int h)
-{
-    LONG style, exstyle;
-    BOOL filter;
-
-    TRACE("Setting up window %p for fullscreen mode.\n", window);
-
-    if (!IsWindow(window))
-    {
-        WARN("%p is not a valid window.\n", window);
-        return WINED3DERR_NOTAVAILABLE;
-    }
-
-    if (device->style || device->exStyle)
-    {
-        ERR("Changing the window style for window %p, but another style (%08x, %08x) is already stored.\n",
-                window, device->style, device->exStyle);
-    }
-
-    device->style = GetWindowLongW(window, GWL_STYLE);
-    device->exStyle = GetWindowLongW(window, GWL_EXSTYLE);
-
-    style = fullscreen_style(device->style);
-    exstyle = fullscreen_exstyle(device->exStyle);
-
-    TRACE("Old style was %08x, %08x, setting to %08x, %08x.\n",
-            device->style, device->exStyle, style, exstyle);
-
-    filter = wined3d_filter_messages(window, TRUE);
-
-    SetWindowLongW(window, GWL_STYLE, style);
-    SetWindowLongW(window, GWL_EXSTYLE, exstyle);
-    SetWindowPos(window, HWND_TOPMOST, 0, 0, w, h, SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE);
-
-    wined3d_filter_messages(window, filter);
-
-    return WINED3D_OK;
-}
-
-void wined3d_device_restore_fullscreen_window(struct wined3d_device *device,
-        HWND window, const RECT *window_rect)
-{
-    unsigned int window_pos_flags = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE;
-    LONG style, exstyle;
-    RECT rect = {0};
-    BOOL filter;
-
-    if (!device->style && !device->exStyle)
-        return;
-
-    style = GetWindowLongW(window, GWL_STYLE);
-    exstyle = GetWindowLongW(window, GWL_EXSTYLE);
-
-    /* These flags are set by wined3d_device_setup_fullscreen_window, not the
-     * application, and we want to ignore them in the test below, since it's
-     * not the application's fault that they changed. Additionally, we want to
-     * preserve the current status of these flags (i.e. don't restore them) to
-     * more closely emulate the behavior of Direct3D, which leaves these flags
-     * alone when returning to windowed mode. */
-    device->style ^= (device->style ^ style) & WS_VISIBLE;
-    device->exStyle ^= (device->exStyle ^ exstyle) & WS_EX_TOPMOST;
-
-    TRACE("Restoring window style of window %p to %08x, %08x.\n",
-            window, device->style, device->exStyle);
-
-    filter = wined3d_filter_messages(window, TRUE);
-
-    /* Only restore the style if the application didn't modify it during the
-     * fullscreen phase. Some applications change it before calling Reset()
-     * when switching between windowed and fullscreen modes (HL2), some
-     * depend on the original style (Eve Online). */
-    if (style == fullscreen_style(device->style) && exstyle == fullscreen_exstyle(device->exStyle))
-    {
-        SetWindowLongW(window, GWL_STYLE, device->style);
-        SetWindowLongW(window, GWL_EXSTYLE, device->exStyle);
-    }
-
-    if (window_rect)
-        rect = *window_rect;
-    else
-        window_pos_flags |= (SWP_NOMOVE | SWP_NOSIZE);
-    SetWindowPos(window, 0, rect.left, rect.top,
-            rect.right - rect.left, rect.bottom - rect.top, window_pos_flags);
-
-    wined3d_filter_messages(window, filter);
-
-    /* Delete the old values. */
-    device->style = 0;
-    device->exStyle = 0;
-}
-
 HRESULT CDECL wined3d_device_acquire_focus_window(struct wined3d_device *device, HWND window)
 {
     TRACE("device %p, window %p.\n", device, window);
@@ -5543,19 +5434,18 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
     }
     else if (!swapchain_desc->windowed)
     {
-        DWORD style = device->style;
-        DWORD exStyle = device->exStyle;
-        /* If we're in fullscreen, and the mode wasn't changed, we have to get the window back into
-         * the right position. Some applications(Battlefield 2, Guild Wars) move it and then call
-         * Reset to clear up their mess. Guild Wars also loses the device during that.
-         */
-        device->style = 0;
-        device->exStyle = 0;
-        wined3d_device_setup_fullscreen_window(device, swapchain->device_window,
-                swapchain_desc->backbuffer_width,
-                swapchain_desc->backbuffer_height);
-        device->style = style;
-        device->exStyle = exStyle;
+        DWORD style = swapchain->state.style;
+        DWORD exstyle = swapchain->state.exstyle;
+        /* If we're in fullscreen, and the mode wasn't changed, we have to get
+         * the window back into the right position. Some applications
+         * (Battlefield 2, Guild Wars) move it and then call Reset() to clean
+         * up their mess. Guild Wars also loses the device during that. */
+        swapchain->state.style = 0;
+        swapchain->state.exstyle = 0;
+        wined3d_swapchain_state_setup_fullscreen(&swapchain->state, swapchain->device_window,
+                swapchain_desc->backbuffer_width, swapchain_desc->backbuffer_height);
+        swapchain->state.style = style;
+        swapchain->state.exstyle = exstyle;
     }
 
     if (FAILED(hr = wined3d_swapchain_resize_buffers(swapchain, swapchain_desc->backbuffer_count,
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index c5db2e919eb..10363e007a8 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -85,14 +85,14 @@ static void swapchain_cleanup(struct wined3d_swapchain *swapchain)
 
             if (swapchain->desc.flags & WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT)
             {
-                wined3d_device_restore_fullscreen_window(swapchain->device, swapchain->device_window,
-                        &swapchain->original_window_rect);
+                wined3d_window_state_restore_from_fullscreen(&swapchain->state,
+                        swapchain->device_window, &swapchain->original_window_rect);
                 wined3d_device_release_focus_window(swapchain->device);
             }
         }
         else
         {
-            wined3d_device_restore_fullscreen_window(swapchain->device, swapchain->device_window, NULL);
+            wined3d_window_state_restore_from_fullscreen(&swapchain->state, swapchain->device_window, NULL);
         }
     }
 
@@ -811,7 +811,8 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
     }
     else
     {
-        wined3d_device_setup_fullscreen_window(device, window, desc->backbuffer_width, desc->backbuffer_height);
+        wined3d_swapchain_state_setup_fullscreen(&swapchain->state,
+                window, desc->backbuffer_width, desc->backbuffer_height);
     }
     swapchain->desc = *desc;
     wined3d_swapchain_apply_sample_count_override(swapchain, swapchain->desc.backbuffer_format,
@@ -1390,6 +1391,115 @@ HRESULT CDECL wined3d_swapchain_resize_target(struct wined3d_swapchain *swapchai
     return WINED3D_OK;
 }
 
+static LONG fullscreen_style(LONG style)
+{
+    /* Make sure the window is managed, otherwise we won't get keyboard input. */
+    style |= WS_POPUP | WS_SYSMENU;
+    style &= ~(WS_CAPTION | WS_THICKFRAME);
+
+    return style;
+}
+
+static LONG fullscreen_exstyle(LONG exstyle)
+{
+    /* Filter out window decorations. */
+    exstyle &= ~(WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE);
+
+    return exstyle;
+}
+
+HRESULT wined3d_swapchain_state_setup_fullscreen(struct wined3d_swapchain_state *state,
+        HWND window, unsigned int w, unsigned int h)
+{
+    LONG style, exstyle;
+    BOOL filter;
+
+    TRACE("Setting up window %p for fullscreen mode.\n", window);
+
+    if (!IsWindow(window))
+    {
+        WARN("%p is not a valid window.\n", window);
+        return WINED3DERR_NOTAVAILABLE;
+    }
+
+    if (state->style || state->exstyle)
+    {
+        ERR("Changing the window style for window %p, but another style (%08x, %08x) is already stored.\n",
+                window, state->style, state->exstyle);
+    }
+
+    state->style = GetWindowLongW(window, GWL_STYLE);
+    state->exstyle = GetWindowLongW(window, GWL_EXSTYLE);
+
+    style = fullscreen_style(state->style);
+    exstyle = fullscreen_exstyle(state->exstyle);
+
+    TRACE("Old style was %08x, %08x, setting to %08x, %08x.\n",
+            state->style, state->exstyle, style, exstyle);
+
+    filter = wined3d_filter_messages(window, TRUE);
+
+    SetWindowLongW(window, GWL_STYLE, style);
+    SetWindowLongW(window, GWL_EXSTYLE, exstyle);
+    SetWindowPos(window, HWND_TOPMOST, 0, 0, w, h, SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE);
+
+    wined3d_filter_messages(window, filter);
+
+    return WINED3D_OK;
+}
+
+void wined3d_window_state_restore_from_fullscreen(struct wined3d_swapchain_state *state,
+        HWND window, const RECT *window_rect)
+{
+    unsigned int window_pos_flags = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE;
+    LONG style, exstyle;
+    RECT rect = {0};
+    BOOL filter;
+
+    if (!state->style && !state->exstyle)
+        return;
+
+    style = GetWindowLongW(window, GWL_STYLE);
+    exstyle = GetWindowLongW(window, GWL_EXSTYLE);
+
+    /* These flags are set by wined3d_device_setup_fullscreen_window, not the
+     * application, and we want to ignore them in the test below, since it's
+     * not the application's fault that they changed. Additionally, we want to
+     * preserve the current status of these flags (i.e. don't restore them) to
+     * more closely emulate the behavior of Direct3D, which leaves these flags
+     * alone when returning to windowed mode. */
+    state->style ^= (state->style ^ style) & WS_VISIBLE;
+    state->exstyle ^= (state->exstyle ^ exstyle) & WS_EX_TOPMOST;
+
+    TRACE("Restoring window style of window %p to %08x, %08x.\n",
+            window, state->style, state->exstyle);
+
+    filter = wined3d_filter_messages(window, TRUE);
+
+    /* Only restore the style if the application didn't modify it during the
+     * fullscreen phase. Some applications change it before calling Reset()
+     * when switching between windowed and fullscreen modes (HL2), some
+     * depend on the original style (Eve Online). */
+    if (style == fullscreen_style(state->style) && exstyle == fullscreen_exstyle(state->exstyle))
+    {
+        SetWindowLongW(window, GWL_STYLE, state->style);
+        SetWindowLongW(window, GWL_EXSTYLE, state->exstyle);
+    }
+
+    if (window_rect)
+        rect = *window_rect;
+    else
+        window_pos_flags |= (SWP_NOMOVE | SWP_NOSIZE);
+    SetWindowPos(window, 0, rect.left, rect.top,
+            rect.right - rect.left, rect.bottom - rect.top, window_pos_flags);
+
+    wined3d_filter_messages(window, filter);
+
+    /* Delete the old values. */
+    state->style = 0;
+    state->exstyle = 0;
+}
+
 HRESULT CDECL wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapchain,
         const struct wined3d_swapchain_desc *swapchain_desc, const struct wined3d_display_mode *mode)
 {
@@ -1446,7 +1556,7 @@ HRESULT CDECL wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapcha
         if (swapchain->desc.windowed)
         {
             /* Switch from windowed to fullscreen */
-            if (FAILED(hr = wined3d_device_setup_fullscreen_window(device,
+            if (FAILED(hr = wined3d_swapchain_state_setup_fullscreen(&swapchain->state,
                     swapchain->device_window, width, height)))
                 return hr;
         }
@@ -1469,7 +1579,7 @@ HRESULT CDECL wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapcha
         RECT *window_rect = NULL;
         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);
+        wined3d_window_state_restore_from_fullscreen(&swapchain->state, swapchain->device_window, window_rect);
     }
 
     swapchain->desc.windowed = swapchain_desc->windowed;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e7da3488315..2ba7bae33e3 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3167,10 +3167,6 @@ struct wined3d_device
     struct wined3d *wined3d;
     struct wined3d_adapter *adapter;
 
-    /* Window styles to restore when switching fullscreen mode */
-    LONG                    style;
-    LONG                    exStyle;
-
     const struct wined3d_shader_backend_ops *shader_backend;
     void *shader_priv;
     void *fragment_priv;
@@ -3255,12 +3251,8 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL
 void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN;
-void wined3d_device_restore_fullscreen_window(struct wined3d_device *device,
-        HWND window, const RECT *window_rect) DECLSPEC_HIDDEN;
 HRESULT wined3d_device_set_implicit_swapchain(struct wined3d_device *device,
         struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
-HRESULT wined3d_device_setup_fullscreen_window(struct wined3d_device *device,
-        HWND window, unsigned int w, unsigned int h) DECLSPEC_HIDDEN;
 void wined3d_device_uninit_3d(struct wined3d_device *device) DECLSPEC_HIDDEN;
 
 struct wined3d_device_no3d
@@ -4182,6 +4174,18 @@ static inline struct wined3d_unordered_access_view_gl *wined3d_unordered_access_
     return CONTAINING_RECORD(view, struct wined3d_unordered_access_view_gl, v);
 }
 
+struct wined3d_swapchain_state
+{
+    /* Window styles to restore when switching fullscreen mode. */
+    LONG style;
+    LONG exstyle;
+};
+
+void wined3d_window_state_restore_from_fullscreen(struct wined3d_swapchain_state *state,
+        HWND window, const RECT *window_rect) DECLSPEC_HIDDEN;
+HRESULT wined3d_swapchain_state_setup_fullscreen(struct wined3d_swapchain_state *state,
+        HWND window, unsigned int w, unsigned int h) DECLSPEC_HIDDEN;
+
 struct wined3d_swapchain_ops
 {
     void (*swapchain_present)(struct wined3d_swapchain *swapchain,
@@ -4215,6 +4219,7 @@ struct wined3d_swapchain
     struct wined3d_context **context;
     unsigned int num_contexts;
 
+    struct wined3d_swapchain_state state;
     HWND win_handle;
     HWND device_window;
 
-- 
2.11.0




More information about the wine-devel mailing list