#!/bin/env python3
# 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
from .base import HidBpf
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 = [
0 x05, 0 x01, # Usage Page (Generic Desktop) 0
0 x09, 0 x04, # Usage (Joystick) 2
0 xa1, 0 x01, # Collection (Application) 4
0 x09, 0 x01, # .Usage (Pointer) 6
0 xa1, 0 x00, # .Collection (Physical) 8
0 x85, 0 x01, # ..Report ID (1) 10
0 x09, 0 x30, # ..Usage (X) 12
0 x15, 0 x00, # ..Logical Minimum (0) 14
0 x26, 0 xff, 0 x00, # ..Logical Maximum (255) 16
0 x35, 0 x00, # ..Physical Minimum (0) 19
0 x46, 0 xff, 0 x00, # ..Physical Maximum (255) 21
0 x75, 0 x08, # ..Report Size (8) 24
0 x95, 0 x01, # ..Report Count (1) 26
0 x81, 0 x02, # ..Input (Data,Var,Abs) 28
0 x09, 0 x31, # ..Usage (Y) 30
0 x81, 0 x02, # ..Input (Data,Var,Abs) 32
0 x05, 0 x02, # ..Usage Page (Simulation Controls) 34
0 x09, 0 xba, # ..Usage (Rudder) 36
0 x81, 0 x02, # ..Input (Data,Var,Abs) 38
0 x09, 0 xbb, # ..Usage (Throttle) 40
0 x81, 0 x02, # ..Input (Data,Var,Abs) 42
0 x05, 0 x09, # ..Usage Page (Button) 44
0 x19, 0 x01, # ..Usage Minimum (1) 46
0 x29, 0 x0c, # ..Usage Maximum (12) 48
0 x25, 0 x01, # ..Logical Maximum (1) 50
0 x45, 0 x01, # ..Physical Maximum (1) 52
0 x75, 0 x01, # ..Report Size (1) 54
0 x95, 0 x0c, # ..Report Count (12) 56
0 x81, 0 x02, # ..Input (Data,Var,Abs) 58
0 x95, 0 x01, # ..Report Count (1) 60
0 x75, 0 x00, # ..Report Size (0) 62
0 x81, 0 x03, # ..Input (Cnst,Var,Abs) 64
0 x05, 0 x01, # ..Usage Page (Generic Desktop) 66
0 x09, 0 x39, # ..Usage (Hat switch) 68
0 x25, 0 x07, # ..Logical Maximum (7) 70
0 x46, 0 x3b, 0 x01, # ..Physical Maximum (315) 72
0 x55, 0 x00, # ..Unit Exponent (0) 75
0 x65, 0 x44, # ..Unit (Degrees^4,EngRotation) 77
0 x75, 0 x04, # ..Report Size (4) 79
0 x81, 0 x42, # ..Input (Data,Var,Abs,Null) 81
0 x65, 0 x00, # ..Unit (None) 83
0 xc0, # .End Collection 85
0 x05, 0 x0f, # .Usage Page (Vendor Usage Page 0x0f) 86
0 x09, 0 x92, # .Usage (Vendor Usage 0x92) 88
0 xa1, 0 x02, # .Collection (Logical) 90
0 x85, 0 x02, # ..Report ID (2) 92
0 x09, 0 xa0, # ..Usage (Vendor Usage 0xa0) 94
0 x09, 0 x9f, # ..Usage (Vendor Usage 0x9f) 96
0 x25, 0 x01, # ..Logical Maximum (1) 98
0 x45, 0 x00, # ..Physical Maximum (0) 100
0 x75, 0 x01, # ..Report Size (1) 102
0 x95, 0 x02, # ..Report Count (2) 104
0 x81, 0 x02, # ..Input (Data,Var,Abs) 106
0 x75, 0 x06, # ..Report Size (6) 108
0 x95, 0 x01, # ..Report Count (1) 110
0 x81, 0 x03, # ..Input (Cnst,Var,Abs) 112
0 x09, 0 x22, # ..Usage (Vendor Usage 0x22) 114
0 x75, 0 x07, # ..Report Size (7) 116
0 x25, 0 x7f, # ..Logical Maximum (127) 118
0 x81, 0 x02, # ..Input (Data,Var,Abs) 120
0 x09, 0 x94, # ..Usage (Vendor Usage 0x94) 122
0 x75, 0 x01, # ..Report Size (1) 124
0 x25, 0 x01, # ..Logical Maximum (1) 126
0 x81, 0 x02, # ..Input (Data,Var,Abs) 128
0 xc0, # .End Collection 130
0 x09, 0 x21, # .Usage (Vendor Usage 0x21) 131
0 xa1, 0 x02, # .Collection (Logical) 133
0 x85, 0 x0b, # ..Report ID (11) 135
0 x09, 0 x22, # ..Usage (Vendor Usage 0x22) 137
0 x26, 0 xff, 0 x00, # ..Logical Maximum (255) 139
0 x75, 0 x08, # ..Report Size (8) 142
0 x91, 0 x02, # ..Output (Data,Var,Abs) 144
0 x09, 0 x53, # ..Usage (Vendor Usage 0x53) 146
0 x25, 0 x0a, # ..Logical Maximum (10) 148
0 x91, 0 x02, # ..Output (Data,Var,Abs) 150
0 x09, 0 x50, # ..Usage (Vendor Usage 0x50) 152
0 x27, 0 xfe, 0 xff, 0 x00, 0 x00, # ..Logical Maximum (65534) 154
0 x47, 0 xfe, 0 xff, 0 x00, 0 x00, # ..Physical Maximum (65534) 159
0 x75, 0 x10, # ..Report Size (16) 164
0 x55, 0 xfd, # ..Unit Exponent (237) 166
0 x66, 0 x01, 0 x10, # ..Unit (Seconds,SILinear) 168
0 x91, 0 x02, # ..Output (Data,Var,Abs) 171
0 x55, 0 x00, # ..Unit Exponent (0) 173
0 x65, 0 x00, # ..Unit (None) 175
0 x09, 0 x54, # ..Usage (Vendor Usage 0x54) 177
0 x55, 0 xfd, # ..Unit Exponent (237) 179
0 x66, 0 x01, 0 x10, # ..Unit (Seconds,SILinear) 181
0 x91, 0 x02, # ..Output (Data,Var,Abs) 184
0 x55, 0 x00, # ..Unit Exponent (0) 186
0 x65, 0 x00, # ..Unit (None) 188
0 x09, 0 xa7, # ..Usage (Vendor Usage 0xa7) 190
0 x55, 0 xfd, # ..Unit Exponent (237) 192
0 x66, 0 x01, 0 x10, # ..Unit (Seconds,SILinear) 194
0 x91, 0 x02, # ..Output (Data,Var,Abs) 197
0 x55, 0 x00, # ..Unit Exponent (0) 199
0 x65, 0 x00, # ..Unit (None) 201
0 xc0, # .End Collection 203
0 x09, 0 x5a, # .Usage (Vendor Usage 0x5a) 204
0 xa1, 0 x02, # .Collection (Logical) 206
0 x85, 0 x0c, # ..Report ID (12) 208
0 x09, 0 x22, # ..Usage (Vendor Usage 0x22) 210
0 x26, 0 xff, 0 x00, # ..Logical Maximum (255) 212
0 x45, 0 x00, # ..Physical Maximum (0) 215
0 x75, 0 x08, # ..Report Size (8) 217
0 x91, 0 x02, # ..Output (Data,Var,Abs) 219
0 x09, 0 x5c, # ..Usage (Vendor Usage 0x5c) 221
0 x26, 0 x10, 0 x27, # ..Logical Maximum (10000) 223
0 x46, 0 x10, 0 x27, # ..Physical Maximum (10000) 226
0 x75, 0 x10, # ..Report Size (16) 229
0 x55, 0 xfd, # ..Unit Exponent (237) 231
0 x66, 0 x01, 0 x10, # ..Unit (Seconds,SILinear) 233
0 x91, 0 x02, # ..Output (Data,Var,Abs) 236
0 x55, 0 x00, # ..Unit Exponent (0) 238
0 x65, 0 x00, # ..Unit (None) 240
0 x09, 0 x5b, # ..Usage (Vendor Usage 0x5b) 242
0 x25, 0 x7f, # ..Logical Maximum (127) 244
0 x75, 0 x08, # ..Report Size (8) 246
0 x91, 0 x02, # ..Output (Data,Var,Abs) 248
0 x09, 0 x5e, # ..Usage (Vendor Usage 0x5e) 250
0 x26, 0 x10, 0 x27, # ..Logical Maximum (10000) 252
0 x75, 0 x10, # ..Report Size (16) 255
0 x55, 0 xfd, # ..Unit Exponent (237) 257
0 x66, 0 x01, 0 x10, # ..Unit (Seconds,SILinear) 259
0 x91, 0 x02, # ..Output (Data,Var,Abs) 262
0 x55, 0 x00, # ..Unit Exponent (0) 264
0 x65, 0 x00, # ..Unit (None) 266
0 x09, 0 x5d, # ..Usage (Vendor Usage 0x5d) 268
0 x25, 0 x7f, # ..Logical Maximum (127) 270
0 x75, 0 x08, # ..Report Size (8) 272
0 x91, 0 x02, # ..Output (Data,Var,Abs) 274
0 xc0, # .End Collection 276
0 x09, 0 x73, # .Usage (Vendor Usage 0x73) 277
0 xa1, 0 x02, # .Collection (Logical) 279
0 x85, 0 x0d, # ..Report ID (13) 281
0 x09, 0 x22, # ..Usage (Vendor Usage 0x22) 283
0 x26, 0 xff, 0 x00, # ..Logical Maximum (255) 285
0 x45, 0 x00, # ..Physical Maximum (0) 288
0 x91, 0 x02, # ..Output (Data,Var,Abs) 290
0 x09, 0 x70, # ..Usage (Vendor Usage 0x70) 292
0 x15, 0 x81, # ..Logical Minimum (-127) 294
0 x25, 0 x7f, # ..Logical Maximum (127) 296
0 x36, 0 xf0, 0 xd8, # ..Physical Minimum (-10000) 298
0 x46, 0 x10, 0 x27, # ..Physical Maximum (10000) 301
0 x91, 0 x02, # ..Output (Data,Var,Abs) 304
0 xc0, # .End Collection 306
0 x09, 0 x6e, # .Usage (Vendor Usage 0x6e) 307
0 xa1, 0 x02, # .Collection (Logical) 309
0 x85, 0 x0e, # ..Report ID (14) 311
0 x09, 0 x22, # ..Usage (Vendor Usage 0x22) 313
0 x15, 0 x00, # ..Logical Minimum (0) 315
0 x26, 0 xff, 0 x00, # ..Logical Maximum (255) 317
0 x35, 0 x00, # ..Physical Minimum (0) 320
0 x45, 0 x00, # ..Physical Maximum (0) 322
0 x91, 0 x02, # ..Output (Data,Var,Abs) 324
0 x09, 0 x70, # ..Usage (Vendor Usage 0x70) 326
0 x25, 0 x7f, # ..Logical Maximum (127) 328
0 x46, 0 x10, 0 x27, # ..Physical Maximum (10000) 330
0 x91, 0 x02, # ..Output (Data,Var,Abs) 333
0 x09, 0 x6f, # ..Usage (Vendor Usage 0x6f) 335
0 x15, 0 x81, # ..Logical Minimum (-127) 337
0 x36, 0 xf0, 0 xd8, # ..Physical Minimum (-10000) 339
0 x91, 0 x02, # ..Output (Data,Var,Abs) 342
0 x09, 0 x71, # ..Usage (Vendor Usage 0x71) 344
0 x15, 0 x00, # ..Logical Minimum (0) 346
0 x26, 0 xff, 0 x00, # ..Logical Maximum (255) 348
0 x35, 0 x00, # ..Physical Minimum (0) 351
0 x46, 0 x68, 0 x01, # ..Physical Maximum (360) 353
0 x91, 0 x02, # ..Output (Data,Var,Abs) 356
0 x09, 0 x72, # ..Usage (Vendor Usage 0x72) 358
0 x75, 0 x10, # ..Report Size (16) 360
0 x26, 0 x10, 0 x27, # ..Logical Maximum (10000) 362
0 x46, 0 x10, 0 x27, # ..Physical Maximum (10000) 365
0 x55, 0 xfd, # ..Unit Exponent (237) 368
0 x66, 0 x01, 0 x10, # ..Unit (Seconds,SILinear) 370
0 x91, 0 x02, # ..Output (Data,Var,Abs) 373
0 x55, 0 x00, # ..Unit Exponent (0) 375
0 x65, 0 x00, # ..Unit (None) 377
0 xc0, # .End Collection 379
0 x09, 0 x77, # .Usage (Vendor Usage 0x77) 380
0 xa1, 0 x02, # .Collection (Logical) 382
0 x85, 0 x51, # ..Report ID (81) 384
0 x09, 0 x22, # ..Usage (Vendor Usage 0x22) 386
0 x25, 0 x7f, # ..Logical Maximum (127) 388
0 x45, 0 x00, # ..Physical Maximum (0) 390
0 x75, 0 x08, # ..Report Size (8) 392
0 x91, 0 x02, # ..Output (Data,Var,Abs) 394
0 x09, 0 x78, # ..Usage (Vendor Usage 0x78) 396
0 xa1, 0 x02, # ..Collection (Logical) 398
0 x09, 0 x7b, # ...Usage (Vendor Usage 0x7b) 400
0 x09, 0 x79, # ...Usage (Vendor Usage 0x79) 402
0 x09, 0 x7a, # ...Usage (Vendor Usage 0x7a) 404
0 x15, 0 x01, # ...Logical Minimum (1) 406
0 x25, 0 x03, # ...Logical Maximum (3) 408
0 x91, 0 x00, # ...Output (Data,Arr,Abs) 410
0 xc0, # ..End Collection 412
0 x09, 0 x7c, # ..Usage (Vendor Usage 0x7c) 413
0 x15, 0 x00, # ..Logical Minimum (0) 415
0 x26, 0 xfe, 0 x00, # ..Logical Maximum (254) 417
0 x91, 0 x02, # ..Output (Data,Var,Abs) 420
0 xc0, # .End Collection 422
0 x09, 0 x92, # .Usage (Vendor Usage 0x92) 423
0 xa1, 0 x02, # .Collection (Logical) 425
0 x85, 0 x52, # ..Report ID (82) 427
0 x09, 0 x96, # ..Usage (Vendor Usage 0x96) 429
0 xa1, 0 x02, # ..Collection (Logical) 431
0 x09, 0 x9a, # ...Usage (Vendor Usage 0x9a) 433
0 x09, 0 x99, # ...Usage (Vendor Usage 0x99) 435
0 x09, 0 x97, # ...Usage (Vendor Usage 0x97) 437
0 x09, 0 x98, # ...Usage (Vendor Usage 0x98) 439
0 x09, 0 x9b, # ...Usage (Vendor Usage 0x9b) 441
0 x09, 0 x9c, # ...Usage (Vendor Usage 0x9c) 443
0 x15, 0 x01, # ...Logical Minimum (1) 445
0 x25, 0 x06, # ...Logical Maximum (6) 447
0 x91, 0 x00, # ...Output (Data,Arr,Abs) 449
0 xc0, # ..End Collection 451
0 xc0, # .End Collection 452
0 x05, 0 xff, # .Usage Page (Vendor Usage Page 0xff) 453
0 x0a, 0 x01, 0 x03, # .Usage (Vendor Usage 0x301) 455
0 xa1, 0 x02, # .Collection (Logical) 458
0 x85, 0 x40, # ..Report ID (64) 460
0 x0a, 0 x02, 0 x03, # ..Usage (Vendor Usage 0x302) 462
0 xa1, 0 x02, # ..Collection (Logical) 465
0 x1a, 0 x11, 0 x03, # ...Usage Minimum (785) 467
0 x2a, 0 x20, 0 x03, # ...Usage Maximum (800) 470
0 x25, 0 x10, # ...Logical Maximum (16) 473
0 x91, 0 x00, # ...Output (Data,Arr,Abs) 475
0 xc0, # ..End Collection 477
0 x0a, 0 x03, 0 x03, # ..Usage (Vendor Usage 0x303) 478
0 x15, 0 x00, # ..Logical Minimum (0) 481
0 x27, 0 xff, 0 xff, 0 x00, 0 x00, # ..Logical Maximum (65535) 483
0 x75, 0 x10, # ..Report Size (16) 488
0 x91, 0 x02, # ..Output (Data,Var,Abs) 490
0 xc0, # .End Collection 492
0 x05, 0 x0f, # .Usage Page (Vendor Usage Page 0x0f) 493
0 x09, 0 x7d, # .Usage (Vendor Usage 0x7d) 495
0 xa1, 0 x02, # .Collection (Logical) 497
0 x85, 0 x43, # ..Report ID (67) 499
0 x09, 0 x7e, # ..Usage (Vendor Usage 0x7e) 501
0 x26, 0 x80, 0 x00, # ..Logical Maximum (128) 503
0 x46, 0 x10, 0 x27, # ..Physical Maximum (10000) 506
0 x75, 0 x08, # ..Report Size (8) 509
0 x91, 0 x02, # ..Output (Data,Var,Abs) 511
0 xc0, # .End Collection 513
0 x09, 0 x7f, # .Usage (Vendor Usage 0x7f) 514
0 xa1, 0 x02, # .Collection (Logical) 516
0 x85, 0 x0b, # ..Report ID (11) 518
0 x09, 0 x80, # ..Usage (Vendor Usage 0x80) 520
0 x26, 0 xff, 0 x7f, # ..Logical Maximum (32767) 522
0 x45, 0 x00, # ..Physical Maximum (0) 525
0 x75, 0 x0f, # ..Report Size (15) 527
0 xb1, 0 x03, # ..Feature (Cnst,Var,Abs) 529
0 x09, 0 xa9, # ..Usage (Vendor Usage 0xa9) 531
0 x25, 0 x01, # ..Logical Maximum (1) 533
0 x75, 0 x01, # ..Report Size (1) 535
0 xb1, 0 x03, # ..Feature (Cnst,Var,Abs) 537
0 x09, 0 x83, # ..Usage (Vendor Usage 0x83) 539
0 x26, 0 xff, 0 x00, # ..Logical Maximum (255) 541
0 x75, 0 x08, # ..Report Size (8) 544
0 xb1, 0 x03, # ..Feature (Cnst,Var,Abs) 546
0 xc0, # .End Collection 548
0 x09, 0 xab, # .Usage (Vendor Usage 0xab) 549
0 xa1, 0 x03, # .Collection (Report) 551
0 x85, 0 x15, # ..Report ID (21) 553
0 x09, 0 x25, # ..Usage (Vendor Usage 0x25) 555
0 xa1, 0 x02, # ..Collection (Logical) 557
0 x09, 0 x26, # ...Usage (Vendor Usage 0x26) 559
0 x09, 0 x30, # ...Usage (Vendor Usage 0x30) 561
0 x09, 0 x32, # ...Usage (Vendor Usage 0x32) 563
0 x09, 0 x31, # ...Usage (Vendor Usage 0x31) 565
0 x09, 0 x33, # ...Usage (Vendor Usage 0x33) 567
0 x09, 0 x34, # ...Usage (Vendor Usage 0x34) 569
0 x15, 0 x01, # ...Logical Minimum (1) 571
0 x25, 0 x06, # ...Logical Maximum (6) 573
0 xb1, 0 x00, # ...Feature (Data,Arr,Abs) 575
0 xc0, # ..End Collection 577
0 xc0, # .End Collection 578
0 x09, 0 x89, # .Usage (Vendor Usage 0x89) 579
0 xa1, 0 x03, # .Collection (Report) 581
0 x85, 0 x16, # ..Report ID (22) 583
0 x09, 0 x8b, # ..Usage (Vendor Usage 0x8b) 585
0 xa1, 0 x02, # ..Collection (Logical) 587
0 x09, 0 x8c, # ...Usage (Vendor Usage 0x8c) 589
0 x09, 0 x8d, # ...Usage (Vendor Usage 0x8d) 591
0 x09, 0 x8e, # ...Usage (Vendor Usage 0x8e) 593
0 x25, 0 x03, # ...Logical Maximum (3) 595
0 xb1, 0 x00, # ...Feature (Data,Arr,Abs) 597
0 xc0, # ..End Collection 599
0 x09, 0 x22, # ..Usage (Vendor Usage 0x22) 600
0 x15, 0 x00, # ..Logical Minimum (0) 602
0 x26, 0 xfe, 0 x00, # ..Logical Maximum (254) 604
0 xb1, 0 x02, # ..Feature (Data,Var,Abs) 607
0 xc0, # .End Collection 609
0 x09, 0 x90, # .Usage (Vendor Usage 0x90) 610
0 xa1, 0 x03, # .Collection (Report) 612
0 x85, 0 x50, # ..Report ID (80) 614
0 x09, 0 x22, # ..Usage (Vendor Usage 0x22) 616
0 x26, 0 xff, 0 x00, # ..Logical Maximum (255) 618
0 x91, 0 x02, # ..Output (Data,Var,Abs) 621
0 xc0, # .End Collection 623
0 xc0, # End Collection 624
]
# fmt: on
def __init__(self, rdesc=report_descriptor, name=None ):
super().__init__(rdesc, name=name, input_info=(BusType.USB, 0 x06A3, 0 xFF0D))
self.buttons = (1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 )
class AsusGamepad(BaseGamepad):
# fmt: off
report_descriptor = [
0 x05, 0 x01, # Usage Page (Generic Desktop) 0
0 x09, 0 x05, # Usage (Game Pad) 2
0 xa1, 0 x01, # Collection (Application) 4
0 x85, 0 x01, # .Report ID (1) 6
0 x05, 0 x09, # .Usage Page (Button) 8
0 x0a, 0 x01, 0 x00, # .Usage (Vendor Usage 0x01) 10
0 x0a, 0 x02, 0 x00, # .Usage (Vendor Usage 0x02) 13
0 x0a, 0 x04, 0 x00, # .Usage (Vendor Usage 0x04) 16
0 x0a, 0 x05, 0 x00, # .Usage (Vendor Usage 0x05) 19
0 x0a, 0 x07, 0 x00, # .Usage (Vendor Usage 0x07) 22
0 x0a, 0 x08, 0 x00, # .Usage (Vendor Usage 0x08) 25
0 x0a, 0 x0e, 0 x00, # .Usage (Vendor Usage 0x0e) 28
0 x0a, 0 x0f, 0 x00, # .Usage (Vendor Usage 0x0f) 31
0 x0a, 0 x0d, 0 x00, # .Usage (Vendor Usage 0x0d) 34
0 x05, 0 x0c, # .Usage Page (Consumer Devices) 37
0 x0a, 0 x24, 0 x02, # .Usage (AC Back) 39
0 x0a, 0 x23, 0 x02, # .Usage (AC Home) 42
0 x15, 0 x00, # .Logical Minimum (0) 45
0 x25, 0 x01, # .Logical Maximum (1) 47
0 x75, 0 x01, # .Report Size (1) 49
0 x95, 0 x0b, # .Report Count (11) 51
0 x81, 0 x02, # .Input (Data,Var,Abs) 53
0 x75, 0 x01, # .Report Size (1) 55
0 x95, 0 x01, # .Report Count (1) 57
0 x81, 0 x03, # .Input (Cnst,Var,Abs) 59
0 x05, 0 x01, # .Usage Page (Generic Desktop) 61
0 x75, 0 x04, # .Report Size (4) 63
0 x95, 0 x01, # .Report Count (1) 65
0 x25, 0 x07, # .Logical Maximum (7) 67
0 x46, 0 x3b, 0 x01, # .Physical Maximum (315) 69
0 x66, 0 x14, 0 x00, # .Unit (Degrees,EngRotation) 72
0 x09, 0 x39, # .Usage (Hat switch) 75
0 x81, 0 x42, # .Input (Data,Var,Abs,Null) 77
0 x66, 0 x00, 0 x00, # .Unit (None) 79
0 x09, 0 x01, # .Usage (Pointer) 82
0 xa1, 0 x00, # .Collection (Physical) 84
0 x09, 0 x30, # ..Usage (X) 86
0 x09, 0 x31, # ..Usage (Y) 88
0 x09, 0 x32, # ..Usage (Z) 90
0 x09, 0 x35, # ..Usage (Rz) 92
0 x05, 0 x02, # ..Usage Page (Simulation Controls) 94
0 x09, 0 xc5, # ..Usage (Brake) 96
0 x09, 0 xc4, # ..Usage (Accelerator) 98
0 x15, 0 x00, # ..Logical Minimum (0) 100
0 x26, 0 xff, 0 x00, # ..Logical Maximum (255) 102
0 x35, 0 x00, # ..Physical Minimum (0) 105
0 x46, 0 xff, 0 x00, # ..Physical Maximum (255) 107
0 x75, 0 x08, # ..Report Size (8) 110
0 x95, 0 x06, # ..Report Count (6) 112
0 x81, 0 x02, # ..Input (Data,Var,Abs) 114
0 xc0, # .End Collection 116
0 x85, 0 x02, # .Report ID (2) 117
0 x05, 0 x08, # .Usage Page (LEDs) 119
0 x0a, 0 x01, 0 x00, # .Usage (Num Lock) 121
0 x0a, 0 x02, 0 x00, # .Usage (Caps Lock) 124
0 x0a, 0 x03, 0 x00, # .Usage (Scroll Lock) 127
0 x0a, 0 x04, 0 x00, # .Usage (Compose) 130
0 x15, 0 x00, # .Logical Minimum (0) 133
0 x25, 0 x01, # .Logical Maximum (1) 135
0 x75, 0 x01, # .Report Size (1) 137
0 x95, 0 x04, # .Report Count (4) 139
0 x91, 0 x02, # .Output (Data,Var,Abs) 141
0 x75, 0 x04, # .Report Size (4) 143
0 x95, 0 x01, # .Report Count (1) 145
0 x91, 0 x03, # .Output (Cnst,Var,Abs) 147
0 xc0, # End Collection 149
0 x05, 0 x0c, # Usage Page (Consumer Devices) 150
0 x09, 0 x01, # Usage (Consumer Control) 152
0 xa1, 0 x01, # Collection (Application) 154
0 x85, 0 x03, # .Report ID (3) 156
0 x05, 0 x01, # .Usage Page (Generic Desktop) 158
0 x09, 0 x06, # .Usage (Keyboard) 160
0 xa1, 0 x02, # .Collection (Logical) 162
0 x05, 0 x06, # ..Usage Page (Generic Device Controls) 164
0 x09, 0 x20, # ..Usage (Battery Strength) 166
0 x15, 0 x00, # ..Logical Minimum (0) 168
0 x26, 0 xff, 0 x00, # ..Logical Maximum (255) 170
0 x75, 0 x08, # ..Report Size (8) 173
0 x95, 0 x01, # ..Report Count (1) 175
0 x81, 0 x02, # ..Input (Data,Var,Abs) 177
0 x06, 0 xbc, 0 xff, # ..Usage Page (Vendor Usage Page 0xffbc) 179
0 x0a, 0 xad, 0 xbd, # ..Usage (Vendor Usage 0xbdad) 182
0 x75, 0 x08, # ..Report Size (8) 185
0 x95, 0 x06, # ..Report Count (6) 187
0 x81, 0 x02, # ..Input (Data,Var,Abs) 189
0 xc0, # .End Collection 191
0 xc0, # End Collection 192
]
# fmt: on
def __init__(self, rdesc=report_descriptor, name=None ):
super().__init__(rdesc, name=name, input_info=(BusType.USB, 0 x18D1, 0 x2C40))
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, 0 x11C0, 0 x5606),
):
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 = [HidBpf("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, 0 x11C0, 0 x5606),
)
Messung V0.5 in Prozent C=91 H=92 G=91
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-06-07)
¤
*© Formatika GbR, Deutschland