Skip to content

別の種類のタッチパッドでは送られてくる形式が異なるようです #1

Description

@kamektx

TouchpadGestures_Advanced の作者のkamektxです。

件名の通り、別の種類のタッチパッドでは送られてくるデータの形式が異なるようです。先日新しいPCを購入してTGAが動かないことで判明しました。

どうやらある種類のタッチパッドでは、

  • マルチタッチ時の2点目以降のデータを 2回目の 後に続く複数回の WM_INPUTメッセージへと分けて送信している
  • 2点目以降のデータは従来の通りLinkCollectionによってインデックス化されているのではなく、RAWINPUT->data.hid.bRawData のバイト列に連なるようにして保存されている

ようです。詳しい仕様としては、

1回目のWM_INPUT

  • RAWINPUT->data.hid.dwCount: 必ず(?) 1
  • Values from RAWINPUT->data.hid.bRawData
    • LinkCollection: 0
      • ScanTime: 2回目のメッセージと同
      • ContactCount: 合計タッチ数
    • LinkCollection: 1
      • ContactID
      • X
      • Y
  • Usages (Button input) from RAWINPUT->data.hid.bRawData
    • LinkCollection: 1
      • Tip (あればOn, なければOff)
      • IsFinger (あれば指判定, なければ手の平判定)

2回目の 後に続く複数回のWM_INPUT

  • 1本指タッチでは送られてこない
  • RAWINPUT->data.hid.dwCount: 合計タッチ数(ContactCount) - 1 とは限らず、計3回に分けて送ってきたりもする
  • Values from (RAWINPUT->data.hid.bRawData + RAWINPUT->data.hid.dwSizeHid * {0, 1, ... , dwCount - 1}) (ポインタ演算です)
    • LinkCollection: 0
      • ScanTime: 1回目のメッセージと同
      • ContactCount: 必ず0
    • LinkCollection: 1
      • ContactID
      • X
      • Y
  • Usages (Button input) from (RAWINPUT->data.hid.bRawData + RAWINPUT->data.hid.dwSizeHid * {0, 1, ... , dwCount - 1})
    • LinkCollection: 1
      • Tip (あればOn, なければOff)
      • IsFinger (あれば指判定, なければ手の平判定)

といった感じになってます。

実装としては、

  • 1回目のメッセージではContactCountとLinkCollectionの最大値が一致しないことで従来型のメッセージと判別できる
  • 2回目のメッセージでは RAWINPUT->data.hid.dwCountが2以上となること、または ContactCountが0であることで従来型のメッセージと判別できる
 HidP_GetUsageValue(
      HIDP_REPORT_TYPE.HidP_Input,
      valueCap.UsagePage,
      valueCap.LinkCollection,
      valueCap.Usage,
      out uint value,
      preparsedDataPointer,
-     rawHidRawDataPointer,
+    // rawHidRawDataPointerからRAWINPUT->data.hid.dwSizeHidバイト * {0, 1, 2 ...}だけポインタをズラしてください。
+    // 現在rawHidRawDataPointerがIntPtr型なのでそのまま+で足すと多分バグります。気をつけて…。
      (uint)rawHidRawData.Length)

みたいな感じで行けると思います。プルリク送れなくてすみません。

一応自前のC++での実装を載せておきます。参考になれば幸いです。

Microsoftのページ の"Packet reporting modes"の節を見る限り、なんだかもっとデータにバリエーションがありそうな気もしていて、非常に恐ろしく思っています……。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions