3 * This file is part of kbd project.
4 * Copyright (C) 1993 Risto Kankkunen.
5 * Copyright (C) 1993 Eugene G. Crosser.
6 * Copyright (C) 1994-2007 Andries E. Brouwer.
7 * Copyright (C) 2007-2012 Alexey Gladkov <gladkov.alexey@gmail.com>
9 * This file is covered by the GNU General Public License,
10 * which should be included with kbd as the file COPYING.
13 #define YY_HEADER_EXPORT_START_CONDITIONS 1
20 #include <sys/ioctl.h>
22 #include <linux/keyboard.h>
26 #include "modifiers.h"
47 %lex-param { yyscan_t scanner }
50 %parse-param { void *scanner }
51 %parse-param { struct keymap *kmap }
53 %token EOL NUMBER LITERAL CHARSET KEYMAPS KEYCODE EQUALS
54 %token PLAIN SHIFT CONTROL ALT ALTGR SHIFTL SHIFTR CTRLL CTRLR CAPSSHIFT
55 %token COMMA DASH STRING STRLITERAL COMPOSE TO CCHAR ERROR PLUS
56 %token UNUMBER ALT_IS_META STRINGS AS USUAL ON FOR
63 %type <str> STRLITERAL
74 int yyerror(yyscan_t scanner, struct keymap *kmap, const char *s);
79 yyerror(yyscan_t scanner attr_unused, struct keymap *kmap, const char *s)
81 log_error(kmap, "%s", s);
86 addmap(struct keymap *kmap, int i, int explicit)
88 if (i < 0 || i >= MAX_NR_KEYMAPS) {
89 log_error(kmap, _("addmap called with bad index %d"), i);
93 if (!kmap->defining[i]) {
94 if (kmap->keymaps_line_seen && !explicit) {
95 log_error(kmap, _("adding map %d violates explicit keymaps line"), i);
99 kmap->defining[i] = i+1;
100 if (kmap->max_keymap <= i)
101 kmap->max_keymap = i + 1;
108 killkey(struct keymap *kmap, int k_index, int k_table)
110 /* roughly: addkey(k_index, k_table, K_HOLE); */
112 if (k_index < 0 || k_index >= NR_KEYS) {
113 log_error(kmap, _("killkey called with bad index %d"), k_index);
117 if (k_table < 0 || k_table >= MAX_NR_KEYMAPS) {
118 log_error(kmap, _("killkey called with bad table %d"), k_table);
122 if (kmap->key_map[k_table])
123 (kmap->key_map[k_table])[k_index] = K_HOLE;
125 if (kmap->keymap_was_set[k_table])
126 (kmap->keymap_was_set[k_table])[k_index] = 0;
132 addkey(struct keymap *kmap, int k_index, int k_table, int keycode)
136 if (keycode == CODE_FOR_UNKNOWN_KSYM) {
137 /* is safer not to be silent in this case,
138 * it can be caused by coding errors as well. */
139 log_error(kmap, _("addkey called with bad keycode %d"), keycode);
143 if (k_index < 0 || k_index >= NR_KEYS) {
144 log_error(kmap, _("addkey called with bad index %d"), k_index);
148 if (k_table < 0 || k_table >= MAX_NR_KEYMAPS) {
149 log_error(kmap, _("addkey called with bad table %d"), k_table);
153 if (!k_index && keycode == K_NOSUCHMAP)
156 if (!kmap->defining[k_table]) {
157 if (addmap(kmap, k_table, 0) == -1)
161 if (!kmap->key_map[k_table]) {
162 kmap->key_map[k_table] = (u_short *)malloc(NR_KEYS * sizeof(u_short));
164 if (kmap->key_map[k_table] == NULL) {
165 log_error(kmap, _("out of memory"));
169 for (i = 0; i < NR_KEYS; i++)
170 (kmap->key_map[k_table])[i] = K_HOLE;
173 if (!kmap->keymap_was_set[k_table]) {
174 kmap->keymap_was_set[k_table] = (char *)malloc(NR_KEYS);
176 if (kmap->key_map[k_table] == NULL) {
177 log_error(kmap, _("out of memory"));
181 for (i = 0; i < NR_KEYS; i++)
182 (kmap->keymap_was_set[k_table])[i] = 0;
185 if (kmap->alt_is_meta && keycode == K_HOLE
186 && (kmap->keymap_was_set[k_table])[k_index])
189 (kmap->key_map[k_table])[k_index] = keycode;
190 (kmap->keymap_was_set[k_table])[k_index] = 1;
192 if (kmap->alt_is_meta) {
193 int alttable = k_table | M_ALT;
194 int type = KTYP(keycode);
195 int val = KVAL(keycode);
197 if (alttable != k_table && kmap->defining[alttable] &&
198 (!kmap->keymap_was_set[alttable] ||
199 !(kmap->keymap_was_set[alttable])[k_index]) &&
200 (type == KT_LATIN || type == KT_LETTER) && val < 128) {
201 if (addkey(kmap, k_index, alttable, K(KT_META, val)) == -1)
209 addfunc(struct keymap *kmap, struct kbsentry kbs)
215 if (x >= MAX_NR_FUNC) {
216 log_error(kmap, _("addfunc called with bad func %d"), kbs.kb_func);
220 if(kmap->func_table[x]) {
221 free(kmap->func_table[x]);
222 kmap->func_table[x] = NULL;
225 kmap->func_table[x] = strdup((char *)kbs.kb_string);
227 if (!kmap->func_table[x]) {
228 log_error(kmap, _("out of memory"));
236 compose(struct keymap *kmap, unsigned int diacr, unsigned int base, unsigned int res)
242 if (kmap->prefer_unicode)
243 direction = TO_UNICODE;
248 if (kmap->accent_table_size == MAX_DIACR) {
249 log_error(kmap, _("compose table overflow"));
253 ptr = &(kmap->accent_table[kmap->accent_table_size++]);
254 ptr->diacr = convert_code(kmap, diacr, direction);
255 ptr->base = convert_code(kmap, base, direction);
256 ptr->result = convert_code(kmap, res, direction);
262 defkeys(struct keymap *kmap, int fd, int kbd_mode)
268 if (kmap->flags & LKFLAG_UNICODE_MODE) {
269 /* temporarily switch to K_UNICODE while defining keys */
270 if (ioctl(fd, KDSKBMODE, K_UNICODE)) {
271 log_error(kmap, _("KDSKBMODE: %s: could not switch to Unicode mode"),
277 for (i = 0; i < MAX_NR_KEYMAPS; i++) {
278 if (kmap->key_map[i]) {
279 for (j = 0; j < NR_KEYS; j++) {
280 if (!((kmap->keymap_was_set[i])[j]))
285 ke.kb_value = (kmap->key_map[i])[j];
287 fail = ioctl(fd, KDSKBENT, (unsigned long)&ke);
290 if (errno == EPERM) {
291 log_error(kmap, _("Keymap %d: Permission denied"), i);
295 log_error(kmap, "%s", strerror(errno));
299 log_verbose(kmap, LOG_VERBOSE1, _("keycode %d, table %d = %d%s"),
300 j, i, (kmap->key_map[i])[j], fail ? _(" FAILED") : "");
302 if (fail && kmap->verbose > 1)
303 log_error(kmap, _("failed to bind key %d to value %d"),
304 j, (kmap->key_map[i])[j]);
307 } else if (kmap->keymaps_line_seen && !kmap->defining[i]) {
308 /* deallocate keymap */
311 ke.kb_value = K_NOSUCHMAP;
313 log_verbose(kmap, LOG_VERBOSE2, _("deallocate keymap %d"), i);
315 if (ioctl(fd, KDSKBENT, (unsigned long)&ke)) {
316 if (errno != EINVAL) {
317 log_error(kmap, _("KDSKBENT: %s: could not deallocate keymap %d"),
321 /* probably an old kernel */
322 /* clear keymap by hand */
323 for (j = 0; j < NR_KEYS; j++) {
326 ke.kb_value = K_HOLE;
328 if (ioctl(fd, KDSKBENT, (unsigned long)&ke)) {
329 if (errno == EINVAL && i >= 16)
330 break; /* old kernel */
332 log_error(kmap, _("KDSKBENT: %s: cannot deallocate or clear keymap"),
341 if ((kmap->flags & LKFLAG_UNICODE_MODE) && ioctl(fd, KDSKBMODE, kbd_mode)) {
342 log_error(kmap, _("KDSKBMODE: %s: could not return to original keyboard mode"),
354 ostr(struct keymap *kmap, char *s)
357 char *ns0 = malloc(4 * lth + 1);
361 log_error(kmap, _("out of memory"));
387 deffuncs(struct keymap *kmap, int fd)
393 for (i = 0; i < MAX_NR_FUNC; i++) {
396 if ((ptr = kmap->func_table[i])) {
397 strcpy((char *)kbs.kb_string, ptr);
398 if (ioctl(fd, KDSKBSENT, (unsigned long)&kbs)) {
399 s = ostr(kmap, (char *)kbs.kb_string);
402 log_error(kmap, _("failed to bind string '%s' to function %s"),
403 s, syms[KT_FN].table[kbs.kb_func]);
408 } else if (kmap->flags & LKFLAG_CLEAR_STRINGS) {
409 kbs.kb_string[0] = 0;
411 if (ioctl(fd, KDSKBSENT, (unsigned long)&kbs)) {
412 log_error(kmap, _("failed to clear string %s"),
413 syms[KT_FN].table[kbs.kb_func]);
423 defdiacs(struct keymap *kmap, int fd)
425 unsigned int i, count;
428 struct kbdiacrsuc kdu;
431 count = kmap->accent_table_size;
432 if (count > MAX_DIACR) {
434 log_error(kmap, _("too many compose definitions"));
437 if (kmap->prefer_unicode) {
440 for (i = 0; i < kdu.kb_cnt; i++) {
441 kdu.kbdiacruc[i].diacr = kmap->accent_table[i].diacr;
442 kdu.kbdiacruc[i].base = kmap->accent_table[i].base;
443 kdu.kbdiacruc[i].result = kmap->accent_table[i].result;
446 if (ioctl(fd, KDSKBDIACRUC, (unsigned long)&kdu))
452 for (i = 0; i < kd.kb_cnt; i++) {
453 kd.kbdiacr[i].diacr = kmap->accent_table[i].diacr;
454 kd.kbdiacr[i].base = kmap->accent_table[i].base;
455 kd.kbdiacr[i].result = kmap->accent_table[i].result;
458 if (ioctl(fd, KDSKBDIACR, (unsigned long)&kd))
464 fail1: log_error(kmap, "KDSKBDIACR: %s", strerror(errno));
468 fail2: log_error(kmap, "KDSKBDIACRUC: %s", strerror(errno));
474 do_constant_key(struct keymap *kmap, int i, u_short key)
481 if ((typ == KT_LATIN || typ == KT_LETTER) &&
482 ((val >= 'a' && val <= 'z') || (val >= 'A' && val <= 'Z'))) {
484 defs[0] = K(KT_LETTER, val);
485 defs[1] = K(KT_LETTER, val ^ 32);
489 for (j = 4; j < 8; j++)
490 defs[j] = K(KT_LATIN, val & ~96);
492 for (j = 8; j < 16; j++)
493 defs[j] = K(KT_META, KVAL(defs[j - 8]));
495 for (j = 0; j < kmap->max_keymap; j++) {
496 if (!kmap->defining[j])
500 kmap->keymap_was_set[j] && (kmap->keymap_was_set[j])[i])
503 if (addkey(kmap, i, j, defs[j % 16]) == -1)
508 /* do this also for keys like Escape,
509 as promised in the man page */
510 for (j = 1; j < kmap->max_keymap; j++) {
511 if (kmap->defining[j] &&
512 (!(kmap->keymap_was_set[j]) || !(kmap->keymap_was_set[j])[i])) {
513 if (addkey(kmap, i, j, key) == -1)
522 do_constant(struct keymap *kmap)
526 if (kmap->keymaps_line_seen) {
527 while (r0 < kmap->max_keymap && !kmap->defining[r0])
531 for (i = 0; i < NR_KEYS; i++) {
532 if (kmap->key_is_constant[i]) {
535 if (!kmap->key_map[r0]) {
536 log_error(kmap, _("impossible error in do_constant"));
540 key = (kmap->key_map[r0])[i];
541 if (do_constant_key(kmap, i, key) == -1)
550 strings_as_usual(struct keymap *kmap)
553 * 26 strings, mostly inspired by the VT100 family
555 char *stringvalues[30] = {
557 "\033[[A", "\033[[B", "\033[[C", "\033[[D", "\033[[E",
558 "\033[17~", "\033[18~", "\033[19~", "\033[20~", "\033[21~",
559 "\033[23~", "\033[24~", "\033[25~", "\033[26~",
560 "\033[28~", "\033[29~",
561 "\033[31~", "\033[32~", "\033[33~", "\033[34~",
562 /* Find, Insert, Remove, Select, Prior */
563 "\033[1~", "\033[2~", "\033[3~", "\033[4~", "\033[5~",
564 /* Next, Macro, Help, Do, Pause */
565 "\033[6~", 0, 0, 0, 0
569 for (i = 0; i < 30; i++) {
570 if (stringvalues[i]) {
573 strncpy((char *)ke.kb_string, stringvalues[i],
574 sizeof(ke.kb_string));
575 ke.kb_string[sizeof(ke.kb_string) - 1] = 0;
577 if (addfunc(kmap, ke) == -1)
585 compose_as_usual(struct keymap *kmap, char *charset)
587 if (charset && strcmp(charset, "iso-8859-1")) {
588 log_error(kmap, _("loadkeys: don't know how to compose for %s"), charset);
593 unsigned char c1, c2, c3;
594 } def_latin1_composes[68] = {
595 { '`', 'A', 0300 }, { '`', 'a', 0340 },
596 { '\'', 'A', 0301 }, { '\'', 'a', 0341 },
597 { '^', 'A', 0302 }, { '^', 'a', 0342 },
598 { '~', 'A', 0303 }, { '~', 'a', 0343 },
599 { '"', 'A', 0304 }, { '"', 'a', 0344 },
600 { 'O', 'A', 0305 }, { 'o', 'a', 0345 },
601 { '0', 'A', 0305 }, { '0', 'a', 0345 },
602 { 'A', 'A', 0305 }, { 'a', 'a', 0345 },
603 { 'A', 'E', 0306 }, { 'a', 'e', 0346 },
604 { ',', 'C', 0307 }, { ',', 'c', 0347 },
605 { '`', 'E', 0310 }, { '`', 'e', 0350 },
606 { '\'', 'E', 0311 }, { '\'', 'e', 0351 },
607 { '^', 'E', 0312 }, { '^', 'e', 0352 },
608 { '"', 'E', 0313 }, { '"', 'e', 0353 },
609 { '`', 'I', 0314 }, { '`', 'i', 0354 },
610 { '\'', 'I', 0315 }, { '\'', 'i', 0355 },
611 { '^', 'I', 0316 }, { '^', 'i', 0356 },
612 { '"', 'I', 0317 }, { '"', 'i', 0357 },
613 { '-', 'D', 0320 }, { '-', 'd', 0360 },
614 { '~', 'N', 0321 }, { '~', 'n', 0361 },
615 { '`', 'O', 0322 }, { '`', 'o', 0362 },
616 { '\'', 'O', 0323 }, { '\'', 'o', 0363 },
617 { '^', 'O', 0324 }, { '^', 'o', 0364 },
618 { '~', 'O', 0325 }, { '~', 'o', 0365 },
619 { '"', 'O', 0326 }, { '"', 'o', 0366 },
620 { '/', 'O', 0330 }, { '/', 'o', 0370 },
621 { '`', 'U', 0331 }, { '`', 'u', 0371 },
622 { '\'', 'U', 0332 }, { '\'', 'u', 0372 },
623 { '^', 'U', 0333 }, { '^', 'u', 0373 },
624 { '"', 'U', 0334 }, { '"', 'u', 0374 },
625 { '\'', 'Y', 0335 }, { '\'', 'y', 0375 },
626 { 'T', 'H', 0336 }, { 't', 'h', 0376 },
627 { 's', 's', 0337 }, { '"', 'y', 0377 },
628 { 's', 'z', 0337 }, { 'i', 'j', 0377 }
631 for (i = 0; i < 68; i++) {
632 struct ccc ptr = def_latin1_composes[i];
633 if (compose(kmap, ptr.c1, ptr.c2, ptr.c3) == -1)
645 mk_mapname(char modifier)
647 static char *mods[8] = {
648 "shift", "altgr", "ctrl", "alt", "shl", "shr", "ctl", "ctr"
656 for (i = 0; i < 8; i++)
657 if (modifier & (1 << i)) {
660 strcat(buf, mods[i]);
666 outchar(FILE *fd, unsigned char c, int comma)
669 fprintf(fd, (c == '\'' || c == '\\') ? "\\%c"
672 fprintf(fd, comma ? "', " : "'");
675 // FIXME: Merge outchar ?
677 dumpchar(FILE *fd, unsigned char c, int comma)
680 fprintf(fd, (c == '\'' || c == '\\') ? "\\%c"
681 : (isgraph(c) || c == ' ' || c >= 0200) ? "%c"
683 fprintf(fd, comma ? "', " : "'");
703 charsetline : CHARSET STRLITERAL EOL
705 if (set_charset((char *) $2.data)) {
707 _("unknown charset %s - ignoring charset request\n"),
712 /* Unicode: The first 256 code points were made
713 identical to the content of ISO 8859-1 */
714 if (kmap->prefer_unicode &&
715 !strcasecmp((char *) $2.data, "iso-8859-1"))
716 kmap->prefer_unicode = 0;
719 altismetaline : ALT_IS_META EOL
721 kmap->alt_is_meta = 1;
724 usualstringsline: STRINGS AS USUAL EOL
726 if (strings_as_usual(kmap) == -1)
730 usualcomposeline: COMPOSE AS USUAL FOR STRLITERAL EOL
732 if (compose_as_usual(kmap, (char *) $5.data) == -1)
735 | COMPOSE AS USUAL EOL
737 if (compose_as_usual(kmap, 0) == -1)
741 keymapline : KEYMAPS range EOL
743 kmap->keymaps_line_seen = 1;
746 range : range COMMA range0
749 range0 : NUMBER DASH NUMBER
752 for (i = $1; i <= $3; i++) {
753 if (addmap(kmap, i, 1) == -1)
759 if (addmap(kmap, $1, 1) == -1)
763 strline : STRING LITERAL EQUALS STRLITERAL EOL
767 if (KTYP($2) != KT_FN) {
768 log_error(kmap, _("'%s' is not a function key symbol"),
769 syms[KTYP($2)].table[KVAL($2)]);
773 ke.kb_func = KVAL($2);
774 strncpy((char *) ke.kb_string,
776 sizeof(ke.kb_string));
777 ke.kb_string[sizeof(ke.kb_string) - 1] = 0;
779 if (addfunc(kmap, ke) == -1)
783 compline : COMPOSE compsym compsym TO compsym EOL
785 if (compose(kmap, $2, $3, $5) == -1)
788 | COMPOSE compsym compsym TO rvalue EOL
790 if (compose(kmap, $2, $3, $5) == -1)
794 compsym : CCHAR { $$ = $1; }
795 | UNUMBER { $$ = $1 ^ 0xf000; }
800 modifiers KEYCODE NUMBER EQUALS rvalue EOL
802 if (addkey(kmap, $4, kmap->mod, $6) == -1)
805 | PLAIN KEYCODE NUMBER EQUALS rvalue EOL
807 if (addkey(kmap, $3, 0, $5) == -1)
811 modifiers : modifiers modifier
814 modifier : SHIFT { kmap->mod |= M_SHIFT; }
815 | CONTROL { kmap->mod |= M_CTRL; }
816 | ALT { kmap->mod |= M_ALT; }
817 | ALTGR { kmap->mod |= M_ALTGR; }
818 | SHIFTL { kmap->mod |= M_SHIFTL; }
819 | SHIFTR { kmap->mod |= M_SHIFTR; }
820 | CTRLL { kmap->mod |= M_CTRLL; }
821 | CTRLR { kmap->mod |= M_CTRLR; }
822 | CAPSSHIFT { kmap->mod |= M_CAPSSHIFT; }
824 fullline : KEYCODE NUMBER EQUALS rvalue0 EOL
828 if (kmap->rvalct == 1) {
829 /* Some files do not have a keymaps line, and
830 * we have to wait until all input has been read
831 * before we know which maps to fill. */
832 kmap->key_is_constant[$2] = 1;
834 /* On the other hand, we now have include files,
835 * and it should be possible to override lines
836 * from an include file. So, kill old defs. */
837 for (j = 0; j < kmap->max_keymap; j++) {
838 if (!(kmap->defining[j]))
841 if (killkey(kmap, $2, j) == -1)
846 if (kmap->keymaps_line_seen) {
849 for (j = 0; j < kmap->max_keymap; j++) {
850 if (!(kmap->defining[j]))
853 if (kmap->rvalct != 1 || i == 0) {
854 keycode = (i < kmap->rvalct)
858 if (addkey(kmap, $2, j, keycode) == -1)
864 if (i < kmap->rvalct) {
865 log_error(kmap, _("too many (%d) entries on one line"),
870 for (i = 0; i < kmap->rvalct; i++) {
871 if (addkey(kmap, $2, i, kmap->key_buf[i]) == -1)
883 if (kmap->rvalct >= MAX_NR_KEYMAPS) {
884 log_error(kmap, _("too many key definitions on one line"));
887 kmap->key_buf[kmap->rvalct++] = $1;
890 rvalue : NUMBER { $$ = convert_code(kmap, $1, TO_AUTO); }
891 | PLUS NUMBER { $$ = add_capslock(kmap, $2); }
892 | UNUMBER { $$ = convert_code(kmap, $1^0xf000, TO_AUTO); }
893 | PLUS UNUMBER { $$ = add_capslock(kmap, $2^0xf000); }
894 | LITERAL { $$ = $1; }
895 | PLUS LITERAL { $$ = add_capslock(kmap, $2); }
900 lk_parse_keymap(struct keymap *kmap, lkfile_t *f)
905 yylex_init(&scanner);
906 yylex_init_extra(kmap, &scanner);
908 log_verbose(kmap, LOG_NORMAL, _("Loading %s"), f->pathname);
910 if (stack_push(kmap, f, scanner) == -1)
913 if (yyparse(scanner, kmap))
918 stack_pop(kmap, scanner);
920 fail: yylex_destroy(scanner);
925 lk_loadkeys(struct keymap *kmap, int fd, int kbd_mode)
927 int keyct, funcct, diacct;
929 if (do_constant(kmap) < 0)
932 if ((keyct = defkeys(kmap, fd, kbd_mode)) < 0 || (funcct = deffuncs(kmap, fd)) < 0)
935 log_verbose(kmap, LOG_VERBOSE1, _("\nChanged %d %s and %d %s"),
936 keyct, (keyct == 1) ? _("key") : _("keys"),
937 funcct, (funcct == 1) ? _("string") : _("strings"));
939 if (kmap->accent_table_size > 0 || kmap->flags & LKFLAG_CLEAR_COMPOSE) {
940 diacct = defdiacs(kmap, fd);
945 log_verbose(kmap, LOG_VERBOSE1, _("Loaded %d compose %s"),
946 diacct, (diacct == 1) ? _("definition") : _("definitions"));
949 log_verbose(kmap, LOG_VERBOSE1, _("(No change in compose definitions)"));