Class: Joystick::Device

Inherits:
Object
  • Object
show all
Defined in:
ext/joystick.c

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.new(path) ⇒ Object

Construct a new Joystick::Device object. path is the file path to the joystick’s input device e.g. “/dev/input/js0”



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'ext/joystick.c', line 74

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;
}

Instance Method Details

#axesObject

Returns the number of axes of the device.



99
100
101
102
103
104
105
106
107
108
109
# File 'ext/joystick.c', line 99

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_mapsObject

TODO figure this out



175
176
177
178
179
180
181
182
183
184
185
# File 'ext/joystick.c', line 175

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);
}

#axisObject

Reader for @axis which stores the latest axis values.



135
136
137
138
# File 'ext/joystick.c', line 135

VALUE js_dev_axis(VALUE klass)
{
	return rb_ivar_get(klass, rb_intern("@axis"));
}

#buttonObject

Reader for @button which stores the latest button values.



146
147
148
149
# File 'ext/joystick.c', line 146

VALUE js_dev_button(VALUE klass)
{
	return rb_ivar_get(klass, rb_intern("@button"));
}

#buttonsObject

Returns the number of buttons on the device.



117
118
119
120
121
122
123
124
125
126
127
# File 'ext/joystick.c', line 117

VALUE js_dev_buttons(VALUE klass)
{
	int *fd;
	unsigned char buttons;
	Data_Get_Struct(klass, int, fd);
	if(ioctl(*fd, JSIOCGBUTTONS, &buttons) == -1) {
		rb_raise(rb_eException, "cannot retrieve buttons");
	}

	return INT2FIX(buttons);
}

#closeObject

Close the file handle for the device. This should be called for all Joystick::Devices before the script terminates.



279
280
281
282
283
284
285
286
# File 'ext/joystick.c', line 279

VALUE js_dev_close(VALUE klass)
{
	int *fd;
	
	Data_Get_Struct(klass, int, fd);
	close(*fd);
	return Qnil;
}

#event(+nonblocking+) ⇒ Object

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.



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'ext/joystick.c', line 233

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;
}

#nameObject

Returns the name of the device.



157
158
159
160
161
162
163
164
165
166
167
# File 'ext/joystick.c', line 157

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);
}

#versionObject

Returns a string containing the version of the device.



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'ext/joystick.c', line 193

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);
}