输入事件模型、状态、同步与时间戳
1. 三元组
每个事件是:
1 | type + code + value |
UAPI struct input_event 还含 timestamp。
2. 类型
| 类型 | 语义 |
|---|---|
| EV_KEY | 键/按钮,0释放、1按下、2重复 |
| EV_REL | 相对位移 |
| EV_ABS | 绝对坐标/轴 |
| EV_SYN | 帧边界/同步 |
| EV_MSC | 扫描码等杂项 |
| EV_SW | 开关状态 |
| EV_LED/SND | 发往设备的输出 |
| EV_REP | repeat参数 |
| EV_FF | 力反馈 |
3. Core状态
input_event() 在 event_lock 下进入 input_handle_event():
- 验证 type/code;
- 对 key/switch/LED等更新 bitmap;
- 丢弃无变化 key/abs;
- REL 0通常不发送;
- ABS应用 fuzz;
- MT处理 slot;
- 决定 PASS_TO_HANDLERS、PASS_TO_DEVICE、FLUSH等 disposition。
4. 帧
driver连续 report,最后:
1 | input_sync(dev); /* EV_SYN/SYN_REPORT */ |
Core把 input_value[] 一批传给 handler。应用应按 SYN_REPORT处理原子逻辑帧,而不是把单个坐标事件当完整触摸。
5. SYN_DROPPED
evdev client buffer溢出时发送 SYN_DROPPED。应用必须忽略到下一个 SYN_REPORT之间的增量,并通过 EVIOCGKEY/ABS/SW 等重新同步当前状态。
6. Repeat
有 EV_REP 能力时 Core timer可软件重复:
REP_DELAY;REP_PERIOD;- repeat value 2。
硬件自己重复时不要与软件 repeat双重上报。
7. Keycode
scancode是硬件码,keycode是 Linux KEY_*。driver可报告 MSC_SCAN,再 EV_KEY。keymap可由 matrix/sparse helper管理,并通过 ioctl查询/修改。
8. Timestamp
driver可 input_set_timestamp() 指定采样时刻;否则 handler在分发时取时钟。evdev client可选 realtime、monotonic或 boottime clock。用户程序不要混合不同 clock计算延迟。
9. 输出事件
LED/SND/FF等由用户向 device写入:
1 | evdev write/ioctl -> input_inject_event() |
dev->event() 在 spinlock/禁中断语境,不能睡眠;需要 I2C写操作时 driver应排队 work。
10. 安全
事件 capability是 ABI合同。虚报能力会导致 libinput分类错误;漏报会令 handler不匹配。注册前应完整设置,注册后修改需按 Core锁规则。
正在加载留言…