665 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			665 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #! /usr/bin/python3 -sP
 | |
| # SPDX-License-Identifier: GPL-2.0
 | |
| # -*- coding: utf-8 -*-
 | |
| #
 | |
| # Copyright (c) 2019 Benjamin Tissoires <benjamin.tissoires@gmail.com>
 | |
| # Copyright (c) 2019 Red Hat, Inc.
 | |
| #
 | |
| 
 | |
| from . import base
 | |
| import libevdev
 | |
| import pytest
 | |
| 
 | |
| from .base_gamepad import BaseGamepad, JoystickGamepad, AxisMapping
 | |
| from hidtools.util import BusType
 | |
| 
 | |
| import logging
 | |
| 
 | |
| logger = logging.getLogger("hidtools.test.gamepad")
 | |
| 
 | |
| 
 | |
| class BaseTest:
 | |
|     class TestGamepad(base.BaseTestCase.TestUhid):
 | |
|         @pytest.fixture(autouse=True)
 | |
|         def send_initial_state(self):
 | |
|             """send an empty report to initialize the axes"""
 | |
|             uhdev = self.uhdev
 | |
| 
 | |
|             r = uhdev.event()
 | |
|             events = uhdev.next_sync_events()
 | |
|             self.debug_reports(r, uhdev, events)
 | |
| 
 | |
|         def assert_button(self, button):
 | |
|             uhdev = self.uhdev
 | |
|             evdev = uhdev.get_evdev()
 | |
|             syn_event = self.syn_event
 | |
| 
 | |
|             buttons = {}
 | |
|             key = libevdev.evbit(uhdev.buttons_map[button])
 | |
| 
 | |
|             buttons[button] = True
 | |
|             r = uhdev.event(buttons=buttons)
 | |
|             expected_event = libevdev.InputEvent(key, 1)
 | |
|             events = uhdev.next_sync_events()
 | |
|             self.debug_reports(r, uhdev, events)
 | |
|             self.assertInputEventsIn((syn_event, expected_event), events)
 | |
|             assert evdev.value[key] == 1
 | |
| 
 | |
|             buttons[button] = False
 | |
|             r = uhdev.event(buttons=buttons)
 | |
|             expected_event = libevdev.InputEvent(key, 0)
 | |
|             events = uhdev.next_sync_events()
 | |
|             self.debug_reports(r, uhdev, events)
 | |
|             self.assertInputEventsIn((syn_event, expected_event), events)
 | |
|             assert evdev.value[key] == 0
 | |
| 
 | |
|         def test_buttons(self):
 | |
|             """check for button reliability."""
 | |
|             uhdev = self.uhdev
 | |
| 
 | |
|             for b in uhdev.buttons:
 | |
|                 self.assert_button(b)
 | |
| 
 | |
|         def test_dual_buttons(self):
 | |
|             """check for button reliability when pressing 2 buttons"""
 | |
|             uhdev = self.uhdev
 | |
|             evdev = uhdev.get_evdev()
 | |
|             syn_event = self.syn_event
 | |
| 
 | |
|             # can change intended b1 b2 values
 | |
|             b1 = uhdev.buttons[0]
 | |
|             key1 = libevdev.evbit(uhdev.buttons_map[b1])
 | |
|             b2 = uhdev.buttons[1]
 | |
|             key2 = libevdev.evbit(uhdev.buttons_map[b2])
 | |
| 
 | |
|             buttons = {b1: True, b2: True}
 | |
|             r = uhdev.event(buttons=buttons)
 | |
|             expected_event0 = libevdev.InputEvent(key1, 1)
 | |
|             expected_event1 = libevdev.InputEvent(key2, 1)
 | |
|             events = uhdev.next_sync_events()
 | |
|             self.debug_reports(r, uhdev, events)
 | |
|             self.assertInputEventsIn(
 | |
|                 (syn_event, expected_event0, expected_event1), events
 | |
|             )
 | |
|             assert evdev.value[key1] == 1
 | |
|             assert evdev.value[key2] == 1
 | |
| 
 | |
|             buttons = {b1: False, b2: None}
 | |
|             r = uhdev.event(buttons=buttons)
 | |
|             expected_event = libevdev.InputEvent(key1, 0)
 | |
|             events = uhdev.next_sync_events()
 | |
|             self.debug_reports(r, uhdev, events)
 | |
|             self.assertInputEventsIn((syn_event, expected_event), events)
 | |
|             assert evdev.value[key1] == 0
 | |
|             assert evdev.value[key2] == 1
 | |
| 
 | |
|             buttons = {b1: None, b2: False}
 | |
|             r = uhdev.event(buttons=buttons)
 | |
|             expected_event = libevdev.InputEvent(key2, 0)
 | |
|             events = uhdev.next_sync_events()
 | |
|             self.debug_reports(r, uhdev, events)
 | |
|             self.assertInputEventsIn((syn_event, expected_event), events)
 | |
|             assert evdev.value[key1] == 0
 | |
|             assert evdev.value[key2] == 0
 | |
| 
 | |
|         def _get_libevdev_abs_events(self, which):
 | |
|             """Returns which ABS_* evdev axes are expected for the given stick"""
 | |
|             abs_map = self.uhdev.axes_map[which]
 | |
| 
 | |
|             x = abs_map["x"].evdev
 | |
|             y = abs_map["y"].evdev
 | |
| 
 | |
|             assert x
 | |
|             assert y
 | |
| 
 | |
|             return x, y
 | |
| 
 | |
|         def _test_joystick_press(self, which, data):
 | |
|             uhdev = self.uhdev
 | |
| 
 | |
|             libevdev_axes = self._get_libevdev_abs_events(which)
 | |
| 
 | |
|             r = None
 | |
|             if which == "left_stick":
 | |
|                 r = uhdev.event(left=data)
 | |
|             else:
 | |
|                 r = uhdev.event(right=data)
 | |
|             events = uhdev.next_sync_events()
 | |
|             self.debug_reports(r, uhdev, events)
 | |
| 
 | |
|             for i, d in enumerate(data):
 | |
|                 if d is not None and d != 127:
 | |
|                     assert libevdev.InputEvent(libevdev_axes[i], d) in events
 | |
|                 else:
 | |
|                     assert libevdev.InputEvent(libevdev_axes[i]) not in events
 | |
| 
 | |
|         def test_left_joystick_press_left(self):
 | |
|             """check for the left joystick reliability"""
 | |
|             self._test_joystick_press("left_stick", (63, None))
 | |
|             self._test_joystick_press("left_stick", (0, 127))
 | |
| 
 | |
|         def test_left_joystick_press_right(self):
 | |
|             """check for the left joystick reliability"""
 | |
|             self._test_joystick_press("left_stick", (191, 127))
 | |
|             self._test_joystick_press("left_stick", (255, None))
 | |
| 
 | |
|         def test_left_joystick_press_up(self):
 | |
|             """check for the left joystick reliability"""
 | |
|             self._test_joystick_press("left_stick", (None, 63))
 | |
|             self._test_joystick_press("left_stick", (127, 0))
 | |
| 
 | |
|         def test_left_joystick_press_down(self):
 | |
|             """check for the left joystick reliability"""
 | |
|             self._test_joystick_press("left_stick", (127, 191))
 | |
|             self._test_joystick_press("left_stick", (None, 255))
 | |
| 
 | |
|         def test_right_joystick_press_left(self):
 | |
|             """check for the right joystick reliability"""
 | |
|             self._test_joystick_press("right_stick", (63, None))
 | |
|             self._test_joystick_press("right_stick", (0, 127))
 | |
| 
 | |
|         def test_right_joystick_press_right(self):
 | |
|             """check for the right joystick reliability"""
 | |
|             self._test_joystick_press("right_stick", (191, 127))
 | |
|             self._test_joystick_press("right_stick", (255, None))
 | |
| 
 | |
|         def test_right_joystick_press_up(self):
 | |
|             """check for the right joystick reliability"""
 | |
|             self._test_joystick_press("right_stick", (None, 63))
 | |
|             self._test_joystick_press("right_stick", (127, 0))
 | |
| 
 | |
|         def test_right_joystick_press_down(self):
 | |
|             """check for the right joystick reliability"""
 | |
|             self._test_joystick_press("right_stick", (127, 191))
 | |
|             self._test_joystick_press("right_stick", (None, 255))
 | |
| 
 | |
|         @pytest.mark.skip_if_uhdev(
 | |
|             lambda uhdev: "Hat switch" not in uhdev.fields,
 | |
|             "Device not compatible, missing Hat switch usage",
 | |
|         )
 | |
|         @pytest.mark.parametrize(
 | |
|             "hat_value,expected_evdev,evdev_value",
 | |
|             [
 | |
|                 (0, "ABS_HAT0Y", -1),
 | |
|                 (2, "ABS_HAT0X", 1),
 | |
|                 (4, "ABS_HAT0Y", 1),
 | |
|                 (6, "ABS_HAT0X", -1),
 | |
|             ],
 | |
|         )
 | |
|         def test_hat_switch(self, hat_value, expected_evdev, evdev_value):
 | |
|             uhdev = self.uhdev
 | |
| 
 | |
|             r = uhdev.event(hat_switch=hat_value)
 | |
|             events = uhdev.next_sync_events()
 | |
|             self.debug_reports(r, uhdev, events)
 | |
|             assert (
 | |
|                 libevdev.InputEvent(
 | |
|                     libevdev.evbit("EV_ABS", expected_evdev), evdev_value
 | |
|                 )
 | |
|                 in events
 | |
|             )
 | |
| 
 | |
| 
 | |
| class SaitekGamepad(JoystickGamepad):
 | |
|     # fmt: off
 | |
|     report_descriptor = [
 | |
|         0x05, 0x01,                    # Usage Page (Generic Desktop)        0
 | |
|         0x09, 0x04,                    # Usage (Joystick)                    2
 | |
|         0xa1, 0x01,                    # Collection (Application)            4
 | |
|         0x09, 0x01,                    # .Usage (Pointer)                    6
 | |
|         0xa1, 0x00,                    # .Collection (Physical)              8
 | |
|         0x85, 0x01,                    # ..Report ID (1)                     10
 | |
|         0x09, 0x30,                    # ..Usage (X)                         12
 | |
|         0x15, 0x00,                    # ..Logical Minimum (0)               14
 | |
|         0x26, 0xff, 0x00,              # ..Logical Maximum (255)             16
 | |
|         0x35, 0x00,                    # ..Physical Minimum (0)              19
 | |
|         0x46, 0xff, 0x00,              # ..Physical Maximum (255)            21
 | |
|         0x75, 0x08,                    # ..Report Size (8)                   24
 | |
|         0x95, 0x01,                    # ..Report Count (1)                  26
 | |
|         0x81, 0x02,                    # ..Input (Data,Var,Abs)              28
 | |
|         0x09, 0x31,                    # ..Usage (Y)                         30
 | |
|         0x81, 0x02,                    # ..Input (Data,Var,Abs)              32
 | |
|         0x05, 0x02,                    # ..Usage Page (Simulation Controls)  34
 | |
|         0x09, 0xba,                    # ..Usage (Rudder)                    36
 | |
|         0x81, 0x02,                    # ..Input (Data,Var,Abs)              38
 | |
|         0x09, 0xbb,                    # ..Usage (Throttle)                  40
 | |
|         0x81, 0x02,                    # ..Input (Data,Var,Abs)              42
 | |
|         0x05, 0x09,                    # ..Usage Page (Button)               44
 | |
|         0x19, 0x01,                    # ..Usage Minimum (1)                 46
 | |
|         0x29, 0x0c,                    # ..Usage Maximum (12)                48
 | |
|         0x25, 0x01,                    # ..Logical Maximum (1)               50
 | |
|         0x45, 0x01,                    # ..Physical Maximum (1)              52
 | |
|         0x75, 0x01,                    # ..Report Size (1)                   54
 | |
|         0x95, 0x0c,                    # ..Report Count (12)                 56
 | |
|         0x81, 0x02,                    # ..Input (Data,Var,Abs)              58
 | |
|         0x95, 0x01,                    # ..Report Count (1)                  60
 | |
|         0x75, 0x00,                    # ..Report Size (0)                   62
 | |
|         0x81, 0x03,                    # ..Input (Cnst,Var,Abs)              64
 | |
|         0x05, 0x01,                    # ..Usage Page (Generic Desktop)      66
 | |
|         0x09, 0x39,                    # ..Usage (Hat switch)                68
 | |
|         0x25, 0x07,                    # ..Logical Maximum (7)               70
 | |
|         0x46, 0x3b, 0x01,              # ..Physical Maximum (315)            72
 | |
|         0x55, 0x00,                    # ..Unit Exponent (0)                 75
 | |
|         0x65, 0x44,                    # ..Unit (Degrees^4,EngRotation)      77
 | |
|         0x75, 0x04,                    # ..Report Size (4)                   79
 | |
|         0x81, 0x42,                    # ..Input (Data,Var,Abs,Null)         81
 | |
|         0x65, 0x00,                    # ..Unit (None)                       83
 | |
|         0xc0,                          # .End Collection                     85
 | |
|         0x05, 0x0f,                    # .Usage Page (Vendor Usage Page 0x0f) 86
 | |
|         0x09, 0x92,                    # .Usage (Vendor Usage 0x92)          88
 | |
|         0xa1, 0x02,                    # .Collection (Logical)               90
 | |
|         0x85, 0x02,                    # ..Report ID (2)                     92
 | |
|         0x09, 0xa0,                    # ..Usage (Vendor Usage 0xa0)         94
 | |
|         0x09, 0x9f,                    # ..Usage (Vendor Usage 0x9f)         96
 | |
|         0x25, 0x01,                    # ..Logical Maximum (1)               98
 | |
|         0x45, 0x00,                    # ..Physical Maximum (0)              100
 | |
|         0x75, 0x01,                    # ..Report Size (1)                   102
 | |
|         0x95, 0x02,                    # ..Report Count (2)                  104
 | |
|         0x81, 0x02,                    # ..Input (Data,Var,Abs)              106
 | |
|         0x75, 0x06,                    # ..Report Size (6)                   108
 | |
|         0x95, 0x01,                    # ..Report Count (1)                  110
 | |
|         0x81, 0x03,                    # ..Input (Cnst,Var,Abs)              112
 | |
|         0x09, 0x22,                    # ..Usage (Vendor Usage 0x22)         114
 | |
|         0x75, 0x07,                    # ..Report Size (7)                   116
 | |
|         0x25, 0x7f,                    # ..Logical Maximum (127)             118
 | |
|         0x81, 0x02,                    # ..Input (Data,Var,Abs)              120
 | |
|         0x09, 0x94,                    # ..Usage (Vendor Usage 0x94)         122
 | |
|         0x75, 0x01,                    # ..Report Size (1)                   124
 | |
|         0x25, 0x01,                    # ..Logical Maximum (1)               126
 | |
|         0x81, 0x02,                    # ..Input (Data,Var,Abs)              128
 | |
|         0xc0,                          # .End Collection                     130
 | |
|         0x09, 0x21,                    # .Usage (Vendor Usage 0x21)          131
 | |
|         0xa1, 0x02,                    # .Collection (Logical)               133
 | |
|         0x85, 0x0b,                    # ..Report ID (11)                    135
 | |
|         0x09, 0x22,                    # ..Usage (Vendor Usage 0x22)         137
 | |
|         0x26, 0xff, 0x00,              # ..Logical Maximum (255)             139
 | |
|         0x75, 0x08,                    # ..Report Size (8)                   142
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             144
 | |
|         0x09, 0x53,                    # ..Usage (Vendor Usage 0x53)         146
 | |
|         0x25, 0x0a,                    # ..Logical Maximum (10)              148
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             150
 | |
|         0x09, 0x50,                    # ..Usage (Vendor Usage 0x50)         152
 | |
|         0x27, 0xfe, 0xff, 0x00, 0x00,  # ..Logical Maximum (65534)           154
 | |
|         0x47, 0xfe, 0xff, 0x00, 0x00,  # ..Physical Maximum (65534)          159
 | |
|         0x75, 0x10,                    # ..Report Size (16)                  164
 | |
|         0x55, 0xfd,                    # ..Unit Exponent (237)               166
 | |
|         0x66, 0x01, 0x10,              # ..Unit (Seconds,SILinear)           168
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             171
 | |
|         0x55, 0x00,                    # ..Unit Exponent (0)                 173
 | |
|         0x65, 0x00,                    # ..Unit (None)                       175
 | |
|         0x09, 0x54,                    # ..Usage (Vendor Usage 0x54)         177
 | |
|         0x55, 0xfd,                    # ..Unit Exponent (237)               179
 | |
|         0x66, 0x01, 0x10,              # ..Unit (Seconds,SILinear)           181
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             184
 | |
|         0x55, 0x00,                    # ..Unit Exponent (0)                 186
 | |
|         0x65, 0x00,                    # ..Unit (None)                       188
 | |
|         0x09, 0xa7,                    # ..Usage (Vendor Usage 0xa7)         190
 | |
|         0x55, 0xfd,                    # ..Unit Exponent (237)               192
 | |
|         0x66, 0x01, 0x10,              # ..Unit (Seconds,SILinear)           194
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             197
 | |
|         0x55, 0x00,                    # ..Unit Exponent (0)                 199
 | |
|         0x65, 0x00,                    # ..Unit (None)                       201
 | |
|         0xc0,                          # .End Collection                     203
 | |
|         0x09, 0x5a,                    # .Usage (Vendor Usage 0x5a)          204
 | |
|         0xa1, 0x02,                    # .Collection (Logical)               206
 | |
|         0x85, 0x0c,                    # ..Report ID (12)                    208
 | |
|         0x09, 0x22,                    # ..Usage (Vendor Usage 0x22)         210
 | |
|         0x26, 0xff, 0x00,              # ..Logical Maximum (255)             212
 | |
|         0x45, 0x00,                    # ..Physical Maximum (0)              215
 | |
|         0x75, 0x08,                    # ..Report Size (8)                   217
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             219
 | |
|         0x09, 0x5c,                    # ..Usage (Vendor Usage 0x5c)         221
 | |
|         0x26, 0x10, 0x27,              # ..Logical Maximum (10000)           223
 | |
|         0x46, 0x10, 0x27,              # ..Physical Maximum (10000)          226
 | |
|         0x75, 0x10,                    # ..Report Size (16)                  229
 | |
|         0x55, 0xfd,                    # ..Unit Exponent (237)               231
 | |
|         0x66, 0x01, 0x10,              # ..Unit (Seconds,SILinear)           233
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             236
 | |
|         0x55, 0x00,                    # ..Unit Exponent (0)                 238
 | |
|         0x65, 0x00,                    # ..Unit (None)                       240
 | |
|         0x09, 0x5b,                    # ..Usage (Vendor Usage 0x5b)         242
 | |
|         0x25, 0x7f,                    # ..Logical Maximum (127)             244
 | |
|         0x75, 0x08,                    # ..Report Size (8)                   246
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             248
 | |
|         0x09, 0x5e,                    # ..Usage (Vendor Usage 0x5e)         250
 | |
|         0x26, 0x10, 0x27,              # ..Logical Maximum (10000)           252
 | |
|         0x75, 0x10,                    # ..Report Size (16)                  255
 | |
|         0x55, 0xfd,                    # ..Unit Exponent (237)               257
 | |
|         0x66, 0x01, 0x10,              # ..Unit (Seconds,SILinear)           259
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             262
 | |
|         0x55, 0x00,                    # ..Unit Exponent (0)                 264
 | |
|         0x65, 0x00,                    # ..Unit (None)                       266
 | |
|         0x09, 0x5d,                    # ..Usage (Vendor Usage 0x5d)         268
 | |
|         0x25, 0x7f,                    # ..Logical Maximum (127)             270
 | |
|         0x75, 0x08,                    # ..Report Size (8)                   272
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             274
 | |
|         0xc0,                          # .End Collection                     276
 | |
|         0x09, 0x73,                    # .Usage (Vendor Usage 0x73)          277
 | |
|         0xa1, 0x02,                    # .Collection (Logical)               279
 | |
|         0x85, 0x0d,                    # ..Report ID (13)                    281
 | |
|         0x09, 0x22,                    # ..Usage (Vendor Usage 0x22)         283
 | |
|         0x26, 0xff, 0x00,              # ..Logical Maximum (255)             285
 | |
|         0x45, 0x00,                    # ..Physical Maximum (0)              288
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             290
 | |
|         0x09, 0x70,                    # ..Usage (Vendor Usage 0x70)         292
 | |
|         0x15, 0x81,                    # ..Logical Minimum (-127)            294
 | |
|         0x25, 0x7f,                    # ..Logical Maximum (127)             296
 | |
|         0x36, 0xf0, 0xd8,              # ..Physical Minimum (-10000)         298
 | |
|         0x46, 0x10, 0x27,              # ..Physical Maximum (10000)          301
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             304
 | |
|         0xc0,                          # .End Collection                     306
 | |
|         0x09, 0x6e,                    # .Usage (Vendor Usage 0x6e)          307
 | |
|         0xa1, 0x02,                    # .Collection (Logical)               309
 | |
|         0x85, 0x0e,                    # ..Report ID (14)                    311
 | |
|         0x09, 0x22,                    # ..Usage (Vendor Usage 0x22)         313
 | |
|         0x15, 0x00,                    # ..Logical Minimum (0)               315
 | |
|         0x26, 0xff, 0x00,              # ..Logical Maximum (255)             317
 | |
|         0x35, 0x00,                    # ..Physical Minimum (0)              320
 | |
|         0x45, 0x00,                    # ..Physical Maximum (0)              322
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             324
 | |
|         0x09, 0x70,                    # ..Usage (Vendor Usage 0x70)         326
 | |
|         0x25, 0x7f,                    # ..Logical Maximum (127)             328
 | |
|         0x46, 0x10, 0x27,              # ..Physical Maximum (10000)          330
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             333
 | |
|         0x09, 0x6f,                    # ..Usage (Vendor Usage 0x6f)         335
 | |
|         0x15, 0x81,                    # ..Logical Minimum (-127)            337
 | |
|         0x36, 0xf0, 0xd8,              # ..Physical Minimum (-10000)         339
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             342
 | |
|         0x09, 0x71,                    # ..Usage (Vendor Usage 0x71)         344
 | |
|         0x15, 0x00,                    # ..Logical Minimum (0)               346
 | |
|         0x26, 0xff, 0x00,              # ..Logical Maximum (255)             348
 | |
|         0x35, 0x00,                    # ..Physical Minimum (0)              351
 | |
|         0x46, 0x68, 0x01,              # ..Physical Maximum (360)            353
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             356
 | |
|         0x09, 0x72,                    # ..Usage (Vendor Usage 0x72)         358
 | |
|         0x75, 0x10,                    # ..Report Size (16)                  360
 | |
|         0x26, 0x10, 0x27,              # ..Logical Maximum (10000)           362
 | |
|         0x46, 0x10, 0x27,              # ..Physical Maximum (10000)          365
 | |
|         0x55, 0xfd,                    # ..Unit Exponent (237)               368
 | |
|         0x66, 0x01, 0x10,              # ..Unit (Seconds,SILinear)           370
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             373
 | |
|         0x55, 0x00,                    # ..Unit Exponent (0)                 375
 | |
|         0x65, 0x00,                    # ..Unit (None)                       377
 | |
|         0xc0,                          # .End Collection                     379
 | |
|         0x09, 0x77,                    # .Usage (Vendor Usage 0x77)          380
 | |
|         0xa1, 0x02,                    # .Collection (Logical)               382
 | |
|         0x85, 0x51,                    # ..Report ID (81)                    384
 | |
|         0x09, 0x22,                    # ..Usage (Vendor Usage 0x22)         386
 | |
|         0x25, 0x7f,                    # ..Logical Maximum (127)             388
 | |
|         0x45, 0x00,                    # ..Physical Maximum (0)              390
 | |
|         0x75, 0x08,                    # ..Report Size (8)                   392
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             394
 | |
|         0x09, 0x78,                    # ..Usage (Vendor Usage 0x78)         396
 | |
|         0xa1, 0x02,                    # ..Collection (Logical)              398
 | |
|         0x09, 0x7b,                    # ...Usage (Vendor Usage 0x7b)        400
 | |
|         0x09, 0x79,                    # ...Usage (Vendor Usage 0x79)        402
 | |
|         0x09, 0x7a,                    # ...Usage (Vendor Usage 0x7a)        404
 | |
|         0x15, 0x01,                    # ...Logical Minimum (1)              406
 | |
|         0x25, 0x03,                    # ...Logical Maximum (3)              408
 | |
|         0x91, 0x00,                    # ...Output (Data,Arr,Abs)            410
 | |
|         0xc0,                          # ..End Collection                    412
 | |
|         0x09, 0x7c,                    # ..Usage (Vendor Usage 0x7c)         413
 | |
|         0x15, 0x00,                    # ..Logical Minimum (0)               415
 | |
|         0x26, 0xfe, 0x00,              # ..Logical Maximum (254)             417
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             420
 | |
|         0xc0,                          # .End Collection                     422
 | |
|         0x09, 0x92,                    # .Usage (Vendor Usage 0x92)          423
 | |
|         0xa1, 0x02,                    # .Collection (Logical)               425
 | |
|         0x85, 0x52,                    # ..Report ID (82)                    427
 | |
|         0x09, 0x96,                    # ..Usage (Vendor Usage 0x96)         429
 | |
|         0xa1, 0x02,                    # ..Collection (Logical)              431
 | |
|         0x09, 0x9a,                    # ...Usage (Vendor Usage 0x9a)        433
 | |
|         0x09, 0x99,                    # ...Usage (Vendor Usage 0x99)        435
 | |
|         0x09, 0x97,                    # ...Usage (Vendor Usage 0x97)        437
 | |
|         0x09, 0x98,                    # ...Usage (Vendor Usage 0x98)        439
 | |
|         0x09, 0x9b,                    # ...Usage (Vendor Usage 0x9b)        441
 | |
|         0x09, 0x9c,                    # ...Usage (Vendor Usage 0x9c)        443
 | |
|         0x15, 0x01,                    # ...Logical Minimum (1)              445
 | |
|         0x25, 0x06,                    # ...Logical Maximum (6)              447
 | |
|         0x91, 0x00,                    # ...Output (Data,Arr,Abs)            449
 | |
|         0xc0,                          # ..End Collection                    451
 | |
|         0xc0,                          # .End Collection                     452
 | |
|         0x05, 0xff,                    # .Usage Page (Vendor Usage Page 0xff) 453
 | |
|         0x0a, 0x01, 0x03,              # .Usage (Vendor Usage 0x301)         455
 | |
|         0xa1, 0x02,                    # .Collection (Logical)               458
 | |
|         0x85, 0x40,                    # ..Report ID (64)                    460
 | |
|         0x0a, 0x02, 0x03,              # ..Usage (Vendor Usage 0x302)        462
 | |
|         0xa1, 0x02,                    # ..Collection (Logical)              465
 | |
|         0x1a, 0x11, 0x03,              # ...Usage Minimum (785)              467
 | |
|         0x2a, 0x20, 0x03,              # ...Usage Maximum (800)              470
 | |
|         0x25, 0x10,                    # ...Logical Maximum (16)             473
 | |
|         0x91, 0x00,                    # ...Output (Data,Arr,Abs)            475
 | |
|         0xc0,                          # ..End Collection                    477
 | |
|         0x0a, 0x03, 0x03,              # ..Usage (Vendor Usage 0x303)        478
 | |
|         0x15, 0x00,                    # ..Logical Minimum (0)               481
 | |
|         0x27, 0xff, 0xff, 0x00, 0x00,  # ..Logical Maximum (65535)           483
 | |
|         0x75, 0x10,                    # ..Report Size (16)                  488
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             490
 | |
|         0xc0,                          # .End Collection                     492
 | |
|         0x05, 0x0f,                    # .Usage Page (Vendor Usage Page 0x0f) 493
 | |
|         0x09, 0x7d,                    # .Usage (Vendor Usage 0x7d)          495
 | |
|         0xa1, 0x02,                    # .Collection (Logical)               497
 | |
|         0x85, 0x43,                    # ..Report ID (67)                    499
 | |
|         0x09, 0x7e,                    # ..Usage (Vendor Usage 0x7e)         501
 | |
|         0x26, 0x80, 0x00,              # ..Logical Maximum (128)             503
 | |
|         0x46, 0x10, 0x27,              # ..Physical Maximum (10000)          506
 | |
|         0x75, 0x08,                    # ..Report Size (8)                   509
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             511
 | |
|         0xc0,                          # .End Collection                     513
 | |
|         0x09, 0x7f,                    # .Usage (Vendor Usage 0x7f)          514
 | |
|         0xa1, 0x02,                    # .Collection (Logical)               516
 | |
|         0x85, 0x0b,                    # ..Report ID (11)                    518
 | |
|         0x09, 0x80,                    # ..Usage (Vendor Usage 0x80)         520
 | |
|         0x26, 0xff, 0x7f,              # ..Logical Maximum (32767)           522
 | |
|         0x45, 0x00,                    # ..Physical Maximum (0)              525
 | |
|         0x75, 0x0f,                    # ..Report Size (15)                  527
 | |
|         0xb1, 0x03,                    # ..Feature (Cnst,Var,Abs)            529
 | |
|         0x09, 0xa9,                    # ..Usage (Vendor Usage 0xa9)         531
 | |
|         0x25, 0x01,                    # ..Logical Maximum (1)               533
 | |
|         0x75, 0x01,                    # ..Report Size (1)                   535
 | |
|         0xb1, 0x03,                    # ..Feature (Cnst,Var,Abs)            537
 | |
|         0x09, 0x83,                    # ..Usage (Vendor Usage 0x83)         539
 | |
|         0x26, 0xff, 0x00,              # ..Logical Maximum (255)             541
 | |
|         0x75, 0x08,                    # ..Report Size (8)                   544
 | |
|         0xb1, 0x03,                    # ..Feature (Cnst,Var,Abs)            546
 | |
|         0xc0,                          # .End Collection                     548
 | |
|         0x09, 0xab,                    # .Usage (Vendor Usage 0xab)          549
 | |
|         0xa1, 0x03,                    # .Collection (Report)                551
 | |
|         0x85, 0x15,                    # ..Report ID (21)                    553
 | |
|         0x09, 0x25,                    # ..Usage (Vendor Usage 0x25)         555
 | |
|         0xa1, 0x02,                    # ..Collection (Logical)              557
 | |
|         0x09, 0x26,                    # ...Usage (Vendor Usage 0x26)        559
 | |
|         0x09, 0x30,                    # ...Usage (Vendor Usage 0x30)        561
 | |
|         0x09, 0x32,                    # ...Usage (Vendor Usage 0x32)        563
 | |
|         0x09, 0x31,                    # ...Usage (Vendor Usage 0x31)        565
 | |
|         0x09, 0x33,                    # ...Usage (Vendor Usage 0x33)        567
 | |
|         0x09, 0x34,                    # ...Usage (Vendor Usage 0x34)        569
 | |
|         0x15, 0x01,                    # ...Logical Minimum (1)              571
 | |
|         0x25, 0x06,                    # ...Logical Maximum (6)              573
 | |
|         0xb1, 0x00,                    # ...Feature (Data,Arr,Abs)           575
 | |
|         0xc0,                          # ..End Collection                    577
 | |
|         0xc0,                          # .End Collection                     578
 | |
|         0x09, 0x89,                    # .Usage (Vendor Usage 0x89)          579
 | |
|         0xa1, 0x03,                    # .Collection (Report)                581
 | |
|         0x85, 0x16,                    # ..Report ID (22)                    583
 | |
|         0x09, 0x8b,                    # ..Usage (Vendor Usage 0x8b)         585
 | |
|         0xa1, 0x02,                    # ..Collection (Logical)              587
 | |
|         0x09, 0x8c,                    # ...Usage (Vendor Usage 0x8c)        589
 | |
|         0x09, 0x8d,                    # ...Usage (Vendor Usage 0x8d)        591
 | |
|         0x09, 0x8e,                    # ...Usage (Vendor Usage 0x8e)        593
 | |
|         0x25, 0x03,                    # ...Logical Maximum (3)              595
 | |
|         0xb1, 0x00,                    # ...Feature (Data,Arr,Abs)           597
 | |
|         0xc0,                          # ..End Collection                    599
 | |
|         0x09, 0x22,                    # ..Usage (Vendor Usage 0x22)         600
 | |
|         0x15, 0x00,                    # ..Logical Minimum (0)               602
 | |
|         0x26, 0xfe, 0x00,              # ..Logical Maximum (254)             604
 | |
|         0xb1, 0x02,                    # ..Feature (Data,Var,Abs)            607
 | |
|         0xc0,                          # .End Collection                     609
 | |
|         0x09, 0x90,                    # .Usage (Vendor Usage 0x90)          610
 | |
|         0xa1, 0x03,                    # .Collection (Report)                612
 | |
|         0x85, 0x50,                    # ..Report ID (80)                    614
 | |
|         0x09, 0x22,                    # ..Usage (Vendor Usage 0x22)         616
 | |
|         0x26, 0xff, 0x00,              # ..Logical Maximum (255)             618
 | |
|         0x91, 0x02,                    # ..Output (Data,Var,Abs)             621
 | |
|         0xc0,                          # .End Collection                     623
 | |
|         0xc0,                          # End Collection                      624
 | |
|     ]
 | |
|     # fmt: on
 | |
| 
 | |
|     def __init__(self, rdesc=report_descriptor, name=None):
 | |
|         super().__init__(rdesc, name=name, input_info=(BusType.USB, 0x06A3, 0xFF0D))
 | |
|         self.buttons = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
 | |
| 
 | |
| 
 | |
| class AsusGamepad(BaseGamepad):
 | |
|     # fmt: off
 | |
|     report_descriptor = [
 | |
|         0x05, 0x01,                    # Usage Page (Generic Desktop)        0
 | |
|         0x09, 0x05,                    # Usage (Game Pad)                    2
 | |
|         0xa1, 0x01,                    # Collection (Application)            4
 | |
|         0x85, 0x01,                    # .Report ID (1)                      6
 | |
|         0x05, 0x09,                    # .Usage Page (Button)                8
 | |
|         0x0a, 0x01, 0x00,              # .Usage (Vendor Usage 0x01)          10
 | |
|         0x0a, 0x02, 0x00,              # .Usage (Vendor Usage 0x02)          13
 | |
|         0x0a, 0x04, 0x00,              # .Usage (Vendor Usage 0x04)          16
 | |
|         0x0a, 0x05, 0x00,              # .Usage (Vendor Usage 0x05)          19
 | |
|         0x0a, 0x07, 0x00,              # .Usage (Vendor Usage 0x07)          22
 | |
|         0x0a, 0x08, 0x00,              # .Usage (Vendor Usage 0x08)          25
 | |
|         0x0a, 0x0e, 0x00,              # .Usage (Vendor Usage 0x0e)          28
 | |
|         0x0a, 0x0f, 0x00,              # .Usage (Vendor Usage 0x0f)          31
 | |
|         0x0a, 0x0d, 0x00,              # .Usage (Vendor Usage 0x0d)          34
 | |
|         0x05, 0x0c,                    # .Usage Page (Consumer Devices)      37
 | |
|         0x0a, 0x24, 0x02,              # .Usage (AC Back)                    39
 | |
|         0x0a, 0x23, 0x02,              # .Usage (AC Home)                    42
 | |
|         0x15, 0x00,                    # .Logical Minimum (0)                45
 | |
|         0x25, 0x01,                    # .Logical Maximum (1)                47
 | |
|         0x75, 0x01,                    # .Report Size (1)                    49
 | |
|         0x95, 0x0b,                    # .Report Count (11)                  51
 | |
|         0x81, 0x02,                    # .Input (Data,Var,Abs)               53
 | |
|         0x75, 0x01,                    # .Report Size (1)                    55
 | |
|         0x95, 0x01,                    # .Report Count (1)                   57
 | |
|         0x81, 0x03,                    # .Input (Cnst,Var,Abs)               59
 | |
|         0x05, 0x01,                    # .Usage Page (Generic Desktop)       61
 | |
|         0x75, 0x04,                    # .Report Size (4)                    63
 | |
|         0x95, 0x01,                    # .Report Count (1)                   65
 | |
|         0x25, 0x07,                    # .Logical Maximum (7)                67
 | |
|         0x46, 0x3b, 0x01,              # .Physical Maximum (315)             69
 | |
|         0x66, 0x14, 0x00,              # .Unit (Degrees,EngRotation)         72
 | |
|         0x09, 0x39,                    # .Usage (Hat switch)                 75
 | |
|         0x81, 0x42,                    # .Input (Data,Var,Abs,Null)          77
 | |
|         0x66, 0x00, 0x00,              # .Unit (None)                        79
 | |
|         0x09, 0x01,                    # .Usage (Pointer)                    82
 | |
|         0xa1, 0x00,                    # .Collection (Physical)              84
 | |
|         0x09, 0x30,                    # ..Usage (X)                         86
 | |
|         0x09, 0x31,                    # ..Usage (Y)                         88
 | |
|         0x09, 0x32,                    # ..Usage (Z)                         90
 | |
|         0x09, 0x35,                    # ..Usage (Rz)                        92
 | |
|         0x05, 0x02,                    # ..Usage Page (Simulation Controls)  94
 | |
|         0x09, 0xc5,                    # ..Usage (Brake)                     96
 | |
|         0x09, 0xc4,                    # ..Usage (Accelerator)               98
 | |
|         0x15, 0x00,                    # ..Logical Minimum (0)               100
 | |
|         0x26, 0xff, 0x00,              # ..Logical Maximum (255)             102
 | |
|         0x35, 0x00,                    # ..Physical Minimum (0)              105
 | |
|         0x46, 0xff, 0x00,              # ..Physical Maximum (255)            107
 | |
|         0x75, 0x08,                    # ..Report Size (8)                   110
 | |
|         0x95, 0x06,                    # ..Report Count (6)                  112
 | |
|         0x81, 0x02,                    # ..Input (Data,Var,Abs)              114
 | |
|         0xc0,                          # .End Collection                     116
 | |
|         0x85, 0x02,                    # .Report ID (2)                      117
 | |
|         0x05, 0x08,                    # .Usage Page (LEDs)                  119
 | |
|         0x0a, 0x01, 0x00,              # .Usage (Num Lock)                   121
 | |
|         0x0a, 0x02, 0x00,              # .Usage (Caps Lock)                  124
 | |
|         0x0a, 0x03, 0x00,              # .Usage (Scroll Lock)                127
 | |
|         0x0a, 0x04, 0x00,              # .Usage (Compose)                    130
 | |
|         0x15, 0x00,                    # .Logical Minimum (0)                133
 | |
|         0x25, 0x01,                    # .Logical Maximum (1)                135
 | |
|         0x75, 0x01,                    # .Report Size (1)                    137
 | |
|         0x95, 0x04,                    # .Report Count (4)                   139
 | |
|         0x91, 0x02,                    # .Output (Data,Var,Abs)              141
 | |
|         0x75, 0x04,                    # .Report Size (4)                    143
 | |
|         0x95, 0x01,                    # .Report Count (1)                   145
 | |
|         0x91, 0x03,                    # .Output (Cnst,Var,Abs)              147
 | |
|         0xc0,                          # End Collection                      149
 | |
|         0x05, 0x0c,                    # Usage Page (Consumer Devices)       150
 | |
|         0x09, 0x01,                    # Usage (Consumer Control)            152
 | |
|         0xa1, 0x01,                    # Collection (Application)            154
 | |
|         0x85, 0x03,                    # .Report ID (3)                      156
 | |
|         0x05, 0x01,                    # .Usage Page (Generic Desktop)       158
 | |
|         0x09, 0x06,                    # .Usage (Keyboard)                   160
 | |
|         0xa1, 0x02,                    # .Collection (Logical)               162
 | |
|         0x05, 0x06,                    # ..Usage Page (Generic Device Controls) 164
 | |
|         0x09, 0x20,                    # ..Usage (Battery Strength)          166
 | |
|         0x15, 0x00,                    # ..Logical Minimum (0)               168
 | |
|         0x26, 0xff, 0x00,              # ..Logical Maximum (255)             170
 | |
|         0x75, 0x08,                    # ..Report Size (8)                   173
 | |
|         0x95, 0x01,                    # ..Report Count (1)                  175
 | |
|         0x81, 0x02,                    # ..Input (Data,Var,Abs)              177
 | |
|         0x06, 0xbc, 0xff,              # ..Usage Page (Vendor Usage Page 0xffbc) 179
 | |
|         0x0a, 0xad, 0xbd,              # ..Usage (Vendor Usage 0xbdad)       182
 | |
|         0x75, 0x08,                    # ..Report Size (8)                   185
 | |
|         0x95, 0x06,                    # ..Report Count (6)                  187
 | |
|         0x81, 0x02,                    # ..Input (Data,Var,Abs)              189
 | |
|         0xc0,                          # .End Collection                     191
 | |
|         0xc0,                          # End Collection                      192
 | |
|     ]
 | |
|     # fmt: on
 | |
| 
 | |
|     def __init__(self, rdesc=report_descriptor, name=None):
 | |
|         super().__init__(rdesc, name=name, input_info=(BusType.USB, 0x18D1, 0x2C40))
 | |
|         self.buttons = (1, 2, 4, 5, 7, 8, 14, 15, 13)
 | |
| 
 | |
| 
 | |
| class RaptorMach2Joystick(JoystickGamepad):
 | |
|     axes_map = {
 | |
|         "left_stick": {
 | |
|             "x": AxisMapping("x"),
 | |
|             "y": AxisMapping("y"),
 | |
|         },
 | |
|         "right_stick": {
 | |
|             "x": AxisMapping("z"),
 | |
|             "y": AxisMapping("Rz"),
 | |
|         },
 | |
|     }
 | |
| 
 | |
|     def __init__(
 | |
|         self,
 | |
|         name,
 | |
|         rdesc=None,
 | |
|         application="Joystick",
 | |
|         input_info=(BusType.USB, 0x11C0, 0x5606),
 | |
|     ):
 | |
|         super().__init__(rdesc, application, name, input_info)
 | |
|         self.buttons = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
 | |
|         self.hat_switch = 240  # null value is 240 as max is 239
 | |
| 
 | |
|     def event(
 | |
|         self, *, left=(None, None), right=(None, None), hat_switch=None, buttons=None
 | |
|     ):
 | |
|         if hat_switch is not None:
 | |
|             hat_switch *= 30
 | |
| 
 | |
|         return super().event(
 | |
|             left=left, right=right, hat_switch=hat_switch, buttons=buttons
 | |
|         )
 | |
| 
 | |
| 
 | |
| class TestSaitekGamepad(BaseTest.TestGamepad):
 | |
|     def create_device(self):
 | |
|         return SaitekGamepad()
 | |
| 
 | |
| 
 | |
| class TestAsusGamepad(BaseTest.TestGamepad):
 | |
|     def create_device(self):
 | |
|         return AsusGamepad()
 | |
| 
 | |
| 
 | |
| class TestRaptorMach2Joystick(BaseTest.TestGamepad):
 | |
|     hid_bpfs = [("FR-TEC__Raptor-Mach-2.bpf.o", True)]
 | |
| 
 | |
|     def create_device(self):
 | |
|         return RaptorMach2Joystick(
 | |
|             "uhid test Sanmos Group FR-TEC Raptor MACH 2",
 | |
|             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",
 | |
|             input_info=(BusType.USB, 0x11C0, 0x5606),
 | |
|         )
 |