Add gamepad support by rom1v · Pull Request #5270 · Genymobile/scrcpy (original) (raw)
rom1v mentioned this pull request
8 tasks
Pushing a close event from the keyboard_aoa or mouse_aoa implementation was racy, because the AOA thread might be stopped before these events were processed.
Instead, keep the list of open AOA devices to close them automatically from the AOA thread before exiting.
Now that the AOA open/close are asynchronous, an open error did not make scrcpy exit anymore.
Add a mechanism to exit if the AOA device could not be opened asynchronously.
Fix typo and reference the latest version of "HID Usage Tables" specifications.
Mouse and keyboard events with unknown button/keycode/scancode cannot be handled properly. Discard them without forwarding them to the keyboard or mouse processors.
This can happen for example if a more recent version of SDL introduces new enum values.
Introduce a gamepad processor trait, similar to the keyboard processor and mouse processor traits.
Handle gamepad events received from SDL, convert them to scrcpy-specific gamepad events, and forward them to the gamepad processor.
Further commits will provide AOA and UHID implementations of the gamepad processor trait.
Co-authored-by: Luiz Henrique Laurini luizhenriquelaurini@gmail.com
This will be helpful for writing HID values.
Implement the HID protocol for gamepads, that will be used in further commits by the AOA and UHID gamepad processor implementations.
Similar to AOA keyboard and mouse, but for gamepads.
Can be enabled with --gamepad=aoa.
Trigger SDL_CONTROLLERDEVICEADDED for all gamepads already connected when scrcpy starts. We want to handle both the gamepads initially connected and the gamepads connected while scrcpy is running.
This is not racy, because this event may not be trigged automatically until SDL events are "pumped" (SDL_PumpEvents/SDL_WaitEvent).
Implement gamepad support for OTG.
This message will be sent on gamepad disconnection.
Contrary to keyboard and mouse devices, which are registered once and unregistered when scrcpy exists, each physical gamepad is mapped with its own HID id, and they can be plugged and unplugged dynamically.
Similar to UHID keyboard and mouse, but for gamepads.
Can be enabled with --gamepad=uhid or -G.
It is not enabled by default because not all devices support UHID (there is a permission error on old Android versions).
For convenience, short options were added to select UHID input modes:
- -K for --keyboard=uhid
- -M for --mouse=uhid
- -G for --gamepad=uhid
In OTG mode, UHID is not available, so the short options should select AOA instead.
Make the local function write_string() accept the output buffer as a first parameter, like the other similar functions.
Initialize UHID devices with a custom name:
- "scrcpy: $GAMEPAD_NAME" for gamepads
- "scrcpy" for keyboard and mouse (or if no gamepad name is available)
The name may appear in Android apps.
There was a registration mechanism to listen to HID outputs with a specific HID id.
However, the UHID gamepad processor handles several ids, so it cannot work. We could complexify the registration mechanism, but instead, directly dispatch to the expected processor based on the UHID id.
Concretely, instead of passing a sc_uhid_devices instance to construct a sc_keyboard_uhid, so that it can register itself, construct the sc_uhid_devices with all the UHID instances (currently only sc_keyboard_uhid) so that it can dispatch HID outputs directly.
The sc_uhid_devices instance is initialized only when there is a UHID keyboard.
The device message receiver assumed that it could not receive HID output reports without a sc_uhid_devices instance (i.e. without a UHID keyboard), but in practice, a UHID driver implementation on the device may decide to send UHID output reports for mouse or for gamepads (and we must just ignore them).
So remove the assert().
Mainly copied and adapted from HID keyboard and mouse documentation.
Capture the gamepads even when the window is not focused.
Note: In theory, with this flag set, we could capture gamepad events even without a window (--no-window). In practice, scrcpy still requires a window, because --no-window implies --no-control, and the input manager is owned by the sc_screen instance, which does not exist if there is no window. Supporting this use case would require a lot of refactors.
Refs <#5270 (comment)> PR #5270 <#5270>
Suggested-by: Luiz Henrique Laurini luizhenriquelaurini@gmail.com
UHID may not work on old Android versions due to permission errors.
Mention it in UHID mouse and gamepad documentation (it was already mentioned for UHID keyboard).
Refs #4473 comment <#4473 (comment)> PR #5270 <#5270>
Android does not support multiple HID gamepads properly over AOA.
This was referenced
Sep 15, 2024
This was referenced
Nov 28, 2024
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
[ Show hidden characters]({{ revealButtonHref }})