1 /* Copyright © 2019 Raheman Vaiya.
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a
4 * copy of this software and associated documentation files (the "Software"),
5 * to deal in the Software without restriction, including without limitation
6 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 * and/or sell copies of the Software, and to permit persons to whom the
8 * Software is furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice (including the next
11 * paragraph) shall be included in all copies or substantial portions of the
12 * Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <assert.h>
26 #include <stdint.h>
27 #include <unistd.h>
28 #include <stdlib.h>
29 #include <assert.h>
30 #include <sys/types.h>
31 #include <dirent.h>
32 #include <ctype.h>
33 #include <limits.h>
34 #include "config.h"
35 #include "keys.h"
36
37 #define MAX_ARGS 10
38
39 struct keyboard_config *configs = NULL;
40
41 struct layer_table_ent {
42 char name[256];
43 char pname[256];
44
45 uint8_t modsonly;
46 struct layer *layer;
47 } layer_table[MAX_LAYERS];
48
49 int nlayers = 0;
50
51 static int lnum = 0;
52 static char path[PATH_MAX];
53
54 static uint32_t macros[MAX_MACROS][MAX_MACRO_SIZE];
55 static size_t nmacros = 0;
56
57 static int lookup_layer(const char *name);
58 static int parse_modset(const char *s, uint16_t *mods);
59
60 #define err(fmt, ...) fprintf(stderr, "%s: ERROR on line %d: "fmt"\n", path, lnum, ##__VA_ARGS__)
61
modseq_to_string(uint16_t mods)62 static const char *modseq_to_string(uint16_t mods)
63 {
64 static char s[32];
65 int i = 0;
66 s[0] = '\0';
67
68 if(mods & MOD_CTRL) {
69 strcpy(s+i, "-C");
70 i+=2;
71 }
72 if(mods & MOD_SHIFT) {
73 strcpy(s+i, "-S");
74 i+=2;
75 }
76
77 if(mods & MOD_SUPER) {
78 strcpy(s+i, "-M");
79 i+=2;
80 }
81
82 if(mods & MOD_ALT) {
83 strcpy(s+i, "-A");
84 i+=2;
85 }
86
87 if(mods & MOD_ALT_GR) {
88 strcpy(s+i, "-G");
89 i+=2;
90 }
91
92 if(i)
93 return s+1;
94 else
95 return s;
96 }
97
keyseq_to_string(uint32_t keyseq)98 const char *keyseq_to_string(uint32_t keyseq)
99 {
100 int i = 0;
101 static char s[256];
102
103 uint16_t mods = keyseq >> 16;
104 uint16_t code = keyseq & 0x00FF;
105
106 const char *key = keycode_table[code].name;
107
108 if(mods & MOD_CTRL) {
109 strcpy(s+i, "C-");
110 i+=2;
111 }
112 if(mods & MOD_SHIFT) {
113 strcpy(s+i, "S-");
114 i+=2;
115 }
116
117 if(mods & MOD_SUPER) {
118 strcpy(s+i, "M-");
119 i+=2;
120 }
121
122 if(mods & MOD_ALT) {
123 strcpy(s+i, "A-");
124 i+=2;
125 }
126
127 if(mods & MOD_ALT_GR) {
128 strcpy(s+i, "G-");
129 i+=2;
130 }
131
132 if(key)
133 strcpy(s+i, keycode_table[code].name);
134 else
135 strcpy(s+i, "UNKNOWN");
136
137 return s;
138 }
139
140 //Returns the position in the layer table
create_layer(const char * name,const char * pname,uint16_t mods)141 static struct layer_table_ent *create_layer(const char *name, const char *pname, uint16_t mods)
142 {
143 struct layer_table_ent *ent = &layer_table[nlayers];
144
145 ent->layer = calloc(1, sizeof(struct layer));
146 ent->layer->keymap = calloc(KEY_CNT, sizeof(struct key_descriptor));
147
148 ent->modsonly = 0;
149 ent->layer->mods = mods;
150
151 strcpy(ent->pname, pname);
152 strcpy(ent->name, name);
153
154 nlayers++;
155 assert(nlayers <= MAX_LAYERS);
156 return ent;
157 }
158
create_mod_layer(uint16_t mods)159 static struct layer_table_ent *create_mod_layer(uint16_t mods)
160 {
161 struct layer_table_ent *ent = create_layer("", "", mods);
162 ent->modsonly = 1;
163
164 return ent;
165 }
166
keyseq_to_desc(uint32_t seq,struct key_descriptor * desc)167 static void keyseq_to_desc(uint32_t seq, struct key_descriptor *desc)
168 {
169 desc->action = ACTION_KEYSEQ;
170 desc->arg.keyseq = seq;
171
172 //To facilitate simplification of modifier handling convert
173 //all traditional modifier keys to their internal layer
174 //representations.
175
176 switch(seq) {
177 case KEY_LEFTCTRL:
178 desc->action = ACTION_LAYER;
179 desc->arg.layer = lookup_layer("C");
180 break;
181 case KEY_LEFTALT:
182 desc->action = ACTION_LAYER;
183 desc->arg.layer = lookup_layer("A");
184 break;
185 case KEY_RIGHTALT:
186 desc->action = ACTION_LAYER;
187 desc->arg.layer = lookup_layer("G");
188 break;
189 case KEY_LEFTSHIFT:
190 desc->action = ACTION_LAYER;
191 desc->arg.layer = lookup_layer("S");
192 break;
193 case KEY_LEFTMETA:
194 desc->action = ACTION_LAYER;
195 desc->arg.layer = lookup_layer("M");
196 break;
197 }
198 }
199
create_main_layer()200 static struct layer_table_ent *create_main_layer()
201 {
202 int i;
203 struct layer_table_ent *ent = create_layer("main", "", 0);
204
205 for(i = 0;i < KEY_CNT;i++)
206 keyseq_to_desc(i, &ent->layer->keymap[i]);
207
208 return ent;
209 }
210
211 //Returns the index in the layer table or -1.
lookup_layer(const char * name)212 static int lookup_layer(const char *name)
213 {
214 int i;
215 uint16_t mods;
216
217 for(i = 0;i < nlayers;i++) {
218 if(!strcmp(layer_table[i].name, name))
219 return i;
220 }
221
222 if(!parse_modset(name, &mods)) {
223 //Check if a dedicated mod layer already exists.
224 for(i = 0;i < nlayers;i++) {
225 struct layer_table_ent *ent = &layer_table[i];
226 if(ent->modsonly && ent->layer->mods == mods)
227 return i;
228 }
229
230 //Autovivify mod layers which don't exist.
231
232 create_mod_layer(mods);
233 return nlayers-1;
234 }
235
236 return -1;
237 }
238
239
parse_modset(const char * s,uint16_t * mods)240 static int parse_modset(const char *s, uint16_t *mods)
241 {
242 *mods = 0;
243
244 while(*s) {
245 switch(*s) {
246 case 'C':
247 *mods |= MOD_CTRL;
248 break;
249 case 'M':
250 *mods |= MOD_SUPER;
251 break;
252 case 'A':
253 *mods |= MOD_ALT;
254 break;
255 case 'S':
256 *mods |= MOD_SHIFT;
257 break;
258 case 'G':
259 *mods |= MOD_ALT_GR;
260 break;
261 default:
262 return -1;
263 break;
264 }
265
266 if(s[1] == 0)
267 return 0;
268 else if(s[1] != '-')
269 return -1;
270
271 s+=2;
272 }
273
274 return 0;
275 }
276
parse_layer_heading(const char * s,char name[256],char parent[256])277 static int parse_layer_heading(const char *s, char name[256], char parent[256])
278 {
279 size_t len = strlen(s);
280 char *c;
281
282 name[0] = 0;
283 parent[0] = 0;
284
285 if(s[0] != '[' || s[len-1] != ']')
286 return -1;
287
288 c = strchr(s, ':');
289 if(c) {
290 int sz = c-(s+1);
291 memcpy(name, s+1, sz);
292 name[sz] = 0;
293
294 sz = len-2-sz-1;
295 memcpy(parent, c+1, sz);
296 parent[sz] = 0;
297 } else {
298 int sz = len-2;
299 memcpy(name, s+1, sz);
300 name[sz] = 0;
301 }
302
303 return 0;
304 }
305
parse_keyseq(const char * s)306 static uint32_t parse_keyseq(const char *s)
307 {
308 const char *c = s;
309 size_t i;
310 uint32_t mods = 0;
311
312 while(*c && c[1] == '-') {
313 switch(*c) {
314 case 'C':
315 mods |= MOD_CTRL;
316 break;
317 case 'M':
318 mods |= MOD_SUPER;
319 break;
320 case 'A':
321 mods |= MOD_ALT;
322 break;
323 case 'S':
324 mods |= MOD_SHIFT;
325 break;
326 case 'G':
327 mods |= MOD_ALT_GR;
328 break;
329 default:
330 return 0;
331 break;
332 }
333
334 c += 2;
335 }
336
337 for(i = 0;i < KEY_MAX;i++) {
338 const struct keycode_table_ent *ent = &keycode_table[i];
339
340 if(ent->name && !strcmp(ent->name, c))
341 return (mods << 16) | i;
342 if(ent->alt_name && !strcmp(ent->alt_name, c))
343 return (mods << 16) | i;
344 if(ent->shifted_name && !strcmp(ent->shifted_name, c))
345 return (mods | MOD_SHIFT) << 16 | i;
346 }
347
348 return 0;
349 }
350
parse_macro_fn(const char * s,size_t * szp)351 uint32_t *parse_macro_fn(const char *s, size_t *szp)
352 {
353 char *_s = strdup(s);
354 size_t len = strlen(s);
355 uint32_t *macro = macros[nmacros];
356
357 char *tok;
358 size_t sz = 0;
359
360 assert(nmacros < MAX_MACROS);
361
362 if(strstr(s, "macro(") != s || s[len-1] != ')') {
363 free(_s);
364 return NULL;
365 }
366
367 _s[len-1] = 0;
368
369 for(tok = strtok(_s+6, " ");tok;tok = strtok(NULL, " ")) {
370 uint32_t seq;
371 len = strlen(tok);
372
373 if((seq=parse_keyseq(tok))) {
374 macro[sz++] = seq;
375 assert(sz < MAX_MACRO_SIZE);
376 } else if(len > 1 && tok[len-1] == 's' && tok[len-2] == 'm') {
377 int len = atoi(tok);
378 assert(len <= MAX_TIMEOUT_LEN);
379
380 macro[sz++] = TIMEOUT_KEY(len);
381 } else {
382 char *c;
383
384 for(c = tok;*c;c++) {
385 char s[2];
386
387 s[0] = *c;
388 s[1] = 0;
389
390 if(!(seq = parse_keyseq(s))) {
391 free(_s);
392 return NULL;
393 }
394
395 macro[sz++] = seq;
396 assert(sz < MAX_MACRO_SIZE);
397 }
398 }
399 }
400
401 free(_s);
402
403 *szp = sz;
404 nmacros++;
405 return macro;
406 }
407
parse_kvp(char * s,char ** _k,char ** _v)408 static int parse_kvp(char *s, char **_k, char **_v)
409 {
410 char *v = NULL, *k = NULL;
411
412 while(*s && isspace(*s)) s++;
413 if(!*s) return -1;
414 k = s;
415
416 if(*s == '=') s++; //Allow the first character to be = as a special case.
417
418 while(*s && !isspace(*s) && *s != '=') s++;
419 if(!*s) return -1;
420
421 while(*s && *s != '=') {
422 *s = 0;
423 s++;
424 }
425 if(!*s) return -1;
426 *s++ = 0;
427
428 while(*s && isspace(*s)) *s++ = 0;
429 if(!*s) return -1;
430 v = s;
431
432 *_k = k;
433 *_v = v;
434 return 0;
435 }
436
parse_fn(char * s,char ** fn_name,char * args[MAX_ARGS],size_t * nargs)437 static int parse_fn(char *s, char **fn_name, char *args[MAX_ARGS], size_t *nargs)
438 {
439 int openparen = 0;
440
441 *fn_name = s;
442 *nargs = 0;
443
444 while(*s && *s != ')') {
445 switch(*s) {
446 case '(':
447 openparen++;
448 *s = '\0';
449 s++;
450
451 while(*s && isspace(*s))
452 s++;
453
454 if(!*s)
455 return -1;
456
457 if(*s == ')') { //No args
458 *s = '\0';
459 return 0;
460 }
461
462 args[(*nargs)++] = s;
463
464 break;
465 case ',':
466 *s = '\0';
467 s++;
468 while(*s && isspace(*s))
469 s++;
470
471 if(!*s)
472 return -1;
473
474 args[(*nargs)++] = s;
475 break;
476 }
477
478 s++;
479 }
480
481 if(*s != ')')
482 return -1;
483
484 *s = '\0';
485
486 return 0;
487 }
488
parse_descriptor(const char * _s,struct key_descriptor * desc)489 static int parse_descriptor(const char *_s, struct key_descriptor *desc)
490 {
491 uint32_t seq;
492
493 char *s = strdup(_s);
494 char *fn;
495 char *args[MAX_ARGS];
496 size_t nargs, sz;
497 uint32_t *macro;
498
499 if((seq=parse_keyseq(s))) {
500 keyseq_to_desc(seq, desc);
501
502 goto cleanup;
503 }
504
505 if((macro = parse_macro_fn(s, &sz))) {
506 desc->action = ACTION_MACRO;
507 desc->arg.macro = macro;
508 desc->arg2.sz = sz;
509
510 goto cleanup;
511 }
512
513 if(parse_fn(s, &fn, args, &nargs)) {
514 err("%s is not a valid key sequence or action.", s);
515 goto fail;
516 }
517
518 if(!strcmp(fn, "layer") && nargs == 1) {
519 int idx = lookup_layer(args[0]);
520
521 if(idx < 0) {
522 err("%s is not a valid layer.", args[0]);
523 goto fail;
524 }
525
526 desc->action = ACTION_LAYER;
527 desc->arg.layer = idx;
528
529 goto cleanup;
530 } else if(!strcmp(fn, "layert") && nargs == 1) {
531 int idx = lookup_layer(args[0]);
532
533 if(idx < 0) {
534 err("%s is not a valid layer.", args[0]);
535 goto fail;
536 }
537
538 desc->action = ACTION_LAYER_TOGGLE;
539 desc->arg.layer = idx;
540
541 goto cleanup;
542 } else if(!strcmp(fn, "layout") && nargs > 0) {
543 int idx;
544
545 if((idx = lookup_layer(args[0])) < 0) {
546 err("%s is not a valid layer.", args[0]);
547 goto fail;
548 }
549
550 desc->action = ACTION_LAYOUT;
551 desc->arg.layer = idx;
552
553 if(nargs == 1) {
554 desc->arg2.layer = idx;
555 } else {
556 if((idx = lookup_layer(args[1])) < 0) {
557 err("%s is not a valid layer.", args[1]);
558 goto fail;
559 }
560
561 desc->action = ACTION_LAYOUT;
562 desc->arg2.layer = idx;
563 }
564
565
566 goto cleanup;
567 } else if(!strcmp(fn, "oneshot") && nargs == 1) {
568 int idx;
569
570 if((idx = lookup_layer(args[0])) < 0) {
571
572 err("%s is not a valid layer.", args[0]);
573 goto fail;
574 }
575
576 desc->action = ACTION_ONESHOT;
577 desc->arg.layer = idx;
578
579 goto cleanup;
580 } else if(!strcmp(fn, "overload") && nargs == 2) {
581 int idx;
582
583 if((idx = lookup_layer(args[0])) < 0) {
584 err("%s is not a valid layer.", args[0]);
585 goto fail;
586 }
587
588 if(!(seq=parse_keyseq(args[1]))) {
589 err("%s is not a valid key sequence.", args[1]);
590 goto fail;
591 }
592
593 desc->action = ACTION_OVERLOAD;
594 desc->arg.keyseq = seq;
595 desc->arg2.layer = idx;
596
597 goto cleanup;
598 } else if(!strcmp(fn, "swap")) {
599 int idx;
600
601 if((idx = lookup_layer(args[0])) < 0) {
602 err("%s is not a valid layer.", args[0]);
603 goto fail;
604 }
605
606 desc->action = ACTION_SWAP;
607 desc->arg.layer = idx;
608 desc->arg2.keyseq = 0;
609
610 if(nargs == 2) {
611 if(!(desc->arg2.keyseq=parse_keyseq(args[1]))) {
612 err("%s is not a valid key sequence.", args[1]);
613 goto fail;
614 }
615 }
616
617 goto cleanup;
618 } else {
619 err("%s is not a valid action or key.", _s);
620 goto fail;
621 }
622
623
624 cleanup:
625 free(s);
626 return 0;
627
628 fail:
629 free(s);
630 return -1;
631 }
632
build_layer_table()633 static void build_layer_table()
634 {
635 ssize_t len;
636 char *line = NULL;
637 size_t line_sz = 0;
638 FILE *fh = fopen(path, "r");
639
640 if(!fh) {
641 perror("fopen");
642 exit(-1);
643 }
644
645 lnum = 0;
646 nlayers = 0;
647
648 create_main_layer();
649 while((len=getline(&line, &line_sz, fh)) != -1) {
650 char name[256];
651 char pname[256];
652
653 lnum++;
654 if(line[len-1] == '\n')
655 line[--len] = 0;
656
657 if(!parse_layer_heading(line, name, pname)) {
658 uint16_t mods;
659
660 if(!parse_modset(pname, &mods))
661 create_layer(name, "", mods);
662 else
663 create_layer(name, pname, 0);
664 }
665 }
666
667 free(line);
668 fclose(fh);
669 }
670
parse_layer_entry(char * s,uint16_t * code,struct key_descriptor * desc)671 static int parse_layer_entry(char *s, uint16_t *code, struct key_descriptor *desc)
672 {
673 uint32_t seq;
674 char *k, *v;
675
676 if(parse_kvp(s, &k, &v)) {
677 err("Invalid key value pair.");
678 return -1;
679 }
680
681 if(!(seq = parse_keyseq(k))) {
682 err("'%s' is not a valid key.", k);
683 return -1;
684 }
685
686 if((seq >> 16) != 0) {
687 err("key cannot contain modifiers.");
688 return -1;
689 }
690
691 if(parse_descriptor(v, desc))
692 return -1;
693
694 *code = seq & 0xFF;
695 return 0;
696 }
697
post_process_config(struct keyboard_config * cfg,const char * layout_name,const char * modlayout_name)698 void post_process_config(struct keyboard_config *cfg,
699 const char *layout_name,
700 const char *modlayout_name)
701 {
702 cfg->default_layout = -1;
703 cfg->default_modlayout = -1;
704
705 int i;
706 for(i = 0;i < nlayers;i++) {
707 struct layer_table_ent *ent = &layer_table[i];
708
709 if(!strcmp(ent->name, layout_name))
710 cfg->default_layout = i;
711
712 if(!strcmp(ent->name, modlayout_name))
713 cfg->default_modlayout = i;
714
715 if(ent->pname[0]) {
716 int j;
717
718 for(j = 0;j < nlayers;j++) {
719 struct layer_table_ent *ent2 = &layer_table[j];
720
721 if(!strcmp(ent->pname, ent2->name)) {
722 int k;
723
724 struct layer *dst = ent->layer;
725 struct layer *src = ent2->layer;
726
727 for(k = 0;k < KEY_CNT;k++)
728 if(dst->keymap[k].action == ACTION_UNDEFINED)
729 dst->keymap[k] = src->keymap[k];
730 }
731 }
732 }
733 }
734
735 if(cfg->default_layout == -1) {
736 fprintf(stderr, "%s is not a valid default layout", layout_name);
737 cfg->default_layout = 0;
738 }
739
740 if(cfg->default_modlayout == -1) {
741 fprintf(stderr, "%s is not a valid default modifier layout\n", modlayout_name);
742 cfg->default_modlayout = 0;
743 }
744 }
745
parse(struct keyboard_config * cfg)746 static void parse(struct keyboard_config *cfg)
747 {
748 int i;
749 char *line = NULL;
750 size_t n = 0;
751 ssize_t len;
752 struct layer *layer;
753
754 char layout_name[256];
755 char modlayout_name[256];
756
757 build_layer_table();
758
759 FILE *fh = fopen(path, "r");
760 if(!fh) {
761 perror("fopen");
762 exit(-1);
763 }
764
765 lnum = 0;
766 layer = layer_table[0].layer;
767
768 strcpy(layout_name, "main");
769 strcpy(modlayout_name, "main");
770
771 while((len=getline(&line, &n, fh)) != -1) {
772 char name[256];
773 char type[256];
774
775 uint16_t code;
776 struct key_descriptor desc;
777
778 size_t nargs;
779 char *fnname;
780 char *args[MAX_ARGS];
781
782
783 lnum++;
784 char *s = line;
785
786 while(len && isspace(s[0])) { //Trim leading whitespace
787 s++;
788 len--;
789 }
790
791 if(len && s[len-1] == '\n') //Strip tailing newline (not present on EOF)
792 s[--len] = '\0';
793
794 if(len == 0 || s[0] == '#')
795 continue;
796
797 if(!parse_layer_heading(s, name, type)) {
798 int idx = lookup_layer(name);
799 assert(idx > 0);
800 layer = layer_table[idx].layer;
801 } else if(strchr(s, '=')) {
802 if(!parse_layer_entry(s, &code, &desc))
803 layer->keymap[code] = desc;
804 else
805 err("Invalid layer entry.");
806 } else if(!parse_fn(s, &fnname, args, &nargs)) {
807 if(!strcmp(fnname, "layout")) {
808 if(nargs == 1) {
809 strcpy(layout_name, args[0]);
810 strcpy(modlayout_name, args[0]);
811 } else if(nargs == 2) {
812 strcpy(layout_name, args[0]);
813 strcpy(modlayout_name, args[1]);
814 }
815 }
816 }
817
818 free(line);
819 line = NULL;
820 n = 0;
821 }
822
823 free(line);
824 fclose(fh);
825
826 post_process_config(cfg, layout_name, modlayout_name);
827
828 for(i = 0;i < nlayers;i++)
829 cfg->layers[i] = layer_table[i].layer;
830
831 cfg->nlayers = nlayers;
832
833 return;
834 }
835
config_free()836 void config_free()
837 {
838 struct keyboard_config *cfg = configs;
839
840 while(cfg) {
841 size_t i;
842 struct keyboard_config *tmp = cfg;
843
844 cfg = cfg->next;
845
846 for(i = 0;i < tmp->nlayers;i++) {
847 struct layer *layer = tmp->layers[i];
848
849 free(layer->keymap);
850 free(layer);
851 }
852
853 free(tmp);
854 };
855 }
856
config_generate()857 void config_generate()
858 {
859 struct dirent *ent;
860 DIR *dh = opendir(CONFIG_DIR);
861
862 if(!dh) {
863 perror("opendir");
864 exit(-1);
865 }
866
867 while((ent=readdir(dh))) {
868 struct keyboard_config *cfg;
869
870 int len = strlen(ent->d_name);
871 if(len <= 4 || strcmp(ent->d_name+len-4, ".cfg"))
872 continue;
873
874
875 sprintf(path, "%s/%s", CONFIG_DIR, ent->d_name);
876
877 cfg = calloc(1, sizeof(struct keyboard_config));
878
879 strcpy(cfg->name, ent->d_name);
880 cfg->name[len-4] = '\0';
881
882 parse(cfg);
883
884 cfg->next = configs;
885 configs = cfg;
886 }
887
888 closedir(dh);
889 }
890