From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/winex11.drv/clipboard.c | 141 ++++++++++------------------------- dlls/winex11.drv/dllmain.c | 102 +++++++++++++++++++++++++ dlls/winex11.drv/unixlib.h | 9 +++ dlls/winex11.drv/x11drv.h | 1 + 4 files changed, 153 insertions(+), 100 deletions(-)
diff --git a/dlls/winex11.drv/clipboard.c b/dlls/winex11.drv/clipboard.c index 4ba36239595..9486f37954e 100644 --- a/dlls/winex11.drv/clipboard.c +++ b/dlls/winex11.drv/clipboard.c @@ -2143,67 +2143,6 @@ BOOL update_clipboard( HWND hwnd ) }
-/************************************************************************** - * clipboard_wndproc - * - * Window procedure for the clipboard manager. - */ -static LRESULT CALLBACK clipboard_wndproc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) -{ - switch (msg) - { - case WM_NCCREATE: - return TRUE; - case WM_CLIPBOARDUPDATE: - if (is_clipboard_owner) break; /* ignore our own changes */ - acquire_selection( thread_init_display() ); - break; - case WM_RENDERFORMAT: - if (render_format( wp )) rendered_formats++; - break; - case WM_TIMER: - if (!is_clipboard_owner) break; - request_selection_contents( thread_display(), FALSE ); - break; - case WM_DESTROYCLIPBOARD: - TRACE( "WM_DESTROYCLIPBOARD: lost ownership\n" ); - is_clipboard_owner = FALSE; - KillTimer( hwnd, 1 ); - break; - } - return DefWindowProcW( hwnd, msg, wp, lp ); -} - - -/************************************************************************** - * wait_clipboard_mutex - * - * Make sure that there's only one clipboard thread per window station. - */ -static BOOL wait_clipboard_mutex(void) -{ - static const WCHAR prefix[] = {'_','_','w','i','n','e','_','c','l','i','p','b','o','a','r','d','_'}; - WCHAR buffer[MAX_PATH + ARRAY_SIZE( prefix )]; - HANDLE mutex; - - memcpy( buffer, prefix, sizeof(prefix) ); - if (!GetUserObjectInformationW( GetProcessWindowStation(), UOI_NAME, - buffer + ARRAY_SIZE( prefix ), - sizeof(buffer) - sizeof(prefix), NULL )) - { - ERR( "failed to get winstation name\n" ); - return FALSE; - } - mutex = CreateMutexW( NULL, TRUE, buffer ); - if (GetLastError() == ERROR_ALREADY_EXISTS) - { - TRACE( "waiting for mutex %s\n", debugstr_w( buffer )); - WaitForSingleObject( mutex, INFINITE ); - } - return TRUE; -} - - /************************************************************************** * selection_notify_event * @@ -2278,15 +2217,11 @@ static void xfixes_init(void) * * Thread running inside the desktop process to manage the clipboard */ -static DWORD WINAPI clipboard_thread( void *arg ) +static BOOL clipboard_init( HWND hwnd ) { - static const WCHAR clipboard_classname[] = {'_','_','w','i','n','e','_','c','l','i','p','b','o','a','r','d','_','m','a','n','a','g','e','r',0}; XSetWindowAttributes attr; - WNDCLASSW class; - MSG msg; - - if (!wait_clipboard_mutex()) return 0;
+ clipboard_hwnd = hwnd; clipboard_display = thread_init_display(); attr.event_mask = PropertyChangeMask; import_window = XCreateWindow( clipboard_display, root_window, 0, 0, 1, 1, 0, CopyFromParent, @@ -2294,34 +2229,53 @@ static DWORD WINAPI clipboard_thread( void *arg ) if (!import_window) { ERR( "failed to create import window\n" ); - return 0; - } - - memset( &class, 0, sizeof(class) ); - class.lpfnWndProc = clipboard_wndproc; - class.lpszClassName = clipboard_classname; - - if (!RegisterClassW( &class ) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) - { - ERR( "could not register clipboard window class err %u\n", GetLastError() ); - return 0; - } - if (!(clipboard_hwnd = CreateWindowW( clipboard_classname, NULL, 0, 0, 0, 0, 0, - HWND_MESSAGE, 0, 0, NULL ))) - { - ERR( "failed to create clipboard window err %u\n", GetLastError() ); - return 0; + return FALSE; }
clipboard_thread_id = GetCurrentThreadId(); - AddClipboardFormatListener( clipboard_hwnd ); + NtUserAddClipboardFormatListener( hwnd ); register_builtin_formats(); xfixes_init(); request_selection_contents( clipboard_display, TRUE );
TRACE( "clipboard thread %04x running\n", GetCurrentThreadId() ); - while (GetMessageW( &msg, 0, 0, 0 )) DispatchMessageW( &msg ); - return 0; + return TRUE; +} + + + + +/************************************************************************** + * x11drv_clipboard_message + */ +NTSTATUS x11drv_clipboard_message( void *arg ) +{ + struct clipboard_message_params *params = arg; + + switch (params->msg) + { + case WM_NCCREATE: + return clipboard_init( params->hwnd ); + case WM_CLIPBOARDUPDATE: + if (is_clipboard_owner) break; /* ignore our own changes */ + acquire_selection( thread_init_display() ); + break; + case WM_RENDERFORMAT: + if (render_format( params->wparam )) rendered_formats++; + break; + case WM_TIMER: + if (!is_clipboard_owner) break; + request_selection_contents( thread_display(), FALSE ); + break; + case WM_DESTROYCLIPBOARD: + TRACE( "WM_DESTROYCLIPBOARD: lost ownership\n" ); + is_clipboard_owner = FALSE; + NtUserKillTimer( params->hwnd, 1 ); + break; + } + + return NtUserMessageCall( params->hwnd, params->msg, params->wparam, params->lparam, + NULL, NtUserDefWindowProc, FALSE ); }
@@ -2400,16 +2354,3 @@ BOOL X11DRV_SelectionClear( HWND hwnd, XEvent *xev ) request_selection_contents( event->display, TRUE ); return FALSE; } - - -/************************************************************************** - * X11DRV_InitClipboard - */ -void X11DRV_InitClipboard(void) -{ - DWORD id; - HANDLE handle = CreateThread( NULL, 0, clipboard_thread, NULL, 0, &id ); - - if (handle) CloseHandle( handle ); - else ERR( "failed to create clipboard thread\n" ); -} diff --git a/dlls/winex11.drv/dllmain.c b/dlls/winex11.drv/dllmain.c index d46cbc6a422..49db5e3d2a5 100644 --- a/dlls/winex11.drv/dllmain.c +++ b/dlls/winex11.drv/dllmain.c @@ -20,10 +20,112 @@
#include "config.h" #include "x11drv.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
HMODULE x11drv_module = 0;
+/************************************************************************** + * wait_clipboard_mutex + * + * Make sure that there's only one clipboard thread per window station. + */ +static BOOL wait_clipboard_mutex(void) +{ + static const WCHAR prefix[] = {'_','_','w','i','n','e','_','c','l','i','p','b','o','a','r','d','_'}; + WCHAR buffer[MAX_PATH + ARRAY_SIZE( prefix )]; + HANDLE mutex; + + memcpy( buffer, prefix, sizeof(prefix) ); + if (!GetUserObjectInformationW( GetProcessWindowStation(), UOI_NAME, + buffer + ARRAY_SIZE( prefix ), + sizeof(buffer) - sizeof(prefix), NULL )) + { + ERR( "failed to get winstation name\n" ); + return FALSE; + } + mutex = CreateMutexW( NULL, TRUE, buffer ); + if (GetLastError() == ERROR_ALREADY_EXISTS) + { + TRACE( "waiting for mutex %s\n", debugstr_w( buffer )); + WaitForSingleObject( mutex, INFINITE ); + } + return TRUE; +} + + +/************************************************************************** + * clipboard_wndproc + * + * Window procedure for the clipboard manager. + */ +static LRESULT CALLBACK clipboard_wndproc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) +{ + struct clipboard_message_params params; + + switch (msg) + { + case WM_NCCREATE: + case WM_CLIPBOARDUPDATE: + case WM_RENDERFORMAT: + case WM_TIMER: + case WM_DESTROYCLIPBOARD: + params.hwnd = hwnd; + params.msg = msg; + params.wparam = wp; + params.lparam = lp; + return x11drv_clipboard_message( ¶ms ); + } + + return DefWindowProcW( hwnd, msg, wp, lp ); +} + + +/************************************************************************** + * clipboard_thread + * + * Thread running inside the desktop process to manage the clipboard + */ +static DWORD WINAPI clipboard_thread( void *arg ) +{ + static const WCHAR clipboard_classname[] = {'_','_','w','i','n','e','_','c','l','i','p','b','o','a','r','d','_','m','a','n','a','g','e','r',0}; + WNDCLASSW class; + MSG msg; + + if (!wait_clipboard_mutex()) return 0; + + memset( &class, 0, sizeof(class) ); + class.lpfnWndProc = clipboard_wndproc; + class.lpszClassName = clipboard_classname; + + if (!RegisterClassW( &class ) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) + { + ERR( "could not register clipboard window class err %u\n", GetLastError() ); + return 0; + } + if (!CreateWindowW( clipboard_classname, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, NULL )) + { + ERR( "failed to create clipboard window err %u\n", GetLastError() ); + return 0; + } + + while (GetMessageW( &msg, 0, 0, 0 )) DispatchMessageW( &msg ); + return 0; +} + + +void X11DRV_InitClipboard(void) +{ + DWORD id; + HANDLE thread = CreateThread( NULL, 0, clipboard_thread, NULL, 0, &id ); + + if (thread) CloseHandle( thread ); + else ERR( "failed to create clipboard thread\n" ); +} + + BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved ) { if (reason != DLL_PROCESS_ATTACH) return TRUE; diff --git a/dlls/winex11.drv/unixlib.h b/dlls/winex11.drv/unixlib.h index 537a8e0326a..3865ecab7a0 100644 --- a/dlls/winex11.drv/unixlib.h +++ b/dlls/winex11.drv/unixlib.h @@ -19,6 +19,15 @@ #include "ntuser.h" #include "wine/unixlib.h"
+/* x11drv_clipboard_message params */ +struct clipboard_message_params +{ + HWND hwnd; + UINT msg; + WPARAM wparam; + LPARAM lparam; +}; + /* DnD support */
struct format_entry diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index f00d69a2f6a..b763a7aa345 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -844,6 +844,7 @@ static inline BOOL is_window_rect_mapped( const RECT *rect ) /* unixlib interface */
extern NTSTATUS x11drv_init( void *arg ) DECLSPEC_HIDDEN; +extern NTSTATUS x11drv_clipboard_message( void *arg ) DECLSPEC_HIDDEN;
/* GDI helpers */