I am currently working on the PR that ports vgamepad
to Linux. vgamepad
emulates virtual gamepads in python.
On Linux, the PR uses libevdev
which in turns creates a uinput
device.
In order to check consistency of the library across platforms, I am trying to use pygame
for checking the state of vgamepad
‘s virtual gamepads.
The code for these unit tests is available here.
They all pass on Windows, and fail on Linux.
(You can test on your system: clone the repo, checkout the yb/linux
branch, follow the prerequisite instructions for Linux, install locally with pip install -e .
and run the python script in the test
directory)
On Linux, pygame
correctly detects the uinput
device with its expected characteristics, and thus the following tests are successful:
# Check that only one gamepad is connected:
self.assertTrue(len(self.joysticks) == 1)
j = self.joysticks[0]
# Check that gamepad properties are correct:
name = j.get_name()
nb_axes = j.get_numaxes()
nb_balls = j.get_numballs()
nb_buttons = j.get_numbuttons()
nb_hats = j.get_numhats()
self.assertTrue(name == "Xbox 360 Controller")
self.assertEqual(nb_axes, 6)
self.assertEqual(nb_balls, 0)
self.assertEqual(nb_buttons, 11)
self.assertEqual(nb_hats, 1)
However, further events are not correctly detected, and thus this test fails:
_ = pygame.event.get()
self.g.press_button(button=v_button)
self.g.update()
time.sleep(WAIT_S)
event = pygame.event.get()
print(event)
self.assertTrue(j.get_button(j_button))
At this point, the A
button is supposed to be detected as pressed, and in fact the gamepad tester website does correctly show button A
as pressed.
Yet, pygame
does not see the event and the print
that I have added here prints []
.
Finally, I have manually tried a modded version of the same code using a real gamepad, and this time the test passed correctly.
Does anyone know why this might happen, please?
Thank you for your help!
EDIT: I have also tried creating a display with pygame.display.set_mode((500, 500))
and focusing the created window before sending the uinput
events, but got the same behavior: no uinput
events were detected by pygame
, only the mouse events corresponding to me focusing the window.
The pygame.event module an pygame.event.get()
requires an initialized display on the same device in the same thread:
Pygame handles all its event messaging through an event queue. The routines in this module help you manage that event queue. The input queue is heavily dependent on the
pygame.display
module. If the display has not been initialized and a video mode not set, the event queue may not work properly.
pygame.event.pump()
/ pygame.event.get()
Caution: This function should only be called in the thread that initialized
pygame.display