wined3d: Track windows styles per-swapchain.
Instead of per-device. Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
0521cc0b8b
commit
3fc96a5d35
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue