Skip to content

Instantly share code, notes, and snippets.

@teknoman117
Last active August 29, 2015 14:15
Show Gist options
  • Save teknoman117/909ef7f7db3209b4dce1 to your computer and use it in GitHub Desktop.
Save teknoman117/909ef7f7db3209b4dce1 to your computer and use it in GitHub Desktop.
A small test program for reading events from a joystick/gamepad on Linux using Apple's libdispatch to handle io operations asynchronously.
#include <iostream>
#include <cstring>
#include <cerrno>
#include <unistd.h>
#include <linux/joystick.h>
#include <linux/input.h>
#include <sys/ioctl.h>
#include <dispatch/dispatch.h>
using namespace std;
int main (int argc, char** argv)
{
// Open the joystick
int fd = open("/dev/input/js0", O_RDONLY);
if(fd < 0)
{
cerr << "Unable to open joystick" << endl;
return 1;
}
// Get joystick info
int axis_count = 0, button_count = 0;
char name[128];
ioctl(fd, JSIOCGAXES, &axis_count); /* Get the number of axes in the joystick */
ioctl(fd, JSIOCGBUTTONS, &button_count); /* Get the number of buttons in the joystick */
ioctl(fd, JSIOCGNAME(80), (char *) name); /* Get the name of the joystick */
// Print joystick information
cout << "----- " << name << " ------" << endl;
cout << " Axis Count: " << axis_count << endl;
cout << " Button Count: " << button_count << endl;
cout << "---------------------------" << endl;
// Locate the high priority queue
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0);
// Create a libdispatch io channel for the joystick
dispatch_io_t joystickChannel = dispatch_io_create(DISPATCH_IO_STREAM, fd, queue, ^(int error)
{
if(error)
{
cerr << "Got an error from Joystick: " << error << " (" << strerror(error) << ")" << endl;
}
});
// Don't bug user unless we've received at least a js_Event object
dispatch_io_set_low_water(joystickChannel, sizeof(struct js_event));
dispatch_io_set_high_water(joystickChannel, sizeof(struct js_event));
// Establish a read handler
dispatch_io_read(joystickChannel, 0, SIZE_MAX, queue, ^(bool done, dispatch_data_t data, int error)
{
// Did we successfully get data?
if(data)
{
// Apply an operation to the received data
dispatch_data_apply(data, ^(dispatch_data_t, size_t, const void *location, size_t size)
{
const struct js_event *event = static_cast<const struct js_event *>(location);
switch (event->type & ~JS_EVENT_INIT)
{
case JS_EVENT_AXIS:
cout << "Axis " << (int) event->number << ": " << (int) event->value << endl;
break;
case JS_EVENT_BUTTON:
cout << "Button " << (int) event->number << ": " << (int) event->value << endl;
break;
}
// Success
return true;
});
}
});
dispatch_main();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment