This page tracks known compatibility work that is larger than a small report packing fix. Keep entries here until the repo has a validated implementation path and consumer tests or manual validation prove the behavior.
Status: unresolved for the Windows VHF backend.
The Windows Xbox Series profile currently preserves the native 17-byte
GIP-shaped input report, including Share/Misc as button bit 12, and uses the
captured VID_045E&PID_0B12 release 0x0509 identity. Browser HID testers can
see the virtual HID device, but Steam's controller tester still does not expose
the Share button.
The blocking issue is Steam's input path selection. Physical Xbox Series USB,
Bluetooth, and Xbox Wireless Adapter controllers enter Steam's Xbox HIDAPI path
and map Share as misc1:b11. The VHF-created Windows HID child is consumed
through the Windows XInput path instead. XInput exposes the standard Xbox button
set only and has no Share/Misc button. SDL's Xbox HIDAPI driver also rejects the
Windows \\?\HID# fake endpoints used for XGIP controllers, so changing only
the VHF HID descriptor cannot force Steam into the same path used by physical
Xbox Series transports.
Proposed solution:
- Add a separate Windows Xbox transport that is not a VHF HID child and can be accepted by Steam's Xbox HIDAPI/GIP path.
- Model the transport on captured physical Xbox Series USB, Bluetooth, and Xbox Wireless Adapter device trees, including the parent transport identity, interface class, compatible IDs, report initialization behavior, and output report routing.
- Keep the existing VHF Xbox Series path as the user-mode compatibility path until the new transport is implemented and validated.
- Validate with Steam controller logs and the Steam controller tester before
claiming Share support. Required proof is a Steam mapping containing
misc1:b11for the virtual device and working normal buttons, triggers, D-pad, Guide, and rumble.
Non-goals for this item:
- Do not add a kernel-mode driver to the normal C++ library.
- Do not keep trying descriptor-only VHF remaps for Steam Share support.
- Do not change the public platform-neutral profile API for a Windows-specific transport limitation.
Status: proposed.
Manual capture files are useful while debugging controller compatibility, but hand-curated JSON is not a durable source-control artifact. Future captures should be generated by the same tool that users run, with a documented schema and predictable redaction behavior.
Proposed solution:
- Add a capture/export mode to
virtualhid_controlthat can enumerate connected HID/gamepad devices, let the user select one, and save a JSON capture file. - Make the capture schema useful for any controller type, not only the profiles currently implemented by libvirtualhid.
- Record stable evidence by default: VID/PID, release number, manufacturer, product, transport, HID descriptor/report metadata, supported feature/output report IDs, public PnP compatible IDs, and consumer observations when the tool can collect them.
- Redact machine-unique values by default, including instance IDs, serial-like values, Bluetooth addresses, container IDs, local file paths, and driver INF names. Add an explicit unsafe/debug option only if raw local evidence is needed.
- Keep JSON support scoped to the tool target. If this is implemented in C++,
prefer
nlohmann/json, but do not expose that dependency through the public libvirtualhid API. - Treat generated capture files as local debugging artifacts by default. Only commit a generated capture later if it is reproducible, sanitized, and used by tests or documentation in a way that justifies keeping it.
Status: unresolved or not fully validated for DualShock 4, DualSense, and Switch Pro-style virtual gamepads in consumer paths.
The profiles expose the native descriptors and the Windows backend answers the
initialization feature reports needed by HIDAPI-style clients. The remaining
gap is output behavior after consumers open the virtual controllers: rumble is
not reliably reaching the public GamepadOutput callback for PlayStation 4,
PlayStation 5, and Nintendo-style gamepads in manual validation.
Proposed solution:
- Capture physical-controller output traffic for DualShock 4, DualSense, and Switch Pro over the relevant transports used by Steam, SDL, and browser HID testers.
- Compare those output and feature reports against the virtual backend's accepted reports, including report IDs, leading zero/report-ID conventions, initialization order, and transport-specific payload variants.
- Extend the report parsers and backend output routing only where a captured consumer report proves the missing behavior.
- Add regression tests for each accepted rumble payload shape before relying on manual testing.
- Validate with at least one real consumer per platform path. For Steam, the required proof is a received virtual-control output report or a normalized rumble callback after triggering controller rumble in Steam's tester.
Implementation notes:
- DualShock 4 and DualSense output paths may differ between USB, Bluetooth, and HIDAPI-initialized reports.
- Switch Pro output may require the native initialization sequence to complete before rumble packets are accepted.
- Linux
uhidand Windows VHF have different report-ID delivery behavior, so both prefixed and unprefixed payloads need explicit coverage where consumers actually send them.