1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
# Copyright 2014 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Utility functions for constructing HID report descriptors.
"""
import struct
import hid_constants
def ReportDescriptor(*items):
return ''.join(items)
def _PackItem(tag, typ, value=0, force_length=0):
"""Pack a multibyte value.
See Device Class Definition for Human Interface Devices (HID) Version 1.11
section 5.8.
Args:
tag: Item tag.
typ: Item type.
value: Item value.
force_length: Force packing to a specific width.
Returns:
Packed string.
"""
if value == 0 and force_length <= 0:
return struct.pack('<B', tag << 4 | typ << 2 | 0)
elif value <= 0xff and force_length <= 1:
return struct.pack('<BB', tag << 4 | typ << 2 | 1, value)
elif value <= 0xffff and force_length <= 2:
return struct.pack('<BH', tag << 4 | typ << 2 | 2, value)
elif value <= 0xffffffff and force_length <= 4:
return struct.pack('<BI', tag << 4 | typ << 2 | 3, value)
else:
raise NotImplementedError('Long items are not implemented.')
def _DefineItem(name, tag, typ):
"""Create a function which encodes a HID item.
Args:
name: Function name.
tag: Item tag.
typ: Item type.
Returns:
A function which encodes a HID item of the given type.
"""
assert tag >= 0 and tag <= 0xF
assert typ >= 0 and typ <= 3
def EncodeItem(value=0, force_length=0):
return _PackItem(tag, typ, value, force_length)
EncodeItem.__name__ = name
return EncodeItem
def _DefineMainItem(name, tag):
"""Create a function which encodes a HID Main item.
See Device Class Definition for Human Interface Devices (HID) Version 1.11
section 6.2.2.4.
Args:
name: Function name.
tag: Item tag.
Returns:
A function which encodes a HID item of the given type.
Raises:
ValueError: If the tag value is out of range.
"""
assert tag >= 0 and tag <= 0xF
def EncodeMainItem(*properties):
value = 0
for bit, is_set in properties:
if is_set:
value |= 1 << bit
return _PackItem(tag, hid_constants.Scope.MAIN, value, force_length=1)
EncodeMainItem.__name__ = name
return EncodeMainItem
Input = _DefineMainItem('Input', 8)
Output = _DefineMainItem('Output', 9)
Feature = _DefineMainItem('Feature', 11)
# Input, Output and Feature Item Properties
#
# See Device Class Definition for Human Interface Devices (HID) Version 1.11
# section 6.2.2.5.
Data = (0, False)
Constant = (0, True)
Array = (1, False)
Variable = (1, True)
Absolute = (2, False)
Relative = (2, True)
NoWrap = (3, False)
Wrap = (3, True)
Linear = (4, False)
NonLinear = (4, True)
PreferredState = (5, False)
NoPreferred = (5, True)
NoNullPosition = (6, False)
NullState = (6, True)
NonVolatile = (7, False)
Volatile = (7, True)
BitField = (8, False)
BufferedBytes = (8, True)
def Collection(typ, *items):
start = struct.pack('<BB', 0xA1, typ)
end = struct.pack('<B', 0xC0)
return start + ''.join(items) + end
# Global Items
#
# See Device Class Definition for Human Interface Devices (HID) Version 1.11
# section 6.2.2.7.
UsagePage = _DefineItem('UsagePage', 0, hid_constants.Scope.GLOBAL)
LogicalMinimum = _DefineItem('LogicalMinimum', 1, hid_constants.Scope.GLOBAL)
LogicalMaximum = _DefineItem('LogicalMaximum', 2, hid_constants.Scope.GLOBAL)
PhysicalMinimum = _DefineItem('PhysicalMinimum', 3, hid_constants.Scope.GLOBAL)
PhysicalMaximum = _DefineItem('PhysicalMaximum', 4, hid_constants.Scope.GLOBAL)
UnitExponent = _DefineItem('UnitExponent', 5, hid_constants.Scope.GLOBAL)
Unit = _DefineItem('Unit', 6, hid_constants.Scope.GLOBAL)
ReportSize = _DefineItem('ReportSize', 7, hid_constants.Scope.GLOBAL)
ReportID = _DefineItem('ReportID', 8, hid_constants.Scope.GLOBAL)
ReportCount = _DefineItem('ReportCount', 9, hid_constants.Scope.GLOBAL)
Push = _DefineItem('Push', 10, hid_constants.Scope.GLOBAL)
Pop = _DefineItem('Pop', 11, hid_constants.Scope.GLOBAL)
# Local Items
#
# See Device Class Definition for Human Interface Devices (HID) Version 1.11
# section 6.2.2.8.
Usage = _DefineItem('Usage', 0, hid_constants.Scope.LOCAL)
UsageMinimum = _DefineItem('UsageMinimum', 1, hid_constants.Scope.LOCAL)
UsageMaximum = _DefineItem('UsageMaximum', 2, hid_constants.Scope.LOCAL)
DesignatorIndex = _DefineItem('DesignatorIndex', 3, hid_constants.Scope.LOCAL)
DesignatorMinimum = _DefineItem('DesignatorMinimum', 4,
hid_constants.Scope.LOCAL)
DesignatorMaximum = _DefineItem('DesignatorMaximum', 5,
hid_constants.Scope.LOCAL)
StringIndex = _DefineItem('StringIndex', 7, hid_constants.Scope.LOCAL)
StringMinimum = _DefineItem('StringMinimum', 8, hid_constants.Scope.LOCAL)
StringMaximum = _DefineItem('StringMaximum', 9, hid_constants.Scope.LOCAL)
Delimiter = _DefineItem('Delimiter', 10, hid_constants.Scope.LOCAL)
|