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