Linux Input Device 介紹: APIs
2010-03-01 14:21
253 查看
Linux Input Device 介紹: APIsjollen 發表於 April 8, 2009 12:18 PMLinux 的 Input Device 是重要的一個 subsystem,在進行實例介紹前,先大略了解一下相關的 API。 Linux Input Device input.c是Linux的”input”驅動程式,主要支援鍵盤與滑鼠的輸入;input.c介面有趣的地方是採用了事件(event)的方式來處理輸入,以下是input.c介面重要的資料結構與函數: * struct input_dev * void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) * void input_register_device(struct input_dev *); * void input_unregister_device(struct input_dev *); * void input_register_handler(struct input_handler *); * void input_unregister_handler(struct input_handler *); Linux 的input機制可用來實作「虛擬鍵盤」或「虛擬滑鼠」,只要呼叫input_event()將輸入資料發佈給input handler即可。 struct input_dev是用來描述輸入事件的重要資料結構,其原型宣告如下: struct input_dev { void *private; int number; char *name; unsigned short idbus; unsigned short idvendor; unsigned short idproduct; unsigned short idversion; unsigned long evbit[NBITS(EV_MAX)]; unsigned long keybit[NBITS(KEY_MAX)]; unsigned long relbit[NBITS(REL_MAX)]; unsigned long absbit[NBITS(ABS_MAX)]; unsigned long mscbit[NBITS(MSC_MAX)]; unsigned long ledbit[NBITS(LED_MAX)]; unsigned long sndbit[NBITS(SND_MAX)]; unsigned long ffbit[NBITS(FF_MAX)]; int ff_effects_max; unsigned int keycodemax; unsigned int keycodesize; void *keycode; unsigned int repeat_key; struct timer_list timer; int abs[ABS_MAX + 1]; int rep[REP_MAX + 1]; unsigned long key[NBITS(KEY_MAX)]; unsigned long led[NBITS(LED_MAX)]; unsigned long snd[NBITS(SND_MAX)]; 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 (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); int (*upload_effect)(struct input_dev *dev, struct ff_effect *effect); int (*erase_effect)(struct input_dev *dev, int effect_id); struct input_handle *handle; struct input_dev *next; }; 定義按鍵 我們可以設定struct input_dev裡的evbit欄位,來定義所要接受的輸入類型,目前共有8種輸入類型如下: * EV_KEY:Keys and buttons(按鍵與按鈕)。 * EV_REL:Relative axes(相對座標)。 * EV_ABS:Absolute axes(絕對座標)。 * EV_MSC:Misc events(其它事件)。 * EV_LED:LEDs。 * EV_SND:Sounds(聲音輸入)。 * EV_REP:Autorepeat values(自動重覆數值)。 * EV_FF:Force feedback事件。 以下是一個範例,我們指定dev可接受EV_KEY事件: dev.evbit[0] = BIT(EV_KEY); evbit是一個陣列,每個元素可以索引一種輸入類型。每種輸入類型均可指定特定的輸入資料,例如:TAB鍵。指定方式是使用set_bit()或BIT巨集來設定每種輸入類型的陣列。以下是各輸入類型的欄位名稱: * keybit[NBITS(KEY_MAX)]:Keys and buttons(按鍵與按鈕)。 * relbit[NBITS(REL_MAX)]:Relative axes(相對座標)。 * absbit[NBITS(ABS_MAX)]:Absolute axes(絕對座標)。 * mscbit[NBITS(MSC_MAX)]:Misc events(其它事件)。 * ledbit[NBITS(LED_MAX)]:LEDs。 * sndbit[NBITS(SND_MAX)]:Sounds(聲音輸入)。 * ffbit[NBITS(FF_MAX)]:Force feedback事件。 以下是使用set_bit()的範例: * set_bit(KEY_UP, dev.keybit); * set_bit(KEY_LEFT, dev.keybit); 或是使用BIT巨集也可以: * keybit[0] = BIT(KEYUP) | BIT(KEY_LEFT); input.h裡做位元運算的3個巨集如下: * NBITS(x):計算要幾個陣列元素,才夠紀錄第x個位元。 * BIT(x):傳回單獨第x個位元為1時所代表的數值,例如:x=0時為0x1,x=1時為0x2,x=2時為0x4。 * LONG(x):第x個位元是屬於第幾個陣列元素(即索引值)。 我們先設定驅動程式能接受EV_KEY事件,然後指定EV_KEY事件的特定輸入值為KEY_UP與KEY_LEFT按鍵。不同事件的輸入資料定義,請參考input.h檔,例如以下是EV_KEY事件的按鍵1~按鍵9定義: /* * Keys and buttons */ #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 設定好struct input_dev後再呼叫input_register_device()註冊至上層。當”input device”註冊至kernel後,當該input device被開啟時,便呼叫input device的open method;當input device關閉時,便呼叫input device的close method。 實作input device的open method時,若成功應傳回0,失敗的話則傳回任意的非零值;close method則不須傳回值。 Report 按鍵 使用者的按鍵往上層回報所使用的API如下: * input_report_key(struct input_dev *dev, unsigned int code, int value); * input_report_rel(struct input_dev *dev, unsigned int code, int value); * input_report_abs(struct input_dev *dev, unsigned int code, int value); * input_report_key與input_report_rel其實都是使用input_event()的巨集,input_event()的函數原型與參數說明如下: * void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value); * @dev:指向input device的指標。 * @type:輸入類型(EV_KEY、EV_ABS等)。 * @code:輸入按鍵(例如EV_KEY的KEY_1)。 * @value:按鍵值。 Input Handler 任何的按鍵輸入,都應呼叫input_event()來將input event送到input.c,再由input.c分派事件(遶送)到每一個”input handler”。有註冊input handler的驅動程式,都能讀取輸入資料。 --jollen |
相关文章推荐
- Linux Input Device 介绍: APIs
- Linux Input Device 介绍: APIs
- Linux Input Device 介绍: APIs
- linux中input_register_device注册函数分析
- Linux input子系统分析之二:深入剖析input_handler、input_core、input_device
- Linux Input Device
- Linux Input Device
- linux中input_register_device注册函数分析
- 在tslib移植中,出现tslib: Selected device is not a Linux input event device
- 四、Linux input 子系统学习之input_register_device 分析
- linux的Input子系统获取Device Name
- Linux磁盘“Device is busy”无法卸载
- Linux设备模型分析之device(基于3.10.1内核)
- linux 输入子系统(2)----简单实例分析系统结构(input_dev层)
- Linux Device Drivers, Third Edition
- 认识linux input子系统
- Linux 驱动模型初探3——device
- Device Drivers, Part 1: Linux Device Drivers for Your Girl Friend
- Linux Device Driver ---USB
- linux内核部件分析(六)——设备驱动模型之device