1. 打开UInput Device: 应用程序: dev 为 UInput Node名:通常为/dev/uinput。 open(dev, O_WRONLY | O_NDELAY);
此时,在Kernel 层,对应的动作为: static int uinput_open(struct inode *inode, struct file *file) 参数inode对应的是 主设备为10,子设备为223的node(即位用户态的dev) 参数file对应打开的文件。 动作: 创建了newdev-- uinput_device结构。
newdev->state = UIST_NEW_DEVICE; file->private_data = newdev;
2. 设置UInput Device: ioctl(fd, UI_SET_EVBIT, EV_KEY); 此时,在Kernel 层,对应的动作为: static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 参数file对应打开的文件。 参数cmd 对应用户态ioctl参数2。UI_SET_EVBIT 参数arg对应用户态ioctl参数3。EV_KEY 动作: 2.1 将driver参数传递过来。 udev = file->private_data;
udev->dev 如果udev->dev为空,则使用 uinput_allocate_device(udev);申请input_dev结构
具体到CMD=UI_SET_EVBIT uinput_set_bit(arg, evbit, EV_MAX); 首先判断newdev->state为UIST_CREATED,则返回错误码。 这就说明:设置bit,需要在create input device 之前。 具体动作为:udev->dev->evbit 设为EV_KEY.
注意:此处input device的evbit: 一个是evbit.表示设备所支持的动作.
#define EV_KEY
3.继续设置 Device: ret = ioctl(fd, UI_SET_RELBIT, REL_X); //鼠标 ret = ioctl(fd, UI_SET_RELBIT, REL_Y);
ret = ioctl(fd, UI_SET_EVBIT, EV_ABS); 同上。设置了Keybit等。 这里就是设置了Input Device关心或者说会产生的消息。
4. 写入设备: struct uinput_user_dev uinput;
uinput.id.version = 4; ret = write(fd, &uinput, sizeof(uinput)); 此时,在Kernel 层,对应的动作为: 此时Device status为UIST_NEW_DEVICE 并将udev->dev 这个input device 具体化。初始化该input_dev。 之后,改变状态: udev->state = UIST_SETUP_COMPLETE;
5.创建Input Device: 注意,此处是创建了Input Device。而不是UInput Device。 ioctl(fd, UI_DEV_CREATE);
input_register_device(udev->dev); //向子系统注册该设备,之后中断时input_event()向子系统报告事件 udev->state = UIST_CREATED;
6. 向Input Device发送Event:
struct input_event event = {0};
static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) 因为此时state为UIST_CREATED input_event(udev->dev, ev.type, ev.code, ev.value); 发送event.
总结: 使用UInput的步骤为: 1. 打开设备。 2. 使用ioctl() 配置设备。 3. 使用write() 将input device信息设置好。 4. 使用ioctl(UI_DEV_CREATE)创建Input Device。(即使用write设置的) 5. 再使用write() 写入event.
UInput添加的Input Device在/proc的反应: #cat /proc/bus/input/device
I: Bus=0003 Vendor=0000 Product=0000 Version=0004 解释如下:
Bus=0003 Vendor=0000 Product=0000 Version=0004
uinp.id.version = 4;
struct input_id {
EV=f
|
|