title: HID Digitizer Descriptor doesn't perform well with landscape orientation
body: <h2>Use-case</h2>
  
  <ul>
  <li>Implement a HID "Touch Screen" for a SmartPhone device using USB</li>
  <li>"Touch Screen" should operate well in either landscape or portrait orientation</li>
  </ul>
  
  <h2>Dev Environment</h2>
  
  <ul>
  <li>Samsung Galaxy 5</li>
  <li>Android 5</li>
  </ul>
  
  <h2>Problem description</h2>
  
  <p>When the phone is in the Portrait orientation ( 1080x1920 ) all is perfectly working, when changing to landscape orientation ( 1920x1080 ) coordinates are 90 degrees rotated and movement along the X axes ( now 1920 ) is limited to 1080.</p>
  
  <p>Manually switching the X &amp; Y coordinates sent through the HID Report makes the cursor aligned with the physical movement of the device, <strong>however</strong> the horizontal axes ( now 1920 ) is still limited to 1080.</p>
  
  <p>On the HID Descriptor, Making the LOGICAL_MAXIMUM lager than the PHYSICAL_MAXIMUM didn't have any affect...</p>
  
  <p>Is it possible, at-all, to support orientation changes for a Digitizer device ? should I change the descriptor in any way to have the orientation changes properly work ?</p>
  
  <h2>UPDATE</h2>
  
  <ul>
  <li>Using USAGE_PAGE Digitizers (0x0D) w/ Azimuth USAGE_ID (0x3F) didn't have any affect</li>
  <li>Using USAGE_PAGE 'Alpha Numeric Display (0x14)' w/ 'Display Orientation' USAGE_ID (0x84) didn't have any affect</li>
  </ul>
  
  <h2>Code Snippet ( Implemented according to <a href="http://www.usb.org/developers/hidpage/Hut1_12v2.pdf" rel="nofollow">this link</a> )</h2>
  
  <pre><code>            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&amp; res, IN OUT USHORT&amp; x, IN OUT USHORT&amp; 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);
                  }
              };
  </code></pre>