|
1. 打開UInput Device: 應(yīng)用程序: dev 為 UInput Node名:通常為/dev/uinput。 open(dev, O_WRONLY | O_NDELAY);
此時(shí),在Kernel 層,對(duì)應(yīng)的動(dòng)作為: static int uinput_open(struct inode *inode, struct file *file) 參數(shù)inode對(duì)應(yīng)的是 主設(shè)備為10,子設(shè)備為223的node(即位用戶態(tài)的dev) 參數(shù)file對(duì)應(yīng)打開的文件。 動(dòng)作: 創(chuàng)建了newdev-- uinput_device結(jié)構(gòu)。
newdev->state = UIST_NEW_DEVICE; file->private_data = newdev;
2. 設(shè)置UInput Device: ioctl(fd, UI_SET_EVBIT, EV_KEY); 此時(shí),在Kernel 層,對(duì)應(yīng)的動(dòng)作為: static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 參數(shù)file對(duì)應(yīng)打開的文件。 參數(shù)cmd 對(duì)應(yīng)用戶態(tài)ioctl參數(shù)2。UI_SET_EVBIT 參數(shù)arg對(duì)應(yīng)用戶態(tài)ioctl參數(shù)3。EV_KEY 動(dòng)作: 2.1 將driver參數(shù)傳遞過來。 udev = file->private_data;
udev->dev 如果udev->dev為空,則使用 uinput_allocate_device(udev);申請(qǐng)input_dev結(jié)構(gòu)
具體到CMD=UI_SET_EVBIT uinput_set_bit(arg, evbit, EV_MAX); 首先判斷newdev->state為UIST_CREATED,則返回錯(cuò)誤碼。 這就說明:設(shè)置bit,需要在create input device 之前。 具體動(dòng)作為:udev->dev->evbit 設(shè)為EV_KEY.
注意:此處input device的evbit: 一個(gè)是evbit.表示設(shè)備所支持的動(dòng)作.
#define EV_KEY
3.繼續(xù)設(shè)置 Device: ret = ioctl(fd, UI_SET_RELBIT, REL_X); //鼠標(biāo) ret = ioctl(fd, UI_SET_RELBIT, REL_Y);
ret = ioctl(fd, UI_SET_EVBIT, EV_ABS); 同上。設(shè)置了Keybit等。 這里就是設(shè)置了Input Device關(guān)心或者說會(huì)產(chǎn)生的消息。
4. 寫入設(shè)備: struct uinput_user_dev uinput;
uinput.id.version = 4; ret = write(fd, &uinput, sizeof(uinput)); 此時(shí),在Kernel 層,對(duì)應(yīng)的動(dòng)作為: 此時(shí)Device status為UIST_NEW_DEVICE 并將udev->dev 這個(gè)input device 具體化。初始化該input_dev。 之后,改變狀態(tài): udev->state = UIST_SETUP_COMPLETE;
5.創(chuàng)建Input Device: 注意,此處是創(chuàng)建了Input Device。而不是UInput Device。 ioctl(fd, UI_DEV_CREATE);
input_register_device(udev->dev); //向子系統(tǒng)注冊(cè)該設(shè)備,之后中斷時(shí)input_event()向子系統(tǒng)報(bào)告事件 udev->state = UIST_CREATED;
6. 向Input Device發(fā)送Event:
struct input_event event = {0};
static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) 因?yàn)榇藭r(shí)state為UIST_CREATED input_event(udev->dev, ev.type, ev.code, ev.value); 發(fā)送event.
總結(jié): 使用UInput的步驟為: 1. 打開設(shè)備。 2. 使用ioctl() 配置設(shè)備。 3. 使用write() 將input device信息設(shè)置好。 4. 使用ioctl(UI_DEV_CREATE)創(chuàng)建Input Device。(即使用write設(shè)置的) 5. 再使用write() 寫入event.
UInput添加的Input Device在/proc的反應(yīng): #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
|
|
|