Bug 53907

Summary: Buttons on Plantronics Audio .648 USB headset are mapped to mouse button presses
Product: xorg Reporter: Alexander Dubov <oakad>
Component: Input/evdevAssignee: Peter Hutterer <peter.hutterer>
Status: RESOLVED WONTFIX QA Contact: Xorg Project Team <xorg-team>
Severity: normal    
Priority: medium CC: 5spice, ginermail, peter.hutterer
Version: unspecified   
Hardware: x86-64 (AMD64)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Attachments:
Description Flags
"evemu-describe" output for the device in question
none
"evemu-record" output containing at least a single key press for each button none

Description Alexander Dubov 2012-08-22 05:01:34 UTC
Created attachment 65925 [details]
"evemu-describe" output for the device in question

This issue was discovered on Xorg-server 1.12 with evdev 2.7.0 on linux-3.4.0.

The device in question (Plantronics Audio .648) has 4 buttons ["call", "volume up", "volume down" and "mic mute"] which upon connection of the device are mapped by evdev to mouse button presses.

dmesg snippet:
[2493902.614043] usb 5-1: new full-speed USB device number 2 using uhci_hcd
[2493902.991044] usb 5-1: New USB device found, idVendor=047f, idProduct=c013
[2493902.991049] usb 5-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[2493902.991053] usb 5-1: Product: Plantronics .Audio 648 USB
[2493902.991056] usb 5-1: Manufacturer: Plantronics
[2493903.121139] input: Plantronics Plantronics .Audio 648 USB as /devices/pci0000:00/0000:00:1d.1/usb5/5-1/5-1:1.3/input/input16
[2493903.121344] generic-usb 0003:047F:C013.0005: input,hiddev0,hidraw2: USB HID v1.00 Device [Plantronics Plantronics .Audio 648 USB] on usb-0000:00:1d.1-1/input3

Xorg.0.log snippet (custom button mapping is applied from a config file to prevent interference with mouse):

[2493903.329] (II) config/udev: Adding input device Plantronics Plantronics .Audio 648 USB (/dev/input/event14)
[2493903.329] (**) Plantronics Plantronics .Audio 648 USB: Applying InputClass "evdev Plantronics USB Headset"
[2493903.329] (II) Using input driver 'evdev' for 'Plantronics Plantronics .Audio 648 USB'
[2493903.329] (**) Plantronics Plantronics .Audio 648 USB: always reports core events
[2493903.329] (**) evdev: Plantronics Plantronics .Audio 648 USB: Device: "/dev/input/event14"
[2493903.329] (**) evdev: Plantronics Plantronics .Audio 648 USB: ButtonMapping '9 10 11 0 0 0 8'
[2493903.329] (--) evdev: Plantronics Plantronics .Audio 648 USB: Vendor 0x47f Product 0xc013
[2493903.329] (--) evdev: Plantronics Plantronics .Audio 648 USB: Found 9 mouse buttons
[2493903.329] (II) evdev: Plantronics Plantronics .Audio 648 USB: Configuring as mouse
[2493903.329] (**) evdev: Plantronics Plantronics .Audio 648 USB: YAxisMapping: buttons 4 and 5
[2493903.329] (**) evdev: Plantronics Plantronics .Audio 648 USB: EmulateWheelButton: 4, EmulateWheelInertia: 10, EmulateWheelTimeout: 200
[2493903.329] (**) Option "config_info" "udev:/sys/devices/pci0000:00/0000:00:1d.1/usb5/5-1/5-1:1.3/input/input16/event14"
[2493903.329] (II) XINPUT: Adding extended input device "Plantronics Plantronics .Audio 648 USB" (type: MOUSE, id 10)

evemu diagnostics are attached separately.
Comment 1 Alexander Dubov 2012-08-22 05:02:34 UTC
Created attachment 65926 [details]
"evemu-record" output containing at least a single key press for each button
Comment 2 Peter Hutterer 2012-08-23 06:38:32 UTC
from the device: 
    Event code 256 (BTN_0)
    Event code 257 (BTN_1)
    Event code 258 (BTN_2)
    Event code 259 (BTN_3)
    Event code 260 (BTN_4)

So this device really just advertises 5 buttons without any semantic meaning. If you want those to be more semantic, you'd have to fix the kernel to assign the keycodes to it.
Comment 3 Alexander Dubov 2012-08-23 07:48:50 UTC
It is not feasible to modify the kernel for every such device, you will surely agree.

At the very least, can these buttons, semantics meaning notwithstanding, be mapped to "keyboard" key presses rather than mouse ones? One approach is to may be add a configurable option to evdev to force the device type.

There's also an issue of why this device is being recognized as mouse in the first place? It is not a mouse, it has no axis, etc. That's why I asked whether it's feasible to introduce a new device class for such devices, which is neither keyboard nor mouse.
Comment 4 Peter Hutterer 2012-08-23 23:30:51 UTC
(In reply to comment #3)
> It is not feasible to modify the kernel for every such device, you will surely
> agree.

it is a surprising amount of work to get this done in X as well, and even if it could be done, it'd still be the wrong place in the stack to do it. see below.
 
> At the very least, can these buttons, semantics meaning notwithstanding, be
> mapped to "keyboard" key presses rather than mouse ones? One approach is to may
> be add a configurable option to evdev to force the device type.
> 
> There's also an issue of why this device is being recognized as mouse in the
> first place? It is not a mouse, it has no axis, etc. That's why I asked whether
> it's feasible to introduce a new device class for such devices, which is
> neither keyboard nor mouse.

X only knows about two types of devices, pointer devices (buttons and/or axes) and keyboards. This device has buttons, hence the initialisation as pointer device.

To get the device initialised as keyboard device, you need to modify the driver to skip the button init process but instead set up a full keyboard device. Then you'll need to re-map the buttons into keycodes on the fly. Evdev is already quite a messy codebase, adding this would only make it worse.

Besides, I really think that if you need a generic solution for this (instead of just for one device) then that solution must be in the client stack, not in the driver where it's hidden from everything and doesn't expose the necessary reconfigurability. What you really need is integration into e.g. GNOME so that you can assign a function to a button on a specific device, and GNOME will handle the required actions. It already does so for Wacom tablets' buttons, so extending this to other devices seems like the right choice.
Comment 5 Alexander Dubov 2012-08-24 05:13:03 UTC
My thinking was exactly about creating an option in xorg.conf to the tune of:

Option "KeyMapping" "<key code> <key code>"

The idea is to force the device into keyboard mode and create a mapping with the set of key codes specified.

At the very least, various user utilities can work with arbitrary key mappings but almost nobody supports arbitrary mouse button mappings.

Not to mention the sorry fact that connecting such device to a computer _immediately_ starts causing annoying, undesired behavior (assuming, not everybody uses gnome and gnome apps - I, for one, rely on quite a few "non-DE" ones). Mapping some loose buttons to first 3 mouse buttons by default is almost the worst default behavior one can expect.

If you don't feel like doing it I can try to tinker with it myself, but would you be willing to accept such a solution into the xorg tree?
Comment 6 Peter Hutterer 2012-08-24 06:50:07 UTC
(In reply to comment #5)
> My thinking was exactly about creating an option in xorg.conf to the tune of:
> 
> Option "KeyMapping" "<key code> <key code>"
> 
> The idea is to force the device into keyboard mode and create a mapping with
> the set of key codes specified.

IIRC we actually had something similar in evdev 1.2 or so and ripped it out because it was too complex.
 
> At the very least, various user utilities can work with arbitrary key mappings
> but almost nobody supports arbitrary mouse button mappings.

Fix the tools? We can't keep putting kludges into X drivers to save tool developers from doing the right thing.

> Not to mention the sorry fact that connecting such device to a computer
> _immediately_ starts causing annoying, undesired behavior (assuming, not
> everybody uses gnome and gnome apps - I, for one, rely on quite a few "non-DE"
> ones). Mapping some loose buttons to first 3 mouse buttons by default is almost
> the worst default behavior one can expect.

Option "ButtonMapping" already exists, so you can shift this to higher logical buttons to avoid immediate interference.

> If you don't feel like doing it I can try to tinker with it myself, but would
> you be willing to accept such a solution into the xorg tree?

tbh, it's unlikely, sorry. We have too many kludges already, some of which even conflict with each other. All put into the drivers because that was the easy thing to do. Now it's largely causing pain. Updating the driver already is a dance between fixing bugs while not breaking everything around.
Comment 7 Alexander Dubov 2012-08-24 17:10:55 UTC
Ok, I see.

Because evdev is considered somehow too complex (and it's not even that bigger than old school mouse_drv, not to mention beasts like synaptics), all the apps relying on customizable hotkeys (including closed source legacy ones) now have to be rewritten to support XI2 style floating devices. Great idea.

And, of course, whoever had some hopes to use one of the untold scores of usb or bluetooth devices, which behave that way, properly under linux, are now welcome to return to their beloved windows installations. :-)
Comment 8 5spice 2013-05-28 23:58:11 UTC
I'm coming from the "windows" world and trying to see if there is something that Plantronics can do differently to avoid this mis-mapping issue. From my standpoint, the buttons are listed under "vendor-unique", 0xFFA0 in the report descriptor. Since they are vendor unique and not explicitly described, would it be possible to not map the buttons? It seems like ignoring a button without an explicit description would be a robust solution.

I'm not looking at the .648 as was mentioned, but I'm seeing the same problem on currently shipping PLT headsets.

thx,
rob
Comment 9 James Cloos 2013-05-29 13:54:59 UTC
> From my standpoint, the buttons are listed under "vendor-unique",
> 0xFFA0 in the report descriptor. Since they are vendor unique and not
> explicitly described, would it be possible to not map the buttons?

Such mapping can be done by, eg, udev.

On my (gentoo) box, the directory /lib/udev/keymaps/ contains device-
specific keymaps.  On other distros that might be in /usr/lib/.

As one example, the file /lib/udev/keymaps/logitech-wave includes a
mapping:

  0x9003D prog1 #gadget

which says that 0x9003D, which is sent by the key marked gadget, instead
should generate the <linux/include.h> keysym KEY_PROG1, which xf86-input-evdev
and xkb convert to the X11 keysym XF86Launch1.
Comment 10 MrLeV 2013-05-29 14:08:22 UTC
I have built a special xorg.conf patch for preventing the Plantronics USB headsets to send core events that would capture the actual mouse buttons events.

Here is what my .conf contains:

Section "InputClass"
  Identifier    "PLTUSBHeadsetsNoCoreEvents"
  MatchVendor   "Plantronics"
  Option        "SendCoreEvents" "off"
EndSection

I used "SendCoreEvents" for it is known from older distros too.
Comment 11 Stanislav German-Evtushenko 2013-11-03 21:24:47 UTC
This works in Ubuntu 12.04: http://www.helplinux.ru/wiki/en:kb:ubuntu-plantronics
Comment 12 Peter Hutterer 2013-11-04 03:34:01 UTC
closing as WONTFIX, this won't be fixed in the evdev driver. Please see the solution Stanislav linked to in comment 11 for a workaround (well, it's almost the proper solution)

Stanislav: I recommend adding this mapping to the systemd/udev hwdb so it is upstreamed. I suspect something like this should do

$> cat /etc/udev/hwdb.d/99-plantronics-headset.hwdb
keyboard:usb:v47fpc013*
  KEYBOARD_KEY_FFA000B1=volumeup
  and the other keys here

I took the FFA000B1 from your link, use showkeys -s to get the scancode for each key.
Comment 13 Stanislav German-Evtushenko 2013-11-17 21:26:09 UTC
Peter,

I've added hwdb variant to the page.
BTW: "showkeys" -s doesn't work for this device.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.