zoukankan      html  css  js  c++  java
  • 使用/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

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

    编译方法:

    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。

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

  • 相关阅读:
    jxl读和取Excel文件
    Studio for WPF:定制 C1WPFChart 标记
    为C1Chart for WPF添加自定义标题、坐标轴单位标签以及旋转坐标轴注释
    自定义饼图(PieChart)各个PieSlice的外观
    vue组件
    vue双向绑定
    第一个Vue程序
    vue入门介绍
    js生成随机固定长度字符串的简便方法
    JavaScript 函数式编程读书笔记1
  • 原文地址:https://www.cnblogs.com/zzb-Dream-90Time/p/9045788.html
Copyright © 2011-2022 走看看