From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/winex11.drv/dllmain.c | 38 ++++++++++++++++++++++++++++-- dlls/winex11.drv/event.c | 15 ++++-------- dlls/winex11.drv/unixlib.h | 42 ++++++++++++++++++++++------------ dlls/winex11.drv/window.c | 2 +- dlls/winex11.drv/x11drv.h | 16 +++++++++---- dlls/winex11.drv/x11drv_main.c | 15 ++++++++++++ dlls/winex11.drv/xdnd.c | 41 ++++++++++----------------------- include/ntuser.h | 3 +++ 8 files changed, 110 insertions(+), 62 deletions(-)
diff --git a/dlls/winex11.drv/dllmain.c b/dlls/winex11.drv/dllmain.c index 6a9f4a57273..751b6ec08a4 100644 --- a/dlls/winex11.drv/dllmain.c +++ b/dlls/winex11.drv/dllmain.c @@ -116,23 +116,57 @@ static DWORD WINAPI clipboard_thread( void *arg ) }
-void X11DRV_InitClipboard(void) +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; }
+typedef NTSTATUS (*callback_func)( UINT arg ); +static const callback_func callback_funcs[] = +{ + x11drv_clipboard_init, + x11drv_dnd_drop_event, + x11drv_dnd_leave_event, +}; + +C_ASSERT( ARRAYSIZE(callback_funcs) == client_funcs_count ); + +static NTSTATUS WINAPI x11drv_callback( void *arg, ULONG size ) +{ + struct client_callback_params *params = arg; + return callback_funcs[params->id]( params->arg ); +} + +typedef NTSTATUS (WINAPI *kernel_callback)( void *params, ULONG size ); +static const kernel_callback kernel_callbacks[] = +{ + x11drv_callback, + x11drv_dnd_enter_event, + x11drv_dnd_position_event, + x11drv_dnd_post_drop, +}; + +C_ASSERT( NtUserDriverCallbackFirst + ARRAYSIZE(kernel_callbacks) == client_func_last ); + BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved ) { + void **callback_table; + if (reason != DLL_PROCESS_ATTACH) return TRUE;
DisableThreadLibraryCalls( instance ); x11drv_module = instance; - return !X11DRV_CALL( init, NULL ); + if (X11DRV_CALL( init, NULL )) return FALSE; + + callback_table = NtCurrentTeb()->Peb->KernelCallbackTable; + memcpy( callback_table + NtUserDriverCallbackFirst, kernel_callbacks, sizeof(kernel_callbacks) ); + return TRUE; }
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 105caab5deb..cefc86d0902 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1479,7 +1479,7 @@ static HWND find_drop_window( HWND hQueryWnd, LPPOINT lpPt ) static void post_drop( HWND hwnd, DROPFILES *drop, ULONG size ) { drop->fWide = HandleToUlong( hwnd ); /* abuse fWide to pass window handle */ - x11drv_post_drop( drop, size ); + x11drv_client_func( client_func_dnd_post_drop, drop, size ); }
/********************************************************************** @@ -1744,7 +1744,7 @@ static void handle_xdnd_enter_event( HWND hWnd, XClientMessageEvent *event ) xdndtypes, count, &size ); if (data) { - handle_dnd_enter_event( data, size ); + x11drv_client_func( client_func_dnd_enter_event, data, size ); free( data ); }
@@ -1795,12 +1795,11 @@ static void handle_xdnd_position_event( HWND hwnd, XClientMessageEvent *event ) XClientMessageEvent e; DWORD effect;
- params.type = DND_POSITION_EVENT; params.hwnd = hwnd; params.point = root_to_virtual_screen( event->data.l[2] >> 16, event->data.l[2] & 0xFFFF ); params.effect = effect = xdnd_action_to_drop_effect( event->data.l[4] );
- effect = handle_dnd_event( ¶ms ); + effect = x11drv_client_func( client_func_dnd_position_event, ¶ms, sizeof(params) );
TRACE( "actionRequested(%ld) chosen(0x%x) at x(%d),y(%d)\n", event->data.l[4], effect, params.point.x, params.point.y ); @@ -1825,13 +1824,10 @@ static void handle_xdnd_position_event( HWND hwnd, XClientMessageEvent *event )
static void handle_xdnd_drop_event( HWND hwnd, XClientMessageEvent *event ) { - struct dnd_drop_event_params params; XClientMessageEvent e; DWORD effect;
- params.type = DND_DROP_EVENT; - params.hwnd = hwnd; - effect = handle_dnd_event( ¶ms ); + effect = x11drv_client_call( client_dnd_drop_event, HandleToUlong( hwnd ));
/* Tell the target we are finished. */ memset( &e, 0, sizeof(e) ); @@ -1849,8 +1845,7 @@ static void handle_xdnd_drop_event( HWND hwnd, XClientMessageEvent *event )
static void handle_xdnd_leave_event( HWND hwnd, XClientMessageEvent *event ) { - UINT type = DND_LEAVE_EVENT; - handle_dnd_event( &type ); + x11drv_client_call( client_dnd_leave_event, 0 ); }
diff --git a/dlls/winex11.drv/unixlib.h b/dlls/winex11.drv/unixlib.h index 2a957af0f56..ec5f75a1697 100644 --- a/dlls/winex11.drv/unixlib.h +++ b/dlls/winex11.drv/unixlib.h @@ -68,33 +68,45 @@ struct xim_preedit_state_params BOOL open; };
-/* DnD support */ +/* driver client callbacks exposed with KernelCallbackTable interface */ +enum x11drv_client_funcs +{ + client_func_callback = NtUserDriverCallbackFirst, + client_func_dnd_enter_event, + client_func_dnd_position_event, + client_func_dnd_post_drop, + client_func_last +};
-struct format_entry +C_ASSERT( client_func_last <= NtUserDriverCallbackLast + 1 ); + +/* simplified interface for client callbacks requiring only a single UINT parameter */ +enum client_callback { - UINT format; - UINT size; - char data[1]; + client_clipboard_init, + client_dnd_drop_event, + client_dnd_leave_event, + client_funcs_count };
-enum dnd_event_type +/* x11drv_callback params */ +struct client_callback_params { - DND_DROP_EVENT, - DND_LEAVE_EVENT, - DND_POSITION_EVENT, + UINT id; + UINT arg; };
-/* DND_DROP_EVENT params */ -struct dnd_drop_event_params +/* x11drv_dnd_enter_event and x11drv_dnd_post_drop params */ +struct format_entry { - UINT type; - HWND hwnd; + UINT format; + UINT size; + char data[1]; };
-/* DND_POSITION_EVENT params */ +/* x11drv_dnd_position_event params */ struct dnd_position_event_params { - UINT type; HWND hwnd; POINT point; DWORD effect; diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index de52023c467..7ccec4ee4ec 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1904,7 +1904,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd ) CWOverrideRedirect | CWEventMask, &attr ); XFlush( data->display ); NtUserSetProp( hwnd, clip_window_prop, (HANDLE)data->clip_window ); - X11DRV_InitClipboard(); + 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 c6e5044c110..02eb67c9cc2 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -296,9 +296,6 @@ extern BOOL IME_SetCompositionString(DWORD dwIndex, LPCVOID lpComp, extern void IME_SetResultString(LPWSTR lpResult, DWORD dwResultlen) DECLSPEC_HIDDEN;
-extern void handle_dnd_enter_event( struct format_entry *formats, ULONG size ) DECLSPEC_HIDDEN; -extern UINT handle_dnd_event( void *params ) DECLSPEC_HIDDEN; - extern struct format_entry *import_xdnd_selection( Display *display, Window win, Atom selection, Atom *targets, UINT count, size_t *size ) DECLSPEC_HIDDEN; @@ -677,7 +674,6 @@ extern XContext winContext DECLSPEC_HIDDEN; /* X context to associate an X cursor to a Win32 cursor handle */ extern XContext cursor_context DECLSPEC_HIDDEN;
-extern void X11DRV_InitClipboard(void) DECLSPEC_HIDDEN; extern void X11DRV_SetFocus( HWND hwnd ) DECLSPEC_HIDDEN; extern void set_window_cursor( Window window, HCURSOR handle ) DECLSPEC_HIDDEN; extern void sync_window_cursor( Window window ) DECLSPEC_HIDDEN; @@ -850,7 +846,17 @@ extern NTSTATUS x11drv_tablet_info( void *arg ) DECLSPEC_HIDDEN; extern NTSTATUS x11drv_xim_preedit_state( void *arg ) DECLSPEC_HIDDEN; extern NTSTATUS x11drv_xim_reset( void *arg ) DECLSPEC_HIDDEN;
-extern NTSTATUS WINAPI x11drv_post_drop( void *data, ULONG size ) DECLSPEC_HIDDEN; +extern NTSTATUS WINAPI x11drv_dnd_enter_event( void *params, ULONG size ) DECLSPEC_HIDDEN; +extern NTSTATUS WINAPI x11drv_dnd_position_event( void *params, ULONG size ) DECLSPEC_HIDDEN; +extern NTSTATUS WINAPI x11drv_dnd_post_drop( void *data, ULONG size ) DECLSPEC_HIDDEN; + +extern NTSTATUS x11drv_dnd_drop_event( UINT arg ) DECLSPEC_HIDDEN; +extern NTSTATUS x11drv_dnd_leave_event( UINT arg ) DECLSPEC_HIDDEN; + + +extern NTSTATUS x11drv_client_func( enum x11drv_client_funcs func, const void *params, + ULONG size ) DECLSPEC_HIDDEN; +extern NTSTATUS x11drv_client_call( enum client_callback func, UINT arg ) DECLSPEC_HIDDEN;
/* GDI helpers */
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 5347bc7c1a5..749fe2f761b 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -957,6 +957,21 @@ NTSTATUS CDECL X11DRV_D3DKMTCheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDP }
+NTSTATUS x11drv_client_func( enum x11drv_client_funcs id, const void *params, ULONG size ) +{ + /* FIXME: use KeUserModeCallback instead */ + NTSTATUS (WINAPI *func)( const void *, ULONG ) = ((void **)NtCurrentTeb()->Peb->KernelCallbackTable)[id]; + return func( params, size ); +} + + +NTSTATUS x11drv_client_call( enum client_callback func, UINT arg ) +{ + struct client_callback_params params = { .id = func, .arg = arg }; + return x11drv_client_func( client_func_callback, ¶ms, sizeof(params) ); +} + + const unixlib_entry_t __wine_unix_call_funcs[] = { x11drv_clipboard_message, diff --git a/dlls/winex11.drv/xdnd.c b/dlls/winex11.drv/xdnd.c index 45205c836be..975fe7a114b 100644 --- a/dlls/winex11.drv/xdnd.c +++ b/dlls/winex11.drv/xdnd.c @@ -176,12 +176,13 @@ static HWND window_accepting_files(HWND hwnd) }
/************************************************************************** - * X11DRV_XDND_PositionEvent + * x11drv_dnd_position_event * * Handle an XdndPosition event. */ -static BOOL handle_position_event( struct dnd_position_event_params *params ) +NTSTATUS WINAPI x11drv_dnd_position_event( void *arg, ULONG size ) { + struct dnd_position_event_params *params = arg; int accept = 0; /* Assume we're not accepting */ IDropTarget *dropTarget = NULL; DWORD effect = params->effect; @@ -264,7 +265,7 @@ static BOOL handle_position_event( struct dnd_position_event_params *params ) return accept ? effect : 0; }
-static DWORD handle_drop_event( struct dnd_drop_event_params *params ) +NTSTATUS x11drv_dnd_drop_event( UINT arg ) { IDropTarget *dropTarget; DWORD effect = XDNDDropEffect; @@ -318,7 +319,7 @@ static DWORD handle_drop_event( struct dnd_drop_event_params *params ) /* Only send WM_DROPFILES if Drop didn't succeed or DROPEFFECT_NONE was set. * Doing both causes winamp to duplicate the dropped files (#29081) */
- HWND hwnd_drop = window_accepting_files(window_from_point_dnd( params->hwnd, XDNDxy )); + HWND hwnd_drop = window_accepting_files(window_from_point_dnd( UlongToHandle(arg), XDNDxy ));
if (hwnd_drop && X11DRV_XDND_HasHDROP()) { @@ -338,11 +339,11 @@ static DWORD handle_drop_event( struct dnd_drop_event_params *params ) }
/************************************************************************** - * X11DRV_XDND_LeaveEvent + * x11drv_dnd_leave_event * * Handle an XdndLeave event. */ -static NTSTATUS handle_leave_event(void) +NTSTATUS x11drv_dnd_leave_event( UINT arg ) { IDropTarget *dropTarget;
@@ -367,10 +368,11 @@ static NTSTATUS handle_leave_event(void)
/************************************************************************** - * handle_dnd_enter_event + * x11drv_dnd_enter_event */ -void handle_dnd_enter_event( struct format_entry *formats, ULONG size ) +NTSTATUS WINAPI x11drv_dnd_enter_event( void *params, ULONG size ) { + struct format_entry *formats = params; XDNDAccepted = FALSE; X11DRV_XDND_FreeDragDropOp(); /* Clear previously cached data */
@@ -379,6 +381,7 @@ void handle_dnd_enter_event( struct format_entry *formats, ULONG size ) memcpy( xdnd_formats, formats, size ); xdnd_formats_end = (struct format_entry *)((char *)xdnd_formats + size); } + return 0; }
@@ -729,27 +732,7 @@ static IDataObjectVtbl xdndDataObjectVtbl =
static IDataObject XDNDDataObject = { &xdndDataObjectVtbl };
-UINT handle_dnd_event( void *params ) -{ - - switch (*(UINT *)params) - { - case DND_DROP_EVENT: - return handle_drop_event( params ); - - case DND_LEAVE_EVENT: - return handle_leave_event(); - - case DND_POSITION_EVENT: - return handle_position_event( params ); - - default: - ERR( "invalid event\n" ); - return 0; - } -} - -NTSTATUS WINAPI x11drv_post_drop( void *data, ULONG size ) +NTSTATUS WINAPI x11drv_dnd_post_drop( void *data, ULONG size ) { HDROP handle;
diff --git a/include/ntuser.h b/include/ntuser.h index d11cffb8950..fdc43cac8ed 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -42,6 +42,9 @@ enum /* Vulkan support */ NtUserCallVulkanDebugReportCallback, NtUserCallVulkanDebugUtilsCallback, + /* Driver-specific callbacks */ + NtUserDriverCallbackFirst, + NtUserDriverCallbackLast = NtUserDriverCallbackFirst + 10, NtUserCallCount };