转自: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. Yale数据库上的人脸识别

    一.问题分析 1. 问题描述 在Yale数据集上完成以下工作:在给定的人脸库中,通过算法完成人脸识别,算法需要做到能判断出测试的人脸是否属于给定的数据集.如果属于,需要判断出测试的人脸属于数据集中的哪 ...

  2. asp.net简述MVC开发模式

    详情请参考:http://www.runoob.com/aspnet/mvc-intro.html 1.MVC 是三种 ASP.NET 编程模式中的一种.MVC 是一种使用 MVC(Model Vie ...

  3. 2013成都网赛1003 hdu 4730 We Love MOE Girls

    题意:有一个字符串,若以"desu"结尾,则将末尾的"desu"替换为"nanodesu",否则在字符串末尾加上"nanodesu ...

  4. 一条sql语句搞定基于mysql的sql执行顺序的基本理解

    对数据库基本操作是每个程序员基本功,如何理解并快速记住sql执行的顺序呢,其实一条复杂的sql就能搞定: SELECT DISTINCT <select_list> FROM <le ...

  5. 使用System.getProperty方法,如何配置JVM系统属性

    原创文章,欢迎转载,转载请注明出处! 很多时候我们需要在项目中读取外部属性文件,用到了System.getProperty("")方法.这个方法需要配置JVM系统属性,那么如何配置 ...

  6. PL/SQL如何设置当前格局确保每次打开都给关闭前一样

    打开plsql  --> windows-->save layout 即可

  7. 自学huawei之路-6005-8AP设备启动界面

    返回自学Huawei之路 自学huawei之路-AC6005-8AP设备启动界面 [YK-MES-MASTER] Please check whether system data has been c ...

  8. 【BZOJ3489】A simple rmq problem(KD-Tree)

    [BZOJ3489]A simple rmq problem(KD-Tree) 题面 BZOJ 题解 直接做肯定不好做,首先我们知道我们是一个二维平面数点,但是限制区间只能出现一次很不好办,那么我们给 ...

  9. 【bzoj3196】 Tyvj1730—二逼平衡树

    http://www.lydsy.com/JudgeOnline/problem.php?id=3196 (题目链接) 题意 1.查询k在区间内的排名:2.查询区间内排名为k的值:3.修改某一位值上的 ...

  10. 解题:POI2008 Building blocks

    题面 显然我们需要考虑每一个区间,而这个问题显然我们都会做,这不就是这道题么,也就是说假如中位数是$mid$,区间和是$sum$,那么代价就是$\sum\limits_{i=l}^r |mid-num ...