mirror of
https://gitlab.com/interception/linux/plugins/caps2esc.git
synced 2025-04-05 06:19:24 +00:00
Given that only EV_KEY events are being mapped, without their scancode counterparts, we just drop all scancode events to avoid having to map them too, to syncing it with the corresponding mapped keys. This is expected to be harmless.
85 lines
2.6 KiB
C
85 lines
2.6 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
#include <linux/input.h>
|
|
|
|
// clang-format off
|
|
const struct input_event
|
|
esc_up = {.type = EV_KEY, .code = KEY_ESC, .value = 0},
|
|
ctrl_up = {.type = EV_KEY, .code = KEY_LEFTCTRL, .value = 0},
|
|
capslock_up = {.type = EV_KEY, .code = KEY_CAPSLOCK, .value = 0},
|
|
esc_down = {.type = EV_KEY, .code = KEY_ESC, .value = 1},
|
|
ctrl_down = {.type = EV_KEY, .code = KEY_LEFTCTRL, .value = 1},
|
|
capslock_down = {.type = EV_KEY, .code = KEY_CAPSLOCK, .value = 1},
|
|
esc_repeat = {.type = EV_KEY, .code = KEY_ESC, .value = 2},
|
|
ctrl_repeat = {.type = EV_KEY, .code = KEY_LEFTCTRL, .value = 2},
|
|
capslock_repeat = {.type = EV_KEY, .code = KEY_CAPSLOCK, .value = 2},
|
|
syn = {.type = EV_SYN, .code = SYN_REPORT, .value = 0};
|
|
// clang-format on
|
|
|
|
int equal(const struct input_event *first, const struct input_event *second) {
|
|
return first->type == second->type && first->code == second->code &&
|
|
first->value == second->value;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
int main(void) {
|
|
int capslock_is_down = 0, esc_give_up = 0;
|
|
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) {
|
|
write_event(&input);
|
|
continue;
|
|
}
|
|
|
|
if (capslock_is_down) {
|
|
if (equal(&input, &capslock_down) ||
|
|
equal(&input, &capslock_repeat))
|
|
continue;
|
|
|
|
if (equal(&input, &capslock_up)) {
|
|
capslock_is_down = 0;
|
|
if (esc_give_up) {
|
|
esc_give_up = 0;
|
|
write_event(&ctrl_up);
|
|
continue;
|
|
}
|
|
write_event(&esc_down);
|
|
write_event(&syn);
|
|
usleep(20000);
|
|
write_event(&esc_up);
|
|
continue;
|
|
}
|
|
|
|
if (!esc_give_up && input.value) {
|
|
esc_give_up = 1;
|
|
write_event(&ctrl_down);
|
|
write_event(&syn);
|
|
usleep(20000);
|
|
}
|
|
} else if (equal(&input, &capslock_down)) {
|
|
capslock_is_down = 1;
|
|
continue;
|
|
}
|
|
|
|
if (input.code == KEY_ESC)
|
|
input.code = KEY_CAPSLOCK;
|
|
write_event(&input);
|
|
}
|
|
}
|