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

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。


这样,就可以通过应用程序的执行模拟鼠标、键盘等的输入事件。


  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寒江独钓2009

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值