在Android上使用/dev/uinput时,单击错误的位置

在Android上使用/dev/uinput时,单击错误的位置,android,Android,我的项目的功能看起来像。但有点不同。 我有一个在Android上运行的服务器程序和一个在PC上运行的客户端。我想通过在PC上操作来控制手机 这个项目的大部分工作已经完成,但在控制步骤中发生了一点错误。也许你知道我们一直 用于实现对操作命令的响应目标 从PC客户端。我在编写这部分程序时参考了其他人。另外,我是Android新手,所以有些事情超出了我的控制范围 好的,我会告诉你下面的细节。 例如,当您单击鼠标或按下PC上的某些键时,服务器通过某些协议(如)接收此命令 ,并获取有关命令事件的相关信息,

我的项目的功能看起来像。但有点不同。 我有一个在Android上运行的服务器程序和一个在PC上运行的客户端。我想通过在PC上操作来控制手机

这个项目的大部分工作已经完成,但在控制步骤中发生了一点错误。也许你知道我们一直 用于实现对操作命令的响应目标 从PC客户端。我在编写这部分程序时参考了其他人。另外,我是Android新手,所以有些事情超出了我的控制范围

好的,我会告诉你下面的细节。 例如,当您单击鼠标或按下PC上的某些键时,服务器通过某些协议(如)接收此命令 ,并获取有关命令事件的相关信息,例如按钮掩码(可以决定向左或向右) 鼠标右键单击)或位置(X、Y坐标)。按照以下三个步骤向Android发送命令

首先,通过android中“/dev/uinput”的开放设备创建输入设备。 其次,向输入子系统注入相关事件。 然后,将事件写入虚拟输入子系统

简化代码:

//First ADN SECOND STEPS:
    int initial()
    {
        int inputfd = -1;

        uinput_fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);

        /* Set device to handle following types of events: */

      /* Key and button repetition events */
        if (ioctl(uinput_fd, UI_SET_EVBIT, EV_REP) == -1)
            return -1;

        /* Absolute pointer motions */
        if (ioctl(uinput_fd, UI_SET_EVBIT, EV_ABS) == -1)
            return -1;
        /* Configure device to handle absolute x and y axis. */
        if (ioctl(uinput_fd, UI_SET_ABSBIT, ABS_X) == -1)
            goto err;
        if (ioctl(uinput_fd, UI_SET_ABSBIT, ABS_Y) == -1)
            return -1;

        /* Synchronization events, this is probably set implicitely too. */
        if (ioctl(uinput_fd, UI_SET_EVBIT, EV_SYN) == -1)
            return -1;


        struct uinput_user_dev user_dev;
        /* Set device-specific information. */
        memset(&user_dev, 0, sizeof(user_dev));
        strncpy(user_dev.name, device_name, UINPUT_MAX_NAME_SIZE);
        user_dev.id.bustype = BUS_USB;
        user_dev.id.vendor = 1;
        user_dev.id.product = 1;
        user_dev.id.version = 1;

        //minor tweak to support ABSolute events
        user_dev.absmin[ABS_X] = 0;
        user_dev.absmax[ABS_X] = 799;
        user_dev.absfuzz[ABS_X] = 0;
        user_dev.absflat[ABS_X] = 0;

        user_dev.absmin[ABS_Y] = 0;
        user_dev.absmax[ABS_Y] = 479;
        user_dev.absfuzz[ABS_Y] = 0;
        user_dev.absflat[ABS_Y] = 0;

        if (write(uinput_fd, &user_dev, sizeof(user_dev)) != sizeof(user_dev))
            return -1;

        if (ioctl(uinput_fd, UI_DEV_CREATE) == -1)
            return -1;
    }

//THREE STEP:
    //call by ptrEvent
    int suinput_write(int uinput_fd, uint16_t type, uint16_t code, int32_t value)
    {
        struct input_event event, nullevent;
        memset(&event, 0, sizeof(event));
        gettimeofday(&event.time, 0); /* This should not be able to fail ever.. */
        event.type = type;
        event.code = code;
        event.value = value;
        if (write(uinput_fd, &event, sizeof(event)) != sizeof(event))
            return -1;

        return 0;
    }
    //begin to deal with event
    void ptrEvent(int buttonMask, int x, int y, rfbClientPtr cl)
    {

        static int leftClicked=0;

        if ( inputfd == -1 )
            return;

        if (buttonMask & 1)
        { //left btn clicked
            leftClicked=1;

            suinput_write(inputfd, EV_ABS, ABS_X, x);
            suinput_write(inputfd, EV_ABS, ABS_Y, y);
            suinput_write(inputfd,EV_KEY,BTN_TOUCH,1);
            suinput_write(inputfd, EV_SYN, SYN_REPORT, 0);
        }
        else if (leftClicked)
        { //left btn released
            leftClicked=0;
            suinput_write(inputfd, EV_ABS, ABS_X, x);
            suinput_write(inputfd, EV_ABS, ABS_Y, y);
            suinput_write(inputfd,EV_KEY,BTN_TOUCH,0);
            suinput_write(inputfd, EV_SYN, SYN_REPORT, 0);
        }
    }
Android设备的分辨率为800*480。客户端图片也有相同的大小。我调试了上面的代码,发现 服务器从事件消息接收正确的位置。在ptrEvent函数中,X和Y正好对应于实数 点击位置出现在PC上。但从Android上显示的实际按下位置来看,有一个不同的位置。如你所见, 我将Android虚拟输入设备的最大绝对范围设置为与实际分辨率相同,因此客户端和服务器之间显然没有偏差
坐标为什么会发生这种情况?

对应于电脑中出现的实际点击位置。
。你认为真正的点击位置是什么?是根据照片的一角画的吗?以与其决议相同的单位?所以这张图片是800*480,位置是400240你指中间吗?@greenapps是的,我在“ptrEvent”功能中打印出x和y。我不确定这是一个非常敏锐的坐标,但从大致位置看,它是正确的。例如,我点击图片三次,然后点击左上角、右上角和右下角,打印出(10,20)、(760,20)、(760754)。从中我们可以看出,该坐标系以左上角为参考,相对于800*400的实际分辨率可能是正确的。所以如果我在中间点击,它会得到(400240)。与分辨率相同的单位是什么意思?
与分辨率相同的单位
。如果分辨率为800*480的图片被缩放为600*360。如果你说“我点击了400280位置,那你是什么意思?但我还是不明白你的问题。你发布了很多代码来传递一些值。但转移是否存在问题?计算一些偏移量和相应的坐标不是更重要吗?