153 lines
3.5 KiB
Markdown
153 lines
3.5 KiB
Markdown
# touch_set.c - 触摸屏坐标转换矩阵设置程序
|
|
|
|
## 概述
|
|
核心模块之一,负责根据配置文件和屏幕信息,自动计算并设置每个触摸屏设备的坐标转换矩阵(Coordinate Transformation Matrix),实现触摸屏与显示器的正确映射。
|
|
|
|
## 程序结构
|
|
|
|
### 数据结构
|
|
```c
|
|
// 设备信息
|
|
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偏移 / 虚拟桌面高度`
|
|
|
|
### 设备匹配策略
|
|
|
|
**第一轮(严格匹配)**:
|
|
1. 设备名完全匹配(去除空格后比较)
|
|
2. 若多个匹配,按VID:PID筛选
|
|
3. 若仍多个,按USB路径筛选
|
|
|
|
**第二轮及以后(宽松匹配)**:
|
|
1. 仅按VID:PID匹配
|
|
2. 若多个匹配,返回失败(-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, ...
|
|
```
|
|
|
|
## 调用方式
|
|
```bash
|
|
./touch_set [输出文件路径]
|
|
```
|
|
|
|
## 依赖
|
|
- X11 + XInput2扩展
|
|
- libudev
|