class Joystick::Device
Public Class Methods
new(path)
click to toggle source
Construct a new Joystick::Device
object. path
is the file path to the joystick's input device e.g. “/dev/input/js0”
VALUE js_dev_init(VALUE klass, VALUE dev_path) { int *fd; VALUE dev; if((fd = malloc(sizeof(int))) != NULL) { if((*fd = open(RSTRING_PTR(dev_path), O_RDONLY)) >= 0) { if(*fd >= MAX_JS) rb_raise(rb_eException, "Error"); dev = Data_Wrap_Struct(klass, jsdevice_mark, jsdevice_free, fd); rb_ivar_set(dev, rb_intern("@axis"), rb_ary_new()); rb_ivar_set(dev, rb_intern("@button"), rb_ary_new()); return dev; } } return Qnil; }
Public Instance Methods
axes()
click to toggle source
Returns the number of axes of the device.
VALUE js_dev_axes(VALUE klass) { int *fd; unsigned char axes; Data_Get_Struct(klass, int, fd); if(ioctl(*fd, JSIOCGAXES, &axes) == -1) { rb_raise(rb_eException, "cannot retrieve axes"); } return INT2FIX(axes); }
axes_maps()
click to toggle source
TODO figure this out
VALUE js_dev_axes_maps(VALUE klass) { int *fd; uint8_t axes_maps[ABS_MAX + 1]; Data_Get_Struct(klass, int, fd); if(ioctl(*fd, JSIOCGAXMAP, &axes_maps) == -1) { rb_raise(rb_eException, "cannot retrive axes"); } return INT2FIX(axes_maps); }
axis()
click to toggle source
Reader for @axis which stores the latest axis values.
VALUE js_dev_axis(VALUE klass) { return rb_ivar_get(klass, rb_intern("@axis")); }
close()
click to toggle source
Close the file handle for the device. This should be called for all Joystick::Devices before the script terminates.
VALUE js_dev_close(VALUE klass) { int *fd; Data_Get_Struct(klass, int, fd); close(*fd); return Qnil; }
event(+nonblocking+)
click to toggle source
Get a Joystick::Event
object from the device.
The optional nonblocking
argument determines whether or not this is a blocking call. It is blocking by default.
VALUE js_dev_event_get(int argc, VALUE *argv, VALUE klass) { struct event_arg arg; int *fd; ssize_t length; VALUE nonblocking; rb_scan_args(argc, argv, "01", &nonblocking); Data_Get_Struct(klass, int, fd); if(RTEST(nonblocking)) { /* TODO I'm not sure how big of a performance hit this is */ fcntl(*fd, F_SETFL, O_NONBLOCK); /* non-blocking mode */ length = read(*fd, &jse[*fd], sizeof(struct js_event)); fcntl(*fd, F_SETFL, fcntl(*fd, F_GETFL) & ~O_NONBLOCK); /* revert to blocking mode */ } else { arg.fd = fd; rb_thread_blocking_region(js_event_func, (void *)&arg, RUBY_UBF_IO, 0); length = arg.l; } if(length > 0) { switch(jse[*fd].type & ~JS_EVENT_INIT) /* TODO I think it's safe to assume we have a valid event now */ { case JS_EVENT_AXIS: rb_ary_store(rb_ivar_get(klass, rb_intern("@axis")), jse[*fd].number, INT2FIX(jse[*fd].value)); break; case JS_EVENT_BUTTON: rb_ary_store(rb_ivar_get(klass, rb_intern("@button")), jse[*fd].number, INT2FIX(jse[*fd].value)); } return Data_Wrap_Struct(rb_cEvent, 0, 0, fd); } return Qnil; }
name()
click to toggle source
Returns the name of the device.
VALUE js_dev_name(VALUE klass) { int *fd; char name[NAME_LENGTH] = "Unknown"; Data_Get_Struct(klass, int, fd); if(ioctl(*fd, JSIOCGNAME(NAME_LENGTH), name) == -1) { rb_raise(rb_eException, "cannot retrieve name"); } return rb_str_new2(name); }
version()
click to toggle source
Returns a string containing the version of the device.
VALUE js_dev_version(VALUE klass) { int *fd; int version = 0x000800; char js_version[16]; Data_Get_Struct(klass, int, fd); if(ioctl(*fd, JSIOCGVERSION, &version) == -1) { rb_raise(rb_eException, "version error"); } sprintf(js_version, "%d.%d.%d\n", version >> 16, (version >> 8) & 0xff, version & 0xff); return rb_str_new2(js_version); }