chrippa / ds4drv

A Sony DualShock 4 userspace driver for Linux
MIT License
1.05k stars 213 forks source link

Make ds4drv compatible with python-evdev 0.6.0 #72

Closed Ryochan7 closed 8 years ago

Ryochan7 commented 8 years ago

As mentioned in issue #70, ds4drv does not currently work with python-evdev 0.6.0. The following changes allow ds4drv to work with python-evdev 0.6.0. I added a small check to try to keep the code compatible with python-evdev < 0.6.0 but there might be a better way to check for the presence of an older version of that package.

Ape commented 8 years ago

I still get the same error with this commit:

Traceback (most recent call last):
  File "/usr/lib/python3.5/runpy.py", line 170, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.5/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/ape/programming/ds4drv/ds4drv/__main__.py", line 184, in <module>
    main()
  File "/home/ape/programming/ds4drv/ds4drv/__main__.py", line 151, in main
    thread = create_controller_thread(index + 1, controller_options)
  File "/home/ape/programming/ds4drv/ds4drv/__main__.py", line 120, in create_controller_thread
    controller = DS4Controller(index, controller_options, dynamic=dynamic)
  File "/home/ape/programming/ds4drv/ds4drv/__main__.py", line 35, in __init__
    self.load_options(self.options)
  File "/home/ape/programming/ds4drv/ds4drv/__main__.py", line 93, in load_options
    self.fire_event("load-options", options)
  File "/home/ape/programming/ds4drv/ds4drv/__main__.py", line 38, in fire_event
    self.loop.fire_event(event, *args)
  File "/home/ape/programming/ds4drv/ds4drv/eventloop.py", line 86, in fire_event
    self.process_events()
  File "/home/ape/programming/ds4drv/ds4drv/eventloop.py", line 92, in process_events
    callback(*args)
  File "/home/ape/programming/ds4drv/ds4drv/actions/input.py", line 79, in load_options
    joystick = create_uinput_device(joystick_layout)
  File "/home/ape/programming/ds4drv/ds4drv/uinput.py", line 435, in create_uinput_device
    device = UInputDevice(mapping)
  File "/home/ape/programming/ds4drv/ds4drv/uinput.py", line 240, in __init__
    self.create_device(layout)
  File "/home/ape/programming/ds4drv/ds4drv/uinput.py", line 300, in create_device
    product=layout.product, version=layout.version)
  File "/usr/lib/python3.5/site-packages/evdev/uinput.py", line 107, in __init__
    _uinput.create(self.fd, name, vendor, product, version, bustype, absinfo)
SystemError: Objects/longobject.c:403: bad argument to internal function
Ryochan7 commented 8 years ago

Can you run ds4drv with Winpdb and see what the value for the events dict is before reaching line 298 (creation of the UInput object)? The problem that I encountered was mainly due to https://github.com/gvalkov/python-evdev/blob/master/evdev/uinput.c#L102 since index 5 did not exist. Another thing that you can try is to modify line 298 using the assignment events=None in the UInput constructor and see if that helps.

Ape commented 8 years ago

This was the value of events just before the crash on line 298:

{1: [304, 305, 307, 308, 310, 311, 314, 315, 316, 317, 318],
 2: [],
 3: [(0, (0, 255, 0, 5)),
     (1, (0, 255, 0, 5)),
     (2, (0, 255, 0, 5)),
     (3, (0, 255, 0, 5)),
     (4, (0, 255, 0, 5)),
     (5, (0, 255, 0, 5)),
     (16, (0, -1, 1, 0, 0)),
     (17, (0, -1, 1, 0, 0))]}
Ape commented 8 years ago

And with event=None it didn't crash.

Ryochan7 commented 8 years ago

I'm sorry. I forgot to carry over a change from my test version. Try the new commit.

Ape commented 8 years ago

Thanks. The new commit seems to fix the crash.

Ape commented 8 years ago

I verified that this commit works with both python-evdev 0.5.0 and python-evdev 0.6.0. Let's see if we can get this commit merged.

Ape commented 8 years ago

Can you squash the commits and add "Resolves #70." to the end of the commit message?

benmoran56 commented 8 years ago

Not to derail this thread, but just a thought:

Since ds4drv only supports a single type of device, It might be better to remove the python-evdev dependency. The evdev interfacing can be done in Python with ctypes, removing the need to have gcc installed to build the python-evdev dependency. This may open up ds4drv to working on more embedded or SOC devices as a bonus. The pyglet library does things this way, and works great.

Don't get me wrong, python-evdev is a fantastic library. But, it might be a bit overkill for ds4drv. Not that writing the code for ds4drv would be easy, but it could be mostly learned from studying pyglet, as the license allows that.

Ape commented 8 years ago

I squashed and merged this. Thanks!