本文中的设备型号、硬件 ID、主机名、用户目录、映射参数、日志时间和规则文件名均为虚构示例,仅用于展示排查方法与配置结构,不可直接复制到真实环境。
一、环境与目标
测试环境如下:
操作系统:Arch Linux
桌面环境:KDE Plasma Wayland
主机名:orion
绘图板:Northstar Pen M NP-620BT
USB ID:1A2B:3C40
蓝牙 HID ID:1A2B:3C41
逻辑分辨率:2304 × 1296
目标是让绘图板在两种连接方式下保持一致的行为:
- USB 有线连接;
- 蓝牙无线连接;
- 映射到屏幕左侧的指定区域;
- 数位板按 270° 方向摆放;
- 保留压感、倾斜和笔侧键;
- 重新连接及系统重启后自动恢复。
期望映射参数如下:
显示区域:
Width: 864 px
Height: 1188 px
X: 528 px
Y: 630 px
数位板区域:
Width: 210 mm
Height: 132 mm
X: 105 mm
Y: 66 mm
Rotation: 270°
其中 X 和 Y 表示区域中心,而不是左上角坐标。
对应的屏幕区域边界为:
左边:96 px
上边:36 px
右边:960 px
下边:1224 px
二、USB 模式:使用 OpenTabletDriver
1. 启动用户级服务
安装驱动后启用用户服务:
systemctl --user enable --now opentabletdriver.service
确认状态:
systemctl --user status opentabletdriver.service --no-pager
插入 USB 后检查日志:
journalctl --user \
-u opentabletdriver.service \
--since '-3 minutes' \
--no-pager |
grep -E \
'Found tablet|Initializing device|Display area|Tablet area|Pressure|Tilt'
成功识别时可能出现:
[Device:Debug] Initializing device 'Northstar Pen M'
[Detect:Info] Found tablet 'Northstar NP-620BT'
[Evdev:Debug] Successfully initialized virtual pressure sensitive tablet
[Northstar NP-620BT:Info] Pressure: Enabled
[Northstar NP-620BT:Info] Tilt: Enabled
还应确认原生内核驱动没有同时接管:
lsmod | grep '^wacom\b' || echo '原生 wacom 模块未加载'
如果第三方驱动与原生驱动同时处理同一设备,可能出现:
- 双重输入;
- 光标抖动;
- 配置不生效;
- 设备被占用;
- 插拔时界面异常。
2. 配置 USB 映射
启动图形界面:
otd-gui
在 Display 区域填写:
Width: 864
Height: 1188
X: 528
Y: 630
在 Tablet 区域填写:
Width: 210
Height: 132
X: 105
Y: 66
Rotation: 270
操作顺序:
- 点击
Apply; - 测试四个边界;
- 测试移动方向;
- 测试压感和倾斜;
- 确认无误后点击
Save。
保存后,USB 再次插入时应自动恢复该配置。
三、断开 USB 时图形界面崩溃
某些 OpenTabletDriver GTK 界面在设备断开时,可能因为设备列表刷新而异常退出。
典型提示类似:
OpenTabletDriver.UX.Gtk has encountered a fatal error and was closed.
这不一定意味着后台 daemon 也已停止。
检查服务:
systemctl --user is-active opentabletdriver.service
检查进程:
pgrep -a -f \
'OpenTabletDriver.Daemon|OpenTabletDriver.UX.Gtk|otd-daemon'
如果 daemon 仍为 active,通常只是 GUI 崩溃,重新启动界面即可:
otd-gui
如果服务异常:
systemctl --user restart opentabletdriver.service
四、蓝牙模式初始表现
断开 USB 并连接蓝牙:
bluetoothctl connect AA:BB:CC:DD:EE:FF
确认:
bluetoothctl info AA:BB:CC:DD:EE:FF |
grep -E 'Name:|Connected:|Trusted:|Modalias:'
示例输出:
Name: Northstar Pen M
Trusted: yes
Connected: yes
Modalias: usb:v1A2Bp3C41d0001
蓝牙连接后,手写笔可以立即移动光标和书写,但默认映射到整个屏幕。
这说明:
- 蓝牙连接本身正常;
- 内核已经识别设备;
- 系统创建了输入节点;
- 当前输入由 Linux 原生输入栈处理;
- 第三方驱动尚未接管蓝牙设备。
五、确认蓝牙输入路径
查看内核日志:
journalctl -b -k \
--since '-5 minutes' \
--no-pager |
grep -iE \
'1a2b|3c41|northstar|uhid|hid-generic|bluetooth'
示例:
input: Northstar Pen M as /devices/virtual/misc/uhid/0005:1A2B:3C41.0007/input/input31
input: Northstar Pen M as /devices/virtual/misc/uhid/0005:1A2B:3C41.0007/input/input32
hid-generic 0005:1A2B:3C41.0007: input,hidraw5: BLUETOOTH HID Device
蓝牙路径为:
绘图板
→ Bluetooth HID
→ uhid
→ hid-generic
→ evdev
→ libinput
→ KDE Wayland
这条路径和 USB 模式下的 OpenTabletDriver 完全不同。
六、检查 hidraw 权限
蓝牙设备可能生成:
/dev/hidraw5
但默认权限可能是:
crw------- root root
普通用户无法访问时,可以通过 udev 为目标设备添加会话级 ACL。
创建示例规则:
/etc/udev/rules.d/70-northstar-pen-bluetooth-access.rules
内容:
# Example only: fictional device IDs
SUBSYSTEM=="hidraw", \
KERNEL=="hidraw*", \
KERNELS=="0005:1A2B:3C41.*", \
TAG+="uaccess", \
TAG+="udev-acl"
加载规则:
sudo udevadm control --reload-rules
重新连接蓝牙后检查:
getfacl /dev/hidraw5
预期包含:
user:example:rw-
这种做法只授权当前图形会话访问目标设备,比把普通用户加入整个 input 组更安全。
七、确认 OpenTabletDriver 是否枚举蓝牙设备
即使:
- 蓝牙连接正常;
- hidraw 节点存在;
- 当前用户拥有读写权限;
- HID 报告长度符合配置;
- USB ID 和蓝牙 ID 都已写入设备配置;
OpenTabletDriver 仍可能无法识别蓝牙设备。
检查:
otd getdiagnostics > \
/home/example/workspace/tablet-audit/otd-diagnostics.json
搜索目标设备:
grep -n -C 10 -Ei \
'Northstar|1A2B|3C41|hidraw5|0005:1A2B:3C41' \
/home/example/workspace/tablet-audit/otd-diagnostics.json
如果 Linux 中存在:
/devices/virtual/misc/uhid/0005:1A2B:3C41...
但 otd getdiagnostics 的 HID Devices 列表中完全没有该设备,则说明:
OpenTabletDriver 使用的 HID 枚举后端没有列出这个蓝牙 uhid 设备。
此时继续修改:
- 用户组;
- 文件权限;
- 报告长度;
- 设备 JSON;
- GUI 参数;
都无法解决问题,因为设备甚至没有进入 OTD 的候选设备列表。
八、蓝牙模式改用 libinput 校准矩阵
蓝牙模式既然已经由原生输入栈正常提供:
- 绝对坐标;
- 压感;
- 倾斜;
- 笔尖;
- 笔侧键;
那么只需要补充局部映射和旋转。
libinput 可以通过校准矩阵完成:
- 缩放;
- 平移;
- 坐标轴交换;
- 水平翻转;
- 垂直翻转;
- 90°、180°、270° 旋转。
目标参数为:
逻辑屏幕:2304 × 1296
目标区域:
宽度:864
高度:1188
左边:96
上边:36
等效 OpenTabletDriver Rotation:270°
归一化参数为:
水平缩放:864 / 2304 = 0.375
垂直缩放:1188 / 1296 = 0.9166667
左侧偏移:96 / 2304 = 0.0416667
顶部偏移:36 / 1296 = 0.0277778
对应的校准矩阵为:
0 -0.375 0.4166667
0.9166667 0 0.0277778
写成 udev 属性:
0 -0.375 0.4166667 0.9166667 0 0.0277778
九、创建蓝牙映射规则
创建:
/etc/udev/rules.d/70-northstar-pen-bluetooth-map.rules
内容:
# Fictional example configuration
# Device: Northstar Pen M NP-620BT
# Logical display: 2304x1296
# Target area: 864x1188
# Target center: 528,630
# Equivalent tablet rotation: 270 degrees
ACTION!="remove", \
SUBSYSTEM=="input", \
KERNEL=="event*", \
KERNELS=="0005:1A2B:3C41.*", \
ENV{ID_INPUT_TABLET}=="1", \
ENV{LIBINPUT_CALIBRATION_MATRIX}="0 -0.375 0.4166667 0.9166667 0 0.0277778"
设置权限:
sudo chmod 0644 \
/etc/udev/rules.d/70-northstar-pen-bluetooth-map.rules
加载:
sudo udevadm control --reload-rules
重新连接设备:
bluetoothctl disconnect AA:BB:CC:DD:EE:FF
sleep 2
bluetoothctl connect AA:BB:CC:DD:EE:FF
十、验证规则
检查 input 节点:
for event in \
/sys/bus/hid/devices/0005:1A2B:3C41.*/input/input*/event*
do
[ -e "$event" ] || continue
node="/dev/input/$(basename "$event")"
echo "===== $node ====="
udevadm info \
--query=property \
--name="$node" |
grep -E \
'ID_INPUT_TABLET=|LIBINPUT_CALIBRATION_MATRIX='
done
预期:
ID_INPUT_TABLET=1
LIBINPUT_CALIBRATION_MATRIX=0 -0.375 0.4166667 0.9166667 0 0.0277778
实际测试应确认:
- 笔向右移动,光标向右;
- 笔向上移动,光标向上;
- 数位板四角对应目标区域四角;
- 映射范围不再覆盖全屏;
- 方向与 USB 模式的 270° 设置一致;
- 压感和倾斜正常;
- 断开再连接后自动恢复。
十一、为什么蓝牙表现仍然很好
绘图板不会通过蓝牙传输图像,只会发送少量 HID 数据,例如:
X 坐标
Y 坐标
压力值
倾斜角度
笔尖状态
笔侧键状态
每份输入报告通常只有十几到几十字节。
即使采样率较高,整体数据量也很小,远低于蓝牙链路能够承受的带宽。
而且蓝牙模式直接使用:
hid-generic
→ evdev
→ libinput
→ Wayland compositor
中间没有复杂图形处理。
校准矩阵也只是简单的二维线性运算:
缩放
平移
旋转
坐标交换
其计算开销几乎可以忽略。
因此,在蓝牙信号稳定、距离较近且无线干扰不严重时,实际书写体验可以非常接近 USB 模式。
十二、最终架构
USB 有线模式
绘图板
→ USB HID
→ OpenTabletDriver
→ 虚拟压感数位板
→ KDE Wayland
由 OpenTabletDriver 保存:
显示区域
数位板区域
270° 旋转
压感
倾斜
笔侧键
蓝牙无线模式
绘图板
→ Bluetooth HID
→ uhid
→ hid-generic
→ evdev
→ libinput
→ KDE Wayland
由 udev 和 libinput 保存:
显示区域
缩放
平移
270° 等效旋转
两种模式底层实现不同,但最终可以获得相同的:
- 屏幕区域;
- 书写比例;
- 旋转方向;
- 压感体验;
- 自动恢复行为。
十三、经验总结
这类问题不能只问“设备是否被识别”,而要区分四个层次:
1. 蓝牙或 USB 是否建立连接
2. Linux 是否创建 HID 和 input 节点
3. 当前究竟由哪个驱动处理
4. 映射参数是否正确
能够书写但映射全屏,通常说明:
设备本身正常
原生输入栈正常
缺少的是坐标校准
第三方驱动显示“未检测到设备”,也不一定是权限问题。应先检查其内部 HID 设备列表。
如果设备根本没有进入第三方驱动的枚举列表,就不应继续扩大权限或反复修改配置,而应考虑保留原生驱动,并用 libinput 完成映射。
最终方案并不要求 USB 和蓝牙使用同一个驱动。真正重要的是:
- 两种模式都稳定;
- 两种模式区域一致;
- 两种模式方向一致;
- 设置能够持久化;
- 权限范围保持最小。