2

我一直在尝试使用 uinput 内核模块将鼠标点击快速连续发送到其他程序。

如果点击之间的延迟为25 毫秒或更长,则此方法可以正常工作,但如果延迟更低,则会中断。当它中断时,我可以看到带有evtest但不带有的事件xinput。只有第一个事件似乎正常工作。(我想后面的事件一定是在这两者之间丢失了?也许我错过了一个限制?)

我做了一个重现这种行为的小例子。(大部分来自 内核文档

#include <linux/uinput.h>
#include <unistd.h>
#include <memory.h>
#include <fcntl.h>

#define TIME_BETWEEN_CLICKS (25000) // in µs

void emit(int fd, int type, int code, int val)
{
    struct input_event ie;
    ie.type = type;
    ie.code = code;
    ie.value = val;
    ie.time.tv_sec = 0;
    ie.time.tv_usec = 0;
    write(fd, &ie, sizeof(ie));
}

int main(void)
{
    struct uinput_setup usetup;
    int i = 50;
    int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);

    ioctl(fd, UI_SET_EVBIT, EV_KEY);
    ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);

    memset(&usetup, 0, sizeof(usetup));
    usetup.id.bustype = BUS_USB;
    usetup.id.vendor = 0x1234; /* sample vendor */
    usetup.id.product = 0x5678; /* sample product */
    strcpy(usetup.name, "Example device");

    ioctl(fd, UI_DEV_SETUP, &usetup);
    ioctl(fd, UI_DEV_CREATE);

    sleep(2);

    while (i--) {
        emit(fd, EV_KEY, BTN_LEFT, 1);
        emit(fd, EV_SYN, SYN_REPORT, 0);
        emit(fd, EV_KEY, BTN_LEFT, 0);
        emit(fd, EV_SYN, SYN_REPORT, 0);
        usleep(TIME_BETWEEN_CLICKS);
    }
    sleep(1);

    ioctl(fd, UI_DEV_DESTROY);
    close(fd);

    return 0;
}
4

0 回答 0