2. 触摸输入基础

在 Linux 图形栈中,触摸屏并不是一个“直接产生鼠标事件”的设备。它首先是一个输入设备,通过内核输入子系统上报原始触摸数据,再由用户空间库(如 libinput、Xorg、Wayland 合成器)解释为指针、手势或触摸事件。理解触摸屏的物理原理、坐标系统和多点触控协议,是后续调试触摸延迟、坐标偏移、手势识别异常等问题的基础。

一、触摸屏工作原理:从物理接触到位图上报

无论采用哪种技术,触摸屏的基本工作链路都可以概括为:感知接触 → 定位坐标 → 生成触摸点 → 上报事件。当手指或触控笔接触屏幕表面时,控制器检测到物理量变化(电容、电阻、光强等),计算出接触点的位置,并将一个或多个触摸点信息通过 I2C、USB、SPI 等总线发送给主控。Linux 内核中的触摸驱动将这些信息转换为 input_event,最终由 /dev/input/eventX 暴露给用户空间。

关键点在于:触摸屏上报的是“绝对坐标”和“触摸状态”,而不是鼠标那样的“相对位移”。因此,驱动必须正确设置 ABS_X、ABS_Y、ABS_MT_POSITION_X、ABS_MT_POSITION_Y 等绝对轴参数,并声明支持的多点触控协议类型。

二、电容、电阻与红外技术对比

不同触摸技术决定了设备的手感、精度、环境适应性和驱动行为。电容屏依赖人体电流感应,支持多点触控,透光率高,是目前手机和平板的主流;电阻屏通过压力使两层导电层接触,成本低、可用任何物体触控,但通常只支持单点,且透光率较差;红外屏在屏幕边缘布置红外发射和接收管,通过遮挡判断坐标,适合大尺寸和户外场景,但容易受强光和灰尘影响。

技术类型 检测原理 多点支持 典型场景 Linux 驱动关注点
电容式 人体电容耦合改变电极电容 支持多点 手机、平板、笔记本触控板 MT 协议 B、坐标范围、压力/面积上报
电阻式 压力使上下导电层接触 通常单点 工业控制、旧式 PDA ABS_X/Y、去抖、校准
红外式 红外光束被遮挡 可支持多点 大屏广告机、教育白板 坐标映射、遮挡补偿、环境光干扰

三、坐标系统:屏幕坐标、设备坐标与校准

触摸屏驱动上报的坐标是“设备坐标”,其范围由 ABS_X 的 min 和 max 决定,通常与屏幕物理分辨率不一致。例如,一块 800×480 的电阻屏,其 ABS_X 范围可能是 0~4095,ABS_Y 范围可能是 0~4095。用户空间需要根据 input_absinfo 中的范围,将设备坐标线性映射到屏幕像素坐标。

如果映射关系不正确,就会出现“点左边、光标在右边”或“触摸区域偏移”的现象。对于电阻屏,还需要进行四点或五点校准,计算仿射变换矩阵,以补偿安装角度和边缘非线性。电容屏虽然出厂时已校准,但在更换屏幕或修改分辨率后,仍可能需要重新配置 libinput 的校准矩阵。

# 查看触摸设备的绝对轴范围
cat /proc/bus/input/devices
# 或使用 evtest 查看 ABS_X / ABS_Y 的 min/max
evtest /dev/input/event2

# 典型输出片段
Event code 0 (ABS_X): value 0, min 0, max 4095, fuzz 0, flat 0, resolution 0
Event code 1 (ABS_Y): value 0, min 0, max 4095, fuzz 0, flat 0, resolution 0

四、多点触控协议:Type A 与 Type B

Linux 内核定义了两种多点触控上报协议:Type A 和 Type B。Type A 使用 ABS_MT_POSITION_X/Y 和 SYN_MT_REPORT 逐个上报触摸点,每个 SYN 周期内所有点一起提交,适合触摸点数量少、变化不频繁的设备。Type B 使用 ABS_MT_SLOT 为每个触摸点分配一个槽位,通过 ABS_MT_TRACKING_ID 跟踪触摸点的生命周期,更适合现代电容屏,能高效处理大量并发触摸点。

在 Type B 中,每个槽位代表一个触摸点,TRACKING_ID 为 -1 表示该槽位释放。用户空间库通过跟踪 ID 判断手指的按下、移动和抬起,从而识别滑动、捏合、旋转等手势。如果驱动错误地复用槽位或未正确释放 TRACKING_ID,就会导致“幽灵触摸”或手势中断。

核心记忆点:Type A 是“报告所有点”,Type B 是“按槽位管理点”。现代触摸屏几乎都使用 Type B,调试时优先检查 ABS_MT_SLOT 和 ABS_MT_TRACKING_ID 是否正常变化。

五、常见术语与调试场景

在 Linux 触摸调试中,以下术语频繁出现:

  • MT:Multi-Touch,多点触控。
  • Slot:Type B 协议中的触摸点槽位。
  • Tracking ID:触摸点生命周期标识,-1 表示释放。
  • ABS_MT_POSITION_X/Y:触摸点绝对坐标。
  • ABS_MT_PRESSURE:触摸压力,电容屏常用“面积”代替。
  • SYN_REPORT:一次完整事件包的结束标记。
  • libinput:Wayland 和 Xorg 常用的输入处理库。
  • evtest:查看输入设备原始事件的工具。

一个典型排障场景是:触摸屏能点击,但滑动不流畅。使用 evtest 观察发现,ABS_MT_TRACKING_ID 在手指未抬起时频繁变为 -1,说明驱动错误地释放了触摸点。此时应检查驱动中触摸点跟踪逻辑,确认 TRACKING_ID 只在真正抬起时置为 -1。另一个常见问题是坐标偏移,通常通过 libinput 的校准矩阵或 xinput 的 Coordinate Transformation Matrix 修正。

调试建议:先用 evtest 确认内核上报的坐标范围和触摸点数量是否正确,再检查用户空间库的映射和校准。不要一上来就修改应用层代码,否则容易掩盖底层驱动问题。

触摸屏输入链路与多点触控协议 物理触摸层 电容 / 电阻 / 红外感应 触摸控制器计算坐标 I2C/USB/SPI Linux 内核输入子系统 触摸驱动 input_event /dev/input/eventX evdev 用户空间处理 libinput / Xorg / Wayland 手势识别 / 坐标映射 Type A 协议 逐个上报 ABS_MT_POSITION_X/Y SYN_MT_REPORT 提交所有点 适合触摸点少、变化不频繁 Type B 协议 ABS_MT_SLOT 分配触摸点槽位 ABS_MT_TRACKING_ID 跟踪生命周期 现代电容屏主流,支持多指手势

总结来看,触摸输入基础的核心在于理解“物理感知—内核上报—用户空间解释”这条链路。电容、电阻、红外技术决定了硬件行为,坐标系统决定了映射关系,而 Type A/Type B 协议决定了多点触控的数据组织方式。掌握这些内容后,再使用 evtest、libinput debug-events 等工具观察实际事件流,就能快速定位大多数触摸异常问题。