使用/dev/uinput的简要介绍(含demo程序)【转】
转自:https://blog.csdn.net/zhongkunjia/article/details/75142699
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。
这样,就可以通过应用程序的执行模拟鼠标、键盘等的输入事件。
使用/dev/uinput的简要介绍(含demo程序)【转】的更多相关文章
- 浅析BMP位图文件结构(含Demo)
浅析BMP位图文件结构(含Demo) 作者:一点一滴的Beer http://beer.cnblogs.com/ 关于BMP位图格式在网上可以找到比较详细的相关文档,有兴趣的可以搜索标题为“BMP ...
- Android Debuggerd 简要介绍和源码分析(转载)
转载: http://dylangao.com/2014/05/16/android-debuggerd-%E7%AE%80%E8%A6%81%E4%BB%8B%E7%BB%8D%E5%92%8C%E ...
- WCF简要介绍
什么是WCF WCF的全称是:Windows Communication Foundation.从本质上来说,它是一套软件开发包,是微软公司推出的符合SOA思想的技术框架.WCF为程序员提供了丰富的功 ...
- 简要介绍BASE64、MD5、SHA、HMAC几种方法。
加密解密,曾经是我一个毕业设计的重要组件.在工作了多年以后回想当时那个加密.解密算法,实在是太单纯了. 言归正传,这里我们主要描述Java已经实现的一些加密解密算法,最后介绍数字证书. ...
- [转]Android系统Surface机制的SurfaceFlinger服务简要介绍和学习计划
转自:Android系统Surface机制的SurfaceFlinger服务简要介绍和学习计划 前面我们从Android应用程序与SurfaceFlinger服务的关系出发,从侧面简单学习了Surfa ...
- [转] Android资源管理框架(Asset Manager)简要介绍和学习计划
转自:http://blog.csdn.net/luoshengyang/article/details/8738877 Android应用程序主要由两部分内容组成:代码和资源.资源主要就是指那些与U ...
- Activity启动过程简要介绍
无论是通过点击应用程序图标来启动Activity,还是通过Activity内部调用startActivity接口来启动新的Activity,都要借助于应用程序框架层的ActivityManagerSe ...
- Android应用程序的Activity启动过程简要介绍和学习计划
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6685853 在Android系统中,Activ ...
- Dalvik虚拟机简要介绍和学习计划
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8852432 我们知道,Android应用程序是 ...
随机推荐
- 20170929php
这是之前学习PHP类使用的代码 <?phpclass animal{ var $name="1"; var $sex="2"; public static ...
- 更新pip10后 ImportError: cannot import name ‘main'
百度了几个回答都没有解决问题,有些回答明显是直接复制过来的一点价值都没有,然后google一下立马解决.很多时候不能怪搜索引擎,问题出在一些国内网友对知识的不负责任 解决:找到报错文件,也就是那个pi ...
- Alpha冲刺——day10
Alpha冲刺--day10 作业链接 Alpha冲刺随笔集 github地址 团队成员 031602636 许舒玲(队长) 031602237 吴杰婷 031602220 雷博浩 031602634 ...
- 基于 Laravel 的 文件管理
以 laravel 5.5 为例,框架集成了文件系统和云存储功能 可以实现文件夹列表.创建.重命名.删除,文件列表.上传.重命名.删除等操作 一.先进行配置 在 config 文件夹下有 filesy ...
- Linux系统编程手册-源码的使用
转自:http://www.cnblogs.com/pluse/p/6296992.html 第三章后续部分重点介绍了后面章节所要使用的头文件及其实现,主要如下: ename.c.inc error_ ...
- 如何用Delphi开发网游外挂
1.动作式,所谓动作式,就是指用API发命令给窗口或API控制鼠标.键盘等,使游戏里的人物进行流动或者攻击,最早以前的“石器”外挂就是这种方式.2.本地修改式,这种外挂跟传统上的一些游戏修改器没有两样 ...
- robotframework+Selenium2Library 模态窗口的处理
原文链接:https://www.cnblogs.com/zuola/p/5750018.html 所谓模态窗口,就是指除非采取有效的关闭手段,用户的鼠标焦点或者输入光标将一直停留在其上的对话框. ...
- Vue入门---属性、style和class绑定方法
一 .用对象的方法绑定class <!DOCTYPE html> <html> <head> <meta charset="UTF-8"& ...
- eclipse运行tomcat中发生异常重启后tomcat端口被占用
在任务管理器关闭javaw进程即可,一般此时会有两个以上javaw进程,关闭其中占用内存较少的那个 可用netstat -ano命令查看端口占用情况
- IDEA中在目录中如何快速指定到当前的类
类似于myeclipse的 Link with Editor 其实也在IDEA的这个位置,跟狙击镜的图标一样,叫做Scroll from Source 不同的的是,IDEA的这个功能,需要手动点击,才 ...