|
|
@@ -50,6 +50,10 @@ static Atom xinput2_rel_y_atom;
|
|
|
static Atom xinput2_abs_x_atom;
|
|
|
static Atom xinput2_abs_y_atom;
|
|
|
|
|
|
+// Pointer button remapping table
|
|
|
+static unsigned char *xinput2_pointer_button_map;
|
|
|
+static int xinput2_pointer_button_map_size;
|
|
|
+
|
|
|
#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_SCROLLINFO
|
|
|
typedef struct
|
|
|
{
|
|
|
@@ -328,6 +332,7 @@ bool X11_InitXinput2(SDL_VideoDevice *_this)
|
|
|
X11_XISelectEvents(data->display, DefaultRootWindow(data->display), &eventmask, 1);
|
|
|
|
|
|
X11_Xinput2UpdateDevices(_this);
|
|
|
+ X11_Xinput2UpdatePointerMapping(_this);
|
|
|
|
|
|
return true;
|
|
|
#else
|
|
|
@@ -337,6 +342,10 @@ bool X11_InitXinput2(SDL_VideoDevice *_this)
|
|
|
|
|
|
void X11_QuitXinput2(SDL_VideoDevice *_this)
|
|
|
{
|
|
|
+ SDL_free(xinput2_pointer_button_map);
|
|
|
+ xinput2_pointer_button_map = NULL;
|
|
|
+ xinput2_pointer_button_map_size = 0;
|
|
|
+
|
|
|
#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_SCROLLINFO
|
|
|
for (int i = 0; i < scrollable_device_count; ++i) {
|
|
|
SDL_free(scrollable_devices[i].scroll_info);
|
|
|
@@ -347,6 +356,29 @@ void X11_QuitXinput2(SDL_VideoDevice *_this)
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+void X11_Xinput2UpdatePointerMapping(SDL_VideoDevice *_this)
|
|
|
+{
|
|
|
+#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2
|
|
|
+ if (X11_Xinput2IsInitialized()) {
|
|
|
+ SDL_VideoData *vid = _this->internal;
|
|
|
+
|
|
|
+ SDL_free(xinput2_pointer_button_map);
|
|
|
+ xinput2_pointer_button_map = NULL;
|
|
|
+ xinput2_pointer_button_map_size = 0;
|
|
|
+
|
|
|
+ xinput2_pointer_button_map_size = X11_XGetPointerMapping(vid->display, NULL, 0);
|
|
|
+ if (xinput2_pointer_button_map_size) {
|
|
|
+ xinput2_pointer_button_map = SDL_calloc(xinput2_pointer_button_map_size, sizeof(unsigned char));
|
|
|
+ if (xinput2_pointer_button_map) {
|
|
|
+ xinput2_pointer_button_map_size = X11_XGetPointerMapping(vid->display, xinput2_pointer_button_map, xinput2_pointer_button_map_size);
|
|
|
+ } else {
|
|
|
+ xinput2_pointer_button_map_size = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2
|
|
|
// xi2 device went away? take it out of the list.
|
|
|
static void xinput2_remove_device_info(SDL_VideoData *videodata, const int device_id)
|
|
|
@@ -562,7 +594,7 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie)
|
|
|
{
|
|
|
const XIDeviceEvent *xev = (const XIDeviceEvent *)cookie->data;
|
|
|
X11_PenHandle *pen = X11_FindPenByDeviceID(xev->sourceid);
|
|
|
- const int button = xev->detail;
|
|
|
+ int button = xev->detail;
|
|
|
const bool down = (cookie->evtype == XI_ButtonPress);
|
|
|
#if defined(SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_SCROLLINFO) || defined(SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH)
|
|
|
bool pointer_emulated = (xev->flags & XIPointerEmulated) != 0;
|
|
|
@@ -587,6 +619,13 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie)
|
|
|
SDL_WindowData *windowdata = xinput2_get_sdlwindowdata(videodata, xev->event);
|
|
|
int x_ticks = 0, y_ticks = 0;
|
|
|
|
|
|
+ // Slave pointer devices don't have button remapping applied automatically, so do it manually.
|
|
|
+ if (xev->deviceid != videodata->xinput_master_pointer_device) {
|
|
|
+ if (button <= xinput2_pointer_button_map_size) {
|
|
|
+ button = xinput2_pointer_button_map[button - 1];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/* Discard wheel events from "Master" devices to avoid duplicates,
|
|
|
* as coarse wheel events are stateless and can't be deduplicated.
|
|
|
*
|