Linux Input Device 介绍: APIs

 Linux 的 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

你可能感兴趣的:(device)