[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