linux uinput 分析。

linux uinput 本文以 2.6.22.7 的kernel 为基础。首先 uinput 是一个字符设备, 其次它还是一个 input 设备。另外它可以是一个鼠标或者键盘设备。从 init 部分说起吧。static const struct file_operations uinput_fops = { .owner = THIS_MODULE, .open = uinput_open, .release = uinput_release, .read = uinput_read, .write = uinput_write, .poll = uinput_poll, .unlocked_ioctl = uinput_ioctl,};static struct miscdevice uinput_misc = { .fops = &uinput_fops, .minor = UINPUT_MINOR, .name = UINPUT_NAME,};static int __init uinput_init(void){ return misc_register(&uinput_misc);}首先说说 miscdevice, 很方便的东西,对 device 做了简单的包装,当 misc_register 的时候就完成了 设备的 注册安装一类的东东, 不用自己再操心了。真是懒人的设计阿。所有的 misc 设备公用同一个主设备号,在 misc_init 中,static int __init misc_init(void){#ifdef CONFIG_PROC_FS struct proc_dir_entry *ent; ent = create_proc_entry("misc", 0, NULL); if (ent) ent->proc_fops = &misc_proc_fops;#endif misc_class = class_create(THIS_MODULE, "misc"); if (IS_ERR(misc_class)) return PTR_ERR(misc_class); if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) { printk("unable to get major %d for misc devices/n", MISC_MAJOR); class_destroy(misc_class); return -EIO; } return 0;}register_chrdev 接口真 BT ,__register_chrdev_region(major, 0, 256, name);直接占用了 0 到 255 的次设备号,注册 misc 类型设备的时候,直接从里面取就是了。而在 misc_open 通过设备节点把 file_operations 指向对应的设备驱动上去, 很良好的设计, 呵呵。有点类似其他总线的设计, 但是只有 device_list, 没有 driver_list, 当然也不需要。不在 misc 上浪费时间了。 接下来再到 uinput 中去。从uinput_open 说起吧, uinput_open 其实啥事情都没干。。做了一些简单的初始化工作。要创建一个 input 设备,我们在调用input_register_device 前需要设置 好input_dev的各种属性。而设置input_dev的属性在 uinput_setup_device 接口中, 但驱动怎么知道你想模拟什么设备呢?又需要通过 uinput_ioctl 设置先。 很糟糕的设计。 用户若是不知道这些流程,如何能使用这个模拟驱动?下面是一个使用 uinput 的用户态程序:int setup_uinput_device(char *device){ // Temporary variable int i=0; // Open the input device //uinp_fd = open("/dev/input/uinput", O_WRONLY | O_NDELAY); uinp_fd = open(device, O_WRONLY | O_NDELAY); if (uinp_fd == 0) { printf("Unable to open /dev/input/uinput/n"); return -1; } memset(&uinp,0,sizeof(uinp)); // Intialize the uInput device to NULL strncpy(uinp.name, "HID Keyboard Device", strlen("HID Keyboard Device")); uinp.id.version = 4; uinp.id.bustype = BUS_USB; uinp.id.product = 1; uinp.id.vendor = 1; // Setup the uinput device ioctl(uinp_fd, UI_SET_EVBIT, EV_KEY); ioctl(uinp_fd, UI_SET_EVBIT, EV_REL); ioctl(uinp_fd, UI_SET_RELBIT, REL_X); ioctl(uinp_fd, UI_SET_RELBIT, REL_Y); for (i=0; i < 256; i++) { ioctl(uinp_fd, UI_SET_KEYBIT, i); } ioctl(uinp_fd, UI_SET_KEYBIT, BTN_MOUSE); ioctl(uinp_fd, UI_SET_KEYBIT, BTN_TOUCH); ioctl(uinp_fd, UI_SET_KEYBIT, BTN_MOUSE); ioctl(uinp_fd, UI_SET_KEYBIT, BTN_LEFT); ioctl(uinp_fd, UI_SET_KEYBIT, BTN_MIDDLE); ioctl(uinp_fd, UI_SET_KEYBIT, BTN_RIGHT); ioctl(uinp_fd, UI_SET_KEYBIT, BTN_FORWARD); ioctl(uinp_fd, UI_SET_KEYBIT, BTN_BACK); write(uinp_fd, &uinp, sizeof(uinp)); if (ioctl(uinp_fd, UI_DEV_CREATE)) { printf("Unable to create UINPUT device."); return -1; } return 1;}很变态的流程, 先用 ioctl 设置参数(模拟鼠标,键盘), 再 write, 在第一次 write 的时候创建 inputdev,然后 ioctl 调用 UI_DEV_CREATE 向系统注册 . BT…………今天先写到这里拉。。

望着它们,我睡着了。今天已经过去——我生命中所有天中的一天,

linux uinput 分析。

相关文章:

你感兴趣的文章:

标签云: