You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
3.0 KiB

  1. import unittest
  2. from contextlib import contextmanager
  3. from .. import emitter_for_format
  4. from ..descriptor import ComplexDescriptorEmitter
  5. from ...types.descriptors.hid import \
  6. HIDDescriptor as HIDDescriptorType
  7. from ...types.descriptors.hid import *
  8. ReportDescriptorEmitter = emitter_for_format(ReportDescriptor)
  9. _hid_item_length = [ 0, 1, 2, 4 ]
  10. class HIDDescriptor(ComplexDescriptorEmitter):
  11. DESCRIPTOR_FORMAT = HIDDescriptorType
  12. def add_report_item(self, report_prefix, *report_data):
  13. hid_report = ReportDescriptorEmitter()
  14. report_len = _hid_item_length.index(len(report_data))
  15. hid_report.bHeader = {
  16. "prefix": report_prefix,
  17. "bSize": report_len
  18. }
  19. hid_report.data = report_data
  20. self._reports.append(hid_report)
  21. def add_input_item(self,
  22. data_constant = False,
  23. array_variable = True,
  24. absolute_relative = False,
  25. wrap = False,
  26. linear = False,
  27. preferred = True,
  28. null = False,
  29. volatile = False):
  30. item_flags = ItemFlags.build({
  31. "data_constant": data_constant,
  32. "array_variable": array_variable,
  33. "absolute_relative": absolute_relative,
  34. "wrap": wrap,
  35. "linear": linear,
  36. "nPreferred": ~preferred,
  37. "null": null,
  38. "volatile": volatile,
  39. })
  40. self.add_report(HIDPrefix.INPUT, ord(item_flags))
  41. def add_output_item(self,
  42. data_constant = False,
  43. array_variable = True,
  44. absolute_relative = False,
  45. wrap = False,
  46. linear = False,
  47. preferred = True,
  48. null = False,
  49. volatile = False):
  50. item_flags = ItemFlags.build({
  51. "data_constant": data_constant,
  52. "array_variable": array_variable,
  53. "absolute_relative": absolute_relative,
  54. "wrap": wrap,
  55. "linear": linear,
  56. "nPreferred": ~preferred,
  57. "null": null,
  58. "volatile": volatile,
  59. })
  60. self.add_report(HIDPrefix.OUTPUT, ord(item_flags))
  61. def __init__(self, parent_descriptor):
  62. super().__init__()
  63. # The HID Report Descriptor sits under a different USB Descriptor,
  64. # we need access to the descriptor root to create this.
  65. self._parent_descriptor = parent_descriptor
  66. self._reports = []
  67. def _pre_emit(self):
  68. report_descriptor = []
  69. for report in self._reports:
  70. if hasattr(report, "emit"):
  71. report_descriptor.append(report.emit())
  72. else:
  73. report_descriptor.append(report)
  74. report_descriptor = b"".join(report_descriptor)
  75. descriptor_len = len(report_descriptor)
  76. self.wDescriptorLength = descriptor_len
  77. self._parent_descriptor.add_descriptor(report_descriptor, 0x22)