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

caps2esclogo4alt.c (2889B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 
      4 #include <unistd.h>
      5 #include <linux/input.h>
      6 
      7 const struct input_event
      8 syn       = { .type = EV_SYN, .code = SYN_REPORT,   .value = 0 },
      9 esc_up    = { .type = EV_KEY, .code = KEY_ESC,      .value = 0 },
     10 ctrl_up   = { .type = EV_KEY, .code = KEY_LEFTCTRL, .value = 0 },
     11 esc_down  = { .type = EV_KEY, .code = KEY_ESC,      .value = 1 },
     12 ctrl_down = { .type = EV_KEY, .code = KEY_LEFTCTRL, .value = 1 };
     13 
     14 static inline int
     15 read_event(struct input_event *event)
     16 {
     17     return fread(event, sizeof(struct input_event), 1, stdin) == 1;
     18 }
     19 
     20 static inline void
     21 write_event(const struct input_event *event)
     22 {
     23     if (fwrite(event, sizeof(struct input_event), 1, stdout) != 1)
     24         exit(EXIT_FAILURE);
     25 }
     26 
     27 static inline void
     28 intercept_event(struct input_event *event)
     29 {
     30     if (event->type == EV_KEY) {
     31         if (event->code == KEY_LEFTALT)
     32             event->code = KEY_LEFTMETA;
     33         else if (event->code == KEY_LEFTMETA)
     34             event->code = KEY_LEFTALT;
     35     }
     36 
     37     write_event(event);
     38 }
     39 
     40 int
     41 main(void)
     42 {
     43     const int delay = 20000;
     44 
     45     enum {
     46         START,
     47         CAPSLOCK_HELD,
     48         CAPSLOCK_IS_CTRL
     49     } state = START;
     50     struct input_event input;
     51 
     52     setbuf(stdin, NULL), setbuf(stdout, NULL);
     53 
     54     while (read_event(&input)) {
     55         if (input.type == EV_MSC && input.code == MSC_SCAN)
     56             continue;
     57 
     58         if (input.type != EV_KEY && input.type != EV_REL && input.type != EV_ABS) {
     59             write_event(&input);
     60             continue;
     61         }
     62 
     63         switch (state) {
     64         case START:
     65             if (input.type == EV_KEY && input.code == KEY_CAPSLOCK &&
     66                 input.value)
     67                 state = CAPSLOCK_HELD;
     68             else
     69                 intercept_event(&input);
     70             break;
     71         case CAPSLOCK_HELD:
     72             if (input.type == EV_KEY && input.code == KEY_CAPSLOCK) {
     73                 if (input.value == 0) {
     74                     write_event(&esc_down);
     75                     write_event(&syn);
     76                     usleep(delay);
     77                     write_event(&esc_up);
     78                     state = START;
     79                 }
     80             } else if ((input.type == EV_KEY && input.value == 1) ||
     81                        input.type == EV_REL || input.type == EV_ABS) {
     82                 write_event(&ctrl_down);
     83                 write_event(&syn);
     84                 usleep(delay);
     85                 intercept_event(&input);
     86                 state = CAPSLOCK_IS_CTRL;
     87             } else
     88                 intercept_event(&input);
     89             break;
     90         case CAPSLOCK_IS_CTRL:
     91             if (input.type == EV_KEY && input.code == KEY_CAPSLOCK) {
     92                 input.code = KEY_LEFTCTRL;
     93                 write_event(&input);
     94                 if (input.value == 0)
     95                     state = START;
     96             } else
     97                 intercept_event(&input);
     98             break;
     99         }
    100     }
    101 }