c - 鼠标指针在输入子系统中移动后无法模拟 Click 事件

标签 c linux uinput

下面的代码非常简单,但我看不到客户端事件的发生。但是,我看到鼠标指针移动到给定的相对值。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/input.h>
#include <linux/uinput.h>

#define die(str, args...) do { \
        perror(str); \
        exit(EXIT_FAILURE); \
    } while(0)

int
main(void)
{
    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");

    if(ioctl(fd, UI_SET_KEYBIT, BTN_MOUSE) < 0)
        die("error: ioctl");

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

    if(write(fd, &uidev, sizeof(uidev)) < 0)
        die("error: write");

    if(ioctl(fd, UI_DEV_CREATE) < 0)
        die("error: ioctl");

    sleep(2);

    srand(time(NULL));


            memset(&ev, 0, sizeof(struct input_event));
            ev.type = EV_REL;
            ev.code = REL_X;
            ev.value = 10;
            if(write(fd, &ev, sizeof(struct input_event)) < 0)
                die("error: write");

            memset(&ev, 0, sizeof(struct input_event));
            ev.type = EV_REL;
            ev.code = REL_Y;
            ev.value = 60;
            if(write(fd, &ev, sizeof(struct input_event)) < 0)
                die("error: write");

            memset(&ev, 0, sizeof(struct input_event));
            ev.type = EV_SYN;
            ev.code = 0;
            ev.value = 0;
            if(write(fd, &ev, sizeof(struct input_event)) < 0)
                die("error: write");

            memset(&ev, 0, sizeof(struct input_event));
            ev.type = EV_KEY;
            ev.code = BTN_RIGHT;
            ev.value = 0;
            if(write(fd, &ev, sizeof(struct input_event)) < 0)
                die("error: write");

            usleep(15000);

    sleep(2);

    if(ioctl(fd, UI_DEV_DESTROY) < 0)
        die("error: ioctl");

    close(fd);

    return 0;
}

引用:

http://thiemonge.org/getting-started-with-uinput

在此链接中,有一个示例代码 uinput-sample.c 我已经使用过,并稍微修改为具有点击事件而不是移动 20 次绝对值。

我错过了什么?

最佳答案

好的,在设置 X Y 位置的绝对值之前,我通过引入以下代码使其工作。

 memset(&ev, 0, sizeof(struct input_event));
 gettimeofday(&ev.time,0);
 ev.type = EV_KEY;
 ev.code = BTN_LEFT;
 ev.value = 1;
 if(write(fd, &ev, sizeof(struct input_event)) < 0)
     die("error: write");

因此,流程将是。

1) set EV_KEY(BTN_LEFT)
2) SET EV_ABS(ABS_X)
3) SET EV_ABS(ABS_Y)
4) SET EV_SYNC(0) 

关于c - 鼠标指针在输入子系统中移动后无法模拟 Click 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40608928/

相关文章:

c++ - 如何在U盘中制作安装程序?

不幸的是,当控制台关闭时,Linux 正在运行的程序会再次显示

c - 如何在 C 中执行 IP 遍历

c - 在 linux 中使用 C 和 uinput 库模拟击键

linux - Uinput 和树莓派

android - android ndk 中的错误类型转换

C、链表: show every int

c++ - 在 C/C++ 中实现 RSA 的开源代码(使用库或自己编写)

c - 将 Linux IOMMU API 与用户空间地址一起使用

linux - "Syntax error near unexpected token ` crontab '"当尝试在一行中添加 cron 作业作为 sudo 时