atar-axis / xpadneo

Advanced Linux Driver for Xbox One Wireless Controller (shipped with Xbox One S)
https://atar-axis.github.io/xpadneo/
GNU General Public License v3.0
2.01k stars 113 forks source link

libinput bug: Event for missing capability CAP_POINTER #205

Closed terencode closed 4 years ago

terencode commented 4 years ago

I have already opened an issue there: https://gitlab.freedesktop.org/libinput/libinput/-/issues/415 but I'm also creating this one because of https://github.com/atar-axis/xpadneo/issues/163#issuecomment-627140427.

Bug Description

This is coming from X11, logged at $HOME/.local/share/xorg/Xorg.1.log When my controller is connected (8BitDo SN30 Pro+), libinput detects it as a keyboard/joystick and when pressing X/Y/B/A/L/R/ leftjoystickbutton/rightjoystickbutton/select/start, Event for missing capability CAP_POINTER on device "8BitDo SN30 Pro+ is logged twice (one for key press and one for release). This happens with and without the kernel module probed both but ONLY using bluetooth.

Expected behavior

From the bug description, it is clear this is not a bug coming from xpadneo. However I was wondering if something could be done from xpadneo's side to mitigate the issue. I don't know at all how libinput works but maybe there is a way to untag the device when xpadneo detects it?

Logs

[ 18037.043] (II) event21 - 8BitDo SN30 Pro+: is tagged by udev as: Keyboard Joystick
[ 18037.043] (II) event21 - 8BitDo SN30 Pro+: device is a keyboard

When pressing buttons

[ 18038.472] (EE) libinput bug: Event for missing capability CAP_POINTER on device "8BitDo SN30 Pro+"

Here is what it says when connected over usb:

juin 23 21:28:42 terence-desktop /usr/lib/gdm-x-session[2391]: (II) config/udev: Adding input device Microsoft X-Box 360 pad (/dev/input/js0)
juin 23 21:28:42 terence-desktop /usr/lib/gdm-x-session[2391]: (II) No input driver specified, ignoring this device.
juin 23 21:28:42 terence-desktop /usr/lib/gdm-x-session[2391]: (II) This device may have been added with another device file.

System information

# Linux terence-desktop 5.7.5-10-tkg-bmq #1 TKG SMP PREEMPT Mon, 22 Jun 2020 16:41:48 +0000 x86_64 GNU/Linux

See https://github.com/atar-axis/xpadneo/issues/163#issuecomment-626173077

Controller and Bluetooth information

See https://github.com/atar-axis/xpadneo/issues/163#issuecomment-626173354

kakra commented 4 years ago

This is probably because we have one key event: The guide button is a keyboard event. We cannot expose it as the 11th button because this messes up the button order. Thus, it's tagged as keyboard/joystick. I don't know why it is expecting CAP_POINTER, tho: Neither keyboards nor joysticks have such a capability. I'll have to research this, it doesn't seem to do harm, tho. I'm seeing these messages just twice, then Xorg unmaps the device from its listing.

DarthShredder commented 4 years ago

Got the same since v0.7 with "Xbox Wireless Controller" on every button press /usr/lib/gdm3/gdm-x-session[1722]: (EE) libinput bug: Event for missing capability CAP_POINTER on device "Xbox Wireless Controller" I am using a Xbox One Grey/Blue Wireless Controller ( https://www.xbox.com/en-US/accessories/controllers/grey-blue ) via Bluetooth

kakra commented 4 years ago

I'm pretty sure by now that this is a libinput bug (as even stated by the error message)... For some reason libinput is expecting a CAP_POINTER capability even when we don't have EV_REL axes. This also happens with other controllers that expose the EV_KEY capability: https://gitlab.freedesktop.org/libinput/libinput/-/issues/244

The question is why it is expecting a pointer when ID_INPUT_KEY is set. There's also ID_INPUT_MOUSE which should do the job. I'm not sure how we could untag it as a keyboard as we need the key event for the Xbox button.

Solution: Just ignore the message.

terencode commented 4 years ago

FYI this started happening with 695a7a547d657954b1cc8b700633c82a82e0d4ca. Of course I can ignore the message but I don't like having my logs being spammed :sweat_smile: Let's hope libinput will fix this at some point...

kakra commented 4 years ago

Yes, the code is semantically identical before and after the change. But we removed BTN_MODE and send KEY_HOMEPAGE instead because otherwise games see an 11th button in the wrong place (before the thumbs stick, not after it).

Since we are having one key now, libinput seems to wrongly think we are a mouse or a touchpad, and thus misses the capability. It should simply do what the kernel suggests: Check, if we have BTN_GAMEPAD and expect we are a gamepad, check if we have BTN_MOUSE and it would be a mouse. The thing about touchpads seems to be more complicated. I'm not sure what's wrong but it is not a problem in this driver.

If you want to get rid of the message, replace KEY_HOMEPAGE with BTN_MODE but in games you'll probably see the thumb stick buttons and guide button mixed up. libinput should just not assume a pointer device only because there's a key with axes.

kakra commented 4 years ago

I believe this code in src/evdev.c from libinput is wrong:

    /* libwacom *adds* TABLET, TOUCHPAD but leaves JOYSTICK in place, so
       make sure we only ignore real joystick devices */
    if (udev_tags == (EVDEV_UDEV_TAG_INPUT|EVDEV_UDEV_TAG_JOYSTICK)) {
        evdev_log_info(device,
                   "device is a joystick, ignoring\n");
        return NULL;
    }

It doesn't exactly do that the comment says it does. If it wants to actually test this, the if should be:

if ((udev_tags& \
    (EVDEV_UDEV_TAG_INPUT|EVDEV_UDEV_TAG_JOYSTICK \
    |EVDEV_UDEV_TAG_TABLET|EVDEV_UDEV_TAG_TOUCHPAD) == \ 
    (EVDEV_UDEV_TAG_INPUT|EVDEV_UDEV_TAG_JOYSTICK)) {

or something similar. It actually doesn't test for the wacom properties currently. Since for our case udev_tags probably has the key tag set (not keyboard!), the test will fail and the device won't be seen as a joystick. Probably somewhere later, it decides to be a touchpad and is missing the pointer capability. This test is just wrong because it tests for joystick only having exactly two tags set. But the controller has a key, so it has a third tag.

terencode commented 4 years ago

Thanks, added your analysis to the libinput issue.

kakra commented 4 years ago

We may get away by setting a tag for libinput to ignore the device but this is only a work-around and doesn't fix the bug in libinput. Rescheduling for v0.9.

kakra commented 4 years ago

Upstream bug report: https://gitlab.freedesktop.org/libinput/libinput/-/issues/415

kakra commented 4 years ago

Please try #230

terencode commented 4 years ago

230 works around it :+1:

terencode commented 4 years ago

libinput log for reference with the PR applied:

(II) config/udev: Adding input device 8BitDo Zero 2 gamepad (/dev/input/js0)
(**) 8BitDo Zero 2 gamepad: Applying InputClass "system-keyboard"
(II) No input driver specified, ignoring this device.
(II) This device may have been added with another device file.
(II) config/udev: Adding input device 8BitDo Zero 2 gamepad (/dev/input/js0)
(**) 8BitDo Zero 2 gamepad: Applying InputClass "system-keyboard"
(II) No input driver specified, ignoring this device.
(II) This device may have been added with another device file.
(II) config/udev: Adding input device 8BitDo Zero 2 gamepad (/dev/input/event26)
(**) 8BitDo Zero 2 gamepad: Applying InputClass "libinput keyboard catchall"
(**) 8BitDo Zero 2 gamepad: Applying InputClass "system-keyboard"
(II) Using input driver 'libinput' for '8BitDo Zero 2 gamepad'
(II) config/udev: Adding input device 8BitDo Zero 2 gamepad (/dev/input/event26)
(**) 8BitDo Zero 2 gamepad: Applying InputClass "libinput keyboard catchall"
(**) 8BitDo Zero 2 gamepad: Applying InputClass "system-keyboard"
(II) Using input driver 'libinput' for '8BitDo Zero 2 gamepad'
(II) systemd-logind: got fd for /dev/input/event26 13:90 fd 82 paused 0
(**) 8BitDo Zero 2 gamepad: always reports core events
(**) Option "Device" "/dev/input/event26"
(**) Option "_source" "server/udev"
(II) event26 - failed to create input device '/dev/input/event26'.
(EE) libinput: 8BitDo Zero 2 gamepad: Failed to create a device for /dev/input/event26
(EE) PreInit returned 2 for "8BitDo Zero 2 gamepad"
(II) UnloadModule: "libinput"
(II) systemd-logind: releasing fd for 13:90
(II) systemd-logind: got fd for /dev/input/event26 13:90 fd 23 paused 1
(II) systemd-logind: releasing fd for 13:90
terencode commented 4 years ago

Looks like libinput fixed it from their side now: https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/475

kakra commented 4 years ago

Cool, thanks for the heads up. I like the solution as two separate commits - easy to bisect, easy to cherry pick, easy to undo in case of problems. So in some point in time, we may need to remove the libinput work-around. Should also fix the bug report about the PS4 controller that's in their issue database.

You just successfully participated in a cross-project bug fixing process. Actually, you manged to get it fixed. Kudos. :-)