From 6d80e988255bf8a76a51fa980c8e53e7a22dccce Mon Sep 17 00:00:00 2001 From: Oxore Date: Thu, 3 Mar 2022 02:09:51 +0300 Subject: Impl basic key mapping, add single key mappings --- main.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 68 insertions(+), 26 deletions(-) diff --git a/main.c b/main.c index faf15b0..dbdef16 100644 --- a/main.c +++ b/main.c @@ -8,6 +8,31 @@ #include #include +enum mapping_type { + MT_SINGLE = 0, + MT_DOUBLE = 1, + MT_SINGLE_SINGLE = 2, + MT_DOUBLE_SINGLE = 3, + MT_SINGLE_DOUBLE = 4, + MT_DOUBLE_DOUBLE = 5, +}; + +// TODO Perhaps scancodes are necessary too +struct mapping { + enum mapping_type type; + unsigned short first[2]; + unsigned short second[2]; + unsigned short key; +}; + +#define MAPPINGS_NUM 10 +struct mapping g_mapping[MAPPINGS_NUM] = { + { .type = MT_SINGLE, .first = { BTN_SOUTH }, .key = KEY_ENTER, }, + { .type = MT_SINGLE, .first = { BTN_EAST }, .key = KEY_SPACE, }, + { .type = MT_SINGLE, .first = { BTN_WEST }, .key = KEY_BACKSPACE, }, + { .type = MT_SINGLE, .first = { BTN_NORTH }, .key = KEY_ESC, }, +}; + bool should_stop = false; void sigint_handler(int _value) @@ -17,17 +42,40 @@ void sigint_handler(int _value) printf("SIGINT handled\n"); } +void setup_output_device(int fd) { + /* + * The ioctls below will enable the device that is about to be + * created, to pass key events, in this case the space key. + */ + ioctl(fd, UI_SET_EVBIT, EV_KEY); + // TODO do not forget to register all keys that are gonna be supported in + // the mapping configuration + ioctl(fd, UI_SET_KEYBIT, KEY_SPACE); + ioctl(fd, UI_SET_KEYBIT, KEY_ENTER); + ioctl(fd, UI_SET_KEYBIT, KEY_ESC); + ioctl(fd, UI_SET_KEYBIT, KEY_BACKSPACE); + struct uinput_setup usetup; + memset(&usetup, 0, sizeof(usetup)); + usetup.id.bustype = BUS_USB; + usetup.id.vendor = 0x1234; /* sample vendor */ + usetup.id.product = 0x5678; /* sample product */ + strcpy(usetup.name, "Example device"); + ioctl(fd, UI_DEV_SETUP, &usetup); + ioctl(fd, UI_DEV_CREATE); +} + void emit(int fd, int type, int code, int val) { - struct input_event ie; - - ie.type = type; - ie.code = code; - ie.value = val; - /* timestamp values below are ignored */ - ie.time.tv_sec = 0; - ie.time.tv_usec = 0; - + struct input_event ie = { + .type = type, + .code = code, + .value = val, + /* timestamp values below are ignored */ + .time = { + .tv_sec = 0, + .tv_usec = 0, + }, + }; write(fd, &ie, sizeof(ie)); } @@ -52,22 +100,7 @@ int main(int argc, char *argv[]) } signal(SIGINT, sigint_handler); - /* - * The ioctls below will enable the device that is about to be - * created, to pass key events, in this case the space key. - */ - ioctl(ofd, UI_SET_EVBIT, EV_KEY); - ioctl(ofd, UI_SET_KEYBIT, KEY_SPACE); - - struct uinput_setup usetup; - memset(&usetup, 0, sizeof(usetup)); - usetup.id.bustype = BUS_USB; - usetup.id.vendor = 0x1234; /* sample vendor */ - usetup.id.product = 0x5678; /* sample product */ - strcpy(usetup.name, "Example device"); - - ioctl(ofd, UI_DEV_SETUP, &usetup); - ioctl(ofd, UI_DEV_CREATE); + setup_output_device(ofd); /* * On UI_DEV_CREATE the kernel will create the device node for this @@ -84,6 +117,15 @@ int main(int argc, char *argv[]) switch (ev.type) { case EV_KEY: printf("EV_KEY, code=%u, value=%d\n", ev.code, ev.value); + for (ssize_t i = 0; i < MAPPINGS_NUM; i++) { + struct mapping mapping = g_mapping[i]; + if (mapping.type == MT_SINGLE && mapping.first[0] == ev.code && ev.value == 0) { + emit(ofd, EV_KEY, mapping.key, 1); + emit(ofd, EV_SYN, SYN_REPORT, 0); + emit(ofd, EV_KEY, mapping.key, 0); + emit(ofd, EV_SYN, SYN_REPORT, 0); + } + } break; case EV_ABS: /* @@ -113,7 +155,7 @@ int main(int argc, char *argv[]) * Give userspace some time to read the events before we destroy the * device with UI_DEV_DESTOY. */ - sleep(1); + //sleep(1); ioctl(ofd, UI_DEV_DESTROY); close(ofd); -- cgit v1.2.3