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 hidtools.device.base_gamepad import AsusGamepad, SaitekGamepad 14 15import logging 16 17logger = logging.getLogger("hidtools.test.gamepad") 18 19 20class BaseTest: 21 class TestGamepad(base.BaseTestCase.TestUhid): 22 @pytest.fixture(autouse=True) 23 def send_initial_state(self): 24 """send an empty report to initialize the axes""" 25 uhdev = self.uhdev 26 27 r = uhdev.event() 28 events = uhdev.next_sync_events() 29 self.debug_reports(r, uhdev, events) 30 31 def assert_button(self, button): 32 uhdev = self.uhdev 33 evdev = uhdev.get_evdev() 34 syn_event = self.syn_event 35 36 buttons = {} 37 key = libevdev.evbit(uhdev.buttons_map[button]) 38 39 buttons[button] = True 40 r = uhdev.event(buttons=buttons) 41 expected_event = libevdev.InputEvent(key, 1) 42 events = uhdev.next_sync_events() 43 self.debug_reports(r, uhdev, events) 44 self.assertInputEventsIn((syn_event, expected_event), events) 45 assert evdev.value[key] == 1 46 47 buttons[button] = False 48 r = uhdev.event(buttons=buttons) 49 expected_event = libevdev.InputEvent(key, 0) 50 events = uhdev.next_sync_events() 51 self.debug_reports(r, uhdev, events) 52 self.assertInputEventsIn((syn_event, expected_event), events) 53 assert evdev.value[key] == 0 54 55 def test_buttons(self): 56 """check for button reliability.""" 57 uhdev = self.uhdev 58 59 for b in uhdev.buttons: 60 self.assert_button(b) 61 62 def test_dual_buttons(self): 63 """check for button reliability when pressing 2 buttons""" 64 uhdev = self.uhdev 65 evdev = uhdev.get_evdev() 66 syn_event = self.syn_event 67 68 # can change intended b1 b2 values 69 b1 = uhdev.buttons[0] 70 key1 = libevdev.evbit(uhdev.buttons_map[b1]) 71 b2 = uhdev.buttons[1] 72 key2 = libevdev.evbit(uhdev.buttons_map[b2]) 73 74 buttons = {b1: True, b2: True} 75 r = uhdev.event(buttons=buttons) 76 expected_event0 = libevdev.InputEvent(key1, 1) 77 expected_event1 = libevdev.InputEvent(key2, 1) 78 events = uhdev.next_sync_events() 79 self.debug_reports(r, uhdev, events) 80 self.assertInputEventsIn( 81 (syn_event, expected_event0, expected_event1), events 82 ) 83 assert evdev.value[key1] == 1 84 assert evdev.value[key2] == 1 85 86 buttons = {b1: False, b2: None} 87 r = uhdev.event(buttons=buttons) 88 expected_event = libevdev.InputEvent(key1, 0) 89 events = uhdev.next_sync_events() 90 self.debug_reports(r, uhdev, events) 91 self.assertInputEventsIn((syn_event, expected_event), events) 92 assert evdev.value[key1] == 0 93 assert evdev.value[key2] == 1 94 95 buttons = {b1: None, b2: False} 96 r = uhdev.event(buttons=buttons) 97 expected_event = libevdev.InputEvent(key2, 0) 98 events = uhdev.next_sync_events() 99 self.debug_reports(r, uhdev, events) 100 self.assertInputEventsIn((syn_event, expected_event), events) 101 assert evdev.value[key1] == 0 102 assert evdev.value[key2] == 0 103 104 def _get_libevdev_abs_events(self, which): 105 """Returns which ABS_* evdev axes are expected for the given stick""" 106 abs_map = self.uhdev.axes_map[which] 107 108 x = abs_map["x"].evdev 109 y = abs_map["y"].evdev 110 111 assert x 112 assert y 113 114 return x, y 115 116 def _test_joystick_press(self, which, data): 117 uhdev = self.uhdev 118 119 libevdev_axes = self._get_libevdev_abs_events(which) 120 121 r = None 122 if which == "left_stick": 123 r = uhdev.event(left=data) 124 else: 125 r = uhdev.event(right=data) 126 events = uhdev.next_sync_events() 127 self.debug_reports(r, uhdev, events) 128 129 for i, d in enumerate(data): 130 if d is not None and d != 127: 131 assert libevdev.InputEvent(libevdev_axes[i], d) in events 132 else: 133 assert libevdev.InputEvent(libevdev_axes[i]) not in events 134 135 def test_left_joystick_press_left(self): 136 """check for the left joystick reliability""" 137 self._test_joystick_press("left_stick", (63, None)) 138 self._test_joystick_press("left_stick", (0, 127)) 139 140 def test_left_joystick_press_right(self): 141 """check for the left joystick reliability""" 142 self._test_joystick_press("left_stick", (191, 127)) 143 self._test_joystick_press("left_stick", (255, None)) 144 145 def test_left_joystick_press_up(self): 146 """check for the left joystick reliability""" 147 self._test_joystick_press("left_stick", (None, 63)) 148 self._test_joystick_press("left_stick", (127, 0)) 149 150 def test_left_joystick_press_down(self): 151 """check for the left joystick reliability""" 152 self._test_joystick_press("left_stick", (127, 191)) 153 self._test_joystick_press("left_stick", (None, 255)) 154 155 def test_right_joystick_press_left(self): 156 """check for the right joystick reliability""" 157 self._test_joystick_press("right_stick", (63, None)) 158 self._test_joystick_press("right_stick", (0, 127)) 159 160 def test_right_joystick_press_right(self): 161 """check for the right joystick reliability""" 162 self._test_joystick_press("right_stick", (191, 127)) 163 self._test_joystick_press("right_stick", (255, None)) 164 165 def test_right_joystick_press_up(self): 166 """check for the right joystick reliability""" 167 self._test_joystick_press("right_stick", (None, 63)) 168 self._test_joystick_press("right_stick", (127, 0)) 169 170 def test_right_joystick_press_down(self): 171 """check for the right joystick reliability""" 172 self._test_joystick_press("right_stick", (127, 191)) 173 self._test_joystick_press("right_stick", (None, 255)) 174 175 @pytest.mark.skip_if_uhdev( 176 lambda uhdev: "Hat switch" not in uhdev.fields, 177 "Device not compatible, missing Hat switch usage", 178 ) 179 @pytest.mark.parametrize( 180 "hat_value,expected_evdev,evdev_value", 181 [ 182 (0, "ABS_HAT0Y", -1), 183 (2, "ABS_HAT0X", 1), 184 (4, "ABS_HAT0Y", 1), 185 (6, "ABS_HAT0X", -1), 186 ], 187 ) 188 def test_hat_switch(self, hat_value, expected_evdev, evdev_value): 189 uhdev = self.uhdev 190 191 r = uhdev.event(hat_switch=hat_value) 192 events = uhdev.next_sync_events() 193 self.debug_reports(r, uhdev, events) 194 assert ( 195 libevdev.InputEvent( 196 libevdev.evbit("EV_ABS", expected_evdev), evdev_value 197 ) 198 in events 199 ) 200 201 202class TestSaitekGamepad(BaseTest.TestGamepad): 203 def create_device(self): 204 return SaitekGamepad() 205 206 207class TestAsusGamepad(BaseTest.TestGamepad): 208 def create_device(self): 209 return AsusGamepad() 210