閑聊linux中的input裝置(3)如果不認識他們仨,故事繼續不下去了

來源:互聯網
上載者:User

最近有這樣一個事情:18名上海某名牌大學學生為了尋求刺激,到某險地進行探險,後迷失森林,然後肚子餓了,衣服穿少了冷,於是與打電話求助當地警員。最後這幫大學生都得以救出,然後飯也吃飽了,衣服也加上了,不過在救援的途中,人民的兒子,年輕的張寧海警員永遠離我們而去了。好好地大學生放著課不上,去外地探險……

好了廢話不多說。繼續我們的input裝置之旅。

從前一節來看,在linux核心中添加一個input裝置變得很簡單了。我們再也不必須去動手寫那些該死的介面函數了。可是你有沒有想過,是誰讓我們的工作變得這麼簡單了呢?答案是linux核心中的input core。她總是那麼癡情,默默地不求回報地為你做許許多多的事情,在你背後默默的支援你愛著你。是的,你所想到的大多數事情,我們的input core都已經為你做好。除了感動,我們還能說什麼呢?(input core對應的實體在linux核心源碼目錄linux-2.6.29/drivers/input/input.c檔案)

在正式接觸我們可愛的input core之前,有必要瞭解一下幾個重要的結構體,這幾個結構體是我們這個故事的主體。

第一個資料結構 struct input_dev。悟性高的哥們馬上就會想到,它就是我們input 裝置在linux核心中的類比,即裡面記錄了一個input裝置的所有資訊。定義於linux-2.6.29/include/linux/input.h中

struct input_dev {

 const char *name;

       const char *phys;

       const char *uniq;

       struct input_id id;

       unsigned long evbit[BITS_TO_LONGS(EV_CNT)];

       unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];

       unsigned long relbit[BITS_TO_LONGS(REL_CNT)];

       unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];

       unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];

       unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];

       unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];

       unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];

       unsigned long swbit[BITS_TO_LONGS(SW_CNT)];

       unsigned int keycodemax;

       unsigned int keycodesize;

       void *keycode;

       int (*setkeycode)(struct input_dev *dev, int scancode, int keycode);

       int (*getkeycode)(struct input_dev *dev, int scancode, int *keycode);

       struct ff_device *ff;

       unsigned int repeat_key;

       struct timer_list timer;

       int sync;

       int abs[ABS_MAX + 1];

       int rep[REP_MAX + 1];

       unsigned long key[BITS_TO_LONGS(KEY_CNT)];

       unsigned long led[BITS_TO_LONGS(LED_CNT)];

       unsigned long snd[BITS_TO_LONGS(SND_CNT)];

       unsigned long sw[BITS_TO_LONGS(SW_CNT)];

 

       int absmax[ABS_MAX + 1];

       int absmin[ABS_MAX + 1];

       int absfuzz[ABS_MAX + 1];

       int absflat[ABS_MAX + 1];

 

       int (*open)(struct input_dev *dev);

       void (*close)(struct input_dev *dev);

       int (*flush)(struct input_dev *dev, struct file *file);

       int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);

       struct input_handle *grab;

       spinlock_t event_lock;

       struct mutex mutex;

       unsigned int users;

       int going_away;

       struct device dev;

       struct list_head  h_list;

       struct list_head  node;

};

很強大的一個結構體,因為她把所有的input裝置的資訊都考慮到了,真的是很無私。不過對於我們的akm驅動來說只需要關注幾個小細節,結構中的加粗部分。unsigned long evbit[BITS_TO_LONGS(EV_CNT)]表示此input裝置支援的事件,比如前面的第二節中的set_bit(EV_ABS, akm->input_dev->evbit)設定input_dev->evbit中的相應位讓它支援絕對值座標。類似的還有以下這些事件:EV_KEY -按鍵, EV_REL -相對座標EV_ABS -絕對座標,EV_LED -  LED,EV_FF- 力反饋。unsigned
long absbit[BITS_TO_LONGS(ABS_CNT)];設定相應的位以支援某一類絕對值座標。比如第二節中的input_set_abs_params(akm->input_dev, ABS_RX, 0, 23040, 0, 0);它的函數體如下:

static inline void input_set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat)

{

       dev->absmin[axis] = min;

       dev->absmax[axis] = max;

       dev->absfuzz[axis] = fuzz;

       dev->absflat[axis] = flat;

 

       dev->absbit[BIT_WORD(axis)] |= BIT_MASK(axis);

}

表示支援絕對值x座標,並設定它在座標系中的最大值和最小值,以及幹擾值和平焊位置等。

struct list_head h_list;表示的是和該裝置相關的所有input handle的結構體鏈表(input handle為何物下文馬上會講到)。struct list_head node;所有input裝置群組成的鏈表結構(後面將會知道它對應於input_dev_list)。

 

Ok 馬上進入第二個結構體struct input_handler(還是來自linux-2.6.29/include/linux/input.h)

struct input_handler {

 

       void *private;

 

       void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);

       int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);

       void (*disconnect)(struct input_handle *handle);

       void (*start)(struct input_handle *handle);

 

       const struct file_operations *fops;

       int minor;

       const char *name;

 

       const struct input_device_id *id_table;

       const struct input_device_id *blacklist;

 

       struct list_head  h_list;

       struct list_head  node;

};

顧名思義:用來處理input裝置的一個結構體。struct list_head h_list表示的是和該裝置相關的所有input handle的結構體鏈表和前面那個一樣;struct list_head       node所有input_handle組成的結構體連鏈表(後面將會知道它對應於input_handler_list)。每一個input裝置在註冊時,他都會遍曆input_handler_list鏈表上的每一個input_handler,去找尋他心中的那個她,同理每一個input_handler在註冊時,他也會去input_dev_list上找尋那個屬於他的她。有時候事情往往不會那麼盡如人意,當input_handler還沒出生時,你這個input_dev就一直在那等吧,等到天荒地老,等到海枯石爛。最後來一句,我等到花兒也謝了,你丫到底還來不來啊。注意這裡的input_handler和input_dev並不是一一對應的關係,有時一個input_handler對應好幾個input_dev。於是乎,作為看代碼的我就在想,linux核心開發人員的思想怎麼這麼不單純呢,這不明擺著教育我們搞一夫多妻制嗎,不過管怎樣,還是得記住公司的企業文化,本分點。如果你丫說你同時擁有兩個馬子,我將會無情的向你拋出那句話:“出來混,遲早要還的!”。

前面多次提到那個input_handle(注意區別input_handler),她到底是何方神聖。好吧,就讓我們來一層一層揭開她那神秘的面紗,當你第一次看到她完完全全展現在你面前時,那時候你的滿足感和興奮度和她的害羞度是成正比的。

同樣來自linux-2.6.29/include/linux/input.h

struct input_handle {

 

       void *private;

 

       int open;

       const char *name;

 

       struct input_dev *dev;

       struct input_handler *handler;

 

       struct list_head  d_node;

       struct list_head  h_node;

};

怎麼啦?是不是很失望,原來就這麼回事啊。嗯,沒錯,兄弟,就這麼回事。人往往都這樣,得到了某樣東西,想想覺得就那麼回事,沒得到呢,那叫一個好奇,那叫一個盼望。好了既然看到她的廬山真面目了,就坦然面對她,作為一個負責的男人,我還是來好好研究一下。

Input_Handle其實也好理解,它就是input_dev和 input_handler粘合劑,通過Input_Handle這麼一攪和,input_dev就和 input_handler發生了點關係,至於什麼樣的關係我們後文將會知道的一清二楚。struct input_dev *dev對應的input裝置。struct input_handler *handler對應該裝置的handler。struct list_head d_node和struct
list_head h_node則分別關聯上前面兩個結構體中的struct list_head h_list。

終於告一段落了,休息,休息一下!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.