Hi Peter
(and list)

After some digging, I found that the mapping from mouse scan code to
button number is hardcoded in the kernel driver[1], so I patched the
evdev Xorg driver to add an Emulate3Button option. It configures the
button number to emit when pressing left and right together. I
followed the style I found in the rest of the evdev driver, including
comments and man page, so I hope you'll be able to merge it.

Tobia

[1] https://github.com/torvalds/linux/blob/master/drivers/hid/hid-kensington.c
diff -ruwB xserver-xorg-input-evdev-2.10.1/aclocal.m4 xserver-xorg-input-evdev-2.10.1/aclocal.m4
--- xserver-xorg-input-evdev-2.10.1/include/evdev-properties.h	2015-08-11 07:19:19.000000000 +0200
+++ xserver-xorg-input-evdev-2.10.1_tobia/include/evdev-properties.h	2016-10-24 13:20:20.162688937 +0200
@@ -33,6 +33,8 @@
 #define EVDEV_PROP_MIDBUTTON "Evdev Middle Button Emulation"
 /* CARD32 */
 #define EVDEV_PROP_MIDBUTTON_TIMEOUT "Evdev Middle Button Timeout"
+/* CARD8 */
+#define EVDEV_PROP_MIDBUTTON_BUTTON "Evdev Middle Button Button"

 /* Wheel emulation */
 /* BOOL */
diff -ruwB xserver-xorg-input-evdev-2.10.1/include/Makefile.in xserver-xorg-input-evdev-2.10.1/include/Makefile.in
--- xserver-xorg-input-evdev-2.10.1/man/evdev.man	2015-12-03 05:40:25.000000000 +0100
+++ xserver-xorg-input-evdev-2.10.1_tobia/man/evdev.man	2016-10-24 13:20:29.750703671 +0200
@@ -94,6 +94,11 @@
 if two buttons where pressed "simultaneously" when 3 button emulation is
 enabled.  Default: 50. Property: "Evdev Middle Button Timeout".
 .TP 7
+.BI "Option \*qEmulate3Button\*q \*q" integer \*q
+Specifies the physical button number to be emitted if middle button emulation
+is triggered.
+Default: 2.  Property: "Evdev Middle Button Button".
+.TP 7
 .BI "Option \*qEmulateWheel\*q \*q" boolean \*q
 Enable/disable "wheel" emulation.  Wheel emulation means emulating button
 press/release events when the mouse is moved while a specific real button
diff -ruwB xserver-xorg-input-evdev-2.10.1/man/Makefile.in xserver-xorg-input-evdev-2.10.1/man/Makefile.in
--- xserver-xorg-input-evdev-2.10.1/src/emuMB.c	2015-11-27 01:51:26.000000000 +0100
+++ xserver-xorg-input-evdev-2.10.1_tobia/src/emuMB.c	2016-10-24 13:18:44.594541356 +0200
@@ -45,6 +45,7 @@

 static Atom prop_mbemu     = 0; /* Middle button emulation on/off property */
 static Atom prop_mbtimeout = 0; /* Middle button timeout property */
+static Atom prop_mbbutton  = 0; /* Middle button target physical button */
 /*
  * Lets create a simple finite-state machine for 3 button emulation:
  *
@@ -191,7 +192,8 @@

     pEvdev->emulateMB.pending = FALSE;
     if ((id = stateTab[pEvdev->emulateMB.state][4][0]) != 0) {
-        EvdevPostButtonEvent(pInfo, abs(id),
+        EvdevPostButtonEvent(pInfo,
+                             abs(id) == 2 ? pEvdev->emulateMB.button : abs(id),
                              (id >= 0) ? BUTTON_PRESS : BUTTON_RELEASE);
         pEvdev->emulateMB.state =
             stateTab[pEvdev->emulateMB.state][4][2];
@@ -237,12 +239,16 @@

     if ((id = stateTab[pEvdev->emulateMB.state][*btstate][0]) != 0)
     {
-        EvdevQueueButtonEvent(pInfo, abs(id), (id >= 0));
+        EvdevQueueButtonEvent(pInfo,
+                              abs(id) == 2 ? pEvdev->emulateMB.button : abs(id),
+                              id >= 0);
         ret = TRUE;
     }
     if ((id = stateTab[pEvdev->emulateMB.state][*btstate][1]) != 0)
     {
-        EvdevQueueButtonEvent(pInfo, abs(id), (id >= 0));
+        EvdevQueueButtonEvent(pInfo,
+                              abs(id) == 2 ? pEvdev->emulateMB.button : abs(id),
+                              id >= 0);
         ret = TRUE;
     }

@@ -304,6 +310,8 @@
                                                   FALSE);
     pEvdev->emulateMB.timeout = xf86SetIntOption(pInfo->options,
                                                  "Emulate3Timeout", 50);
+    pEvdev->emulateMB.button = xf86SetIntOption(pInfo->options,
+                                                "Emulate3Button", 2);
 }

 void
@@ -350,6 +358,13 @@

         if (!checkonly)
             pEvdev->emulateMB.timeout = *((CARD32*)val->data);
+    } else if (atom == prop_mbbutton)
+    {
+        if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
+            return BadMatch;
+
+        if (!checkonly)
+            pEvdev->emulateMB.button = *((CARD8*)val->data);
     }

     return Success;
@@ -368,6 +383,7 @@
     if (!dev->button) /* don't init prop for keyboards */
         return;

+    /* middle button emulation on/off */
     prop_mbemu = MakeAtom(EVDEV_PROP_MIDBUTTON, strlen(EVDEV_PROP_MIDBUTTON), TRUE);
     rc = XIChangeDeviceProperty(dev, prop_mbemu, XA_INTEGER, 8,
                                 PropModeReplace, 1,
@@ -377,6 +393,7 @@
         return;
     XISetDevicePropertyDeletable(dev, prop_mbemu, FALSE);

+    /* middle button emulation timeout */
     prop_mbtimeout = MakeAtom(EVDEV_PROP_MIDBUTTON_TIMEOUT,
                               strlen(EVDEV_PROP_MIDBUTTON_TIMEOUT),
                               TRUE);
@@ -387,5 +404,16 @@
         return;
     XISetDevicePropertyDeletable(dev, prop_mbtimeout, FALSE);

+    /* middle button emulation button to be triggered */
+    prop_mbbutton = MakeAtom(EVDEV_PROP_MIDBUTTON_BUTTON,
+                             strlen(EVDEV_PROP_MIDBUTTON_BUTTON),
+                             TRUE);
+    rc = XIChangeDeviceProperty(dev, prop_mbbutton, XA_INTEGER, 8, PropModeReplace, 1,
+                                &pEvdev->emulateMB.button, FALSE);
+
+    if (rc != Success)
+        return;
+    XISetDevicePropertyDeletable(dev, prop_mbbutton, FALSE);
+
     XIRegisterPropertyHandler(dev, EvdevMBEmuSetProperty, NULL, NULL);
 }
diff -ruwB xserver-xorg-input-evdev-2.10.1/src/evdev.h xserver-xorg-input-evdev-2.10.1/src/evdev.h
--- xserver-xorg-input-evdev-2.10.1/src/evdev.h	2015-12-03 05:40:25.000000000 +0100
+++ xserver-xorg-input-evdev-2.10.1_tobia/src/evdev.h	2016-10-24 12:54:25.420994459 +0200
@@ -181,6 +181,7 @@
         BOOL                enabled;
         BOOL                pending;     /* timer waiting? */
         int                 buttonstate; /* phys. button state */
+        int                 button;      /* phys button to emit */
         int                 state;       /* state machine (see bt3emu.c) */
         Time                expires;     /* time of expiry */
         Time                timeout;
_______________________________________________
xorg@lists.x.org: X.Org support
Archives: http://lists.freedesktop.org/archives/xorg
Info: https://lists.x.org/mailman/listinfo/xorg
Your subscription address: %(user_address)s

Reply via email to