test_gamepad.py 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. #!/bin/env python3
  2. # SPDX-License-Identifier: GPL-2.0
  3. # -*- coding: utf-8 -*-
  4. #
  5. # Copyright (c) 2019 Benjamin Tissoires <benjamin.tissoires@gmail.com>
  6. # Copyright (c) 2019 Red Hat, Inc.
  7. #
  8. from . import base
  9. import libevdev
  10. import pytest
  11. from .base_gamepad import BaseGamepad, JoystickGamepad, AxisMapping
  12. from hidtools.util import BusType
  13. from .base import HidBpf
  14. import logging
  15. logger = logging.getLogger("hidtools.test.gamepad")
  16. class BaseTest:
  17. class TestGamepad(base.BaseTestCase.TestUhid):
  18. @pytest.fixture(autouse=True)
  19. def send_initial_state(self):
  20. """send an empty report to initialize the axes"""
  21. uhdev = self.uhdev
  22. r = uhdev.event()
  23. events = uhdev.next_sync_events()
  24. self.debug_reports(r, uhdev, events)
  25. def assert_button(self, button):
  26. uhdev = self.uhdev
  27. evdev = uhdev.get_evdev()
  28. syn_event = self.syn_event
  29. buttons = {}
  30. key = libevdev.evbit(uhdev.buttons_map[button])
  31. buttons[button] = True
  32. r = uhdev.event(buttons=buttons)
  33. expected_event = libevdev.InputEvent(key, 1)
  34. events = uhdev.next_sync_events()
  35. self.debug_reports(r, uhdev, events)
  36. self.assertInputEventsIn((syn_event, expected_event), events)
  37. assert evdev.value[key] == 1
  38. buttons[button] = False
  39. r = uhdev.event(buttons=buttons)
  40. expected_event = libevdev.InputEvent(key, 0)
  41. events = uhdev.next_sync_events()
  42. self.debug_reports(r, uhdev, events)
  43. self.assertInputEventsIn((syn_event, expected_event), events)
  44. assert evdev.value[key] == 0
  45. def test_buttons(self):
  46. """check for button reliability."""
  47. uhdev = self.uhdev
  48. for b in uhdev.buttons:
  49. self.assert_button(b)
  50. def test_dual_buttons(self):
  51. """check for button reliability when pressing 2 buttons"""
  52. uhdev = self.uhdev
  53. evdev = uhdev.get_evdev()
  54. syn_event = self.syn_event
  55. # can change intended b1 b2 values
  56. b1 = uhdev.buttons[0]
  57. key1 = libevdev.evbit(uhdev.buttons_map[b1])
  58. b2 = uhdev.buttons[1]
  59. key2 = libevdev.evbit(uhdev.buttons_map[b2])
  60. buttons = {b1: True, b2: True}
  61. r = uhdev.event(buttons=buttons)
  62. expected_event0 = libevdev.InputEvent(key1, 1)
  63. expected_event1 = libevdev.InputEvent(key2, 1)
  64. events = uhdev.next_sync_events()
  65. self.debug_reports(r, uhdev, events)
  66. self.assertInputEventsIn(
  67. (syn_event, expected_event0, expected_event1), events
  68. )
  69. assert evdev.value[key1] == 1
  70. assert evdev.value[key2] == 1
  71. buttons = {b1: False, b2: None}
  72. r = uhdev.event(buttons=buttons)
  73. expected_event = libevdev.InputEvent(key1, 0)
  74. events = uhdev.next_sync_events()
  75. self.debug_reports(r, uhdev, events)
  76. self.assertInputEventsIn((syn_event, expected_event), events)
  77. assert evdev.value[key1] == 0
  78. assert evdev.value[key2] == 1
  79. buttons = {b1: None, b2: False}
  80. r = uhdev.event(buttons=buttons)
  81. expected_event = libevdev.InputEvent(key2, 0)
  82. events = uhdev.next_sync_events()
  83. self.debug_reports(r, uhdev, events)
  84. self.assertInputEventsIn((syn_event, expected_event), events)
  85. assert evdev.value[key1] == 0
  86. assert evdev.value[key2] == 0
  87. def _get_libevdev_abs_events(self, which):
  88. """Returns which ABS_* evdev axes are expected for the given stick"""
  89. abs_map = self.uhdev.axes_map[which]
  90. x = abs_map["x"].evdev
  91. y = abs_map["y"].evdev
  92. assert x
  93. assert y
  94. return x, y
  95. def _test_joystick_press(self, which, data):
  96. uhdev = self.uhdev
  97. libevdev_axes = self._get_libevdev_abs_events(which)
  98. r = None
  99. if which == "left_stick":
  100. r = uhdev.event(left=data)
  101. else:
  102. r = uhdev.event(right=data)
  103. events = uhdev.next_sync_events()
  104. self.debug_reports(r, uhdev, events)
  105. for i, d in enumerate(data):
  106. if d is not None and d != 127:
  107. assert libevdev.InputEvent(libevdev_axes[i], d) in events
  108. else:
  109. assert libevdev.InputEvent(libevdev_axes[i]) not in events
  110. def test_left_joystick_press_left(self):
  111. """check for the left joystick reliability"""
  112. self._test_joystick_press("left_stick", (63, None))
  113. self._test_joystick_press("left_stick", (0, 127))
  114. def test_left_joystick_press_right(self):
  115. """check for the left joystick reliability"""
  116. self._test_joystick_press("left_stick", (191, 127))
  117. self._test_joystick_press("left_stick", (255, None))
  118. def test_left_joystick_press_up(self):
  119. """check for the left joystick reliability"""
  120. self._test_joystick_press("left_stick", (None, 63))
  121. self._test_joystick_press("left_stick", (127, 0))
  122. def test_left_joystick_press_down(self):
  123. """check for the left joystick reliability"""
  124. self._test_joystick_press("left_stick", (127, 191))
  125. self._test_joystick_press("left_stick", (None, 255))
  126. def test_right_joystick_press_left(self):
  127. """check for the right joystick reliability"""
  128. self._test_joystick_press("right_stick", (63, None))
  129. self._test_joystick_press("right_stick", (0, 127))
  130. def test_right_joystick_press_right(self):
  131. """check for the right joystick reliability"""
  132. self._test_joystick_press("right_stick", (191, 127))
  133. self._test_joystick_press("right_stick", (255, None))
  134. def test_right_joystick_press_up(self):
  135. """check for the right joystick reliability"""
  136. self._test_joystick_press("right_stick", (None, 63))
  137. self._test_joystick_press("right_stick", (127, 0))
  138. def test_right_joystick_press_down(self):
  139. """check for the right joystick reliability"""
  140. self._test_joystick_press("right_stick", (127, 191))
  141. self._test_joystick_press("right_stick", (None, 255))
  142. @pytest.mark.skip_if_uhdev(
  143. lambda uhdev: "Hat switch" not in uhdev.fields,
  144. "Device not compatible, missing Hat switch usage",
  145. )
  146. @pytest.mark.parametrize(
  147. "hat_value,expected_evdev,evdev_value",
  148. [
  149. (0, "ABS_HAT0Y", -1),
  150. (2, "ABS_HAT0X", 1),
  151. (4, "ABS_HAT0Y", 1),
  152. (6, "ABS_HAT0X", -1),
  153. ],
  154. )
  155. def test_hat_switch(self, hat_value, expected_evdev, evdev_value):
  156. uhdev = self.uhdev
  157. r = uhdev.event(hat_switch=hat_value)
  158. events = uhdev.next_sync_events()
  159. self.debug_reports(r, uhdev, events)
  160. assert (
  161. libevdev.InputEvent(
  162. libevdev.evbit("EV_ABS", expected_evdev), evdev_value
  163. )
  164. in events
  165. )
  166. class SaitekGamepad(JoystickGamepad):
  167. # fmt: off
  168. report_descriptor = [
  169. 0x05, 0x01, # Usage Page (Generic Desktop) 0
  170. 0x09, 0x04, # Usage (Joystick) 2
  171. 0xa1, 0x01, # Collection (Application) 4
  172. 0x09, 0x01, # .Usage (Pointer) 6
  173. 0xa1, 0x00, # .Collection (Physical) 8
  174. 0x85, 0x01, # ..Report ID (1) 10
  175. 0x09, 0x30, # ..Usage (X) 12
  176. 0x15, 0x00, # ..Logical Minimum (0) 14
  177. 0x26, 0xff, 0x00, # ..Logical Maximum (255) 16
  178. 0x35, 0x00, # ..Physical Minimum (0) 19
  179. 0x46, 0xff, 0x00, # ..Physical Maximum (255) 21
  180. 0x75, 0x08, # ..Report Size (8) 24
  181. 0x95, 0x01, # ..Report Count (1) 26
  182. 0x81, 0x02, # ..Input (Data,Var,Abs) 28
  183. 0x09, 0x31, # ..Usage (Y) 30
  184. 0x81, 0x02, # ..Input (Data,Var,Abs) 32
  185. 0x05, 0x02, # ..Usage Page (Simulation Controls) 34
  186. 0x09, 0xba, # ..Usage (Rudder) 36
  187. 0x81, 0x02, # ..Input (Data,Var,Abs) 38
  188. 0x09, 0xbb, # ..Usage (Throttle) 40
  189. 0x81, 0x02, # ..Input (Data,Var,Abs) 42
  190. 0x05, 0x09, # ..Usage Page (Button) 44
  191. 0x19, 0x01, # ..Usage Minimum (1) 46
  192. 0x29, 0x0c, # ..Usage Maximum (12) 48
  193. 0x25, 0x01, # ..Logical Maximum (1) 50
  194. 0x45, 0x01, # ..Physical Maximum (1) 52
  195. 0x75, 0x01, # ..Report Size (1) 54
  196. 0x95, 0x0c, # ..Report Count (12) 56
  197. 0x81, 0x02, # ..Input (Data,Var,Abs) 58
  198. 0x95, 0x01, # ..Report Count (1) 60
  199. 0x75, 0x00, # ..Report Size (0) 62
  200. 0x81, 0x03, # ..Input (Cnst,Var,Abs) 64
  201. 0x05, 0x01, # ..Usage Page (Generic Desktop) 66
  202. 0x09, 0x39, # ..Usage (Hat switch) 68
  203. 0x25, 0x07, # ..Logical Maximum (7) 70
  204. 0x46, 0x3b, 0x01, # ..Physical Maximum (315) 72
  205. 0x55, 0x00, # ..Unit Exponent (0) 75
  206. 0x65, 0x44, # ..Unit (Degrees^4,EngRotation) 77
  207. 0x75, 0x04, # ..Report Size (4) 79
  208. 0x81, 0x42, # ..Input (Data,Var,Abs,Null) 81
  209. 0x65, 0x00, # ..Unit (None) 83
  210. 0xc0, # .End Collection 85
  211. 0x05, 0x0f, # .Usage Page (Vendor Usage Page 0x0f) 86
  212. 0x09, 0x92, # .Usage (Vendor Usage 0x92) 88
  213. 0xa1, 0x02, # .Collection (Logical) 90
  214. 0x85, 0x02, # ..Report ID (2) 92
  215. 0x09, 0xa0, # ..Usage (Vendor Usage 0xa0) 94
  216. 0x09, 0x9f, # ..Usage (Vendor Usage 0x9f) 96
  217. 0x25, 0x01, # ..Logical Maximum (1) 98
  218. 0x45, 0x00, # ..Physical Maximum (0) 100
  219. 0x75, 0x01, # ..Report Size (1) 102
  220. 0x95, 0x02, # ..Report Count (2) 104
  221. 0x81, 0x02, # ..Input (Data,Var,Abs) 106
  222. 0x75, 0x06, # ..Report Size (6) 108
  223. 0x95, 0x01, # ..Report Count (1) 110
  224. 0x81, 0x03, # ..Input (Cnst,Var,Abs) 112
  225. 0x09, 0x22, # ..Usage (Vendor Usage 0x22) 114
  226. 0x75, 0x07, # ..Report Size (7) 116
  227. 0x25, 0x7f, # ..Logical Maximum (127) 118
  228. 0x81, 0x02, # ..Input (Data,Var,Abs) 120
  229. 0x09, 0x94, # ..Usage (Vendor Usage 0x94) 122
  230. 0x75, 0x01, # ..Report Size (1) 124
  231. 0x25, 0x01, # ..Logical Maximum (1) 126
  232. 0x81, 0x02, # ..Input (Data,Var,Abs) 128
  233. 0xc0, # .End Collection 130
  234. 0x09, 0x21, # .Usage (Vendor Usage 0x21) 131
  235. 0xa1, 0x02, # .Collection (Logical) 133
  236. 0x85, 0x0b, # ..Report ID (11) 135
  237. 0x09, 0x22, # ..Usage (Vendor Usage 0x22) 137
  238. 0x26, 0xff, 0x00, # ..Logical Maximum (255) 139
  239. 0x75, 0x08, # ..Report Size (8) 142
  240. 0x91, 0x02, # ..Output (Data,Var,Abs) 144
  241. 0x09, 0x53, # ..Usage (Vendor Usage 0x53) 146
  242. 0x25, 0x0a, # ..Logical Maximum (10) 148
  243. 0x91, 0x02, # ..Output (Data,Var,Abs) 150
  244. 0x09, 0x50, # ..Usage (Vendor Usage 0x50) 152
  245. 0x27, 0xfe, 0xff, 0x00, 0x00, # ..Logical Maximum (65534) 154
  246. 0x47, 0xfe, 0xff, 0x00, 0x00, # ..Physical Maximum (65534) 159
  247. 0x75, 0x10, # ..Report Size (16) 164
  248. 0x55, 0xfd, # ..Unit Exponent (237) 166
  249. 0x66, 0x01, 0x10, # ..Unit (Seconds,SILinear) 168
  250. 0x91, 0x02, # ..Output (Data,Var,Abs) 171
  251. 0x55, 0x00, # ..Unit Exponent (0) 173
  252. 0x65, 0x00, # ..Unit (None) 175
  253. 0x09, 0x54, # ..Usage (Vendor Usage 0x54) 177
  254. 0x55, 0xfd, # ..Unit Exponent (237) 179
  255. 0x66, 0x01, 0x10, # ..Unit (Seconds,SILinear) 181
  256. 0x91, 0x02, # ..Output (Data,Var,Abs) 184
  257. 0x55, 0x00, # ..Unit Exponent (0) 186
  258. 0x65, 0x00, # ..Unit (None) 188
  259. 0x09, 0xa7, # ..Usage (Vendor Usage 0xa7) 190
  260. 0x55, 0xfd, # ..Unit Exponent (237) 192
  261. 0x66, 0x01, 0x10, # ..Unit (Seconds,SILinear) 194
  262. 0x91, 0x02, # ..Output (Data,Var,Abs) 197
  263. 0x55, 0x00, # ..Unit Exponent (0) 199
  264. 0x65, 0x00, # ..Unit (None) 201
  265. 0xc0, # .End Collection 203
  266. 0x09, 0x5a, # .Usage (Vendor Usage 0x5a) 204
  267. 0xa1, 0x02, # .Collection (Logical) 206
  268. 0x85, 0x0c, # ..Report ID (12) 208
  269. 0x09, 0x22, # ..Usage (Vendor Usage 0x22) 210
  270. 0x26, 0xff, 0x00, # ..Logical Maximum (255) 212
  271. 0x45, 0x00, # ..Physical Maximum (0) 215
  272. 0x75, 0x08, # ..Report Size (8) 217
  273. 0x91, 0x02, # ..Output (Data,Var,Abs) 219
  274. 0x09, 0x5c, # ..Usage (Vendor Usage 0x5c) 221
  275. 0x26, 0x10, 0x27, # ..Logical Maximum (10000) 223
  276. 0x46, 0x10, 0x27, # ..Physical Maximum (10000) 226
  277. 0x75, 0x10, # ..Report Size (16) 229
  278. 0x55, 0xfd, # ..Unit Exponent (237) 231
  279. 0x66, 0x01, 0x10, # ..Unit (Seconds,SILinear) 233
  280. 0x91, 0x02, # ..Output (Data,Var,Abs) 236
  281. 0x55, 0x00, # ..Unit Exponent (0) 238
  282. 0x65, 0x00, # ..Unit (None) 240
  283. 0x09, 0x5b, # ..Usage (Vendor Usage 0x5b) 242
  284. 0x25, 0x7f, # ..Logical Maximum (127) 244
  285. 0x75, 0x08, # ..Report Size (8) 246
  286. 0x91, 0x02, # ..Output (Data,Var,Abs) 248
  287. 0x09, 0x5e, # ..Usage (Vendor Usage 0x5e) 250
  288. 0x26, 0x10, 0x27, # ..Logical Maximum (10000) 252
  289. 0x75, 0x10, # ..Report Size (16) 255
  290. 0x55, 0xfd, # ..Unit Exponent (237) 257
  291. 0x66, 0x01, 0x10, # ..Unit (Seconds,SILinear) 259
  292. 0x91, 0x02, # ..Output (Data,Var,Abs) 262
  293. 0x55, 0x00, # ..Unit Exponent (0) 264
  294. 0x65, 0x00, # ..Unit (None) 266
  295. 0x09, 0x5d, # ..Usage (Vendor Usage 0x5d) 268
  296. 0x25, 0x7f, # ..Logical Maximum (127) 270
  297. 0x75, 0x08, # ..Report Size (8) 272
  298. 0x91, 0x02, # ..Output (Data,Var,Abs) 274
  299. 0xc0, # .End Collection 276
  300. 0x09, 0x73, # .Usage (Vendor Usage 0x73) 277
  301. 0xa1, 0x02, # .Collection (Logical) 279
  302. 0x85, 0x0d, # ..Report ID (13) 281
  303. 0x09, 0x22, # ..Usage (Vendor Usage 0x22) 283
  304. 0x26, 0xff, 0x00, # ..Logical Maximum (255) 285
  305. 0x45, 0x00, # ..Physical Maximum (0) 288
  306. 0x91, 0x02, # ..Output (Data,Var,Abs) 290
  307. 0x09, 0x70, # ..Usage (Vendor Usage 0x70) 292
  308. 0x15, 0x81, # ..Logical Minimum (-127) 294
  309. 0x25, 0x7f, # ..Logical Maximum (127) 296
  310. 0x36, 0xf0, 0xd8, # ..Physical Minimum (-10000) 298
  311. 0x46, 0x10, 0x27, # ..Physical Maximum (10000) 301
  312. 0x91, 0x02, # ..Output (Data,Var,Abs) 304
  313. 0xc0, # .End Collection 306
  314. 0x09, 0x6e, # .Usage (Vendor Usage 0x6e) 307
  315. 0xa1, 0x02, # .Collection (Logical) 309
  316. 0x85, 0x0e, # ..Report ID (14) 311
  317. 0x09, 0x22, # ..Usage (Vendor Usage 0x22) 313
  318. 0x15, 0x00, # ..Logical Minimum (0) 315
  319. 0x26, 0xff, 0x00, # ..Logical Maximum (255) 317
  320. 0x35, 0x00, # ..Physical Minimum (0) 320
  321. 0x45, 0x00, # ..Physical Maximum (0) 322
  322. 0x91, 0x02, # ..Output (Data,Var,Abs) 324
  323. 0x09, 0x70, # ..Usage (Vendor Usage 0x70) 326
  324. 0x25, 0x7f, # ..Logical Maximum (127) 328
  325. 0x46, 0x10, 0x27, # ..Physical Maximum (10000) 330
  326. 0x91, 0x02, # ..Output (Data,Var,Abs) 333
  327. 0x09, 0x6f, # ..Usage (Vendor Usage 0x6f) 335
  328. 0x15, 0x81, # ..Logical Minimum (-127) 337
  329. 0x36, 0xf0, 0xd8, # ..Physical Minimum (-10000) 339
  330. 0x91, 0x02, # ..Output (Data,Var,Abs) 342
  331. 0x09, 0x71, # ..Usage (Vendor Usage 0x71) 344
  332. 0x15, 0x00, # ..Logical Minimum (0) 346
  333. 0x26, 0xff, 0x00, # ..Logical Maximum (255) 348
  334. 0x35, 0x00, # ..Physical Minimum (0) 351
  335. 0x46, 0x68, 0x01, # ..Physical Maximum (360) 353
  336. 0x91, 0x02, # ..Output (Data,Var,Abs) 356
  337. 0x09, 0x72, # ..Usage (Vendor Usage 0x72) 358
  338. 0x75, 0x10, # ..Report Size (16) 360
  339. 0x26, 0x10, 0x27, # ..Logical Maximum (10000) 362
  340. 0x46, 0x10, 0x27, # ..Physical Maximum (10000) 365
  341. 0x55, 0xfd, # ..Unit Exponent (237) 368
  342. 0x66, 0x01, 0x10, # ..Unit (Seconds,SILinear) 370
  343. 0x91, 0x02, # ..Output (Data,Var,Abs) 373
  344. 0x55, 0x00, # ..Unit Exponent (0) 375
  345. 0x65, 0x00, # ..Unit (None) 377
  346. 0xc0, # .End Collection 379
  347. 0x09, 0x77, # .Usage (Vendor Usage 0x77) 380
  348. 0xa1, 0x02, # .Collection (Logical) 382
  349. 0x85, 0x51, # ..Report ID (81) 384
  350. 0x09, 0x22, # ..Usage (Vendor Usage 0x22) 386
  351. 0x25, 0x7f, # ..Logical Maximum (127) 388
  352. 0x45, 0x00, # ..Physical Maximum (0) 390
  353. 0x75, 0x08, # ..Report Size (8) 392
  354. 0x91, 0x02, # ..Output (Data,Var,Abs) 394
  355. 0x09, 0x78, # ..Usage (Vendor Usage 0x78) 396
  356. 0xa1, 0x02, # ..Collection (Logical) 398
  357. 0x09, 0x7b, # ...Usage (Vendor Usage 0x7b) 400
  358. 0x09, 0x79, # ...Usage (Vendor Usage 0x79) 402
  359. 0x09, 0x7a, # ...Usage (Vendor Usage 0x7a) 404
  360. 0x15, 0x01, # ...Logical Minimum (1) 406
  361. 0x25, 0x03, # ...Logical Maximum (3) 408
  362. 0x91, 0x00, # ...Output (Data,Arr,Abs) 410
  363. 0xc0, # ..End Collection 412
  364. 0x09, 0x7c, # ..Usage (Vendor Usage 0x7c) 413
  365. 0x15, 0x00, # ..Logical Minimum (0) 415
  366. 0x26, 0xfe, 0x00, # ..Logical Maximum (254) 417
  367. 0x91, 0x02, # ..Output (Data,Var,Abs) 420
  368. 0xc0, # .End Collection 422
  369. 0x09, 0x92, # .Usage (Vendor Usage 0x92) 423
  370. 0xa1, 0x02, # .Collection (Logical) 425
  371. 0x85, 0x52, # ..Report ID (82) 427
  372. 0x09, 0x96, # ..Usage (Vendor Usage 0x96) 429
  373. 0xa1, 0x02, # ..Collection (Logical) 431
  374. 0x09, 0x9a, # ...Usage (Vendor Usage 0x9a) 433
  375. 0x09, 0x99, # ...Usage (Vendor Usage 0x99) 435
  376. 0x09, 0x97, # ...Usage (Vendor Usage 0x97) 437
  377. 0x09, 0x98, # ...Usage (Vendor Usage 0x98) 439
  378. 0x09, 0x9b, # ...Usage (Vendor Usage 0x9b) 441
  379. 0x09, 0x9c, # ...Usage (Vendor Usage 0x9c) 443
  380. 0x15, 0x01, # ...Logical Minimum (1) 445
  381. 0x25, 0x06, # ...Logical Maximum (6) 447
  382. 0x91, 0x00, # ...Output (Data,Arr,Abs) 449
  383. 0xc0, # ..End Collection 451
  384. 0xc0, # .End Collection 452
  385. 0x05, 0xff, # .Usage Page (Vendor Usage Page 0xff) 453
  386. 0x0a, 0x01, 0x03, # .Usage (Vendor Usage 0x301) 455
  387. 0xa1, 0x02, # .Collection (Logical) 458
  388. 0x85, 0x40, # ..Report ID (64) 460
  389. 0x0a, 0x02, 0x03, # ..Usage (Vendor Usage 0x302) 462
  390. 0xa1, 0x02, # ..Collection (Logical) 465
  391. 0x1a, 0x11, 0x03, # ...Usage Minimum (785) 467
  392. 0x2a, 0x20, 0x03, # ...Usage Maximum (800) 470
  393. 0x25, 0x10, # ...Logical Maximum (16) 473
  394. 0x91, 0x00, # ...Output (Data,Arr,Abs) 475
  395. 0xc0, # ..End Collection 477
  396. 0x0a, 0x03, 0x03, # ..Usage (Vendor Usage 0x303) 478
  397. 0x15, 0x00, # ..Logical Minimum (0) 481
  398. 0x27, 0xff, 0xff, 0x00, 0x00, # ..Logical Maximum (65535) 483
  399. 0x75, 0x10, # ..Report Size (16) 488
  400. 0x91, 0x02, # ..Output (Data,Var,Abs) 490
  401. 0xc0, # .End Collection 492
  402. 0x05, 0x0f, # .Usage Page (Vendor Usage Page 0x0f) 493
  403. 0x09, 0x7d, # .Usage (Vendor Usage 0x7d) 495
  404. 0xa1, 0x02, # .Collection (Logical) 497
  405. 0x85, 0x43, # ..Report ID (67) 499
  406. 0x09, 0x7e, # ..Usage (Vendor Usage 0x7e) 501
  407. 0x26, 0x80, 0x00, # ..Logical Maximum (128) 503
  408. 0x46, 0x10, 0x27, # ..Physical Maximum (10000) 506
  409. 0x75, 0x08, # ..Report Size (8) 509
  410. 0x91, 0x02, # ..Output (Data,Var,Abs) 511
  411. 0xc0, # .End Collection 513
  412. 0x09, 0x7f, # .Usage (Vendor Usage 0x7f) 514
  413. 0xa1, 0x02, # .Collection (Logical) 516
  414. 0x85, 0x0b, # ..Report ID (11) 518
  415. 0x09, 0x80, # ..Usage (Vendor Usage 0x80) 520
  416. 0x26, 0xff, 0x7f, # ..Logical Maximum (32767) 522
  417. 0x45, 0x00, # ..Physical Maximum (0) 525
  418. 0x75, 0x0f, # ..Report Size (15) 527
  419. 0xb1, 0x03, # ..Feature (Cnst,Var,Abs) 529
  420. 0x09, 0xa9, # ..Usage (Vendor Usage 0xa9) 531
  421. 0x25, 0x01, # ..Logical Maximum (1) 533
  422. 0x75, 0x01, # ..Report Size (1) 535
  423. 0xb1, 0x03, # ..Feature (Cnst,Var,Abs) 537
  424. 0x09, 0x83, # ..Usage (Vendor Usage 0x83) 539
  425. 0x26, 0xff, 0x00, # ..Logical Maximum (255) 541
  426. 0x75, 0x08, # ..Report Size (8) 544
  427. 0xb1, 0x03, # ..Feature (Cnst,Var,Abs) 546
  428. 0xc0, # .End Collection 548
  429. 0x09, 0xab, # .Usage (Vendor Usage 0xab) 549
  430. 0xa1, 0x03, # .Collection (Report) 551
  431. 0x85, 0x15, # ..Report ID (21) 553
  432. 0x09, 0x25, # ..Usage (Vendor Usage 0x25) 555
  433. 0xa1, 0x02, # ..Collection (Logical) 557
  434. 0x09, 0x26, # ...Usage (Vendor Usage 0x26) 559
  435. 0x09, 0x30, # ...Usage (Vendor Usage 0x30) 561
  436. 0x09, 0x32, # ...Usage (Vendor Usage 0x32) 563
  437. 0x09, 0x31, # ...Usage (Vendor Usage 0x31) 565
  438. 0x09, 0x33, # ...Usage (Vendor Usage 0x33) 567
  439. 0x09, 0x34, # ...Usage (Vendor Usage 0x34) 569
  440. 0x15, 0x01, # ...Logical Minimum (1) 571
  441. 0x25, 0x06, # ...Logical Maximum (6) 573
  442. 0xb1, 0x00, # ...Feature (Data,Arr,Abs) 575
  443. 0xc0, # ..End Collection 577
  444. 0xc0, # .End Collection 578
  445. 0x09, 0x89, # .Usage (Vendor Usage 0x89) 579
  446. 0xa1, 0x03, # .Collection (Report) 581
  447. 0x85, 0x16, # ..Report ID (22) 583
  448. 0x09, 0x8b, # ..Usage (Vendor Usage 0x8b) 585
  449. 0xa1, 0x02, # ..Collection (Logical) 587
  450. 0x09, 0x8c, # ...Usage (Vendor Usage 0x8c) 589
  451. 0x09, 0x8d, # ...Usage (Vendor Usage 0x8d) 591
  452. 0x09, 0x8e, # ...Usage (Vendor Usage 0x8e) 593
  453. 0x25, 0x03, # ...Logical Maximum (3) 595
  454. 0xb1, 0x00, # ...Feature (Data,Arr,Abs) 597
  455. 0xc0, # ..End Collection 599
  456. 0x09, 0x22, # ..Usage (Vendor Usage 0x22) 600
  457. 0x15, 0x00, # ..Logical Minimum (0) 602
  458. 0x26, 0xfe, 0x00, # ..Logical Maximum (254) 604
  459. 0xb1, 0x02, # ..Feature (Data,Var,Abs) 607
  460. 0xc0, # .End Collection 609
  461. 0x09, 0x90, # .Usage (Vendor Usage 0x90) 610
  462. 0xa1, 0x03, # .Collection (Report) 612
  463. 0x85, 0x50, # ..Report ID (80) 614
  464. 0x09, 0x22, # ..Usage (Vendor Usage 0x22) 616
  465. 0x26, 0xff, 0x00, # ..Logical Maximum (255) 618
  466. 0x91, 0x02, # ..Output (Data,Var,Abs) 621
  467. 0xc0, # .End Collection 623
  468. 0xc0, # End Collection 624
  469. ]
  470. # fmt: on
  471. def __init__(self, rdesc=report_descriptor, name=None):
  472. super().__init__(rdesc, name=name, input_info=(BusType.USB, 0x06A3, 0xFF0D))
  473. self.buttons = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
  474. class AsusGamepad(BaseGamepad):
  475. # fmt: off
  476. report_descriptor = [
  477. 0x05, 0x01, # Usage Page (Generic Desktop) 0
  478. 0x09, 0x05, # Usage (Game Pad) 2
  479. 0xa1, 0x01, # Collection (Application) 4
  480. 0x85, 0x01, # .Report ID (1) 6
  481. 0x05, 0x09, # .Usage Page (Button) 8
  482. 0x0a, 0x01, 0x00, # .Usage (Vendor Usage 0x01) 10
  483. 0x0a, 0x02, 0x00, # .Usage (Vendor Usage 0x02) 13
  484. 0x0a, 0x04, 0x00, # .Usage (Vendor Usage 0x04) 16
  485. 0x0a, 0x05, 0x00, # .Usage (Vendor Usage 0x05) 19
  486. 0x0a, 0x07, 0x00, # .Usage (Vendor Usage 0x07) 22
  487. 0x0a, 0x08, 0x00, # .Usage (Vendor Usage 0x08) 25
  488. 0x0a, 0x0e, 0x00, # .Usage (Vendor Usage 0x0e) 28
  489. 0x0a, 0x0f, 0x00, # .Usage (Vendor Usage 0x0f) 31
  490. 0x0a, 0x0d, 0x00, # .Usage (Vendor Usage 0x0d) 34
  491. 0x05, 0x0c, # .Usage Page (Consumer Devices) 37
  492. 0x0a, 0x24, 0x02, # .Usage (AC Back) 39
  493. 0x0a, 0x23, 0x02, # .Usage (AC Home) 42
  494. 0x15, 0x00, # .Logical Minimum (0) 45
  495. 0x25, 0x01, # .Logical Maximum (1) 47
  496. 0x75, 0x01, # .Report Size (1) 49
  497. 0x95, 0x0b, # .Report Count (11) 51
  498. 0x81, 0x02, # .Input (Data,Var,Abs) 53
  499. 0x75, 0x01, # .Report Size (1) 55
  500. 0x95, 0x01, # .Report Count (1) 57
  501. 0x81, 0x03, # .Input (Cnst,Var,Abs) 59
  502. 0x05, 0x01, # .Usage Page (Generic Desktop) 61
  503. 0x75, 0x04, # .Report Size (4) 63
  504. 0x95, 0x01, # .Report Count (1) 65
  505. 0x25, 0x07, # .Logical Maximum (7) 67
  506. 0x46, 0x3b, 0x01, # .Physical Maximum (315) 69
  507. 0x66, 0x14, 0x00, # .Unit (Degrees,EngRotation) 72
  508. 0x09, 0x39, # .Usage (Hat switch) 75
  509. 0x81, 0x42, # .Input (Data,Var,Abs,Null) 77
  510. 0x66, 0x00, 0x00, # .Unit (None) 79
  511. 0x09, 0x01, # .Usage (Pointer) 82
  512. 0xa1, 0x00, # .Collection (Physical) 84
  513. 0x09, 0x30, # ..Usage (X) 86
  514. 0x09, 0x31, # ..Usage (Y) 88
  515. 0x09, 0x32, # ..Usage (Z) 90
  516. 0x09, 0x35, # ..Usage (Rz) 92
  517. 0x05, 0x02, # ..Usage Page (Simulation Controls) 94
  518. 0x09, 0xc5, # ..Usage (Brake) 96
  519. 0x09, 0xc4, # ..Usage (Accelerator) 98
  520. 0x15, 0x00, # ..Logical Minimum (0) 100
  521. 0x26, 0xff, 0x00, # ..Logical Maximum (255) 102
  522. 0x35, 0x00, # ..Physical Minimum (0) 105
  523. 0x46, 0xff, 0x00, # ..Physical Maximum (255) 107
  524. 0x75, 0x08, # ..Report Size (8) 110
  525. 0x95, 0x06, # ..Report Count (6) 112
  526. 0x81, 0x02, # ..Input (Data,Var,Abs) 114
  527. 0xc0, # .End Collection 116
  528. 0x85, 0x02, # .Report ID (2) 117
  529. 0x05, 0x08, # .Usage Page (LEDs) 119
  530. 0x0a, 0x01, 0x00, # .Usage (Num Lock) 121
  531. 0x0a, 0x02, 0x00, # .Usage (Caps Lock) 124
  532. 0x0a, 0x03, 0x00, # .Usage (Scroll Lock) 127
  533. 0x0a, 0x04, 0x00, # .Usage (Compose) 130
  534. 0x15, 0x00, # .Logical Minimum (0) 133
  535. 0x25, 0x01, # .Logical Maximum (1) 135
  536. 0x75, 0x01, # .Report Size (1) 137
  537. 0x95, 0x04, # .Report Count (4) 139
  538. 0x91, 0x02, # .Output (Data,Var,Abs) 141
  539. 0x75, 0x04, # .Report Size (4) 143
  540. 0x95, 0x01, # .Report Count (1) 145
  541. 0x91, 0x03, # .Output (Cnst,Var,Abs) 147
  542. 0xc0, # End Collection 149
  543. 0x05, 0x0c, # Usage Page (Consumer Devices) 150
  544. 0x09, 0x01, # Usage (Consumer Control) 152
  545. 0xa1, 0x01, # Collection (Application) 154
  546. 0x85, 0x03, # .Report ID (3) 156
  547. 0x05, 0x01, # .Usage Page (Generic Desktop) 158
  548. 0x09, 0x06, # .Usage (Keyboard) 160
  549. 0xa1, 0x02, # .Collection (Logical) 162
  550. 0x05, 0x06, # ..Usage Page (Generic Device Controls) 164
  551. 0x09, 0x20, # ..Usage (Battery Strength) 166
  552. 0x15, 0x00, # ..Logical Minimum (0) 168
  553. 0x26, 0xff, 0x00, # ..Logical Maximum (255) 170
  554. 0x75, 0x08, # ..Report Size (8) 173
  555. 0x95, 0x01, # ..Report Count (1) 175
  556. 0x81, 0x02, # ..Input (Data,Var,Abs) 177
  557. 0x06, 0xbc, 0xff, # ..Usage Page (Vendor Usage Page 0xffbc) 179
  558. 0x0a, 0xad, 0xbd, # ..Usage (Vendor Usage 0xbdad) 182
  559. 0x75, 0x08, # ..Report Size (8) 185
  560. 0x95, 0x06, # ..Report Count (6) 187
  561. 0x81, 0x02, # ..Input (Data,Var,Abs) 189
  562. 0xc0, # .End Collection 191
  563. 0xc0, # End Collection 192
  564. ]
  565. # fmt: on
  566. def __init__(self, rdesc=report_descriptor, name=None):
  567. super().__init__(rdesc, name=name, input_info=(BusType.USB, 0x18D1, 0x2C40))
  568. self.buttons = (1, 2, 4, 5, 7, 8, 14, 15, 13)
  569. class RaptorMach2Joystick(JoystickGamepad):
  570. axes_map = {
  571. "left_stick": {
  572. "x": AxisMapping("x"),
  573. "y": AxisMapping("y"),
  574. },
  575. "right_stick": {
  576. "x": AxisMapping("z"),
  577. "y": AxisMapping("Rz"),
  578. },
  579. }
  580. def __init__(
  581. self,
  582. name,
  583. rdesc=None,
  584. application="Joystick",
  585. input_info=(BusType.USB, 0x11C0, 0x5606),
  586. ):
  587. super().__init__(rdesc, application, name, input_info)
  588. self.buttons = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
  589. self.hat_switch = 240 # null value is 240 as max is 239
  590. def event(
  591. self, *, left=(None, None), right=(None, None), hat_switch=None, buttons=None
  592. ):
  593. if hat_switch is not None:
  594. hat_switch *= 30
  595. return super().event(
  596. left=left, right=right, hat_switch=hat_switch, buttons=buttons
  597. )
  598. class TestSaitekGamepad(BaseTest.TestGamepad):
  599. def create_device(self):
  600. return SaitekGamepad()
  601. class TestAsusGamepad(BaseTest.TestGamepad):
  602. def create_device(self):
  603. return AsusGamepad()
  604. class TestRaptorMach2Joystick(BaseTest.TestGamepad):
  605. hid_bpfs = [HidBpf("FR-TEC__Raptor-Mach-2.bpf.o", True)]
  606. def create_device(self):
  607. return RaptorMach2Joystick(
  608. "uhid test Sanmos Group FR-TEC Raptor MACH 2",
  609. rdesc="05 01 09 04 a1 01 05 01 85 01 05 01 09 30 75 10 95 01 15 00 26 ff 07 46 ff 07 81 02 05 01 09 31 75 10 95 01 15 00 26 ff 07 46 ff 07 81 02 05 01 09 33 75 10 95 01 15 00 26 ff 03 46 ff 03 81 02 05 00 09 00 75 10 95 01 15 00 26 ff 03 46 ff 03 81 02 05 01 09 32 75 10 95 01 15 00 26 ff 03 46 ff 03 81 02 05 01 09 35 75 10 95 01 15 00 26 ff 03 46 ff 03 81 02 05 01 09 34 75 10 95 01 15 00 26 ff 07 46 ff 07 81 02 05 01 09 36 75 10 95 01 15 00 26 ff 03 46 ff 03 81 02 05 09 19 01 2a 1d 00 15 00 25 01 75 01 96 80 00 81 02 05 01 09 39 26 ef 00 46 68 01 65 14 75 10 95 01 81 42 05 01 09 00 75 08 95 1d 81 01 15 00 26 ef 00 85 58 26 ff 00 46 ff 00 75 08 95 3f 09 00 91 02 85 59 75 08 95 80 09 00 b1 02 c0",
  610. input_info=(BusType.USB, 0x11C0, 0x5606),
  611. )