/* * gamepad.c: A plugin for the Video Disk Recorder * * See the README file for copyright information and how to reach the author. * * $Id$ */ #include "gamepad_handler.h" #include #include #include #include #include cGamepadHandler::cGamepadHandler() : m_fd(0) { } cGamepadHandler::~cGamepadHandler() { disconnect(); } bool cGamepadHandler::connect(const char* device) { this->m_fd = open(device, O_RDONLY); return this->m_fd; } void cGamepadHandler::disconnect() { if (m_fd) { close(this->m_fd); this->m_fd = 0; } } bool cGamepadHandler::ready() { return (this->m_fd > 0); } int cGamepadHandler::buttons() { char buttons; ioctl(this->m_fd, JSIOCGBUTTONS, &buttons); return (int)buttons; } int cGamepadHandler::axes() { char axes; ioctl(this->m_fd, JSIOCGAXES, &axes); return (int)axes; } char* cGamepadHandler::name() { char* name = new char[128]; ioctl(this->m_fd, JSIOCGNAME(128), name); return name; } cGamepadHandler::generic_event* cGamepadHandler::event() { js_event raw_event; int read_bytes; fd_set set; struct timeval timeout; FD_ZERO(&set); FD_SET(this->m_fd, &set); timeout.tv_sec = 1; timeout.tv_usec = 0; if (select(FD_SETSIZE, &set, NULL, NULL, &timeout) > 0) { read_bytes = read(this->m_fd, &raw_event, sizeof(raw_event)); if (read_bytes == sizeof(raw_event)) { if (raw_event.type == JS_EVENT_BUTTON) { if (raw_event.value < MAX_NUM_BUTTONS) { if (raw_event.value == 1) // button pressed { dsyslog("[gamepad] Pressed %d", raw_event.number); this->m_event.type = PRESS; } else // button released { dsyslog("[gamepad] Released %d", raw_event.number); this->m_event.type = RELEASE; } this->m_event.key = raw_event.number; return &(this->m_event); } } else if (raw_event.type == JS_EVENT_AXIS) { if (raw_event.number < MAX_NUM_AXIS) { int last_axis_state; last_axis_state = m_axis_state[raw_event.number]; m_axis_state[raw_event.number] = raw_event.value; if (last_axis_state < AXIS_DEAD_ZONE && last_axis_state > -AXIS_DEAD_ZONE) { this->m_event.key = MAX_NUM_BUTTONS + raw_event.number*2 + (raw_event.value >= 0); this->m_event.type = PRESS; if (raw_event.value >= AXIS_DEAD_ZONE) { dsyslog("[gamepad] Axis+ %d", raw_event.number); return &(this->m_event); } else if (raw_event.value <= -AXIS_DEAD_ZONE) { dsyslog("[gamepad] Axis- %d", raw_event.number); return &(this->m_event); } } else if (raw_event.value < AXIS_DEAD_ZONE && raw_event.value > -AXIS_DEAD_ZONE) { dsyslog("[gamepad] Axis stop %d", raw_event.number); this->m_event.key = MAX_NUM_BUTTONS + raw_event.number*2 + (last_axis_state >= 0); this->m_event.type = RELEASE; return &(this->m_event); } } } } } return NULL; }