[PATCH 0/2] MR5243: winex11: Listen on XInput2 touch events and send WM_POINTER messages.
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/winex11.drv/desktop.c | 2 ++ dlls/winex11.drv/mouse.c | 56 ++++++++++++++++++++++++-------------- dlls/winex11.drv/window.c | 9 +++++- dlls/winex11.drv/x11drv.h | 2 ++ 4 files changed, 48 insertions(+), 21 deletions(-) diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c index d6fa078e8a9..cb119c9a7be 100644 --- a/dlls/winex11.drv/desktop.c +++ b/dlls/winex11.drv/desktop.c @@ -86,6 +86,8 @@ BOOL X11DRV_CreateDesktop( const WCHAR *name, UINT width, UINT height ) 0, 0, width, height, 0, default_visual.depth, InputOutput, default_visual.visual, CWEventMask | CWCursor | CWColormap, &win_attr ); if (!win) return FALSE; + + x11drv_xinput2_enable( display, win ); XFlush( display ); X11DRV_init_desktop( win, width, height ); diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 03c2152b76b..19a82d23ab0 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -253,11 +253,10 @@ static void update_relative_valuators( XIAnyClassInfo **classes, int num_classes /*********************************************************************** - * enable_xinput2 + * x11drv_xinput2_enable */ -static void enable_xinput2(void) +void x11drv_xinput2_enable( Display *display, Window window ) { - struct x11drv_thread_data *data = x11drv_thread_data(); XIEventMask mask; unsigned char mask_bits[XIMaskLen(XI_LASTEVENT)]; @@ -267,21 +266,23 @@ static void enable_xinput2(void) mask.mask_len = sizeof(mask_bits); mask.deviceid = XIAllMasterDevices; memset( mask_bits, 0, sizeof(mask_bits) ); - XISetMask( mask_bits, XI_DeviceChanged ); - XISetMask( mask_bits, XI_RawMotion ); - XISetMask( mask_bits, XI_ButtonPress ); - pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 ); + + if (window == DefaultRootWindow( display )) + { + XISetMask( mask_bits, XI_DeviceChanged ); + XISetMask( mask_bits, XI_RawMotion ); + XISetMask( mask_bits, XI_ButtonPress ); + } + + pXISelectEvents( display, window, &mask, 1 ); } -#endif /*********************************************************************** - * disable_xinput2 + * x11drv_xinput2_disable */ -static void disable_xinput2(void) +void x11drv_xinput2_disable( Display *display, Window window ) { -#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H - struct x11drv_thread_data *data = x11drv_thread_data(); unsigned char mask_bits[XIMaskLen(XI_LASTEVENT)]; XIEventMask mask; @@ -291,9 +292,11 @@ static void disable_xinput2(void) mask.mask_len = sizeof(mask_bits); mask.deviceid = XIAllMasterDevices; memset( mask_bits, 0, sizeof(mask_bits) ); - XISetMask( mask_bits, XI_DeviceChanged ); - pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 ); -#endif + + if (window == DefaultRootWindow( display )) + XISetMask( mask_bits, XI_DeviceChanged ); + + pXISelectEvents( display, window, &mask, 1 ); } @@ -302,7 +305,6 @@ static void disable_xinput2(void) */ void x11drv_xinput2_init( struct x11drv_thread_data *data ) { -#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H unsigned char mask_bits[XIMaskLen(XI_LASTEVENT)]; int major = 2, minor = 2; XIEventMask mask; @@ -332,9 +334,23 @@ void x11drv_xinput2_init( struct x11drv_thread_data *data ) } TRACE( "XInput2 %d.%d available\n", major, minor ); -#endif } +#else /* HAVE_X11_EXTENSIONS_XINPUT2_H */ + +void x11drv_xinput2_enable( Display *display, Window window ) +{ +} + +void x11drv_xinput2_disable( Display *display, Window window ) +{ +} + +void x11drv_xinput2_init( struct x11drv_thread_data *data ) +{ +} + +#endif /* HAVE_X11_EXTENSIONS_XINPUT2_H */ /*********************************************************************** * grab_clipping_window @@ -370,7 +386,7 @@ static BOOL grab_clipping_window( const RECT *clip ) } /* enable XInput2 unless we are already clipping */ - if (!data->clipping_cursor) enable_xinput2(); + if (!data->clipping_cursor) x11drv_xinput2_enable( data->display, DefaultRootWindow( data->display ) ); TRACE( "clipping to %s win %lx\n", wine_dbgstr_rect(clip), clip_window ); @@ -403,7 +419,7 @@ static BOOL grab_clipping_window( const RECT *clip ) if (!clipping_cursor) { - disable_xinput2(); + x11drv_xinput2_disable( data->display, DefaultRootWindow( data->display ) ); return FALSE; } clip_rect = *clip; @@ -432,7 +448,7 @@ void ungrab_clipping_window(void) if (clipping_cursor) XUngrabPointer( data->display, CurrentTime ); clipping_cursor = FALSE; data->clipping_cursor = FALSE; - disable_xinput2(); + x11drv_xinput2_disable( data->display, DefaultRootWindow( data->display ) ); } /*********************************************************************** diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 84878e95e37..afa13f01277 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -362,6 +362,7 @@ static void sync_window_style( struct x11drv_win_data *data ) int mask = get_window_attributes( data, &attr ); XChangeWindowAttributes( data->display, data->whole_window, mask, &attr ); + x11drv_xinput2_enable( data->display, data->whole_window ); } } @@ -1700,6 +1701,7 @@ static void create_whole_window( struct x11drv_win_data *data ) data->vis.visual, mask, &attr ); if (!data->whole_window) goto done; + x11drv_xinput2_enable( data->display, data->whole_window ); set_initial_wm_hints( data->display, data->whole_window ); set_wm_hints( data ); @@ -1742,7 +1744,12 @@ static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_des Window xwin = (Window)NtUserGetProp( data->hwnd, foreign_window_prop ); if (xwin) { - if (!already_destroyed) XSelectInput( data->display, xwin, 0 ); + if (!already_destroyed) + { + x11drv_xinput2_disable( data->display, xwin ); + XSelectInput( data->display, xwin, 0 ); + } + XDeleteContext( data->display, xwin, winContext ); NtUserRemoveProp( data->hwnd, foreign_window_prop ); } diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 9c1b8012466..2f46522f59f 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -573,6 +573,8 @@ extern BOOL X11DRV_GenericEvent( HWND hwnd, XEvent *event ); extern int xinput2_opcode; extern void x11drv_xinput2_load(void); extern void x11drv_xinput2_init( struct x11drv_thread_data *data ); +extern void x11drv_xinput2_enable( Display *display, Window window ); +extern void x11drv_xinput2_disable( Display *display, Window window ); extern Bool (*pXGetEventData)( Display *display, XEvent /*XGenericEventCookie*/ *event ); extern void (*pXFreeEventData)( Display *display, XEvent /*XGenericEventCookie*/ *event ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5243
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/winex11.drv/mouse.c | 50 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 19a82d23ab0..8ad612b0b66 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -273,6 +273,12 @@ void x11drv_xinput2_enable( Display *display, Window window ) XISetMask( mask_bits, XI_RawMotion ); XISetMask( mask_bits, XI_ButtonPress ); } + else if (event_mask & PointerMotionMask) + { + XISetMask( mask_bits, XI_TouchBegin ); + XISetMask( mask_bits, XI_TouchUpdate ); + XISetMask( mask_bits, XI_TouchEnd ); + } pXISelectEvents( display, window, &mask, 1 ); } @@ -1742,6 +1748,44 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev ) return TRUE; } +static BOOL X11DRV_TouchEvent( HWND hwnd, XGenericEventCookie *xev ) +{ + RECT virtual = NtUserGetVirtualScreenRect(); + INPUT input = {.type = INPUT_HARDWARE}; + XIDeviceEvent *event = xev->data; + int flags = 0; + POINT pos; + + input.mi.dx = event->event_x; + input.mi.dy = event->event_y; + map_event_coords( hwnd, event->event, event->root, event->root_x, event->root_y, &input ); + pos.x = input.mi.dx * 65535 / (virtual.right - virtual.left); + pos.y = input.mi.dy * 65535 / (virtual.bottom - virtual.top); + + switch (event->evtype) + { + case XI_TouchBegin: + input.hi.uMsg = WM_POINTERDOWN; + flags |= POINTER_MESSAGE_FLAG_NEW; + TRACE("XI_TouchBegin detail %u pos %dx%d, flags %#x\n", event->detail, (int)pos.x, (int)pos.y, flags); + break; + case XI_TouchEnd: + input.hi.uMsg = WM_POINTERUP; + TRACE("XI_TouchEnd detail %u pos %dx%d, flags %#x\n", event->detail, (int)pos.x, (int)pos.y, flags); + break; + case XI_TouchUpdate: + input.hi.uMsg = WM_POINTERUPDATE; + TRACE("XI_TouchUpdate detail %u pos %dx%d, flags %#x\n", event->detail, (int)pos.x, (int)pos.y, flags); + break; + } + + input.hi.wParamL = event->detail; + input.hi.wParamH = POINTER_MESSAGE_FLAG_INRANGE | POINTER_MESSAGE_FLAG_INCONTACT | flags; + NtUserSendHardwareInput( hwnd, 0, &input, MAKELPARAM( pos.x, pos.y ) ); + + return TRUE; +} + #endif /* HAVE_X11_EXTENSIONS_XINPUT2_H */ @@ -1807,6 +1851,12 @@ BOOL X11DRV_GenericEvent( HWND hwnd, XEvent *xev ) ret = X11DRV_RawMotion( event ); break; + case XI_TouchBegin: + case XI_TouchUpdate: + case XI_TouchEnd: + ret = X11DRV_TouchEvent( hwnd, event ); + break; + default: TRACE( "Unhandled event %#x\n", event->evtype ); break; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5243
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=143739 Your paranoid android. === debian11 (build log) === ../wine/dlls/winex11.drv/mouse.c:276:14: error: ���event_mask��� undeclared (first use in this function); did you mean ���event_op���? Task: The win32 Wine build failed === debian11b (build log) === ../wine/dlls/winex11.drv/mouse.c:276:14: error: ���event_mask��� undeclared (first use in this function); did you mean ���event_op���? Task: The wow64 Wine build failed
participants (2)
-
Marvin -
Rémi Bernon