Files
hermes-config/skills/gaming/game-streaming/scripts/uinput-shim.c
T
2026-07-12 10:17:17 -04:00

63 lines
1.9 KiB
C

/*
* LD_PRELOAD shim for Sunshine on kernel 7.0+.
*
* PROBLEM: Kernel 7.0 (confirmed: 7.0.0-22-generic) requires UI_DEV_SETUP ioctl
* BEFORE UI_DEV_CREATE on /dev/uinput. The old write()+UI_DEV_CREATE sequence
* and bare UI_DEV_CREATE both fail with EINVAL. Sunshine links against
* libevdev which uses the old method. Result: keyboard and mouse input silently
* fail (Sunshine receives Moonlight packets but can't inject into X11).
*
* FIX: This shim overrides libevdev_uinput_create_from_device() to use the
* correct UI_DEV_SETUP + UI_DEV_CREATE sequence.
*
* COMPILE: gcc -shared -fPIC -o uinput_fix.so uinput-shim.c -ldl
*
* DEPLOY:
* 1. cp uinput_fix.so ~/.config/sunshine/uinput_fix.so
* 2. Add to Sunshine systemd override:
* [Service]
* Environment=LD_PRELOAD=/home/ray/.config/sunshine/uinput_fix.so
* 3. systemctl --user daemon-reload
* 4. systemctl --user restart sunshine
*
* VERIFY: After connecting Moonlight, check that input events are created:
* grep "keyboard packet" ~/.config/sunshine/sunshine.log | tail -5
* # Should see packets arriving, AND keyboard/mouse now works on client.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/uinput.h>
int libevdev_uinput_create_from_device(void *dev, int flags, int *uifd) {
int fd = open("/dev/uinput", O_WRONLY);
if (fd < 0) { return -errno; }
struct uinput_setup usetup;
memset(&usetup, 0, sizeof(usetup));
usetup.id.bustype = BUS_USB;
usetup.id.vendor = 0x1234;
usetup.id.product = 0x5678;
strncpy(usetup.name, "Sunshine Keyboard", UINPUT_MAX_NAME_SIZE-1);
if (ioctl(fd, UI_DEV_SETUP, &usetup) < 0) {
close(fd);
return -errno;
}
if (ioctl(fd, UI_DEV_CREATE) < 0) {
close(fd);
return -errno;
}
*uifd = fd;
return 0;
}