MooseBoys
MooseBoys

Reputation: 6793

What's the difference between the Keyboard HID page and the Generic HID page with the Keyboard ID?

The HID usages specification defines a Generic Desktop Usage Page (0x01) which contains a Keyboard Usage ID (0x06). It also defines a Keyboard Usage Page (0x09) with Usage IDs corresponding to individual keyboard keys. The entry for the former just says to refer to the latter for details. Why does this distinction exist? Is there any practical difference between defining a device as DesktopGeneric/Keyboard vs. just Keyboard?

Upvotes: 3

Views: 1577

Answers (1)

aja
aja

Reputation: 1740

For background, each USB usage code is a 4-byte number comprising two parts: a 2-byte usage page, followed by a 2-byte usage id. The Generic Desktop page is 0x0001 and the Keyboard/Keypad usage page is 0x0007. A reasonably complete list of known usages can be found at https://github.com/abend0c1/hidrdd/blob/master/rd.conf

The Keyboard usage id (0x0006) within the Generic Desktop page (i.e. usage 0x00010006) has the type "CA" and is meant to be used to identify a keyboard Application Collection. That identifies a collection of usages - usually from the Keyboard/Keypad page (0x0007) and LED Indicator page (0x0008) - that are to be associated with a Keyboard device. This way of identifying a collection of usages may be used by device drivers to direct USB HID reports to the appropriate device handler.

Note that HID report descriptors are formed by specifying GLOBAL and/or LOCAL items first, and then specifying MAIN items that use those GLOBAL/LOCAL items (kind of like Reverse Polish Notation: the operands come first, followed by the operations).

To illustrate, below is the example from "Appendix E.6 Report Descriptor (Keyboard)" of the HID Device Class Definition 1.11 that I have reformatted for clarity. The Generic Desktop Page is specified, then the Keyboard usage within that page, then an Application Collection MAIN item is begun for that usage (0x00010006).

05 01        (GLOBAL) USAGE_PAGE         0x0001 Generic Desktop Page 
09 06        (LOCAL)  USAGE              0x00010006 Keyboard (CA=Application Collection) 
A1 01        (MAIN)   COLLECTION         0x01 Application (Usage=0x00010006: Page=Generic Desktop Page, Usage=Keyboard, Type=CA)
05 07          (GLOBAL) USAGE_PAGE         0x0007 Keyboard/Keypad Page 
19 E0          (LOCAL)  USAGE_MINIMUM      0x000700E0 Keyboard Left Control (DV=Dynamic Value) 
29 E7          (LOCAL)  USAGE_MAXIMUM      0x000700E7 Keyboard Right GUI (DV=Dynamic Value) 
15 00          (GLOBAL) LOGICAL_MINIMUM    0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0
25 01          (GLOBAL) LOGICAL_MAXIMUM    0x01 (1) 
75 01          (GLOBAL) REPORT_SIZE        0x01 (1) Number of bits per field 
95 08          (GLOBAL) REPORT_COUNT       0x08 (8) Number of fields 
81 02          (MAIN)   INPUT              0x00000002 (8 fields x 1 bit) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
95 01          (GLOBAL) REPORT_COUNT       0x01 (1) Number of fields 
75 08          (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field 
81 01          (MAIN)   INPUT              0x00000001 (1 field x 8 bits) 1=Constant 0=Array 0=Absolute 0=Ignored 0=Ignored 0=PrefState 0=NoNull 
95 05          (GLOBAL) REPORT_COUNT       0x05 (5) Number of fields 
75 01          (GLOBAL) REPORT_SIZE        0x01 (1) Number of bits per field 
05 08          (GLOBAL) USAGE_PAGE         0x0008 LED Indicator Page 
19 01          (LOCAL)  USAGE_MINIMUM      0x00080001 Num Lock (OOC=On/Off Control) 
29 05          (LOCAL)  USAGE_MAXIMUM      0x00080005 Kana (OOC=On/Off Control) 
91 02          (MAIN)   OUTPUT             0x00000002 (5 fields x 1 bit) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
95 01          (GLOBAL) REPORT_COUNT       0x01 (1) Number of fields 
75 03          (GLOBAL) REPORT_SIZE        0x03 (3) Number of bits per field 
91 01          (MAIN)   OUTPUT             0x00000001 (1 field x 3 bits) 1=Constant 0=Array 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
95 06          (GLOBAL) REPORT_COUNT       0x06 (6) Number of fields 
75 08          (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field 
15 00          (GLOBAL) LOGICAL_MINIMUM    0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0
25 65          (GLOBAL) LOGICAL_MAXIMUM    0x65 (101) 
05 07          (GLOBAL) USAGE_PAGE         0x0007 Keyboard/Keypad Page 
19 00          (LOCAL)  USAGE_MINIMUM      0x00070000 Keyboard No event indicated (Sel=Selector) <-- Redundant: USAGE_MINIMUM is already 0x0000
29 65          (LOCAL)  USAGE_MAXIMUM      0x00070065 Keyboard Application (Sel=Selector) 
81 00          (MAIN)   INPUT              0x00000000 (6 fields x 8 bits) 0=Data 0=Array 0=Absolute 0=Ignored 0=Ignored 0=PrefState 0=NoNull 
C0           (MAIN)   END_COLLECTION     Application

Upvotes: 3

Related Questions