Created
January 26, 2012 11:29
-
-
Save acdimalev/1682350 to your computer and use it in GitHub Desktop.
WiP -- xpad support for Ecore
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// NEEDS WORK!!! | |
// I have no doubt that there are memory leaks in here | |
#include <Ecore.h> | |
#include <fcntl.h> | |
#include <linux/joystick.h> | |
#include <libudev.h> | |
#include "xpad.h" | |
#define MAX_XPADS 4 | |
#define XPAD_NUM_AXES 8 | |
#define XPAD_NUM_BUTTONS 11 | |
#define XPAD_AXIS_MAX ((1 << 15) - 1) | |
struct xpad_flat { | |
int is_alive, is_assigned; | |
float axes[8]; | |
int buttons[11]; | |
}; | |
struct xpad xpads[MAX_XPADS]; | |
int max_xpads = MAX_XPADS; | |
Eina_Bool xpad_fd_handler(void *data, Ecore_Fd_Handler *fdh) { | |
int fd = ecore_main_fd_handler_fd_get(fdh); | |
struct xpad_flat *xpad = data; | |
struct js_event e; | |
ssize_t retval; | |
retval = read(fd, &e, sizeof(struct js_event)); | |
if (retval == 0) { | |
// this shouldn't happen | |
} | |
if (retval == -1) { | |
// xpad disconnect | |
xpad->is_alive = 0; | |
ecore_main_fd_handler_del(fdh); | |
close(fd); | |
return ECORE_CALLBACK_CANCEL; | |
} | |
switch(e.type & ~JS_EVENT_INIT) { | |
case JS_EVENT_BUTTON: | |
printf("%d->buttons[%d]: %f\n", xpad, e.number, (float) e.value / XPAD_AXIS_MAX); | |
if (e.number < XPAD_NUM_BUTTONS) | |
{ xpad->buttons[e.number] = e.value; } | |
break; | |
case JS_EVENT_AXIS: | |
printf("%d->axes[%d]: %f\n", xpad, e.number, (float) e.value / XPAD_AXIS_MAX); | |
if (e.number < XPAD_NUM_AXES) | |
{ xpad->axes[e.number] = (float) e.value / XPAD_AXIS_MAX; } | |
} | |
return ECORE_CALLBACK_RENEW; | |
} | |
Eina_Bool xpad_dev_attach(void *data) { | |
struct udev_device *device = data; | |
const char *devnode = udev_device_get_devnode(device); | |
// BUG! -- what happens if the device is disconnected | |
// before it is successfully opened? | |
//printf("%s\n", devnode); | |
int fd = open(devnode, O_RDONLY); | |
if (fd == -1) | |
{ return ECORE_CALLBACK_RENEW; } | |
udev_device_unref(device); | |
int i; | |
struct xpad *xpad; | |
for (i = 0; i < max_xpads; i++) { | |
xpad = &xpads[i]; | |
if (! xpad->is_alive) { break; } | |
} | |
if (i == max_xpads) { | |
close(fd); | |
return ECORE_CALLBACK_CANCEL; | |
} | |
ecore_main_fd_handler_add( | |
fd, ECORE_FD_READ, xpad_fd_handler, xpad, NULL, NULL); | |
xpad->is_alive = -1; | |
xpad->is_assigned = 0; | |
return ECORE_CALLBACK_CANCEL; | |
} | |
void xpad_udev_attach(struct udev *udev, struct udev_device *device) { | |
struct udev_device *usb_device = udev_device_get_parent_with_subsystem_devtype(device, "usb", 0); | |
const char *sysname = udev_device_get_sysname(device); | |
const char *usb_driver = udev_device_get_driver(usb_device); | |
//printf("%s - %s\n", sysname, usb_driver); | |
if (usb_driver && ! strcmp("xpad", usb_driver)) | |
{ ecore_timer_add(1, xpad_dev_attach, device); } | |
} | |
Eina_Bool xpad_udev_fd_handler(void *data, Ecore_Fd_Handler *fdh) { | |
struct udev_monitor *monitor = data; | |
struct udev *udev = udev_monitor_get_udev(monitor); | |
struct udev_device *device = udev_monitor_receive_device(monitor); | |
const char *sysname = udev_device_get_sysname(device); | |
if ( ! strncmp("js", sysname, 2) ) | |
{ xpad_udev_attach(udev, device); } | |
return ECORE_CALLBACK_RENEW; | |
} | |
void xpad_init() { | |
struct udev *udev = udev_new(); | |
// monitor | |
struct udev_monitor *monitor = udev_monitor_new_from_netlink(udev, "udev"); | |
udev_monitor_filter_add_match_subsystem_devtype( | |
monitor, "input", 0); | |
udev_monitor_enable_receiving(monitor); | |
int fd = udev_monitor_get_fd(monitor); | |
ecore_main_fd_handler_add( | |
fd, ECORE_FD_READ, xpad_udev_fd_handler, monitor, NULL, NULL ); | |
// enumerate | |
struct udev_enumerate *enumerate = udev_enumerate_new(udev); | |
struct udev_list_entry *devices, *list_entry; | |
udev_enumerate_add_match_subsystem(enumerate, "input"); | |
udev_enumerate_scan_devices(enumerate); | |
devices = udev_enumerate_get_list_entry(enumerate); | |
udev_list_entry_foreach(list_entry, devices) { | |
const char *path = udev_list_entry_get_name(list_entry); | |
struct udev_device *device = udev_device_new_from_syspath(udev, path); | |
const char *sysname = udev_device_get_sysname(device); | |
if ( ! strncmp("js", sysname, 2) ) | |
{ xpad_udev_attach(udev, device); } | |
} | |
udev_enumerate_unref(enumerate); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct xpad { | |
int is_alive, is_assigned; | |
float lsx, lsy, lt, rsx, rsy, rt, dx, dy; | |
int a, b, x, y, lb, rb, back, start, guide, lsb, rsb; | |
}; | |
extern struct xpad xpads[]; | |
extern int max_xpads; | |
void xpad_init(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment