From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/win32u/driver.c | 7 +++++++ dlls/win32u/message.c | 2 ++ include/ntuser.h | 5 +++-- include/wine/gdi_driver.h | 1 + 4 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 4dac0760464..b4cea3d42c8 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -1099,6 +1099,11 @@ static BOOL loaderdrv_ClipCursor( const RECT *clip ) return load_driver()->pClipCursor( clip ); }
+static LRESULT nulldrv_ClipboardWindowProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + return 0; +} + static void loaderdrv_UpdateClipboard(void) { load_driver()->pUpdateClipboard(); @@ -1172,6 +1177,7 @@ static const struct user_driver_funcs lazy_load_driver = loaderdrv_SetCursorPos, loaderdrv_ClipCursor, /* clipboard functions */ + nulldrv_ClipboardWindowProc, loaderdrv_UpdateClipboard, /* display modes */ loaderdrv_ChangeDisplaySettingsEx, @@ -1247,6 +1253,7 @@ void CDECL __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT v SET_USER_FUNC(GetCursorPos); SET_USER_FUNC(SetCursorPos); SET_USER_FUNC(ClipCursor); + SET_USER_FUNC(ClipboardWindowProc); SET_USER_FUNC(UpdateClipboard); SET_USER_FUNC(ChangeDisplaySettingsEx); SET_USER_FUNC(EnumDisplaySettingsEx); diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 6bb9aa455f5..bc6db20d164 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2911,6 +2911,8 @@ LRESULT WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpa return send_notify_message( hwnd, msg, wparam, lparam, ansi ); case NtUserSendMessageCallback: return send_message_callback( hwnd, msg, wparam, lparam, (void *)result_info, ansi ); + case NtUserClipboardWindowProc: + return user_driver->pClipboardWindowProc( hwnd, msg, wparam, lparam ); case NtUserSpyEnter: spy_enter_message( ansi, hwnd, msg, wparam, lparam ); return 0; diff --git a/include/ntuser.h b/include/ntuser.h index 29de027a334..091d34c3a5f 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -189,8 +189,9 @@ enum NtUserSendNotifyMessage = 0x02b7, NtUserSendMessageCallback = 0x02b8, /* Wine-specific exports */ - NtUserSpyEnter = 0x0300, - NtUserSpyExit = 0x0301, + NtUserClipboardWindowProc = 0x0300, + NtUserSpyEnter = 0x0301, + NtUserSpyExit = 0x0302, };
/* NtUserThunkedMenuItemInfo codes */ diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 21fff4d4aa2..52fd6fe49d3 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -291,6 +291,7 @@ struct user_driver_funcs BOOL (*pSetCursorPos)(INT,INT); BOOL (*pClipCursor)(LPCRECT); /* clipboard functions */ + LRESULT (*pClipboardWindowProc)(HWND,UINT,WPARAM,LPARAM); void (*pUpdateClipboard)(void); /* display modes */ LONG (*pChangeDisplaySettingsEx)(LPCWSTR,LPDEVMODEW,HWND,DWORD,LPVOID);
From: Jacek Caban jacek@codeweavers.com
Based on winex11.drv. Drivers that don't implement ClipboardWindowProc entry point will disable it by failing to create the window.
Signed-off-by: Jacek Caban jacek@codeweavers.com --- programs/explorer/Makefile.in | 2 +- programs/explorer/desktop.c | 90 +++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-)
diff --git a/programs/explorer/Makefile.in b/programs/explorer/Makefile.in index 5507d747bb1..3a2ddec3fd4 100644 --- a/programs/explorer/Makefile.in +++ b/programs/explorer/Makefile.in @@ -1,5 +1,5 @@ MODULE = explorer.exe -IMPORTS = rpcrt4 user32 gdi32 advapi32 +IMPORTS = rpcrt4 user32 gdi32 advapi32 win32u DELAYIMPORTS = comctl32 shell32 oleaut32 ole32 shlwapi
EXTRADLLFLAGS = -mwindows -municode diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c index 400cc1d560e..96673adc254 100644 --- a/programs/explorer/desktop.c +++ b/programs/explorer/desktop.c @@ -29,6 +29,7 @@ #include <rpc.h> #include <shlobj.h> #include <shellapi.h> +#include <ntuser.h> #include "exdisp.h"
#include "wine/debug.h" @@ -618,6 +619,91 @@ static void initialize_launchers( HWND hwnd ) } }
+/************************************************************************** + * 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[] = L"__wine_clipboard_"; + WCHAR buffer[MAX_PATH + ARRAY_SIZE( prefix )]; + HANDLE mutex; + + memcpy( buffer, prefix, sizeof(prefix) ); + if (!GetUserObjectInformationW( GetProcessWindowStation(), UOI_NAME, + buffer + ARRAY_SIZE( prefix ) - 1, + 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 ) +{ + switch (msg) + { + case WM_NCCREATE: + case WM_CLIPBOARDUPDATE: + case WM_RENDERFORMAT: + case WM_TIMER: + case WM_DESTROYCLIPBOARD: + case WM_USER: + return NtUserMessageCall( hwnd, msg, wp, lp, 0, NtUserClipboardWindowProc, FALSE ); + } + + 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[] = L"__wine_clipboard_manager"; + WNDCLASSW class; + ATOM atom; + MSG msg; + + if (!wait_clipboard_mutex()) return 0; + + memset( &class, 0, sizeof(class) ); + class.lpfnWndProc = clipboard_wndproc; + class.lpszClassName = clipboard_classname; + + if (!(atom = RegisterClassW( &class )) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) + { + ERR( "could not register clipboard window class err %lu\n", GetLastError() ); + return 0; + } + if (!CreateWindowW( clipboard_classname, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, NULL )) + { + TRACE( "failed to create clipboard window err %lu\n", GetLastError() ); + UnregisterClassW( MAKEINTRESOURCEW(atom), NULL ); + return 0; + } + + while (GetMessageW( &msg, 0, 0, 0 )) DispatchMessageW( &msg ); + return 0; +} + static WNDPROC desktop_orig_wndproc;
/* window procedure for the desktop window */ @@ -961,6 +1047,8 @@ void manage_desktop( WCHAR *arg ) BOOL enable_shell = FALSE; void (WINAPI *pShellDDEInit)( BOOL ) = NULL; HMODULE shell32; + HANDLE thread; + DWORD id;
/* get the rest of the command line (if any) */ while (*p && !is_whitespace(*p)) p++; @@ -1025,6 +1113,8 @@ void manage_desktop( WCHAR *arg ) SetWindowPos( hwnd, 0, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN), GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN), SWP_SHOWWINDOW ); + thread = CreateThread( NULL, 0, clipboard_thread, NULL, 0, &id ); + if (thread) CloseHandle( thread ); SystemParametersInfoW( SPI_SETDESKWALLPAPER, 0, NULL, FALSE ); ClipCursor( NULL ); initialize_display_settings();
From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/winex11.drv/clipboard.c | 17 +++--- dlls/winex11.drv/dllmain.c | 102 --------------------------------- dlls/winex11.drv/init.c | 1 + dlls/winex11.drv/unixlib.h | 11 ---- dlls/winex11.drv/window.c | 1 - dlls/winex11.drv/x11drv.h | 2 +- dlls/winex11.drv/x11drv_main.c | 1 - 7 files changed, 9 insertions(+), 126 deletions(-)
diff --git a/dlls/winex11.drv/clipboard.c b/dlls/winex11.drv/clipboard.c index f2be4386e65..da451fad57c 100644 --- a/dlls/winex11.drv/clipboard.c +++ b/dlls/winex11.drv/clipboard.c @@ -2215,7 +2215,7 @@ static void xfixes_init(void)
/************************************************************************** - * clipboard_thread + * clipboard_init * * Thread running inside the desktop process to manage the clipboard */ @@ -2250,20 +2250,18 @@ static BOOL clipboard_init( HWND hwnd ) /************************************************************************** * x11drv_clipboard_message */ -NTSTATUS x11drv_clipboard_message( void *arg ) +LRESULT X11DRV_ClipboardWindowProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { - struct clipboard_message_params *params = arg; - - switch (params->msg) + switch (msg) { case WM_NCCREATE: - return clipboard_init( params->hwnd ); + return clipboard_init( 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++; + if (render_format( wparam )) rendered_formats++; break; case WM_TIMER: if (!is_clipboard_owner) break; @@ -2272,12 +2270,11 @@ NTSTATUS x11drv_clipboard_message( void *arg ) case WM_DESTROYCLIPBOARD: TRACE( "WM_DESTROYCLIPBOARD: lost ownership\n" ); is_clipboard_owner = FALSE; - NtUserKillTimer( params->hwnd, 1 ); + NtUserKillTimer( hwnd, 1 ); break; }
- return NtUserMessageCall( params->hwnd, params->msg, params->wparam, params->lparam, - NULL, NtUserDefWindowProc, FALSE ); + return NtUserMessageCall( hwnd, msg, wparam, lparam, NULL, NtUserDefWindowProc, FALSE ); }
diff --git a/dlls/winex11.drv/dllmain.c b/dlls/winex11.drv/dllmain.c index b06c955c2a4..e2cbd51351d 100644 --- a/dlls/winex11.drv/dllmain.c +++ b/dlls/winex11.drv/dllmain.c @@ -21,112 +21,11 @@ #include "x11drv_dll.h" #include "wine/debug.h"
-WINE_DEFAULT_DEBUG_CHANNEL(x11drv); -
HMODULE x11drv_module = 0; static unixlib_handle_t x11drv_handle; NTSTATUS (CDECL *x11drv_unix_call)( enum x11drv_funcs code, void *params );
-/************************************************************************** - * 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_CALL( 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; -} - - -static NTSTATUS x11drv_clipboard_init( UINT arg ) -{ - DWORD id; - HANDLE thread = CreateThread( NULL, 0, clipboard_thread, NULL, 0, &id ); - - if (thread) CloseHandle( thread ); - else ERR( "failed to create clipboard thread\n" ); - return 0; -} -
static NTSTATUS x11drv_load_icon( UINT id ) { @@ -137,7 +36,6 @@ static NTSTATUS x11drv_load_icon( UINT id ) typedef NTSTATUS (*callback_func)( UINT arg ); static const callback_func callback_funcs[] = { - x11drv_clipboard_init, x11drv_dnd_drop_event, x11drv_dnd_leave_event, x11drv_ime_get_cursor_pos, diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 3bdc05999f1..7c5a1acd7b6 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -425,6 +425,7 @@ static const struct user_driver_funcs x11drv_funcs = .pSetWindowText = X11DRV_SetWindowText, .pShowWindow = X11DRV_ShowWindow, .pSysCommand = X11DRV_SysCommand, + .pClipboardWindowProc = X11DRV_ClipboardWindowProc, .pUpdateClipboard = X11DRV_UpdateClipboard, .pUpdateLayeredWindow = X11DRV_UpdateLayeredWindow, .pWindowMessage = X11DRV_WindowMessage, diff --git a/dlls/winex11.drv/unixlib.h b/dlls/winex11.drv/unixlib.h index 76cfad88f4d..451c308f0cd 100644 --- a/dlls/winex11.drv/unixlib.h +++ b/dlls/winex11.drv/unixlib.h @@ -21,7 +21,6 @@
enum x11drv_funcs { - unix_clipboard_message, unix_create_desktop, unix_init, unix_systray_clear, @@ -41,15 +40,6 @@ enum x11drv_funcs extern NTSTATUS (CDECL *x11drv_unix_call)( enum x11drv_funcs code, void *params ) DECLSPEC_HIDDEN; #define X11DRV_CALL(func, params) x11drv_unix_call( unix_ ## func, params )
-/* x11drv_clipboard_message params */ -struct clipboard_message_params -{ - HWND hwnd; - UINT msg; - WPARAM wparam; - LPARAM lparam; -}; - /* x11drv_create_desktop params */ struct create_desktop_params { @@ -108,7 +98,6 @@ C_ASSERT( client_func_last <= NtUserDriverCallbackLast + 1 ); /* simplified interface for client callbacks requiring only a single UINT parameter */ enum client_callback { - client_clipboard_init, client_dnd_drop_event, client_dnd_leave_event, client_ime_get_cursor_pos, diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 07fb1515e24..5d9a93688c3 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1913,7 +1913,6 @@ BOOL X11DRV_CreateWindow( HWND hwnd ) CWOverrideRedirect | CWEventMask, &attr ); XFlush( data->display ); NtUserSetProp( hwnd, clip_window_prop, (HANDLE)data->clip_window ); - x11drv_client_call( client_clipboard_init, 0 ); X11DRV_DisplayDevices_RegisterEventHandlers(); } return TRUE; diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 222d7328387..307932b0bf0 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -238,6 +238,7 @@ extern void X11DRV_SetWindowStyle( HWND hwnd, INT offset, STYLESTRUCT *style ) D extern void X11DRV_SetWindowText( HWND hwnd, LPCWSTR text ) DECLSPEC_HIDDEN; extern UINT X11DRV_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp ) DECLSPEC_HIDDEN; extern LRESULT X11DRV_SysCommand( HWND hwnd, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN; +extern LRESULT X11DRV_ClipboardWindowProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) DECLSPEC_HIDDEN; extern void X11DRV_UpdateClipboard(void) DECLSPEC_HIDDEN; extern BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, const RECT *window_rect ) DECLSPEC_HIDDEN; @@ -833,7 +834,6 @@ static inline BOOL is_window_rect_mapped( const RECT *rect )
/* unixlib interface */
-extern NTSTATUS x11drv_clipboard_message( void *arg ) DECLSPEC_HIDDEN; extern NTSTATUS x11drv_create_desktop( void *arg ) DECLSPEC_HIDDEN; extern NTSTATUS x11drv_systray_clear( void *arg ) DECLSPEC_HIDDEN; extern NTSTATUS x11drv_systray_dock( void *arg ) DECLSPEC_HIDDEN; diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index a118757dfbe..dc987ae70a2 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -1302,7 +1302,6 @@ NTSTATUS x11drv_client_call( enum client_callback func, UINT arg )
const unixlib_entry_t __wine_unix_call_funcs[] = { - x11drv_clipboard_message, x11drv_create_desktop, x11drv_init, x11drv_systray_clear,
From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/winemac.drv/clipboard.c | 133 ++++++++--------------------------- dlls/winemac.drv/gdi.c | 2 +- dlls/winemac.drv/macdrv.h | 3 +- dlls/winemac.drv/window.c | 13 ---- 4 files changed, 33 insertions(+), 118 deletions(-)
diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c index d431728036e..16eff401a98 100644 --- a/dlls/winemac.drv/clipboard.c +++ b/dlls/winemac.drv/clipboard.c @@ -1425,7 +1425,7 @@ static UINT *get_clipboard_formats(UINT *size) for (;;) { if (!(ids = malloc(*size * sizeof(*ids)))) return NULL; - if (GetUpdatedClipboardFormats(ids, *size, size)) break; + if (NtUserGetUpdatedClipboardFormats(ids, *size, size)) break; free(ids); if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return NULL; } @@ -1579,20 +1579,44 @@ static void update_clipboard(void) }
+static BOOL init_clipboard(HWND hwnd) +{ + struct macdrv_window_features wf; + + memset(&wf, 0, sizeof(wf)); + clipboard_cocoa_window = macdrv_create_cocoa_window(&wf, CGRectMake(100, 100, 100, 100), hwnd, + macdrv_init_thread_data()->queue); + if (!clipboard_cocoa_window) + { + ERR("failed to create clipboard Cocoa window\n"); + return FALSE; + } + + clipboard_hwnd = hwnd; + clipboard_thread_id = GetCurrentThreadId(); + NtUserAddClipboardFormatListener(clipboard_hwnd); + register_builtin_formats(); + grab_win32_clipboard(); + + TRACE("clipboard thread %04x running\n", GetCurrentThreadId()); + return TRUE; +} + + /************************************************************************** - * clipboard_wndproc + * macdrv_ClipboardWindowProc * * Window procedure for the clipboard manager. */ -static LRESULT CALLBACK clipboard_wndproc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) +LRESULT macdrv_ClipboardWindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { switch (msg) { case WM_NCCREATE: - return TRUE; + return init_clipboard(hwnd); case WM_CLIPBOARDUPDATE: if (is_clipboard_owner) break; /* ignore our own changes */ - if ((LONG)(GetClipboardSequenceNumber() - last_get_seqno) <= 0) break; + if ((LONG)(NtUserGetClipboardSequenceNumber() - last_get_seqno) <= 0) break; set_mac_pasteboard_types_from_win32_clipboard(); break; case WM_RENDERFORMAT: @@ -1605,95 +1629,13 @@ static LRESULT CALLBACK clipboard_wndproc(HWND hwnd, UINT msg, WPARAM wp, LPARAM case WM_DESTROYCLIPBOARD: TRACE("WM_DESTROYCLIPBOARD: lost ownership\n"); is_clipboard_owner = FALSE; - KillTimer(hwnd, 1); + NtUserKillTimer(hwnd, 1); break; case WM_USER: update_clipboard(); 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; -} - - -/************************************************************************** - * clipboard_thread - * - * Thread running inside the desktop process to manage the clipboard - */ -static DWORD WINAPI clipboard_thread(void *arg) -{ - WNDCLASSW class; - struct macdrv_window_features wf; - 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 (!(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; - } - - memset(&wf, 0, sizeof(wf)); - clipboard_cocoa_window = macdrv_create_cocoa_window(&wf, CGRectMake(100, 100, 100, 100), clipboard_hwnd, - macdrv_init_thread_data()->queue); - if (!clipboard_cocoa_window) - { - ERR("failed to create clipboard Cocoa window\n"); - goto done; - } - - clipboard_thread_id = GetCurrentThreadId(); - NtUserAddClipboardFormatListener(clipboard_hwnd); - register_builtin_formats(); - grab_win32_clipboard(); - - TRACE("clipboard thread %04x running\n", GetCurrentThreadId()); - while (GetMessageW(&msg, 0, 0, 0)) DispatchMessageW(&msg); - -done: - macdrv_destroy_cocoa_window(clipboard_cocoa_window); - DestroyWindow(clipboard_hwnd); - return 0; + return NtUserMessageCall(hwnd, msg, wp, lp, NULL, NtUserDefWindowProc, FALSE); }
@@ -1804,16 +1746,3 @@ void macdrv_lost_pasteboard_ownership(HWND hwnd) if (!macdrv_is_pasteboard_owner(clipboard_cocoa_window)) grab_win32_clipboard(); } - - -/************************************************************************** - * macdrv_init_clipboard - */ -void macdrv_init_clipboard(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/winemac.drv/gdi.c b/dlls/winemac.drv/gdi.c index 8d41778b472..3f83436d97a 100644 --- a/dlls/winemac.drv/gdi.c +++ b/dlls/winemac.drv/gdi.c @@ -266,8 +266,8 @@ static const struct user_driver_funcs macdrv_funcs = .pBeep = macdrv_Beep, .pChangeDisplaySettingsEx = macdrv_ChangeDisplaySettingsEx, .pClipCursor = macdrv_ClipCursor, + .pClipboardWindowProc = macdrv_ClipboardWindowProc, .pCreateDesktopWindow = macdrv_CreateDesktopWindow, - .pCreateWindow = macdrv_CreateWindow, .pDesktopWindowProc = macdrv_DesktopWindowProc, .pDestroyCursorIcon = macdrv_DestroyCursorIcon, .pDestroyWindow = macdrv_DestroyWindow, diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 26028247a96..9cd0509a39c 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -128,13 +128,13 @@ extern LONG macdrv_ChangeDisplaySettingsEx(LPCWSTR devname, LPDEVMODEW devmode, HWND hwnd, DWORD flags, LPVOID lpvoid) DECLSPEC_HIDDEN; extern BOOL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, LPDEVMODEW devmode, DWORD flags) DECLSPEC_HIDDEN; +extern LRESULT macdrv_ClipboardWindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) DECLSPEC_HIDDEN; extern void macdrv_UpdateDisplayDevices( const struct gdi_device_manager *device_manager, BOOL force, void *param ) DECLSPEC_HIDDEN; extern BOOL macdrv_GetDeviceGammaRamp(PHYSDEV dev, LPVOID ramp) DECLSPEC_HIDDEN; extern BOOL macdrv_SetDeviceGammaRamp(PHYSDEV dev, LPVOID ramp) DECLSPEC_HIDDEN; extern BOOL macdrv_ClipCursor(LPCRECT clip) DECLSPEC_HIDDEN; extern BOOL macdrv_CreateDesktopWindow(HWND hwnd) DECLSPEC_HIDDEN; -extern BOOL macdrv_CreateWindow(HWND hwnd) DECLSPEC_HIDDEN; extern LRESULT macdrv_DesktopWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) DECLSPEC_HIDDEN; extern void macdrv_DestroyWindow(HWND hwnd) DECLSPEC_HIDDEN; extern void macdrv_SetFocus(HWND hwnd) DECLSPEC_HIDDEN; @@ -252,7 +252,6 @@ extern HKL macdrv_get_hkl_from_source(TISInputSourceRef input_source) DECLSPEC_H extern void macdrv_displays_changed(const macdrv_event *event) DECLSPEC_HIDDEN;
extern void macdrv_UpdateClipboard(void) DECLSPEC_HIDDEN; -extern void macdrv_init_clipboard(void) DECLSPEC_HIDDEN; extern BOOL query_pasteboard_data(HWND hwnd, CFStringRef type) DECLSPEC_HIDDEN; extern void macdrv_lost_pasteboard_ownership(HWND hwnd) DECLSPEC_HIDDEN; extern const char *debugstr_format(UINT id) DECLSPEC_HIDDEN; diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index 59788244c22..2f473730b2f 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -1593,19 +1593,6 @@ LRESULT macdrv_DesktopWindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) return NtUserMessageCall(hwnd, msg, wp, lp, 0, NtUserDefWindowProc, FALSE); }
-/********************************************************************** - * CreateWindow (MACDRV.@) - */ -BOOL macdrv_CreateWindow(HWND hwnd) -{ - if (hwnd == NtUserGetDesktopWindow()) - { - macdrv_init_clipboard(); - } - return TRUE; -} - - /*********************************************************************** * DestroyWindow (MACDRV.@) */
From: Jacek Caban jacek@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53020 Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/user32/user_main.c | 1 + dlls/win32u/driver.c | 7 +++++-- dlls/win32u/ntuser_private.h | 1 + 3 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index 9cd9bd60146..e470d2ad688 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -162,6 +162,7 @@ static const struct user_callbacks user_funcs = EndMenu, ImmProcessKey, ImmTranslateMessage, + NtWaitForMultipleObjects, free_win_ptr, MENU_GetSysMenu, MENU_IsMenuActive, diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index b4cea3d42c8..1f538d100ed 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -813,8 +813,11 @@ static NTSTATUS nulldrv_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE * { if (!count && timeout && !timeout->QuadPart) return WAIT_TIMEOUT;
- return NtWaitForMultipleObjects( count, handles, !(flags & MWMO_WAITALL), - !!(flags & MWMO_ALERTABLE), timeout ); + if (!user_callbacks) + return NtWaitForMultipleObjects( count, handles, !(flags & MWMO_WAITALL), + !!(flags & MWMO_ALERTABLE), timeout ); + return user_callbacks->pNtWaitForMultipleObjects( count, handles, !(flags & MWMO_WAITALL), + !!(flags & MWMO_ALERTABLE), timeout ); }
static void nulldrv_ReleaseDC( HWND hwnd, HDC hdc ) diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 931c87a6e1c..e39e3f54169 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -35,6 +35,7 @@ struct user_callbacks BOOL (WINAPI *pEndMenu)(void); BOOL (WINAPI *pImmProcessKey)(HWND, HKL, UINT, LPARAM, DWORD); BOOL (WINAPI *pImmTranslateMessage)(HWND, UINT, WPARAM, LPARAM); + NTSTATUS (WINAPI *pNtWaitForMultipleObjects)(ULONG,const HANDLE*,BOOLEAN,BOOLEAN,const LARGE_INTEGER*); void (CDECL *free_win_ptr)( struct tagWND *win ); HMENU (CDECL *get_sys_menu)( HWND hwnd, HMENU popup ); HWND (CDECL *is_menu_active)(void);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=115874
Your paranoid android.
=== debian11 (64 bit WoW report) ===
user32: msg.c:8724: Test failed: WmParentPaintNc: 0: the msg 0x000f was expected, but got msg 0x0021 instead msg.c:8724: Test failed: WmParentPaintNc: 1: the msg 0x000f was expected, but got msg 0x0021 instead msg.c:8724: Test failed: WmParentPaintNc: 2: the msg 0x0085 was expected, but got msg 0x0021 instead msg.c:8724: Test failed: WmParentPaintNc: 6: the msg sequence is not complete: expected 0000 - actual 000f
This merge request was approved by Huw Davies.