Module: wine Branch: master Commit: a8b0b07c45c9cac0066c2b4311123d0a9774c7ac URL: https://source.winehq.org/git/wine.git/?a=commit;h=a8b0b07c45c9cac0066c2b431...
Author: Jacek Caban jacek@codeweavers.com Date: Tue Feb 15 13:10:20 2022 +0100
win32u: Move window surfaces list from user32.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Huw Davies huw@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/user32/win.c | 33 ++++----------------------------- dlls/win32u/sysparams.c | 12 ++++++++++-- dlls/win32u/win32u_private.h | 5 +++++ dlls/win32u/window.c | 41 +++++++++++++++++++++++++++++++++++++++++ include/ntuser.h | 3 +++ 5 files changed, 63 insertions(+), 31 deletions(-)
diff --git a/dlls/user32/win.c b/dlls/user32/win.c index 70c3521ab1d..8a0a91ff4fb 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -41,16 +41,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(win);
static DWORD process_layout = ~0u;
-static struct list window_surfaces = LIST_INIT( window_surfaces ); - -static CRITICAL_SECTION surfaces_section; -static CRITICAL_SECTION_DEBUG critsect_debug = -{ - 0, 0, &surfaces_section, - { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": surfaces_section") } -}; -static CRITICAL_SECTION surfaces_section = { &critsect_debug, -1, 0, 0, 0, 0 };
/**********************************************************************/
@@ -730,11 +720,9 @@ void create_offscreen_window_surface( const RECT *visible_rect, struct window_su */ void register_window_surface( struct window_surface *old, struct window_surface *new ) { - if (old == new) return; - EnterCriticalSection( &surfaces_section ); - if (old && old != &dummy_surface) list_remove( &old->entry ); - if (new && new != &dummy_surface) list_add_tail( &window_surfaces, &new->entry ); - LeaveCriticalSection( &surfaces_section ); + if (old == &dummy_surface) old = NULL; + if (new == &dummy_surface) new = NULL; + NtUserCallTwoParam( (UINT_PTR)old, (UINT_PTR)new, NtUserRegisterWindowSurface ); }
@@ -745,20 +733,7 @@ void register_window_surface( struct window_surface *old, struct window_surface */ void flush_window_surfaces( BOOL idle ) { - static DWORD last_idle; - DWORD now; - struct window_surface *surface; - - EnterCriticalSection( &surfaces_section ); - now = GetTickCount(); - if (idle) last_idle = now; - /* if not idle, we only flush if there's evidence that the app never goes idle */ - else if ((int)(now - last_idle) < 50) goto done; - - LIST_FOR_EACH_ENTRY( surface, &window_surfaces, struct window_surface, entry ) - surface->funcs->flush( surface ); -done: - LeaveCriticalSection( &surfaces_section ); + NtUserCallOneParam( idle, NtUserFlushWindowSurfaces ); }
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index ae9b4f73cfb..6d1d6689bfe 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -4504,10 +4504,14 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code ) return HandleToUlong( get_sys_color_pen(arg) ); case NtUserGetSystemMetrics: return get_system_metrics( arg ); - case NtUserGetDeskPattern: - return get_entry( &entry_DESKPATTERN, 256, (WCHAR *)arg ); case NtUserMessageBeep: return message_beep( arg ); + /* temporary exports */ + case NtUserFlushWindowSurfaces: + flush_window_surfaces( arg ); + return 0; + case NtUserGetDeskPattern: + return get_entry( &entry_DESKPATTERN, 256, (WCHAR *)arg ); default: FIXME( "invalid code %u\n", code ); return 0; @@ -4529,6 +4533,10 @@ ULONG_PTR WINAPI NtUserCallTwoParam( ULONG_PTR arg1, ULONG_PTR arg2, ULONG code return mirror_window_region( UlongToHandle(arg1), UlongToHandle(arg2) ); case NtUserMonitorFromRect: return HandleToUlong( monitor_from_rect( (const RECT *)arg1, arg2, get_thread_dpi() )); + /* temporary exports */ + case NtUserRegisterWindowSurface: + register_window_surface( (struct window_surface *)arg1, (struct window_surface *)arg2 ); + return 0; default: FIXME( "invalid code %u\n", code ); return 0; diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index cd50b48feec..29c8a6d719f 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -260,6 +260,11 @@ extern RECT map_dpi_rect( RECT rect, UINT dpi_from, UINT dpi_to ) DECLSPEC_HIDDE extern HMONITOR monitor_from_point( POINT pt, DWORD flags, UINT dpi ) DECLSPEC_HIDDEN; extern HMONITOR monitor_from_rect( const RECT *rect, DWORD flags, UINT dpi ) DECLSPEC_HIDDEN;
+/* window.c */ +extern void flush_window_surfaces( BOOL idle ) DECLSPEC_HIDDEN; +extern void register_window_surface( struct window_surface *old, + struct window_surface *new ) DECLSPEC_HIDDEN; + extern void wrappers_init( unixlib_handle_t handle ) DECLSPEC_HIDDEN; extern NTSTATUS gdi_init(void) DECLSPEC_HIDDEN; extern NTSTATUS callbacks_init( void *args ) DECLSPEC_HIDDEN; diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index e880594d98c..439f51e986f 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -23,11 +23,52 @@ #pragma makedep unix #endif
+#include <pthread.h> + #include "ntstatus.h" #define WIN32_NO_STATUS #include "win32u_private.h" #include "wine/server.h"
+static struct list window_surfaces = LIST_INIT( window_surfaces ); +static pthread_mutex_t surfaces_lock = PTHREAD_MUTEX_INITIALIZER; + +/******************************************************************* + * register_window_surface + * + * Register a window surface in the global list, possibly replacing another one. + */ +void register_window_surface( struct window_surface *old, struct window_surface *new ) +{ + if (old == new) return; + pthread_mutex_lock( &surfaces_lock ); + if (old) list_remove( &old->entry ); + if (new) list_add_tail( &window_surfaces, &new->entry ); + pthread_mutex_unlock( &surfaces_lock ); +} + +/******************************************************************* + * flush_window_surfaces + * + * Flush pending output from all window surfaces. + */ +void flush_window_surfaces( BOOL idle ) +{ + static DWORD last_idle; + DWORD now; + struct window_surface *surface; + + pthread_mutex_lock( &surfaces_lock ); + now = NtGetTickCount(); + if (idle) last_idle = now; + /* if not idle, we only flush if there's evidence that the app never goes idle */ + else if ((int)(now - last_idle) < 50) goto done; + + LIST_FOR_EACH_ENTRY( surface, &window_surfaces, struct window_surface, entry ) + surface->funcs->flush( surface ); +done: + pthread_mutex_unlock( &surfaces_lock ); +}
/*********************************************************************** * NtUserGetProp (win32u.@) diff --git a/include/ntuser.h b/include/ntuser.h index a115f7c9259..dd16d11dcb8 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -61,6 +61,7 @@ enum NtUserMessageBeep, NtUserRealizePalette, /* temporary exports */ + NtUserFlushWindowSurfaces, NtUserGetDeskPattern, };
@@ -71,6 +72,8 @@ enum NtUserGetSystemMetricsForDpi, NtUserMirrorRgn, NtUserMonitorFromRect, + /* temporary exports */ + NtUserRegisterWindowSurface, };
/* color index used to retrieve system 55aa brush */