1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
6 """Utility functions for constructing HID report descriptors.
14 def ReportDescriptor(*items):
18 def _PackItem(tag, typ, value=0, force_length=0):
19 """Pack a multibyte value.
21 See Device Class Definition for Human Interface Devices (HID) Version 1.11
28 force_length: Force packing to a specific width.
33 if value == 0 and force_length <= 0:
34 return struct.pack('<B', tag << 4 | typ << 2 | 0)
35 elif value <= 0xff and force_length <= 1:
36 return struct.pack('<BB', tag << 4 | typ << 2 | 1, value)
37 elif value <= 0xffff and force_length <= 2:
38 return struct.pack('<BH', tag << 4 | typ << 2 | 2, value)
39 elif value <= 0xffffffff and force_length <= 4:
40 return struct.pack('<BI', tag << 4 | typ << 2 | 3, value)
42 raise NotImplementedError('Long items are not implemented.')
45 def _DefineItem(name, tag, typ):
46 """Create a function which encodes a HID item.
54 A function which encodes a HID item of the given type.
56 assert tag >= 0 and tag <= 0xF
57 assert typ >= 0 and typ <= 3
59 def EncodeItem(value=0, force_length=0):
60 return _PackItem(tag, typ, value, force_length)
62 EncodeItem.__name__ = name
66 def _DefineMainItem(name, tag):
67 """Create a function which encodes a HID Main item.
69 See Device Class Definition for Human Interface Devices (HID) Version 1.11
77 A function which encodes a HID item of the given type.
80 ValueError: If the tag value is out of range.
82 assert tag >= 0 and tag <= 0xF
84 def EncodeMainItem(*properties):
86 for bit, is_set in properties:
89 return _PackItem(tag, hid_constants.Scope.MAIN, value, force_length=1)
91 EncodeMainItem.__name__ = name
94 Input = _DefineMainItem('Input', 8)
95 Output = _DefineMainItem('Output', 9)
96 Feature = _DefineMainItem('Feature', 11)
98 # Input, Output and Feature Item Properties
100 # See Device Class Definition for Human Interface Devices (HID) Version 1.11
106 Absolute = (2, False)
111 NonLinear = (4, True)
112 PreferredState = (5, False)
113 NoPreferred = (5, True)
114 NoNullPosition = (6, False)
115 NullState = (6, True)
116 NonVolatile = (7, False)
118 BitField = (8, False)
119 BufferedBytes = (8, True)
122 def Collection(typ, *items):
123 start = struct.pack('<BB', 0xA1, typ)
124 end = struct.pack('<B', 0xC0)
125 return start + ''.join(items) + end
129 # See Device Class Definition for Human Interface Devices (HID) Version 1.11
131 UsagePage = _DefineItem('UsagePage', 0, hid_constants.Scope.GLOBAL)
132 LogicalMinimum = _DefineItem('LogicalMinimum', 1, hid_constants.Scope.GLOBAL)
133 LogicalMaximum = _DefineItem('LogicalMaximum', 2, hid_constants.Scope.GLOBAL)
134 PhysicalMinimum = _DefineItem('PhysicalMinimum', 3, hid_constants.Scope.GLOBAL)
135 PhysicalMaximum = _DefineItem('PhysicalMaximum', 4, hid_constants.Scope.GLOBAL)
136 UnitExponent = _DefineItem('UnitExponent', 5, hid_constants.Scope.GLOBAL)
137 Unit = _DefineItem('Unit', 6, hid_constants.Scope.GLOBAL)
138 ReportSize = _DefineItem('ReportSize', 7, hid_constants.Scope.GLOBAL)
139 ReportID = _DefineItem('ReportID', 8, hid_constants.Scope.GLOBAL)
140 ReportCount = _DefineItem('ReportCount', 9, hid_constants.Scope.GLOBAL)
141 Push = _DefineItem('Push', 10, hid_constants.Scope.GLOBAL)
142 Pop = _DefineItem('Pop', 11, hid_constants.Scope.GLOBAL)
146 # See Device Class Definition for Human Interface Devices (HID) Version 1.11
148 Usage = _DefineItem('Usage', 0, hid_constants.Scope.LOCAL)
149 UsageMinimum = _DefineItem('UsageMinimum', 1, hid_constants.Scope.LOCAL)
150 UsageMaximum = _DefineItem('UsageMaximum', 2, hid_constants.Scope.LOCAL)
151 DesignatorIndex = _DefineItem('DesignatorIndex', 3, hid_constants.Scope.LOCAL)
152 DesignatorMinimum = _DefineItem('DesignatorMinimum', 4,
153 hid_constants.Scope.LOCAL)
154 DesignatorMaximum = _DefineItem('DesignatorMaximum', 5,
155 hid_constants.Scope.LOCAL)
156 StringIndex = _DefineItem('StringIndex', 7, hid_constants.Scope.LOCAL)
157 StringMinimum = _DefineItem('StringMinimum', 8, hid_constants.Scope.LOCAL)
158 StringMaximum = _DefineItem('StringMaximum', 9, hid_constants.Scope.LOCAL)
159 Delimiter = _DefineItem('Delimiter', 10, hid_constants.Scope.LOCAL)