2009-02-07
A few years ago, I converted a Nintendo NES gamepad to a USB gamepad, using a hardware chip from Raphnet, in order to control an MPD frontend that I wrote using Pygame. Fast forward to the present...... While working on my new media player application, I needed a way to receive joystick events but I didn't want to include the Pygame library just for joystick support. Thus was born the need for a python gobject joystick class.
Where is it? I looked all over the inter-tubes and couldn't find what I needed.

A bit of the old "clickity click click" on the keyboard ( a quite a bit on documentation reading ) and I came up with:
''' Copyright 2009 Jezra Lickter This software is distributed AS IS. Use at your own risk. If it borks your system, you have been forewarned. This software is licensed under the LGPL Version 3 http://www.gnu.org/licenses/lgpl-3.0.txt for documentation on Linux Joystick programming please see http://www.mjmwired.net/kernel/Documentation/input/joystick-api.txt ''' import gobject #needed for sending signals import struct #needed for holding chunks of data class Joystick(gobject.GObject): '''The Joystick class is a GObject that sends signals that represent Joystick events''' EVENT_BUTTON = 0x01 #button pressed/released EVENT_AXIS = 0x02 #axis moved EVENT_INIT = 0x80 #button/axis initialized #see http://docs.python.org/library/struct.html for the format determination EVENT_FORMAT = "IhBB" EVENT_SIZE = struct.calcsize(EVENT_FORMAT) # we need a few signals to send data to the main '''signals will return 4 variables as follows: 1. a string representing if the signal is from an axis or a button 2. an integer representation of a particular button/axis 3. an integer representing axis direction or button press/release 4. an integer representing the "init" of the button/axis ''' __gsignals__ = { 'axis' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT,gobject.TYPE_INT,gobject.TYPE_INT)), 'button' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT,gobject.TYPE_INT,gobject.TYPE_INT)) } def __init__(self,dev_num): gobject.GObject.__init__(self) #define the device device = '/dev/input/js%s' % dev_num #error check that this can be read try: #open the joystick device self.device = open(device) #keep an eye on the device, when there is data to read, execute the read function gobject.io_add_watch(self.device,gobject.IO_IN,self.read_buttons) except Exception,ex: #raise an exception raise Exception( ex ) def read_buttons(self, arg0='', arg1=''): ''' read the button and axis press event from the joystick device and emit a signal containing the event data ''' #read self.EVENT_SIZE bytes from the joystick read_event = self.device.read(self.EVENT_SIZE) #get the event structure values from the read event time, value, type, number = struct.unpack(self.EVENT_FORMAT, read_event) #get just the button/axis press event from the event type event = type & ~self.EVENT_INIT #get just the INIT event from the event type init = type & ~event if event == self.EVENT_AXIS: signal = "axis" elif event == self.EVENT_BUTTON: signal = "button" if signal: print("%s %s %s %s" % (signal,number,value,init) ) self.emit(signal,number,value,init) return True if __name__ == "__main__": try: j = Joystick(0) loop = gobject.MainLoop() loop.run() except Exception,e: print(e)

It still needs a bit of work, not all of the button/axis init signals are emitted when the class is started. The remaining init signals are sent on the first button press or axis movement. All in all, it fits my needs wonderfully.
Comments
2010-11-13 Anonymous:
Awesome and thank you. Not only useful for joysticks, but has opened my eyes to signals and the power of the gobject class.
2011-01-09 Anonymous:
Awesame, many thanks.
2011-02-11 John Crisp:
Like this but I am trying to do it on a time base so rather than waiting for the event, I'd like to be able to check the status at predefined intervals.

Any suggestions on how I might achieve this as I cannot for the life of me see how !
2011-02-11 jezra:
John, you would need to use something like gobject.timeout_add to run the "read_buttons" function at a set period of time

http://www.pygtk.org/pygtk2reference/gobject-functions.html#function-gobject--timeout-add
Name:
not required
Email:
not required (will not be displayed)
Website:
not required (will link your name to your site)
Comment:
required
Please do not post HTML code or bbcode unless you want it to show up as code in your post. (or if you are a blog spammer, in which case, you probably aren't reading this anyway).
Prove you are human by solving a math problem! I'm sorry, but due to an increase of blog spam, I've had to implement a CAPTCHA.
Problem:
5 minus 4
Answer:
required
  • Tags:
  • Python
subscribe
 
2019
2016
2015
2014
2013
2012
2011
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008