转自: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

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <fcntl.h>
  5. #include <string.h>
  6. #include <linux/uinput.h>
  7. #include <linux/input.h>
  8. #define KEY_CUSTOM_UP 0x20
  9. #define KEY_CUSTOM_DOWN 0x30
  10. static struct uinput_user_dev uinput_dev;
  11. static int uinput_fd;
  12. int creat_user_uinput(void);
  13. int report_key(unsigned int type, unsigned int keycode, unsigned int value);
  14. int main(int argc, char *argv[])
  15. {
  16. int ret = 0;
  17. ret = creat_user_uinput();
  18. if(ret < 0){
  19. printf("%s:%d\n", __func__, __LINE__);
  20. return -1;//error process.
  21. }
  22. sleep(10);// help you to 'hexdump -C /dev/input/event[X]' for test.
  23. report_key(EV_KEY, KEY_A, 1);// Report BUTTON A CLICK - PRESS event
  24. report_key(EV_KEY, KEY_A, 0);// Report BUTTON A CLICK - RELEASE event
  25. report_key(EV_KEY, KEY_CUSTOM_UP, 12);
  26. report_key(EV_KEY, KEY_CUSTOM_UP, 0);
  27. sleep(5);
  28. close(uinput_fd);
  29. return 0;
  30. }
  31. int creat_user_uinput(void)
  32. {
  33. int i;
  34. int ret = 0;
  35. uinput_fd = open("/dev/uinput", O_RDWR | O_NDELAY);
  36. if(uinput_fd < 0){
  37. printf("%s:%d\n", __func__, __LINE__);
  38. return -1;//error process.
  39. }
  40. //to set uinput dev
  41. memset(&uinput_dev, 0, sizeof(struct uinput_user_dev));
  42. snprintf(uinput_dev.name, UINPUT_MAX_NAME_SIZE, "uinput-custom-dev");
  43. uinput_dev.id.version = 1;
  44. uinput_dev.id.bustype = BUS_VIRTUAL;
  45. ioctl(uinput_fd, UI_SET_EVBIT, EV_SYN);
  46. ioctl(uinput_fd, UI_SET_EVBIT, EV_KEY);
  47. ioctl(uinput_fd, UI_SET_EVBIT, EV_MSC);
  48. for(i = 0; i < 256; i++){
  49. ioctl(uinput_fd, UI_SET_KEYBIT, i);
  50. }
  51. ioctl(uinput_fd, UI_SET_MSCBIT, KEY_CUSTOM_UP);
  52. ioctl(uinput_fd, UI_SET_MSCBIT, KEY_CUSTOM_DOWN);
  53. ret = write(uinput_fd, &uinput_dev, sizeof(struct uinput_user_dev));
  54. if(ret < 0){
  55. printf("%s:%d\n", __func__, __LINE__);
  56. return ret;//error process.
  57. }
  58. ret = ioctl(uinput_fd, UI_DEV_CREATE);
  59. if(ret < 0){
  60. printf("%s:%d\n", __func__, __LINE__);
  61. close(uinput_fd);
  62. return ret;//error process.
  63. }
  64. }
  65. int report_key(unsigned int type, unsigned int keycode, unsigned int value)
  66. {
  67. struct input_event key_event;
  68. int ret;
  69. memset(&key_event, 0, sizeof(struct input_event));
  70. gettimeofday(&key_event.time, NULL);
  71. key_event.type = type;
  72. key_event.code = keycode;
  73. key_event.value = value;
  74. ret = write(uinput_fd, &key_event, sizeof(struct input_event));
  75. if(ret < 0){
  76. printf("%s:%d\n", __func__, __LINE__);
  77. return ret;//error process.
  78. }
  79. gettimeofday(&key_event.time, NULL);
  80. key_event.type = EV_SYN;
  81. key_event.code = SYN_REPORT;
  82. key_event.value = 0;//event status sync
  83. ret = write(uinput_fd, &key_event, sizeof(struct input_event));
  84. if(ret < 0){
  85. printf("%s:%d\n", __func__, __LINE__);
  86. return ret;//error process.
  87. }
  88. return 0;
  89. }

编译方法:

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程序)【转】的更多相关文章

  1. 浅析BMP位图文件结构(含Demo)

    浅析BMP位图文件结构(含Demo) 作者:一点一滴的Beer http://beer.cnblogs.com/   关于BMP位图格式在网上可以找到比较详细的相关文档,有兴趣的可以搜索标题为“BMP ...

  2. 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 ...

  3. WCF简要介绍

    什么是WCF WCF的全称是:Windows Communication Foundation.从本质上来说,它是一套软件开发包,是微软公司推出的符合SOA思想的技术框架.WCF为程序员提供了丰富的功 ...

  4. 简要介绍BASE64、MD5、SHA、HMAC几种方法。

    加密解密,曾经是我一个毕业设计的重要组件.在工作了多年以后回想当时那个加密.解密算法,实在是太单纯了.     言归正传,这里我们主要描述Java已经实现的一些加密解密算法,最后介绍数字证书.     ...

  5. [转]Android系统Surface机制的SurfaceFlinger服务简要介绍和学习计划

    转自:Android系统Surface机制的SurfaceFlinger服务简要介绍和学习计划 前面我们从Android应用程序与SurfaceFlinger服务的关系出发,从侧面简单学习了Surfa ...

  6. [转] Android资源管理框架(Asset Manager)简要介绍和学习计划

    转自:http://blog.csdn.net/luoshengyang/article/details/8738877 Android应用程序主要由两部分内容组成:代码和资源.资源主要就是指那些与U ...

  7. Activity启动过程简要介绍

    无论是通过点击应用程序图标来启动Activity,还是通过Activity内部调用startActivity接口来启动新的Activity,都要借助于应用程序框架层的ActivityManagerSe ...

  8. Android应用程序的Activity启动过程简要介绍和学习计划

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6685853 在Android系统中,Activ ...

  9. Dalvik虚拟机简要介绍和学习计划

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8852432 我们知道,Android应用程序是 ...

随机推荐

  1. 第一个spring,第五天。

    陈志棚:界面跳转与框架 李天麟:游戏界面ui 徐侃:算法代码的设计 经过五天的时间,经过队员的汇报,我们初步已经完成了各项的任务.

  2. 关于vue-eslint自动补全代码,以及自动生成雪碧图

    一.配置eslint module.exports={ "printWidth": 240, //一行的字符数,如果超过会进行换行,默认为80 "tabWidth&quo ...

  3. Yii 框架的Rbac [权限控制]

    转载自 xmlife 的博客 : http://blog.csdn.net/xmlife/article/details/50733451 1.首先我们要在配置文件的组件(component)里面配置 ...

  4. POJ 3436 ACM Computer Factory (网络流,最大流)

    POJ 3436 ACM Computer Factory (网络流,最大流) Description As you know, all the computers used for ACM cont ...

  5. Python 模块之shutil模块

    #拷贝文件,可指定长度,fsrc和fdst都是一个文件对象 def copyfileobj(fsrc, fdst, length=16*1024) shutil.copyfileobj(open(&q ...

  6. Python微信红包算法

    sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频) https://study.163.com/course/introduction.htm?courseId=1005269003& ...

  7. SQL记录-PLSQL数组

    PL/SQL数组 PL/SQL程序设计语言提供叫一种叫做VARRAY的数据结构,其可存储相同类型元素的一个固定大小的连续集合.VARRAY用于存储数据的有序集合,但它往往是更加有用认为数组作为相同类型 ...

  8. SQL记录-PLSQL日期与时间

    PL/SQL日期及时间 PL/SQL提供两个日期和时间相关的数据类型: 日期时间(Datetime)数据类型 间隔数据类型 datetime数据类型有: DATE TIMESTAMP TIMESTAM ...

  9. SQL语句(十四)子查询

    --1. 使用IN关键字 --例1 查询系别人数不足5人的系别中学生的学号.姓名和系别 --系别人数不足5人的系别 ==>选择条件 select Sdept from Student Group ...

  10. [C]语法, 知识点总结(二. 结构体, 类别名, static, const)

    结构体 定义: struct Student{ // 定义结构体Student, stu是创建的对象         char a[17]; // 结构体里面可以有多种不同类型的变量         ...