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.
18 #include <sys/ioctl.h>
20 #include "../config.h"
28 static const char *progname = NULL;
29 static const char *const dirpath1[] = { "", DATADIR "/" KEYMAPDIR "/**", KERNDIR "/", 0 };
30 static const char *const suffixes[] = { "", ".kmap", ".map", 0 };
32 static void __attribute__ ((noreturn))
35 fprintf(stderr, _("loadkeys version %s\n"
37 "Usage: %s [option...] [mapfile...]\n"
39 "Valid options are:\n"
41 " -a --ascii force conversion to ASCII\n"
42 " -b --bkeymap output a binary keymap to stdout\n"
43 " -c --clearcompose clear kernel compose table\n"
44 " -C --console=file\n"
45 " the console device to be used\n"
46 " -d --default load \"%s\"\n"
47 " -h --help display this help text\n"
48 " -m --mktable output a \"defkeymap.c\" to stdout\n"
49 " -q --quiet suppress all normal output\n"
50 " -s --clearstrings clear kernel string table\n"
51 " -u --unicode force conversion to Unicode\n"
52 " -v --verbose report the changes\n"),
53 PACKAGE_VERSION, progname, DEFMAP);
57 static inline const char *
58 set_progname(const char *name)
61 p = strrchr(name, '/');
62 return (p && p + 1 ? p + 1 : name);
66 main(int argc, char *argv[])
68 const char *const short_opts = "abcC:dhmsuqvV";
69 const struct option const long_opts[] = {
70 { "console", required_argument, NULL, 'C'},
71 { "ascii", no_argument, NULL, 'a' },
72 { "bkeymap", no_argument, NULL, 'b' },
73 { "clearcompose", no_argument, NULL, 'c' },
74 { "default", no_argument, NULL, 'd' },
75 { "help", no_argument, NULL, 'h' },
76 { "mktable", no_argument, NULL, 'm' },
77 { "clearstrings", no_argument, NULL, 's' },
78 { "unicode", no_argument, NULL, 'u' },
79 { "quiet", no_argument, NULL, 'q' },
80 { "verbose", no_argument, NULL, 'v' },
81 { "version", no_argument, NULL, 'V' },
94 const char *const *dirpath;
95 const char *dirpath2[] = { 0, 0 };
104 char *console = NULL;
108 setlocale(LC_ALL, "");
109 bindtextdomain(PACKAGE_NAME, LOCALEDIR);
110 textdomain(PACKAGE_NAME);
112 progname = set_progname(argv[0]);
116 while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
125 ctx.flags |= LK_FLAG_CLEAR_COMPOSE;
137 flags |= LK_FLAG_CLEAR_STRINGS;
141 flags |= LK_FLAG_UNICODE_MODE;
142 flags |= LK_FLAG_PREFER_UNICODE;
145 lk_set_log_priority(&ctx, LOG_ERR);
148 lk_set_log_priority(&ctx, LOG_INFO);
151 fprintf(stdout, _("%s from %s\n"), progname, PACKAGE_STRING);
159 if ((options & OPT_U) && (options & OPT_A)) {
161 _("%s: Options --unicode and --ascii are mutually exclusive\n"),
169 if (!(options & OPT_M) && !(options & OPT_B)) {
170 /* check whether the keyboard is in Unicode mode */
171 if (ioctl(fd, KDGKBMODE, &kbd_mode) ||
172 ioctl(fd, KDGETMODE, &kd_mode)) {
173 fprintf(stderr, _("%s: error reading keyboard mode: %m\n"),
178 if (kbd_mode == K_UNICODE) {
179 if (options & OPT_A) {
181 _("%s: warning: loading non-Unicode keymap on Unicode console\n"
182 " (perhaps you want to do `kbd_mode -a'?)\n"),
185 flags |= LK_FLAG_PREFER_UNICODE;
188 /* reset -u option if keyboard is in K_UNICODE anyway */
189 flags ^= LK_FLAG_UNICODE_MODE;
191 } else if (options & OPT_U && kd_mode != KD_GRAPHICS) {
193 _("%s: warning: loading Unicode keymap on non-Unicode console\n"
194 " (perhaps you want to do `kbd_mode -u'?)\n"),
199 lk_set_parser_flags(&ctx, flags);
202 if ((ev = getenv("LOADKEYS_KEYMAP_PATH")) != NULL) {
207 if (options & OPT_D) {
208 /* first read default map - search starts in . */
210 if (lk_findfile(DEFMAP, dirpath, suffixes, &f)) {
211 fprintf(stderr, _("Cannot find %s\n"), DEFMAP);
215 if ((rc = lk_parse_keymap(&ctx, &f)) == -1)
219 } else if (optind == argc) {
221 strcpy(f.pathname, "<stdin>");
223 if ((rc = lk_parse_keymap(&ctx, &f)) == -1)
227 for (i = optind; argv[i]; i++) {
228 if (!strcmp(argv[i], "-")) {
230 strcpy(f.pathname, "<stdin>");
232 } else if (lk_findfile(argv[i], dirpath, suffixes, &f)) {
233 fprintf(stderr, _("cannot open file %s\n"), argv[i]);
237 if ((rc = lk_parse_keymap(&ctx, &f)) == -1)
241 if (options & OPT_B) {
242 rc = lk_dump_bkeymap(&ctx, stdout);
243 } else if (options & OPT_M) {
244 rc = lk_dump_ctable(&ctx, stdout);
246 rc = lk_load_keymap(&ctx, fd, kbd_mode);