SDL icon indicating copy to clipboard operation
SDL copied to clipboard

Add support for libusb device whitelisting

Open flibitijibibo opened this issue 3 years ago • 9 comments

When combining both libusb and an OS backend for SDL_hidapi, we want to ensure that libusb is only used when absolutely necessary. At the same time, we don't want to interfere with platforms that only have libusb. So, implement a whitelist but only use it when another backend exists.

With this in place, it should now be safe to enable libusb support by default.

Affects SDL_hidapi (Sam), configure.ac (Ozkan), and CMake (Anon).

Fixes #6005

flibitijibibo avatar Aug 06 '22 17:08 flibitijibibo

This doesn't bring back https://github.com/libsdl-org/SDL/issues/5722 does it?

sezero avatar Aug 06 '22 17:08 sezero

No, it should only affect devices that aren't visible to the Linux hid.c backend. There's logic in the libusb hid.c that takes over devices during enumeration but it's disabled (with good reason).

flibitijibibo avatar Aug 06 '22 17:08 flibitijibibo

I believe this will break Xbox controllers on Steam Link, where we use linux/hid.c, but xpad is largely unused and we rely on libusb for access to those devices.

I'm putting this in the next milestone so we can smoke out issues like these early in the milestone.

slouken avatar Aug 06 '22 19:08 slouken

Pushed the SDL_bool change.

For Link, it should be possible to make the list user-modifiable, not sure how that might be done though.

flibitijibibo avatar Aug 06 '22 20:08 flibitijibibo

Moved the check a little closer to the whitelist declaration, to make it easier to keep the whitelist work in one place (in case we do end up adding variables or something).

flibitijibibo avatar Aug 06 '22 20:08 flibitijibibo

For Link, it should be possible to make the list user-modifiable, not sure how that might be done though.

For systems where exclusive access to the device isn't an issue, like Steam Link, we probably want to turn this off. Maybe we can make it a configure option?

slouken avatar Aug 06 '22 20:08 slouken

It's almost like we want 3 passes:

  1. Devices where libusb is preferred (e.g. GameCube adapter)
  2. Devices where platform support is preferred (e.g. almost everything else)
  3. Devices which platform support doesn't pick up (e.g. Xbox controllers)

slouken avatar Aug 06 '22 20:08 slouken

If it's possible to prioritize, switching the order to have libusb as the last pass would definitely be enough, since the adapter doesn't show up as a regular device anyhow.

flibitijibibo avatar Aug 06 '22 20:08 flibitijibibo

It looks like the backend priority was flipped to libusb first in this commit: https://github.com/libsdl-org/SDL/commit/69a8c8468c211d66ad547a352c4762470298aa36

slouken avatar Aug 06 '22 20:08 slouken

libusb enforces exclusive access to the device, which isn't generally useful on desktop systems. I don't mind a define for custom systems that enables this, but I don't think we should do it by default.

Feel free to submit another PR that implements an option for this, but I'll go ahead and close this one.

slouken avatar Nov 23 '22 18:11 slouken

Just to be sure: Does it enforce exclusive access during enumeration time? The main goal of this patch was to enumerate first and avoid any device that wasn't in the list, so that libusb doesn't take it over - if anything this should make it take devices less often, but that will only be true if enumeration doesn't grab the device to get the product information.

flibitijibibo avatar Nov 23 '22 18:11 flibitijibibo

No, enumeration is fine, it's only if you open it. I'm going to reopen this, I think I misunderstood the intent.

slouken avatar Nov 23 '22 20:11 slouken

Is this blocked on something in particular? or is it held up by just a lack of time?

Lokathor avatar Aug 09 '23 15:08 Lokathor

I'm going to change it to merge lists based on device priority, but I haven't gotten time to do that yet.

slouken avatar Aug 09 '23 16:08 slouken

Actually... this is pretty good as-is. We just need to enable an option to change the whitelist behavior from CMake.

slouken avatar Aug 09 '23 16:08 slouken

I'll rebase this today!

flibitijibibo avatar Aug 09 '23 17:08 flibitijibibo

Rebase is done - CMake should now enable libusb by default when available for all targets, but at the same time it will only affect builds that have libusb and another hidapi backend available, so the *BSDs shouldn't be affected here.

flibitijibibo avatar Aug 09 '23 17:08 flibitijibibo

Just to be clear:

  • would this make the pre-built SDL for windows support things like the GameCube controller automatically?
  • would an SDL built from source also need to get a copy of libusb for windows during the build for that to be enabled, or is the necessary libusb stuff dynamically linked or whatever?

Lokathor avatar Aug 09 '23 18:08 Lokathor

Updated to "fix" the CMake changes, but my solution is really clumsy - feel free to redo it if it's not too hard to fix! (This may affect the premade project files as well, not sure if that's in CI...)

flibitijibibo avatar Aug 09 '23 18:08 flibitijibibo

@madebr, can you review the CMake changes?

slouken avatar Aug 09 '23 18:08 slouken

Just to be clear:

  • would this make the pre-built SDL for windows support things like the GameCube controller automatically?
  • would an SDL built from source also need to get a copy of libusb for windows during the build for that to be enabled, or is the necessary libusb stuff dynamically linked or whatever?

I don't think we're planning on adding libusb to the Windows build. That may change by the time SDL 3.0 ships though.

slouken avatar Aug 09 '23 18:08 slouken

Ah. It was suggested in https://github.com/libsdl-org/SDL/issues/7481 that this PR would be the most likely path to using gamecube controllers on Windows. Unfortunate, but I guess that can be resolved in the future.

Lokathor avatar Aug 09 '23 19:08 Lokathor

Took a different approach that mostly avoids CMake altogether - instead of determining the use as a build config, I've changed it to a hint, which is enabled by default only when there are other hidapi backends available. This seemed like a better way to allow enabling/disabling this for a particular application without having to rebuild SDL or redirect dynapi to a custom file.

flibitijibibo avatar Aug 12 '23 16:08 flibitijibibo

Assuming https://github.com/libsdl-org/SDL/pull/6014#issuecomment-1207251777 holds, the cmake changes are fine: libusb will be enabled for most platforms.

madebr avatar Aug 12 '23 18:08 madebr

Looks good, thanks!

slouken avatar Aug 13 '23 21:08 slouken

This did indeed break Steam Link hardware: https://steamcommunity.com/app/353380/discussions/0/5992658048661696817/

The problem is that opening a device with libusb unbinds it from the HID subsystem, which is what SDL uses to detect and open Steam Controllers on Steam Link hardware.

What we really need to do is enumerate the devices using all the back ends and then add them to the enumeration list based on driver priority, which is controlled by the whitelisting process.

slouken avatar Sep 15 '23 10:09 slouken

Fixed in 5774c9638

slouken avatar Sep 15 '23 12:09 slouken