觸覺畫筆實作指南

本文件詳細說明了連接相容 Windows 11 主機的觸覺筆裝置的協定實作。 這不包括對機械約束、電氣限制或元件選擇的指導,以產生筆型換能器內的觸覺響應。 此實作指引與筆型換能器與筆數位化器之間的筆型協定無關,但實作者可選擇使用具備上行功能的筆型協定,使筆數位化器能為筆型換能器提供額外參數,以調節觸覺反應。

裝置類別

觸覺筆是 Windows 上筆裝置類別的擴充。 本實作指南對應於筆型實作指南,重點在於實現在筆型換能器中的觸覺功能。此外,觸覺筆除了必須符合本書中的要求之外,還須符合筆型實作指南的要求。

裝置匯流排連線

觸覺筆將使用 Microsoft 提供的收件匣驅動程式,透過藍牙連接 HID 與 Windows 主機。

觸覺筆協定實作

需要充分了解 HID 協議才能理解此處提供的信息。 如需 HID 通訊協定的相關資訊,請參閱下列資源:

Windows 內建 HID 類別驅動程式及相應的 HID 藍牙迷你埠驅動程式,因此不需要第三方迷你埠驅動程式。 觸覺筆裝置韌體只需回報本主題中描述的使用情況。 Windows 會使用韌體和自家的 HID 驅動程式來啟用裝置,讓 Windows 應用程式存取裝置。

範例描述元在下方的範例報表描述元區段中提供。

必要的高層 HID 集合

觸覺筆所需的頂層 HID 集合

觸覺筆裝置應在 Windows 11 系統上使用 HID 協定,使裝置提供頂層集合,呈現為數位化儀/觸控筆(頁碼 0x0D,使用情況 0x20)。

筆數位化器輸入報告

筆數位化器集合必須在提交給操作系統的輸入報告中回報由換能器序號與換能器廠商 ID 組成的觸控筆識別碼。 必須在觸控筆集合中回報相同的觸控筆識別碼。 這使得作業系統能夠將數位化器產生的筆輸入與觸控筆進行關聯。 關於筆實作指南的詳細資訊可在此找到: 筆協定實作

換能器序號

換能器序號是用於筆型配件與筆數位化器通訊時,唯一且持久的識別碼。 這需要 32 位元,並由由換能器廠商 ID 所識別的廠商或實體定義。 若數位化器不知道換能器序號,無論是因為筆型配件不支援傳送此數值,或是傳輸尚未完整接收,數位化器應向主機回報 0。 空位置不被主機支援。

換能器序號 – 第二部分

換能器序號 – 第二部分允許額外指定 32 位元作為筆式配件中換能器唯一持久識別碼的一部分。 如果數位化器不知道 Transducer 序號 – 第二部分,可能是因為筆配件不支援傳輸此數值,或者是傳輸尚未完整被接收,那麼數位化器應向主機回報 0。 空位置不被主機支援。

頁面 ID 註釋
0xD 0x5B 必須為依賴唯一筆識別的功能(見下文)提供支持
0xD 0x6E 可選擇將序號額外延長32位元

換能器廠商識別碼

換能器廠商識別碼是用於標示使用於筆型配件中的換能器製造商的欄位,該配件與筆數位化器進行通訊。 此 ID 必須是由 USB-IF 指定的 2 位元組廠商 ID,可以是製造商的 ID,或者是 IHV/OEM 授權用於此目的的 USB-IF 廠商 ID。

頁面 ID 註釋
0xD 0x91 必須為依賴唯一筆識別的功能(見下文)提供支持

唯一筆識別所依賴的功能

啟用各種功能(例如筆觸回饋)需要強制性報告 PenID(觸覺功能的必需條件在本指南中說明)。

對於使用多支筆進行描線的情境,這也是必須的。 例如:

  • Windows 上的 Whiteboard 應用程式支援多支筆使用,每支筆可以對應到特定的墨線工具
  • 一般來說,應用程式通常會想要為不同的實體筆指派屬性或行為,即便數位化器可能一次只能在螢幕上支援一支筆。
  • 想要在支援的數位板上追蹤多支觸控筆的應用程式

觸覺特徵報告

若筆裝置支援觸覺回饋,系統與應用程式可透過在觸控筆 TLC 中加入觸覺反饋集合(頁 0x0E、使用0x01)來利用此功能。 欲了解更多關於 HID 規範如何支援觸覺回饋的資訊,請參閱 HID 規範的觸 覺頁面 確認。

主機在GET_FEATURE報告中(透過觸覺回饋收集)使用以下用法來查詢筆裝置的觸覺功能,特別是支援的波形與持續時間。 若裝置選擇暴露觸覺回饋功能集,則此功能報告為必須,以便主機能透過適當的輸出報告偵測在啟動觸覺回饋時可能使用的能力。

會員 Description 頁面 ID 強制/選擇性
波形清單 裝置支援的有序觸覺波形列表 0x0E 0x10 強制的
持續時間列表 波形列表中波形持續時間的排序列表 0x0E 0x11 強制的

波形清單

波形清單使用代表的是一組所支援的HID用途之波形,並根據序數順序排列。 預先定義的觸覺波形在 HID 規範中有所定義。 對於筆式觸覺裝置,這些波形可分為兩個對應不同情境的段:

  • 連續式 - 基於墨水的反饋,用於模擬使用者在使用筆、鉛筆等不同工具進行描墨時的各種紋理。
  • 離散式(Discrete) -當使用者執行某些輸入驅動任務(如滑鼠移至按鈕、點擊停用按鈕及成功辨識墨水形狀)時,提供離散且非連續的互動回饋。

以下為筆式觸覺裝置所支援的完整波形清單:

波形 Description 頁面 ID 強制/選擇性
沒有 無操作。 不應影響正在進行的波形的播放狀態 0x0E 0x1001 強制的
停止 停止播放正在進行的波形 0x0E 0x1002 強制的
Click 產生一個短促的「點擊」回饋。 當應用程式選擇的互動回饋波形無法受到觸感筆支援時,啟動預設回退機制 0x0E 0x1003 強制的
墨水連續 模擬用實體原子筆描墨的手感。 預設的備援選項,當觸覺筆不支援墨線波形時 0x0E 0x100B 強制的
成功 一個向上的圖案,確認動作已完成 0x0E 0x1009 請參閱下方
錯誤 下降的模式表示行動失敗 0x0E 0x100A 請參閱下方
盤旋 當使用者用觸覺筆將滑鼠移到互動式 UI 元素上時,會產生觸覺訊號 0x0E 0x1008 可選
代表按下按鈕的脈衝 0x0E 0x1006 請參閱下方
版本 代表按鈕釋放的脈衝 0x0E 0x1007 請參閱下方
軟脈衝表示達到邊界或極限 0x0E 0x1012 可選
Align 當物體卡在對準導軌上時,會發出銳利的脈衝 0x0E 0x1013 可選
Step 對於像步驟或數值移動這樣的離散變化,則有穩定的脈衝。 0x0E 0x1014 可選
成長 傳達運動、轉換或智慧系統活動的動態脈衝 0x0E 0x1015 可選
鉛筆不間斷 使用者選擇鉛筆作為描線工具時,會持續提供觸覺反饋 0x0E 0x100C 可選
持續標記 使用者選擇麥克筆作為描線工具時,會有持續的觸覺回饋。 0x0E 0x100D 可選
ChiselMarkerContinuous 當使用者選擇鑿子筆或螢光筆作為描線工具時,會有持續的觸覺訊號 0x0E 0x100E 可選
刷子連續 當使用者選擇筆刷作為墨跡工具時,會有持續的觸覺訊號 0x0E 0x100F 可選
EraserContinuous 使用者在墨線工具中選擇橡皮擦時,會持續有震動反饋。 0x0E 0x1010 可選
閃耀持續 針對特殊墨水工具(如多色畫筆)的連續觸覺訊號 0x0E 0x1011 可選

備註

雖然非強制,但鼓勵也實作其他列舉的波形,以提供更完整的使用者體驗。

所有符合HID標準的觸覺裝置都必須使用 NoneStop 。 序數 1 和 2 隱含地設為 NoneStop。 它們不需要在波形清單或持續時間清單中宣告。 波形列表與持續時間清單根據其序數使用範圍(使用/邏輯最小值與最大值)及每個序數回傳的值宣告支援波形,對於不支援的序數則使用 「None 」。

按壓釋放波形為可選,但若支援其中一種,另一項也必須支援。 同樣適用於成功錯誤

持續時間列表

時值清單的使用代表波形列表中所支援波形的時長集合,並以序數排序。 波形持續時間的單位為毫秒,且對任何非連續波形,持續時間必須是正且非零的值。 若波形為連續(會播放直到主持人停止或波形截止時間超過),則其持續時間定義為零。

假設 NoneStop 的持續時間為零。 它們不需要在期限清單中申報。

觸覺輸出報告

主機在輸出報告中使用以下用法向觸覺筆裝置發出觸覺回饋事件。 某些使用方式是為了與 Windows 主機實作相容而必須。

會員 Description 頁面 ID 強制/選擇性
手動觸發 由主機的明確命令觸發的波形 0x0E 0x21 強制的
強度 輸出 - 手動觸發波形的強度百分比 0x0E 0x23 可選
重複計數 輸出 - 初始播放後手動觸發波形的播放次數 0x0E 0x24 可選
重新觸發期間 輸出 - 重複時,在重新觸發手動觸發之前的等待時間長度 0x0E 0x25 可選
波形截止時刻 手動觸發波形在被切斷前,最多可播放的時間 0x0E 0x28 可選

手動觸發

手動觸發的使用並不會直接攜帶波形使用ID。 取而代之的是,其數值是裝置擴展波形表中的 序數 。 序數 1 保留給強制性的 None (no-op)波形,序數 2 保留給 停止 波形,序數 3 及以上則對應裝置波形清單/持續時間清單中的條目(參見波形列表/持續時間清單機制),其中序數 3 對應列表的第一條目,序數 4 對應第二條目。 等等。 主機可能會傳送隱含的序數 12,對於序數 3 及以上,只會傳送與裝置宣告支援的條目對應的值。

當包含手動觸發且序數解析為 離散 波形的輸出報告送達裝置時,裝置應立即開始播放指定波形,並包含輸出報告中包含的額外屬性(強度、重複次數、重觸發週期)。 若手動觸發序數解析為 連續 波形,播放應由裝置自行決定(例如當觸控筆與顯示器接觸時)。

備註

此要求與 HID 規範有所不同——通常,所有透過手動觸發器傳送的波形應立即播放。 然而,Windows 的觸覺筆主機實作並未實作自動觸發(Auto Trigger)支援,因此裝置必須區分離散波形與連續波形。

當輸出報告包含一個手動觸發器,其序數解析為 停止 波形(序數2)時,任何正在進行的波形播放都應停止。 當輸出報告包含手動觸發器,其序數解析為強制性的 None (no-op) 波形(序數 1)時,裝置不得啟動任何新波形,也不得改變任何正在播放的波形狀態;報告應視為觸覺輸出的無操作。

強度

強度使用表示應用於波形的最大強度百分比。 這個數值應該在0到100%之間變化。 100% 表示裝置會以最大強度觸發波形,0% 表示觸覺換能器未啟用。

重複計數

重複計數的使用代表重複一個波形的次數。 重複計數為零表示手動觸發波形只能播放一次(不得重複)。 若波形截止時間已超過,預期任何不完整的重複將被忽略。

重新觸發期間

重觸發週期用於表示裝置在輸出報告中根據重複次數指定的值,在再次手動觸發波形之前需等待的時間。 此數值的單位為毫秒。 如果重觸發週期短於播放波形的持續時間,則應在重觸發週期所指示的時間點停止並重新啟動波形。

波形截止時刻

波形截止時間使用代表裝置允許手動觸發波形重複的最大時間,直到結束播放。 這是裝置的常數值,包含無固定時長的連續波形,以及設定為多次重複且具有離散波長的波形。 此數值的單位為毫秒。

啟動與停止觸覺

下方流程圖說明筆觸覺訊號應何時設定、清除、啟動與停止。

以下描述的各種觸覺狀態如下:

  • 播放中:筆正在播放觸覺波形
  • 暫停:筆已設定波形,但未積極播放
  • 停止:筆沒有設定波形,也沒有在積極播放任何東西

關於數位化儀的筆狀態,請參考Windows 的筆狀態

備註

當觸控筆超出範圍時,建議但不是必須,先清除觸覺設定。 在下方的圖表中,當筆超出範圍時,會透過「筆:在範圍內;觸覺:暫停」這個狀態的兩條替代路徑來傳達。

備註

主持人隨時可請求播放非連續波形。 在這種情況下,筆應該播放它,然後回到之前的狀態。

備註

主機只能設定連續波形。 離散/非連續波形只能手動觸發。

觸覺筆狀態圖

鍵盤收藏(選配)

可選擇的功能,能夠通過 HID 鍵盤報告將尾端按鈕點擊情況傳送給主機。

為了實作尾端藍牙按鈕,裝置會透過暴露給主機的 HID 藍牙 LE 鍵盤裝置,回報三種不同的鍵盤組合,對應三種不同的按鍵操作。 以下列出了操作方式及相應的鍵盤組合:

藍牙按鈕動作 要報告的鍵組合
單擊 WIN+F20
按兩下 WIN+F19
按住 WIN+F18

筆插槽

從 Windows 10 版本 1903 開始,Windows 支援對於具有相容筆收納設計的裝置發送通知。 此機制依賴於硬體偵測筆的移除或放回,並針對一對快捷鍵組合產生對應的 HID 鍵盤報告。 若要指示停靠(筆已置於存放區),則回報 WIN+CTRL+F20;若要指示脫離停靠(筆已自存放區取出),則回報 WIN+CTRL+F19。 這可以透過韌體或驅動程式來實現。

這些卸載/停靠事件會顯示或關閉 Shell 墨水工作區選單。 從 Windows 10 開始,2004 版 Office 也會透過 platform API來回應這些事件,讓任何開發者都能擴展應用程式以提升儲存事件的感知。 沒有支援查詢筆是否存在於底座,只有當應用程式在前景時,才會收到移除與返回事件的通知。

範例 HID 報告描述符

下列描述元支援所有必要和選擇性用法。 它宣稱支援十七個波形列表條目(不含隱含的波形 1()和 2(停止),共十九種波形),最長的離散波形持續時間為 50毫秒。 連續波形的持續時間為零。

所有邏輯範圍都應根據裝置支援進行更新。 若要支援不同數量的波形:

  • 必須更新「手動觸發」使用量的邏輯範圍
  • 必須更新波形清單和持續時間清單的使用範圍和報告計數

若要支援不同的最形長度,必須更新下列邏輯範圍:

  • 重新觸發週期(輸出)
  • 波形截止時間(輸出)
  • 持續時間清單(功能)
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 (Simple Haptic Controller)
A1,02,                      //   Collection (Logical)
85,41,                      //     Report ID (65)
09,10,                      //     Usage (Waveform List)
A1,02,                      //     Collection (Logical)
05,0A,                      //       Usage Page (Ordinal)
19,03,                      //       Usage Minimum (0x03)
29,13,                      //       Usage Maximum (0x13)
16,01,10,                   //       Logical Minimum (4097)
26,FF,2F,                   //       Logical Maximum (12287)
95,11,                      //       Report Count (17)
75,10,                      //       Report Size (16)
B1,02,                      //       Feature (Data,Var,Abs)
C0,                         //     End Collection ()
05,0E,                      //     Usage Page (Haptics)
09,11,                      //     Usage (Duration List)
A1,02,                      //     Collection (Logical)
05,0A,                      //       Usage Page (Ordinal)
19,03,                      //       Usage Minimum (0x03)
29,13,                      //       Usage Maximum (0x13)
35,00,                      //       Physical Minimum (0)
45,32,                      //       Physical Maximum (50)
66,01,10,                   //       Unit (SiLinear, Seconds:1)
55,0D,                      //       Unit Exponent (-3)
15,00,                      //       Logical Minimum (0)
25,32,                      //       Logical Maximum (50)
95,11,                      //       Report Count (17)
75,08,                      //       Report Size (8)
B1,02,                      //       Feature (Data,Var,Abs)
C0,                         //     End Collection ()
85,42,                      //     Report ID (66)
95,01,                      //     Report Count (1)
75,08,                      //     Report Size (8)
35,00,                      //     Physical Minimum (0)
45,00,                      //     Physical Maximum (0)
65,00,                      //     Unit (None)
55,00,                      //     Unit Exponent (0)
15,01,                      //     Logical Minimum (1)
25,13,                      //     Logical Maximum (19)
09,21,                      //     Usage (Manual Trigger)
91,02,                      //     Output (Data,Var,Abs)
15,00,                      //     Logical Minimum (0)
26,64,00,                   //     Logical Maximum (100)
09,23,                      //     Usage (Intensity)
91,02,                      //     Output (Data,Var,Abs)
25,05,                      //     Logical Maximum (5)
09,24,                      //     Usage (Repeat Count)
91,02,                      //     Output (Data,Var,Abs)
75,10,                      //     Report Size (16)
46,E8,03,                   //     Physical Maximum (1000)
66,01,10,                   //     Unit (SiLinear, Seconds:1)
55,0D,                      //     Unit Exponent (-3)
15,00,                      //     Logical Minimum (0)
26,E8,03,                   //     Logical Maximum (1000)
09,25,                      //     Usage (Retrigger Period)
91,02,                      //     Output (Data,Var,Abs)
36,E8,03,                   //     Physical Minimum (1000)
46,88,13,                   //     Physical Maximum (5000)
16,E8,03,                   //     Logical Minimum (1000)
26,88,13,                   //     Logical Maximum (5000)
09,28,                      //     Usage (Waveform Cutoff Time)
91,02,                      //     Output (Data,Var,Abs)
C0,                         //   End Collection ()
C0                          // End Collection ()