使用uinput驱动程序创建虚拟多点触控设备

时间:2013-08-31 05:10:20

标签: java android java-native-interface linux-device-driver

我尝试在没有触摸屏的Android设备上注入事件。我正在使用用户空间输入设备(uinput)这样做但它不起作用。

我正在使用此代码:

fd_virtual_dev = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
if (fd_virtual_dev < 0)
    return die("error: open");

if (ioctl(fd_virtual_dev, UI_SET_EVBIT, EV_ABS) < 0)
    return die("error: ioctl ev_abs");
if (ioctl(fd_virtual_dev, UI_SET_EVBIT, EV_SYN) < 0)
    return die("error: ioctl ev_syn");
if (ioctl(fd_virtual_dev,UI_SET_ABSBIT,ABS_MT_TOUCH_M AJOR) < 0)
    return die("error: ioctl ABS_MT_TOUCH_MAJOR");
if (ioctl(fd_virtual_dev,UI_SET_ABSBIT,ABS_MT_WIDTH_M AJOR) < 0)
    return die("error: ioctl ABS_MT_TOUCH_MAJOR");
if (ioctl(fd_virtual_dev,UI_SET_ABSBIT,ABS_MT_POSITIO N_X) < 0)
    return die("error: ioctl ABS_MT_POSITION_X");
if (ioctl(fd_virtual_dev,UI_SET_ABSBIT,ABS_MT_POSITIO N_Y) < 0)
    return die("error: ioctl ABS_MT_POSITION_Y");
if (ioctl(fd_virtual_dev,UI_SET_ABSBIT,ABS_MT_TRACKIN G_ID) < 0)
    return die("error: ioctl ABS_MT_TRACKING_ID");
if (ioctl(fd_virtual_dev,UI_SET_ABSBIT,ABS_MT_SLOT) < 0)
    return die("error: ioctl");
if (ioctl(fd_virtual_dev,UI_SET_ABSBIT,ABS_MT_PRESSUR E) < 0)
    return die("error: ioctl ABS_MT_PRESSURE");

memset(&uidev, 0, sizeof(uidev));
snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "uinput-device");
uidev.id.bustype = BUS_VIRTUAL;
uidev.id.vendor = 0x0;
uidev.id.product = 0x0;
uidev.id.version = 0;    
uidev.absmax[ABS_MT_TOUCH_MAJOR] = 64;
uidev.absmax[ABS_MT_WIDTH_MAJOR] = 64;
uidev.absmax[ABS_MT_POSITION_X] = 1024;
uidev.absmax[ABS_MT_POSITION_Y] = 800;
uidev.absmax[ABS_MT_TRACKING_ID] = 65535;
uidev.absmax[ABS_MT_SLOT] = 9;
uidev.absmax[ABS_MT_PRESSURE] = 64;

现在,如果我尝试发送多点触控协议B事件,我可以在屏幕上看到一个小圆圈在pseduorandom点

我也尝试使用protocoll A和触摸屏手机,结果相同 阿方索

2 个答案:

答案 0 :(得分:2)

如果未在头文件'uinput.h'中定义UI_SET_PROPBIT,请添加以下行:

#define UI_SET_PROPBIT    _IOW(UINPUT_IOCTL_BASE, 110, int)

行之前:

ioctl(uinput_fd, UI_SET_PROPBIT, INPUT_PROP_DIRECT)

我在Nexus7上测试过它。触摸事件运行良好,但它不能应用于Android系统虚拟按钮(BACK,HOME和RECENT),这是一个不同的问题。

答案 1 :(得分:1)

尝试添加以下ioctl调用:

ioctl(dev_file, UI_SET_PROPBIT, INPUT_PROP_DIRECT)

如果这不起作用,您需要在/system/usr/idc下为您指定的产品和供应商ID添加IDC文件(如here所述)。在您的情况下,它将是/system/usr/idc/Vendor_0000_Product_0000.idc,但考虑使用唯一的产品/供应商值。

IDC文件应指定设备是触摸屏: touch.deviceType = touchScreen

如果没有IDC文件,设备很可能被识别为鼠标,从而产生小圆圈。如果您要构建自定义Android图像,则可以将IDC文件放在/out/target/product/<product>/system/usr/idc下的Android源代码树中。否则,请尝试通过“adb shell”上传IDC。