/* * 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 #include #include #include #include #include #include #include #include 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; }