Re: Xinput button mapping and middle button emulation

2016-10-27 Thread Peter Hutterer
On Mon, Oct 24, 2016 at 05:02:47PM +0200, Tobia Conforto wrote:
> 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.

yes, thanks. please re-submit as signed-off git-formatted patch though, one
nitpick below. Oh, and patches go to xorg-devel@, not xorg@

> 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.0 +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.0 +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.0 +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),

split that out into an assignment and the Queue call please, this is getting
too nested.

also, good lord, that state machine... I think we should clean that one up
and start using some enums and structs instead of just some wall of
magic numbers. feel free to volunteer for that ;)

the rest looks good, thanks.

Cheers,
   Peter


> +  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 (v

Re: Xinput button mapping and middle button emulation

2016-10-24 Thread Tobia Conforto
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.0 +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.0 +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.0 +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,
   s

Re: Xinput button mapping and middle button emulation

2016-10-17 Thread Peter Hutterer
On Mon, Oct 17, 2016 at 07:57:14PM +0200, Tobia Conforto wrote:
> > I think what you could do is map MB emulation to button 10 (that is
> > driver-internal) and then init the button mapping so that button 10 is
> > logical button 2 and button 2 is logical button 8.
> 
> Yes, but how do I map the MB emulation to button 10, short of patching
> the driver? It doesn't look like it's configurable.

oh, true. that's the one thing we apparently don't have a config option for.
so yeah, patching the driver is required then. sorry for the noise.

Cheers,
   Peter

___
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

Re: Xinput button mapping and middle button emulation

2016-10-17 Thread Tobia Conforto
> I think what you could do is map MB emulation to button 10 (that is
> driver-internal) and then init the button mapping so that button 10 is
> logical button 2 and button 2 is logical button 8.

Yes, but how do I map the MB emulation to button 10, short of patching
the driver? It doesn't look like it's configurable.

Tobia
___
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

Re: Xinput button mapping and middle button emulation

2016-10-16 Thread Peter Hutterer
On Thu, Oct 13, 2016 at 01:31:06PM +0200, Tobia Conforto wrote:
> Yes, I probably misused a couple of terms.
> 
> As you say, the middle button emulation happens in the evdev Xorg
> driver, in fact it's controlled by the "Emulate3Buttons" option. The
> kernel simply generates the MSC_SCAN and BTN_* codes that I pasted.
> 
> So, as far as I can tell, there are two ways to get what I need (which
> is middle button emulation A+B outputting button number 2, while
> having the physical button C outputting some other number instead of
> 2.)
> 
> Option 1.
> Have the Xorg driver (evdev or another?) remap button C from 2 to 8,
> while still providing an emulation for A+B to number 2. This is
> clearly something that an Xorg driver could do, but I don't know
> whether there is an existing driver that can be configured to do so,
> or if I would need to patch / write one. (Hence this thread.)
> 
> By the way, this could arguably be considered a bug in the
> Emulate3Buttons feature: if I remap button 2 to 8, because it's
> physically in a different position on the trackball, the middle button
> emulation should still output number 2, which is what is needed to
> paste stuff.

hmm, yeah, after looking at the code the ButtonMapping option merely sets
the X logical button mapping on startup, the one that is changed by all the
x client tools. There is no internal button mapping.

I think what you could do is map MB emulation to button 10 (that is
driver-internal) and then init the button mapping so that button 10 is
logical button 2 and button 2 is logical button 8. 

> Option 2.
> Change the kernel mapping between MSC_SCAN and BTN_* codes, so that
> button C won't output BTN_MIDDLE in the first place. Again, this is
> something the kernel can clearly do, but I don't know where that
> mapping is stored, and whether it can be changed without patching the
> kernel or writing an input driver.

on most usb devices it's handled by the HID code, so I don't think you can
arbitrarily remap without extra efforts. never tried though.

Cheers,
   Peter
___
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

Re: Xinput button mapping and middle button emulation

2016-10-13 Thread Tobia Conforto
Yes, I probably misused a couple of terms.

As you say, the middle button emulation happens in the evdev Xorg
driver, in fact it's controlled by the "Emulate3Buttons" option. The
kernel simply generates the MSC_SCAN and BTN_* codes that I pasted.

So, as far as I can tell, there are two ways to get what I need (which
is middle button emulation A+B outputting button number 2, while
having the physical button C outputting some other number instead of
2.)

Option 1.
Have the Xorg driver (evdev or another?) remap button C from 2 to 8,
while still providing an emulation for A+B to number 2. This is
clearly something that an Xorg driver could do, but I don't know
whether there is an existing driver that can be configured to do so,
or if I would need to patch / write one. (Hence this thread.)

By the way, this could arguably be considered a bug in the
Emulate3Buttons feature: if I remap button 2 to 8, because it's
physically in a different position on the trackball, the middle button
emulation should still output number 2, which is what is needed to
paste stuff.

Option 2.
Change the kernel mapping between MSC_SCAN and BTN_* codes, so that
button C won't output BTN_MIDDLE in the first place. Again, this is
something the kernel can clearly do, but I don't know where that
mapping is stored, and whether it can be changed without patching the
kernel or writing an input driver.

Any ideas?

-Tobia
___
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

Re: Xinput button mapping and middle button emulation

2016-10-13 Thread Peter Hutterer
On Mon, Oct 10, 2016 at 12:35:42PM +0200, Tobia Conforto wrote:
> I have a mouse with 4 physical buttons (Kensington Slimblade
> Trackball), let's call them A B C D, plus 3 axes: mouse X, Y, and
> scroll wheel. I'm using Xorg 1:7.7+13ubuntu3 on Linux Mint 18, kernel
> 4.4.0-38-generic.
> 
> Buttons A and B work out of the box as primary (button 1) and right
> click (button 3). Pressing A + B together triggers the middle button
> emulation (button 2) which is also great.
> 
> Now I'd like to map buttons C and D for my own purposes, but I cannot
> find how to map button C separately from the A+B emulation.
> 
> With the default xinput button-map, I get this mapping:
> 
> 1 A
> 2 C
> 3 B
> 4
> 5
> 6
> 7 D
> ...
> 
> If I try to map button C to 8 and D to 9, with `xinput set-button-map
> "..." 1 8 3 0 0 0 9`, then button C is mapped to 8, but the middle
> button emulation (A+B) gets mapped to button 8 too!
> 
> 1 A
> 8 C, but also A+B!
> 3 B
> 0
> 0
> 0
> 9 D
> 
> How can I map button C to an arbitrary button number (such as 8) while
> keeping the A+B emulation as button 2? Can it be done at the Xinput
> level at all?

not really. middle button emulation is done at the driver level (evdev or
libinput), the button mapping you're changing is handled by the server once
the driver sends an event. the server doesn't know whether you're pressing
the physical button or doing the emulation.

I think with evdev you could use the ButtonMapping option to remap button 2
to some other button but that definitely won't work in libinput.

> Here are the evtest codes for the 4 buttons:
> 
> A:
> type 4 (EV_MSC), code 4 (MSC_SCAN), value 90001
> type 1 (EV_KEY), code 272 (BTN_LEFT), value 1
> 
> B:
> type 4 (EV_MSC), code 4 (MSC_SCAN), value 90002
> type 1 (EV_KEY), code 273 (BTN_RIGHT), value 1
> 
> C:
> type 4 (EV_MSC), code 4 (MSC_SCAN), value ff01
> type 1 (EV_KEY), code 274 (BTN_MIDDLE), value 1
> 
> D:
> type 4 (EV_MSC), code 4 (MSC_SCAN), value ff02
> type 1 (EV_KEY), code 275 (BTN_SIDE), value 1
> 
> If Xinput cannot do it, does anybody know if I can change the mapping
> between MSC_SCAN and BTN_* without writing a kernel driver?

there isn't anything to remap short of putting a uinput device in between,
but that's a bit excessive.

Cheers,
   Peter
___
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