您的位置:首页 > 产品设计 > UI/UE

使用/dev/uinput的简要介绍(含demo程序)

2017-07-15 08:47 507 查看
uinput机制有2个很大的优点:

1) 不用自己写驱动(比如弄个红外遥控器、车载线控)。

2) 创建/dev/input/eventX节点,在用户态下向/dev/input/eventX写入事件,即可模拟键盘、鼠标等的事件输入。

操作流程:
1)打开UInput Device
2)设置UInput Device
3)写入设备信息
4)创建Input Device
5*)向Input Device发送Event
具体的demo代码如下:
//uinput-demo.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <linux/uinput.h>
#include <linux/input.h>

#define KEY_CUSTOM_UP 0x20
#define KEY_CUSTOM_DOWN 0x30

static struct uinput_user_dev uinput_dev;
static int uinput_fd;

int creat_user_uinput(void);
int report_key(unsigned int type, unsigned int keycode, unsigned int value);

int main(int argc, char *argv[])
{
int ret = 0;
ret = creat_user_uinput();
if(ret < 0){
printf("%s:%d\n", __func__, __LINE__);
return -1;//error process.
}

sleep(10);// help you to 'hexdump -C /dev/input/event[X]' for test.

report_key(EV_KEY, KEY_A, 1);// Report BUTTON A CLICK - PRESS event
report_key(EV_KEY, KEY_A, 0);// Report BUTTON A CLICK - RELEASE event

report_key(EV_KEY, KEY_CUSTOM_UP, 12);
report_key(EV_KEY, KEY_CUSTOM_UP, 0);

sleep(5);
close(uinput_fd);
return 0;
}

int creat_user_uinput(void)
{
int i;
int ret = 0;

uinput_fd = open("/dev/uinput", O_RDWR | O_NDELAY);
if(uinput_fd < 0){
printf("%s:%d\n", __func__, __LINE__);
return -1;//error process.
}

//to set uinput dev
memset(&uinput_dev, 0, sizeof(struct uinput_user_dev));
snprintf(uinput_dev.name, UINPUT_MAX_NAME_SIZE, "uinput-custom-dev");
uinput_dev.id.version = 1;
uinput_dev.id.bustype = BUS_VIRTUAL;

ioctl(uinput_fd, UI_SET_EVBIT, EV_SYN);
ioctl(uinput_fd, UI_SET_EVBIT, EV_KEY);
ioctl(uinput_fd, UI_SET_EVBIT, EV_MSC);

for(i = 0; i < 256; i++){
ioctl(uinput_fd, UI_SET_KEYBIT, i);
}
ioctl(uinput_fd, UI_SET_MSCBIT, KEY_CUSTOM_UP);
ioctl(uinput_fd, UI_SET_MSCBIT, KEY_CUSTOM_DOWN);

ret = write(uinput_fd, &uinput_dev, sizeof(struct uinput_user_dev));
if(ret < 0){
printf("%s:%d\n", __func__, __LINE__);
return ret;//error process.
}

ret = ioctl(uinput_fd, UI_DEV_CREATE);
if(ret < 0){
printf("%s:%d\n", __func__, __LINE__);
close(uinput_fd);
return ret;//error process.
}
}

int report_key(unsigned int type, unsigned int keycode, unsigned int value)
{
struct input_event key_event;
int ret;

memset(&key_event, 0, sizeof(struct input_event));

gettimeofday(&key_event.time, NULL);
key_event.type = type;
key_event.code = keycode;
key_event.value = value;
ret = write(uinput_fd, &key_event, sizeof(struct input_event));
if(ret < 0){
printf("%s:%d\n", __func__, __LINE__);
return ret;//error process.
}

gettimeofday(&key_event.time, NULL);
key_event.type = EV_SYN;
key_event.code = SYN_REPORT;
key_event.value = 0;//event status sync
ret = write(uinput_fd, &key_event, sizeof(struct input_event));
if(ret < 0){
printf("%s:%d\n", __func__, __LINE__);
return ret;//error process.
}

return 0;
}
编译方法:

root@ubuntu:/home/ubuntu/Documents# gcc uinput-demo.c -o uinput-demo

root@ubuntu:/home/ubuntu/Documents# ls

uinput-demo  uinput-demo.c

root@ubuntu:/home/ubuntu/Documents# ./uinput-demo     ------执行时要用root用户登入才行
这时,在开个终端,切换到:root@ubuntu:/dev/input#
执行hexdump -C event5  ------event5是创建uinput时生成的节点

10秒到后,显示结果:
root@ubuntu:/dev/input# hexdump -C event5

00000000  bd 5e 69 59 aa fd 05 00  01 00 1e 00 01 00 00 00  |.^iY............|

00000010  bd 5e 69 59 aa fd 05 00  00 00 00 00 00 00 00 00  |.^iY............|

00000020  bd 5e 69 59 d7 fd 05 00  01 00 1e 00 00 00 00 00  |.^iY............|

00000030  bd 5e 69 59 d7 fd 05 00  00 00 00 00 00 00 00 00  |.^iY............|

00000040  bd 5e 69 59 db fd 05 00  01 00 20 00 0c 00 00 00  |.^iY...... .....|

00000050  bd 5e 69 59 db fd 05 00  00 00 00 00 00 00 00 00  |.^iY............|

00000060  bd 5e 69 59 dd fd 05 00  01 00 20 00 00 00 00 00  |.^iY...... .....|

00000070  bd 5e 69 59 dd fd 05 00  00 00 00 00 00 00 00 00  |.^iY............|

adhexdump: event5: 没有那个设备

00000080

root@ubuntu:/dev/input# 

也可以打开记事本,再次执行:
root@ubuntu:/home/ubuntu/Documents#
./uinput-demo
10秒到后,就会在记事本里输入:ad。

这样,就可以通过应用程序的执行模拟鼠标、键盘等的输入事件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息