【问题标题】:Touch event simulation using uinput in a linux based hmi screen is not working?在基于 linux 的 hmi 屏幕中使用 uinput 模拟触摸事件不起作用?
【发布时间】:2016-04-27 16:28:23
【问题描述】:

下面是我尝试将触摸事件从用户空间发送到我们的 hmi 的代码。明确检查所有 ioctl 调用和写入是否成功,但未注入事件。供应商 ID 和产品 ID 设备名称输入不正确。不确定它是否与输出相关。 (事件注入的三种方式都已经一一试用过了)。它需要供应商 id 产品 id 和设备名称,然后我们将从基于 Linux 的嵌入式系统中的何处获取这些数据。

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

void injectEvent(int, int, int, int);

int main()
{
    struct uinput_user_dev dev;
    int i;
    int err;
    int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
    if(fd < 0) {
        //perror("Failed to open: /dev/uinput");
        printf("Failed to open: /dev/uinput\n");
        return fd;
    }

    err = ioctl(fd, UI_SET_EVBIT, EV_KEY);
    if (err)
        goto err;

    err = ioctl(fd, UI_SET_EVBIT, EV_ABS);
    if (err)
        goto err;

    err = ioctl(fd, UI_SET_KEYBIT, BTN_TOUCH);
    if (err)
        goto err;

    err = ioctl(fd, UI_SET_ABSBIT, ABS_MT_SLOT);
    if (err)
        goto err;

    memset(&dev, 0, sizeof(dev));
    snprintf(dev.name, sizeof(dev.name), "Test device");
    printf("devname = %s\n",dev.name);
    dev.id.bustype = BUS_SPI;

    /* 10 touch inputs */
    dev.absmax[ABS_MT_SLOT] = 10;

    dev.absmax[ABS_X] = 4096;
    dev.absmin[ABS_X] = 0;

    dev.absmax[ABS_Y] = 4096;
    dev.absmin[ABS_Y] = 0;

    dev.absmax[ABS_PRESSURE] = 0xff;
    dev.absmin[ABS_PRESSURE] = 0;

    dev.absmax[ABS_MT_TOUCH_MAJOR] = 0xff;
    dev.absmin[ABS_MT_TOUCH_MAJOR] = 0;

    dev.absmax[ABS_MT_POSITION_X] = 4096;
    dev.absmin[ABS_MT_POSITION_X] = 0;

    dev.absmax[ABS_MT_POSITION_Y] = 4096;
    dev.absmin[ABS_MT_POSITION_Y] = 0;

    dev.absmax[ABS_MT_PRESSURE] = 4096;
    dev.absmin[ABS_MT_PRESSURE] = 0;

    err = write(fd, &dev, sizeof(dev));
    if (err < 0)
        goto err;

    err = ioctl(fd, UI_DEV_CREATE);
    if (err < 0)
        goto err;

    /* Event should be injected here.... */

    /********************First Method***********************/
#if 1
    struct input_event ev[2];

    memset(ev, 0, sizeof(ev));

    ev[0].type = EV_ABS;
    ev[0].code = ABS_X;
    ev[0].value = 1001;
    ev[1].type = EV_ABS;
    ev[1].code = ABS_Y;
    ev[1].value = 2002;

    if(write(fd, &ev, sizeof(ev)) < 0)
        printf("Error::event injection failed\n");

#endif

    /********************Second Method***********************/
#if 0
    injectEvent( fd, EV_ABS, ABS_MT_TRACKING_ID, 0  );
    injectEvent( fd, EV_ABS, ABS_MT_POSITION_X, 1001  );
    injectEvent( fd, EV_ABS, ABS_MT_POSITION_Y, 2002  );
    injectEvent( fd, EV_ABS, ABS_MT_TOUCH_MAJOR,    111 );
    injectEvent( fd, EV_ABS, ABS_MT_PRESSURE,   3003 );
    injectEvent( fd, EV_SYN, SYN_MT_REPORT, 0   );
    injectEvent( fd, EV_SYN, SYN_REPORT, 0  );
    injectEvent( fd, EV_SYN, SYN_MT_REPORT, 0   );
    injectEvent( fd, EV_SYN, SYN_REPORT, 0  );

    void injectEvent(int fd_ev,int type, int code, int value)
    {
        printf("(%s)==>> (%d,%d,%d,%d)\n",__func__, fd_ev, type, code, value);

        struct uinput_event event;
        int len;

        if (fd_ev <= fileno(stderr))
            return;

        memset(&event, 0, sizeof(event));
        event.type = type;
        event.code = code;
        event.value = value;

        len = write( fd_ev, &event, sizeof(event) );

        printf("(%s) done:%d\n",__func__,len);
    }
#endif

    /********************Third Method***********************/
#if 0
    struct uinput_event event;
    for (int i=0; i<30; i++)
    {
        memset(&event, 0, sizeof(event));

        event.type=EV_ABS;
        event.code=ABS_X;
        event.value=1005;

        if(write(fd, &event, sizeof(event)) < 0)
            printf("Error::event injection failed\n");

        sleep (5);
    }
#endif

    sleep (180);
    /* start cleanup ... */
    err = ioctl(fd, UI_DEV_DESTROY);
    if (err < 0)
        goto err;

    close(fd);
    return 0;
err:
    //perror("Failed to initialise");
    printf("(%s) Failed to initialise\n",__func__);
    close(fd);
    return err;
}

【问题讨论】:

    标签: c linux embedded uinput


    【解决方案1】:

    我不知道这是否是你的解决方案,但是ABS_X和ABS_Y不能与ABS_MT_POSITION_X和*_Y一起设置,它们不能同时存在,你必须激活一个或另一个。您可以在 linux 中使用“xinput list-props + 设备号”进行检查。希望对你有所帮助;)

    【讨论】:

      猜你喜欢
      • 2012-06-17
      • 1970-01-01
      • 2018-09-05
      • 2016-07-03
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 2021-10-27
      • 1970-01-01
      相关资源
      最近更新 更多