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
- 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
- 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"の節を見る限り、なんだかもっとデータにバリエーションがありそうな気もしていて、非常に恐ろしく思っています……。
TouchpadGestures_Advanced の作者のkamektxです。
件名の通り、別の種類のタッチパッドでは送られてくるデータの形式が異なるようです。先日新しいPCを購入してTGAが動かないことで判明しました。
どうやらある種類のタッチパッドでは、
2回目の後に続く複数回の WM_INPUTメッセージへと分けて送信しているようです。詳しい仕様としては、
1回目のWM_INPUT
2回目の後に続く複数回のWM_INPUT合計タッチ数(ContactCount) - 1とは限らず、計3回に分けて送ってきたりもするといった感じになってます。
実装としては、
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"の節を見る限り、なんだかもっとデータにバリエーションがありそうな気もしていて、非常に恐ろしく思っています……。