winex11: Support XInput2 events on individual windows.

This commit is contained in:
Rémi Bernon 2024-02-12 10:01:33 +01:00 committed by Alexandre Julliard
parent e7ff2688c8
commit 0f1322d2df
4 changed files with 48 additions and 21 deletions

View file

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

View file

@ -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 ) );
}
/***********************************************************************

View file

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

View file

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