- C 77.6%
- Shell 22.4%
|
All checks were successful
CI / build (push) Successful in 2s
No CI before this. evjoyd is in the input path for every splitux seat — the CUSE daemon that synthesizes /dev/input/js* from the evdev pads, including the splitux-together virtual pads it allowlists by name — so a build break here is a launch that comes up with no working controller. Builds with the exact command lines validate.sh uses, so CI and the on-hardware script cannot drift into compiling different things. -Wextra runs non-blocking: these sources have never been compiled under it and reporting that debt is more useful than gating on it today. validate.sh is deliberately not run here. It modprobes cuse, creates a uinput pad and reads the synthesized js node, so it needs root and a kernel with cuse.ko. CI proves this builds; validate.sh proves it works, and only hardware can do that. |
||
|---|---|---|
| .github/workflows | ||
| .gitignore | ||
| evjoyd-supervisor | ||
| evjoyd.c | ||
| jsprobe.c | ||
| mkpad.c | ||
| openlog.c | ||
| README.md | ||
| validate.sh | ||
evjoyd — userspace joydev replacement
A CUSE daemon that translates an evdev device (/dev/input/eventN) into a legacy
joystick node (/dev/input/jsN), faithfully reproducing joydev's axis/button
map, value correction, and js_event/JSIOC* protocol — so consumers that only
speak the old /dev/input/js* API see the controller.
Why
This host removed/blacklisted the in-kernel joydev (it mis-enumerated four
identical 8BitDo pads as one controller). That left no js* nodes at all, which
breaks path-scanning js* consumers — notably the Chromium Gamepad API
(browsers read /dev/input/js* directly). evjoyd restores correct, 1:1-unique
js* nodes without bringing joydev back.
Scope note: udev-based discovery (SDL2, Unity's modern path) filters
SUBSYSTEM=="input", and CUSE nodes are SUBSYSTEM=="cuse", so those consumers
never see an evjoyd node regardless of tagging. evjoyd serves the path-scanning
consumers (Chromium); evdev-native games are unaffected. For Unity/InControl
games that crash on virtual pads, see the sibling project xpad-gadget.
Design
One process owns one js node (crash isolation, no shared state). A supervisor
spawns one per matched controller and assigns unique js numbers. joydev itself
stays unloaded — this is its replacement, not a companion.
Build
gcc -O2 -Wall evjoyd.c -o evjoyd $(pkg-config --cflags --libs fuse3)
gcc -O2 -Wall jsprobe.c -o jsprobe # inspect a js node (debug)
gcc -O2 -Wall mkpad.c -o mkpad # synthesize a test uinput pad
gcc -O2 -Wall -shared -fPIC openlog.c -o openlog.so # open-trace shim (debug)
Requires /dev/cuse (CONFIG_CUSE) and libfuse3.
Run
sudo ./evjoyd --evdev /dev/input/event8 --js 0 [--name "..."] [-f]
# or let the supervisor match an allowlist and spawn one per controller:
./evjoyd-supervisor
validate.sh smoke-tests a node against the joydev protocol.
Files
evjoyd.c— the CUSE daemon (one evdev → one js node).evjoyd-supervisor— spawns and assigns one evjoyd per allowlisted controller.jsprobe.c,mkpad.c,openlog.c— debugging helpers.validate.sh— protocol smoke test.