xref: /linux/tools/testing/selftests/hid/tests/test_gamepad.py (revision e29fd84c5b49085cf27e1d5f27237d2fb19edefe)
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
9from . import base
10import libevdev
11import pytest
12
13from .base_gamepad import BaseGamepad, JoystickGamepad, AxisMapping
14from hidtools.util import BusType
15
16import logging
17
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.uhdev
27
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.uhdev
34            evdev = uhdev.get_evdev()
35            syn_event = self.syn_event
36
37            buttons = {}
38            key = libevdev.evbit(uhdev.buttons_map[button])
39
40            buttons[button] = True
41            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] == 1
47
48            buttons[button] = False
49            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] == 0
55
56        def test_buttons(self):
57            """check for button reliability."""
58            uhdev = self.uhdev
59
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.uhdev
66            evdev = uhdev.get_evdev()
67            syn_event = self.syn_event
68
69            # can change intended b1 b2 values
70            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), events
83            )
84            assert evdev.value[key1] == 1
85            assert evdev.value[key2] == 1
86
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] == 0
94            assert evdev.value[key2] == 1
95
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] == 0
103            assert evdev.value[key2] == 0
104
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"].evdev
110            y = abs_map["y"].evdev
111
112            assert x
113            assert y
114
115            return x, y
116
117        def _test_joystick_press(self, which, data):
118            uhdev = self.uhdev
119
120            libevdev_axes = self._get_libevdev_abs_events(which)
121
122            r = None
123            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 events
133                else:
134                    assert libevdev.InputEvent(libevdev_axes[i]) not in events
135
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.uhdev
191
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_value
198                )
199                in events
200            )
201
202
203class SaitekGamepad(JoystickGamepad):
204    # fmt: off
205    report_descriptor = [
206        0x05, 0x01,                    # Usage Page (Generic Desktop)        0
207        0x09, 0x04,                    # Usage (Joystick)                    2
208        0xa1, 0x01,                    # Collection (Application)            4
209        0x09, 0x01,                    # .Usage (Pointer)                    6
210        0xa1, 0x00,                    # .Collection (Physical)              8
211        0x85, 0x01,                    # ..Report ID (1)                     10
212        0x09, 0x30,                    # ..Usage (X)                         12
213        0x15, 0x00,                    # ..Logical Minimum (0)               14
214        0x26, 0xff, 0x00,              # ..Logical Maximum (255)             16
215        0x35, 0x00,                    # ..Physical Minimum (0)              19
216        0x46, 0xff, 0x00,              # ..Physical Maximum (255)            21
217        0x75, 0x08,                    # ..Report Size (8)                   24
218        0x95, 0x01,                    # ..Report Count (1)                  26
219        0x81, 0x02,                    # ..Input (Data,Var,Abs)              28
220        0x09, 0x31,                    # ..Usage (Y)                         30
221        0x81, 0x02,                    # ..Input (Data,Var,Abs)              32
222        0x05, 0x02,                    # ..Usage Page (Simulation Controls)  34
223        0x09, 0xba,                    # ..Usage (Rudder)                    36
224        0x81, 0x02,                    # ..Input (Data,Var,Abs)              38
225        0x09, 0xbb,                    # ..Usage (Throttle)                  40
226        0x81, 0x02,                    # ..Input (Data,Var,Abs)              42
227        0x05, 0x09,                    # ..Usage Page (Button)               44
228        0x19, 0x01,                    # ..Usage Minimum (1)                 46
229        0x29, 0x0c,                    # ..Usage Maximum (12)                48
230        0x25, 0x01,                    # ..Logical Maximum (1)               50
231        0x45, 0x01,                    # ..Physical Maximum (1)              52
232        0x75, 0x01,                    # ..Report Size (1)                   54
233        0x95, 0x0c,                    # ..Report Count (12)                 56
234        0x81, 0x02,                    # ..Input (Data,Var,Abs)              58
235        0x95, 0x01,                    # ..Report Count (1)                  60
236        0x75, 0x00,                    # ..Report Size (0)                   62
237        0x81, 0x03,                    # ..Input (Cnst,Var,Abs)              64
238        0x05, 0x01,                    # ..Usage Page (Generic Desktop)      66
239        0x09, 0x39,                    # ..Usage (Hat switch)                68
240        0x25, 0x07,                    # ..Logical Maximum (7)               70
241        0x46, 0x3b, 0x01,              # ..Physical Maximum (315)            72
242        0x55, 0x00,                    # ..Unit Exponent (0)                 75
243        0x65, 0x44,                    # ..Unit (Degrees^4,EngRotation)      77
244        0x75, 0x04,                    # ..Report Size (4)                   79
245        0x81, 0x42,                    # ..Input (Data,Var,Abs,Null)         81
246        0x65, 0x00,                    # ..Unit (None)                       83
247        0xc0,                          # .End Collection                     85
248        0x05, 0x0f,                    # .Usage Page (Vendor Usage Page 0x0f) 86
249        0x09, 0x92,                    # .Usage (Vendor Usage 0x92)          88
250        0xa1, 0x02,                    # .Collection (Logical)               90
251        0x85, 0x02,                    # ..Report ID (2)                     92
252        0x09, 0xa0,                    # ..Usage (Vendor Usage 0xa0)         94
253        0x09, 0x9f,                    # ..Usage (Vendor Usage 0x9f)         96
254        0x25, 0x01,                    # ..Logical Maximum (1)               98
255        0x45, 0x00,                    # ..Physical Maximum (0)              100
256        0x75, 0x01,                    # ..Report Size (1)                   102
257        0x95, 0x02,                    # ..Report Count (2)                  104
258        0x81, 0x02,                    # ..Input (Data,Var,Abs)              106
259        0x75, 0x06,                    # ..Report Size (6)                   108
260        0x95, 0x01,                    # ..Report Count (1)                  110
261        0x81, 0x03,                    # ..Input (Cnst,Var,Abs)              112
262        0x09, 0x22,                    # ..Usage (Vendor Usage 0x22)         114
263        0x75, 0x07,                    # ..Report Size (7)                   116
264        0x25, 0x7f,                    # ..Logical Maximum (127)             118
265        0x81, 0x02,                    # ..Input (Data,Var,Abs)              120
266        0x09, 0x94,                    # ..Usage (Vendor Usage 0x94)         122
267        0x75, 0x01,                    # ..Report Size (1)                   124
268        0x25, 0x01,                    # ..Logical Maximum (1)               126
269        0x81, 0x02,                    # ..Input (Data,Var,Abs)              128
270        0xc0,                          # .End Collection                     130
271        0x09, 0x21,                    # .Usage (Vendor Usage 0x21)          131
272        0xa1, 0x02,                    # .Collection (Logical)               133
273        0x85, 0x0b,                    # ..Report ID (11)                    135
274        0x09, 0x22,                    # ..Usage (Vendor Usage 0x22)         137
275        0x26, 0xff, 0x00,              # ..Logical Maximum (255)             139
276        0x75, 0x08,                    # ..Report Size (8)                   142
277        0x91, 0x02,                    # ..Output (Data,Var,Abs)             144
278        0x09, 0x53,                    # ..Usage (Vendor Usage 0x53)         146
279        0x25, 0x0a,                    # ..Logical Maximum (10)              148
280        0x91, 0x02,                    # ..Output (Data,Var,Abs)             150
281        0x09, 0x50,                    # ..Usage (Vendor Usage 0x50)         152
282        0x27, 0xfe, 0xff, 0x00, 0x00,  # ..Logical Maximum (65534)           154
283        0x47, 0xfe, 0xff, 0x00, 0x00,  # ..Physical Maximum (65534)          159
284        0x75, 0x10,                    # ..Report Size (16)                  164
285        0x55, 0xfd,                    # ..Unit Exponent (237)               166
286        0x66, 0x01, 0x10,              # ..Unit (Seconds,SILinear)           168
287        0x91, 0x02,                    # ..Output (Data,Var,Abs)             171
288        0x55, 0x00,                    # ..Unit Exponent (0)                 173
289        0x65, 0x00,                    # ..Unit (None)                       175
290        0x09, 0x54,                    # ..Usage (Vendor Usage 0x54)         177
291        0x55, 0xfd,                    # ..Unit Exponent (237)               179
292        0x66, 0x01, 0x10,              # ..Unit (Seconds,SILinear)           181
293        0x91, 0x02,                    # ..Output (Data,Var,Abs)             184
294        0x55, 0x00,                    # ..Unit Exponent (0)                 186
295        0x65, 0x00,                    # ..Unit (None)                       188
296        0x09, 0xa7,                    # ..Usage (Vendor Usage 0xa7)         190
297        0x55, 0xfd,                    # ..Unit Exponent (237)               192
298        0x66, 0x01, 0x10,              # ..Unit (Seconds,SILinear)           194
299        0x91, 0x02,                    # ..Output (Data,Var,Abs)             197
300        0x55, 0x00,                    # ..Unit Exponent (0)                 199
301        0x65, 0x00,                    # ..Unit (None)                       201
302        0xc0,                          # .End Collection                     203
303        0x09, 0x5a,                    # .Usage (Vendor Usage 0x5a)          204
304        0xa1, 0x02,                    # .Collection (Logical)               206
305        0x85, 0x0c,                    # ..Report ID (12)                    208
306        0x09, 0x22,                    # ..Usage (Vendor Usage 0x22)         210
307        0x26, 0xff, 0x00,              # ..Logical Maximum (255)             212
308        0x45, 0x00,                    # ..Physical Maximum (0)              215
309        0x75, 0x08,                    # ..Report Size (8)                   217
310        0x91, 0x02,                    # ..Output (Data,Var,Abs)             219
311        0x09, 0x5c,                    # ..Usage (Vendor Usage 0x5c)         221
312        0x26, 0x10, 0x27,              # ..Logical Maximum (10000)           223
313        0x46, 0x10, 0x27,              # ..Physical Maximum (10000)          226
314        0x75, 0x10,                    # ..Report Size (16)                  229
315        0x55, 0xfd,                    # ..Unit Exponent (237)               231
316        0x66, 0x01, 0x10,              # ..Unit (Seconds,SILinear)           233
317        0x91, 0x02,                    # ..Output (Data,Var,Abs)             236
318        0x55, 0x00,                    # ..Unit Exponent (0)                 238
319        0x65, 0x00,                    # ..Unit (None)                       240
320        0x09, 0x5b,                    # ..Usage (Vendor Usage 0x5b)         242
321        0x25, 0x7f,                    # ..Logical Maximum (127)             244
322        0x75, 0x08,                    # ..Report Size (8)                   246
323        0x91, 0x02,                    # ..Output (Data,Var,Abs)             248
324        0x09, 0x5e,                    # ..Usage (Vendor Usage 0x5e)         250
325        0x26, 0x10, 0x27,              # ..Logical Maximum (10000)           252
326        0x75, 0x10,                    # ..Report Size (16)                  255
327        0x55, 0xfd,                    # ..Unit Exponent (237)               257
328        0x66, 0x01, 0x10,              # ..Unit (Seconds,SILinear)           259
329        0x91, 0x02,                    # ..Output (Data,Var,Abs)             262
330        0x55, 0x00,                    # ..Unit Exponent (0)                 264
331        0x65, 0x00,                    # ..Unit (None)                       266
332        0x09, 0x5d,                    # ..Usage (Vendor Usage 0x5d)         268
333        0x25, 0x7f,                    # ..Logical Maximum (127)             270
334        0x75, 0x08,                    # ..Report Size (8)                   272
335        0x91, 0x02,                    # ..Output (Data,Var,Abs)             274
336        0xc0,                          # .End Collection                     276
337        0x09, 0x73,                    # .Usage (Vendor Usage 0x73)          277
338        0xa1, 0x02,                    # .Collection (Logical)               279
339        0x85, 0x0d,                    # ..Report ID (13)                    281
340        0x09, 0x22,                    # ..Usage (Vendor Usage 0x22)         283
341        0x26, 0xff, 0x00,              # ..Logical Maximum (255)             285
342        0x45, 0x00,                    # ..Physical Maximum (0)              288
343        0x91, 0x02,                    # ..Output (Data,Var,Abs)             290
344        0x09, 0x70,                    # ..Usage (Vendor Usage 0x70)         292
345        0x15, 0x81,                    # ..Logical Minimum (-127)            294
346        0x25, 0x7f,                    # ..Logical Maximum (127)             296
347        0x36, 0xf0, 0xd8,              # ..Physical Minimum (-10000)         298
348        0x46, 0x10, 0x27,              # ..Physical Maximum (10000)          301
349        0x91, 0x02,                    # ..Output (Data,Var,Abs)             304
350        0xc0,                          # .End Collection                     306
351        0x09, 0x6e,                    # .Usage (Vendor Usage 0x6e)          307
352        0xa1, 0x02,                    # .Collection (Logical)               309
353        0x85, 0x0e,                    # ..Report ID (14)                    311
354        0x09, 0x22,                    # ..Usage (Vendor Usage 0x22)         313
355        0x15, 0x00,                    # ..Logical Minimum (0)               315
356        0x26, 0xff, 0x00,              # ..Logical Maximum (255)             317
357        0x35, 0x00,                    # ..Physical Minimum (0)              320
358        0x45, 0x00,                    # ..Physical Maximum (0)              322
359        0x91, 0x02,                    # ..Output (Data,Var,Abs)             324
360        0x09, 0x70,                    # ..Usage (Vendor Usage 0x70)         326
361        0x25, 0x7f,                    # ..Logical Maximum (127)             328
362        0x46, 0x10, 0x27,              # ..Physical Maximum (10000)          330
363        0x91, 0x02,                    # ..Output (Data,Var,Abs)             333
364        0x09, 0x6f,                    # ..Usage (Vendor Usage 0x6f)         335
365        0x15, 0x81,                    # ..Logical Minimum (-127)            337
366        0x36, 0xf0, 0xd8,              # ..Physical Minimum (-10000)         339
367        0x91, 0x02,                    # ..Output (Data,Var,Abs)             342
368        0x09, 0x71,                    # ..Usage (Vendor Usage 0x71)         344
369        0x15, 0x00,                    # ..Logical Minimum (0)               346
370        0x26, 0xff, 0x00,              # ..Logical Maximum (255)             348
371        0x35, 0x00,                    # ..Physical Minimum (0)              351
372        0x46, 0x68, 0x01,              # ..Physical Maximum (360)            353
373        0x91, 0x02,                    # ..Output (Data,Var,Abs)             356
374        0x09, 0x72,                    # ..Usage (Vendor Usage 0x72)         358
375        0x75, 0x10,                    # ..Report Size (16)                  360
376        0x26, 0x10, 0x27,              # ..Logical Maximum (10000)           362
377        0x46, 0x10, 0x27,              # ..Physical Maximum (10000)          365
378        0x55, 0xfd,                    # ..Unit Exponent (237)               368
379        0x66, 0x01, 0x10,              # ..Unit (Seconds,SILinear)           370
380        0x91, 0x02,                    # ..Output (Data,Var,Abs)             373
381        0x55, 0x00,                    # ..Unit Exponent (0)                 375
382        0x65, 0x00,                    # ..Unit (None)                       377
383        0xc0,                          # .End Collection                     379
384        0x09, 0x77,                    # .Usage (Vendor Usage 0x77)          380
385        0xa1, 0x02,                    # .Collection (Logical)               382
386        0x85, 0x51,                    # ..Report ID (81)                    384
387        0x09, 0x22,                    # ..Usage (Vendor Usage 0x22)         386
388        0x25, 0x7f,                    # ..Logical Maximum (127)             388
389        0x45, 0x00,                    # ..Physical Maximum (0)              390
390        0x75, 0x08,                    # ..Report Size (8)                   392
391        0x91, 0x02,                    # ..Output (Data,Var,Abs)             394
392        0x09, 0x78,                    # ..Usage (Vendor Usage 0x78)         396
393        0xa1, 0x02,                    # ..Collection (Logical)              398
394        0x09, 0x7b,                    # ...Usage (Vendor Usage 0x7b)        400
395        0x09, 0x79,                    # ...Usage (Vendor Usage 0x79)        402
396        0x09, 0x7a,                    # ...Usage (Vendor Usage 0x7a)        404
397        0x15, 0x01,                    # ...Logical Minimum (1)              406
398        0x25, 0x03,                    # ...Logical Maximum (3)              408
399        0x91, 0x00,                    # ...Output (Data,Arr,Abs)            410
400        0xc0,                          # ..End Collection                    412
401        0x09, 0x7c,                    # ..Usage (Vendor Usage 0x7c)         413
402        0x15, 0x00,                    # ..Logical Minimum (0)               415
403        0x26, 0xfe, 0x00,              # ..Logical Maximum (254)             417
404        0x91, 0x02,                    # ..Output (Data,Var,Abs)             420
405        0xc0,                          # .End Collection                     422
406        0x09, 0x92,                    # .Usage (Vendor Usage 0x92)          423
407        0xa1, 0x02,                    # .Collection (Logical)               425
408        0x85, 0x52,                    # ..Report ID (82)                    427
409        0x09, 0x96,                    # ..Usage (Vendor Usage 0x96)         429
410        0xa1, 0x02,                    # ..Collection (Logical)              431
411        0x09, 0x9a,                    # ...Usage (Vendor Usage 0x9a)        433
412        0x09, 0x99,                    # ...Usage (Vendor Usage 0x99)        435
413        0x09, 0x97,                    # ...Usage (Vendor Usage 0x97)        437
414        0x09, 0x98,                    # ...Usage (Vendor Usage 0x98)        439
415        0x09, 0x9b,                    # ...Usage (Vendor Usage 0x9b)        441
416        0x09, 0x9c,                    # ...Usage (Vendor Usage 0x9c)        443
417        0x15, 0x01,                    # ...Logical Minimum (1)              445
418        0x25, 0x06,                    # ...Logical Maximum (6)              447
419        0x91, 0x00,                    # ...Output (Data,Arr,Abs)            449
420        0xc0,                          # ..End Collection                    451
421        0xc0,                          # .End Collection                     452
422        0x05, 0xff,                    # .Usage Page (Vendor Usage Page 0xff) 453
423        0x0a, 0x01, 0x03,              # .Usage (Vendor Usage 0x301)         455
424        0xa1, 0x02,                    # .Collection (Logical)               458
425        0x85, 0x40,                    # ..Report ID (64)                    460
426        0x0a, 0x02, 0x03,              # ..Usage (Vendor Usage 0x302)        462
427        0xa1, 0x02,                    # ..Collection (Logical)              465
428        0x1a, 0x11, 0x03,              # ...Usage Minimum (785)              467
429        0x2a, 0x20, 0x03,              # ...Usage Maximum (800)              470
430        0x25, 0x10,                    # ...Logical Maximum (16)             473
431        0x91, 0x00,                    # ...Output (Data,Arr,Abs)            475
432        0xc0,                          # ..End Collection                    477
433        0x0a, 0x03, 0x03,              # ..Usage (Vendor Usage 0x303)        478
434        0x15, 0x00,                    # ..Logical Minimum (0)               481
435        0x27, 0xff, 0xff, 0x00, 0x00,  # ..Logical Maximum (65535)           483
436        0x75, 0x10,                    # ..Report Size (16)                  488
437        0x91, 0x02,                    # ..Output (Data,Var,Abs)             490
438        0xc0,                          # .End Collection                     492
439        0x05, 0x0f,                    # .Usage Page (Vendor Usage Page 0x0f) 493
440        0x09, 0x7d,                    # .Usage (Vendor Usage 0x7d)          495
441        0xa1, 0x02,                    # .Collection (Logical)               497
442        0x85, 0x43,                    # ..Report ID (67)                    499
443        0x09, 0x7e,                    # ..Usage (Vendor Usage 0x7e)         501
444        0x26, 0x80, 0x00,              # ..Logical Maximum (128)             503
445        0x46, 0x10, 0x27,              # ..Physical Maximum (10000)          506
446        0x75, 0x08,                    # ..Report Size (8)                   509
447        0x91, 0x02,                    # ..Output (Data,Var,Abs)             511
448        0xc0,                          # .End Collection                     513
449        0x09, 0x7f,                    # .Usage (Vendor Usage 0x7f)          514
450        0xa1, 0x02,                    # .Collection (Logical)               516
451        0x85, 0x0b,                    # ..Report ID (11)                    518
452        0x09, 0x80,                    # ..Usage (Vendor Usage 0x80)         520
453        0x26, 0xff, 0x7f,              # ..Logical Maximum (32767)           522
454        0x45, 0x00,                    # ..Physical Maximum (0)              525
455        0x75, 0x0f,                    # ..Report Size (15)                  527
456        0xb1, 0x03,                    # ..Feature (Cnst,Var,Abs)            529
457        0x09, 0xa9,                    # ..Usage (Vendor Usage 0xa9)         531
458        0x25, 0x01,                    # ..Logical Maximum (1)               533
459        0x75, 0x01,                    # ..Report Size (1)                   535
460        0xb1, 0x03,                    # ..Feature (Cnst,Var,Abs)            537
461        0x09, 0x83,                    # ..Usage (Vendor Usage 0x83)         539
462        0x26, 0xff, 0x00,              # ..Logical Maximum (255)             541
463        0x75, 0x08,                    # ..Report Size (8)                   544
464        0xb1, 0x03,                    # ..Feature (Cnst,Var,Abs)            546
465        0xc0,                          # .End Collection                     548
466        0x09, 0xab,                    # .Usage (Vendor Usage 0xab)          549
467        0xa1, 0x03,                    # .Collection (Report)                551
468        0x85, 0x15,                    # ..Report ID (21)                    553
469        0x09, 0x25,                    # ..Usage (Vendor Usage 0x25)         555
470        0xa1, 0x02,                    # ..Collection (Logical)              557
471        0x09, 0x26,                    # ...Usage (Vendor Usage 0x26)        559
472        0x09, 0x30,                    # ...Usage (Vendor Usage 0x30)        561
473        0x09, 0x32,                    # ...Usage (Vendor Usage 0x32)        563
474        0x09, 0x31,                    # ...Usage (Vendor Usage 0x31)        565
475        0x09, 0x33,                    # ...Usage (Vendor Usage 0x33)        567
476        0x09, 0x34,                    # ...Usage (Vendor Usage 0x34)        569
477        0x15, 0x01,                    # ...Logical Minimum (1)              571
478        0x25, 0x06,                    # ...Logical Maximum (6)              573
479        0xb1, 0x00,                    # ...Feature (Data,Arr,Abs)           575
480        0xc0,                          # ..End Collection                    577
481        0xc0,                          # .End Collection                     578
482        0x09, 0x89,                    # .Usage (Vendor Usage 0x89)          579
483        0xa1, 0x03,                    # .Collection (Report)                581
484        0x85, 0x16,                    # ..Report ID (22)                    583
485        0x09, 0x8b,                    # ..Usage (Vendor Usage 0x8b)         585
486        0xa1, 0x02,                    # ..Collection (Logical)              587
487        0x09, 0x8c,                    # ...Usage (Vendor Usage 0x8c)        589
488        0x09, 0x8d,                    # ...Usage (Vendor Usage 0x8d)        591
489        0x09, 0x8e,                    # ...Usage (Vendor Usage 0x8e)        593
490        0x25, 0x03,                    # ...Logical Maximum (3)              595
491        0xb1, 0x00,                    # ...Feature (Data,Arr,Abs)           597
492        0xc0,                          # ..End Collection                    599
493        0x09, 0x22,                    # ..Usage (Vendor Usage 0x22)         600
494        0x15, 0x00,                    # ..Logical Minimum (0)               602
495        0x26, 0xfe, 0x00,              # ..Logical Maximum (254)             604
496        0xb1, 0x02,                    # ..Feature (Data,Var,Abs)            607
497        0xc0,                          # .End Collection                     609
498        0x09, 0x90,                    # .Usage (Vendor Usage 0x90)          610
499        0xa1, 0x03,                    # .Collection (Report)                612
500        0x85, 0x50,                    # ..Report ID (80)                    614
501        0x09, 0x22,                    # ..Usage (Vendor Usage 0x22)         616
502        0x26, 0xff, 0x00,              # ..Logical Maximum (255)             618
503        0x91, 0x02,                    # ..Output (Data,Var,Abs)             621
504        0xc0,                          # .End Collection                     623
505        0xc0,                          # End Collection                      624
506    ]
507    # fmt: on
508
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: off
516    report_descriptor = [
517        0x05, 0x01,                    # Usage Page (Generic Desktop)        0
518        0x09, 0x05,                    # Usage (Game Pad)                    2
519        0xa1, 0x01,                    # Collection (Application)            4
520        0x85, 0x01,                    # .Report ID (1)                      6
521        0x05, 0x09,                    # .Usage Page (Button)                8
522        0x0a, 0x01, 0x00,              # .Usage (Vendor Usage 0x01)          10
523        0x0a, 0x02, 0x00,              # .Usage (Vendor Usage 0x02)          13
524        0x0a, 0x04, 0x00,              # .Usage (Vendor Usage 0x04)          16
525        0x0a, 0x05, 0x00,              # .Usage (Vendor Usage 0x05)          19
526        0x0a, 0x07, 0x00,              # .Usage (Vendor Usage 0x07)          22
527        0x0a, 0x08, 0x00,              # .Usage (Vendor Usage 0x08)          25
528        0x0a, 0x0e, 0x00,              # .Usage (Vendor Usage 0x0e)          28
529        0x0a, 0x0f, 0x00,              # .Usage (Vendor Usage 0x0f)          31
530        0x0a, 0x0d, 0x00,              # .Usage (Vendor Usage 0x0d)          34
531        0x05, 0x0c,                    # .Usage Page (Consumer Devices)      37
532        0x0a, 0x24, 0x02,              # .Usage (AC Back)                    39
533        0x0a, 0x23, 0x02,              # .Usage (AC Home)                    42
534        0x15, 0x00,                    # .Logical Minimum (0)                45
535        0x25, 0x01,                    # .Logical Maximum (1)                47
536        0x75, 0x01,                    # .Report Size (1)                    49
537        0x95, 0x0b,                    # .Report Count (11)                  51
538        0x81, 0x02,                    # .Input (Data,Var,Abs)               53
539        0x75, 0x01,                    # .Report Size (1)                    55
540        0x95, 0x01,                    # .Report Count (1)                   57
541        0x81, 0x03,                    # .Input (Cnst,Var,Abs)               59
542        0x05, 0x01,                    # .Usage Page (Generic Desktop)       61
543        0x75, 0x04,                    # .Report Size (4)                    63
544        0x95, 0x01,                    # .Report Count (1)                   65
545        0x25, 0x07,                    # .Logical Maximum (7)                67
546        0x46, 0x3b, 0x01,              # .Physical Maximum (315)             69
547        0x66, 0x14, 0x00,              # .Unit (Degrees,EngRotation)         72
548        0x09, 0x39,                    # .Usage (Hat switch)                 75
549        0x81, 0x42,                    # .Input (Data,Var,Abs,Null)          77
550        0x66, 0x00, 0x00,              # .Unit (None)                        79
551        0x09, 0x01,                    # .Usage (Pointer)                    82
552        0xa1, 0x00,                    # .Collection (Physical)              84
553        0x09, 0x30,                    # ..Usage (X)                         86
554        0x09, 0x31,                    # ..Usage (Y)                         88
555        0x09, 0x32,                    # ..Usage (Z)                         90
556        0x09, 0x35,                    # ..Usage (Rz)                        92
557        0x05, 0x02,                    # ..Usage Page (Simulation Controls)  94
558        0x09, 0xc5,                    # ..Usage (Brake)                     96
559        0x09, 0xc4,                    # ..Usage (Accelerator)               98
560        0x15, 0x00,                    # ..Logical Minimum (0)               100
561        0x26, 0xff, 0x00,              # ..Logical Maximum (255)             102
562        0x35, 0x00,                    # ..Physical Minimum (0)              105
563        0x46, 0xff, 0x00,              # ..Physical Maximum (255)            107
564        0x75, 0x08,                    # ..Report Size (8)                   110
565        0x95, 0x06,                    # ..Report Count (6)                  112
566        0x81, 0x02,                    # ..Input (Data,Var,Abs)              114
567        0xc0,                          # .End Collection                     116
568        0x85, 0x02,                    # .Report ID (2)                      117
569        0x05, 0x08,                    # .Usage Page (LEDs)                  119
570        0x0a, 0x01, 0x00,              # .Usage (Num Lock)                   121
571        0x0a, 0x02, 0x00,              # .Usage (Caps Lock)                  124
572        0x0a, 0x03, 0x00,              # .Usage (Scroll Lock)                127
573        0x0a, 0x04, 0x00,              # .Usage (Compose)                    130
574        0x15, 0x00,                    # .Logical Minimum (0)                133
575        0x25, 0x01,                    # .Logical Maximum (1)                135
576        0x75, 0x01,                    # .Report Size (1)                    137
577        0x95, 0x04,                    # .Report Count (4)                   139
578        0x91, 0x02,                    # .Output (Data,Var,Abs)              141
579        0x75, 0x04,                    # .Report Size (4)                    143
580        0x95, 0x01,                    # .Report Count (1)                   145
581        0x91, 0x03,                    # .Output (Cnst,Var,Abs)              147
582        0xc0,                          # End Collection                      149
583        0x05, 0x0c,                    # Usage Page (Consumer Devices)       150
584        0x09, 0x01,                    # Usage (Consumer Control)            152
585        0xa1, 0x01,                    # Collection (Application)            154
586        0x85, 0x03,                    # .Report ID (3)                      156
587        0x05, 0x01,                    # .Usage Page (Generic Desktop)       158
588        0x09, 0x06,                    # .Usage (Keyboard)                   160
589        0xa1, 0x02,                    # .Collection (Logical)               162
590        0x05, 0x06,                    # ..Usage Page (Generic Device Controls) 164
591        0x09, 0x20,                    # ..Usage (Battery Strength)          166
592        0x15, 0x00,                    # ..Logical Minimum (0)               168
593        0x26, 0xff, 0x00,              # ..Logical Maximum (255)             170
594        0x75, 0x08,                    # ..Report Size (8)                   173
595        0x95, 0x01,                    # ..Report Count (1)                  175
596        0x81, 0x02,                    # ..Input (Data,Var,Abs)              177
597        0x06, 0xbc, 0xff,              # ..Usage Page (Vendor Usage Page 0xffbc) 179
598        0x0a, 0xad, 0xbd,              # ..Usage (Vendor Usage 0xbdad)       182
599        0x75, 0x08,                    # ..Report Size (8)                   185
600        0x95, 0x06,                    # ..Report Count (6)                  187
601        0x81, 0x02,                    # ..Input (Data,Var,Abs)              189
602        0xc0,                          # .End Collection                     191
603        0xc0,                          # End Collection                      192
604    ]
605    # fmt: on
606
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 239
634
635    def event(
636        self, *, left=(None, None), right=(None, None), hat_switch=None, buttons=None
637    ):
638        if hat_switch is not None:
639            hat_switch *= 30
640
641        return super().event(
642            left=left, right=right, hat_switch=hat_switch, buttons=buttons
643        )
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