665 lines · python
1#!/bin/env python32# SPDX-License-Identifier: GPL-2.03# -*- coding: utf-8 -*-4#5# Copyright (c) 2019 Benjamin Tissoires <benjamin.tissoires@gmail.com>6# Copyright (c) 2019 Red Hat, Inc.7#8 9from . import base10import libevdev11import pytest12 13from .base_gamepad import BaseGamepad, JoystickGamepad, AxisMapping14from hidtools.util import BusType15 16import logging17 18logger = logging.getLogger("hidtools.test.gamepad")19 20 21class BaseTest:22 class TestGamepad(base.BaseTestCase.TestUhid):23 @pytest.fixture(autouse=True)24 def send_initial_state(self):25 """send an empty report to initialize the axes"""26 uhdev = self.uhdev27 28 r = uhdev.event()29 events = uhdev.next_sync_events()30 self.debug_reports(r, uhdev, events)31 32 def assert_button(self, button):33 uhdev = self.uhdev34 evdev = uhdev.get_evdev()35 syn_event = self.syn_event36 37 buttons = {}38 key = libevdev.evbit(uhdev.buttons_map[button])39 40 buttons[button] = True41 r = uhdev.event(buttons=buttons)42 expected_event = libevdev.InputEvent(key, 1)43 events = uhdev.next_sync_events()44 self.debug_reports(r, uhdev, events)45 self.assertInputEventsIn((syn_event, expected_event), events)46 assert evdev.value[key] == 147 48 buttons[button] = False49 r = uhdev.event(buttons=buttons)50 expected_event = libevdev.InputEvent(key, 0)51 events = uhdev.next_sync_events()52 self.debug_reports(r, uhdev, events)53 self.assertInputEventsIn((syn_event, expected_event), events)54 assert evdev.value[key] == 055 56 def test_buttons(self):57 """check for button reliability."""58 uhdev = self.uhdev59 60 for b in uhdev.buttons:61 self.assert_button(b)62 63 def test_dual_buttons(self):64 """check for button reliability when pressing 2 buttons"""65 uhdev = self.uhdev66 evdev = uhdev.get_evdev()67 syn_event = self.syn_event68 69 # can change intended b1 b2 values70 b1 = uhdev.buttons[0]71 key1 = libevdev.evbit(uhdev.buttons_map[b1])72 b2 = uhdev.buttons[1]73 key2 = libevdev.evbit(uhdev.buttons_map[b2])74 75 buttons = {b1: True, b2: True}76 r = uhdev.event(buttons=buttons)77 expected_event0 = libevdev.InputEvent(key1, 1)78 expected_event1 = libevdev.InputEvent(key2, 1)79 events = uhdev.next_sync_events()80 self.debug_reports(r, uhdev, events)81 self.assertInputEventsIn(82 (syn_event, expected_event0, expected_event1), events83 )84 assert evdev.value[key1] == 185 assert evdev.value[key2] == 186 87 buttons = {b1: False, b2: None}88 r = uhdev.event(buttons=buttons)89 expected_event = libevdev.InputEvent(key1, 0)90 events = uhdev.next_sync_events()91 self.debug_reports(r, uhdev, events)92 self.assertInputEventsIn((syn_event, expected_event), events)93 assert evdev.value[key1] == 094 assert evdev.value[key2] == 195 96 buttons = {b1: None, b2: False}97 r = uhdev.event(buttons=buttons)98 expected_event = libevdev.InputEvent(key2, 0)99 events = uhdev.next_sync_events()100 self.debug_reports(r, uhdev, events)101 self.assertInputEventsIn((syn_event, expected_event), events)102 assert evdev.value[key1] == 0103 assert evdev.value[key2] == 0104 105 def _get_libevdev_abs_events(self, which):106 """Returns which ABS_* evdev axes are expected for the given stick"""107 abs_map = self.uhdev.axes_map[which]108 109 x = abs_map["x"].evdev110 y = abs_map["y"].evdev111 112 assert x113 assert y114 115 return x, y116 117 def _test_joystick_press(self, which, data):118 uhdev = self.uhdev119 120 libevdev_axes = self._get_libevdev_abs_events(which)121 122 r = None123 if which == "left_stick":124 r = uhdev.event(left=data)125 else:126 r = uhdev.event(right=data)127 events = uhdev.next_sync_events()128 self.debug_reports(r, uhdev, events)129 130 for i, d in enumerate(data):131 if d is not None and d != 127:132 assert libevdev.InputEvent(libevdev_axes[i], d) in events133 else:134 assert libevdev.InputEvent(libevdev_axes[i]) not in events135 136 def test_left_joystick_press_left(self):137 """check for the left joystick reliability"""138 self._test_joystick_press("left_stick", (63, None))139 self._test_joystick_press("left_stick", (0, 127))140 141 def test_left_joystick_press_right(self):142 """check for the left joystick reliability"""143 self._test_joystick_press("left_stick", (191, 127))144 self._test_joystick_press("left_stick", (255, None))145 146 def test_left_joystick_press_up(self):147 """check for the left joystick reliability"""148 self._test_joystick_press("left_stick", (None, 63))149 self._test_joystick_press("left_stick", (127, 0))150 151 def test_left_joystick_press_down(self):152 """check for the left joystick reliability"""153 self._test_joystick_press("left_stick", (127, 191))154 self._test_joystick_press("left_stick", (None, 255))155 156 def test_right_joystick_press_left(self):157 """check for the right joystick reliability"""158 self._test_joystick_press("right_stick", (63, None))159 self._test_joystick_press("right_stick", (0, 127))160 161 def test_right_joystick_press_right(self):162 """check for the right joystick reliability"""163 self._test_joystick_press("right_stick", (191, 127))164 self._test_joystick_press("right_stick", (255, None))165 166 def test_right_joystick_press_up(self):167 """check for the right joystick reliability"""168 self._test_joystick_press("right_stick", (None, 63))169 self._test_joystick_press("right_stick", (127, 0))170 171 def test_right_joystick_press_down(self):172 """check for the right joystick reliability"""173 self._test_joystick_press("right_stick", (127, 191))174 self._test_joystick_press("right_stick", (None, 255))175 176 @pytest.mark.skip_if_uhdev(177 lambda uhdev: "Hat switch" not in uhdev.fields,178 "Device not compatible, missing Hat switch usage",179 )180 @pytest.mark.parametrize(181 "hat_value,expected_evdev,evdev_value",182 [183 (0, "ABS_HAT0Y", -1),184 (2, "ABS_HAT0X", 1),185 (4, "ABS_HAT0Y", 1),186 (6, "ABS_HAT0X", -1),187 ],188 )189 def test_hat_switch(self, hat_value, expected_evdev, evdev_value):190 uhdev = self.uhdev191 192 r = uhdev.event(hat_switch=hat_value)193 events = uhdev.next_sync_events()194 self.debug_reports(r, uhdev, events)195 assert (196 libevdev.InputEvent(197 libevdev.evbit("EV_ABS", expected_evdev), evdev_value198 )199 in events200 )201 202 203class SaitekGamepad(JoystickGamepad):204 # fmt: off205 report_descriptor = [206 0x05, 0x01, # Usage Page (Generic Desktop) 0207 0x09, 0x04, # Usage (Joystick) 2208 0xa1, 0x01, # Collection (Application) 4209 0x09, 0x01, # .Usage (Pointer) 6210 0xa1, 0x00, # .Collection (Physical) 8211 0x85, 0x01, # ..Report ID (1) 10212 0x09, 0x30, # ..Usage (X) 12213 0x15, 0x00, # ..Logical Minimum (0) 14214 0x26, 0xff, 0x00, # ..Logical Maximum (255) 16215 0x35, 0x00, # ..Physical Minimum (0) 19216 0x46, 0xff, 0x00, # ..Physical Maximum (255) 21217 0x75, 0x08, # ..Report Size (8) 24218 0x95, 0x01, # ..Report Count (1) 26219 0x81, 0x02, # ..Input (Data,Var,Abs) 28220 0x09, 0x31, # ..Usage (Y) 30221 0x81, 0x02, # ..Input (Data,Var,Abs) 32222 0x05, 0x02, # ..Usage Page (Simulation Controls) 34223 0x09, 0xba, # ..Usage (Rudder) 36224 0x81, 0x02, # ..Input (Data,Var,Abs) 38225 0x09, 0xbb, # ..Usage (Throttle) 40226 0x81, 0x02, # ..Input (Data,Var,Abs) 42227 0x05, 0x09, # ..Usage Page (Button) 44228 0x19, 0x01, # ..Usage Minimum (1) 46229 0x29, 0x0c, # ..Usage Maximum (12) 48230 0x25, 0x01, # ..Logical Maximum (1) 50231 0x45, 0x01, # ..Physical Maximum (1) 52232 0x75, 0x01, # ..Report Size (1) 54233 0x95, 0x0c, # ..Report Count (12) 56234 0x81, 0x02, # ..Input (Data,Var,Abs) 58235 0x95, 0x01, # ..Report Count (1) 60236 0x75, 0x00, # ..Report Size (0) 62237 0x81, 0x03, # ..Input (Cnst,Var,Abs) 64238 0x05, 0x01, # ..Usage Page (Generic Desktop) 66239 0x09, 0x39, # ..Usage (Hat switch) 68240 0x25, 0x07, # ..Logical Maximum (7) 70241 0x46, 0x3b, 0x01, # ..Physical Maximum (315) 72242 0x55, 0x00, # ..Unit Exponent (0) 75243 0x65, 0x44, # ..Unit (Degrees^4,EngRotation) 77244 0x75, 0x04, # ..Report Size (4) 79245 0x81, 0x42, # ..Input (Data,Var,Abs,Null) 81246 0x65, 0x00, # ..Unit (None) 83247 0xc0, # .End Collection 85248 0x05, 0x0f, # .Usage Page (Vendor Usage Page 0x0f) 86249 0x09, 0x92, # .Usage (Vendor Usage 0x92) 88250 0xa1, 0x02, # .Collection (Logical) 90251 0x85, 0x02, # ..Report ID (2) 92252 0x09, 0xa0, # ..Usage (Vendor Usage 0xa0) 94253 0x09, 0x9f, # ..Usage (Vendor Usage 0x9f) 96254 0x25, 0x01, # ..Logical Maximum (1) 98255 0x45, 0x00, # ..Physical Maximum (0) 100256 0x75, 0x01, # ..Report Size (1) 102257 0x95, 0x02, # ..Report Count (2) 104258 0x81, 0x02, # ..Input (Data,Var,Abs) 106259 0x75, 0x06, # ..Report Size (6) 108260 0x95, 0x01, # ..Report Count (1) 110261 0x81, 0x03, # ..Input (Cnst,Var,Abs) 112262 0x09, 0x22, # ..Usage (Vendor Usage 0x22) 114263 0x75, 0x07, # ..Report Size (7) 116264 0x25, 0x7f, # ..Logical Maximum (127) 118265 0x81, 0x02, # ..Input (Data,Var,Abs) 120266 0x09, 0x94, # ..Usage (Vendor Usage 0x94) 122267 0x75, 0x01, # ..Report Size (1) 124268 0x25, 0x01, # ..Logical Maximum (1) 126269 0x81, 0x02, # ..Input (Data,Var,Abs) 128270 0xc0, # .End Collection 130271 0x09, 0x21, # .Usage (Vendor Usage 0x21) 131272 0xa1, 0x02, # .Collection (Logical) 133273 0x85, 0x0b, # ..Report ID (11) 135274 0x09, 0x22, # ..Usage (Vendor Usage 0x22) 137275 0x26, 0xff, 0x00, # ..Logical Maximum (255) 139276 0x75, 0x08, # ..Report Size (8) 142277 0x91, 0x02, # ..Output (Data,Var,Abs) 144278 0x09, 0x53, # ..Usage (Vendor Usage 0x53) 146279 0x25, 0x0a, # ..Logical Maximum (10) 148280 0x91, 0x02, # ..Output (Data,Var,Abs) 150281 0x09, 0x50, # ..Usage (Vendor Usage 0x50) 152282 0x27, 0xfe, 0xff, 0x00, 0x00, # ..Logical Maximum (65534) 154283 0x47, 0xfe, 0xff, 0x00, 0x00, # ..Physical Maximum (65534) 159284 0x75, 0x10, # ..Report Size (16) 164285 0x55, 0xfd, # ..Unit Exponent (237) 166286 0x66, 0x01, 0x10, # ..Unit (Seconds,SILinear) 168287 0x91, 0x02, # ..Output (Data,Var,Abs) 171288 0x55, 0x00, # ..Unit Exponent (0) 173289 0x65, 0x00, # ..Unit (None) 175290 0x09, 0x54, # ..Usage (Vendor Usage 0x54) 177291 0x55, 0xfd, # ..Unit Exponent (237) 179292 0x66, 0x01, 0x10, # ..Unit (Seconds,SILinear) 181293 0x91, 0x02, # ..Output (Data,Var,Abs) 184294 0x55, 0x00, # ..Unit Exponent (0) 186295 0x65, 0x00, # ..Unit (None) 188296 0x09, 0xa7, # ..Usage (Vendor Usage 0xa7) 190297 0x55, 0xfd, # ..Unit Exponent (237) 192298 0x66, 0x01, 0x10, # ..Unit (Seconds,SILinear) 194299 0x91, 0x02, # ..Output (Data,Var,Abs) 197300 0x55, 0x00, # ..Unit Exponent (0) 199301 0x65, 0x00, # ..Unit (None) 201302 0xc0, # .End Collection 203303 0x09, 0x5a, # .Usage (Vendor Usage 0x5a) 204304 0xa1, 0x02, # .Collection (Logical) 206305 0x85, 0x0c, # ..Report ID (12) 208306 0x09, 0x22, # ..Usage (Vendor Usage 0x22) 210307 0x26, 0xff, 0x00, # ..Logical Maximum (255) 212308 0x45, 0x00, # ..Physical Maximum (0) 215309 0x75, 0x08, # ..Report Size (8) 217310 0x91, 0x02, # ..Output (Data,Var,Abs) 219311 0x09, 0x5c, # ..Usage (Vendor Usage 0x5c) 221312 0x26, 0x10, 0x27, # ..Logical Maximum (10000) 223313 0x46, 0x10, 0x27, # ..Physical Maximum (10000) 226314 0x75, 0x10, # ..Report Size (16) 229315 0x55, 0xfd, # ..Unit Exponent (237) 231316 0x66, 0x01, 0x10, # ..Unit (Seconds,SILinear) 233317 0x91, 0x02, # ..Output (Data,Var,Abs) 236318 0x55, 0x00, # ..Unit Exponent (0) 238319 0x65, 0x00, # ..Unit (None) 240320 0x09, 0x5b, # ..Usage (Vendor Usage 0x5b) 242321 0x25, 0x7f, # ..Logical Maximum (127) 244322 0x75, 0x08, # ..Report Size (8) 246323 0x91, 0x02, # ..Output (Data,Var,Abs) 248324 0x09, 0x5e, # ..Usage (Vendor Usage 0x5e) 250325 0x26, 0x10, 0x27, # ..Logical Maximum (10000) 252326 0x75, 0x10, # ..Report Size (16) 255327 0x55, 0xfd, # ..Unit Exponent (237) 257328 0x66, 0x01, 0x10, # ..Unit (Seconds,SILinear) 259329 0x91, 0x02, # ..Output (Data,Var,Abs) 262330 0x55, 0x00, # ..Unit Exponent (0) 264331 0x65, 0x00, # ..Unit (None) 266332 0x09, 0x5d, # ..Usage (Vendor Usage 0x5d) 268333 0x25, 0x7f, # ..Logical Maximum (127) 270334 0x75, 0x08, # ..Report Size (8) 272335 0x91, 0x02, # ..Output (Data,Var,Abs) 274336 0xc0, # .End Collection 276337 0x09, 0x73, # .Usage (Vendor Usage 0x73) 277338 0xa1, 0x02, # .Collection (Logical) 279339 0x85, 0x0d, # ..Report ID (13) 281340 0x09, 0x22, # ..Usage (Vendor Usage 0x22) 283341 0x26, 0xff, 0x00, # ..Logical Maximum (255) 285342 0x45, 0x00, # ..Physical Maximum (0) 288343 0x91, 0x02, # ..Output (Data,Var,Abs) 290344 0x09, 0x70, # ..Usage (Vendor Usage 0x70) 292345 0x15, 0x81, # ..Logical Minimum (-127) 294346 0x25, 0x7f, # ..Logical Maximum (127) 296347 0x36, 0xf0, 0xd8, # ..Physical Minimum (-10000) 298348 0x46, 0x10, 0x27, # ..Physical Maximum (10000) 301349 0x91, 0x02, # ..Output (Data,Var,Abs) 304350 0xc0, # .End Collection 306351 0x09, 0x6e, # .Usage (Vendor Usage 0x6e) 307352 0xa1, 0x02, # .Collection (Logical) 309353 0x85, 0x0e, # ..Report ID (14) 311354 0x09, 0x22, # ..Usage (Vendor Usage 0x22) 313355 0x15, 0x00, # ..Logical Minimum (0) 315356 0x26, 0xff, 0x00, # ..Logical Maximum (255) 317357 0x35, 0x00, # ..Physical Minimum (0) 320358 0x45, 0x00, # ..Physical Maximum (0) 322359 0x91, 0x02, # ..Output (Data,Var,Abs) 324360 0x09, 0x70, # ..Usage (Vendor Usage 0x70) 326361 0x25, 0x7f, # ..Logical Maximum (127) 328362 0x46, 0x10, 0x27, # ..Physical Maximum (10000) 330363 0x91, 0x02, # ..Output (Data,Var,Abs) 333364 0x09, 0x6f, # ..Usage (Vendor Usage 0x6f) 335365 0x15, 0x81, # ..Logical Minimum (-127) 337366 0x36, 0xf0, 0xd8, # ..Physical Minimum (-10000) 339367 0x91, 0x02, # ..Output (Data,Var,Abs) 342368 0x09, 0x71, # ..Usage (Vendor Usage 0x71) 344369 0x15, 0x00, # ..Logical Minimum (0) 346370 0x26, 0xff, 0x00, # ..Logical Maximum (255) 348371 0x35, 0x00, # ..Physical Minimum (0) 351372 0x46, 0x68, 0x01, # ..Physical Maximum (360) 353373 0x91, 0x02, # ..Output (Data,Var,Abs) 356374 0x09, 0x72, # ..Usage (Vendor Usage 0x72) 358375 0x75, 0x10, # ..Report Size (16) 360376 0x26, 0x10, 0x27, # ..Logical Maximum (10000) 362377 0x46, 0x10, 0x27, # ..Physical Maximum (10000) 365378 0x55, 0xfd, # ..Unit Exponent (237) 368379 0x66, 0x01, 0x10, # ..Unit (Seconds,SILinear) 370380 0x91, 0x02, # ..Output (Data,Var,Abs) 373381 0x55, 0x00, # ..Unit Exponent (0) 375382 0x65, 0x00, # ..Unit (None) 377383 0xc0, # .End Collection 379384 0x09, 0x77, # .Usage (Vendor Usage 0x77) 380385 0xa1, 0x02, # .Collection (Logical) 382386 0x85, 0x51, # ..Report ID (81) 384387 0x09, 0x22, # ..Usage (Vendor Usage 0x22) 386388 0x25, 0x7f, # ..Logical Maximum (127) 388389 0x45, 0x00, # ..Physical Maximum (0) 390390 0x75, 0x08, # ..Report Size (8) 392391 0x91, 0x02, # ..Output (Data,Var,Abs) 394392 0x09, 0x78, # ..Usage (Vendor Usage 0x78) 396393 0xa1, 0x02, # ..Collection (Logical) 398394 0x09, 0x7b, # ...Usage (Vendor Usage 0x7b) 400395 0x09, 0x79, # ...Usage (Vendor Usage 0x79) 402396 0x09, 0x7a, # ...Usage (Vendor Usage 0x7a) 404397 0x15, 0x01, # ...Logical Minimum (1) 406398 0x25, 0x03, # ...Logical Maximum (3) 408399 0x91, 0x00, # ...Output (Data,Arr,Abs) 410400 0xc0, # ..End Collection 412401 0x09, 0x7c, # ..Usage (Vendor Usage 0x7c) 413402 0x15, 0x00, # ..Logical Minimum (0) 415403 0x26, 0xfe, 0x00, # ..Logical Maximum (254) 417404 0x91, 0x02, # ..Output (Data,Var,Abs) 420405 0xc0, # .End Collection 422406 0x09, 0x92, # .Usage (Vendor Usage 0x92) 423407 0xa1, 0x02, # .Collection (Logical) 425408 0x85, 0x52, # ..Report ID (82) 427409 0x09, 0x96, # ..Usage (Vendor Usage 0x96) 429410 0xa1, 0x02, # ..Collection (Logical) 431411 0x09, 0x9a, # ...Usage (Vendor Usage 0x9a) 433412 0x09, 0x99, # ...Usage (Vendor Usage 0x99) 435413 0x09, 0x97, # ...Usage (Vendor Usage 0x97) 437414 0x09, 0x98, # ...Usage (Vendor Usage 0x98) 439415 0x09, 0x9b, # ...Usage (Vendor Usage 0x9b) 441416 0x09, 0x9c, # ...Usage (Vendor Usage 0x9c) 443417 0x15, 0x01, # ...Logical Minimum (1) 445418 0x25, 0x06, # ...Logical Maximum (6) 447419 0x91, 0x00, # ...Output (Data,Arr,Abs) 449420 0xc0, # ..End Collection 451421 0xc0, # .End Collection 452422 0x05, 0xff, # .Usage Page (Vendor Usage Page 0xff) 453423 0x0a, 0x01, 0x03, # .Usage (Vendor Usage 0x301) 455424 0xa1, 0x02, # .Collection (Logical) 458425 0x85, 0x40, # ..Report ID (64) 460426 0x0a, 0x02, 0x03, # ..Usage (Vendor Usage 0x302) 462427 0xa1, 0x02, # ..Collection (Logical) 465428 0x1a, 0x11, 0x03, # ...Usage Minimum (785) 467429 0x2a, 0x20, 0x03, # ...Usage Maximum (800) 470430 0x25, 0x10, # ...Logical Maximum (16) 473431 0x91, 0x00, # ...Output (Data,Arr,Abs) 475432 0xc0, # ..End Collection 477433 0x0a, 0x03, 0x03, # ..Usage (Vendor Usage 0x303) 478434 0x15, 0x00, # ..Logical Minimum (0) 481435 0x27, 0xff, 0xff, 0x00, 0x00, # ..Logical Maximum (65535) 483436 0x75, 0x10, # ..Report Size (16) 488437 0x91, 0x02, # ..Output (Data,Var,Abs) 490438 0xc0, # .End Collection 492439 0x05, 0x0f, # .Usage Page (Vendor Usage Page 0x0f) 493440 0x09, 0x7d, # .Usage (Vendor Usage 0x7d) 495441 0xa1, 0x02, # .Collection (Logical) 497442 0x85, 0x43, # ..Report ID (67) 499443 0x09, 0x7e, # ..Usage (Vendor Usage 0x7e) 501444 0x26, 0x80, 0x00, # ..Logical Maximum (128) 503445 0x46, 0x10, 0x27, # ..Physical Maximum (10000) 506446 0x75, 0x08, # ..Report Size (8) 509447 0x91, 0x02, # ..Output (Data,Var,Abs) 511448 0xc0, # .End Collection 513449 0x09, 0x7f, # .Usage (Vendor Usage 0x7f) 514450 0xa1, 0x02, # .Collection (Logical) 516451 0x85, 0x0b, # ..Report ID (11) 518452 0x09, 0x80, # ..Usage (Vendor Usage 0x80) 520453 0x26, 0xff, 0x7f, # ..Logical Maximum (32767) 522454 0x45, 0x00, # ..Physical Maximum (0) 525455 0x75, 0x0f, # ..Report Size (15) 527456 0xb1, 0x03, # ..Feature (Cnst,Var,Abs) 529457 0x09, 0xa9, # ..Usage (Vendor Usage 0xa9) 531458 0x25, 0x01, # ..Logical Maximum (1) 533459 0x75, 0x01, # ..Report Size (1) 535460 0xb1, 0x03, # ..Feature (Cnst,Var,Abs) 537461 0x09, 0x83, # ..Usage (Vendor Usage 0x83) 539462 0x26, 0xff, 0x00, # ..Logical Maximum (255) 541463 0x75, 0x08, # ..Report Size (8) 544464 0xb1, 0x03, # ..Feature (Cnst,Var,Abs) 546465 0xc0, # .End Collection 548466 0x09, 0xab, # .Usage (Vendor Usage 0xab) 549467 0xa1, 0x03, # .Collection (Report) 551468 0x85, 0x15, # ..Report ID (21) 553469 0x09, 0x25, # ..Usage (Vendor Usage 0x25) 555470 0xa1, 0x02, # ..Collection (Logical) 557471 0x09, 0x26, # ...Usage (Vendor Usage 0x26) 559472 0x09, 0x30, # ...Usage (Vendor Usage 0x30) 561473 0x09, 0x32, # ...Usage (Vendor Usage 0x32) 563474 0x09, 0x31, # ...Usage (Vendor Usage 0x31) 565475 0x09, 0x33, # ...Usage (Vendor Usage 0x33) 567476 0x09, 0x34, # ...Usage (Vendor Usage 0x34) 569477 0x15, 0x01, # ...Logical Minimum (1) 571478 0x25, 0x06, # ...Logical Maximum (6) 573479 0xb1, 0x00, # ...Feature (Data,Arr,Abs) 575480 0xc0, # ..End Collection 577481 0xc0, # .End Collection 578482 0x09, 0x89, # .Usage (Vendor Usage 0x89) 579483 0xa1, 0x03, # .Collection (Report) 581484 0x85, 0x16, # ..Report ID (22) 583485 0x09, 0x8b, # ..Usage (Vendor Usage 0x8b) 585486 0xa1, 0x02, # ..Collection (Logical) 587487 0x09, 0x8c, # ...Usage (Vendor Usage 0x8c) 589488 0x09, 0x8d, # ...Usage (Vendor Usage 0x8d) 591489 0x09, 0x8e, # ...Usage (Vendor Usage 0x8e) 593490 0x25, 0x03, # ...Logical Maximum (3) 595491 0xb1, 0x00, # ...Feature (Data,Arr,Abs) 597492 0xc0, # ..End Collection 599493 0x09, 0x22, # ..Usage (Vendor Usage 0x22) 600494 0x15, 0x00, # ..Logical Minimum (0) 602495 0x26, 0xfe, 0x00, # ..Logical Maximum (254) 604496 0xb1, 0x02, # ..Feature (Data,Var,Abs) 607497 0xc0, # .End Collection 609498 0x09, 0x90, # .Usage (Vendor Usage 0x90) 610499 0xa1, 0x03, # .Collection (Report) 612500 0x85, 0x50, # ..Report ID (80) 614501 0x09, 0x22, # ..Usage (Vendor Usage 0x22) 616502 0x26, 0xff, 0x00, # ..Logical Maximum (255) 618503 0x91, 0x02, # ..Output (Data,Var,Abs) 621504 0xc0, # .End Collection 623505 0xc0, # End Collection 624506 ]507 # fmt: on508 509 def __init__(self, rdesc=report_descriptor, name=None):510 super().__init__(rdesc, name=name, input_info=(BusType.USB, 0x06A3, 0xFF0D))511 self.buttons = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)512 513 514class AsusGamepad(BaseGamepad):515 # fmt: off516 report_descriptor = [517 0x05, 0x01, # Usage Page (Generic Desktop) 0518 0x09, 0x05, # Usage (Game Pad) 2519 0xa1, 0x01, # Collection (Application) 4520 0x85, 0x01, # .Report ID (1) 6521 0x05, 0x09, # .Usage Page (Button) 8522 0x0a, 0x01, 0x00, # .Usage (Vendor Usage 0x01) 10523 0x0a, 0x02, 0x00, # .Usage (Vendor Usage 0x02) 13524 0x0a, 0x04, 0x00, # .Usage (Vendor Usage 0x04) 16525 0x0a, 0x05, 0x00, # .Usage (Vendor Usage 0x05) 19526 0x0a, 0x07, 0x00, # .Usage (Vendor Usage 0x07) 22527 0x0a, 0x08, 0x00, # .Usage (Vendor Usage 0x08) 25528 0x0a, 0x0e, 0x00, # .Usage (Vendor Usage 0x0e) 28529 0x0a, 0x0f, 0x00, # .Usage (Vendor Usage 0x0f) 31530 0x0a, 0x0d, 0x00, # .Usage (Vendor Usage 0x0d) 34531 0x05, 0x0c, # .Usage Page (Consumer Devices) 37532 0x0a, 0x24, 0x02, # .Usage (AC Back) 39533 0x0a, 0x23, 0x02, # .Usage (AC Home) 42534 0x15, 0x00, # .Logical Minimum (0) 45535 0x25, 0x01, # .Logical Maximum (1) 47536 0x75, 0x01, # .Report Size (1) 49537 0x95, 0x0b, # .Report Count (11) 51538 0x81, 0x02, # .Input (Data,Var,Abs) 53539 0x75, 0x01, # .Report Size (1) 55540 0x95, 0x01, # .Report Count (1) 57541 0x81, 0x03, # .Input (Cnst,Var,Abs) 59542 0x05, 0x01, # .Usage Page (Generic Desktop) 61543 0x75, 0x04, # .Report Size (4) 63544 0x95, 0x01, # .Report Count (1) 65545 0x25, 0x07, # .Logical Maximum (7) 67546 0x46, 0x3b, 0x01, # .Physical Maximum (315) 69547 0x66, 0x14, 0x00, # .Unit (Degrees,EngRotation) 72548 0x09, 0x39, # .Usage (Hat switch) 75549 0x81, 0x42, # .Input (Data,Var,Abs,Null) 77550 0x66, 0x00, 0x00, # .Unit (None) 79551 0x09, 0x01, # .Usage (Pointer) 82552 0xa1, 0x00, # .Collection (Physical) 84553 0x09, 0x30, # ..Usage (X) 86554 0x09, 0x31, # ..Usage (Y) 88555 0x09, 0x32, # ..Usage (Z) 90556 0x09, 0x35, # ..Usage (Rz) 92557 0x05, 0x02, # ..Usage Page (Simulation Controls) 94558 0x09, 0xc5, # ..Usage (Brake) 96559 0x09, 0xc4, # ..Usage (Accelerator) 98560 0x15, 0x00, # ..Logical Minimum (0) 100561 0x26, 0xff, 0x00, # ..Logical Maximum (255) 102562 0x35, 0x00, # ..Physical Minimum (0) 105563 0x46, 0xff, 0x00, # ..Physical Maximum (255) 107564 0x75, 0x08, # ..Report Size (8) 110565 0x95, 0x06, # ..Report Count (6) 112566 0x81, 0x02, # ..Input (Data,Var,Abs) 114567 0xc0, # .End Collection 116568 0x85, 0x02, # .Report ID (2) 117569 0x05, 0x08, # .Usage Page (LEDs) 119570 0x0a, 0x01, 0x00, # .Usage (Num Lock) 121571 0x0a, 0x02, 0x00, # .Usage (Caps Lock) 124572 0x0a, 0x03, 0x00, # .Usage (Scroll Lock) 127573 0x0a, 0x04, 0x00, # .Usage (Compose) 130574 0x15, 0x00, # .Logical Minimum (0) 133575 0x25, 0x01, # .Logical Maximum (1) 135576 0x75, 0x01, # .Report Size (1) 137577 0x95, 0x04, # .Report Count (4) 139578 0x91, 0x02, # .Output (Data,Var,Abs) 141579 0x75, 0x04, # .Report Size (4) 143580 0x95, 0x01, # .Report Count (1) 145581 0x91, 0x03, # .Output (Cnst,Var,Abs) 147582 0xc0, # End Collection 149583 0x05, 0x0c, # Usage Page (Consumer Devices) 150584 0x09, 0x01, # Usage (Consumer Control) 152585 0xa1, 0x01, # Collection (Application) 154586 0x85, 0x03, # .Report ID (3) 156587 0x05, 0x01, # .Usage Page (Generic Desktop) 158588 0x09, 0x06, # .Usage (Keyboard) 160589 0xa1, 0x02, # .Collection (Logical) 162590 0x05, 0x06, # ..Usage Page (Generic Device Controls) 164591 0x09, 0x20, # ..Usage (Battery Strength) 166592 0x15, 0x00, # ..Logical Minimum (0) 168593 0x26, 0xff, 0x00, # ..Logical Maximum (255) 170594 0x75, 0x08, # ..Report Size (8) 173595 0x95, 0x01, # ..Report Count (1) 175596 0x81, 0x02, # ..Input (Data,Var,Abs) 177597 0x06, 0xbc, 0xff, # ..Usage Page (Vendor Usage Page 0xffbc) 179598 0x0a, 0xad, 0xbd, # ..Usage (Vendor Usage 0xbdad) 182599 0x75, 0x08, # ..Report Size (8) 185600 0x95, 0x06, # ..Report Count (6) 187601 0x81, 0x02, # ..Input (Data,Var,Abs) 189602 0xc0, # .End Collection 191603 0xc0, # End Collection 192604 ]605 # fmt: on606 607 def __init__(self, rdesc=report_descriptor, name=None):608 super().__init__(rdesc, name=name, input_info=(BusType.USB, 0x18D1, 0x2C40))609 self.buttons = (1, 2, 4, 5, 7, 8, 14, 15, 13)610 611 612class RaptorMach2Joystick(JoystickGamepad):613 axes_map = {614 "left_stick": {615 "x": AxisMapping("x"),616 "y": AxisMapping("y"),617 },618 "right_stick": {619 "x": AxisMapping("z"),620 "y": AxisMapping("Rz"),621 },622 }623 624 def __init__(625 self,626 name,627 rdesc=None,628 application="Joystick",629 input_info=(BusType.USB, 0x11C0, 0x5606),630 ):631 super().__init__(rdesc, application, name, input_info)632 self.buttons = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)633 self.hat_switch = 240 # null value is 240 as max is 239634 635 def event(636 self, *, left=(None, None), right=(None, None), hat_switch=None, buttons=None637 ):638 if hat_switch is not None:639 hat_switch *= 30640 641 return super().event(642 left=left, right=right, hat_switch=hat_switch, buttons=buttons643 )644 645 646class TestSaitekGamepad(BaseTest.TestGamepad):647 def create_device(self):648 return SaitekGamepad()649 650 651class TestAsusGamepad(BaseTest.TestGamepad):652 def create_device(self):653 return AsusGamepad()654 655 656class TestRaptorMach2Joystick(BaseTest.TestGamepad):657 hid_bpfs = [("FR-TEC__Raptor-Mach-2.bpf.o", True)]658 659 def create_device(self):660 return RaptorMach2Joystick(661 "uhid test Sanmos Group FR-TEC Raptor MACH 2",662 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",663 input_info=(BusType.USB, 0x11C0, 0x5606),664 )665