本文中的设备型号、硬件 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°

其中 XY 表示区域中心,而不是左上角坐标。

对应的屏幕区域边界为:

左边: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

操作顺序:

  1. 点击 Apply
  2. 测试四个边界;
  3. 测试移动方向;
  4. 测试压感和倾斜;
  5. 确认无误后点击 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 getdiagnosticsHID 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 和蓝牙使用同一个驱动。真正重要的是:

  • 两种模式都稳定;
  • 两种模式区域一致;
  • 两种模式方向一致;
  • 设置能够持久化;
  • 权限范围保持最小。

Leave a Reply

Your email address will not be published. Required fields are marked *