ValveSoftware / Proton

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

USB joystick device (pedals) works via wine and proton, but not when run via Steam client #5126

Open coljac opened 3 years ago

coljac commented 3 years ago

This occurs with Proton 6.3-6 though I've reproduced with other versions as well.

Issue: USB joystick device (pedals) works via wine and proton, but not when run via steam

Description: I have a set of USB pedals that work fine in wine/proton games and show up in wine's control.exe panel (ID 068e:00f2 CH Products, Inc. Flight Sim Pedals). The device has an /dev/input/js and /dev/input/event device. It's a 3-axis joystick. The device doesn't show up in steam controller settings though two other joysticks do. When I play games, or invoke control.exe instead of the game's executable, the pedals are missing. However, if I invoke wine or proton in a different way (say, by setting the COMPAT_PATH and invoking "proton run /path/to/exe") this device does show up and does work. This is a workaround.

To reproduce: Run game via steam, then run from the command line with a different environment. In the first case, no pedals joystick; in the latter, it's there and usable. For testing I symlinked the game's launcher executable to proton's wine's control.exe, where I could see/not see the device appear.

I've attached a zip file with:

Attachments here

I also note, when I start Steam from the command line I see this; only the second two show up in game and in controller settings.


 type: 068e 00f2                            
  path: sdl://0                              
  serial_number:  - 0                        
  Manufacturer:                              
  Product:      CH PRODUCTS CH PRO PEDALS USB
  Release:      100                          
  Interface:    -1

Local Device Found
  type: 06a3 0c2d    
  path: sdl://1 
  serial_number:  - 0                        
  Manufacturer:    
  Product:      Saitek Pro Flight Quadrant
  Release:      100
  Interface:    -1

Local Device Found
  type: 044f b108    
  path: sdl://2 
  serial_number:  - 0                     
  Manufacturer:    
  Product:      Thrustmaster T.Flight Hotas X
  Release:      100
  Interface:    -1```

(I don't understand how proton invoked from Steam has a different environment, but I think it comes down to something in the LD_LIBRARY_PATH as messing around with this in my scripts can reproduce the behavior.)
aeikum commented 3 years ago

Do you have any of Steam's controller support features enabled? Any of the checkboxes in "Steam Settings -> Controller -> General Controller Settings".

coljac commented 3 years ago

Hi, thanks for responding.

I have Guide Button, Playstation and Generic Gamepad checked in controller settings.

I also forgot to mention I have "Steam Input Disabled" selected when I run. More info:

With steam input enabled, I see this in the logs for each joystick, including the pedals:

try_add_device hidraw "/dev/hidraw0": ignoring device 068e/00f2 with virtual Steam controller

coljac commented 3 years ago

I will leave one more update here for anyone with a similar problem comes across this issue.

The only thing I have to add is that, using sdl-jstest I find that the pedals are not detected by default with SDL1.2 but are with 2.0. However, I could fix this with export SDL_JOYSTICK_DEVICE=/dev/input/eventX for the pedals. This had no effect on Steam or wine.

I wanted to figure this out, and I traced things through proton to wine, reasoning that given my shell script invoking proton and pressing play in Steam ultimately invoke the same binary (wine), there must be some difference in the environment variables that is key. I went as far as replacing wine with a shell script that dumped the environment, then copying a working environment before invoking wine proper (i.e. copying a known working env at the very last stage when wine is run), and this seemed to make no difference. I'm not sure how the same command, with the same arguments and environment, could yield reproducibly different results. Apart from running wine in a debugger that's the best I can do!

martinezpenya commented 2 years ago

Similar situation with Raceroom... but I have to add that playing with proton 4.11, and 5.13 it was working well. But with later proton the pedals are not detected.

berarma commented 2 years ago

Originally posted by @martinezpenya in https://github.com/ValveSoftware/Proton/issues/1321#issuecomment-945190484

  • g27 pedals with leo bodnar (works only with proton 4.11 and 5.13, not with the latest version of proton) I've tested this in Assetto Corsa... because raceroom only works with proton-GE 2

I've talked to @martinezpenya to help him. In this case, the kernel doesn't create a /dev/input/js* entry for this device.

Looking at the SDL code that identifies devices classes, we can see that devices with axes and no buttons are identified as accelerometers: https://github.com/libsdl-org/SDL/blob/373216ae5be62b710ad68524777ae38ca712c53d/src/core/linux/SDL_evdev_capabilities.c#L58

The kernel might be doing the same but I haven't checked.

I don't know how Proton/Steam handles this, but since there's work being done to use SDL where possible, could it be that Steam is ruling out some devices because SDL doesn't report them as joysticks?

ttelford commented 2 years ago

Here's my system's behaviors. All devices work on Proton <= 5.0-10. Any greater version of Proton results in only the G29 wheel appearing.

Kernel/udev:

Devices created by udev and the kernel:

G29 Wheel:

/dev/input/js0
/dev/input/by-id/usb-Logitech_G29_Driving_Force_Racing_Wheel-event-joystick

Leo Bodnar Pedal Controller

/dev/input/by-id/usb-Leo_Bodnar_Logitech®_G25_Pedals_B75139-event-joystick

Generic handbrake

/dev/input/js1
/dev/input/by-id/usb-Vitaly__mega_mozg__Naidentsev_$'\302\210'$'\302\210'$'\302\210'$'\302\210'ODDOR-handbrake_MMJoy2-20160801-if01-event-joystick

Userspace Tests

evtest: works fine with the devices. sdl-jstest -l: Only shows the G29 wheel. sdl2-jstest -l: Shows all three devices.

aqxa1 commented 2 years ago

I just want to add that I can reproduce this as well. My SHH Shifter and Logitech Driving Force GT are detected, but CSL Elite LC pedals aren't detected in versions of Proton newer than 5.0.X.

All three devices are allocated /dev/input/jsX devices in my case, however.

sambazley commented 2 years ago

I've tracked the problem down to SDL's EV_IsJoystick function. For a device to be classed as a joystick, it must:

As a work around, I've written this program which duplicates a device's axes and adds an A button. I've tested it on Assetto Corsa and Assetto Corsa Competizione with my Fanatec CSL pedals.

coljac commented 2 years ago

I have tested @sambazley's solution and it works! Hats off to you sir/madam - I spent many hours on this and could not crack it.

berarma commented 2 years ago

I've tracked the problem down to SDL's EV_IsJoystick function. For a device to be classed as a joystick, it must:

* have either X and Y axes or a X and Y hat

* have a trigger, A button, or 1 button

As a work around, I've written this program which duplicates a device's axes and adds an A button. I've tested it on Assetto Corsa and Assetto Corsa Competizione with my Fanatec CSL pedals.

Please, see https://github.com/ValveSoftware/Proton/issues/5126#issuecomment-949428314.

Your link references SDL1.2 that is deprecated. In my comment there's a reference to the function in SDL2.

sambazley commented 2 years ago

@berarma You're right. I assumed the problem was caused by SDL-1.2 since sdl2-jstest found the devices where as sdl-jstest didn't, and because I noticed that it only worked when an A or 1 button was added, but looking now I seen that that function also checks for an A or 1 button.

berarma commented 2 years ago

How to tell SDL that a device with only axes is a joystick, not an accelerometer: https://github.com/libsdl-org/SDL/blob/d4f2f01580454deef8ac43d8939ebc907d4ad759/README-linux.txt

coljac commented 2 years ago

How to tell SDL that a device with only axes is a joystick, not an accelerometer: https://github.com/libsdl-org/SDL/blob/d4f2f01580454deef8ac43d8939ebc907d4ad759/README-linux.txt

Can somebody confirm this? I opened this issue, and I have

ENV{ID_INPUT_JOYSTICK}="1"

in a udev rule for my rudder pedals. It is possible I made an error somewhere else though.

berarma commented 2 years ago

Replying to https://github.com/ValveSoftware/Proton/issues/5126#issuecomment-1014960877

The rules consist of a line like this: SUBSYSTEM=="input", ATTRS{idProduct}=="0763", ATTRS{idVendor}=="06a3", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1"

Replace 0763 and 06a3 with the product and vendor ids of your device. You can see the ids in the output of the lsusb command.

coljac commented 2 years ago

The rules consist of a line like this:

Sorry to be unclear. I meant, I have a well-formed udev rule with the correct vendor and product IDs that also includes the ENV{ID_INPUT_JOYSTICK}="1" parameter, as specified in the link you provided. In other words, I tried that before I gave up and opened this issue.

sambazley commented 2 years ago

This didn't work me either. I verified that ID_INPUT_JOYSTICK=1 with udevadm info --query=all, and when that didn't work, I set ID_INPUT_ACCELEROMETER=0, which also didn't work.

berarma commented 2 years ago

This didn't work me either. I verified that ID_INPUT_JOYSTICK=1 with udevadm info --query=all, and when that didn't work, I set ID_INPUT_ACCELEROMETER=0, which also didn't work.

Does it something when runing Wine/Proton directly without Steam?

sambazley commented 2 years ago

Does it something when runing Wine/Proton directly without Steam?

It works with the same game running through Steam on Wine.

azampatti commented 2 years ago

Hey, +1 here. This issue is being bugging me since a while ago with an independent set of pedals for my driving simulator. Same issue as everybody else here with recent versions of Proton (I'm forced to use 5.0-10).

The program written by @sambazley works to an extent. Steam DOES detect the input and I can somehow map the axis, but they are all completely screwed up in terms of the movement, dead zone, etc so still unusable.

sdl2-jstest -l does list my device but again, other programs (like Manjaro's KDE default Game Controller settings page) won´t see it as a joystick.

My pedals have three axis and (of course) no buttons.

@berarma, I've been using your lg4ff for a WHILE (Thanks again for that! and being seeing this since I upgraded my pedals and Proton 5.13 launched.

Happy to help here with any input or logs/tests anybody would like me to contribute with. best, -Aldo

hodasemi commented 2 years ago

There was a comment with a more flexible mapper: https://github.com/berarma/oversteer/issues/89#issuecomment-1019553258

I haven't checked it, but it seems promising.

berarma commented 2 years ago

Replying to https://github.com/ValveSoftware/Proton/issues/5126#issuecomment-1024723981

Have you tested the workaround in https://github.com/ValveSoftware/Proton/issues/5126#issuecomment-1014421315.

azampatti commented 2 years ago

Replying to https://github.com/ValveSoftware/Proton/issues/5126#issuecomment-1024879263

Yes. It was already "on 1" the variable. I created the udev rules anyway, made no difference.

berarma commented 2 years ago

Anyone with this issue should check this: https://github.com/ValveSoftware/steam-for-linux/issues/8443#issuecomment-1054587604

ttelford commented 2 years ago

I wish I could report success for the EDTracker thread's tip, but it seems the udev rule is merely setting permissions on the hidraw device.

At least with my two devices (Leo Bodnar Pedal controller, and a generic handbrake), neither of the proposed ideas work:

# The rule to set permissions does function - but it doesn't let the controller function
KERNEL=="hidraw*", ATTRS{idVendor}=="1dd2", ATTRS{idProduct}=="100c", ATTRS{manufacturer}=="Leo Bodnar", MODE="0660", TAG+="uaccess"
# Manually setting the OS the input device is a Joystick doesn't seem to override anything in SDL, as the devices already report ID_INPUT_JOYSTICK properly. But, just to beat a dead horse...
KERNEL=="input", ATTRS{idVendor}=="1dd2", ATTRS{idProduct}=="100c", ATTRS{manufacturer}=="Leo Bodnar", MODE="0660", TAG+="uaccess", ENV{ID_CLASS}=="joystick", ENV{ID_INPUT_JOYSTICK}="1"

It's not a write permission issue, as far as I can see. steam-runtime-input-monitor reports the device as:

"guessed_type_flags" : [
        "accelerometer"
      ]

... There might be hope for the single-axis handbrake, though, as it at least reports as /dev/input/js0 (an old-style joystick device). The trick there is the USB device uses an invalid idVendor and idProduct (0000 in both - the rules don't seem to work; at least not yet. Maybe a night's sleep will fix it...)

Cr1515b commented 2 years ago

I had an issue with my flight pedals not showing up in steam, only 3 axies. I used this to solve the issue, https://github.com/beniwtv/evdev-spoof-device, maybe it will help you guys out.

ttelford commented 2 years ago

No joy with evdev-spoof-device or virtjs either.

virtjs appears to run:

./virtjs /dev/input/by-id/usb-Leo_Bodnar_Logitech®_G25_Pedals_B75139-event-joystick 
Leo Bodnar Logitech® G25 Pedals (1dd2:100c)

But proton games launched via Steam do not detect the pedals, and neither does sdl-jstest.

evdev-spoof-device doesn't work out of the box with Debian(sid) (index out of bounds), but it's dead simple... I just haven't had time to hack it yet... time being the big thing I wish I had to use to unravel this puzzle.

It's annoying that Steam's steam-runtime-input-monitor is able to see the devices... and that with Proton 5.0-10, they work -- but newer versions won't make these devices available for use.

ebak commented 2 years ago

Hi,

On Manjaro KDE the rudder is detected when I add my user to the input group.

$ sdl-jstest --list
Found 2 joystick(s)

Joystick Name:     'Thrustmaster T.16000M'
Joystick Number:    0
Number of Axes:     4
Number of Buttons: 16
Number of Hats:     1
Number of Balls:    0

Joystick Name:     'Thrustmaster T-Rudder'
Joystick Number:    1
Number of Axes:     3
Number of Buttons:  0
Number of Hats:     0
Number of Balls:    0

sudo usermod -aG input <your_user_name>

telegrapher commented 2 years ago

I've been impacted by this bug too. I'll make a summary:

BenFradella commented 2 years ago

Still affecting me. No issues with my wheel/pedals, but the usb handbrake is not detected by steam or the game (dirt rally 2). The handbrake is detected by sdl-jstest, and shows up in the KDE game controller thing.

Tried virtjs, evdev-spoof-device, and adding the udev rule -- nothing seemed to make any difference.

Spacefreak18 commented 1 year ago

I'm not sure if I'm looking at a different issue, but I'd like to share my findings.

I was experiencing issues with my usb-Leo_Bodnar_µBBI_Interface_B92816-event-joystick, showing up in wine, but not proton/steam.

This thread has sort of gone in multiple directions, but looking at the original issue, OP states that his equipment works fine when ran through wine, but it doesn't work through steam.

For me, that rules out a wine or SDL issue.

Maybe I'm chasing a red herring here, but I also noticed that my device was properly detected when I ran protontricks --no-bwrap -c 'wine control joy.cpl' gameid . Hopefully someone else here can try it and report back. But it sounds like an issue created by the containerization steam uses (bwrap). Is steam whitelisting only certain types of devices into the container?

Again, I am not too versed in the specifics of the steam implementation, and I'm not sure how much deeper I will dive as I have found a ( though not ideal ) workaround.

Spacefreak18 commented 1 year ago

I am currently using a workaround for my situation.

Similar to evdev-spoof-device I am using the xboxdrv. It has a feature called --mimic-xpad which allows any device to be detected as an xbox controller. Proton/Steam then has no problems detecting such a device.

So, I create a udev rule, that fires a systemd unit, with the xboxdrv mapping I chose for my devices.

here's an example systemd unit: https://github.com/Spacefreak18/linux-simracerx/blob/main/dotfiles/.config/systemd/user/button_box.service

here's an example udev rule: https://github.com/Spacefreak18/linux-simracerx/blob/main/udev/91-input.rules

BenFradella commented 1 year ago

FYI, I was able to use xboxdrv as a workaround for my handbrake as well. I just made a bash script that I can add to my launch options, e.g. spoof-hbrake %command%. The deadzone and calibration options map it to just the negative axis, rather than being bidirectional.

#!/bin/bash

xboxdrv --silent \
        --evdev        /dev/input/by-id/usb-FANATEC_ClubSport_USB_Handbrake-event-joystick \
        --evdev-absmap ABS_X=Y2 \
        --axismap      Y2^dead:-32768:0:1=Y2 \
        --calibration  Y2=-32768:-32767:32768 \
        --mimic-xpad &

trap "kill $!" EXIT

"$@"
VectorWolf commented 1 year ago

I have the exact same problem with my "Thrustmaster MFD Cougar Pack" but this time it isn't recognized by steam because it lacks two axis and only has its 28 buttons. Last working proton version is 5.0-10 . Lutris always worked without any problems, even their newest lutris-GE-Proton7-33 versions.

As a workaround I forked evdev-spoof-device with a little modification and now it works everywhere without any problems. If a device lacks any axis it now adds two dummy axis so my MFD is properly recognized by steam.

At first I tried protopedal but that did about the opposite of what i needed. Only mirrors axis and no buttons and adds dummy buttons.

DM0407 commented 1 year ago

Replying to https://github.com/ValveSoftware/Proton/issues/5126#issuecomment-1162098496

Device: Fanatec CSL LC pedals.

I wasn't able to see the pedals using any version of Proton. After trying the the work around (https://github.com/ValveSoftware/Proton/issues/5126#issuecomment-1113713848) I realized that my user could not see pedals unless I was root. I may have inadvertently changed the ownership while trying different fixes, but it might be worth a check.

While every other device was part of the input group, this device was owned by root:root and had incorrect permissions.

chown root:input /dev/input/eventX chmod 660 /dev/input/event20

kevenwyld commented 1 year ago

I had opened an issue over at steam-runtime because everything was magically working as of mid January. It turns out that some accidental changes to Steam Linux Runtime - Soldier allowed devices to be detected which previously did not work. Specifically my Heusinkveld Ultimate+ Sim Pedals which report only 3 axis and no buttons were detected on Steam Linux Runtime - Soldier version 0.20230111.85 with no intervention, but only that version, none before it and none after it.

I'm posting this here because I hope someone smarter than me can figure out why this happened and maybe help make this permanent without persisting the bug referenced in valve's reply.

For 3 glorious weeks I could play every simracing game I had in my library on Linux without any hacks =]

smcv commented 1 year ago

Specifically my Heusinkveld Ultimate+ Sim Pedals which report only 3 axis and no buttons were detected on Steam Linux Runtime - Soldier version 0.20230111.85 with no intervention, but only that version, none before it and none after it.

I think the problem here is that there is no way for Proton and SDL to distinguish between a 3-axis accelerometer and 3-axis pedals, other than "just knowing" that a particular list of device IDs are accelerometers or that a particular list of device IDs are pedals.

This is a design issue in the evdev interface that Linux uses to represent input devices: the kernel tells us that a device has an X, Y and Z axis, but doesn't give us many clues about what those axes mean. User-space code has to apply heuristics, like "if it has two or more axes and at least one joystick button, then it's probably some sort of gaming controller".

In particular, if a device has an accelerometer (like the one that's part of a PS3/PS4/PS5 gamepad), or if a device is an accelerometer, then all the kernel tells us is: "here is a device, it has X, Y and Z axes and no buttons. Enjoy!" For example, some tablet PCs have a built-in accelerometer to detect which way is up and change the screen orientation, while some older Thinkpad laptops have an accelerometer that was intended to detect the device being dropped and shut down the hard drive to prevent damage. We don't want accelerometers to be used as a gaming input by default, because then tilting your tablet PC or Thinkpad would act as a joystick, which is hilarious but not very practical.

If your sim pedals have 3 axes and no buttons, the information the kernel gives us is ... the same! So SDL assumes it's probably an accelerometer which needs to be avoided unless specifically requested, and so does Proton.

With hindsight, the good solution for this would have been for the kernel to have separate axes for "gaming X-axis" (which would be reported by joysticks) and "accelerometer X-axis" (which would be reported by accelerometers), but it doesn't, and changing that now would be a compatibility break, so we're stuck with it.

When not using a container environment, the workaround for this is that udevd has a big list of known devices in /lib/udev, and puts markers on them that say "this is a joystick" or "this is an accelerometer" or whatever, which SDL and Proton can use to refine their heuristic. This isn't meant to happen in versions of Proton that use the Steam Linux Runtime container (that's Proton 5.13+) because it isn't reliable in containers. However, in the versions of the container runtime that caused https://github.com/ValveSoftware/steam-for-linux/issues/9150, this was briefly happening even when in a container, which is why @kevenwyld's sim pedals were suddenly working, and stopped working with the recent hotfix for https://github.com/ValveSoftware/steam-for-linux/issues/9150.

The reason why we don't use udev in versions of Proton that use the container runtime (5.13+) is that it doesn't work properly across a container boundary. The events that tell Proton/SDL about game controller plug/unplug events don't get delivered, so hotplug doesn't work (which is why it caused https://github.com/ValveSoftware/steam-for-linux/issues/9150 when we accidentally used the udev code path). Also, the information that tells SDL/Proton more details about a device is not designed to be compatible between different versions of udev, but the version of libudev inside the container doesn't necessarily match the version in the host operating system. Sometimes it accidentally works (as it did for @kevenwyld recently) - but when it does, that's only through luck, and a udev upgrade could easily make it permanently stop working. So we can't rely on this.

I think the only way to make these devices work in the container environment would be to teach SDL or Proton (I'm not immediately sure which layer is the relevant one here) to be able to recognise them as gaming devices and not accelerometers.

Simulator controls like steering wheels, pedals and flight sticks are less commonly-used than Xbox/Playstation-style gamepads, so recognising gamepads has been a higher priority for the SDL and Proton developers. Pedals are also particularly difficult to recognise reliably if they only have axes and no buttons.

smcv commented 1 year ago

@ttelford:

steam-runtime-input-monitor reports the device as:

"guessed_type_flags" : [
        "accelerometer"
      ]

Yes, that's why SDL and/or Proton is rejecting it: based on the axes and buttons we can see, our best guess is that it is (or could be) an accelerometer. We definitely don't want accelerometers to be treated as joysticks, because then tablet PC users would find that tilting their device acted like a joystick.

Can you post the entire steam-runtime-input-monitor output for your device? If it's USB and hotpluggable, the easiest way would be:

  1. unplug the device you are having trouble with
  2. run ~/.steam/root/ubuntu12_32/steam-runtime/run.sh -- steam-runtime-input-monitor --direct
  3. wait for it to output all your other input devices
  4. at the end, it should output {"all-for-now": true} and then wait
  5. plug in the device you are having trouble with
  6. after steam-runtime-input-monitor stops producing new output, press Ctrl+C to exit from it
  7. copy all of the steam-runtime-input-monitor output that appeared after the all-for-now marker

If we're lucky then there might be something else in there that could positively identify it as being sim pedals.

Other people with a similar issue on different devices could do the same.

berarma commented 1 year ago

That's what USB HID report descriptors are for. There may be cases where the information in those descriptors might be wrong and that's when a device list might be needed but first use the information there.

smcv commented 1 year ago

@coljac:

However, if I invoke wine or proton in a different way (say, by setting the COMPAT_PATH and invoking "proton run /path/to/exe") this device does show up and does work. ... (I don't understand how proton invoked from Steam has a different environment

This is because you are, accidentally or intentionally, bypassing the container runtime. Proton 5.13+ is designed to run in a "Steam Linux Runtime - soldier" container, and is not guaranteed to run correctly without that. Even if it happens to work today, it won't necessarily work tomorrow, or next year, or for people running on a different OS.

I have ENV{ID_INPUT_JOYSTICK}="1" in a udev rule

Unfortunately this will have no effect on Proton and SDL running inside a "Steam Linux Runtime - soldier" container, because as I described in a previous comment, the udev code path will never be reliable there (and so we avoid using it).

@ttelford:

It's annoying that Steam's steam-runtime-input-monitor is able to see the devices

steam-runtime-input-monitor is designed to output information about all devices that Proton/SDL/Steam would technically be able to use if they wanted to. A device showing up there does not guarantee that it is something that Proton/SDL/Steam would want to use: in particular, accelerometers are not joysticks, and it would be a bug if Wine presented them to Windows games as an emulation of how joysticks appear in Windows. (It should either provide them as an emulation of how accelerometers appear in Windows, or not at all.)

Input devices that only have axes (no buttons) or only buttons (no axes) are collateral damage here, unfortunately.

@martinezpenya:

I have to add that playing with proton 4.11, and 5.13 it was working well

I think perhaps you were mixing up versions? I would have expected Proton 4.11 and 5.0 to be on the "not a container" code path (which would explain different behaviour there), while 5.13 and all later versions run in a container.

@Spacefreak18:

OP states that his equipment works fine when ran through wine, but it doesn't work through steam. For me, that rules out a wine or SDL issue.

The overall system made up of the container runtime, SDL, Wine and Proton is quite complicated, and this is an issue that touches multiple layers. The container runtime cannot be 100% transparent because we're constrained by how other components behave, so SDL/Wine/Proton also need to be doing the right thing.

I think the difference here is that the OP was (intentionally or accidentally) not using the container runtime in the working situation.

But it sounds like an issue created by the containerization steam uses (bwrap). Is steam whitelisting only certain types of devices into the container?

No, the way the container runtime uses bwrap is not designed to be a sandbox or a security boundary, and all devices are made available in the container. The problem is that SDL/Wine/Proton in the container can't use the same code path to identify "good" and "bad" devices that they would use outside the container, so they have to use a heuristic to identify what is a joystick ("good") and what is an accelerometer ("bad"), which works fine for typical gamepads and flight sticks but breaks down in corner cases like pedals that have no buttons.

smcv commented 1 year ago

That's what USB HID report descriptors are for. There may be cases where the information in those descriptors might be wrong and that's when a device list might be needed but first use the information there.

I wish it was that simple! The evdev devices are a semi-high-level interface to input devices for which user-space doesn't necessarily have direct access. If the kernel can get this information out of the USB HID report descriptors, but doesn't share it with user-space, then user-space can't magic that information out of nowhere.

The information that's available from the evdev device node is the information that steam-runtime-input-monitor --direct shows, and that's what's available as input to the heuristics used in SDL and Wine/Proton.

SDL and Proton can access some HID devices via "raw HID", which does provide access to the HID report descriptors, but this only works if user programs are given access to the /dev/hidraw* device nodes. However, giving user-space access to all /dev/hidraw* device nodes would be a security vulnerability on multi-user systems, because it would let one user run a keylogger that monitors another user's keyboard input; so the developers of lower layers of the system are (justifiably) reluctant to open up access to those.

berarma commented 1 year ago

Replying to https://github.com/ValveSoftware/Proton/issues/5126#issuecomment-1434539649

There you have the issue that has to be fixed. If the kernel doesn't supply that information then why not fix it? Trying to guess what a device is when the kernel could tell you is the wrong approach in my opinion.

smcv commented 1 year ago

There you have the issue that has to be fixed. If the kernel doesn't supply that information then why not fix it? Trying to guess what a device is when the kernel could tell you is the wrong approach in my opinion.

That isn't something that Proton can do. I've asked some kernel developers to look into it, but even if they solved it in the kernel today, it would take quite a long time for it to get through the kernel review and release process and into your distribution.

(I do agree with you that the ideal long-term solution is for the kernel to give user-space more information.)

schlegp commented 1 year ago

Since I am not able to provide much else that might be helping, here is the output of steam-runtime-input-monitor when hotplugging my VRS DirectForcePro Pedals:

{
  "added" : {
    "interface_flags" : [
      "event",
      "readable",
      "read-write"
    ],
    "type_flags" : [
      "accelerometer"
    ],
    "dev_node" : "/dev/input/event4",
    "subsystem" : "input",
    "sys_path" : "/sys/devices/pci0000:00/0000:00:08.1/0000:0d:00.3/usb5/5-3/5-3:1.0/0003:0483:A3BE.0039/input/input68/event4",
    "bus_type" : "0x0003",
    "vendor_id" : "0x0483",
    "product_id" : "0xa3be",
    "version" : "0x0111",
    "evdev" : {
      "types" : [
        "SYN",
        "ABS"
      ],
      "absolute_axes" : [
        "X",
        "Y",
        "Z"
      ],
      "relative_axes" : [
      ],
      "keys" : [
      ],
      "input_properties" : [
      ]
    },
    "hid_ancestor" : {
      "sys_path" : "/sys/devices/pci0000:00/0000:00:08.1/0000:0d:00.3/usb5/5-3/5-3:1.0/0003:0483:A3BE.0039",
      "name" : "Smarty Co. VRS DirectForce Pro Pedals",
      "bus_type" : "0x0003",
      "vendor_id" : "0x0483",
      "product_id" : "0xa3be",
      "uniq" : "PCC92BBA6B"
    },
    "input_ancestor" : {
      "sys_path" : "/sys/devices/pci0000:00/0000:00:08.1/0000:0d:00.3/usb5/5-3/5-3:1.0/0003:0483:A3BE.0039/input/input68",
      "name" : "Smarty Co. VRS DirectForce Pro Pedals",
      "bus_type" : "0x0003",
      "vendor_id" : "0x0483",
      "product_id" : "0xa3be",
      "version" : "0x0111"
    },
    "usb_device_ancestor" : {
      "sys_path" : "/sys/devices/pci0000:00/0000:00:08.1/0000:0d:00.3/usb5/5-3",
      "vendor_id" : "0x0483",
      "product_id" : "0xa3be",
      "version" : "0x0100",
      "manufacturer" : "Smarty Co.",
      "product" : "VRS DirectForce Pro Pedals",
      "serial" : null
    }
  }
}

Has anyone else had the issue of Protopedal now not working anymore aswell? Something changed and now even the workaround doesn't work anymore.

smcv commented 1 year ago

Thank you, this confirms what I suspected. This amount of information:

      "types" : [
        "SYN",
        "ABS"
      ],
      "absolute_axes" : [
        "X",
        "Y",
        "Z"
      ],
      "relative_axes" : [
      ],
      "keys" : [
      ],
      "input_properties" : [
      ]

is not enough for SDL or Proton to tell the difference between an accelerometer and 3 pedals.

schlegp commented 1 year ago

How realistic would something like a environment variable be, where we override this decision by SDL/Proton?

I am not sure where something like that would be placed correctly, but explicitely passing a device over could be quite useful for these scenarios.

kevenwyld commented 1 year ago

Can you post the entire steam-runtime-input-monitor output for your device?

Sorry for the delay, mine looks roughly the same as above:

expand for output from steam-runtime-input-monitor

```json { "added" : { "interface_flags" : [ "event", "readable", "read-write" ], "type_flags" : [ "accelerometer" ], "dev_node" : "/dev/input/event8", "subsystem" : "input", "sys_path" : "/sys/devices/pci0000:00/0000:00:08.1/0000:0e:00.3/usb5/5-3/5-3.2/5-3.2.3/5-3.2.3:1.0/0003:30B7:1003.005F/input/input123/event8", "bus_type" : "0x0003", "vendor_id" : "0x30b7", "product_id" : "0x1003", "version" : "0x0111", "evdev" : { "types" : [ "SYN", "ABS" ], "absolute_axes" : [ "RX", "RY", "RZ" ], "relative_axes" : [ ], "keys" : [ ], "input_properties" : [ ] }, "hid_ancestor" : { "sys_path" : "/sys/devices/pci0000:00/0000:00:08.1/0000:0e:00.3/usb5/5-3/5-3.2/5-3.2.3/5-3.2.3:1.0/0003:30B7:1003.005F", "name" : "Heusinkveld Heusinkveld Sim Pedals Ultimate", "bus_type" : "0x0003", "vendor_id" : "0x30b7", "product_id" : "0x1003", "uniq" : "SP24CB020358DEF856" }, "input_ancestor" : { "sys_path" : "/sys/devices/pci0000:00/0000:00:08.1/0000:0e:00.3/usb5/5-3/5-3.2/5-3.2.3/5-3.2.3:1.0/0003:30B7:1003.005F/input/input123", "name" : "Heusinkveld Heusinkveld Sim Pedals Ultimate", "bus_type" : "0x0003", "vendor_id" : "0x30b7", "product_id" : "0x1003", "version" : "0x0111" }, "usb_device_ancestor" : { "sys_path" : "/sys/devices/pci0000:00/0000:00:08.1/0000:0e:00.3/usb5/5-3/5-3.2/5-3.2.3", "vendor_id" : "0x30b7", "product_id" : "0x1003", "version" : "0x0000", "manufacturer" : "Heusinkveld", "product" : "Heusinkveld Sim Pedals Ultimate", "serial" : null } } } ```

smcv commented 1 year ago

mine looks roughly the same as above

This has RX, RY, RZ axes instead of X, Y, Z, but is otherwise the same "shape". It's useful to confirm that both sets of 3 axes exist as sets of pedals in practice.

kevenwyld commented 1 year ago

@smcv I'm also curious if there isn't some compromise that could be implemented here allowing users to specify device overrides somehow, or simply to detect all devices, even some that might be problematic, when some flag/var is provided. In the absence of a perfect solution that fits everyone's use case it seems like the next best thing would be to allow downstream customization for users who understand the risks.

For example I'm 100% confident that my sim rig doesn't have an accelerometer, and even if it did I'd be fine making it do nothing in game, just like I do with the input from my joystick when I'm not using it.

felixhaedicke commented 1 year ago

Another workaround is forcing SDL (which is used by Proton to access joysticks) to use the Linux classic joystick API, using the environment variable SDL_LINUX_JOYSTICK_CLASSIC=1. Specify e. g. SDL_LINUX_JOYSTICK_CLASSIC=1 %command% in the Steam launch options.

felixhaedicke commented 1 year ago

SDL issue: https://github.com/libsdl-org/SDL/issues/7500, and proposed fix: https://github.com/libsdl-org/SDL/pull/7501.