Libevdev playground #gsoc
#include <stdio.h> | |
#include <fcntl.h> | |
#include <errno.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <libevdev/libevdev.h> | |
#include <glib.h> | |
// A lot of the following code has been adapted from SDL | |
// Dependencies are glib and libevdev so compile with: | |
// gcc `pkg-config --cflags --libs libevdev glib-2.0` gamepad-libevdev-playground.c | |
void get_guid(struct libevdev *dev, guint16 * guid) { | |
guid[0] = GINT16_TO_LE(libevdev_get_id_bustype(dev)); | |
guid[1] = 0; | |
guid[2] = GINT16_TO_LE(libevdev_get_id_vendor(dev)); | |
guid[3] = 0; | |
guid[4] = GINT16_TO_LE(libevdev_get_id_product(dev)); | |
guid[5] = 0; | |
guid[6] = GINT16_TO_LE(libevdev_get_id_version(dev)); | |
guid[7] = 0; | |
} | |
void guid_to_string(guint16 * guid, char * guidstr) { | |
static const char k_rgchHexToASCII[] = "0123456789abcdef"; | |
int i; | |
for (i = 0; i < 8; i++) { | |
unsigned char c = guid[i]; | |
*guidstr++ = k_rgchHexToASCII[c >> 4]; | |
*guidstr++ = k_rgchHexToASCII[c & 0x0F]; | |
c = guid[i] >> 8; | |
*guidstr++ = k_rgchHexToASCII[c >> 4]; | |
*guidstr++ = k_rgchHexToASCII[c & 0x0F]; | |
} | |
*guidstr = '\0'; | |
} | |
int main () { | |
int i; | |
struct libevdev *dev = NULL; | |
int fd; | |
int rc = 1; | |
// Detect the first joystick event file | |
GDir* dir = g_dir_open("/dev/input/by-path/", 0, NULL); | |
const gchar * fname; | |
while ((fname = g_dir_read_name (dir))) { | |
if (g_str_has_suffix (fname, "event-joystick")) break; | |
} | |
printf("Opening event file /dev/input/by-path/%s\n", fname); | |
fd = open(g_strconcat("/dev/input/by-path/", fname, NULL), O_RDONLY|O_NONBLOCK); | |
rc = libevdev_new_from_fd(fd, &dev); | |
if (rc < 0) { | |
fprintf(stderr, "Failed to init libevdev (%s)\n", strerror(-rc)); | |
exit(1); | |
} | |
printf("Input device name: \"%s\"\n", libevdev_get_name(dev)); | |
printf("Input device ID: bus %#x vendor %#x product %#x\n", | |
libevdev_get_id_bustype(dev), | |
libevdev_get_id_vendor(dev), | |
libevdev_get_id_product(dev)); | |
// GUID stuff | |
guint16 guid[8]; | |
get_guid(dev, guid); | |
char guidstr[33]; | |
guid_to_string(guid, guidstr); | |
printf("Input device GUID %s\n", guidstr); | |
// printf("KEY_MAX : %d\tBTN_JOYSTICK : %d\tBTN_MISC : %d\n", KEY_MAX, BTN_JOYSTICK, BTN_MISC); | |
printf("\n\n"); | |
// Get info about buttons | |
int nbuttons = 0; | |
guint8 key_map[KEY_MAX]; | |
for (i = BTN_JOYSTICK; i < KEY_MAX; ++i) { | |
if (libevdev_has_event_code(dev, EV_KEY, i)) { | |
printf("%d - Joystick has button: 0x%x - %s\n", nbuttons, i, | |
libevdev_event_code_get_name(EV_KEY, i)); | |
key_map[i - BTN_MISC] = nbuttons; | |
++nbuttons; | |
} | |
} | |
for (i = BTN_MISC; i < BTN_JOYSTICK; ++i) { | |
if (libevdev_has_event_code(dev, EV_KEY, i)) { | |
printf("%d - Joystick has button: 0x%x - %s\n", nbuttons, i, | |
libevdev_event_code_get_name(EV_KEY, i)); | |
key_map[i - BTN_MISC] = nbuttons; | |
++nbuttons; | |
} | |
} | |
printf("\n\n"); | |
// Get info about axes | |
int naxes; | |
guint8 abs_map[ABS_MAX]; | |
for (i = 0; i < ABS_MAX; ++i) { | |
/* Skip hats */ | |
if (i == ABS_HAT0X) { | |
i = ABS_HAT3Y; | |
continue; | |
} | |
if (libevdev_has_event_code(dev, EV_ABS, i)) { | |
const struct input_absinfo *absinfo = libevdev_get_abs_info(dev, i); | |
printf("Joystick has absolute axis: 0x%.2x - %s\n", i, libevdev_event_code_get_name(EV_ABS, i)); | |
printf("Values = { %d, %d, %d, %d, %d }\n", | |
absinfo->value, absinfo->minimum, absinfo->maximum, | |
absinfo->fuzz, absinfo->flat); | |
abs_map[i] = naxes; | |
++naxes; | |
} | |
} | |
printf("\n\n"); | |
// Get info about hats | |
int nhats = 0; | |
for (i = ABS_HAT0X; i <= ABS_HAT3Y; i += 2) { | |
if (libevdev_has_event_code(dev, EV_ABS, i) || libevdev_has_event_code(dev, EV_ABS, i+1)) { | |
const struct input_absinfo *absinfo = libevdev_get_abs_info(dev, i); | |
if (absinfo == NULL) continue; | |
printf("Joystick has hat %d\n", (i - ABS_HAT0X) / 2); | |
printf("Values = { %d, %d, %d, %d, %d }\n", | |
absinfo->value, absinfo->minimum, absinfo->maximum, | |
absinfo->fuzz, absinfo->flat); | |
++nhats; | |
} | |
} | |
printf("\n\n"); | |
// Poll events | |
do { | |
struct input_event ev; | |
rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev); | |
if (rc == 0) { | |
switch (ev.type) { | |
case EV_KEY: | |
if (ev.code >= BTN_MISC) { | |
printf("Button %d\n", key_map[ev.code - BTN_MISC]); | |
} | |
break; | |
case EV_ABS: | |
switch (ev.code) { | |
case ABS_HAT0X: | |
case ABS_HAT0Y: | |
case ABS_HAT1X: | |
case ABS_HAT1Y: | |
case ABS_HAT2X: | |
case ABS_HAT2Y: | |
case ABS_HAT3X: | |
case ABS_HAT3Y: | |
ev.code -= ABS_HAT0X; | |
printf("Hat %d Axis %d Value %d\n", ev.code / 2, ev.code % 2, ev.value); | |
break; | |
default: | |
printf("Axis %d Value %d\n", abs_map[ev.code], ev.value); | |
break; | |
} | |
break; | |
case EV_REL: | |
switch (ev.code) { | |
case REL_X: | |
case REL_Y: | |
ev.code -= REL_X; | |
printf("Ball %d Axis %d Value %d\n", ev.code / 2, ev.code % 2, ev.value); | |
break; | |
default: | |
break; | |
} | |
break; | |
} | |
} | |
} while (rc == 1 || rc == 0 || rc == -EAGAIN); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
ln 117: compile error, naxes undefined, probably should set on line 103: "int naxes = 0;"