From 0521cc0b8b49affe86d1e4687ea5fb39650b09f8 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Mon, 29 Jul 2019 16:00:53 +0430 Subject: [PATCH] wined3d: Filter messages per-window instead of per-device. Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/wined3d/device.c | 24 ++++++---------------- dlls/wined3d/swapchain.c | 34 +++++++++++++++---------------- dlls/wined3d/wined3d_main.c | 37 +++++++++++++++++++++++++++++++++- dlls/wined3d/wined3d_private.h | 4 ++-- 4 files changed, 60 insertions(+), 39 deletions(-) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 343e25b482c..71242bba111 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -930,8 +930,8 @@ static LONG fullscreen_exstyle(LONG exstyle) HRESULT wined3d_device_setup_fullscreen_window(struct wined3d_device *device, HWND window, unsigned int w, unsigned int h) { - BOOL filter_messages; LONG style, exstyle; + BOOL filter; TRACE("Setting up window %p for fullscreen mode.\n", window); @@ -956,14 +956,13 @@ HRESULT wined3d_device_setup_fullscreen_window(struct wined3d_device *device, TRACE("Old style was %08x, %08x, setting to %08x, %08x.\n", device->style, device->exStyle, style, exstyle); - filter_messages = device->filter_messages; - device->filter_messages = TRUE; + 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); - device->filter_messages = filter_messages; + wined3d_filter_messages(window, filter); return WINED3D_OK; } @@ -972,9 +971,9 @@ 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; - BOOL filter_messages; LONG style, exstyle; RECT rect = {0}; + BOOL filter; if (!device->style && !device->exStyle) return; @@ -994,8 +993,7 @@ void wined3d_device_restore_fullscreen_window(struct wined3d_device *device, TRACE("Restoring window style of window %p to %08x, %08x.\n", window, device->style, device->exStyle); - filter_messages = device->filter_messages; - device->filter_messages = TRUE; + 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() @@ -1014,7 +1012,7 @@ void wined3d_device_restore_fullscreen_window(struct wined3d_device *device, SetWindowPos(window, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, window_pos_flags); - device->filter_messages = filter_messages; + wined3d_filter_messages(window, filter); /* Delete the old values. */ device->style = 0; @@ -5994,16 +5992,6 @@ void device_invalidate_state(const struct wined3d_device *device, DWORD state) LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL unicode, UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc) { - if (device->filter_messages && message != WM_DISPLAYCHANGE) - { - TRACE("Filtering message: window %p, message %#x, wparam %#lx, lparam %#lx.\n", - window, message, wparam, lparam); - if (unicode) - return DefWindowProcW(window, message, wparam, lparam); - else - return DefWindowProcA(window, message, wparam, lparam); - } - if (message == WM_DESTROY) { TRACE("unregister window %p.\n", window); diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 366ce80bb59..d08ddf0d81a 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -1148,16 +1148,16 @@ void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activate) { struct wined3d_device *device = swapchain->device; - BOOL filter_messages = device->filter_messages; - BOOL focus_messages = device->wined3d->flags & WINED3D_FOCUS_MESSAGES; + HWND window = swapchain->device_window; + BOOL focus_messages, filter; /* This code is not protected by the wined3d mutex, so it may run while * wined3d_device_reset is active. Testing on Windows shows that changing * focus during resets and resetting during focus change events causes * the application to crash with an invalid memory access. */ - if (!focus_messages) - device->filter_messages = 1; + if (!(focus_messages = device->wined3d->flags & WINED3D_FOCUS_MESSAGES)) + filter = wined3d_filter_messages(window, TRUE); if (activate) { @@ -1170,9 +1170,8 @@ void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activa * * Guild Wars 1 wants a WINDOWPOSCHANGED message on the device window to * resume drawing after a focus loss. */ - SetWindowPos(swapchain->device_window, NULL, 0, 0, - swapchain->desc.backbuffer_width, swapchain->desc.backbuffer_height, - SWP_NOACTIVATE | SWP_NOZORDER); + SetWindowPos(window, NULL, 0, 0, swapchain->desc.backbuffer_width, + swapchain->desc.backbuffer_height, SWP_NOACTIVATE | SWP_NOZORDER); } if (device->wined3d->flags & WINED3D_RESTORE_MODE_ON_ACTIVATE) @@ -1204,13 +1203,12 @@ void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activa if (swapchain == device->swapchains[0]) device->device_parent->ops->activate(device->device_parent, FALSE); - if (!(device->create_parms.flags & WINED3DCREATE_NOWINDOWCHANGES) - && IsWindowVisible(swapchain->device_window)) - ShowWindow(swapchain->device_window, SW_MINIMIZE); + if (!(device->create_parms.flags & WINED3DCREATE_NOWINDOWCHANGES) && IsWindowVisible(window)) + ShowWindow(window, SW_MINIMIZE); } if (!focus_messages) - device->filter_messages = filter_messages; + wined3d_filter_messages(window, filter); } HRESULT CDECL wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapchain, unsigned int buffer_count, @@ -1454,14 +1452,14 @@ HRESULT CDECL wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapcha } else { + HWND window = swapchain->device_window; + BOOL filter; + /* Fullscreen -> fullscreen mode change */ - BOOL filter_messages = device->filter_messages; - device->filter_messages = TRUE; - - MoveWindow(swapchain->device_window, 0, 0, width, height, TRUE); - ShowWindow(swapchain->device_window, SW_SHOW); - - device->filter_messages = filter_messages; + filter = wined3d_filter_messages(window, TRUE); + MoveWindow(window, 0, 0, width, height, TRUE); + ShowWindow(window, SW_SHOW); + wined3d_filter_messages(window, filter); } swapchain->d3d_mode = actual_mode; } diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c index 716a2b088c8..2d74d6f9d94 100644 --- a/dlls/wined3d/wined3d_main.c +++ b/dlls/wined3d/wined3d_main.c @@ -36,6 +36,7 @@ struct wined3d_wndproc struct wined3d *wined3d; HWND window; BOOL unicode; + BOOL filter; WNDPROC proc; struct wined3d_device *device; uint32_t flags; @@ -474,11 +475,32 @@ static struct wined3d_wndproc *wined3d_find_wndproc(HWND window, struct wined3d return NULL; } +BOOL wined3d_filter_messages(HWND window, BOOL filter) +{ + struct wined3d_wndproc *entry; + BOOL ret; + + wined3d_wndproc_mutex_lock(); + + if (!(entry = wined3d_find_wndproc(window, NULL))) + { + wined3d_wndproc_mutex_unlock(); + return FALSE; + } + + ret = entry->filter; + entry->filter = filter; + + wined3d_wndproc_mutex_unlock(); + + return ret; +} + static LRESULT CALLBACK wined3d_wndproc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) { struct wined3d_wndproc *entry; struct wined3d_device *device; - BOOL unicode; + BOOL unicode, filter; WNDPROC proc; wined3d_wndproc_mutex_lock(); @@ -492,11 +514,24 @@ static LRESULT CALLBACK wined3d_wndproc(HWND window, UINT message, WPARAM wparam device = entry->device; unicode = entry->unicode; + filter = entry->filter; proc = entry->proc; wined3d_wndproc_mutex_unlock(); if (device) + { + if (filter && message != WM_DISPLAYCHANGE) + { + TRACE("Filtering message: window %p, message %#x, wparam %#lx, lparam %#lx.\n", + window, message, wparam, lparam); + + if (unicode) + return DefWindowProcW(window, message, wparam, lparam); + return DefWindowProcA(window, message, wparam, lparam); + } + return device_process_message(device, window, unicode, message, wparam, lparam, proc); + } if (unicode) return CallWindowProcW(proc, window, message, wparam, lparam); return CallWindowProcA(proc, window, message, wparam, lparam); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 85392900122..d62774cc659 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2993,6 +2993,7 @@ struct wined3d struct wined3d_adapter *adapters[1]; }; +BOOL wined3d_filter_messages(HWND window, BOOL filter) DECLSPEC_HIDDEN; void wined3d_hook_swapchain(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; HRESULT wined3d_init(struct wined3d *wined3d, DWORD flags) DECLSPEC_HIDDEN; void wined3d_unhook_swapchain(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; @@ -3183,8 +3184,7 @@ struct wined3d_device BYTE d3d_initialized : 1; BYTE inScene : 1; /* A flag to check for proper BeginScene / EndScene call pairs */ BYTE softwareVertexProcessing : 1; /* process vertex shaders using software or hardware */ - BYTE filter_messages : 1; - BYTE padding : 3; + BYTE padding : 4; unsigned char surface_alignment; /* Line Alignment of surfaces */