3.5 KiB
3.5 KiB
touch_set.c - 触摸屏坐标转换矩阵设置程序
概述
核心模块之一,负责根据配置文件和屏幕信息,自动计算并设置每个触摸屏设备的坐标转换矩阵(Coordinate Transformation Matrix),实现触摸屏与显示器的正确映射。
程序结构
数据结构
// 设备信息
typedef struct {
int device_id; // XInput设备ID
char name[256]; // 设备名称
char device_node[256]; // 设备节点路径
char vid[10]; // 供应商ID
char pid[10]; // 产品ID
char usb_path[100]; // 物理路径
int is_touchscreen; // 是否为触摸屏
float matrix[9]; // 3x3坐标转换矩阵
int matched; // 是否已匹配
} InputDeviceInfo;
// 配置项
typedef struct {
char display_name[50]; // 显示器名称
char touchscreen_name[50]; // 触摸屏名称
char vid[10]; // 供应商ID
char pid[10]; // 产品ID
char usb_path[100]; // USB路径
int matched; // 是否已匹配
} TouchConfig;
// 屏幕信息
typedef struct {
char name[50]; // 屏幕名称
int width, height; // 分辨率
int x, y; // 位置
char rotation; // 旋转: N/L/R/I
} ScreenInfo;
工作原理
整体流程
读取配置文件(/opt/ktouch/config)
↓
读取屏幕信息(/tmp/ktouch/screen.txt)
↓
计算虚拟桌面大小
↓
获取所有触摸设备(XInput + udev)
↓
多轮匹配(严格→宽松)
↓
计算坐标转换矩阵
↓
通过XInput设置矩阵
↓
保存结果到输出文件
矩阵计算原理
坐标转换矩阵将触摸屏的原始坐标映射到虚拟桌面坐标系:
正常方向(N):
| sx 0 dx |
| 0 sy dy |
| 0 0 1 |
左旋转(L):
| 0 -sx sx+dx |
| sy 0 dy |
| 0 0 1 |
右旋转(R):
| 0 sx dx |
| -sy 0 sy+dy |
| 0 0 1 |
翻转(I):
| -sx 0 sx+dx |
| 0 -sy sy+dy |
| 0 0 1 |
其中:
sx = 屏幕宽度 / 虚拟桌面宽度sy = 屏幕高度 / 虚拟桌面高度dx = 屏幕X偏移 / 虚拟桌面宽度dy = 屏幕Y偏移 / 虚拟桌面高度
设备匹配策略
第一轮(严格匹配):
- 设备名完全匹配(去除空格后比较)
- 若多个匹配,按VID:PID筛选
- 若仍多个,按USB路径筛选
第二轮及以后(宽松匹配):
- 仅按VID:PID匹配
- 若多个匹配,返回失败(-1)
关键函数
| 函数 | 功能 |
|---|---|
get_input_devices() |
通过XInput+udev获取所有触摸设备 |
read_config() |
读取触摸屏配置文件 |
read_screen_info() |
读取屏幕信息文件 |
find_matching_device() |
多策略设备匹配 |
calculate_virtual_desktop() |
计算虚拟桌面总尺寸 |
calculate_ctm() |
计算坐标转换矩阵 |
set_ctm() |
通过XInput设置矩阵属性 |
devnode_to_syspath() |
设备节点转sysfs路径 |
输入文件格式
配置文件(/opt/ktouch/config)
显示器名|触摸屏名|VID|PID|USB路径
HDMI-1|USB Touchscreen|046d|c52b|usb-0000:00:14.0-1
屏幕信息文件(/tmp/ktouch/screen.txt)
HDMI-1|1920x1080|0x0|N
DP-2|1920x1080|1920x0|N
输出文件格式
设备ID|设备名|设备节点|VID:PID|矩阵值
12345|USB Touchscreen|/dev/input/event5|046d:c52b|1.000000, 0.000000, ...
调用方式
./touch_set [输出文件路径]
依赖
- X11 + XInput2扩展
- libudev