Create a gist now

Instantly share code, notes, and snippets.

anonymous /readinput_c.c Secret
Created Mar 2, 2012

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <dirent.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/time.h>
#include <termios.h>
#include <signal.h>
#include <ruby.h>
#include <poll.h>
static VALUE t_init(VALUE self, VALUE device)
int k_fd;
int m_fd;
char * path = RSTRING_PTR(device);
if ((k_fd = open (path, O_RDONLY)) == -1)
rb_raise(rb_eIOError, "Cannot open device %s", path);
rb_iv_set(self, "@fd", INT2FIX(k_fd));
return self;
static VALUE t_read(VALUE self)
int fd = FIX2INT(rb_iv_get(self, "@fd"));
int retval;
struct pollfd rfds[1] =
{fd, POLLIN, 0}
retval = poll(rfds, 1, -1);
if (retval == -1)
rb_raise(rb_eIOError, "Poll error");
else if (!retval)
rb_raise(rb_eIOError, "No data");
if (!(rfds[0].revents & POLLIN))
rb_raise(rb_eIOError, "No descriptor ready");
struct input_event ev[64];
size_t size = sizeof(struct input_event);
size_t maxSize = sizeof(ev);
size_t readSize;
if ((readSize = read(fd, ev, maxSize)) < size)
rb_raise(rb_eIOError, "Cannot read on device");
size_t i;
for(i = 0; i < readSize / size; i++)
struct input_event *event = ev + i;
printf("%d:%d", event->type, event->code);
if (event->type == EV_KEY)
VALUE result = rb_funcall(self,
rb_time_new(event->time.tv_sec, event->time.tv_usec));
return result;
return Qnil;
VALUE mReadInput;
VALUE cReader;
void Init_readinput_c()
mReadInput = rb_define_module("ReadInput");
cReader = rb_define_class_under(mReadInput, "Reader", rb_cObject);
rb_define_method(cReader, "initialize", t_init, 1);
rb_define_method(cReader, "read", t_read, 0);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment