[GH-ISSUE #50] What inputtino could adopt from libvirtualhid (Sunshine's new cross-platform virtual-HID sibling) #15

Closed
opened 2026-10-15 12:51:12 +00:00 by bsakaguchi · 3 comments
Owner

Originally created by @kmreisi on GitHub (Sep 26, 2026).
Original GitHub issue: https://github.com/games-on-whales/inputtino/issues/50

Why this issue

Independent comparison research prompted by #44 (the dynamic-UHID/Joy-Con roadmap) and games-on-whales/gst-wayland-display#64 (pen/tablet support). Posting findings here since they're actionable for inputtino specifically, not a critique of the roadmap.

Side finding for anyone tracing #64 → inputtino: gst-wayland-display PR #64 (zwp_tablet_v2 pen support) is self-contained to the compositor; its own description says the only other piece needed is a wolf-side companion patch for lobby hotplug. It does not need or use any inputtino change — inputtino's existing uinput-based PenTablet was already sufficient. (#42, the pen-tablet flaky-test fix, is unrelated pre-existing test-stability work, not something #64 required.)

The comparison

LizardByte/libvirtualhid is a new (created 2026-06-18) C++ virtual-HID library from Sunshine's org, targeting the same "virtual HID for a remote streaming host" problem inputtino solves. Worth knowing about regardless of any adoption decision, since Sunshine is a downstream consumer of inputtino today.

inputtino libvirtualhid
Platforms Linux only Windows (signed UMDF2/VHF driver), Linux, FreeBSD, partial macOS
License MIT throughout MIT for the library; Windows driver source + package under a separate source-available license, and creating gamepads/keyboards/Raw-Input mice via the Windows driver requires a paid license
API shape VirtualDevice base + a concrete C++ subclass per controller family Runtime factory + one device interface + a capability-flag struct (GamepadProfileSupport: rumble/trigger-rumble/RGB/adaptive-trigger/motion/touchpad/battery) queried at runtime
Bindings Python + Rust, in-tree C++ only
Docs README + external blog posts In-repo per-platform quirks doc (463 lines), streaming-host integration guide, driver docs
Diagnostic tooling none virtualhid_control (SDL3+ImGui GUI for manual device testing)
CI none for the C++ core (see below) 11 workflows: build+test, CodeQL, SonarCloud, Codecov, Renovate
Recent velocity 0 commits to stable in 90 days; last merge 2026-07-13 50 commits in the last 90 days; pushed today

inputtino's own in-flight #40 (Joypad::TYPE + Joypad::create() + capability flags hoisted onto the base class) is already converging on libvirtualhid's capability-struct model independently — worth treating libvirtualhid as existing prior art for that direction, not a reason to change course.

Concrete finding: the C++ test suite isn't wired into CI, and it currently fails

Verified hands-on against stable @ d28ec79 (not just the WIP branch):

  1. Default test build is broken out of the box. cmake -DBUILD_TESTING=ON .. fails to link: tests/CMakeLists.txt unconditionally compiles testCAPI.cpp into inputtino_tests, but the C API it calls only exists when -DBUILD_C_BINDINGS=ON is also passed (off by default). Needs -DBUILD_TESTING=ON -DBUILD_C_BINDINGS=ON together to link at all.
  2. With that fixed, ctest on stable gives 18/20 passing, 2 failing:
    • virtual mouse absolue — SIGSEGV (testLibinput.cpp:129), right after a libinput debounce press/release sequence.
    • PS Joypad — assertion failure on a motion/IMU sample (testUHID.cpp:321): expected -28.595, got 0.0.
    • Both reproduce identically on the feature/joycons roadmap tip, so they predate and are independent of the open roadmap PRs.
    • Caveat: this was run in a minimal container without a full desktop/udev session, so I can't rule out an environment artifact for either failure — but that's exactly the point: there's currently no CI baseline to compare against, so nobody can tell from the repo alone whether these are real regressions or sandbox noise.

Suggestion: add a CI workflow that builds with -DBUILD_TESTING=ON -DBUILD_C_BINDINGS=ON and runs ctest, mirroring what libvirtualhid already does. This is the single highest-leverage adoption item — it would have caught both issues above automatically, and would materially help the review bottleneck visible on #37/#40/#43 (a single reviewer currently has to manually verify each PR builds and passes).

Other adoption suggestions, roughly by leverage

  1. CI for the existing Catch2 suite (above).
  2. In-repo platform/quirks documentation, modeled on libvirtualhid's docs/platform-support.md — the hard-won HID compatibility knowledge currently lives in PR descriptions, commit messages, and external blog posts rather than the repo.
  3. Capability-struct API — already the direction of #40; no change needed, just flagging libvirtualhid as a working reference implementation of the same idea.
  4. (Lower priority) a small diagnostic tool for manually creating/driving test devices, à la virtualhid_control — could have made the touchscreen MT-slot bug (#47) easier to catch by hand.

Not proposing inputtino chase Windows/macOS/FreeBSD support — that's a different scope decision — just flagging that libvirtualhid exists, since it's built by Sunshine's own org for the same problem.

Originally created by @kmreisi on GitHub (Sep 26, 2026). Original GitHub issue: https://github.com/games-on-whales/inputtino/issues/50 ## Why this issue Independent comparison research prompted by #44 (the dynamic-UHID/Joy-Con roadmap) and games-on-whales/gst-wayland-display#64 (pen/tablet support). Posting findings here since they're actionable for inputtino specifically, not a critique of the roadmap. **Side finding for anyone tracing #64 → inputtino:** gst-wayland-display PR #64 (zwp_tablet_v2 pen support) is self-contained to the compositor; its own description says the only other piece needed is a wolf-side companion patch for lobby hotplug. It does not need or use any inputtino change — inputtino's existing uinput-based `PenTablet` was already sufficient. (#42, the pen-tablet flaky-test fix, is unrelated pre-existing test-stability work, not something #64 required.) ## The comparison [LizardByte/libvirtualhid](https://github.com/LizardByte/libvirtualhid) is a new (created 2026-06-18) C++ virtual-HID library from Sunshine's org, targeting the same "virtual HID for a remote streaming host" problem inputtino solves. Worth knowing about regardless of any adoption decision, since Sunshine is a downstream consumer of inputtino today. | | inputtino | libvirtualhid | |---|---|---| | Platforms | Linux only | Windows (signed UMDF2/VHF driver), Linux, FreeBSD, partial macOS | | License | MIT throughout | MIT for the library; Windows driver source + package under a separate source-available license, and creating gamepads/keyboards/Raw-Input mice via the Windows driver requires a paid license | | API shape | `VirtualDevice` base + a concrete C++ subclass per controller family | `Runtime` factory + one device interface + a capability-flag struct (`GamepadProfileSupport`: rumble/trigger-rumble/RGB/adaptive-trigger/motion/touchpad/battery) queried at runtime | | Bindings | Python + Rust, in-tree | C++ only | | Docs | README + external blog posts | In-repo per-platform quirks doc (463 lines), streaming-host integration guide, driver docs | | Diagnostic tooling | none | `virtualhid_control` (SDL3+ImGui GUI for manual device testing) | | CI | none for the C++ core (see below) | 11 workflows: build+test, CodeQL, SonarCloud, Codecov, Renovate | | Recent velocity | 0 commits to `stable` in 90 days; last merge 2026-07-13 | 50 commits in the last 90 days; pushed today | inputtino's own in-flight #40 (`Joypad::TYPE` + `Joypad::create()` + capability flags hoisted onto the base class) is already converging on libvirtualhid's capability-struct model independently — worth treating libvirtualhid as existing prior art for that direction, not a reason to change course. ## Concrete finding: the C++ test suite isn't wired into CI, and it currently fails Verified hands-on against `stable` @ d28ec79 (not just the WIP branch): 1. **Default test build is broken out of the box.** `cmake -DBUILD_TESTING=ON ..` fails to link: `tests/CMakeLists.txt` unconditionally compiles `testCAPI.cpp` into `inputtino_tests`, but the C API it calls only exists when `-DBUILD_C_BINDINGS=ON` is also passed (off by default). Needs `-DBUILD_TESTING=ON -DBUILD_C_BINDINGS=ON` together to link at all. 2. With that fixed, `ctest` on `stable` gives **18/20 passing, 2 failing**: - `virtual mouse absolue` — **SIGSEGV** (testLibinput.cpp:129), right after a libinput debounce press/release sequence. - `PS Joypad` — assertion failure on a motion/IMU sample (testUHID.cpp:321): expected `-28.595`, got `0.0`. - Both reproduce identically on the `feature/joycons` roadmap tip, so they predate and are independent of the open roadmap PRs. - Caveat: this was run in a minimal container without a full desktop/udev session, so I can't rule out an environment artifact for either failure — but that's exactly the point: there's currently no CI baseline to compare against, so nobody can tell from the repo alone whether these are real regressions or sandbox noise. **Suggestion:** add a CI workflow that builds with `-DBUILD_TESTING=ON -DBUILD_C_BINDINGS=ON` and runs `ctest`, mirroring what libvirtualhid already does. This is the single highest-leverage adoption item — it would have caught both issues above automatically, and would materially help the review bottleneck visible on #37/#40/#43 (a single reviewer currently has to manually verify each PR builds and passes). ## Other adoption suggestions, roughly by leverage 1. **CI for the existing Catch2 suite** (above). 2. **In-repo platform/quirks documentation**, modeled on libvirtualhid's `docs/platform-support.md` — the hard-won HID compatibility knowledge currently lives in PR descriptions, commit messages, and external blog posts rather than the repo. 3. **Capability-struct API** — already the direction of #40; no change needed, just flagging libvirtualhid as a working reference implementation of the same idea. 4. *(Lower priority)* a small diagnostic tool for manually creating/driving test devices, à la `virtualhid_control` — could have made the touchscreen MT-slot bug (#47) easier to catch by hand. Not proposing inputtino chase Windows/macOS/FreeBSD support — that's a different scope decision — just flagging that libvirtualhid exists, since it's built by Sunshine's own org for the same problem.
Author
Owner

@salty2011 commented on GitHub (Sep 26, 2026):

I've taken a quick look at this and there's a few things that your research doesn't show. Firstly, the Lizard Bites virtual hid has a cost associated with it when on Windows, though it is free for non Windows platforms. However, that doesn't preclude that in the future they would start charging for it for all platform and that would impact wolf.

<!-- gh-comment-id:5846044600 --> @salty2011 commented on GitHub (Sep 26, 2026): I've taken a quick look at this and there's a few things that your research doesn't show. Firstly, the Lizard Bites virtual hid has a cost associated with it when on Windows, though it is free for non Windows platforms. However, that doesn't preclude that in the future they would start charging for it for all platform and that would impact wolf.
Author
Owner

@JBailes commented on GitHub (Sep 26, 2026):

Based on Salty's feedback (Salty feedback? Heh), I'm closing this ticket. There's no action items for us within the current scope of the project. If you want to add something to CI, you are welcome to make a PR to do that.

<!-- gh-comment-id:5849733515 --> @JBailes commented on GitHub (Sep 26, 2026): Based on Salty's feedback (Salty feedback? Heh), I'm closing this ticket. There's no action items for us within the current scope of the project. If you want to add something to CI, you are welcome to make a PR to do that.
Author
Owner

@kmreisi commented on GitHub (Sep 27, 2026):

Thanks both — to close the loop on motivation: this wasn't a proposal to push inputtino toward Windows/FreeBSD/macOS, and there's no intent behind it to move wolf/Sunshine away from inputtino. The actual question I was chasing was narrower and license-clean: on Linux, both projects are MIT, so it's a fair apples-to-apples comparison, and I wanted to know whether libvirtualhid's Linux path builds on inputtino's work, and if so what it added on top. No specific goal beyond understanding that.

Short answer: yes, credited. libvirtualhid's src/core/profiles.cpp has, verbatim:

// DualSense USB descriptor data is derived from the public reverse-engineered descriptor used by inputtino.
// DualSense Bluetooth descriptor data is derived from the public reverse-engineered descriptor used by inputtino.

and docs/platform-support.md: "DualSense motion packing ... applies the same raw sensor calibration used by Inputtino." So the DualSense HID descriptor bytes and IMU calibration constants that inputtino's contributors worked out are credited by name as the source.

Also found libvirtualhid's own README has a self-authored comparison table against inputtino (## 🔁 Alternatives) I'd missed the first pass. On the Linux side, the delta it claims is mostly breadth of descriptor-defined (uhid) gamepad profiles — Generic HID, Xbox 360, Xbox Series, DualShock 4 — where inputtino today only has uhid-descriptor profiles for Xbox One, Switch(Pro), and PS5/DualSense. Worth noting that's libvirtualhid's own framing, not an independent check.

No action needed here — just answering the "why" and the borrowing question for the record.

<!-- gh-comment-id:5853926401 --> @kmreisi commented on GitHub (Sep 27, 2026): Thanks both — to close the loop on motivation: this wasn't a proposal to push inputtino toward Windows/FreeBSD/macOS, and there's no intent behind it to move wolf/Sunshine away from inputtino. The actual question I was chasing was narrower and license-clean: on **Linux**, both projects are MIT, so it's a fair apples-to-apples comparison, and I wanted to know whether libvirtualhid's Linux path builds on inputtino's work, and if so what it added on top. No specific goal beyond understanding that. Short answer: yes, credited. `libvirtualhid`'s `src/core/profiles.cpp` has, verbatim: ``` // DualSense USB descriptor data is derived from the public reverse-engineered descriptor used by inputtino. // DualSense Bluetooth descriptor data is derived from the public reverse-engineered descriptor used by inputtino. ``` and `docs/platform-support.md`: *"DualSense motion packing ... applies the same raw sensor calibration used by Inputtino."* So the DualSense HID descriptor bytes and IMU calibration constants that inputtino's contributors worked out are credited by name as the source. Also found libvirtualhid's own README has a self-authored comparison table against inputtino (`## 🔁 Alternatives`) I'd missed the first pass. On the Linux side, the delta it claims is mostly breadth of *descriptor-defined* (uhid) gamepad profiles — Generic HID, Xbox 360, Xbox Series, DualShock 4 — where inputtino today only has uhid-descriptor profiles for Xbox One, Switch(Pro), and PS5/DualSense. Worth noting that's libvirtualhid's own framing, not an independent check. No action needed here — just answering the "why" and the borrowing question for the record.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
games-on-whales/inputtino#15
No description provided.