本文档详细介绍了连接到兼容 Windows 11 主机的触觉笔设备的协议实现。 这不包括关于用于笔传感器内生成触觉响应的机械约束、电气约束或组件选择的指导。 此实现指南与笔传感器和笔数字化器之间使用的笔协议无关,但实现可以选择使用具有上行功能的笔协议,使笔数字化器能够为笔传感器提供额外的参数,以便进行触觉响应的调节。
设备类
触觉笔是 Windows 上的 Pen Device 类的扩展。 此实施指南是对笔实施指南的补充,重点在于在笔传感器中实现触觉功能。因此,触觉笔除须符合此处所述的要求外,还必须满足笔实施指南中的要求。
设备总线连接
触觉笔应使用提供的Microsoft收件箱驱动程序通过蓝牙使用 HID 连接到 Windows 主机。
触觉笔协议实现
需要充分了解 HID 协议才能理解此处提供的信息。 有关 HID 协议的信息,请参阅以下资源:
Windows 包括 HID 类驱动程序和启用 HID 蓝牙的微型端口驱动程序,因此无需任何第三方微型端口驱动程序。 触觉笔设备固件只需要报告本主题中所述的使用情况。 Windows 将使用固件及其自己的 HID 驱动程序来启用设备,并为 Windows 应用程序授予设备访问权限。
下面的示例报告描述符部分提供了示例描述符。
所需的顶级 HID 集合
触觉笔设备应在 Windows 10 系统上使用 HID 协议,以便设备提供一个显示为数字化器/触笔的顶级集合(页面 0x0D、使用情况 0x20)。
笔数字化器输入报表
笔数字化器集合必须在报告给操作系统的输入报告中报告触笔标识符,该标识符由换能器序列号和换能器供应商ID组成。 必须使用相同的触控笔标识符通过触控笔集合进行报告。 这使 OS 能够将数字化器生成的笔输入与触笔相关联。 可在此处找到笔实现指南的详细信息: 笔协议实现。
传感器序列号
换能器序列号是用于笔配件中并与笔数字化器进行通信时的唯一持久标识符。 这项要求必须是 32 位,由传感器供应商 ID 标识的供应商或实体定义。 如果数字化器不知道传感器序列号,要么因为笔配件不支持传输此值,或者尚未完全接收传输,数字化器应向主机报告 0。 主机不支持 Null 位置。
传感器序列号 - 第 2 部分
传感器序列号 – 第 2 部分允许将额外的 32 位指定为笔配件中使用的传感器的唯一持久标识符的一部分。 如果换能器序列号 – 第 2 部分对数位转换器未知,因为笔配件不支持传输此值,或者尚未完全接收传输,数位转换器应向主机报告 0。 主机不支持 Null 位置。
| 页 | ID | 注释 |
|---|---|---|
| 0xD | 0x5B | 依赖唯一笔标识的功能必须具备此特性(请参阅下文) |
| 0xD | 0x6E | 序列号的可选扩展(其他 32 位) |
换能器供应商 ID
变换器供应商 ID 是用于标识与笔数字化器通信的笔配件中使用的变换器制造商的字段。 这是一个 2 字节 USB-IF 分配的供应商 ID(制造商)或 IHV/OEM 的 ID,授权其 USB-IF 供应商 ID 用于此目的。
| 页 | ID | 注释 |
|---|---|---|
| 0xD | 0x91 | 依赖唯一笔标识的功能必须具备此特性(请参阅下文) |
依赖于唯一笔标识的功能
报告 PenID 是必须的,以启用例如笔触觉(此指南中的触觉功能所必需)的场景。
对于使用多个笔进行书写的场景,也是必要的。 例如:
- Windows 上的白板应用支持多个笔用法,其中每个笔都可以映射到特定的墨迹书写工具
- 一般情况下,想将属性或行为分配给不同物理笔的应用,哪怕数字化器在同一时间仅支持屏幕上的一支笔。
- 需要跟踪受支持数字化器上多个同时使用的笔的应用程序
触觉输出报告
如果数位笔设备支持触觉反馈,则系统和应用程序可以通过在数位笔 TLC 中包含触觉反馈集合(页面0x0E、使用情况0x01)来加以利用。 有关 HID 规范如何支持触觉反馈的更多信息,请查阅有关 HID 规格的 触觉页面 核准。
主机在输出报告中使用以下用法(通过触觉反馈收集),使主机能够向触觉笔设备发出触觉反馈事件。 如果设备选择公开触觉反馈集合,则必须使用某些用法,以允许支持主机发起的触觉反馈。
| 成员 | Description | 页 | ID | 必需/可选 |
|---|---|---|---|---|
| 波形列表 | 设备支持的触觉波形的有序列表 | 0x0E | 0x10 | 强制的 |
| 持续时间列表 | 波形列表中的波形持续时间的有序列表 | 0x0E | 0x11 | 强制的 |
| 自动触发器 | 波形在设备自由裁量权下自动触发 | 0x0E | 0x20 | 强制的 |
| 自动触发器关联控件 | 与触觉反馈相关的 HID 控件用法 | 0x0E | 0x22 | 强制的 |
| 强度 | 输出 - 手动触发器波形的强度(以百分比表示) | 0x0E | 0x23 | 可选 |
| 重复计数 | 输出 - 初始播放后播放手动触发器波形的次数 | 0x0E | 0x24 | 可选 |
| 重新触发周期 | 输出 - 在重复时重新触发手动触发器之前的等待时间 | 0x0E | 0x25 | 可选 |
| 波形截止时间 | 手动触发器波形在被中断之前可以播放的最大时间 | 0x0E | 0x28 | 可选 |
波形列表
波形列表用法表示受支持波形的 HID 用法的集合,使用序号排序。 预定义的触觉波形在 HID 规范中定义。 对于笔触觉设备,这些波形可以归类为对应于不同方案的两个段:
- WAVEFORM_*CONTINUOUS - 基于墨水的反馈,用于在用户使用不同工具(如钢笔、铅笔等)进行积极书写时模拟各种纹理。
- WAVEFORM_* - 当用户执行某些输入驱动任务(例如将鼠标悬停在按钮上、单击禁用的按钮和成功的墨迹形状识别)时,不连续的基于交互的离散反馈。
笔触觉设备支持的波形的完整列表如下:
| 波形 | Description | 页 | ID | 必需/可选 |
|---|---|---|---|---|
| WAVEFORM_NONE | No-op。 不应影响正在进行的波形的播放状态 | 0x0E | 0x1001 | 强制的 |
| 波形停止 | 停止正在进行的波形播放 | 0x0E | 0x1002 | 强制的 |
| WAVEFORM_CLICK | 创建简短的“单击”反馈。 当应用选择的交互反馈波形不受触觉笔支持时的默认回退 | 0x0E | 0x1003 | 强制的 |
| WAVEFORM_INKCONTINUOUS | 模拟用圆珠笔书写的感觉。 当触觉笔不支持墨迹书写波形时,使用默认回退选项。 | 0x0E | 0x100B | 强制的 |
| 波形成功 | 强触觉信号,提醒用户作已成功 | 0x0E | 0x1009 | 可选 |
| WAVEFORM_ERROR | 发出强触觉信号,提醒用户作失败,或发生错误 | 0x0E | 0x100A | 可选 |
| WAVEFORM_HOVER | 当用户将鼠标悬停在具有触觉笔的交互式 UI 元素上时发出触觉信号 | 0x0E | 0x1008 | 可选 |
| WAVEFORM_PRESS | 当用户在增量操作中按交互式 UI 元素时的触觉信号(请参阅发布信息) | 0x0E | 0x1006 | 可选 |
| WAVEFORM_RELEASE | 用户何时在增量作中释放交互式 UI 元素时的触觉信号(请参阅 Press) | 0x0E | 0x1007 | 可选 |
| WAVEFORM_PENCILCONTINUOUS | 当用户选择铅笔作为墨迹工具时,会有持续的触觉反馈 | 0x0E | 0x100C | 可选 |
| 波形_标记连续 | 当用户选择将标记作为墨迹工具时,将会产生连续的触觉信号。 | 0x0E | 0x100D | 可选 |
| WAVEFORM_CHISELMARKERCONTINUOUS | 当用户选择凿形/荧光笔标记作为书写工具时,生成连续的触觉信号 | 0x0E | 0x100E | 可选 |
| WAVEFORM_BRUSHCONTINUOUS | 当用户选择画笔作为墨迹书写工具时,连续的触觉信号将持续存在。 | 0x0E | 0x100F | 可选 |
| 波形擦除器(连续模式) | 选择橡皮擦作为墨迹书写工具时,会产生连续的触觉反馈信号。 | 0x0E | 0x1010 | 可选 |
| 波形_闪光连续 | 特殊墨迹工具(如多色画笔)的连续触觉信号 | 0x0E | 0x1011 | 可选 |
注释
虽然不需要,但建议还实现其他枚举波形,以提供更完整的用户体验。 特别是,强烈建议WAVEFORM_PRESS和WAVEFORM_RELEASE,因为它们提供有价值的交互反馈。
所有符合 HID 的触觉设备都需要WAVEFORM_NONE和WAVEFORM_STOP。 序号 1 和 2 隐式设置为 WAVEFORM_NONE 和 WAVEFORM_STOP。 它们不需要在波形列表或持续时间列表中声明。 波形列表按列表中每个序号的物理最小值和最大值声明支持的波形。
持续时间列表
持续时间列表用法表示波形列表中支持的波形持续时间的集合,使用序号排序。 波形持续时间的单位为毫秒,持续时间必须为任何非连续波形的正非零值。 如果波形是连续的(将播放直到主机停止或超过波形截止时间),则其持续时间定义为零。
假定WAVEFORM_NONE和WAVEFORM_STOP持续时间为零。 不需要在持续时间列表中声明它们。
强度
强度使用量表示应用于波形的最大强度百分比。 此值应介于 0 和 100% 之间。 100% 表示波形将以最大强度由设备触发,0% 表示触觉传感器未启用。
重复计数
重复计数用法表示重复波形的次数。 重复计数为零表示手动触发器波形只应播放一次(无重复)。 如果超过波形截止时间,则预计将忽略任何不完整的重复。
重新触发周期
重触发周期的使用表示设备在输出报告中重复手动触发波形前需要等待的时间,该时间根据指定的重复计数值来确定。 此值的单位为毫秒。 如果重触发周期低于所播放波形的持续时间,则应在重触发周期指示的时间段停止并重启波形。
波形截止时间
波形截止时间使用量表示设备允许在结束播放之前重复手动触发器波形的最大时间量。 这是设备的常量值,包括没有设置持续时间的连续波形,以及具有离散持续时间的波形,这些持续时间设置为重复多次。 此值的单位为毫秒。
触觉输出报告
主机在输出报告中通过以下用途向触觉笔设备发出触觉反馈事件。 某些用法是必需的,以便与 Windows 主机实现兼容。
| 成员 | Description | 页 | ID | 必需/可选 |
|---|---|---|---|---|
| 手动触发器 | 要从主机作为显式命令触发的波形 | 0x0E | 0x21 | 强制的 |
| 强度 | 手动触发器波形的强度(以百分比表示) | 0x0E | 0x23 | 强制的 |
| 重复计数 | 在初始播放后播放手动触发器波形的次数 | 0x0E | 0x24 | 可选 |
| 重新触发周期 | 在重复时重新触发手动触发器之前的等待持续时间 | 0x0E | 0x25 | 可选 |
手动触发器
手动触发器用法表示一种来自波形列表中的受支持的波形,该波形用法已被主机请求播放。 当包含除WAVEFORM_NONE以外的手动触发器的输出报告发送到设备时,设备应立即开始播放指定的波形,并应用输出报告中包含的附加属性(强度、重复计数、重置周期)。 当输出报告包含手动触发WAVEFORM_STOP时,应停止任何正在进行的波形播放。
有关 强度、重复计数和 重新触发周期 使用情况,请参阅相关输出功能报告的上一部分。
启动和停止触觉反馈
下面的流程图描述了何时应配置、清除、启动和停止笔的触觉信号。
下面介绍的各种触觉状态如下:
- 正在播放:笔正在播放触感波形
- 已暂停:笔配置为波形,但不主动播放
- 已停止:笔未配置波形,并且未主动播放任何内容
有关数字器的笔状态,请参阅 Windows 触控笔状态。
注释
当笔超出范围时,建议清除触觉配置,但并非必须。 当笔超出范围时,下图显示了退出“笔:在范围内;触觉反馈:暂停”状态的两个备选路径。
注释
主机随时可以请求播放非连续波形。 在这种情况下,笔应播放该内容,然后恢复到之前的状态。
注释
主机应仅配置连续波形。 离散/非连续波形应仅手动触发。
键盘集合(可选)
可选功能,用于通过 HID 键盘报告向主机报告尾端按钮单击。
兼容设备应通过公开给主机的 HID 蓝牙键盘设备报告对应于3个不同按钮操作的3个不同键盘快捷键组合。 下面对照表列出了动作和相应的键盘组合:
| 按钮操作 | 组合键 |
|---|---|
| 单击 | WIN+F20 |
| 双击 | WIN+F19 |
| 按住 | Win+F18 |
蓝牙按钮实现
若要实现尾端蓝牙按钮,设备将通过一个向主机公开的 HID 蓝牙 LE 键盘设备,报告对应于 3 个不同按钮操作的 3 个不同键盘组合。 下面对照表列出了动作和相应的键盘组合:
| 蓝牙按钮动作 | 用于报表的键组合 |
|---|---|
| 单击 | WIN+F20 |
| 双击 | WIN+F19 |
| 长按 | WIN+F18 |
笔存放
从 Windows 10 版本 1903 开始,Windows 支持包含兼容笔槽的设备的通知功能。 该机制依赖于硬件检测笔的移除或更换,并为一组快捷键组合生成相应的 HID 键盘报告。 若要向笔对接发出信号(笔放入存放位置),请报告 WIN+CTRL+F20,若要发出取消对接(笔从存放位置移除)信号,请报告 WIN+CTRL+F19。 这可以通过固件或驱动程序来实现。
此类解除停靠/停靠事件调出/收起 Shell 墨迹工作区菜单。 从 Windows 10 开始,版本 2004 Office 还通过使用 平台 API 对这些事件做出反应,使任何开发人员都能够扩展其应用程序,以便了解存存事件。 不支持查询扩展坞中是否存在笔,仅当应用位于前台时,才会收到删除通知并返回事件。
示例 HID 报表描述符
05,0D, // Usage Page (Digitizers)
09,20, // Usage (Stylus)
A1,01, // Collection (Application)
85,40, // Report ID (64)
95,01, // Report Count (1)
75,20, // Report Size (32)
17,00,00,00,80, // Logical Minimum (-2147483648)
27,FF,FF,FF,7F, // Logical Maximum (2147483647)
09,5B, // Transducer Serial Number
81,02, // Input (Data,Var,Abs)
75,10, // Report Size (16)
15,01, // Logical Minimum (1)
27,FF,FF,00,00, // Logical Maximum (65535)
09,91, // Transducer Vendor ID
81,02, // Input (Data,Var,Abs)
05,0E, // Usage Page (Haptics)
09,01, // Usage (0x01)
A1,02, // Collection (Logical)
85,41, // Report ID (65)
95,01, // Report Count (1)
75,08, // Report Size (8)
15,01, // Logical Minimum (1)
26,FF,00, // Logical Maximum (255)
09,24, // Usage (0x24)
B1,02, // Feature (Data,Var,Abs)
09,24, // Usage (0x24)
91,02, // Output (Data,Var,Abs)
09,23, // Usage (0x23)
B1,02, // Feature (Data,Var,Abs)
09,23, // Usage (0x23)
91,02, // Output (Data,Var,Abs)
15,01, // Logical Minimum (1)
25,12, // Logical Maximum (18)
09,20, // Usage (0x20)
B1,02, // Feature (Data,Var,Abs)
09,21, // Usage (0x21)
91,02, // Output (Data,Var,Abs)
15,00, // Logical Minimum (0)
26,FE,00, // Logical Maximum (254)
66,01,10, // Unit (SI Linear)
55,FD, // Unit Exponent (253)
35,00, // Physical Minimum (0)
46,EC,09, // Physical Maximum (2540)
09,28, // Usage (0x28)
91,02, // Output (Data,Var,Abs)
75,10, // Report Size (16)
26,D0,07, // Logical Maximum (2000)
46,D0,07, // Physical Maximum (2000)
09,25, // Usage (0x25)
91,02, // Output (Data,Var,Abs)
09,25, // Usage (0x25)
B1,02, // Feature (Data,Var,Abs)
45,00, // Physical Maximum (0)
85,42, // Report ID (66)
75,20, // Report Size (32)
17,42,00,0D,00, // Logical Minimum (852034)
27,42,00,0D,00, // Logical Maximum (852034)
09,22, // Usage (0x22)
B1,02, // Feature (Data,Var,Abs)
09,11, // Usage (0x11)
A1,02, // Collection (Logical)
05,0A, // Usage Page (Ordinal)
75,10, // Report Size (16)
95,10, // Report Count (16)
15,01, // Logical Minimum (1)
27,FF,FF,00,00, // Logical Maximum (65535)
19,03, // Usage Minimum (0x03)
29,12, // Usage Maximum (0x12)
B1,02, // Feature (Data,Var,Abs)
C0, // End Collection ()
05,0E, // Usage Page (Haptics)
09,10, // Usage (0x10)
A1,02, // Collection (Logical)
05,0A, // Usage Page (Ordinal)
16,03,10, // Logical Minimum (4099)
26,FF,2F, // Logical Maximum (12287)
19,03, // Usage Minimum (0x03)
29,12, // Usage Maximum (0x12)
B1,02, // Feature (Data,Var,Abs)
C0, // End Collection ()
C0, // End Collection ()
C0 // End Collection ()