【Linux系统编程应用】 Linux Input子系统(一)
1. 什么是輸入子系統 ?
輸入子系統是 Linux內核用于管理各種輸入設備 (鍵盤,鼠標,遙控桿,書寫板等等 )的部分,用戶通過輸入子系統進行內核,命令行,圖形接口之間的交換。輸入子系統在內核里實現,因為設備經常要通過特定的硬件接口被訪問 (例如串口, ps/2, usb等等 ),這些硬件接口由內核保護和管理。內核給用戶導出一套固定的硬件無關的 input API,供用戶空間程序使用。
?
2. 理解內核內部實現
輸入子系統分為三塊: input core, drivers和 event handlers。他們之間的關系如圖 1所示。正常的路徑是從底層硬件到驅動,從驅動到 input core,從 input core到 event handler,從 event handler到 user space。此外,還存在一個返回路徑 (return path)。返回路徑允許給一個鍵盤設置 LED,給一個 force feedback joystick提供 motion commands。路徑的兩個方向(指從內核到用戶的方向和從用戶到內核的方向)使用相同的event定義和不同的 type identifier。
3. 相關結構體
[root@uplooking ~]# vim /usr/include/linux/input.h?
/** The event structure itself*/ struct input_event {struct timeval time; 輸入事件時間;__u16 type; 類型; __u16 code; 按鍵值: __s32 value; 按鍵狀態: };code:事件代碼
事件的代碼。如果事件的類型代碼是EV_KEY,該代碼code為設備鍵盤代碼,代碼值0~127為鍵盤上的按鍵代碼, 0x110~0x116 為鼠標上按鍵代碼,其中0x110(BTN_ LEFT)為鼠標左鍵,0x111(BTN_RIGHT)為鼠標右鍵,0x112(BTN_ MIDDLE)為鼠標中鍵。其它代碼含義請參看include/linux /input.h文件。如果事件的類型代碼是EV_REL,code值表示軌跡的類型。如指示鼠標的X軸方向 REL_X (代碼為0x00),指示鼠標的Y軸方向REL_Y(代碼為0x01),指示鼠標中輪子方向REL_WHEEL(代碼為0x08)。
** Keys and buttons*/#define KEY_RESERVED 0 #define KEY_ESC 1 #define KEY_1 2 #define KEY_2 3 #define KEY_3 4 #define KEY_4 5 #define KEY_5 6 #define KEY_6 7 #define KEY_7 8 #define KEY_8 9 #define KEY_9 10 #define KEY_0 11 #define KEY_MINUS 12 #define KEY_EQUAL 13 #define KEY_BACKSPACE 14 #define KEY_TAB 15 #define KEY_Q 16 #define KEY_W 17 #define KEY_E 18 #define KEY_R 19 #define KEY_T 20 #define KEY_Y 21 #define KEY_U 22 #define KEY_I 23 #define KEY_O 24 #define KEY_P 25 #define KEY_LEFTBRACE 26 #define KEY_RIGHTBRACE 27 #define KEY_ENTER 28 #define KEY_LEFTCTRL 29 #define KEY_A 30 #define KEY_S 31 #define KEY_D 32 #define KEY_F 33 #define KEY_G 34 #define KEY_H 35 #define KEY_J 36 #define KEY_K 37 #define KEY_L 38 #define KEY_SEMICOLON 39 #define KEY_APOSTROPHE 40 #define KEY_GRAVE 41 #define KEY_LEFTSHIFT 42 #define KEY_BACKSLASH 43 #define KEY_Z 44 #define KEY_X 45 #define KEY_C 46 #define KEY_V 47 #define KEY_B 48 #define KEY_N 49 #define KEY_M 50 #define KEY_COMMA 51 #define KEY_DOT 52 #define KEY_SLASH 53 #define KEY_RIGHTSHIFT 54 #define KEY_KPASTERISK 55 #define KEY_LEFTALT 56 #define KEY_SPACE 57 #define KEY_CAPSLOCK 58 #define KEY_F1 59 #define KEY_F2 60 #define KEY_F3 61 #define KEY_F4 62 #define KEY_F5 63 #define KEY_F6 64 #define KEY_F7 65 #define KEY_F8 66 #define KEY_F9 67 #define KEY_F10 68 #define KEY_NUMLOCK 69 #define KEY_SCROLLLOCK 70 #define KEY_KP7 71 #define KEY_KP8 72 #define KEY_KP9 73 #define KEY_KPMINUS 74 #define KEY_KP4 75 #define KEY_KP5 76 #define KEY_KP6 77 #define KEY_KPPLUS 78 #define KEY_KP1 79 #define KEY_KP2 80 #define KEY_KP3 81 #define KEY_KP0 82 #define KEY_KPDOT 83#define KEY_ZENKAKUHANKAKU 85 #define KEY_102ND 86 #define KEY_F11 87 #define KEY_F12 88 #define KEY_RO 89 #define KEY_KATAKANA 90 #define KEY_HIRAGANA 91 #define KEY_HENKAN 92 #define KEY_KATAKANAHIRAGANA 93 #define KEY_MUHENKAN 94 #define KEY_KPJPCOMMA 95 #define KEY_KPENTER 96 #define KEY_RIGHTCTRL 97 #define KEY_KPSLASH 98 #define KEY_SYSRQ 99 #define KEY_RIGHTALT 100 #define KEY_LINEFEED 101 #define KEY_HOME 102 #define KEY_UP 103 #define KEY_PAGEUP 104 #define KEY_LEFT 105 #define KEY_RIGHT 106 #define KEY_END 107 #define KEY_DOWN 108 #define KEY_PAGEDOWN 109 #define KEY_INSERT 110 #define KEY_DELETE 111 #define KEY_MACRO 112 #define KEY_MUTE 113 #define KEY_VOLUMEDOWN 114 #define KEY_VOLUMEUP 115 #define KEY_POWER 116 #define KEY_KPEQUAL 117 #define KEY_KPPLUSMINUS 118 #define KEY_PAUSE 119#define KEY_KPCOMMA 121 #define KEY_HANGEUL 122 #define KEY_HANGUEL KEY_HANGEUL #define KEY_HANJA 123 #define KEY_YEN 124 #define KEY_LEFTMETA 125 #define KEY_RIGHTMETA 126 #define KEY_COMPOSE 127
鼠標相關的值
#define BTN_MOUSE 0x110 #define BTN_LEFT 0x110 #define BTN_RIGHT 0x111 #define BTN_MIDDLE 0x112 #define BTN_SIDE 0x113 #define BTN_EXTRA 0x114 #define BTN_FORWARD 0x115 #define BTN_BACK 0x116 #define BTN_TASK 0x117
相對坐標
Type為EV_REL時,code表示操作的是哪個坐標軸,如:REL_X,REL_Y。(因為鼠標有x,y兩個軸向,所以一次鼠標移動,會產生兩個input_event)** Relative axes*/#define REL_X 0x00 #define REL_Y 0x01 #define REL_Z 0x02 #define REL_RX 0x03 #define REL_RY 0x04 #define REL_RZ 0x05 #define REL_HWHEEL 0x06 #define REL_DIAL 0x07 #define REL_WHEEL 0x08 #define REL_MISC 0x09 #define REL_MAX 0x0f value:根據Type的不同而含義不同。 例如: Type為EV_KEY時,value: 0表示按鍵抬起。1表示按鍵按下。(4表示持續按下等?)。 Type為EV_REL時,value: 表明移動的值和方向(正負值)。 Type為EV_ABS時,code表示絕對位置。
4. 鍵盤設備示例代碼
執行結果如下:
5. 鼠標設備示例代碼
執行結果如下:
6. 模擬鼠標和按鍵的示例代碼
#include <stdio.h> #include <linux/input.h> #include <fcntl.h> #include <sys/time.h> #include <unistd.h>//按鍵模擬,按鍵包含按下和松開兩個環節void simulate_key(int fd, int kval) {struct input_event event;gettimeofday(&event.time, 0);//按下kval鍵event.type = EV_KEY;event.value = 1;event.code = kval;write(fd, &event, sizeof(event));//同步,也就是把它報告給系統event.type = EV_SYN;event.value = 0;event.code = SYN_REPORT;write(fd, &event, sizeof(event));memset(&event, 0, sizeof(event));gettimeofday(&event.time, 0);//松開kval鍵event.type = EV_KEY;event.value = 0;event.code = kval;write(fd, &event, sizeof(event));//同步,也就是把它報告給系統event.type = EV_SYN;event.value = 0;event.code = SYN_REPORT;write(fd, &event, sizeof(event)); }//鼠標移動模擬 void simulate_mouse(int fd, int rel_x, int rel_y) {struct input_event event;gettimeofday(&event.time, 0);//x軸坐標的相對位移event.type = EV_REL;event.value = rel_x;event.code = REL_X;write(fd, &event, sizeof(event));//y軸坐標的相對位移event.type = EV_REL;event.value = rel_y;event.code = REL_Y;write(fd, &event, sizeof(event));//同步event.type = EV_SYN;event.value = 0;event.code = SYN_REPORT;write(fd, &event, sizeof(event));}int main(int argc, char **argv) {int fd_mouse = -1;int fd_kbd = -1;int i = 0;fd_kbd = open("/dev/input/event3", O_RDWR);if(fd_kbd <= 0){printf("Can not open keyboard input file\n");return -1;}fd_mouse = open("/dev/input/event2", O_RDWR);if(fd_mouse <= 0){printf("Can not open mouse input file\n");return -1;} for (i = 0; i < 50; i++){simulate_key(fd_mouse, BTN_LEFT); //模擬按下鼠標左鍵//if (i % 3 == 0)// simulate_key(fd_kbd, KEY_A); //模擬按下鍵盤A鍵//模擬鼠標相對上次x和y軸相應移動10個像素//simulate_mouse(fd_mouse, 10, 10); sleep(3);}close(fd_kbd);close(fd_mouse); }總結
以上是生活随笔為你收集整理的【Linux系统编程应用】 Linux Input子系统(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【SDL】 如何在RedHat6.5中搭
- 下一篇: 【Linux系统编程应用】 Linux输