input-event-codes.h 是 Linux 输入子系统中最核心的头文件之一,定义了用户空间与内核之间传递输入事件时使用的所有标准常量。

它位于内核源码的 include/uapi/linux/input-event-codes.h 路径下,其中的 uapi 表示这是用户空间 API(User Space API),意味着用户空间程序(如 Android 的 getevent 工具)可以直接包含并使用这个头文件中定义的宏。

1. 核心数据结构:input_event

input_event 是用户空间从 /dev/input/eventX 节点读取到的原始事件结构。input-event-codes.h 中定义的宏,主要就是用于填充和解析这个结构体的 typecode 和 value 字段。

struct input_event {
    struct timeval time;  // 事件发生的时间戳
    __u16 type;           // 事件类型,如 EV_KEY, EV_ABS
    __u16 code;           // 事件代号,如 KEY_VOLUMEUP, ABS_X
    __s32 value;          // 事件的值,如 1 (按下), 0 (释放)
};

2. 事件类型 (type)

type 字段定义了事件的宏观类别,系统根据它来决定如何解析 code 和 value

类型常量 描述
EV_SYN 0x00 同步事件:用作事件分隔符,标志着一组输入事件的结束。例如,一次触摸移动会产生多个EV_ABS事件,最后以一个EV_SYNSYN_REPORT来同步。
EV_KEY 0x01 按键事件:用于描述键盘、鼠标按钮或其他按键类设备的状态变化。
EV_REL 0x02 相对坐标事件:用于描述相对轴值的变化,例如鼠标的移动量REL_XREL_Y
EV_ABS 0x03 绝对坐标事件:用于描述绝对轴值的变化,例如触摸屏上报的触点坐标ABS_XABS_Y
EV_MSC 0x04 其他无法归类的杂项事件。
EV_SW 0x05 用于描述开关状态,如笔记本盖子开合(SW_LID)。
EV_LED 0x11 用于控制设备上的 LED 指示灯。
EV_SND 0x12 用于向设备输出声音。
EV_REP 0x14 用于设置按键自动重复(长按连发)的参数。
EV_FF 0x15 用于力反馈设备,如游戏手柄的震动。
EV_PWR 0x16 电源事件,一个特殊的事件类型。

3. 同步事件 (EV_SYN) 的子代码

EV_SYN 类型下,code 字段被用来定义不同的同步语义:

  • SYN_REPORT (0):最常用的同步点。用于分隔一组完整的输入数据包,例如,上报一次完整的按键(按下和释放)或一个完整的触摸点坐标。用户空间程序只有在收到 SYN_REPORT 后,才认为这一帧事件是完整的。

  • SYN_MT_REPORT (2):在多指触摸协议中,用于分隔单个触摸点的数据。

  • SYN_DROPPED (3):表示内核事件队列发生溢出,一些事件被丢弃。此时用户空间应该忽略当前队列中的所有事件,直到下一个 SYN_REPORT,并重新同步设备状态。

4. 按键与按钮 (EV_KEY) 的子代码

这是 input-event-codes.h 中最庞大的部分,定义了成百上千的按键码,以 KEY_ 或 BTN_ 开头。它们遵循 USB HUT (HID Usage Tables) 标准。

常用按键分类
分类 示例代码 说明
标准键盘 KEY_A 30 字母 'A' 键
KEY_1 2 数字 '1' 键
KEY_ENTER 28 回车键
KEY_SPACE 57 空格键
功能键 KEY_F1 - KEY_F12 59-68 键盘顶部的 F1-F12 功能键
媒体控制 KEY_POWER 116 电源键
KEY_VOLUMEUP / KEY_VOLUMEDOWN 115 / 114 音量加减键
KEY_MUTE 113 静音键
导航键 KEY_UP / KEY_DOWN / KEY_LEFT / KEY_RIGHT 103-106 方向键
KEY_HOME / KEY_END 102 / 107 导航键
修饰键 KEY_LEFTSHIFT / KEY_RIGHTSHIFT 42 / 54 左右 Shift 键
KEY_LEFTALT / KEY_RIGHTALT 56 / 100 左右 Alt 键
KEY_LEFTMETA / KEY_RIGHTMETA 125 / 126 Windows/Command 键
鼠标按钮 BTN_LEFT 0x110 鼠标左键
BTN_RIGHT 0x111 鼠标右键
BTN_MIDDLE 0x112 鼠标中键
特殊工具 BTN_TOUCH 0x14a 接触触摸屏或触摸板
BTN_TOOL_FINGER / BTN_TOOL_PEN 0x140 / 0x140 用于区分手指或手写笔工具

value 字段在 EV_KEY 事件中的含义非常明确:0 表示按键释放,1 表示按键按下,2 表示按键重复(长按自动连发)。

5. 绝对坐标轴 (EV_ABS) 的子代码

EV_ABS 类型用于触摸屏、手写板、摇杆等上报绝对位置的设备。code 指定坐标轴,value 是坐标值。

  • 基本轴ABS_X (0), ABS_Y (1), ABS_Z (2)。

  • 旋转轴ABS_RX (3), ABS_RY (4), ABS_RZ (5)。

  • 多指触摸轴ABS_MT_ 系列,如 ABS_MT_POSITION_X (0x35), ABS_MT_POSITION_Y (0x36),用于上报多点触摸坐标。

  • 工具属性ABS_DISTANCE (0x19) 用于表示笔或手指悬停时离屏幕的距离。

6. 设备属性与 I/O 控制

除了事件码,该头文件还定义了设备属性,可通过 ioctl 系统调用来查询或设置输入设备的特性。

  • 设备属性 (INPUT_PROP_*):描述设备的物理特性,如 INPUT_PROP_DIRECT (直接输入设备,如触摸屏) 和 INPUT_PROP_POINTER (间接输入设备,如触摸板)。

  • 常用 ioctl 命令

    • EVIOCGVERSION:获取输入子系统的驱动版本。

    • EVIOCGID:获取设备的 bustype (总线类型,如 BUS_USB)、vendorproduct 和 version ID。

    • EVIOCGNAME(len) / EVIOCGPHYS(len):获取设备名称或物理拓扑路径。

    • EVIOCGBIT(ev, len):查询设备支持哪些事件类型。例如,EVIOCGBIT(0, EV_MAX) 返回设备支持的所有事件类型的位图。

7. 开发与调试工具

理解这些事件码后,可以使用以下工具进行验证:

  • getevent -l:在 Android 或 Linux 上运行。-l 参数会直接将 typecode 和 value 解析为我们在本文档中讨论的宏名称。例如,按下音量加键,你会看到:

    /dev/input/event4: 0001 0073 00000001  # EV_KEY (0001), KEY_VOLUMEUP (0x73=115), value 1 (按下)
    /dev/input/event4: 0000 0000 00000000  # EV_SYN (0000), SYN_REPORT (0), value 0
  • evtest:一个更强大的 Linux 命令行工具,可以详细列出设备支持的所有事件类型、code 范围,并实时打印解析后的事件信息。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐