[PATCH v2 1/9] winex11: Introduce x11drv_client_call.
Jacek Caban
wine at gitlab.winehq.org
Thu May 5 08:42:36 CDT 2022
From: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Jacek Caban <jacek at 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
};
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/39
More information about the wine-devel
mailing list