一 、 整體架構 圖node
上層是圖形界面和應用程序,經過監聽設備節點,獲取用戶相應的輸入事件,根據輸入事件來作出相應的反應;eventX (X從0開始)表示 按鍵事件,mice 表示鼠標事件linux
Input core --- input 核心架構
Input event drivers --- input事件驅動(mousedev 、 evdev、keyboard)spa
Input device drivers --- input設備驅動(觸摸屏、鍵盤、鼠標)3d
三個重要的結構體:code
代碼路徑: include\linux\input.h (基於kernel4.0)orm
1 struct input_dev { ///表明 input 設備 2 const char *name; /// 設備名稱 3 const char *phys; ////設備在系統結構中的物理路徑 4 const char *uniq; ///設備的惟一標識符 5 struct input_id id; ///描述硬件設備屬性的 ID 6 7 unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];/// INPUT_PROP_CNT--0x20 ,一個long包含32bit,因此 propbit[1] 8 9 unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; ///設備支持的事件類型 10 unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; 11 unsigned long relbit[BITS_TO_LONGS(REL_CNT)]; 12 unsigned long absbit[BITS_TO_LONGS(ABS_CNT)]; 13 unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)]; 14 unsigned long ledbit[BITS_TO_LONGS(LED_CNT)]; 15 unsigned long sndbit[BITS_TO_LONGS(SND_CNT)]; 16 unsigned long ffbit[BITS_TO_LONGS(FF_CNT)]; 17 unsigned long swbit[BITS_TO_LONGS(SW_CNT)]; 18 19 unsigned int hint_events_per_packet; 20 21 unsigned int keycodemax; 22 unsigned int keycodesize; 23 void *keycode; 24 25 int (*setkeycode)(struct input_dev *dev, 26 const struct input_keymap_entry *ke, 27 unsigned int *old_keycode); 28 int (*getkeycode)(struct input_dev *dev, 29 struct input_keymap_entry *ke); 30 31 struct ff_device *ff; 32 33 unsigned int repeat_key; 34 struct timer_list timer; 35 36 int rep[REP_CNT]; 37 38 struct input_mt *mt; 39 40 struct input_absinfo *absinfo; 41 42 unsigned long key[BITS_TO_LONGS(KEY_CNT)]; 43 unsigned long led[BITS_TO_LONGS(LED_CNT)]; 44 unsigned long snd[BITS_TO_LONGS(SND_CNT)]; 45 unsigned long sw[BITS_TO_LONGS(SW_CNT)]; 46 47 int (*open)(struct input_dev *dev);///打開設備 48 void (*close)(struct input_dev *dev); 49 int (*flush)(struct input_dev *dev, struct file *file); 50 int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); 51 52 struct input_handle __rcu *grab; 53 54 spinlock_t event_lock; 55 struct mutex mutex; 56 57 unsigned int users; 58 bool going_away; 59 60 struct device dev;///每一個設備的基類 61 62 struct list_head h_list; 63 struct list_head node; 64 65 unsigned int num_vals; 66 unsigned int max_vals; 67 struct input_value *vals; 68 69 bool devres_managed; 70 };
1 struct input_handler {///表明輸入設備的處理方法 2 3 void *private; 4 5 void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); 6 void (*events)(struct input_handle *handle, 7 const struct input_value *vals, unsigned int count); 8 bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);/// 9 bool (*match)(struct input_handler *handler, struct input_dev *dev); 10 int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); 11 void (*disconnect)(struct input_handle *handle); 12 void (*start)(struct input_handle *handle); 13 14 bool legacy_minors; ///是否遺留次設備號 15 int minor;///次設備號 16 const char *name;///名稱 17 18 const struct input_device_id *id_table;/// input_device 和 input_handle 經過id_table 進行匹配 19 20 struct list_head h_list; 21 struct list_head node; 22 };
Match :在設備id 和handler 的id_table 匹配成功的時候調用; (called after comparing device's id with handler's id_table to perform fine-grained matching between device and handler)blog
Connect : 當一個handle 匹配到一個device 的時候執行(called when attaching a handler to an input device)事件
Start :當input 核心執行完 connect 之後調用(called by input core right after connect() method)圖片
1 struct input_handle { //// 用來關聯input_dev 和 input_handler (links input device with an input handler) 2 3 void *private;///私有成員變量 4 5 int open; 6 const char *name; 7 8 struct input_dev *dev; 9 struct input_handler *handler; 10 11 struct list_head d_node; 12 struct list_head h_node; 13 };
如圖,橫軸表示一系列的input 設備,縱軸表示事件驅動event,中間的紫色圓點表明input_handle,經過input_handle來關聯設備驅動和事件驅動
(注:以上圖片均來自麥子學院 金鑫老師的課程,在此對其辛勤付出和無私分享表示真摯的感謝!)