触控笔实现指南
本文档详细介绍了连接到兼容 Windows 11 主机的触觉笔设备的协议实现。 本文档不包括关于用于在笔传感器内产生触觉响应的机械约束、电气约束或组件选择的指导。 该实施指南与笔换能器和笔数字化仪之间使用的笔协议无关,但是实施可以选择使用具有上行链路能力的笔协议,这使得笔数字化仪能够向笔换能器提供附加参数以用于调制触觉反应。
设备分类
触觉笔是 Windows 上“笔设备”类的扩展。 本实施指南是对笔实施指南的补充,重点介绍在笔传感器内实施触觉,因此触觉笔除了要满足此处包含的要求外,还必须满足笔实施指南中的要求。
设备总线连接
触觉笔应使用 Microsoft 提供的内置驱动程序通过蓝牙连接到使用 HID 的 Windows 主机。
触觉笔协议实施
需要对 HID 协议有很好的理解才能理解此处提供的信息。 有关 HID 协议的信息,请参阅以下资源:
Windows 包括一个 HID 类驱动程序和相应的 HID 启用蓝牙的微型端口驱动程序,因此不需要任何第三方微型端口驱动程序。 触觉笔设备固件只需要报告本主题中描述的使用情况。 Windows 将使用固件和它自己的 HID 驱动程序来启用设备并让 Windows 应用程序访问设备。
下面的示例报告描述符部分提供了示例描述符。
所需的顶级 HID 集合
Haptic Pen 设备应在 Windows 10 系统上使用 HID 协议,以便设备提供显示为数字化仪/触控笔的顶级集合(页面 0x0D,用法 0x20)。
笔数字化仪输入报告
笔数字化仪集合必须在报告给操作系统的输入报告中报告由换能器序列号和换能器供应商 ID 组成的触控笔标识符。 必须通过手写笔集合报告相同的手写笔标识符。 这使操作系统能够将数字化仪生成的笔输入与触控笔相关联。 可在此处找到有关笔实施指南的详细信息:笔协议实施。
传感器序列号
传感器序列号是用于与笔数字化仪通信的笔附件中使用的传感器的唯一持久标识符。 这必须是 32 位,并且由传感器供应商 ID 标识的供应商或实体定义。 如果数字化器不知道传感器序列号,要么因为笔配件不支持传输此值,或者尚未完全接收传输,数字化器应向主机报告 0。 主机不支持 Null 位置。
传感器序列号 - 第 2 部分
传感器序列号 – 第 2 部分允许将额外的 32 位指定为笔配件中使用的传感器的唯一持久标识符的一部分。 如果传感器序列号 – 第 2 部分对数字化器未知,因为笔配件不支持传输此值,或者尚未完全接收传输,数字化器应向主机报告 0。 主机不支持 Null 位置。
页面 | ID | 注释 |
---|---|---|
0xD | 0x5B | 对于依赖于唯一笔标识的功能是强制性的(见下文) |
0xD | 0x6E | 序列号的可选扩展(其他 32 位) |
传感器供应商 ID
“传感器供应商 ID”字段用于表明与笔式数字化仪通信的笔附件中使用的换能器的制造商。 这需要是一个 2 字节的 USB-IF 分配的供应商 ID,制造商或 IHV/OEM 授权为此目的而使用的 USB-IF 供应商 ID。
页面 | ID | 注释 |
---|---|---|
0xD | 0x91 | 对于依赖于唯一笔标识的功能是强制性的(见下文) |
取决于唯一笔标识的功能
必须报告 PenID 才能启用笔触感等场景(本指南中的触感功能需要)。
对于使用多支笔进行上墨的场景,它也是强制性的。 例如:
- Windows 上的白板应用支持多笔使用,每支笔都可以映射到特定的墨迹工具
- 通常,应用想要将属性或行为分配给不同的物理笔,即使数字化仪当时可能只支持屏幕上的单支笔
- 应用希望在支持的数字化仪上同时跟踪多个笔
触觉输出报告
如果笔设备支持触觉反馈,你可以通过触控笔 TLC 中包含触觉反馈集合(页面 0x0E,用法 0x01)来让系统和应用程序利用触觉反馈。 有关 HID 规范如何支持触觉反馈的更多信息,请参阅 HID 规范的触觉页面批准。
主机在输出报告中使用以下用法(通过触觉反馈收集),以允许主机向触觉笔设备发出触觉反馈事件。 如果设备选择公开触觉反馈集合,则必须使用某些用法来支持主机启动的触觉反馈。
成员 | 说明 | 页 | ID | 必需/可选 |
---|---|---|---|---|
波形列表 | 设备支持的触觉波形的有序列表 | 0x0E | 0x10 | 必需 |
持续时间列表 | 波形列表中波形持续时间的有序列表 | 0x0E | 0x11 | 必需 |
自动触发 | 波形由设备自行决定自动触发 | 0x0E | 0x20 | 必需 |
自动触发器关联控件 | 与触觉反馈相关的控件的 HID 使用 | 0x0E | 0x22 | 必需 |
强度 | 输出 - 手动触发波形的强度百分比 | 0x0E | 0x23 | 可选 |
重复计数 | 输出 - 初始播放后播放手动触发波形的次数 | 0x0E | 0x24 | 可选 |
重新触发周期 | 输出 - 重复时重新触发手动触发之前等待的持续时间 | 0x0E | 0x25 | 可选 |
波形截止时间 | 手动触发器波形在被截止之前可以播放的最长时间 | 0x0E | 0x28 | 可选 |
波形列表
波形列表用法表示支持的波形的 HID 用法的集合,使用序数排序。 预定义的触觉波形在 HID 规范中定义。 对于笔式触觉设备,这些波形可以分为两个部分,分别对应不同的场景:
- WAVEFORM_*CONTINOUS - 基于墨水的反馈,用于在用户使用钢笔、铅笔等不同工具主动上墨时模拟各种纹理。
- WAVEFORM_* - 当用户执行某些输入驱动的任务(例如将鼠标悬停在按钮上、单击禁用的按钮和成功的墨水形状识别时)提供离散的、非连续的基于交互的反馈。
笔触设备支持的完整波形列表如下:
波形 | 说明 | 页 | ID | 必需/可选 |
---|---|---|---|---|
WAVEFORM_NONE | 无操作。 不应影响正在进行的波形的播放状态 | 0x0E | 0x1001 | 必需 |
WAVEFORM_STOP | 停止播放正在进行的波形 | 0x0E | 0x1002 | 必需 |
WAVEFORM_CLICK | 创建一个简短的“点击”反馈。 触觉笔不支持应用选择的交互反馈波形时的默认回退 | 0x0E | 0x1003 | 必需 |
WAVEFORM_INKCONTINUOUS | 模拟使用物理圆珠笔进行墨迹书写的感觉。 触觉笔不支持墨迹波形时的默认回退 | 0x0E | 0x100B | 必需 |
WAVEFORM_SUCCESS | 强触觉信号,用于提醒用户操作已成功 | 0x0E | 0x1009 | 可选 |
WAVEFORM_ERROR | 强触觉信号,用于提醒用户操作失败或发生错误 | 0x0E | 0x100A | 可选 |
WAVEFORM_HOVER | 当用户使用触觉笔将鼠标悬停在交互式 UI 元素上时的触觉信号 | 0x0E | 0x1008 | 可选 |
WAVEFORM_PRESS | 当用户在增量操作中按下交互式 UI 元素时的触觉信号(请参阅“松开”) | 0x0E | 0x1006 | 可选 |
WAVEFORM_RELEASE | 用户在增量操作中松开交互式 UI 元素时的触觉信号(请参阅“按下”) | 0x0E | 0x1007 | 可选 |
WAVEFORM_PENCILCONTINUOUS | 当用户选择铅笔作为墨迹工具时的连续触觉信号 | 0x0E | 0x100C | 可选 |
WAVEFORM_MARKERCONTINUOUS | 当用户选择记号笔作为墨迹工具时的连续触觉信号 | 0x0E | 0x100D | 可选 |
WAVEFORM_CHISELMARKERCONTINUOUS | 当用户选择扁头记号笔/荧光笔作为墨迹工具时的连续触觉信号 | 0x0E | 0x100E | 可选 |
WAVEFORM_BRUSHCONTINUOUS | 当用户选择画笔作为墨迹工具时的连续触觉信号 | 0x0E | 0x100F | 可选 |
WAVEFORM_ERASERCONTINUOUS | 当用户选择橡皮擦作为墨迹工具时的连续触觉信号 | 0x0E | 0x1010 | 可选 |
WAVEFORM_SPARKLECONTINUOUS | 特殊墨迹工具(例如多色画笔)的连续触觉信号 | 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 主机实现兼容,某些用法是强制性的。
成员 | 说明 | 页 | 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 ()