Should be able to open a device
This commit is contained in:
parent
ae0892eec6
commit
857c359e0b
5 changed files with 108 additions and 42 deletions
4
Makefile
4
Makefile
|
|
@ -1,5 +1,5 @@
|
||||||
CFLAGS=-g -O0 -std=c11 -fPIE -pedantic -Wall # -Werror
|
CFLAGS=-g -O0 -std=c11 -fPIE -pedantic -Wall # -Werror
|
||||||
LDFLAGS=-lpthread
|
LDFLAGS=-lpthread -levdev
|
||||||
CC=gcc
|
CC=gcc
|
||||||
OBJECTS=main.o input_dev.o output_dev.o queue.o
|
OBJECTS=main.o input_dev.o output_dev.o queue.o
|
||||||
TARGET=rogue_enemy
|
TARGET=rogue_enemy
|
||||||
|
|
@ -7,7 +7,7 @@ TARGET=rogue_enemy
|
||||||
all: $(TARGET)
|
all: $(TARGET)
|
||||||
|
|
||||||
$(TARGET): $(OBJECTS)
|
$(TARGET): $(OBJECTS)
|
||||||
$(CC) $(OBJECTS) -o $@
|
$(CC) $(LDFLAGS) $(OBJECTS) -o $@
|
||||||
|
|
||||||
include depends
|
include depends
|
||||||
|
|
||||||
|
|
|
||||||
88
input_dev.c
88
input_dev.c
|
|
@ -12,26 +12,63 @@
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
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) {
|
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 (;;) {
|
for (;;) {
|
||||||
const uint32_t flags = out_dev->crtl_flags;
|
const uint32_t flags = in_dev->crtl_flags;
|
||||||
if (flags & INPUT_DEV_CTRL_FLAG_EXIT) {
|
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;
|
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);
|
const int input_acquire_lock_result = pthread_mutex_lock(&input_acquire_mutex);
|
||||||
if (input_acquire_lock_result != 0) {
|
if (input_acquire_lock_result != 0) {
|
||||||
|
fprintf(stderr, "Cannot lock input mutex: %d, will retry later...\n", input_acquire_lock_result);
|
||||||
|
usleep(250000);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
char path[512] = "\0";
|
char path[512] = "\0";
|
||||||
const char *input_path = "/sys/class/input/";
|
|
||||||
|
|
||||||
DIR *d;
|
DIR *d;
|
||||||
struct dirent *dir;
|
struct dirent *dir;
|
||||||
d = opendir(input_path);
|
d = opendir(input_path);
|
||||||
|
|
@ -39,39 +76,34 @@ void *input_dev_thread_func(void *ptr) {
|
||||||
while ((dir = readdir(d)) != NULL) {
|
while ((dir = readdir(d)) != NULL) {
|
||||||
if (dir->d_name[0] == '.') {
|
if (dir->d_name[0] == '.') {
|
||||||
continue;
|
continue;
|
||||||
}
|
} else if (dir->d_name[0] == 'b') { // by-id
|
||||||
|
continue;
|
||||||
sprintf(path, "%s%s", input_path, dir->d_name);
|
} else if (dir->d_name[0] == 'j') { // js-0
|
||||||
|
|
||||||
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);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
fseek(n, 0L, SEEK_END);
|
sprintf(path, "%s%s", input_path, dir->d_name);
|
||||||
const size_t name_length = ftell(n);
|
|
||||||
fseek(n, 0L, SEEK_SET);
|
if (ev_matches(path, in_dev->ev_filters) != NULL) {
|
||||||
fread(name, 1, name_length, n);
|
printf("Opened device %s\n name: %s", path, libevdev_get_name(dev));
|
||||||
fclose(n);
|
break;
|
||||||
printf(" name: %s\n", name);
|
}
|
||||||
}
|
}
|
||||||
closedir(d);
|
closedir(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&input_acquire_mutex);
|
pthread_mutex_unlock(&input_acquire_mutex);
|
||||||
|
|
||||||
|
if (dev == NULL) {
|
||||||
|
usleep(250000);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// TODO: do the required
|
// 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) {
|
if (flags & INPUT_DEV_CTRL_FLAG_EXIT) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
11
input_dev.h
11
input_dev.h
|
|
@ -9,9 +9,20 @@ typedef enum input_dev_type {
|
||||||
input_dev_type_iio,
|
input_dev_type_iio,
|
||||||
} input_dev_type_t;
|
} 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 {
|
typedef struct input_dev {
|
||||||
input_dev_type_t dev_type;
|
input_dev_type_t dev_type;
|
||||||
|
|
||||||
|
const uinput_filters_t* ev_filters;
|
||||||
|
const iio_filters_t* iio_filters;
|
||||||
|
|
||||||
volatile uint32_t crtl_flags;
|
volatile uint32_t crtl_flags;
|
||||||
} input_dev_t;
|
} input_dev_t;
|
||||||
|
|
||||||
|
|
|
||||||
41
main.c
41
main.c
|
|
@ -6,36 +6,56 @@
|
||||||
ev_queue_t imu_ev;
|
ev_queue_t imu_ev;
|
||||||
ev_queue_t gamepad_ev;
|
ev_queue_t gamepad_ev;
|
||||||
|
|
||||||
output_dev_t out_imu_dev = {
|
static output_dev_t out_imu_dev = {
|
||||||
.fd = -1,
|
.fd = -1,
|
||||||
.crtl_flags = 0x00000000U,
|
.crtl_flags = 0x00000000U,
|
||||||
.queue = &imu_ev,
|
.queue = &imu_ev,
|
||||||
};
|
};
|
||||||
|
|
||||||
output_dev_t out_gamepadd_dev = {
|
static output_dev_t out_gamepadd_dev = {
|
||||||
.fd = -1,
|
.fd = -1,
|
||||||
.crtl_flags = 0x00000000U,
|
.crtl_flags = 0x00000000U,
|
||||||
.queue = &gamepad_ev,
|
.queue = &gamepad_ev,
|
||||||
};
|
};
|
||||||
|
|
||||||
input_dev_t in_asus_kb_1_dev = {
|
static uinput_filters_t in_asus_kb_1_filters = {
|
||||||
.dev_type = input_dev_type_uinput,
|
.name = "Asus Keyboard",
|
||||||
.crtl_flags = 0x00000000U,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
input_dev_t in_asus_kb_2_dev = {
|
static input_dev_t in_asus_kb_1_dev = {
|
||||||
.dev_type = input_dev_type_uinput,
|
.dev_type = input_dev_type_uinput,
|
||||||
.crtl_flags = 0x00000000U,
|
.crtl_flags = 0x00000000U,
|
||||||
|
.ev_filters = &in_asus_kb_1_filters,
|
||||||
};
|
};
|
||||||
|
|
||||||
input_dev_t in_asus_kb_3_dev = {
|
static uinput_filters_t in_asus_kb_2_filters = {
|
||||||
.dev_type = input_dev_type_uinput,
|
.name = "Asus Keyboard",
|
||||||
.crtl_flags = 0x00000000U,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
input_dev_t in_xbox_dev = {
|
static input_dev_t in_asus_kb_2_dev = {
|
||||||
.dev_type = input_dev_type_uinput,
|
.dev_type = input_dev_type_uinput,
|
||||||
.crtl_flags = 0x00000000U,
|
.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() {
|
void request_termination() {
|
||||||
|
|
@ -57,7 +77,6 @@ void sig_handler(int signo)
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char ** argv) {
|
int main(int argc, char ** argv) {
|
||||||
|
|
||||||
out_imu_dev.fd = create_output_dev("/dev/uinput", "Virtual IMU - ROGueENEMY", output_dev_imu);
|
out_imu_dev.fd = create_output_dev("/dev/uinput", "Virtual IMU - ROGueENEMY", output_dev_imu);
|
||||||
if (out_imu_dev.fd < 0) {
|
if (out_imu_dev.fd < 0) {
|
||||||
// TODO: free(imu_dev.events_list);
|
// TODO: free(imu_dev.events_list);
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,12 @@
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/ipc.h>
|
#include <sys/ipc.h>
|
||||||
#include <sys/sem.h>
|
#include <sys/sem.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
|
||||||
#include <linux/uinput.h>
|
#include <linux/uinput.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <libevdev-1.0/libevdev/libevdev.h>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue