使用/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

 

  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\n", __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\n", __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\n", __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\n", __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\n", __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\n", __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。

 

這樣,就可以通過應用程序的執行模擬鼠標、鍵盤等的輸入事件。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM