wine-staging/patches/user32-rawinput-mouse/0005-winex11-Keep-track-of-mouse-device-and-pointer-butto.patch
2024-05-03 07:32:40 +10:00

244 lines
7.3 KiB
Diff

From a0452d319eecec33d0e130e19e9d1993b52caa2f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 19 Dec 2019 22:34:44 +0100
Subject: [PATCH] winex11: Keep track of mouse device and pointer button
mappings.
We are going to receive raw button events and we will need to apply the
correct button mappings ourselves.
Original patch by Andrew Eikum <aeikum@codeweavers.com>.
---
configure.ac | 1 +
dlls/winex11.drv/keyboard.c | 24 +++++++--
dlls/winex11.drv/mouse.c | 93 +++++++++++++++++++++++++++++++++-
dlls/winex11.drv/x11drv.h | 1 +
dlls/winex11.drv/x11drv_main.c | 1 +
5 files changed, 114 insertions(+), 6 deletions(-)
diff --git a/configure.ac b/configure.ac
index d95ff178367..5d38e874089 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1194,6 +1194,7 @@ then
dnl *** All of the following tests require X11/Xlib.h
AC_CHECK_HEADERS([X11/extensions/shape.h \
+ X11/extensions/XInput.h \
X11/extensions/XInput2.h \
X11/extensions/XShm.h \
X11/extensions/Xfixes.h \
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index 23f07b851a7..130b7e516a2 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -1838,11 +1838,7 @@ BOOL X11DRV_ActivateKeyboardLayout(HKL hkl, UINT flags)
return TRUE;
}
-
-/***********************************************************************
- * X11DRV_MappingNotify
- */
-BOOL X11DRV_MappingNotify( HWND dummy, XEvent *event )
+static BOOL X11DRV_KeyboardMappingNotify( HWND dummy, XEvent *event )
{
HWND hwnd;
@@ -1856,6 +1852,24 @@ BOOL X11DRV_MappingNotify( HWND dummy, XEvent *event )
return TRUE;
}
+/***********************************************************************
+ * X11DRV_MappingNotify
+ */
+BOOL X11DRV_MappingNotify( HWND dummy, XEvent *event )
+{
+ switch (event->xmapping.request)
+ {
+ case MappingModifier:
+ case MappingKeyboard:
+ return X11DRV_KeyboardMappingNotify( dummy, event );
+ case MappingPointer:
+ X11DRV_InitMouse( event->xmapping.display );
+ break;
+ }
+
+ return TRUE;
+}
+
/***********************************************************************
* VkKeyScanEx (X11DRV.@)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index d3c97468fdb..5a5ec51e370 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -31,6 +31,9 @@
#include <X11/cursorfont.h>
#include <stdarg.h>
#include <stdint.h>
+#ifdef HAVE_X11_EXTENSIONS_XINPUT_H
+#include <X11/extensions/XInput.h>
+#endif
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
#include <X11/extensions/XInput2.h>
#endif
@@ -142,6 +145,14 @@ MAKE_FUNCPTR(XISelectEvents);
#undef MAKE_FUNCPTR
#endif
+#ifdef HAVE_X11_EXTENSIONS_XINPUT_H
+#define MAKE_FUNCPTR(f) static typeof(f) * p##f
+MAKE_FUNCPTR(XOpenDevice);
+MAKE_FUNCPTR(XCloseDevice);
+MAKE_FUNCPTR(XGetDeviceButtonMapping);
+#undef MAKE_FUNCPTR
+#endif
+
/***********************************************************************
* X11DRV_Xcursor_Init
*
@@ -229,6 +240,75 @@ void set_window_cursor( Window window, HCURSOR handle )
XFlush( gdi_display );
}
+struct mouse_button_mapping
+{
+ int deviceid;
+ unsigned int button_count;
+ unsigned char buttons[256];
+};
+
+static struct mouse_button_mapping *pointer_mapping;
+static struct mouse_button_mapping *device_mapping;
+
+#ifdef HAVE_X11_EXTENSIONS_XINPUT_H
+
+static void update_pointer_mapping( Display *display )
+{
+ struct mouse_button_mapping *tmp;
+
+ if (!(tmp = malloc( sizeof(*tmp) )))
+ {
+ WARN("Unable to allocate device mapping.\n");
+ return;
+ }
+
+ tmp->button_count = ARRAY_SIZE( tmp->buttons );
+ tmp->button_count = XGetPointerMapping( display, tmp->buttons, tmp->button_count );
+
+ free( InterlockedExchangePointer( (void**)&pointer_mapping, tmp ) );
+}
+
+static void update_device_mapping( Display *display, int deviceid )
+{
+ struct mouse_button_mapping *tmp;
+ XDevice *device;
+
+ if (!(device = pXOpenDevice( display, deviceid )))
+ {
+ WARN( "Unable to open cursor device %d\n", deviceid );
+ return;
+ }
+
+ if (!(tmp = malloc( sizeof(*tmp) )))
+ {
+ WARN( "Unable to allocate device mapping.\n" );
+ pXCloseDevice( display, device );
+ return;
+ }
+
+ tmp->deviceid = deviceid;
+ tmp->button_count = ARRAY_SIZE( tmp->buttons );
+ tmp->button_count = pXGetDeviceButtonMapping( display, device, tmp->buttons, tmp->button_count );
+
+ free( InterlockedExchangePointer( (void**)&device_mapping, tmp ) );
+
+ pXCloseDevice( display, device );
+}
+
+void X11DRV_InitMouse( Display *display )
+{
+ update_pointer_mapping( display );
+}
+
+#else /* HAVE_X11_EXTENSIONS_XINPUT_H */
+
+void X11DRV_InitMouse( Display *display )
+{
+}
+
+#endif /* HAVE_X11_EXTENSIONS_XINPUT_H */
+
+
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
/***********************************************************************
* update_relative_valuators
@@ -1674,6 +1754,8 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev )
if (event->deviceid != data->xinput2_pointer) return FALSE;
update_relative_valuators( event->classes, event->num_classes );
+ update_device_mapping( event->display, event->sourceid );
+
return TRUE;
}
@@ -1822,7 +1904,7 @@ static BOOL X11DRV_TouchEvent( HWND hwnd, XGenericEventCookie *xev )
*/
void x11drv_xinput2_load(void)
{
-#if defined(SONAME_LIBXI) && defined(HAVE_X11_EXTENSIONS_XINPUT2_H)
+#if defined(SONAME_LIBXI)
int event, error;
void *libxi_handle = dlopen( SONAME_LIBXI, RTLD_NOW );
@@ -1838,11 +1920,20 @@ void x11drv_xinput2_load(void)
return; \
}
+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
LOAD_FUNCPTR(XIGetClientPointer);
LOAD_FUNCPTR(XIFreeDeviceInfo);
LOAD_FUNCPTR(XIQueryDevice);
LOAD_FUNCPTR(XIQueryVersion);
LOAD_FUNCPTR(XISelectEvents);
+#endif
+
+#ifdef HAVE_X11_EXTENSIONS_XINPUT_H
+ LOAD_FUNCPTR(XOpenDevice);
+ LOAD_FUNCPTR(XCloseDevice);
+ LOAD_FUNCPTR(XGetDeviceButtonMapping);
+#endif
+
#undef LOAD_FUNCPTR
xinput2_available = XQueryExtension( gdi_display, "XInputExtension", &xinput2_opcode, &event, &error );
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 70ef0a112ac..a56eb8b0046 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -682,6 +682,7 @@ extern void retry_grab_clipping_window(void);
extern void ungrab_clipping_window(void);
extern void move_resize_window( HWND hwnd, int dir );
extern void X11DRV_InitKeyboard( Display *display );
+extern void X11DRV_InitMouse( Display *display );
extern BOOL process_events( Display *display, Bool (*filter)(Display*, XEvent*, XPointer), ULONG_PTR arg );
extern BOOL X11DRV_ProcessEvents( DWORD mask );
extern HWND *build_hwnd_list(void);
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index c9e0d43c9ce..930f3a1c088 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -680,6 +680,7 @@ static NTSTATUS x11drv_init( void *arg )
XkbUseExtension( gdi_display, NULL, NULL );
X11DRV_InitKeyboard( gdi_display );
+ X11DRV_InitMouse( gdi_display );
if (use_xim) use_xim = xim_init( input_style );
init_user_driver();
--
2.43.0