加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

使用uinput模拟Linux中的绝对鼠标移动

发布时间:2020-12-14 02:20:33 所属栏目:Linux 来源:网络整理
导读:我正在尝试使用绝对坐标移动光标.这是代码: #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#include signal.h#define die(str,args...) do { perr
我正在尝试使用绝对坐标移动光标.这是代码:
#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>
#include <signal.h>

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

    int                    fd;

static void signal_handler(int signo)
{
    printf("nCaught SIGINTn");
        if(ioctl(fd,UI_DEV_DESTROY) < 0)
           die("error: cannot destroy uinput devicen");
    else printf("Destroyed uinput_user_devnn");
    close(fd);
    exit(EXIT_SUCCESS);
}

int
main(void)
{

    struct uinput_user_dev uidev;
    struct input_event     ev;
    int                    x,y;
    int                    i;

    if(signal(SIGINT,signal_handler)==SIG_ERR)
    {
    printf("error registering signal handlern");
    exit(EXIT_FAILURE);

    }

    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_MOUSE) < 0)
    //    die("error: ioctl");
    if(ioctl(fd,BTN_LEFT) < 0)
        die("error: ioctl");
    if(ioctl(fd,BTN_RIGHT) < 0)
        die("error: ioctl");

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

    if(ioctl(fd,EV_ABS) < 0)       
        die("error: ioctl");
    if(ioctl(fd,UI_SET_ABSBIT,ABS_X) < 0)
        die("error: ioctl");
    if(ioctl(fd,ABS_Y) < 0)
        die("error: ioctl");

    memset(&uidev,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;

    uidev.absmin[ABS_X]=0;
    uidev.absmax[ABS_X]=1023;
    uidev.absfuzz[ABS_X]=0;
    uidev.absflat[ABS_X ]=0;
    uidev.absmin[ABS_Y]=0;
    uidev.absmax[ABS_Y]=767;
    uidev.absfuzz[ABS_Y]=0;
    uidev.absflat[ABS_Y ]=0;

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

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

    sleep(2);
    while(1)
    {

       printf("nEnter the absoulte x(0-1023) and y(0-767) co-ordinates:");
           scanf("%d %d",&x,&y);       
           memset(&ev,sizeof(struct input_event));
       gettimeofday(&ev.time,NULL);
           ev.type = EV_ABS;
           ev.code = ABS_X;
           ev.value = x;
           if(write(fd,&ev,sizeof(struct input_event)) < 0)
                die("error: write1");

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

           memset(&ev,sizeof(struct input_event));
           ev.type = EV_ABS;
           ev.code = ABS_Y;
           ev.value = y;
           if(write(fd,sizeof(struct input_event)) < 0)
                die("error: write2");
           memset(&ev,sizeof(struct input_event)) < 0)
                die("error: write3");
       usleep(15000);
       printf("nWritten x:%d y:%d to uinput.Press CTRL-C to quit:",x,y);


    }

        if(ioctl(fd,UI_DEV_DESTROY) < 0)
           die("error: cannot destroy uinput devicen");
        close(fd);

    return 0;
}

该程序似乎通过uinput将我输入的绝对坐标发送到内核的输入核心.

在启用evbug之后,我在dmesg上验证了这一点.但我的鼠标指针不会在屏幕上移动.我想知道我搞砸了什么.

也许EV_ABS与光标无关?我想知道因为使用EV_REL移动光标可以正常工作,如this tutorial所述.

样品运行:

ravi@linux-lxaf:~/workspace/driver> sudo ./a.out 

Enter the absoulte x(0-1023) and y(0-767) co-ordinates:100 200

Written x:100 y:200 to uinput.Press CTRL-C to quit:
Enter the absoulte x(0-1023) and y(0-767) co-ordinates:10 765

Written x:10 y:765 to uinput.Press CTRL-C to quit:
Enter the absoulte x(0-1023) and y(0-767) co-ordinates:^C
Caught SIGINT
Destroyed uinput_user_dev

Dmesg输出:

ravi@linux-lxaf:~/workspace/driver> dmesg |grep input16
[ 4750.660420] input: uinput-sample as /devices/virtual/input/input16
[ 4750.660594] evbug.c: Connected device: input16 (uinput-sample at unknown)
[ 4761.389036] evbug.c: Event. Dev: input16,Type: 3,Code: 0,Value: 100
[ 4761.389047] evbug.c: Event. Dev: input16,Type: 0,Value: 0
[ 4761.389053] evbug.c: Event. Dev: input16,Code: 1,Value: 200
[ 4761.389058] evbug.c: Event. Dev: input16,Value: 0
[ 4776.893126] evbug.c: Event. Dev: input16,Value: 10
[ 4776.893138] evbug.c: Event. Dev: input16,Value: 0
[ 4776.893144] evbug.c: Event. Dev: input16,Value: 765
[ 4776.893148] evbug.c: Event. Dev: input16,Value: 0
[ 4778.729711] evbug.c: Event. Dev: input16,Value: 1
[ 4778.745506] evbug.c: Disconnected device: input16

解决方法

我刚刚发现输入内核将EV_ABS值作为绝对值传播到设备节点,如从/ dev / input / eventX中看到的那样(现在看起来很明显!).一直以来,控制光标的应用程序(X11? )当我给它绝对值时,期待相对鼠标移动,这可能会让它感到困惑!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读