caps2esc:logo4alt

Interception tools plugin that maps caps->{esc,ctrl} and logo<->alt
git clone git://git.deurzen.net/caps2esc:logo4alt
Log | Files | Refs | README | LICENSE

commit c1d0826fe0cdd976875fcc049081ebfbc5ff60c1
parent 6ad00311380254ce6c879f08456238c52b5f44c8
Author: deurzen <max@deurzen.net>
Date:   Fri,  3 Jun 2022 09:18:15 +0200

maps logo<->alt and removes esc/grave bindings

Diffstat:
Dcaps2esc.c | 140-------------------------------------------------------------------------------
Acaps2esclogo4alt.c | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 101 insertions(+), 140 deletions(-)

diff --git a/caps2esc.c b/caps2esc.c @@ -1,140 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> - -#include <unistd.h> -#include <linux/input.h> - -// clang-format off -const struct input_event -syn = {.type = EV_SYN , .code = SYN_REPORT , .value = 0}, -esc_up = {.type = EV_KEY , .code = KEY_ESC , .value = 0}, -ctrl_up = {.type = EV_KEY , .code = KEY_LEFTCTRL , .value = 0}, -esc_down = {.type = EV_KEY , .code = KEY_ESC , .value = 1}, -ctrl_down = {.type = EV_KEY , .code = KEY_LEFTCTRL , .value = 1}; -// clang-format on - -void print_usage(FILE *stream, const char *program) { - // clang-format off - fprintf(stream, - "caps2esc - transforming the most useless key ever in the most useful one\n" - "\n" - "usage: %s [-h | [-m mode] [-t delay]]\n" - "\n" - "options:\n" - " -h show this message and exit\n" - " -t delay used for key sequences (default: 20000 microseconds)\n" - " -m mode 0: default\n" - " - caps as esc/ctrl\n" - " - esc as caps\n" - " 1: minimal\n" - " - caps as esc/ctrl\n" - " 2: useful on 60%% layouts\n" - " - caps as esc/ctrl\n" - " - esc as grave accent\n" - " - grave accent as caps\n", - program); - // clang-format on -} - -int read_event(struct input_event *event) { - return fread(event, sizeof(struct input_event), 1, stdin) == 1; -} - -void write_event(const struct input_event *event) { - if (fwrite(event, sizeof(struct input_event), 1, stdout) != 1) - exit(EXIT_FAILURE); -} - -void write_event_with_mode(struct input_event *event, int mode) { - if (event->type == EV_KEY) - switch (mode) { - case 0: - if (event->code == KEY_ESC) - event->code = KEY_CAPSLOCK; - break; - case 2: - switch (event->code) { - case KEY_ESC: - event->code = KEY_GRAVE; - break; - case KEY_GRAVE: - event->code = KEY_CAPSLOCK; - break; - } - break; - } - write_event(event); -} - -int main(int argc, char *argv[]) { - int mode = 0, delay = 20000; - - for (int opt; (opt = getopt(argc, argv, "ht:m:")) != -1;) { - switch (opt) { - case 'h': - return print_usage(stdout, argv[0]), EXIT_SUCCESS; - case 'm': - mode = atoi(optarg); - continue; - case 't': - delay = atoi(optarg); - continue; - } - - return print_usage(stderr, argv[0]), EXIT_FAILURE; - } - - struct input_event input; - enum { START, CAPSLOCK_HELD, CAPSLOCK_IS_CTRL } state = START; - - setbuf(stdin, NULL), setbuf(stdout, NULL); - - while (read_event(&input)) { - if (input.type == EV_MSC && input.code == MSC_SCAN) - continue; - - if (input.type != EV_KEY && input.type != EV_REL && - input.type != EV_ABS) { - write_event(&input); - continue; - } - - switch (state) { - case START: - if (input.type == EV_KEY && input.code == KEY_CAPSLOCK && - input.value) - state = CAPSLOCK_HELD; - else - write_event_with_mode(&input, mode); - break; - case CAPSLOCK_HELD: - if (input.type == EV_KEY && input.code == KEY_CAPSLOCK) { - if (input.value == 0) { - write_event(&esc_down); - write_event(&syn); - usleep(delay); - write_event(&esc_up); - state = START; - } - } else if ((input.type == EV_KEY && input.value == 1) || - input.type == EV_REL || input.type == EV_ABS) { - write_event(&ctrl_down); - write_event(&syn); - usleep(delay); - write_event_with_mode(&input, mode); - state = CAPSLOCK_IS_CTRL; - } else - write_event_with_mode(&input, mode); - break; - case CAPSLOCK_IS_CTRL: - if (input.type == EV_KEY && input.code == KEY_CAPSLOCK) { - input.code = KEY_LEFTCTRL; - write_event(&input); - if (input.value == 0) - state = START; - } else - write_event_with_mode(&input, mode); - break; - } - } -} diff --git a/caps2esclogo4alt.c b/caps2esclogo4alt.c @@ -0,0 +1,101 @@ +#include <stdio.h> +#include <stdlib.h> + +#include <unistd.h> +#include <linux/input.h> + +const struct input_event +syn = { .type = EV_SYN, .code = SYN_REPORT, .value = 0 }, +esc_up = { .type = EV_KEY, .code = KEY_ESC, .value = 0 }, +ctrl_up = { .type = EV_KEY, .code = KEY_LEFTCTRL, .value = 0 }, +esc_down = { .type = EV_KEY, .code = KEY_ESC, .value = 1 }, +ctrl_down = { .type = EV_KEY, .code = KEY_LEFTCTRL, .value = 1 }; + +static inline int +read_event(struct input_event *event) +{ + return fread(event, sizeof(struct input_event), 1, stdin) == 1; +} + +static inline void +write_event(const struct input_event *event) +{ + if (fwrite(event, sizeof(struct input_event), 1, stdout) != 1) + exit(EXIT_FAILURE); +} + +static inline void +intercept_event(struct input_event *event) +{ + if (event->type == EV_KEY) { + if (event->code == KEY_LEFTALT) + event->code = KEY_LEFTMETA; + else if (event->code == KEY_LEFTMETA) + event->code = KEY_LEFTALT; + } + + write_event(event); +} + +int +main(void) +{ + const int delay = 20000; + + enum { + START, + CAPSLOCK_HELD, + CAPSLOCK_IS_CTRL + } state = START; + struct input_event input; + + setbuf(stdin, NULL), setbuf(stdout, NULL); + + while (read_event(&input)) { + if (input.type == EV_MSC && input.code == MSC_SCAN) + continue; + + if (input.type != EV_KEY && input.type != EV_REL && input.type != EV_ABS) { + write_event(&input); + continue; + } + + switch (state) { + case START: + if (input.type == EV_KEY && input.code == KEY_CAPSLOCK && + input.value) + state = CAPSLOCK_HELD; + else + intercept_event(&input); + break; + case CAPSLOCK_HELD: + if (input.type == EV_KEY && input.code == KEY_CAPSLOCK) { + if (input.value == 0) { + write_event(&esc_down); + write_event(&syn); + usleep(delay); + write_event(&esc_up); + state = START; + } + } else if ((input.type == EV_KEY && input.value == 1) || + input.type == EV_REL || input.type == EV_ABS) { + write_event(&ctrl_down); + write_event(&syn); + usleep(delay); + intercept_event(&input); + state = CAPSLOCK_IS_CTRL; + } else + intercept_event(&input); + break; + case CAPSLOCK_IS_CTRL: + if (input.type == EV_KEY && input.code == KEY_CAPSLOCK) { + input.code = KEY_LEFTCTRL; + write_event(&input); + if (input.value == 0) + state = START; + } else + intercept_event(&input); + break; + } + } +}