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
)