使用事例
- USBを使用してスマートフォンデバイス用のHID「タッチスクリーン」を実装
- 「タッチ スクリーン」は、横向きでも縦向きでも適切に動作する必要があります
開発環境
- サムスン ギャラクシー 5
- 人造人間5
問題の説明
電話が縦向き ( 1080x1920 ) の場合、すべてが完全に機能します。横向き ( 1920x1080 ) に変更すると、座標は 90 度回転し、X 軸 (現在は 1920 ) に沿った動きは 1080 に制限されます。
HID レポートを介して送信された X & Y 座標を手動で切り替えると、カーソルがデバイスの物理的な動きに合わせられますが、水平軸 (現在は 1920 ) は依然として 1080 に制限されています。
HID ディスクリプタでは、LOGICAL_MAXIMUM を PHYSICAL_MAXIMUM よりも大きくしても影響はありませんでした...
Digitizer デバイスの向きの変更をサポートすることは、まったく可能ですか? 方向の変更が適切に機能するように、何らかの方法で記述子を変更する必要がありますか?
アップデート
- USAGE_PAGE デジタイザー (0x0D) と方位角 USAGE_ID (0x3F) を使用しても影響はありませんでした
- USAGE_PAGE 'Alpha Numeric Display (0x14)' with 'Display Orientation' USAGE_ID (0x84) を使用しても影響はありませんでした
コード スニペット (このリンクに従って実装)
enum :BYTE { REPORT_ID = 4 };
const UCHAR DESCRIPTOR[] = {
0x05, 0x0d, // USAGE_PAGE (Digitizers)
0x09, 0x04, // USAGE (Touch Screen)
0xa1, 0x01, // COLLECTION (Application)
0x85, REPORT_ID, // REPORT_ID (4)
0x09, 0x20, // USAGE (Stylus)
0xa1, 0x00, // COLLECTION (Physical)
0x09, 0x42, // USAGE (Tip Switch)
0x09, 0x32, // USAGE (In Range)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x02, // REPORT_COUNT (2)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x06, // REPORT_COUNT (6)
0x81, 0x01, // INPUT (Cnst,Ary,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x46, 0x10, 0x27, // PHYSICAL_MAXIMUM (10000)
0x26, 0x10, 0x27, // LOGICAL_MAXIMUM (10000)
0x75, 0x10, // REPORT_SIZE (16)
0x95, 0x01, // REPORT_COUNT (1)
0x55, 0x0F, // UNIT_EXPONENT (-1)
0x65, 0x11, // UNIT (cm,SI Linear)
0x35, 0x00, // PHYSICAL_MINIMUM (0)
0x45, 0x00, // PHYSICAL_MAXIMUM (0)
0x09, 0x30, // USAGE (X)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x09, 0x31, // USAGE (Y)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0, // END_COLLECTION
0xc0, // END_COLLECTION
};
struct Report {
enum :LONG { RES_X = 10000, RES_Y = 10000 };
UCHAR report_id; // Must be set to 4
struct {
UCHAR bTipSwitch : 1;
UCHAR bInRange : 1;
UCHAR reserved : 6;
} status;
USHORT wXData;
USHORT wYData;
inline static void NormalizeCoordinates(IN const SIZE& res, IN OUT USHORT& x, IN OUT USHORT& y) {
if ((0 == res.cx) || (0 == res.cy)) {
assert(FALSE);
return;
}
x = (USHORT)((RES_X * x) / res.cx);
y = (USHORT)((RES_Y * y) / res.cy);
}
};