5 Commits

Author SHA1 Message Date
0c8326646a Expand mouse support
Until now mouse support existed just as side effect of muxing and that
mouse clicks are registered as key events. This expands the support for
mouse wheel and movement.
2020-12-29 02:43:04 -03:00
5c7e6b5a5d Formatting 2020-12-28 23:35:47 -03:00
7428d959e0 Formatting 2020-12-28 23:31:58 -03:00
e5dc581ddf Formatting 2020-12-28 23:24:11 -03:00
41a2fa7f1e Rewrite in state machine look
- Also add new option to control internal delay of programmatic key
  sequences, when they're necessary.
2020-12-28 23:13:34 -03:00
2 changed files with 88 additions and 80 deletions

View File

@ -37,10 +37,11 @@ $ cmake --build build
```
caps2esc - transforming the most useless key ever in the most useful one
usage: caps2esc [-h] [-m mode]
usage: caps2esc [-h] [-m mode] [-t delay]
options:
-h show this message and exit
-t delay used for key sequences (default: 20000 microseconds)
-m mode 0: default
- caps as esc/ctrl
- esc as caps
@ -117,7 +118,7 @@ As always, there's always a caveat:
I can't recall when I started using CAPSLOCK as both ESC and CTRL but it has
been quite some time already. It started when I was on OS X where it was quite
easy to achieve using the [Karabiner][], which already provides an option to
turn CTRL into CTRL/ESC (which can be coupled with OS X system settings that
turn CTRL into ESC/CTRL (which can be coupled with OS X system settings that
turn CAPSLOCK into CTRL).
Moving on, permanently making Linux my home, I searched and tweaked a similar

View File

@ -6,16 +6,11 @@
// 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},
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};
ctrl_down = {.type = EV_KEY , .code = KEY_LEFTCTRL , .value = 1};
// clang-format on
void print_usage(FILE *stream, const char *program) {
@ -23,10 +18,11 @@ void print_usage(FILE *stream, const char *program) {
fprintf(stream,
"caps2esc - transforming the most useless key ever in the most useful one\n"
"\n"
"usage: %s [-h] [-m mode]\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"
@ -40,11 +36,6 @@ void print_usage(FILE *stream, const char *program) {
// 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;
}
@ -54,22 +45,48 @@ void write_event(const struct input_event *event) {
exit(EXIT_FAILURE);
}
void write_event_with_mode(struct input_event *event, int mode) {
if (event->type == EV_REL || event->type == EV_ABS)
return;
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 opt, mode = 0;
while ((opt = getopt(argc, argv, "hm:")) != -1) {
int opt, mode = 0, delay = 20000;
while ((opt = getopt(argc, argv, "ht:m:")) != -1) {
switch (opt) {
case 'h':
return print_usage(stdout, argv[0]), EXIT_SUCCESS;
case 'm':
mode = optarg[0] - '0';
mode = atoi(optarg);
continue;
case 't':
delay = atoi(optarg);
continue;
}
return print_usage(stderr, argv[0]), EXIT_FAILURE;
}
int capslock_is_down = 0, esc_give_up = 0;
struct input_event input;
enum { START, CAPSLOCK_HELD, CAPSLOCK_IS_CTRL } state = START;
setbuf(stdin, NULL), setbuf(stdout, NULL);
@ -77,58 +94,48 @@ int main(int argc, char *argv[]) {
if (input.type == EV_MSC && input.code == MSC_SCAN)
continue;
if (input.type != EV_KEY) {
if (input.type != EV_KEY && input.type != EV_REL &&
input.type != EV_ABS) {
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;
}
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(20000);
usleep(delay);
write_event(&esc_up);
continue;
state = START;
}
if (!esc_give_up && input.value) {
esc_give_up = 1;
} 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(20000);
}
} else if (equal(&input, &capslock_down)) {
capslock_is_down = 1;
continue;
}
switch (mode) {
case 0:
if (input.code == KEY_ESC)
input.code = KEY_CAPSLOCK;
usleep(delay);
write_event_with_mode(&input, mode);
state = CAPSLOCK_IS_CTRL;
} else
write_event_with_mode(&input, mode);
break;
case 2:
switch (input.code) {
case KEY_ESC:
input.code = KEY_GRAVE;
break;
case KEY_GRAVE:
input.code = KEY_CAPSLOCK;
break;
}
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;
}
}
}