Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/wined3d/device.c | 214 +++++++++++++++++---------------- dlls/wined3d/wined3d.spec | 3 + dlls/wined3d/wined3d_private.h | 5 +- include/wine/wined3d.h | 12 ++ 4 files changed, 127 insertions(+), 107 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index d35a064..2e2da32 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -910,115 +910,24 @@ 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 CDECL wined3d_device_setup_fullscreen_window(struct wined3d_device *device, HWND window, unsigned int w, unsigned int h) { - BOOL filter_messages; - LONG style, exstyle; - - 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_messages = device->filter_messages; + HRESULT hr; + BOOL filter_messages = device->filter_messages; device->filter_messages = 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); - + hr = wined3d_fullscreen_setup_window(&device->fullscreen_state, window, w, h); device->filter_messages = filter_messages; - - return WINED3D_OK; + return hr; }
void CDECL 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; - BOOL filter_messages; - LONG style, exstyle; - RECT rect = {0}; - - 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_messages = device->filter_messages; + BOOL filter_messages = device->filter_messages; device->filter_messages = 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_fullscreen_restore_window(&device->fullscreen_state, window, window_rect); device->filter_messages = filter_messages; - - /* Delete the old values. */ - device->style = 0; - device->exStyle = 0; }
HRESULT CDECL wined3d_device_acquire_focus_window(struct wined3d_device *device, HWND window) @@ -5538,19 +5447,19 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, } else if (!swapchain_desc->windowed) { - DWORD style = device->style; - DWORD exStyle = device->exStyle; + DWORD style = device->fullscreen_state.style; + DWORD exStyle = device->fullscreen_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 clear up their mess. Guild Wars also loses the device during that. */ - device->style = 0; - device->exStyle = 0; + device->fullscreen_state.style = 0; + device->fullscreen_state.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; + device->fullscreen_state.style = style; + device->fullscreen_state.exStyle = exStyle; }
if (FAILED(hr = wined3d_swapchain_resize_buffers(swapchain, swapchain_desc->backbuffer_count, @@ -6036,3 +5945,102 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL else return CallWindowProcA(proc, window, message, wparam, lparam); } + +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 CDECL wined3d_fullscreen_setup_window(struct wined3d_fullscreen_state *fullscreen, + HWND window, unsigned int w, unsigned int h) +{ + LONG style, exstyle; + + 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 (fullscreen->style || fullscreen->exStyle) + { + ERR("Changing the window style for window %p, but another style (%08x, %08x) is already stored.\n", + window, fullscreen->style, fullscreen->exStyle); + } + + fullscreen->style = GetWindowLongW(window, GWL_STYLE); + fullscreen->exStyle = GetWindowLongW(window, GWL_EXSTYLE); + + style = fullscreen_style(fullscreen->style); + exstyle = fullscreen_exstyle(fullscreen->exStyle); + + TRACE("Old style was %08x, %08x, setting to %08x, %08x.\n", + fullscreen->style, fullscreen->exStyle, style, exstyle); + + SetWindowLongW(window, GWL_STYLE, style); + SetWindowLongW(window, GWL_EXSTYLE, exstyle); + SetWindowPos(window, HWND_TOPMOST, 0, 0, w, h, SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE); + + return WINED3D_OK; +} + +void CDECL wined3d_fullscreen_restore_window(struct wined3d_fullscreen_state *fullscreen, HWND window, + const RECT *window_rect) +{ + unsigned int window_pos_flags = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE; + LONG style, exstyle; + RECT rect = {0}; + + if (!fullscreen->style && !fullscreen->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. */ + fullscreen->style ^= (fullscreen->style ^ style) & WS_VISIBLE; + fullscreen->exStyle ^= (fullscreen->exStyle ^ exstyle) & WS_EX_TOPMOST; + + TRACE("Restoring window style of window %p to %08x, %08x.\n", + window, fullscreen->style, fullscreen->exStyle); + + /* 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(fullscreen->style) && exstyle == fullscreen_exstyle(fullscreen->exStyle)) + { + SetWindowLongW(window, GWL_STYLE, fullscreen->style); + SetWindowLongW(window, GWL_EXSTYLE, fullscreen->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); + + /* Delete the old values. */ + fullscreen->style = 0; + fullscreen->exStyle = 0; +} diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 904bb34..ddb4e56 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -314,3 +314,6 @@ @ cdecl wined3d_vertex_declaration_incref(ptr)
@ cdecl wined3d_extract_shader_input_signature_from_dxbc(ptr ptr long) + +@ cdecl wined3d_fullscreen_setup_window(ptr ptr long long) +@ cdecl wined3d_fullscreen_restore_window(ptr ptr ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 8e23653..9d649fe 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3150,10 +3150,7 @@ struct wined3d_device struct wined3d_device_parent *device_parent; struct wined3d *wined3d; struct wined3d_adapter *adapter; - - /* Window styles to restore when switching fullscreen mode */ - LONG style; - LONG exStyle; + struct wined3d_fullscreen_state fullscreen_state;
const struct wined3d_shader_backend_ops *shader_backend; void *shader_priv; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index d1d3ca4..f08383a 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2171,6 +2171,13 @@ struct wined3d_private_data } content; };
+struct wined3d_fullscreen_state +{ + /* Window styles to restore when switching fullscreen mode */ + LONG style; + LONG exStyle; +}; + typedef HRESULT (CDECL *wined3d_device_reset_cb)(struct wined3d_resource *resource);
void __stdcall wined3d_mutex_lock(void); @@ -2756,6 +2763,11 @@ ULONG __cdecl wined3d_vertex_declaration_incref(struct wined3d_vertex_declaratio HRESULT __cdecl wined3d_extract_shader_input_signature_from_dxbc(struct wined3d_shader_signature *signature, const void *byte_code, SIZE_T byte_code_size);
+void __cdecl wined3d_fullscreen_restore_window(struct wined3d_fullscreen_state *fullscreen, HWND window, + const RECT *window_rect); +HRESULT __cdecl wined3d_fullscreen_setup_window(struct wined3d_fullscreen_state *fullscreen, + HWND window, unsigned int w, unsigned int h); + /* Return the integer base-2 logarithm of x. Undefined for x == 0. */ static inline unsigned int wined3d_log2i(unsigned int x) {