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
1.87k stars 110 forks source link

Guide button recognized as BTN_MODE instead of KEY_MENU #415

Open Shatur opened 1 year ago

Shatur commented 1 year ago

Version of xpadneo

0.9.5

Controller Model

Connection mode

Installed Software

Protocol Information

Please help us identify at which layer the problem can be found if you want to report mapping errors or if the controller fails to be detected:

Please describe how it is failing below in the next sections.

Severity / Impact

Describe the Bug

In evtest guide button recognized as BTN_MODE instead of KEY_MENU. If I remove the driver, 8BitDo SN30 Pro reports this buttons as KEY_MENU.

Steps to Reproduce

Connect the gamepad and run sudo evtest.

Expected Behavior

Should this button recognized as KEY_MENU? For example I can't map BTN_MODE in Retroarch, it's simply not recognized it as a button. But with KEY_MENU it works (this is how it works without the driver) and it's the default shortcut for opening Retroarch menu.

Screenshots / GIFs / Videos

System Information

# uname -a
Linux AcerAspire5 6.1.22-1-lts #1 SMP PREEMPT_DYNAMIC Thu, 30 Mar 2023 14:10:04 +0000 x86_64 GNU/Linux
# xxd -c20 -g1 /sys/module/hid_xpadneo/drivers/hid:xpadneo/0005:045E:*/report_descriptor | tee >(cksum)
00000000: 05 01 09 05 a1 01 85 01 09 01 a1 00 09 30 09 31 15 00 27 ff  .............0.1..'.
00000014: ff 00 00 95 02 75 10 81 02 c0 09 01 a1 00 09 33 09 34 15 00  .....u.........3.4..
00000028: 27 ff ff 00 00 95 02 75 10 81 02 c0 05 01 09 32 15 00 26 ff  '......u.......2..&.
0000003c: 03 95 01 75 0a 81 02 15 00 25 00 75 06 95 01 81 03 05 01 09  ...u.....%.u........
00000050: 35 15 00 26 ff 03 95 01 75 0a 81 02 15 00 25 00 75 06 95 01  5..&....u.....%.u...
00000064: 81 03 05 01 09 39 15 01 25 08 35 00 46 3b 01 66 14 00 75 04  .....9..%.5.F;.f..u.
00000078: 95 01 81 42 75 04 95 01 15 00 25 00 35 00 45 00 65 00 81 03  ...Bu.....%.5.E.e...
0000008c: 05 09 19 01 29 0a 15 00 25 01 75 01 95 0a 81 02 15 00 25 00  ....)...%.u.......%.
000000a0: 75 06 95 01 81 03 05 01 09 80 85 02 a1 00 09 85 15 00 25 01  u.................%.
000000b4: 95 01 75 01 81 02 15 00 25 00 75 07 95 01 81 03 c0 05 0f 09  ..u.....%.u.........
000000c8: 21 85 03 a1 02 09 97 15 00 25 01 75 04 95 01 91 02 15 00 25  !........%.u.......%
000000dc: 00 75 04 95 01 91 03 09 70 15 00 25 64 75 08 95 04 91 02 09  .u......p..%du......
000000f0: 50 66 01 10 55 0e 15 00 26 ff 00 75 08 95 01 91 02 09 a7 15  Pf..U...&..u........
00000104: 00 26 ff 00 75 08 95 01 91 02 65 00 55 00 09 7c 15 00 26 ff  .&..u.....e.U..|..&.
00000118: 00 75 08 95 01 91 02 c0 85 04 05 06 09 20 15 00 26 ff 00 75  .u........... ..&..u
0000012c: 08 95 01 81 02 c0                                            ......
3445511648 1458

Controller and Bluetooth Information

xpadneo-btmon.txt xpadneo-dmesg.txt

Additional Context

kakra commented 1 year ago

Devices that have BTN_GAMEPAD are not really allowed to expose KEY_MENU in the sense the kernel defines device type detection for user-space. It's technically possible and nothing in the kernel prevents it but at least libinput complains about that in xorg.log. In a more correct way, we would need to create a compound device that has one gaming input device (having a "key" BTN_GAMEPAD) and one keyboard device (having at least a key code below 128 which KEY_MENU does not belong to).

The behavior you are asking for has actually been in xpadneo in different implementations:

  1. KEY_MENU has been part of the main gamepad device, it caused some software to not detect the Guide button, including Steam. It also caused libinput warnings.
  2. BTN_MODE and KEY_MENU have been moved to a separate device which in most cases resulted in software not detecting the button at all because they seem to watch only devices that identify as a gamepad or keyboard exactly (because neither a key code below 128 nor a BTN_GAMEPAD).
  3. Many gaming-related software (like emulators) cannot map KEY_MENU neither they react to it. So I wonder why yours is different.

In the end, xpadneo currently settled to BTN_MODE and tricks SDL into thinking this would be another model so the button order isn't shuffled around - because if we pass the native HID report button order, jsdev becomes confused. We are now left with only Chrome being confused because it maps buttons via evdev but reads buttons via jsdev, including some boilerplate code to fix devices that are known to not work with this mess (because: you just don't do that, both are separate interfaces which have nothing in common).

See also #286

After v0.10 release, I will be working to resolve this and add features to remap buttons to different codes. The xpadneo driver will then expose a keyboard and gamepad device at the same time so you can mix and match mappings whatever you like, including switchable profile presets. But first, I'll have to resolve some open bug reports.

Until then, you may be able to use something like anti-micro to resolve the issue or simply ask the Retroarch developers to support both event codes no matter which device they think is connected (because I think original Xbox controllers DO NOT send KEY_MENU and it probably still works, so Retroarch probably looks at the model IDs of the device to decide for an event code).

You may also try using https://github.com/atar-axis/xpadneo/pull/283 which is an attempt to work around some software quirks. Most of this patch has been absorbed into the main branches already: It mostly only changes trigger scaling now, and also pretends to be a USB device instead of Bluetooth. It also disables the shift mode operation of the Guide button as used for future features and makes it operate as a real gamepad button.

Shatur commented 1 year ago

Thank you a lot for the explanation! Will open an issue in Retroarch. And looking forward to 0.11. I currently use sudo rmmod hid-xpadneo as a temporary workaround when I want to play in Retroarch and Xpadneo for everything else.

Shatur commented 1 year ago

Tried "Switch" mode and the button is also recognized as BTN_MODE, but works correctly in Retroarch, so you are right, looks like they looking for the device ID. Am I understand correctly, that this mode is unaffected by the driver?

kakra commented 1 year ago

What "Switch" mode? There's nothing that changes the device ID unless you're using PR #283.

If you mean "Nintendo Switch" emulation (which swaps A/B and X/Y) using the quirks option, there's absolutely nothing Retroarch could know about it - we swap the buttons at a very low level in the HID reports without touching anything else, even SDL has no chance to see this modification.

Ahhh wait! You mean the Switch hardware emulation mode of your controller... Yeah, that proves my point. Our driver currently doesn't support this controller mode, so you're not using xpadneo in this case. If you see BTN_MODE, that comes directly from your hardware.

Shatur commented 1 year ago

Ahhh wait! You mean the Switch hardware emulation mode of your controller... Yeah, that proves my point. Our driver currently doesn't support this controller mode, so you're not using xpadneo in this case. If you see BTN_MODE, that comes directly from your hardware.

Yep! Thanks for the info.

Shatur commented 1 year ago

Sorry, closed it accidentally. I assume that you wanted to keep this open as a remainder for 0.11.

kakra commented 1 year ago

There's a small chance that RetroArch uses SDL - and SDL may not see BTN_MODE from xpadneo. You can test that with gamepad-tool. In that case, RetroArch may react to both KEY_MENU and BTN_MODE but would not be able to see the latter. I've just tested latest xpadneo with my Xbox One S controller: SDL does see the Guide button. So at least with latest versions and no quirky controllerdb mappings, it will work correctly.

Shatur commented 1 year ago

You can test that with gamepad-tool

The Guide button works in gamepad-tool, yes. But not in Retroarch. I use Archlinux, so I have the latest versions of everything.

Shatur commented 1 year ago

There is a setting in Retroarch to use SDL2. But it set to udev by default. So it's definitely a bug in Retroarch. Thank you a lot!

kakra commented 1 year ago

If it uses udev and evdev, it should read either the HID descriptor (complicated) or use the symbol mappings (preferred) provided by the evdev interface (which is a result of the descriptor parser).

Shatur commented 1 year ago

Tried switching input driver to sdl2 in settings - also doesn't work. Will open an issue, thank you!

kakra commented 1 year ago

Upcoming SDL2 will have better support for all Xbox controllers, no matter if xpad, xpadneo or hid-microsoft is used. For xpadneo, tho, customizing how the Guide button is handled will be deferred until after v0.10.

AlexFolland commented 1 year ago

I am seeing this issue with xpadneo-dkms installed on Manjaro and the 8bitdo SN30 Pro connected in Windows mode (Start+X). The logo button (as the official manual calls it instead of the guide button or menu button) appears as BTN_MODE in evtest.

Furthermore, when testing in evtest, pressing that logo button shows 2 events simultaneously when the button is physically released, instead of an event when pressed and another event later when released. I observed this when pressing the B button once, then pressing the logo button twice (fully pressed and released physically twice). See the following evtest output with timestamps for clarification of this.

Testing ... (interrupt to exit)
Event: time 1687984503.970395, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90002
Event: time 1687984503.970395, type 1 (EV_KEY), code 305 (BTN_EAST), value 1
Event: time 1687984503.970395, -------------- SYN_REPORT ------------
Event: time 1687984504.053694, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90002
Event: time 1687984504.053694, type 1 (EV_KEY), code 305 (BTN_EAST), value 0
Event: time 1687984504.053694, -------------- SYN_REPORT ------------
Event: time 1687984505.223710, type 1 (EV_KEY), code 316 (BTN_MODE), value 1
Event: time 1687984505.223710, -------------- SYN_REPORT ------------
Event: time 1687984505.223715, type 1 (EV_KEY), code 316 (BTN_MODE), value 0
Event: time 1687984505.223715, -------------- SYN_REPORT ------------
Event: time 1687984513.610510, type 1 (EV_KEY), code 316 (BTN_MODE), value 1
Event: time 1687984513.610510, -------------- SYN_REPORT ------------
Event: time 1687984513.610520, type 1 (EV_KEY), code 316 (BTN_MODE), value 0
Event: time 1687984513.610520, -------------- SYN_REPORT ------------

@Shatur I am also using RetroArch and I'm interested in tracking the status of this issue across xpadneo and RetroArch. If you did end up opening a RetroArch issue ticket, please link your RetroArch issue ticket here for ease of navigation. Thank you for reporting this.

kakra commented 1 year ago

pressing that logo button shows 2 events simultaneously when the button is physically released

This is intended behavior: While holding the logo button, you can press A,B,X,Y to switch between mapping profiles (which are not yet implemented) and there will be a mouse emulation mode which can be enabled in a similar way (will land in v0.10). When running dmesg -w and then using these combos, you'll see that the driver actually makes use of that. When a combo is used, releasing the logo button would no longer emit an event. This also prevents the logo button from emitting an event when used to turn the controller off.

Future versions will allow to disable the shift mode operation so it can better support applications like RetroArch.

BTN_MODE vs KEY_MENU actually seems to be a bug in RetroArch. KEY_MENU is not allowed to be part of the gamepad mappings (although the kernel wouldn't prevent that). Some drivers thus implement this wrong, and RetroArch is relying on such broken behavior. It seems to actually handle BTN_MODE for other gamepad models, so it can handle both events, it just ignores it for xpadneo for some unknown reason.

KEY_MENU is part of the consumer control device mappings (e.g., remote controls), so it is actually not even a keyboard event. That event cannot be mapped as a keyboard shortcut in desktops, thus we replaced it with BTN_MODE. It fixed operation with some emulators.

That said, custom mappings will come after v0.10, thus in a future version you will be able to customize which button emits which event and switch to different mappings using 3 custom profiles (the first profile will always be the default mapping which makes it 4 profiles in total).

AlexFolland commented 1 year ago

This is intended behavior: While holding the logo button, you can press A,B,X,Y to switch between mapping profiles (which are not yet implemented) and there will be a mouse emulation mode which can be enabled in a similar way (will land in v0.10).

I'm not sure if what I wrote was understood. What I wrote was that there is no event on press, but two instantaneously on release, which was the press and release events. The press event should fire when the button is pressed, not when it is released.

Any profile-switching behavior should be irrelevant to this. I'm talking simply about when the corresponding events fire. If a button combination is implemented for switching profiles, it would need to know when the button is pressed anyway, and currently because these two events fire simultaneously only on release, there can be no "held" state, which would prevent any hypothetical button combination from being able to work.

Shatur commented 1 year ago

If you did end up opening a RetroArch issue ticket, please link your RetroArch issue ticket here for ease of navigation.

Oh, I'm sorry, I forgot to open it. Could you please do it instead and like the issue?

AlexFolland commented 1 year ago

I tried uninstalling xpadneo-dkms as I had only installed it originally as a workaround for this RetroArch issue, which is now resolved. The driver that is handling the 8bitdo SN30 Pro Windows mode in the Manjaro Linux kernel version 6.4.0-0.1 works well, with no logo button issue. It can be bound in RetroArch as expected, and reports both presses and releases at the correct times in evtest.

Therefore, I am no longer interested in this issue. I wish the xpadneo devs well and hope they can resolve the logo button press event issue for users who want to use xpadneo still. If BTN_MODE is the right event, then I hope it can be sent at the correct times and be detected by all software.

By the way, I can confirm that the default driver (not xpadneo) seems to use KEY_MENU, as shown in this evtest output from pressing the logo button twice:

Event: time 1687995487.331960, type 4 (EV_MSC), code 4 (MSC_SCAN), value 10085
Event: time 1687995487.331960, type 1 (EV_KEY), code 139 (KEY_MENU), value 1
Event: time 1687995487.331960, -------------- SYN_REPORT ------------
Event: time 1687995487.538535, type 4 (EV_MSC), code 4 (MSC_SCAN), value 10085
Event: time 1687995487.538535, type 1 (EV_KEY), code 139 (KEY_MENU), value 0
Event: time 1687995487.538535, -------------- SYN_REPORT ------------
Event: time 1687995488.145301, type 4 (EV_MSC), code 4 (MSC_SCAN), value 10085
Event: time 1687995488.145301, type 1 (EV_KEY), code 139 (KEY_MENU), value 1
Event: time 1687995488.145301, -------------- SYN_REPORT ------------
Event: time 1687995488.441842, type 4 (EV_MSC), code 4 (MSC_SCAN), value 10085
Event: time 1687995488.441842, type 1 (EV_KEY), code 139 (KEY_MENU), value 0
Event: time 1687995488.441842, -------------- SYN_REPORT ------------

Also, I'd like to add that I tried the 8bitdo SN30 Pro with xpadneo in evtest-qt, a GUI evdev event tester, and it seemed to ignore any presses of the logo button when using xpadneo, so maybe Qt has an issue handling BTN_MODE (or maybe it just couldn't animate it because xpadneo has a bug causing the press and release events to fire instantaneously, so there's no time the button is "held").

kakra commented 1 year ago

I'm not sure if what I wrote was understood. What I wrote was that there is no event on press, but two instantaneously on release, which was the press and release events. The press event should fire when the button is pressed, not when it is released.

Yes, this is intended behavior. We hold the button event back until released, because it could be used as a shift key, and in that case, no event at all would be fired for the logo button.

kakra commented 1 year ago

hope they can resolve the logo button press event issue for users who want to use xpadneo still

This is not an issue because this behavior is intended - as written above.

By the way, I can confirm that the default driver (not xpadneo) seems to use KEY_MENU

Yes, but this is probably wrong. It was done because the original firmware of the Xbox Bluetooth controllers sent KEY_MENU - but they did so in a secondary HID application page used for consumer control mappings. But, the kernel at that time did not support multiple applications per device and thus the keybit ended up in the gamepad mapping - which is wrong.

AlexFolland commented 1 year ago

Yes, this is intended behavior. We hold the button event back until released, because it could be used as a shift key, and in that case, no event at all would be fired for the logo button.

This is another reason I can't use xpadneo then. I personally prefer if the driver I'm using faithfully translates hardware signals to OS-level events, which can then be interpreted in any way desired by applications. If I want to add a button combination to change "profiles" by myself using a user-land application, that would allow me to. With the "pressed" event being sent only on release, there is no possibility of doing that, which makes the driver lack functionality.

kakra commented 1 year ago

I personally prefer if the driver I'm using faithfully translates hardware signals to OS-level events, which can then be interpreted in any way desired by applications.

As written above, this is planned for after v0.10 initially released. But for your use-case, the native hid-microsoft driver in the kernel is probably what you're looking for.

darcyrush commented 11 months ago

Upcoming SDL2 will have better support for all Xbox controllers, no matter if xpad, xpadneo or hid-microsoft is used. For xpadneo, tho, customizing how the Guide button is handled will be deferred until after v0.10.

Can you link to any release notes or give a very brief overview of the changes?

kakra commented 11 months ago

This is one of the relevant commits: https://github.com/libsdl-org/SDL/commit/db1d4d3d76f5e21b2547463710b513fe0ebd7fad

There's one before which prepared those changes, then there's one following which fixes a few things I've found. This may give a better overview:

https://github.com/libsdl-org/SDL/commits/883b0f4071687f2e5c8329963f97504e9679394b/src/joystick/linux/SDL_sysjoystick.c

I'm not sure if it has been merged into a released version yet. It should be in 2.28.0 and newer if I remember correctly.

Regarding xpadneo itself, you could browse the projects tab of xpadneo: https://github.com/atar-axis/xpadneo/projects?type=classic

And here's the relevant discussion: https://github.com/atar-axis/xpadneo/issues/428

awsms commented 11 months ago

I still don't understand how programs like Steam can detect inputs on the Guide button :thinking: