日期:2014-05-16  浏览次数:20810 次

linux下获取按键响应事件
1、问题
通过一个死循环将读取键盘对应的设备文件将触发键盘事件在屏幕上打印出来,按esc退出程序
代码是在unbuntu10.04编译执行通过的

2、input_event描述
在Linux内核中,input设备用input_dev结构体描述,使用input子系统实现输入设备驱动的时候,驱动的核心工作就是向系统报告按键、触摸屏、键盘、鼠标等输入事件(event,通过input_event结构体描述),不再需要关心文件操作接口,因为Input子系统已经完成了文件操作接口
linux/input.h 这个文件定义了event事件的结构体,API和标准按键的编码等;
struct input_event {
    struct timeval time;  //按键时间
    __u16 type; //事件类型
    __u16 code; //要模拟成什么按键
    __s32 value;//是按下还是释放
};

type,指事件类型,常见的事件类型有:
EV_KEY, 按键事件,如键盘的按键(按下哪个键),鼠标的左键右键(是非击下)等;
EV_REL, 相对坐标,主要是指鼠标的移动事件(相对位移);
EV_ABS, 绝对坐标,主要指触摸屏的移动事件
code:事件的代码.
如果事件的类型代码是EV_KEY,该代码code为设备键盘代码.0~127为键盘上的按键代码
关于按键代码的定义,部分如下所示:
#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
value:
事件的值.如果事件的类型代码是EV_KEY,当按键按下时值为1,松开时值为0;如果事件的类型代码是EV_REL,value的正数值和负数值分别代表两个不同方向的值.


3、相关代码
key_simulator.c
#include
#include
#include
#include
#include

int main ()
{
  int keys_fd;
  char ret[2];
  struct input_event t;

  keys_fd = open ("/dev/input/event2", O_RDONLY);
  if (keys_fd <= 0)
    {
      printf ("open /dev/input/event2 device error!\n");
      return 0;
    }

  while (1)
    {
      if (read (keys_fd, &t, sizeof (t)) == sizeof (t))
        {
          if (t.type == EV_KEY)
            if (t.value == 0 || t.value == 1)
        {
              printf ("key %d %s\n", t.code,
                      (t.value) ? "Pressed" : "Released");
          if(t.code==KEY_ESC)
              break;
        }
        }
    }
  close (keys_fd);

  return 0;
}

4、注意问题
1)不同的类型计算机,设备对应event信息会有所不同
可以用cat获得的设备对应event信息:
# cat /proc/bus/input/devices
I: Bus=0019 Vendor=0000 Product=0001 Version=0000
N: Name="Power Button"
P: Phys=LNXPWRBN/button/input0
S: Sysfs=/devices/LNXSYSTM:00/LNXPWRBN:00/input/input0
U: Uniq=
H: Handlers=kbd event0
B: EV=3
B: KEY=100000 0 0 0

I: Bus=0017 Vendor=0001 Product=0001 Version=0100
N: Name="Macintosh mouse button emulation"
P: Phys=
S: Sysfs=/devices/virtual/input/input1
U: Uniq=
H: Handlers=mouse0 event1
B: EV=7
B: KEY=70000 0 0 0 0 0 0 0 0
B: REL=3

I: Bus=0011 Vendor=0001 Product=0001 Version=ab41
N: Name="AT Translated Set 2 keyboard"
P: Phys=isa0060/serio0/input0
S: Sysfs=/devices/platform/i8042/serio0/input/input2
U: Uniq=
H: Handlers=kbd event2
B: EV=120013
B: KEY=4 2000000 3803078 f800d001 feffffdf ffefffff ffffffff fffffffe
B: MSC=10
B: LED=7

I: Bus=0011 Vendor=0002 Product=0005 Version=0000
N: Name="ImPS/2 Generic Wheel Mouse"
P: Phys=isa0060/serio1/input0
S: Sysfs=/devices/platform/i8042/serio1/input/input3
U: Uniq=
H: Handlers=mouse1 event3
B: EV=7
B: KEY=70000 0 0 0 0 0 0 0 0
B: REL=103


I line:这行包含身份信息,显示了 bus type是 3 (usb), vendor, product, version等信息。
N line:这行包含了名字信息。