diff --git a/input_dev.c b/input_dev.c index 2bb6364..4a9fd66 100644 --- a/input_dev.c +++ b/input_dev.c @@ -2,6 +2,8 @@ #include "message.h" #include "queue.h" +#include +#include #include #include #include @@ -58,6 +60,8 @@ static char* open_sysfs[] = { }; #define MAX_MESSAGES_IN_FLIGHT 32 +#define DEFAULT_EVENTS_IN_REPORT 4 + struct input_ctx { struct libevdev* dev; @@ -76,6 +80,7 @@ void* input_read_thread_func(void* ptr) { for (int h = 0; h < MAX_MESSAGES_IN_FLIGHT; ++h) { if ((ctx->messages[h].flags & MESSAGE_FLAGS_HANDLE_DONE) != 0) { msg = &ctx->messages[h]; + msg->ev_count = 0; break; } } @@ -85,17 +90,30 @@ void* input_read_thread_func(void* ptr) { continue; } - rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_BLOCKING, &msg->ev); + // TODO: malloc for msg->ev and assign the result + + struct input_event read_ev; + rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_BLOCKING, &read_ev); if (rc == 0) { - // clear out flags - msg->flags = 0x00000000U; + if ((read_ev.type == EV_SYN) && (read_ev.code == SYN_REPORT)) { + // clear out flags + msg->flags = 0x00000000U; - if (queue_push(ctx->queue, (void*)msg) != 0) { - fprintf(stderr, "Error pushing event.\n"); + if (queue_push(ctx->queue, (void*)msg) != 0) { + fprintf(stderr, "Error pushing event.\n"); - // flag the memory to be safe to reuse - msg->flags |= MESSAGE_FLAGS_HANDLE_DONE; - continue; + // flag the memory to be safe to reuse + msg->flags |= MESSAGE_FLAGS_HANDLE_DONE; + continue; + } + } else { + if ((msg->ev_count+1) == msg->ev_size) { + // perform a memove + } else { + // just copy the input event + msg->ev[msg->ev_count] = read_ev; + ++msg->ev_count; + } } } } while (rc == 1 || rc == 0 || rc == -EAGAIN); @@ -113,6 +131,8 @@ void *input_dev_thread_func(void *ptr) { for (int h = 0; h < MAX_MESSAGES_IN_FLIGHT; ++h) { ctx.messages[h].flags = MESSAGE_FLAGS_HANDLE_DONE; + ctx.messages[h].ev_size = DEFAULT_EVENTS_IN_REPORT; + ctx.messages[h].ev = malloc(sizeof(struct input_event) * ctx.messages[h].ev_size); } int open_sysfs_idx = -1; diff --git a/main.c b/main.c index 3d07d43..c4bf9a2 100644 --- a/main.c +++ b/main.c @@ -84,7 +84,7 @@ int main(int argc, char ** argv) { queue_init(&gamepad_ev, 32); queue_init(&imu_ev, 32); - out_imu_dev.fd = create_output_dev("/dev/uinput", "Microsoft X-Box 360 pad - ROGueENEMY", output_dev_imu); + out_imu_dev.fd = create_output_dev("/dev/uinput", OUTPUT_DEV_NAME " - ROGueENEMY", output_dev_imu); if (out_imu_dev.fd < 0) { // TODO: free(imu_dev.events_list); // TODO: free(gamepadd_dev.events_list); @@ -92,7 +92,7 @@ int main(int argc, char ** argv) { return EXIT_FAILURE; } - out_gamepadd_dev.fd = create_output_dev("/dev/uinput", "Microsoft X-Box 360 pad - ROGueENEMY", output_dev_gamepad); + out_gamepadd_dev.fd = create_output_dev("/dev/uinput", OUTPUT_DEV_NAME " - ROGueENEMY", output_dev_gamepad); if (out_gamepadd_dev.fd < 0) { close(out_imu_dev.fd); // TODO: free(imu_dev.events_list); diff --git a/message.h b/message.h index 20b6992..93976f5 100644 --- a/message.h +++ b/message.h @@ -5,6 +5,11 @@ #define MESSAGE_FLAGS_HANDLE_DONE 0x00000001U typedef struct message { - struct input_event ev; + struct input_event* ev; + + uint32_t ev_count; + + size_t ev_size; + volatile uint32_t flags; } message_t; \ No newline at end of file diff --git a/output_dev.c b/output_dev.c index ad92000..e34b51b 100644 --- a/output_dev.c +++ b/output_dev.c @@ -337,6 +337,7 @@ create_output_dev_err: void *output_dev_thread_func(void *ptr) { output_dev_t *out_dev = (output_dev_t*)ptr; + struct timeval now = {0}; const int fd = out_dev->fd; @@ -346,30 +347,51 @@ void *output_dev_thread_func(void *ptr) { if (pop_res == 0) { message_t *const msg = (message_t *)raw_ev; - printf( - "Event: %s %s %d\n", - libevdev_event_type_get_name(msg->ev.type), - libevdev_event_code_get_name(msg->ev.type, msg->ev.code), - msg->ev.value - ); + for (uint32_t i = 0; i < msg->ev_count; ++i) { + printf( + "Event: %s %s %d\n", + libevdev_event_type_get_name(msg->ev[i].type), + libevdev_event_code_get_name(msg->ev[i].type, msg->ev[i].code), + msg->ev[i].value + ); - struct timeval now = {0}; + gettimeofday(&now, NULL); + + /*const*/ struct input_event ev = { + .code = msg->ev[i].code, + .type = msg->ev[i].type, + .value = msg->ev[i].value, + .time = now, + }; + + if ((ev.type == EV_KEY) && (ev.code == KEY_F16)) { + ev.code = BTN_MODE; + } + + const ssize_t written = write(fd, (void*)&ev, sizeof(ev)); + if (written != sizeof(ev)) { + fprintf( + stderr, + "Error writing event %s %s %d: written %ld bytes out of %ld\n", + libevdev_event_type_get_name(ev.type), + libevdev_event_code_get_name(ev.type, ev.code), + ev.value, + written, + sizeof(ev) + ); + } + } + gettimeofday(&now, NULL); - - /*const*/ struct input_event ev = { - .code = msg->ev.code, - .type = msg->ev.type, - .value = msg->ev.value, + const struct input_event syn_ev = { + .code = SYN_REPORT, + .type = EV_SYN, + .value = 0, .time = now, }; - - if ((ev.type == EV_KEY) && (ev.code == KEY_F16)) { - ev.code = BTN_MODE; - } - - ssize_t written = write(fd, (void*)&ev, sizeof(ev)); - if (written != sizeof(ev)) { - fprintf(stderr, "Error writing event: written %ld bytes out of %ld\n", written, sizeof(ev)); + const ssize_t sync_written = write(fd, (void*)&syn_ev, sizeof(syn_ev)); + if (sync_written != sizeof(syn_ev)) { + fprintf(stderr, "Error in sync: written %ld bytes out of %ld\n", sync_written, sizeof(syn_ev)); } // from now on it's forbidden to use this memory diff --git a/output_dev.h b/output_dev.h index 7d34f0f..502cc5b 100644 --- a/output_dev.h +++ b/output_dev.h @@ -2,8 +2,15 @@ #include "queue.h" -#define OUTPUT_DEV_VENDOR_ID 0x045e -#define OUTPUT_DEV_PRODUCT_ID 0x028e +/* +Emulates an Xbox controller: +#define OUTPUT_DEV_NAME "" +#define OUTPUT_DEV_VENDOR_ID 0x045e +#define OUTPUT_DEV_PRODUCT_ID 0x028e +*/ +#define OUTPUT_DEV_NAME "Sony Interactive Entertainment DualSense Wireless Controller" +#define OUTPUT_DEV_VENDOR_ID 0x054c +#define OUTPUT_DEV_PRODUCT_ID 0x0ce6 #define OUTPUT_DEV_CTRL_FLAG_EXIT 0x00000001U #define OUTPUT_DEV_CTRL_FLAG_DATA 0x00000002U