clinuxinputkernelsubsystem

Virtual mouse and eventX


I am playing with uinput by creating a virtual keyboard/mouse. I have no problem to set up the virtual device.

int                    fd;
struct uinput_user_dev uidev;
struct input_event     ev;
int                    dx, dy;
int                    i;

fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
if(fd < 0)
    die("error: open");


if(ioctl(fd, UI_SET_EVBIT, EV_KEY) < 0)
    die("error: ioctl");
if(ioctl(fd, UI_SET_KEYBIT, BTN_LEFT) < 0)
    die("error: ioctl");

if(ioctl(fd, UI_SET_EVBIT, EV_REL) < 0)
    die("error: ioctl");
if(ioctl(fd, UI_SET_RELBIT, REL_X) < 0)
    die("error: ioctl");
if(ioctl(fd, UI_SET_RELBIT, REL_Y) < 0)
    die("error: ioctl");

memset(&uidev, 0, sizeof(uidev));
snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "test");
uidev.id.bustype = BUS_USB;
uidev.id.vendor  = 0x1;
uidev.id.product = 0x1;
uidev.id.version = 1;

write(fd, &uidev, sizeof(uidev))
ioctl(fd, UI_DEV_CREATE)

And I can write events in /dev/uinput. It is working like a charm, the mouse is moving or the keyboard is working.

However I don't understand where I can read the inputed events. I can read on /dev/input/mice the mouse and see the data of the virtual mouse. but /dev/input/mice is for all mice...

In which /dev/input/eventX should I read? I've tried to read all of them but there is nothing.

I read event0 for my usb mouse, event1 for the keyboard... but where can I read about my virtual device?


Solution

  • Typically standard udev rules are used to generate symlinks based on the name; for example, in Debian-based systems, as /dev/input/by-id/*-event-* to the corresponding input event device. Because these are based on the device properties, they are stable: you can just use the symlink in there to access your virtual device.

    If you cannot find the symlink, you can search for the input event device.

    Each Linux input event device is described by a pseudodirectory /sys/class/input/event*, i.e. /sys/class/input/event0, corresponding to /dev/input/event0 or /dev/input/event/0 (whichever exists).

    The pseudofile /sys/class/input/event*/device/name contains the device name. The product, vendor, version, and bus type are available as four-character hexadecimal strings in pseudofiles /sys/class/input/event*/device/id/product, /sys/class/input/event*/device/id/vendor, /sys/class/input/event*/device/id/version, and /sys/class/input/event*/device/id/bustype, respectively. You can read these files as normal, except that if you stat() or fstat() them, their size is zero. Instead, read the contents of these files to a small buffer (length 128, or up to 126 characters + "\n\0", should suffice for the name; 8 (4 + "\n\0") should suffice for the files under id/), and compare it to the desired device name, or parse the hexadecimal numbers.