] [
.I -s --clearstrings
] [
+.I -u --unicode
+] [
.I -v --verbose
] [
.I filename...
keymap as expected by Busybox
.B loadkmap
command (and does not modify the current keymap).
+.SH "UNICODE MODE"
+.B loadkeys
+automatically detects whether the console is in Unicode or
+ASCII (XLATE) mode. When a keymap is loaded, literal
+keysyms (such as
+.BR section )
+are resolved accordingly; numerical keysyms are converted to
+fit the current console mode, regardless of the way they are
+specified (decimal, octal, hexadecimal or Unicode).
+.LP
+The
+.I -u
+(or
+.IR --unicode )
+switch tells
+.B loadkeys
+to bypass the check and assume that the console is in Unicode mode.
.SH "OTHER OPTIONS"
.TP
.B \-h \-\-help
t = KTYP(code);
v = KVAL(code);
if (t >= syms_size) {
- code = code ^ 0xf000;
- if (!numeric && (p = unicodetoksym(code)) != NULL)
+ if (!numeric && (p = codetoksym(code)) != NULL)
printf("%-16s", p);
else
- printf("U+%04x ", code);
+ printf("U+%04x ", code ^ 0xf000);
return;
}
plus = 0;
/* Functions for both dumpkeys and loadkeys. */
-static int prefer_unicode = 0;
+int prefer_unicode = 0;
static const char *chosen_charset = NULL;
void
sym *p;
unsigned int i;
- if (!strcasecmp(charset, "unicode")) {
- prefer_unicode = 1;
- return 0;
- }
-
for (i = 1; i < sizeof(charsets)/sizeof(charsets[0]); i++) {
if (!strcasecmp(charsets[i].charset, charset)) {
charsets[0].charset = charsets[i].charset;
if(p->name[0])
syms[0].table[i] = p->name;
}
- chosen_charset = charset;
+ chosen_charset = strdup(charset);
return 0;
}
}
}
const char *
-unicodetoksym(int code) {
+codetoksym(int code) {
unsigned int i;
int j;
sym *p;
if (code < 0)
return NULL;
- if (code < 0x80)
- return iso646_syms[code];
- for (i = 0; i < sizeof(charsets)/sizeof(charsets[0]); i++) {
- p = charsets[i].charnames;
- for (j = charsets[i].start; j < 256; j++, p++) {
- if (p->uni == code && p->name[0])
+
+ if (code < 0x1000) { /* "traditional" keysym */
+ if (KTYP(code) == KT_META)
+ return NULL;
+ if (KTYP(code) == KT_LETTER)
+ code = K(KT_LATIN, KVAL(code));
+ if (KTYP(code) > KT_LATIN)
+ return syms[KTYP(code)].table[KVAL(code)];
+
+ for (i = 0; i < sizeof(charsets)/sizeof(charsets[0]); i++) {
+ p = charsets[i].charnames;
+ if (!p)
+ continue;
+ p += KVAL(code) - charsets[i].start;
+ if (p->name[0])
return p->name;
}
}
+
+ else { /* Unicode keysym */
+ code ^= 0xf000;
+
+ if (code < 0x80)
+ return iso646_syms[code];
+
+ for (i = 0; i < sizeof(charsets)/sizeof(charsets[0]); i++) {
+ p = charsets[i].charnames;
+ if (!p)
+ continue;
+ for (j = charsets[i].start; j < 256; j++, p++) {
+ if (p->uni == code && p->name[0])
+ return p->name;
+ }
+ }
+ }
+
return NULL;
}
/* Functions for loadkeys. */
-int unicode_used = 0;
-
int
ksymtocode(const char *s) {
unsigned int i;
int j, jmax;
int keycode;
sym *p;
+ int save_prefer_unicode;
if (!strncmp(s, "Meta_", 5)) {
+ save_prefer_unicode = prefer_unicode;
+ prefer_unicode = 0;
keycode = ksymtocode(s+5);
+ prefer_unicode = save_prefer_unicode;
if (KTYP(keycode) == KT_LATIN)
return K(KT_META, KVAL(keycode));
for (i = 0; i < sizeof(charsets)/sizeof(charsets[0]); i++) {
p = charsets[i].charnames;
for (j = charsets[i].start; j < 256; j++, p++)
- if (!strcmp(s,p->name)) {
- unicode_used = 1;
- return (p->uni ^ 0xf000); /* %%% */
- }
+ if (!strcmp(s,p->name))
+ return (p->uni ^ 0xf000);
}
} else /* if (!chosen_charset) */ {
/* note: some keymaps use latin1 but with euro,
}
int
-unicodetocode(int code) {
- const char *s;
-
- s = unicodetoksym(code);
- if (s)
- return ksymtocode(s);
- else {
- unicode_used = 1;
- return (code ^ 0xf000); /* %%% */
- }
+convert_code(int code)
+{
+ const char *ksym;
+
+ if (KTYP(code) == KT_META)
+ return code;
+ else if (prefer_unicode == (code >= 0x1000))
+ return code; /* no conversion necessary */
+
+ /* depending on prefer_unicode, this will give us either an 8-bit
+ * K(KTYP, KVAL) or a Unicode keysym xor 0xf000 */
+ ksym = codetoksym(code);
+ if (ksym)
+ return ksymtocode(ksym);
+ else
+ return code;
}
int
add_capslock(int code)
{
- char buf[7];
- const char *p;
-
- if (KTYP(code) == KT_LATIN)
+ if (KTYP(code) == KT_LATIN && (!prefer_unicode || code < 0x80))
return K(KT_LETTER, KVAL(code));
- if ((unsigned) KTYP(code) >= syms_size) {
- if ((p = unicodetoksym(code ^ 0xf000)) == NULL) {
- sprintf(buf, "U+%04x", code ^ 0xf000);
- p = buf;
- }
- } else {
- sprintf(buf, "0x%04x", code);
- p = buf;
- }
-#if 0
- /* silence the common usage dumpkeys | loadkeys -u */
- fprintf(stderr, _("plus before %s ignored\n"), p);
-#endif
- return code;
+ else if ((code ^ 0xf000) < 0x100)
+ /* Unicode Latin-1 Supplement */
+ /* a bit dirty to use KT_LETTER here, but it should work */
+ return K(KT_LETTER, code ^ 0xf000);
+ else
+ return convert_code(code);
}
#define CODE_FOR_UNKNOWN_KSYM (-1)
extern int set_charset(const char *name);
-extern const char *unicodetoksym(int code);
+extern const char *codetoksym(int code);
extern void list_charsets(FILE *f);
extern int ksymtocode(const char *s);
-extern int unicodetocode(int code);
+extern int convert_code(int code);
extern int add_capslock(int code);
#endif
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 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;
}
;
rvalue : NUMBER
- {$$=$1;}
- | UNUMBER
- {$$=($1 ^ 0xf000); unicode_used=1;}
+ {$$=convert_code($1);}
| PLUS NUMBER
{$$=add_capslock($2);}
+ | UNUMBER
+ {$$=convert_code($1^0xf000);}
+ | PLUS UNUMBER
+ {$$=add_capslock($2^0xf000);}
| LITERAL
{$$=$1;}
| PLUS LITERAL
" -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"
+" -u --unicode force conversion to Unicode\n"
" -v --verbose report the changes\n"), PACKAGE_VERSION, DEFMAP);
exit(1);
}
{ NULL, 0, NULL, 0 }
};
int c;
+ int fd;
+ int mode;
char *console = NULL;
- int warned = 0;
set_progname(argv[0]);
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"));
char ch = *e;
*e = '\0';
if (verbose) printf("%s\n", s);
- loadkeys(s, &warned);
+ loadkeys(s);
*e = ch;
s = e;
}
free(buf);
}
else
- loadkeys(NULL, &warned);
+ loadkeys(NULL);
exit(0);
}
}
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]) {
}
}
- 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 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"),