ValveSoftware / Proton

Compatibility tool for Steam Play based on Wine and additional components
Other
24.29k stars 1.06k forks source link

Thumbstick on HOTAS X52 (Pro) does trigger all kinds of buttons pressed #6537

Closed bekopharm closed 11 months ago

bekopharm commented 1 year ago

This is a regression that worked fine with Proton 6.3 and starts to misbehave with Proton 7 and Experimental.

The HOTAS in question is the Logitech X52 Pro registered as:

ID 06a3:0762 Saitek PLC Saitek X52 Pro Flight Control System

It has a thumb-stick on the throttle that operates the axis 8 and 9. This works as expected with AntiMicroX, sdl-test, sdl2-test, jstest-gtk, evtest even at the same time while Proton is run.

The axis are typically used as mouse up/down and left/right with AntiMicroX.

Starting with Proton 7 operating the thumb stick in any direction results in various buttons to be pressed in a game. This can be seen by executing proton run control and switching to the "Test joystick" tab:

x52-wine-controller-config

x52-thumbstick-broken-proton-experimental

This also happens on builds that use Proton 7, like the GE one to run StarCitizen (without any involvement of e.g. Steam Input). This is a short DEMO video to show the behavior. It's the exact same with Proton 7 and Experimental:

https://user-images.githubusercontent.com/5016428/219058425-8f6fef22-5bba-49d7-8f40-4085cd3ccb9b.mp4

No SDL override was used. wine-8.0-rc4 seems to be affected as well so I'm no longer sure if this is the right place to report this. I have no idea how to debug this any further though.

MNS26 commented 1 year ago

a (somewhat) hacky temp workaround i found was building and using the libx52 kernel module made by nirenjan, sadly it removes the 2 axis (axis 7 & 8).

when testing the X52 pro on wine (w/o) kernel module loaded it doesnt go balistic... its just a proton issue

cpprophet commented 1 year ago

As i was observing the issue. Reading a lot about it and searching i found following 'maybe' equivalent bug: https://bugs.winehq.org/show_bug.cgi?id=53666 which is fixed in wine 8.1. devel.

Patola commented 1 year ago
[17:44] [3209] [patola@risadinha /tmp]% lsusb | egrep -i 'saitek|logitech' 2>/dev/null
Bus 007 Device 009: ID 06a3:0762 Saitek PLC Saitek X52 Pro Flight Control System

I can confirm I have the same issue as Beko on Proton 7.0-6 image

TeddyDD commented 1 year ago

which is fixed in wine 8.1. devel.

The issue is still present on Wine 8.2

TeddyDD commented 1 year ago

a (somewhat) hacky temp workaround i found was building and using the libx52 kernel module made by nirenjan, sadly it removes the 2 axis (axis 7 & 8).

You can disable this thumb stick thingy in software using a evdev, no need to compile kernel module. You lose two axes, but at least your airplane won't go batshit by accident 🤣

import asyncio
# pip install evdev
from evdev import ecodes, UInput, util, InputDevice

DEVICE_NAME = "Saitek Saitek X52 Pro Flight Control System"

def find_device():
    for d in util.list_devices():
        device = InputDevice(d)
        if device.name == DEVICE_NAME:
            return device

def main():
    device = find_device()

    caps = device.capabilities()
    # EV_SYN is automatically added to uinput devices
    del caps[ecodes.EV_SYN]

    out = UInput(caps, DEVICE_NAME + "-fixed")

    asyncio.ensure_future(process_events(device, out))
    loop = asyncio.get_event_loop()
    try:
        loop.run_forever()
    except KeyboardInterrupt:
        print("closing")

async def process_events(input, output):
    input.grab()
    async for ev in input.async_read_loop():
        # Disable thumb thingy
        if ev.type == 3 and (40 <= ev.code <= 42):
            continue
        output.write_event(ev)
    input.ungrab()

if __name__ == "__main__":
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    main()

Just run it before starting a game and configure joystick with -fixed suffix.

MNS26 commented 1 year ago

@TeddyDD i didnt know thats also a way, i used the kernel module because i use libX52 to control the lights on the HOTAS and the kernel module was also in there.

MNS26 commented 1 year ago

is it possible to do it without having it add another device? (if i read the code correctly) it will be a nightmare to redo all of my keybinds for different games

running the script threw a traceback

Traceback (most recent call last):
  File "/home/noah/HOTAS-fix.py", line 3, in <module>
    from evdev import ecodes, UInput, util, InputDevice
ModuleNotFoundError: No module named 'evdev'
TeddyDD commented 1 year ago

Not sure. You could try to change out = UInput(caps, DEVICE_NAME) so it does not add the suffix.

running the script threw a traceback

pip install evdev

MNS26 commented 1 year ago

hmm weird it erorrs on the install

> pip install --user evdev
Collecting evdev
  Using cached evdev-1.6.1.tar.gz (26 kB)
  Preparing metadata (setup.py) ... done
Using legacy 'setup.py install' for evdev, since package 'wheel' is not installed.
Installing collected packages: evdev
  Running setup.py install for evdev ... error
  error: subprocess-exited-with-error

  × Running setup.py install for evdev did not run successfully.
  │ exit code: 1
  ╰─> [31 lines of output]
      running install
      /usr/lib/python3.11/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
        warnings.warn(
      running build
      running build_py
      creating build
      creating build/lib.linux-x86_64-cpython-311
      creating build/lib.linux-x86_64-cpython-311/evdev
      copying evdev/util.py -> build/lib.linux-x86_64-cpython-311/evdev
      copying evdev/uinput.py -> build/lib.linux-x86_64-cpython-311/evdev
      copying evdev/genecodes.py -> build/lib.linux-x86_64-cpython-311/evdev
      copying evdev/ff.py -> build/lib.linux-x86_64-cpython-311/evdev
      copying evdev/evtest.py -> build/lib.linux-x86_64-cpython-311/evdev
      copying evdev/events.py -> build/lib.linux-x86_64-cpython-311/evdev
      copying evdev/eventio_async.py -> build/lib.linux-x86_64-cpython-311/evdev
      copying evdev/eventio.py -> build/lib.linux-x86_64-cpython-311/evdev
      copying evdev/ecodes.py -> build/lib.linux-x86_64-cpython-311/evdev
      copying evdev/device.py -> build/lib.linux-x86_64-cpython-311/evdev
      copying evdev/__init__.py -> build/lib.linux-x86_64-cpython-311/evdev
      running build_ext
      running build_ecodes
      writing /tmp/pip-install-bve1k663/evdev_14b6398339c54692ba6e8fe729a80a57/evdev/ecodes.c (using /usr/include/linux/input.h /usr/include/linux/input-event-codes.h /usr/include/linux/uinput.h)
      building 'evdev._input' extension
      creating build/temp.linux-x86_64-cpython-311
      creating build/temp.linux-x86_64-cpython-311/evdev
      gcc -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -fPIC -I/usr/include/python3.11 -c evdev/input.c -o build/temp.linux-x86_64-cpython-311/evdev/input.o -std=c99 -Wno-error=declaration-after-statement
      evdev/input.c:10:10: fatal error: Python.h: No such file or directory
         10 | #include <Python.h>
            |          ^~~~~~~~~~
      compilation terminated.
      error: command '/usr/bin/gcc' failed with exit code 1
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
error: legacy-install-failure

× Encountered error while trying to install package.
╰─> evdev

note: This is an issue with the package mentioned above, not pip.
hint: See above for output from the failure.
MNS26 commented 1 year ago

Hmm so the OS itself only 1 of the 2 axis as a absolute axis (40 is horizontal/ 41 is vertical). Could it be a kernel issue?

image image

cpprophet commented 1 year ago

jstest (gtk) having /dev/input/js0 shows all axis and these are moving properly.

TeddyDD commented 1 year ago

Evtest-qt also shows everything working correctly. It's a Wine issue.

MNS26 commented 1 year ago

hmm weird.. for me its happening on all wine/proton versions

Web-eWorks commented 1 year ago

Can reproduce the issue on GE-wine-custom-7-38 (the version I use for DCS World) and other vanilla Wine 7 versions. Attempting to move either thumbstick axis causes up to 30 buttons to simultaneously show as depressed, some of which "stick" on after the thumbstick is returned to center.

In the WINE joystick control panel applet, the joystick only shows as having 6 axes, one hat, and 32 buttons, while in reality it has 9 axes, 1 hat, and 39 buttons. Buttons beyond 32 appear to be bindable in Simple Radio Standalone running in the same WINE prefix.

The thumbstick is (zero-based) axis 7 and 8 in Linux, neither of which show up as present in the WINE joystick applet or in a client application (DCS World). I've confirmed that the axes are present and report input natively in linux with a SDL application (Pioneeer Space Simulator), so the issue exists somewhere inside of WINE's input device handling.

MNS26 commented 1 year ago

so its a issue with WINE itself. has anyone checked on wineHQ if its already been reported? (havent had the time to check)

EDIT: just checked and there are 2 that are from 1.5-2 years ago image

bekopharm commented 1 year ago

Don't think https://bugs.winehq.org/show_bug.cgi?id=43741 is related.

https://bugs.winehq.org/show_bug.cgi?id=48799 is probably obsolete as the patch by @Patola was afaik merged long ago.

The Wine controller dialog is kinda a red herring because while it may not display more than 32 buttons they do work just fine as long as the game run uses a more recent dinput lib. This can be observed with more modern games, like StarCitizen, where buttons > 32 also do not show in Wine's controller dialog but DO work just fine within the game. It's the additional axis, denoted as type 3 (EV_ABS), code 40 (ABS_MISC) and type 3 (EV_ABS), code 41 (?) in evtest that makes it go bonkers.

So what is responsible for interpreting these axis as buttons?

MNS26 commented 1 year ago

So what is responsible for interpreting these axis as buttons?

i still believe its not a (direct) issue with wine since i had a kernel version that worked fine (i sadly dont remember the version but it was... might be somewhere from end of 2021 - half way 2022)

MNS26 commented 1 year ago

any things to try and find out what it could be?

MNS26 commented 1 year ago

well after opening the throttle and poking wires to find the mouse nub P_20230501_162218

the top one is for vertical and bottom one is horizontal pulling the top to ground makes the mouse move down pulling the bottom to ground makes the mouse move right

only when testing with the top one makes wine go nuts

MNS26 commented 1 year ago

im not that great when it comes to software related bugs and debugging (i can do it but it would be my last choice)

MNS26 commented 1 year ago

shorting the pin to gnd gives 15, floating (middle point) is 8, vcc is 0

i couldnt find a easy way to pull high w/o risk of damage but grounding it was image

MNS26 commented 11 months ago

🥳 thanks to Rémi Bernon who helped me over on wineHQ to test a patch and seems to fix it

for those who want it too patch

(i mentioned this one in a new issue since this one has stagnated)


more than 8 axis breaks proton

Issue transferred from https://github.com/ValveSoftware/Proton/issues/7252. @MNS26 posted on 2023-11-11T15:07:53:

proton version: tested with 6.3 and newer wine version:

testing RP2040 with 8 axis image

RP2040 with 9 axis image

i have had this issue with my X52 pro as well but didnt know how to debug it

bekopharm made the folowing issue Thumbstick on HOTAS X52 (Pro) does trigger all kinds of buttons pressed

also made a report on wineHQ about this https://bugs.winehq.org/show_bug.cgi?id=55660


@MNS26 commented on 2023-11-11T17:05:38:

i just got a patch from Rémi Bernon over on wineHQ bus_sdl.c patch (cant send file directly since its not supported)

Web-eWorks commented 11 months ago

Excellent catch! That patch looks fairly straightforward, and the buffer-overrun would certainly explain why seemingly-random buttons start being pressed when the axis receives non-zero events. If the patch makes it into a wine-ge-custom build or regular lutris wine build I'll certainly test it, but I don't have the time or disk space to try to set up a custom wine build at the moment.

bekopharm commented 11 months ago

This was merged: https://gitlab.winehq.org/wine/wine/-/merge_requests/4389

So I guess we can close this and just have to wait for Proton to catch up.

Thanks everyone for debugging and fixing this :+1:

MNS26 commented 11 months ago

Excellent catch! That patch looks fairly straightforward, and the buffer-overrun would certainly explain why seemingly-random buttons start being pressed when the axis receives non-zero events. If the patch makes it into a wine-ge-custom build or regular lutris wine build I'll certainly test it, but I don't have the time or disk space to try to set up a custom wine build at the moment.

lutris wine will be applying them until its in wine itself (from GloriousEggroll) https://github.com/lutris/wine/issues/167#issuecomment-1806988110