[kbd] [PATCH] loadkeys -u: Switch to Unicode mode, if necessary

Michael Schutte michi at uiae.at
Sun Nov 15 15:34:16 UTC 2009


Make defkeys() KDSKBMODE to K_UNICODE before it starts to do KDSKBENT
ioctls.  Switch back to the preceding keyboard mode after defining keys.

This change is introduced for compatibility reasons, see
<http://bugs.gentoo.org/289265>.  As a minor difference, the warning
message telling users to run “kbd_mode -u” is printed whenever “loadkeys
-u” is used, not only when actual Unicode keysyms are loaded.

Signed-off-by: Michael Schutte <michi at uiae.at>
---
 man/man1/loadkeys.1.in |   16 ++++++++++++-
 src/loadkeys.y         |   54 ++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 55 insertions(+), 15 deletions(-)

diff --git a/man/man1/loadkeys.1.in b/man/man1/loadkeys.1.in
index 7e168e4..e39eb76 100644
--- a/man/man1/loadkeys.1.in
+++ b/man/man1/loadkeys.1.in
@@ -160,9 +160,21 @@ The
 .I -u
 (or
 .IR --unicode )
-switch tells
+switch forces
 .B loadkeys
-to bypass the check and assume that the console is in Unicode mode.
+to convert all keymaps to Unicode.  If the keyboard is in a
+non-Unicode mode, such as XLATE,
+.B loadkeys
+will change it to Unicode for the time of its execution.  A
+warning message will be printed in this case.
+.LP
+It is recommended to run
+.BR kbd_mode (1)
+before
+.B loadkeys
+instead of using the
+.I -u
+option.
 .SH "OTHER OPTIONS"
 .TP
 .B \-h \-\-help
diff --git a/src/loadkeys.y b/src/loadkeys.y
index 6beba09..03654ac 100644
--- a/src/loadkeys.y
+++ b/src/loadkeys.y
@@ -68,7 +68,7 @@ static void killkey(int index, int table);
 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);
+static void loadkeys(char *console, int kbd_mode);
 static void mktable(void);
 static void bkeymap(void);
 static void strings_as_usual(void);
@@ -293,6 +293,7 @@ int optb = 0;
 int optd = 0;
 int optm = 0;
 int opts = 0;
+int optu = 0;
 int verbose = 0;
 int quiet = 0;
 int nocompose = 0;
@@ -316,7 +317,8 @@ main(int argc, char *argv[]) {
 	};
 	int c;
 	int fd;
-	int mode;
+	int kbd_mode;
+	int kd_mode;
 	char *console = NULL;
 
 	set_progname(argv[0]);
@@ -348,7 +350,7 @@ main(int argc, char *argv[]) {
 				opts = 1;
 				break;
 			case 'u':
-				prefer_unicode = 1;
+				optu = 1;
 				break;
 			case 'q':
 				quiet = 1;
@@ -364,16 +366,26 @@ main(int argc, char *argv[]) {
 		}
 	}
 
-	if (!optm && !prefer_unicode) {
-		/* no -u option: auto-enable it if console is in Unicode mode */
+	prefer_unicode = optu;
+	if (!optm) {
+		/* check whether the keyboard is in Unicode mode */
 		fd = getfd(NULL);
-		if (ioctl(fd, KDGKBMODE, &mode)) {
+		if (ioctl(fd, KDGKBMODE, &kbd_mode)) {
 			perror("KDGKBMODE");
-			fprintf(stderr, _("loadkeys: error reading keyboard mode\n"));
+			fprintf(stderr, _("%s: error reading keyboard mode\n"), progname);
 			exit(1);
 		}
-		if (mode == K_UNICODE)
+
+		if (kbd_mode == K_UNICODE) {
 			prefer_unicode = 1;
+			/* reset -u option if keyboard is in K_UNICODE anyway */
+			optu = 0;
+		}
+		else if (optu && (ioctl(fd, KDGETMODE, &kd_mode) || (kd_mode != KD_GRAPHICS)))
+			fprintf(stderr, _("%s: warning: loading Unicode keymap on non-Unicode console\n"
+					  "    (perhaps you want to do `kbd_mode -u'?)\n"),
+				progname);
+
 		close(fd);
 	}
 
@@ -402,14 +414,14 @@ main(int argc, char *argv[]) {
 		char ch = *e;
 		*e = '\0';
 		if (verbose) printf("%s\n", s);
-	        loadkeys(s);
+	        loadkeys(s, kbd_mode);
 		*e = ch;
 		s = e;
 	      }
 	    free(buf);
 	  }
 	else
-	  loadkeys(NULL);
+	  loadkeys(NULL, kbd_mode);
 	exit(0);
 }
 
@@ -847,11 +859,20 @@ compose(int diacr, int base, int res) {
 }
 
 static int
-defkeys(int fd) {
+defkeys(int fd, int kbd_mode) {
 	struct kbentry ke;
 	int ct = 0;
 	int i,j,fail;
 
+	if (optu) {
+		/* temporarily switch to K_UNICODE while defining keys */
+		if (ioctl(fd, KDSKBMODE, K_UNICODE)) {
+			perror("KDSKBMODE");
+			fprintf(stderr, _("%s: could not switch to Unicode mode\n"), progname);
+			exit(1);
+		}
+	}
+
 	for(i=0; i<MAX_NR_KEYMAPS; i++) {
 	    if (key_map[i]) {
 		for(j=0; j<NR_KEYS; j++) {
@@ -917,6 +938,13 @@ defkeys(int fd) {
 	    }
 	}
 
+	if (optu && ioctl(fd, KDSKBMODE, kbd_mode)) {
+		perror("KDSKBMODE");
+		fprintf(stderr, _("%s: could not return to original keyboard mode\n"),
+			progname);
+		exit(1);
+	}
+
 	return ct;
 }
 
@@ -1074,12 +1102,12 @@ do_constant (void) {
 }
 
 static void
-loadkeys (char *console) {
+loadkeys (char *console, int kbd_mode) {
         int fd;
         int keyct, funcct, diacct = 0;
 
 	fd = getfd(console);
-	keyct = defkeys(fd);
+	keyct = defkeys(fd, kbd_mode);
 	funcct = deffuncs(fd);
 	if (verbose) {
 	        printf(_("\nChanged %d %s and %d %s.\n"),
-- 
1.6.5
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 490 bytes
Desc: Digital signature
URL: <http://lists.altlinux.org/pipermail/kbd/attachments/20091115/1f9b24c8/attachment-0001.bin>


More information about the kbd mailing list