自制Mac触摸屏驱动:让普通显示器支持触控

5 minutes read
macOSHardwareDriverDIY

触摸屏硬件介绍

在某宝购买了一块扩展显示屏,它支持触摸功能但仅限Windows系统,而非Mac系统。如果能让它在Mac上支持触控,相当于拥有了一台额外的iPad大小的触控设备。

触摸屏演示效果

市场上有专业解决方案如touch-base提供商业驱动,但价格昂贵,甚至超过了显示器本身的价格。

触摸屏实物图

技术原理分析

既然商业驱动可以实现触控功能,说明显示器能产生触摸信号,问题在于Mac缺少对应驱动程序来处理这些信号。显示器通过一根Type-C线连接Mac,理论上只需正确解析信号并转换为系统可识别的触控事件即可。

信号连接示意图

驱动程序开发

经过在GitHub搜索相关项目,多数方案并不完善。最终选择了osxhidtouch作为基础进行修改,因为该项目虽然不能完全解决问题,但至少能正确执行而不会报错。

驱动程序调试界面

通过查阅Apple AppKit文档,学习C++基础语法和调试技术,逐步修改了程序参数。一开始效果不理想,例如点击右侧屏幕时,左侧屏幕会有反应。

经过反复调试,我转变思路,不求兼容所有触摸屏,只针对自己的这块屏幕定制驱动,这大大降低了开发难度。最终,通过将参数写死,成功实现了基本触控功能。

驱动程序测试成功

参数调优与信号分析

通过分析触摸事件数据,我整理出了关键参数映射表:

# 触摸信号参数映射
- 0x30: X坐标信息
- 0x31: Y坐标信息
- 0x42: 按下/按起事件
  - currentValue = 1 (按下)
  - currentValue = 0 (按起)
  - cookie:
    - 26: 第1个手指
    - 27: 第1个手指
    - ...
- 0x51: 屏幕手指数量变更
  - cookie:
    - 42: 第1个手指
    - 45: 第2个手指
    - ...
  - currentValue:
    - 0: 1个手指
    - 1: 2个手指
    - 2: 3个手指
- 0x54: 多指触摸 (一个手指时不触发)
  - currentValue: (手指数量)
- 0x56: 长按事件
  - currentValue > 0: (持续的时间)
  - currentValue = 0: (长按结束)

# 手指坐标cookie映射
- 第1个手指信息:
  - 43: XCOORD
  - 44: YCOORD
- 第2个手指信息:
  - 46: YCOORD
  - 47: XCOORD
- 第3个手指信息:
  - 49: YCOORD
  - 50: XCOORD
- 第4个手指信息:
  - 52: YCOORD
  - 53: XCOORD

触摸事件流程分析

通过对原始数据的分析,确定了触摸事件的完整流程:

  1. 0x56 手指开始触摸屏幕,记录时间
  2. 0x31 反馈坐标信息 Y
  3. 0x30 反馈坐标信息 X
  4. 0x42 反馈按下事件(value=1)
  5. 0x56 保持按住状态,持续派发事件
  6. 0x42 反馈按起事件(value=0)

以下是某次点击的实际数据样本:

CLICK-FRAME1
usage: 0x56 cookie: 72 value: 2113600 raw: 1
usage: 0x31 cookie: 44 value: 8729 raw: 1
usage: 0x30 cookie: 43 value: 5766 raw: 1
usage: 0x42 cookie: 27 value: 1 raw: 2
usage: 0x56 cookie: 72 value: 2113680 raw: 1
// ...继续事件流...
usage: 0x42 cookie: 27 value: 0 raw: 2

驱动打包与开机自启

使用Xcode将程序打包为可执行文件后,需要解决开机自动启动问题。

编译后的可执行文件

创建了一个简单的启动脚本:

#!/bin/bash
MYAPP=`dirname $0`/TouchDriver
$MYAPP > /dev/null &

将此脚本添加到系统的启动项中,确保驱动在系统启动时自动运行。

开机启动项设置

成果与局限性

目前驱动运行稳定,资源占用极低,基本满足日常使用需求。主要局限是暂不支持多指操作,这需要进一步开发才能实现。

触控操作演示

On this page

Scroll to top