*/
%token EOL NUMBER LITERAL CHARSET KEYMAPS KEYCODE EQUALS
-%token PLAIN SHIFT CONTROL ALT ALTGR SHIFTL SHIFTR CTRLL CTRLR
+%token PLAIN SHIFT CONTROL ALT ALTGR SHIFTL SHIFTR CTRLL CTRLR CAPSSHIFT
%token COMMA DASH STRING STRLITERAL COMPOSE TO CCHAR ERROR PLUS
%token UNUMBER ALT_IS_META STRINGS AS USUAL ON FOR
/* the kernel structures we want to set or print */
u_short *key_map[MAX_NR_KEYMAPS];
char *func_table[MAX_NR_FUNC];
-struct kbdiacr accent_table[MAX_DIACR];
+#ifdef KDSKBDIACRUC
+typedef struct kbdiacruc accent_entry;
+#else
+typedef struct kbdiacr accent_entry;
+#endif
+accent_entry accent_table[MAX_DIACR];
unsigned int accent_table_size = 0;
char key_is_constant[NR_KEYS];
static void compose(int diacr, int base, int res);
static void do_constant(void);
static void do_constant_key (int, u_short);
-static void loadkeys(char *console, int *warned);
+static void loadkeys(char *console);
static void mktable(void);
+static void bkeymap(void);
static void strings_as_usual(void);
/* static void keypad_as_usual(char *keyboard); */
/* static void function_keys_as_usual(char *keyboard); */
static void compose_as_usual(char *charset);
static void lkfatal0(const char *, int);
extern int set_charset(const char *charset);
+extern int prefer_unicode;
extern char *xstrdup(char *);
int key_buf[MAX_NR_KEYMAPS];
int mod;
-extern int unicode_used;
int private_error_ct = 0;
extern int rvalct;
int yyerror(const char *s);
extern void lkfatal(const char *s);
extern void lkfatal1(const char *s, const char *s2);
+void lk_push(void);
+int lk_pop(void);
+void lk_scan_string(char *s);
+void lk_end_string(void);
+
+FILE *find_incl_file_near_fn(char *s, char *fn);
+FILE *find_standard_incl_file(char *s);
+FILE *find_incl_file(char *s);
#include "ksyms.h"
int yylex (void);
| SHIFTR { mod |= M_SHIFTR; }
| CTRLL { mod |= M_CTRLL; }
| CTRLR { mod |= M_CTRLR; }
+ | CAPSSHIFT { mod |= M_CAPSSHIFT; }
;
fullline : KEYCODE NUMBER EQUALS rvalue0 EOL
{
rvalue1 : rvalue
{
if (rvalct >= MAX_NR_KEYMAPS)
- lkfatal(_("too many keydefinitions on one line"));
+ lkfatal(_("too many key definitions on one line"));
key_buf[rvalct++] = $1;
}
;
rvalue : NUMBER
- {$$=$1;}
- | UNUMBER
- {$$=($1 ^ 0xf000); unicode_used=1;}
+ {$$=convert_code($1, TO_AUTO);}
| PLUS NUMBER
{$$=add_capslock($2);}
+ | UNUMBER
+ {$$=convert_code($1^0xf000, TO_AUTO);}
+ | PLUS UNUMBER
+ {$$=add_capslock($2^0xf000);}
| LITERAL
{$$=$1;}
| PLUS LITERAL
#include "analyze.c"
-void
+static void attr_noreturn
usage(void) {
fprintf(stderr, _("loadkeys version %s\n"
"\n"
"Usage: loadkeys [option...] [mapfile...]\n"
"\n"
-"valid options are:\n"
+"Valid options are:\n"
"\n"
-" -c --clearcompose clear kernel compose table\n"
-" -C <cons1,cons2,...>\n"
-" --console=<...> Indicate console device(s) to be used.\n"
-" -d --default load \"" DEFMAP "\"\n"
-" -h --help display this help text\n"
-" -m --mktable output a \"defkeymap.c\" to stdout\n"
-" -s --clearstrings clear kernel string table\n"
-" -u --unicode implicit conversion to Unicode\n"
-" -v --verbose report the changes\n"), VERSION);
+" -b --bkeymap output a binary keymap to stdout\n"
+" -c --clearcompose clear kernel compose table\n"
+" -C <cons1,cons2,...> --console=<cons1,cons2,...>\n"
+" the console device(s) to be used\n"
+" -d --default load \"%s\"\n"
+" -h --help display this help text\n"
+" -m --mktable output a \"defkeymap.c\" to stdout\n"
+" -s --clearstrings clear kernel string table\n"
+" -u --unicode force conversion to Unicode\n"
+" -v --verbose report the changes\n"), PACKAGE_VERSION, DEFMAP);
exit(1);
}
char **args;
+int optb = 0;
int optd = 0;
int optm = 0;
int opts = 0;
int
main(int argc, char *argv[]) {
- const char *short_opts = "cC:dhmsuqvV";
+ const char *short_opts = "bcC:dhmsuqvV";
const struct option long_opts[] = {
+ { "bkeymap", no_argument, NULL, 'b' },
{ "clearcompose", no_argument, NULL, 'c' },
{ "console", 1, NULL, 'C' },
{ "default", no_argument, NULL, 'd' },
{ NULL, 0, NULL, 0 }
};
int c;
+ int fd;
+ int mode;
char *console = NULL;
- int warned = 0;
set_progname(argv[0]);
+#ifndef __klibc__
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE_NAME, LOCALEDIR);
+ textdomain(PACKAGE_NAME);
+#endif
while ((c = getopt_long(argc, argv,
short_opts, long_opts, NULL)) != -1) {
switch (c) {
+ case 'b':
+ optb = 1;
+ break;
case 'c':
nocompose = 1;
break;
opts = 1;
break;
case 'u':
- set_charset("unicode");
+ prefer_unicode = 1;
break;
case 'q':
quiet = 1;
}
}
+ if (!optm && !prefer_unicode) {
+ /* no -u option: auto-enable it if console is in Unicode mode */
+ fd = getfd(NULL);
+ if (ioctl(fd, KDGKBMODE, &mode)) {
+ perror("KDGKBMODE");
+ fprintf(stderr, _("loadkeys: error reading keyboard mode\n"));
+ exit(1);
+ }
+ if (mode == K_UNICODE)
+ prefer_unicode = 1;
+ close(fd);
+ }
+
args = argv + optind - 1;
- unicode_used = 0;
yywrap(); /* set up the first input file, if any */
if (yyparse() || private_error_ct) {
fprintf(stderr, _("syntax error in map file\n"));
exit(1);
}
do_constant();
- if(optm)
+ if(optb) {
+ bkeymap();
+ } else if(optm) {
mktable();
- else if (console)
+ } else if (console)
{
char *buf = strdup(console); /* make writable */
char *e, *s = buf;
while ( *s == ' ' || *s == '\t' || *s == ',') s++;
e = s;
while (*e && *e != ' ' && *e != '\t' && *e != ',') e++;
- char c = *e;
+ char ch = *e;
*e = '\0';
if (verbose) printf("%s\n", s);
- loadkeys(s, &warned);
- *e = c;
+ loadkeys(s);
+ *e = ch;
s = e;
}
free(buf);
}
else
- loadkeys(NULL, &warned);
+ loadkeys(NULL);
exit(0);
}
}
/* fatal errors - change to varargs next time */
-void
+void attr_noreturn
lkfatal(const char *s) {
fprintf(stderr, "%s: %s:%d: %s\n", progname, filename, line_nr, s);
exit(1);
}
-void
+void attr_noreturn
lkfatal0(const char *s, int d) {
fprintf(stderr, "%s: %s:%d: ", progname, filename, line_nr);
fprintf(stderr, s, d);
exit(1);
}
-void
+void attr_noreturn
lkfatal1(const char *s, const char *s2) {
fprintf(stderr, "%s: %s:%d: ", progname, filename, line_nr);
fprintf(stderr, s, s2);
void
lk_push(void) {
if (infile_stack_ptr >= MAX_INCLUDE_DEPTH)
- lkfatal(_("includes nested too deeply"));
+ lkfatal(_("includes are nested too deeply"));
/* preserve current state */
infile_stack[infile_stack_ptr].filename = filename;
/* If filename is a symlink, also look near its target. */
if (!f) {
- char buf[1024], path[1024], *p;
- int n;
+ char buf[1024], path[1024], *ptr;
+ unsigned int n;
n = readlink(filename, buf, sizeof(buf));
if (n > 0 && n < sizeof(buf)) {
else if (strlen(filename) + n < sizeof(path)) {
strcpy(path, filename);
path[sizeof(path)-1] = 0;
- p = rindex(path, '/');
- if (p)
- p[1] = 0;
+ ptr = rindex(path, '/');
+ if (ptr)
+ ptr[1] = 0;
strcat(path, buf);
f = find_incl_file_near_fn(s, path);
}
/* unset a key */
static void
-killkey(int index, int table) {
- /* roughly: addkey(index, table, K_HOLE); */
-
- if (index < 0 || index >= NR_KEYS)
- lkfatal0(_("killkey called with bad index %d"), index);
- if (table < 0 || table >= MAX_NR_KEYMAPS)
- lkfatal0(_("killkey called with bad table %d"), table);
- if (key_map[table])
- (key_map[table])[index] = K_HOLE;
- if (keymap_was_set[table])
- (keymap_was_set[table])[index] = 0;
+killkey(int k_index, int k_table) {
+ /* roughly: addkey(k_index, k_table, K_HOLE); */
+
+ if (k_index < 0 || k_index >= NR_KEYS)
+ lkfatal0(_("killkey called with bad index %d"), k_index);
+ if (k_table < 0 || k_table >= MAX_NR_KEYMAPS)
+ lkfatal0(_("killkey called with bad table %d"), k_table);
+ if (key_map[k_table])
+ (key_map[k_table])[k_index] = K_HOLE;
+ if (keymap_was_set[k_table])
+ (keymap_was_set[k_table])[k_index] = 0;
}
static void
-addkey(int index, int table, int keycode) {
+addkey(int k_index, int k_table, int keycode) {
int i;
if (keycode == CODE_FOR_UNKNOWN_KSYM)
/* is safer not to be silent in this case,
* it can be caused by coding errors as well. */
lkfatal0(_("addkey called with bad keycode %d"), keycode);
- if (index < 0 || index >= NR_KEYS)
- lkfatal0(_("addkey called with bad index %d"), index);
- if (table < 0 || table >= MAX_NR_KEYMAPS)
- lkfatal0(_("addkey called with bad table %d"), table);
-
- if (!defining[table])
- addmap(table, 0);
- if (!key_map[table]) {
- key_map[table] = (u_short *)xmalloc(NR_KEYS * sizeof(u_short));
+ if (k_index < 0 || k_index >= NR_KEYS)
+ lkfatal0(_("addkey called with bad index %d"), k_index);
+ if (k_table < 0 || k_table >= MAX_NR_KEYMAPS)
+ lkfatal0(_("addkey called with bad table %d"), k_table);
+
+ if (!defining[k_table])
+ addmap(k_table, 0);
+ if (!key_map[k_table]) {
+ key_map[k_table] = (u_short *)xmalloc(NR_KEYS * sizeof(u_short));
for (i = 0; i < NR_KEYS; i++)
- (key_map[table])[i] = K_HOLE;
+ (key_map[k_table])[i] = K_HOLE;
}
- if (!keymap_was_set[table]) {
- keymap_was_set[table] = (char *) xmalloc(NR_KEYS);
+ if (!keymap_was_set[k_table]) {
+ keymap_was_set[k_table] = (char *) xmalloc(NR_KEYS);
for (i = 0; i < NR_KEYS; i++)
- (keymap_was_set[table])[i] = 0;
+ (keymap_was_set[k_table])[i] = 0;
}
- if (alt_is_meta && keycode == K_HOLE && (keymap_was_set[table])[index])
+ if (alt_is_meta && keycode == K_HOLE && (keymap_was_set[k_table])[k_index])
return;
- (key_map[table])[index] = keycode;
- (keymap_was_set[table])[index] = 1;
+ (key_map[k_table])[k_index] = keycode;
+ (keymap_was_set[k_table])[k_index] = 1;
if (alt_is_meta) {
- int alttable = table | M_ALT;
+ int alttable = k_table | M_ALT;
int type = KTYP(keycode);
int val = KVAL(keycode);
- if (alttable != table && defining[alttable] &&
+ if (alttable != k_table && defining[alttable] &&
(!keymap_was_set[alttable] ||
- !(keymap_was_set[alttable])[index]) &&
+ !(keymap_was_set[alttable])[k_index]) &&
(type == KT_LATIN || type == KT_LETTER) && val < 128)
- addkey(index, alttable, K(KT_META, val));
+ addkey(k_index, alttable, K(KT_META, val));
}
}
static void
addfunc(struct kbsentry kbs) {
int sh, i, x;
- char *p, *q, *r;
+ char *ptr, *q, *r;
x = kbs.kb_func;
q = func_table[x];
if (q) { /* throw out old previous def */
sh = strlen(q) + 1;
- p = q + sh;
- while (p < fp)
- *q++ = *p++;
+ ptr = q + sh;
+ while (ptr < fp)
+ *q++ = *ptr++;
fp -= sh;
for (i = x + 1; i < MAX_NR_FUNC; i++)
func_table[i] -= sh;
}
- p = func_buf; /* find place for new def */
+ ptr = func_buf; /* find place for new def */
for (i = 0; i < x; i++)
if (func_table[i]) {
- p = func_table[i];
- while(*p++);
+ ptr = func_table[i];
+ while(*ptr++);
}
- func_table[x] = p;
+ func_table[x] = ptr;
sh = strlen((char *) kbs.kb_string) + 1;
if (fp + sh > func_buf + sizeof(func_buf)) {
fprintf(stderr,
q = fp;
fp += sh;
r = fp;
- while (q > p)
+ while (q > ptr)
*--r = *--q;
- strcpy(p, (char *) kbs.kb_string);
+ strcpy(ptr, (char *) kbs.kb_string);
for (i = x + 1; i < MAX_NR_FUNC; i++)
if (func_table[i])
func_table[i] += sh;
static void
compose(int diacr, int base, int res) {
- struct kbdiacr *p;
+ accent_entry *ptr;
+ int direction;
+
+#ifdef KDSKBDIACRUC
+ if (prefer_unicode)
+ direction = TO_UNICODE;
+ else
+#endif
+ direction = TO_8BIT;
+
if (accent_table_size == MAX_DIACR) {
fprintf(stderr, _("compose table overflow\n"));
exit(1);
}
- p = &accent_table[accent_table_size++];
- p->diacr = diacr;
- p->base = base;
- p->result = res;
+ ptr = &accent_table[accent_table_size++];
+ ptr->diacr = convert_code(diacr, direction);
+ ptr->base = convert_code(base, direction);
+ ptr->result = convert_code(res, direction);
}
static int
-defkeys(int fd, char *cons, int *warned) {
+defkeys(int fd) {
struct kbentry ke;
int ct = 0;
int i,j,fail;
- int oldm;
-
- if (unicode_used) {
- /* Switch keyboard mode for a moment -
- do not complain about errors.
- Do not attempt a reset if the change failed. */
- if (ioctl(fd, KDGKBMODE, &oldm)
- || (oldm != K_UNICODE && ioctl(fd, KDSKBMODE, K_UNICODE)))
- oldm = K_UNICODE;
- }
for(i=0; i<MAX_NR_KEYMAPS; i++) {
if (key_map[i]) {
} else
ct++;
if(verbose)
- printf("keycode %d, table %d = %d%s\n", j, i,
+ printf(_("keycode %d, table %d = %d%s\n"), j, i,
(key_map[i])[j], fail ? _(" FAILED") : "");
else if (fail)
fprintf(stderr,
}
}
- if(unicode_used && oldm != K_UNICODE) {
- if (ioctl(fd, KDSKBMODE, oldm)) {
- fprintf(stderr, _("%s: failed to restore keyboard mode\n"),
- progname);
- }
-
- if (!warned++)
- {
- int kd_mode = -1;
- if (ioctl(fd, KDGETMODE, &kd_mode) || (kd_mode != KD_GRAPHICS))
- {
- /*
- * It is okay for the graphics console to have a non-unicode mode.
- * only talk about other consoles
- */
- fprintf(stderr, _("%s: warning: this map uses Unicode symbols, %s mode=%d\n"
- " (perhaps you want to do `kbd_mode -u'?)\n"),
- progname, cons ? cons : "NULL", kd_mode);
- }
- }
- }
return ct;
}
static int
deffuncs(int fd){
int i, ct = 0;
- char *p;
+ char *ptr;
for (i = 0; i < MAX_NR_FUNC; i++) {
kbs_buf.kb_func = i;
- if ((p = func_table[i])) {
- strcpy((char *) kbs_buf.kb_string, p);
+ if ((ptr = func_table[i])) {
+ strcpy((char *) kbs_buf.kb_string, ptr);
if (ioctl(fd, KDSKBSENT, (unsigned long)&kbs_buf))
fprintf(stderr, _("failed to bind string '%s' to function %s\n"),
- ostr(kbs_buf.kb_string), syms[KT_FN].table[kbs_buf.kb_func]);
+ ostr((char *) kbs_buf.kb_string), syms[KT_FN].table[kbs_buf.kb_func]);
else
ct++;
} else if (opts) {
static int
defdiacs(int fd){
- struct kbdiacrs kd;
- int i;
+ unsigned int i, count;
+ struct kbdiacrs kd;
+#ifdef KDSKBDIACRUC
+ struct kbdiacrsuc kdu;
+#endif
- kd.kb_cnt = accent_table_size;
- if (kd.kb_cnt > MAX_DIACR) {
- kd.kb_cnt = MAX_DIACR;
+ count = accent_table_size;
+ if (count > MAX_DIACR) {
+ count = MAX_DIACR;
fprintf(stderr, _("too many compose definitions\n"));
}
- for (i = 0; i < kd.kb_cnt; i++)
- kd.kbdiacr[i] = accent_table[i];
- if(ioctl(fd, KDSKBDIACR, (unsigned long) &kd)) {
- perror("KDSKBDIACR");
- exit(1);
+#ifdef KDSKBDIACRUC
+ if (prefer_unicode) {
+ kdu.kb_cnt = count;
+ for (i = 0; i < kdu.kb_cnt; i++) {
+ kdu.kbdiacruc[i].diacr = accent_table[i].diacr;
+ kdu.kbdiacruc[i].base = accent_table[i].base;
+ kdu.kbdiacruc[i].result = accent_table[i].result;
+ }
+ if(ioctl(fd, KDSKBDIACRUC, (unsigned long) &kdu)) {
+ perror("KDSKBDIACRUC");
+ exit(1);
+ }
}
+ else
+#endif
+ {
+ kd.kb_cnt = count;
+ for (i = 0; i < kd.kb_cnt; i++) {
+ kd.kbdiacr[i].diacr = accent_table[i].diacr;
+ kd.kbdiacr[i].base = accent_table[i].base;
+ kd.kbdiacr[i].result = accent_table[i].result;
+ }
+ if(ioctl(fd, KDSKBDIACR, (unsigned long) &kd)) {
+ perror("KDSKBDIACR");
+ exit(1);
+ }
+ }
+
return kd.kb_cnt;
}
}
static void
-loadkeys (char *console, int *warned) {
+loadkeys (char *console) {
int fd;
int keyct, funcct, diacct = 0;
fd = getfd(console);
- keyct = defkeys(fd, console, warned);
+ keyct = defkeys(fd);
funcct = deffuncs(fd);
if (verbose) {
printf(_("\nChanged %d %s and %d %s.\n"),
};
int i;
for(i=0; i<68; i++) {
- struct ccc p = def_latin1_composes[i];
- compose(p.c1, p.c2, p.c3);
+ struct ccc ptr = def_latin1_composes[i];
+ compose(ptr.c1, ptr.c2, ptr.c3);
}
}
}
"shift", "altgr", "ctrl", "alt", "shl", "shr", "ctl", "ctr"
};
-static char *mk_mapname(char mod) {
+static char *mk_mapname(char modifier) {
static char buf[60];
int i;
- if (!mod)
+ if (!modifier)
return "plain";
buf[0] = 0;
for (i=0; i<8; i++)
- if (mod & (1<<i)) {
+ if (modifier & (1<<i)) {
if (buf[0])
strcat(buf, "_");
strcat(buf, modifiers[i]);
printf(comma ? "', " : "'");
}
-static void
+static void attr_noreturn
mktable () {
- int i, imax, j;
+ int j;
+ unsigned int i, imax;
- u_char *p;
- int maxfunc;
+ char *ptr;
+ unsigned int maxfunc;
unsigned int keymap_count = 0;
printf(
printf("char func_buf[] = {\n");
for (i = 0; i < maxfunc; i++) {
- p = func_table[i];
- if (p) {
+ ptr = func_table[i];
+ if (ptr) {
printf("\t");
- for ( ; *p; p++)
- outchar(*p, 1);
+ for ( ; *ptr; ptr++)
+ outchar(*ptr, 1);
printf("0, \n");
}
}
printf("char *func_table[MAX_NR_FUNC] = {\n");
for (i = 0; i < maxfunc; i++) {
if (func_table[i])
- printf("\tfunc_buf + %d,\n", func_table[i] - func_buf);
+ printf("\tfunc_buf + %ld,\n", (long) (func_table[i] - func_buf));
else
printf("\t0,\n");
}
printf("\t0,\n");
printf("};\n");
- printf("\nstruct kbdiacr accent_table[MAX_DIACR] = {\n");
- for (i = 0; i < accent_table_size; i++) {
- printf("\t{");
- outchar(accent_table[i].diacr, 1);
- outchar(accent_table[i].base, 1);
- outchar(accent_table[i].result, 0);
- printf("},");
+#ifdef KDSKBDIACRUC
+ if (prefer_unicode) {
+ printf("\nstruct kbdiacruc accent_table[MAX_DIACR] = {\n");
+ for (i = 0; i < accent_table_size; i++) {
+ printf("\t{");
+ outchar(accent_table[i].diacr, 1);
+ outchar(accent_table[i].base, 1);
+ printf("0x%04x},", accent_table[i].result);
+ if(i%2) printf("\n");
+ }
if(i%2) printf("\n");
+ printf("};\n\n");
+ }
+ else
+#endif
+ {
+ printf("\nstruct kbdiacr accent_table[MAX_DIACR] = {\n");
+ for (i = 0; i < accent_table_size; i++) {
+ printf("\t{");
+ outchar(accent_table[i].diacr, 1);
+ outchar(accent_table[i].base, 1);
+ outchar(accent_table[i].result, 0);
+ printf("},");
+ if(i%2) printf("\n");
+ }
+ if(i%2) printf("\n");
+ printf("};\n\n");
}
- if(i%2) printf("\n");
- printf("};\n\n");
printf("unsigned int accent_table_size = %d;\n",
accent_table_size);
exit(0);
}
+
+static void attr_noreturn
+bkeymap () {
+ int i, j;
+
+ //u_char *p;
+ char flag, magic[] = "bkeymap";
+ unsigned short v;
+
+ if (write(1, magic, 7) == -1)
+ goto fail;
+ for (i = 0; i < MAX_NR_KEYMAPS; i++) {
+ flag = key_map[i] ? 1 : 0;
+ if (write(1, &flag, 1) == -1)
+ goto fail;
+ }
+ for (i = 0; i < MAX_NR_KEYMAPS; i++) {
+ if (key_map[i]) {
+ for (j = 0; j < NR_KEYS / 2; j++) {
+ v = key_map[i][j];
+ if (write(1, &v, 2) == -1)
+ goto fail;
+ }
+ }
+ }
+ exit(0);
+fail: fprintf(stderr, _("Error writing map to file\n"));
+ exit(1);
+}