diff --git a/Makefile b/Makefile index 8c9130d..a8a9483 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CFLAGS=-g -O0 -std=c11 -fPIE -pedantic -Wall # -Werror -LDFLAGS=-lpthread +LDFLAGS=-lpthread -levdev CC=gcc OBJECTS=main.o input_dev.o output_dev.o queue.o TARGET=rogue_enemy @@ -7,7 +7,7 @@ TARGET=rogue_enemy all: $(TARGET) $(TARGET): $(OBJECTS) - $(CC) $(OBJECTS) -o $@ + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ include depends diff --git a/input_dev.c b/input_dev.c index 7ecbba4..f1878de 100644 --- a/input_dev.c +++ b/input_dev.c @@ -12,26 +12,63 @@ #include #include -pthread_mutex_t input_acquire_mutex = PTHREAD_MUTEX_INITIALIZER; +static const char *input_path = "/dev/input/"; + +static struct libevdev* ev_matches(const char* sysfs_entry, const uinput_filters_t* const filters) { + struct libevdev *dev = NULL; + + int fd = open(sysfs_entry, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "Cannot open %s, device skipped.\n", sysfs_entry); + return NULL; + } + + if (libevdev_new_from_fd(fd, &dev) != 0) { + fprintf(stderr, "Cannot initialize libevdev from this device (%s): skipping.\n", sysfs_entry); + return NULL; + } + + if (strcmp(libevdev_get_name(dev), filters->name) != 0) { + return NULL; + } + + if (libevdev_grab(dev, LIBEVDEV_GRAB) != 0) { + fprintf(stderr, "Unable to grab the device: skipping.\n"); + return NULL; + } + + return 0; +} + +static pthread_mutex_t input_acquire_mutex = PTHREAD_MUTEX_INITIALIZER; void *input_dev_thread_func(void *ptr) { - input_dev_t *out_dev = (input_dev_t*)ptr; + input_dev_t *in_dev = (input_dev_t*)ptr; + + struct libevdev* dev = NULL; for (;;) { - const uint32_t flags = out_dev->crtl_flags; + const uint32_t flags = in_dev->crtl_flags; if (flags & INPUT_DEV_CTRL_FLAG_EXIT) { - out_dev->crtl_flags &= ~INPUT_DEV_CTRL_FLAG_EXIT; + in_dev->crtl_flags &= ~INPUT_DEV_CTRL_FLAG_EXIT; break; } - + + // clean up from previous iteration + if (dev != NULL) { + libevdev_free(dev); + dev = NULL; + } + const int input_acquire_lock_result = pthread_mutex_lock(&input_acquire_mutex); if (input_acquire_lock_result != 0) { + fprintf(stderr, "Cannot lock input mutex: %d, will retry later...\n", input_acquire_lock_result); + usleep(250000); continue; } char path[512] = "\0"; - const char *input_path = "/sys/class/input/"; - + DIR *d; struct dirent *dir; d = opendir(input_path); @@ -39,39 +76,34 @@ void *input_dev_thread_func(void *ptr) { while ((dir = readdir(d)) != NULL) { if (dir->d_name[0] == '.') { continue; - } - - sprintf(path, "%s%s", input_path, dir->d_name); - - printf("device: %s\n", path); - - char name[510] = "\0"; - - char name_path[512] = "\0"; - sprintf(name_path, "%s/device/name", path); - - FILE* n = fopen(name_path, "r"); - if (n == NULL) { - fprintf(stderr, " name: [ERROR]: %s\n", name_path); + } else if (dir->d_name[0] == 'b') { // by-id + continue; + } else if (dir->d_name[0] == 'j') { // js-0 continue; } - fseek(n, 0L, SEEK_END); - const size_t name_length = ftell(n); - fseek(n, 0L, SEEK_SET); - fread(name, 1, name_length, n); - fclose(n); - printf(" name: %s\n", name); + sprintf(path, "%s%s", input_path, dir->d_name); + + if (ev_matches(path, in_dev->ev_filters) != NULL) { + printf("Opened device %s\n name: %s", path, libevdev_get_name(dev)); + break; + } } closedir(d); } pthread_mutex_unlock(&input_acquire_mutex); + if (dev == NULL) { + usleep(250000); + continue; + } + for (;;) { // TODO: do the required + //process_events(dev); - const uint32_t flags = out_dev->crtl_flags; + const uint32_t flags = in_dev->crtl_flags; if (flags & INPUT_DEV_CTRL_FLAG_EXIT) { break; } diff --git a/input_dev.h b/input_dev.h index 4a67dce..0305edc 100644 --- a/input_dev.h +++ b/input_dev.h @@ -9,9 +9,20 @@ typedef enum input_dev_type { input_dev_type_iio, } input_dev_type_t; +typedef struct uinput_filters { + const char* name; +} uinput_filters_t; + +typedef struct iio_filters { + const char* name; +} iio_filters_t; + typedef struct input_dev { input_dev_type_t dev_type; + const uinput_filters_t* ev_filters; + const iio_filters_t* iio_filters; + volatile uint32_t crtl_flags; } input_dev_t; diff --git a/main.c b/main.c index 54e69aa..c8f65e8 100644 --- a/main.c +++ b/main.c @@ -6,36 +6,56 @@ ev_queue_t imu_ev; ev_queue_t gamepad_ev; -output_dev_t out_imu_dev = { +static output_dev_t out_imu_dev = { .fd = -1, .crtl_flags = 0x00000000U, .queue = &imu_ev, }; -output_dev_t out_gamepadd_dev = { +static output_dev_t out_gamepadd_dev = { .fd = -1, .crtl_flags = 0x00000000U, .queue = &gamepad_ev, }; -input_dev_t in_asus_kb_1_dev = { - .dev_type = input_dev_type_uinput, - .crtl_flags = 0x00000000U, +static uinput_filters_t in_asus_kb_1_filters = { + .name = "Asus Keyboard", }; -input_dev_t in_asus_kb_2_dev = { +static input_dev_t in_asus_kb_1_dev = { .dev_type = input_dev_type_uinput, .crtl_flags = 0x00000000U, + .ev_filters = &in_asus_kb_1_filters, }; -input_dev_t in_asus_kb_3_dev = { - .dev_type = input_dev_type_uinput, - .crtl_flags = 0x00000000U, +static uinput_filters_t in_asus_kb_2_filters = { + .name = "Asus Keyboard", }; -input_dev_t in_xbox_dev = { +static input_dev_t in_asus_kb_2_dev = { .dev_type = input_dev_type_uinput, .crtl_flags = 0x00000000U, + .ev_filters = &in_asus_kb_2_filters, +}; + +static uinput_filters_t in_asus_kb_3_filters = { + .name = "Asus Keyboard", +}; + +static input_dev_t in_asus_kb_3_dev = { + .dev_type = input_dev_type_uinput, + .crtl_flags = 0x00000000U, + .ev_filters = &in_asus_kb_3_filters, +}; + +static uinput_filters_t in_xbox_filters = { + .name = "Microsoft X-Box 360 pad 0", +}; + +static input_dev_t in_xbox_dev = { + .dev_type = input_dev_type_uinput, + .crtl_flags = 0x00000000U, + .ev_filters = &in_xbox_filters, }; void request_termination() { @@ -57,7 +77,6 @@ void sig_handler(int signo) } int main(int argc, char ** argv) { - out_imu_dev.fd = create_output_dev("/dev/uinput", "Virtual IMU - ROGueENEMY", output_dev_imu); if (out_imu_dev.fd < 0) { // TODO: free(imu_dev.events_list); diff --git a/rogue_enemy.h b/rogue_enemy.h index dfaad8f..a02639f 100644 --- a/rogue_enemy.h +++ b/rogue_enemy.h @@ -12,8 +12,12 @@ #include #include #include +#include + #include #include -#include \ No newline at end of file +#include + +#include \ No newline at end of file