winex11: Introduce x11drv_client_call.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2022-05-03 01:07:17 +02:00 committed by Alexandre Julliard
parent d823e344c8
commit 040d1f9bbd
8 changed files with 112 additions and 64 deletions

View File

@ -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;
}

View File

@ -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( &params );
effect = x11drv_client_func( client_func_dnd_position_event, &params, 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( &params );
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 );
}

View File

@ -68,8 +68,35 @@ 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
};
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_funcs_count
};
/* x11drv_callback params */
struct client_callback_params
{
UINT id;
UINT arg;
};
/* x11drv_dnd_enter_event and x11drv_dnd_post_drop params */
struct format_entry
{
UINT format;
@ -77,24 +104,9 @@ struct format_entry
char data[1];
};
enum dnd_event_type
{
DND_DROP_EVENT,
DND_LEAVE_EVENT,
DND_POSITION_EVENT,
};
/* DND_DROP_EVENT params */
struct dnd_drop_event_params
{
UINT type;
HWND hwnd;
};
/* DND_POSITION_EVENT params */
/* x11drv_dnd_position_event params */
struct dnd_position_event_params
{
UINT type;
HWND hwnd;
POINT point;
DWORD effect;

View File

@ -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;

View File

@ -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 */

View File

@ -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, &params, sizeof(params) );
}
const unixlib_entry_t __wine_unix_call_funcs[] =
{
x11drv_clipboard_message,

View File

@ -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;

View File

@ -42,6 +42,9 @@ enum
/* Vulkan support */
NtUserCallVulkanDebugReportCallback,
NtUserCallVulkanDebugUtilsCallback,
/* Driver-specific callbacks */
NtUserDriverCallbackFirst,
NtUserDriverCallbackLast = NtUserDriverCallbackFirst + 10,
NtUserCallCount
};