4 * For history, see older versions.
7 %token EOL NUMBER LITERAL CHARSET KEYMAPS KEYCODE EQUALS
8 %token PLAIN SHIFT CONTROL ALT ALTGR SHIFTL SHIFTR CTRLL CTRLR
9 %token COMMA DASH STRING STRLITERAL COMPOSE TO CCHAR ERROR PLUS
10 %token UNUMBER ALT_IS_META STRINGS AS USUAL ON FOR
20 #include <sys/ioctl.h>
22 #include <linux/keyboard.h>
23 #include <unistd.h> /* readlink */
27 #include "modifiers.h"
32 #define KT_LETTER KT_LATIN
38 /* What keymaps are we defining? */
39 char defining[MAX_NR_KEYMAPS];
40 char keymaps_line_seen = 0;
41 int max_keymap = 0; /* from here on, defining[] is false */
44 /* the kernel structures we want to set or print */
45 u_short *key_map[MAX_NR_KEYMAPS];
46 char *func_table[MAX_NR_FUNC];
47 struct kbdiacr accent_table[MAX_DIACR];
48 unsigned int accent_table_size = 0;
50 char key_is_constant[NR_KEYS];
51 char *keymap_was_set[MAX_NR_KEYMAPS];
52 char func_buf[4096]; /* should be allocated dynamically */
55 #define U(x) ((x) ^ 0xf000)
59 static void addmap(int map, int explicit);
60 static void addkey(int index, int table, int keycode);
61 static void addfunc(struct kbsentry kbs_buf);
62 static void killkey(int index, int table);
63 static void compose(int diacr, int base, int res);
64 static void do_constant(void);
65 static void do_constant_key (int, u_short);
66 static void loadkeys(char *console, int *warned);
67 static void mktable(void);
68 static void bkeymap(void);
69 static void strings_as_usual(void);
70 /* static void keypad_as_usual(char *keyboard); */
71 /* static void function_keys_as_usual(char *keyboard); */
72 /* static void consoles_as_usual(char *keyboard); */
73 static void compose_as_usual(char *charset);
74 static void lkfatal0(const char *, int);
75 extern int set_charset(const char *charset);
76 extern char *xstrdup(char *);
77 int key_buf[MAX_NR_KEYMAPS];
79 extern int unicode_used;
80 int private_error_ct = 0;
83 extern struct kbsentry kbs_buf;
84 int yyerror(const char *s);
85 extern void lkfatal(const char *s);
86 extern void lkfatal1(const char *s, const char *s2);
107 charsetline : CHARSET STRLITERAL EOL
109 set_charset((char *) kbs_buf.kb_string);
112 altismetaline : ALT_IS_META EOL
117 usualstringsline: STRINGS AS USUAL EOL
122 usualcomposeline: COMPOSE AS USUAL FOR STRLITERAL EOL
124 compose_as_usual((char *) kbs_buf.kb_string);
126 | COMPOSE AS USUAL EOL
131 keymapline : KEYMAPS range EOL
133 keymaps_line_seen = 1;
136 range : range COMMA range0
139 range0 : NUMBER DASH NUMBER
142 for (i = $1; i<= $3; i++)
150 strline : STRING LITERAL EQUALS STRLITERAL EOL
152 if (KTYP($2) != KT_FN)
153 lkfatal1(_("'%s' is not a function key symbol"),
154 syms[KTYP($2)].table[KVAL($2)]);
155 kbs_buf.kb_func = KVAL($2);
159 compline : COMPOSE CCHAR CCHAR TO CCHAR EOL
163 | COMPOSE CCHAR CCHAR TO rvalue EOL
168 singleline : { mod = 0; }
169 modifiers KEYCODE NUMBER EQUALS rvalue EOL
173 | PLAIN KEYCODE NUMBER EQUALS rvalue EOL
178 modifiers : modifiers modifier
181 modifier : SHIFT { mod |= M_SHIFT; }
182 | CONTROL { mod |= M_CTRL; }
183 | ALT { mod |= M_ALT; }
184 | ALTGR { mod |= M_ALTGR; }
185 | SHIFTL { mod |= M_SHIFTL; }
186 | SHIFTR { mod |= M_SHIFTR; }
187 | CTRLL { mod |= M_CTRLL; }
188 | CTRLR { mod |= M_CTRLR; }
190 fullline : KEYCODE NUMBER EQUALS rvalue0 EOL
195 /* Some files do not have a keymaps line, and
196 we have to wait until all input has been read
197 before we know which maps to fill. */
198 key_is_constant[$2] = 1;
200 /* On the other hand, we now have include files,
201 and it should be possible to override lines
202 from an include file. So, kill old defs. */
203 for (j = 0; j < max_keymap; j++)
207 if (keymaps_line_seen) {
209 for (j = 0; j < max_keymap; j++)
211 if (rvalct != 1 || i == 0)
212 addkey($2, j, (i < rvalct) ? key_buf[i] : K_HOLE);
216 lkfatal0(_("too many (%d) entries on one line"), rvalct);
218 for (i = 0; i < rvalct; i++)
219 addkey($2, i, key_buf[i]);
228 if (rvalct >= MAX_NR_KEYMAPS)
229 lkfatal(_("too many keydefinitions on one line"));
230 key_buf[rvalct++] = $1;
236 {$$=($1 ^ 0xf000); unicode_used=1;}
238 {$$=add_capslock($2);}
242 {$$=add_capslock($2);}
250 fprintf(stderr, _("loadkeys version %s\n"
252 "Usage: loadkeys [option...] [mapfile...]\n"
254 "valid options are:\n"
256 " -b --bkeymap output a binary keymap to stdout\n"
257 " -c --clearcompose clear kernel compose table\n"
258 " -C <cons1,cons2,...>\n"
259 " --console=<...> Indicate console device(s) to be used.\n"
260 " -d --default load \"" DEFMAP "\"\n"
261 " -h --help display this help text\n"
262 " -m --mktable output a \"defkeymap.c\" to stdout\n"
263 " -s --clearstrings clear kernel string table\n"
264 " -u --unicode implicit conversion to Unicode\n"
265 " -v --verbose report the changes\n"), PACKAGE_VERSION);
279 main(int argc, char *argv[]) {
280 const char *short_opts = "bcC:dhmsuqvV";
281 const struct option long_opts[] = {
282 { "bkeymap", no_argument, NULL, 'b' },
283 { "clearcompose", no_argument, NULL, 'c' },
284 { "console", 1, NULL, 'C' },
285 { "default", no_argument, NULL, 'd' },
286 { "help", no_argument, NULL, 'h' },
287 { "mktable", no_argument, NULL, 'm' },
288 { "clearstrings", no_argument, NULL, 's' },
289 { "unicode", no_argument, NULL, 'u' },
290 { "quiet", no_argument, NULL, 'q' },
291 { "verbose", no_argument, NULL, 'v' },
292 { "version", no_argument, NULL, 'V' },
296 char *console = NULL;
299 set_progname(argv[0]);
301 while ((c = getopt_long(argc, argv,
302 short_opts, long_opts, NULL)) != -1) {
323 set_charset("unicode");
332 print_version_and_exit();
339 args = argv + optind - 1;
341 yywrap(); /* set up the first input file, if any */
342 if (yyparse() || private_error_ct) {
343 fprintf(stderr, _("syntax error in map file\n"));
345 fprintf(stderr, _("key bindings not changed\n"));
355 char *buf = strdup(console); /* make writable */
359 while ( *s == ' ' || *s == '\t' || *s == ',') s++;
361 while (*e && *e != ' ' && *e != '\t' && *e != ',') e++;
364 if (verbose) printf("%s\n", s);
365 loadkeys(s, &warned);
372 loadkeys(NULL, &warned);
376 extern char pathname[];
381 yyerror(const char *s) {
382 fprintf(stderr, "%s:%d: %s\n", filename, line_nr, s);
387 /* fatal errors - change to varargs next time */
389 lkfatal(const char *s) {
390 fprintf(stderr, "%s: %s:%d: %s\n", progname, filename, line_nr, s);
395 lkfatal0(const char *s, int d) {
396 fprintf(stderr, "%s: %s:%d: ", progname, filename, line_nr);
397 fprintf(stderr, s, d);
398 fprintf(stderr, "\n");
403 lkfatal1(const char *s, const char *s2) {
404 fprintf(stderr, "%s: %s:%d: ", progname, filename, line_nr);
405 fprintf(stderr, s, s2);
406 fprintf(stderr, "\n");
410 /* Include file handling - unfortunately flex-specific. */
411 #define MAX_INCLUDE_DEPTH 20
416 } infile_stack[MAX_INCLUDE_DEPTH];
417 int infile_stack_ptr = 0;
421 if (infile_stack_ptr >= MAX_INCLUDE_DEPTH)
422 lkfatal(_("includes nested too deeply"));
424 /* preserve current state */
425 infile_stack[infile_stack_ptr].filename = filename;
426 infile_stack[infile_stack_ptr].linenr = line_nr;
427 infile_stack[infile_stack_ptr++].bs =
433 if (--infile_stack_ptr >= 0) {
434 filename = infile_stack[infile_stack_ptr].filename;
435 line_nr = infile_stack[infile_stack_ptr].linenr;
436 yy_delete_buffer(YY_CURRENT_BUFFER);
437 yy_switch_to_buffer(infile_stack[infile_stack_ptr].bs);
444 * Where shall we look for an include file?
445 * Current strategy (undocumented, may change):
447 * 1. Look for a user-specified LOADKEYS_INCLUDE_PATH
448 * 2. Try . and ../include and ../../include
449 * 3. Try D and D/../include and D/../../include
450 * where D is the directory from where we are loading the current file.
451 * 4. Try KD/include and KD/#/include where KD = DATADIR/KEYMAPDIR.
454 * KD has subdirectories amiga, atari, i386, mac, sun, include
455 * KD/include contains architecture-independent stuff
456 * like strings and iso-8859-x compose tables.
457 * KD/i386 has subdirectories qwerty, ... and include;
458 * this latter include dir contains stuff with keycode=...
460 * (Of course, if the present setup turns out to be reasonable,
461 * then later also the other architectures will grow and get
462 * subdirectories, and the hard-coded i386 below will go again.)
464 * People that dislike a dozen lookups for loadkeys
465 * can easily do "loadkeys file_with_includes; dumpkeys > my_keymap"
466 * and afterwards use only "loadkeys /fullpath/mykeymap", where no
467 * lookups are required.
469 char *include_dirpath0[] = { "", 0 };
470 char *include_dirpath1[] = { "", "../include/", "../../include/", 0 };
471 char *include_dirpath2[] = { 0, 0, 0, 0 };
472 char *include_dirpath3[] = { DATADIR "/" KEYMAPDIR "/include/",
473 DATADIR "/" KEYMAPDIR "/i386/include/",
474 DATADIR "/" KEYMAPDIR "/mac/include/", 0 };
475 char *include_suffixes[] = { "", ".inc", 0 };
477 FILE *find_incl_file_near_fn(char *s, char *fn) {
479 char *t, *te, *t1, *t2;
489 include_dirpath2[0] = t;
491 include_dirpath2[1] = t1 = xmalloc(len + 12);
492 include_dirpath2[2] = t2 = xmalloc(len + 15);
494 strcat(t1, "../include/");
496 strcat(t2, "../../include/");
497 f = findfile(s, include_dirpath2, include_suffixes);
504 FILE *find_standard_incl_file(char *s) {
507 f = findfile(s, include_dirpath1, include_suffixes);
509 f = find_incl_file_near_fn(s, filename);
511 /* If filename is a symlink, also look near its target. */
513 char buf[1024], path[1024], *p;
516 n = readlink(filename, buf, sizeof(buf));
517 if (n > 0 && n < sizeof(buf)) {
520 f = find_incl_file_near_fn(s, buf);
521 else if (strlen(filename) + n < sizeof(path)) {
522 strcpy(path, filename);
523 path[sizeof(path)-1] = 0;
524 p = rindex(path, '/');
528 f = find_incl_file_near_fn(s, path);
534 f = findfile(s, include_dirpath3, include_suffixes);
538 FILE *find_incl_file(char *s) {
543 if (*s == '/') /* no path required */
544 return (findfile(s, include_dirpath0, include_suffixes));
546 if((ev = getenv("LOADKEYS_INCLUDE_PATH")) != NULL) {
547 /* try user-specified path */
548 char *user_dir[2] = { 0, 0 };
550 char *t = index(ev, ':');
558 f = findfile(s, user_dir, include_suffixes);
559 else /* empty string denotes system path */
560 f = find_standard_incl_file(s);
569 return find_standard_incl_file(s);
573 open_include(char *s) {
576 /* start reading include file */
577 fprintf(stdout, _("switching to %s\n"), s);
581 yyin = find_incl_file(s);
583 lkfatal1(_("cannot open include file %s"), s);
584 filename = xstrdup(pathname);
586 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
589 /* String file handling - flex-specific. */
593 lk_scan_string(char *s) {
600 lk_end_string(void) {
605 char *dirpath[] = { "", DATADIR "/" KEYMAPDIR "/**", KERNDIR "/", 0 };
606 char *suffixes[] = { "", ".kmap", ".map", 0 };
607 extern FILE *findfile(char *fnam, char **dirpath, char **suffixes);
613 static int first_file = 1; /* ugly kludge flag */
620 if (infile_stack_ptr > 0) {
627 /* first read default map - search starts in . */
629 if((f = findfile(DEFMAP, dirpath, suffixes)) == NULL) {
630 fprintf(stderr, _("Cannot find %s\n"), DEFMAP);
639 if (!strcmp(*args, "-")) {
641 strcpy(pathname, "<stdin>");
642 } else if ((f = findfile(*args, dirpath, suffixes)) == NULL) {
643 fprintf(stderr, _("cannot open file %s\n"), *args);
647 Can't use yyrestart if this is called before entering yyparse()
648 I think assigning directly to yyin isn't necessarily safe in
649 other situations, hence the flag.
652 filename = xstrdup(pathname);
654 fprintf(stdout, _("Loading %s\n"), pathname);
664 addmap(int i, int explicit) {
665 if (i < 0 || i >= MAX_NR_KEYMAPS)
666 lkfatal0(_("addmap called with bad index %d"), i);
669 if (keymaps_line_seen && !explicit)
670 lkfatal0(_("adding map %d violates explicit keymaps line"), i);
680 killkey(int index, int table) {
681 /* roughly: addkey(index, table, K_HOLE); */
683 if (index < 0 || index >= NR_KEYS)
684 lkfatal0(_("killkey called with bad index %d"), index);
685 if (table < 0 || table >= MAX_NR_KEYMAPS)
686 lkfatal0(_("killkey called with bad table %d"), table);
688 (key_map[table])[index] = K_HOLE;
689 if (keymap_was_set[table])
690 (keymap_was_set[table])[index] = 0;
694 addkey(int index, int table, int keycode) {
697 if (keycode == CODE_FOR_UNKNOWN_KSYM)
698 /* is safer not to be silent in this case,
699 * it can be caused by coding errors as well. */
700 lkfatal0(_("addkey called with bad keycode %d"), keycode);
701 if (index < 0 || index >= NR_KEYS)
702 lkfatal0(_("addkey called with bad index %d"), index);
703 if (table < 0 || table >= MAX_NR_KEYMAPS)
704 lkfatal0(_("addkey called with bad table %d"), table);
706 if (!defining[table])
708 if (!key_map[table]) {
709 key_map[table] = (u_short *)xmalloc(NR_KEYS * sizeof(u_short));
710 for (i = 0; i < NR_KEYS; i++)
711 (key_map[table])[i] = K_HOLE;
713 if (!keymap_was_set[table]) {
714 keymap_was_set[table] = (char *) xmalloc(NR_KEYS);
715 for (i = 0; i < NR_KEYS; i++)
716 (keymap_was_set[table])[i] = 0;
719 if (alt_is_meta && keycode == K_HOLE && (keymap_was_set[table])[index])
722 (key_map[table])[index] = keycode;
723 (keymap_was_set[table])[index] = 1;
726 int alttable = table | M_ALT;
727 int type = KTYP(keycode);
728 int val = KVAL(keycode);
729 if (alttable != table && defining[alttable] &&
730 (!keymap_was_set[alttable] ||
731 !(keymap_was_set[alttable])[index]) &&
732 (type == KT_LATIN || type == KT_LETTER) && val < 128)
733 addkey(index, alttable, K(KT_META, val));
738 addfunc(struct kbsentry kbs) {
744 if (x >= MAX_NR_FUNC) {
745 fprintf(stderr, _("%s: addfunc called with bad func %d\n"),
746 progname, kbs.kb_func);
751 if (q) { /* throw out old previous def */
758 for (i = x + 1; i < MAX_NR_FUNC; i++)
763 p = func_buf; /* find place for new def */
764 for (i = 0; i < x; i++)
770 sh = strlen((char *) kbs.kb_string) + 1;
771 if (fp + sh > func_buf + sizeof(func_buf)) {
773 _("%s: addfunc: func_buf overflow\n"), progname);
781 strcpy(p, (char *) kbs.kb_string);
782 for (i = x + 1; i < MAX_NR_FUNC; i++)
788 compose(int diacr, int base, int res) {
790 if (accent_table_size == MAX_DIACR) {
791 fprintf(stderr, _("compose table overflow\n"));
794 p = &accent_table[accent_table_size++];
801 defkeys(int fd, char *cons, int *warned) {
808 /* Switch keyboard mode for a moment -
809 do not complain about errors.
810 Do not attempt a reset if the change failed. */
811 if (ioctl(fd, KDGKBMODE, &oldm)
812 || (oldm != K_UNICODE && ioctl(fd, KDSKBMODE, K_UNICODE)))
816 for(i=0; i<MAX_NR_KEYMAPS; i++) {
818 for(j=0; j<NR_KEYS; j++) {
819 if ((keymap_was_set[i])[j]) {
822 ke.kb_value = (key_map[i])[j];
824 fail = ioctl(fd, KDSKBENT, (unsigned long)&ke);
826 if (errno == EPERM) {
828 _("Keymap %d: Permission denied\n"), i);
836 printf("keycode %d, table %d = %d%s\n", j, i,
837 (key_map[i])[j], fail ? _(" FAILED") : "");
840 _("failed to bind key %d to value %d\n"),
844 } else if (keymaps_line_seen && !defining[i]) {
845 /* deallocate keymap */
848 ke.kb_value = K_NOSUCHMAP;
851 printf(_("deallocate keymap %d\n"), i);
853 if(ioctl(fd, KDSKBENT, (unsigned long)&ke)) {
854 if (errno != EINVAL) {
857 _("%s: could not deallocate keymap %d\n"),
861 /* probably an old kernel */
862 /* clear keymap by hand */
863 for (j = 0; j < NR_KEYS; j++) {
866 ke.kb_value = K_HOLE;
867 if(ioctl(fd, KDSKBENT, (unsigned long)&ke)) {
868 if (errno == EINVAL && i >= 16)
869 break; /* old kernel */
872 _("%s: cannot deallocate or clear keymap\n"),
881 if(unicode_used && oldm != K_UNICODE) {
882 if (ioctl(fd, KDSKBMODE, oldm)) {
883 fprintf(stderr, _("%s: failed to restore keyboard mode\n"),
890 if (ioctl(fd, KDGETMODE, &kd_mode) || (kd_mode != KD_GRAPHICS))
893 * It is okay for the graphics console to have a non-unicode mode.
894 * only talk about other consoles
896 fprintf(stderr, _("%s: warning: this map uses Unicode symbols, %s mode=%d\n"
897 " (perhaps you want to do `kbd_mode -u'?)\n"),
898 progname, cons ? cons : "NULL", kd_mode);
908 char *ns0 = xmalloc(4*lth + 1);
937 for (i = 0; i < MAX_NR_FUNC; i++) {
939 if ((p = func_table[i])) {
940 strcpy((char *) kbs_buf.kb_string, p);
941 if (ioctl(fd, KDSKBSENT, (unsigned long)&kbs_buf))
942 fprintf(stderr, _("failed to bind string '%s' to function %s\n"),
943 ostr(kbs_buf.kb_string), syms[KT_FN].table[kbs_buf.kb_func]);
947 kbs_buf.kb_string[0] = 0;
948 if (ioctl(fd, KDSKBSENT, (unsigned long)&kbs_buf))
949 fprintf(stderr, _("failed to clear string %s\n"),
950 syms[KT_FN].table[kbs_buf.kb_func]);
963 kd.kb_cnt = accent_table_size;
964 if (kd.kb_cnt > MAX_DIACR) {
965 kd.kb_cnt = MAX_DIACR;
966 fprintf(stderr, _("too many compose definitions\n"));
968 for (i = 0; i < kd.kb_cnt; i++)
969 kd.kbdiacr[i] = accent_table[i];
971 if(ioctl(fd, KDSKBDIACR, (unsigned long) &kd)) {
972 perror("KDSKBDIACR");
979 do_constant_key (int i, u_short key) {
984 if ((typ == KT_LATIN || typ == KT_LETTER) &&
985 ((val >= 'a' && val <= 'z') ||
986 (val >= 'A' && val <= 'Z'))) {
988 defs[0] = K(KT_LETTER, val);
989 defs[1] = K(KT_LETTER, val ^ 32);
993 defs[j] = K(KT_LATIN, val & ~96);
995 defs[j] = K(KT_META, KVAL(defs[j-8]));
996 for(j=0; j<max_keymap; j++) {
1000 keymap_was_set[j] && (keymap_was_set[j])[i])
1002 addkey(i, j, defs[j%16]);
1005 /* do this also for keys like Escape,
1006 as promised in the man page */
1007 for (j=1; j<max_keymap; j++)
1009 (!(keymap_was_set[j]) || !(keymap_was_set[j])[i]))
1015 do_constant (void) {
1018 if (keymaps_line_seen)
1019 while (r0 < max_keymap && !defining[r0])
1022 for (i=0; i<NR_KEYS; i++) {
1023 if (key_is_constant[i]) {
1026 lkfatal(_("impossible error in do_constant"));
1027 key = (key_map[r0])[i];
1028 do_constant_key (i, key);
1034 loadkeys (char *console, int *warned) {
1036 int keyct, funcct, diacct = 0;
1038 fd = getfd(console);
1039 keyct = defkeys(fd, console, warned);
1040 funcct = deffuncs(fd);
1042 printf(_("\nChanged %d %s and %d %s.\n"),
1043 keyct, (keyct == 1) ? _("key") : _("keys"),
1044 funcct, (funcct == 1) ? _("string") : _("strings"));
1046 if (accent_table_size > 0 || nocompose) {
1047 diacct = defdiacs(fd);
1049 printf(_("Loaded %d compose %s.\n"), diacct,
1050 (diacct == 1) ? _("definition") : _("definitions"));
1055 printf(_("(No change in compose definitions.)\n"));
1058 static void strings_as_usual(void) {
1060 * 26 strings, mostly inspired by the VT100 family
1062 char *stringvalues[30] = {
1064 "\033[[A", "\033[[B", "\033[[C", "\033[[D", "\033[[E",
1065 "\033[17~", "\033[18~", "\033[19~", "\033[20~", "\033[21~",
1066 "\033[23~", "\033[24~", "\033[25~", "\033[26~",
1067 "\033[28~", "\033[29~",
1068 "\033[31~", "\033[32~", "\033[33~", "\033[34~",
1069 /* Find, Insert, Remove, Select, Prior */
1070 "\033[1~", "\033[2~", "\033[3~", "\033[4~", "\033[5~",
1071 /* Next, Macro, Help, Do, Pause */
1072 "\033[6~", 0, 0, 0, 0
1075 for (i=0; i<30; i++) if(stringvalues[i]) {
1078 strncpy((char *) ke.kb_string, stringvalues[i], sizeof(ke.kb_string));
1079 ke.kb_string[sizeof(ke.kb_string)-1] = 0;
1085 compose_as_usual(char *charset) {
1086 if (charset && strcmp(charset, "iso-8859-1")) {
1087 fprintf(stderr, _("loadkeys: don't know how to compose for %s\n"),
1093 } def_latin1_composes[68] = {
1094 { '`', 'A', 0300 }, { '`', 'a', 0340 },
1095 { '\'', 'A', 0301 }, { '\'', 'a', 0341 },
1096 { '^', 'A', 0302 }, { '^', 'a', 0342 },
1097 { '~', 'A', 0303 }, { '~', 'a', 0343 },
1098 { '"', 'A', 0304 }, { '"', 'a', 0344 },
1099 { 'O', 'A', 0305 }, { 'o', 'a', 0345 },
1100 { '0', 'A', 0305 }, { '0', 'a', 0345 },
1101 { 'A', 'A', 0305 }, { 'a', 'a', 0345 },
1102 { 'A', 'E', 0306 }, { 'a', 'e', 0346 },
1103 { ',', 'C', 0307 }, { ',', 'c', 0347 },
1104 { '`', 'E', 0310 }, { '`', 'e', 0350 },
1105 { '\'', 'E', 0311 }, { '\'', 'e', 0351 },
1106 { '^', 'E', 0312 }, { '^', 'e', 0352 },
1107 { '"', 'E', 0313 }, { '"', 'e', 0353 },
1108 { '`', 'I', 0314 }, { '`', 'i', 0354 },
1109 { '\'', 'I', 0315 }, { '\'', 'i', 0355 },
1110 { '^', 'I', 0316 }, { '^', 'i', 0356 },
1111 { '"', 'I', 0317 }, { '"', 'i', 0357 },
1112 { '-', 'D', 0320 }, { '-', 'd', 0360 },
1113 { '~', 'N', 0321 }, { '~', 'n', 0361 },
1114 { '`', 'O', 0322 }, { '`', 'o', 0362 },
1115 { '\'', 'O', 0323 }, { '\'', 'o', 0363 },
1116 { '^', 'O', 0324 }, { '^', 'o', 0364 },
1117 { '~', 'O', 0325 }, { '~', 'o', 0365 },
1118 { '"', 'O', 0326 }, { '"', 'o', 0366 },
1119 { '/', 'O', 0330 }, { '/', 'o', 0370 },
1120 { '`', 'U', 0331 }, { '`', 'u', 0371 },
1121 { '\'', 'U', 0332 }, { '\'', 'u', 0372 },
1122 { '^', 'U', 0333 }, { '^', 'u', 0373 },
1123 { '"', 'U', 0334 }, { '"', 'u', 0374 },
1124 { '\'', 'Y', 0335 }, { '\'', 'y', 0375 },
1125 { 'T', 'H', 0336 }, { 't', 'h', 0376 },
1126 { 's', 's', 0337 }, { '"', 'y', 0377 },
1127 { 's', 'z', 0337 }, { 'i', 'j', 0377 }
1130 for(i=0; i<68; i++) {
1131 struct ccc p = def_latin1_composes[i];
1132 compose(p.c1, p.c2, p.c3);
1141 static char *modifiers[8] = {
1142 "shift", "altgr", "ctrl", "alt", "shl", "shr", "ctl", "ctr"
1145 static char *mk_mapname(char mod) {
1146 static char buf[60];
1156 strcat(buf, modifiers[i]);
1163 outchar (unsigned char c, int comma) {
1165 printf((c == '\'' || c == '\\') ? "\\%c" : isgraph(c) ? "%c"
1167 printf(comma ? "', " : "'");
1176 unsigned int keymap_count = 0;
1179 /* not to be translated... */
1180 "/* Do not edit this file! It was automatically generated by */\n");
1182 "/* loadkeys --mktable defkeymap.map > defkeymap.c */\n\n");
1183 printf("#include <linux/types.h>\n");
1184 printf("#include <linux/keyboard.h>\n");
1185 printf("#include <linux/kd.h>\n\n");
1187 for (i = 0; i < MAX_NR_KEYMAPS; i++)
1192 printf("u_short %s_map[NR_KEYS] = {", mk_mapname(i));
1193 for (j = 0; j < NR_KEYS; j++) {
1196 printf("\t0x%04x,", U((key_map[i])[j]));
1201 for (imax = MAX_NR_KEYMAPS-1; imax > 0; imax--)
1204 printf("ushort *key_maps[MAX_NR_KEYMAPS] = {");
1205 for (i = 0; i <= imax; i++) {
1206 printf((i%4) ? " " : "\n\t");
1208 printf("%s_map,", mk_mapname(i));
1212 if (imax < MAX_NR_KEYMAPS-1)
1214 printf("\n};\n\nunsigned int keymap_count = %d;\n\n", keymap_count);
1216 /* uglified just for xgettext - it complains about nonterminated strings */
1219 " * Philosophy: most people do not define more strings, but they who do\n"
1220 " * often want quite a lot of string space. So, we statically allocate\n"
1221 " * the default and allocate dynamically in chunks of 512 bytes.\n"
1224 for (maxfunc = MAX_NR_FUNC; maxfunc; maxfunc--)
1225 if(func_table[maxfunc-1])
1228 printf("char func_buf[] = {\n");
1229 for (i = 0; i < maxfunc; i++) {
1243 "char *funcbufptr = func_buf;\n"
1244 "int funcbufsize = sizeof(func_buf);\n"
1245 "int funcbufleft = 0; /* space left */\n"
1248 printf("char *func_table[MAX_NR_FUNC] = {\n");
1249 for (i = 0; i < maxfunc; i++) {
1251 printf("\tfunc_buf + %d,\n", func_table[i] - func_buf);
1255 if (maxfunc < MAX_NR_FUNC)
1259 printf("\nstruct kbdiacr accent_table[MAX_DIACR] = {\n");
1260 for (i = 0; i < accent_table_size; i++) {
1262 outchar(accent_table[i].diacr, 1);
1263 outchar(accent_table[i].base, 1);
1264 outchar(accent_table[i].result, 0);
1266 if(i%2) printf("\n");
1268 if(i%2) printf("\n");
1270 printf("unsigned int accent_table_size = %d;\n",
1281 char flag, magic[] = "bkeymap";
1284 if (write(1, magic, 7) == -1)
1286 for (i = 0; i < MAX_NR_KEYMAPS; i++) {
1287 flag = key_map[i] ? 1 : 0;
1288 if (write(1, &flag, 1) == -1)
1291 for (i = 0; i < MAX_NR_KEYMAPS; i++) {
1293 for (j = 0; j < NR_KEYS / 2; j++) {
1295 if (write(1, &v, 2) == -1)
1301 fail: fprintf(stderr, _("Error writing map to file\n"));