Commit Diff


commit - 4f52e8afe9e41647cd1742c6fff47ed928ff6c1c
commit + b567422f98b815a45fa8e7144057a8834e98616b
blob - ef372a2d1c0d3a8eca18645b8315a9fb2a986df0
blob + bc7cb5afb507137175c26c4639d37447643c8feb
--- man/man7/keyboard.7
+++ man/man7/keyboard.7
@@ -171,6 +171,57 @@ yields £.
 .PP
 Note the difference between ß (ss) and µ (micron) and
 the Greek β and μ.
+.SS "X WINDOWS
+Under X Windows, both the Alt key and the ``Multi key''
+can begin a compose sequence in a Plan 9 program.
+.PP
+It is also possible to configure X Windows to use the
+same keystroke mappings as the Plan 9 programs.
+First, generate an XCompose sequence list by using
+.IR mklatinkbd :
+.IP
+.EX
+mklatinkbd -x $PLAN9/lib/keyboard >$HOME/.XCompose
+.EE
+.LP
+Second, configure a ``Multi key'' by running
+.IP
+.EX
+xmodmap -e 'keysym Super_L = Multi_key'
+.EE
+.LP
+(The name
+.L Super_L
+typically denotes the Windows key on recent keyboards.)
+.PP
+Third, set these environment variables so that GTK- and QT-based programs
+will use the compose sequences:
+.IP
+.EX
+export GTK_IM_MODULE=xim
+export QT_IM_MODULE=xim
+.EE
+.LP
+Finally, start a new GTK- or QT-based program:
+.IP
+.EX
+gnome-terminal &
+.EE
+.LP
+In that terminal, typing the key sequence
+.RB ` Windows
+.B *
+.BR a '
+should be interpreted as the Greek letter
+.LR α .
+.PP
+If using the GNOME Window Manager, put the
+.B xmodmap
+and
+.B export
+commands into the file
+.B $HOME/.gnomerc
+to run them automatically at startup.
 .SH FILES
 .TP
 .B \*9/lib/keyboard
blob - d3505bcf1fe40a57d23feca9e2ae729e8ae97fcb
blob + 83f55242473d613aaef5a6f24bac28aec1a0f122
--- src/cmd/devdraw/mkfile
+++ src/cmd/devdraw/mkfile
@@ -48,3 +48,4 @@ $O.macargv: macargv.$O
 	$LD -o $target $prereq
 
 install: $MACARGV
+install: mklatinkbd.install
blob - 64787f00f1b984a5a9468425df058c5df837766c
blob + 2e48332e03e202451840d025a6a9c9fa9e843b08
--- src/cmd/devdraw/mklatinkbd.c
+++ src/cmd/devdraw/mklatinkbd.c
@@ -9,6 +9,7 @@
 #include <ctype.h>
 
 int rflag;
+int xflag;
 
 enum {
 	MAXLD = 2,	/* latin1.c assumes this is 2 */
@@ -115,39 +116,56 @@ cprints(Biobuf *b, char *p)
 		cprintchar(b, *p++);
 }
 
+void
+xprint(Biobuf *b, int c)
+{
+}
 
 void
 printtrie(Biobuf *b, Trie *t)
 {
 	int i;
+	char *p;
 
 	for(i=0; i<256; i++)
 		if(t->link[i])
 			printtrie(b, t->link[i]);
+	if(t->n == 0)
+		return;
+	
+	if(xflag) {
+		for(i=0; i<256; i++) {
+			if(t->r[i] == 0)
+				continue;
+			Bprint(b, "<Multi_key>");
+			for(p=t->seq; *p; p++)
+				Bprint(b, " %k", *p);
+			Bprint(b, " %k : \"%C\" U%04X\n", i, t->r[i], t->r[i]);
+		}
+		return;			
+	}
 
-	if(t->n > 0) {
-		Bprint(b, "\t\"");
-		cprints(b, t->seq);
-		Bprint(b, "\", \"");
+	Bprint(b, "\t\"");
+	cprints(b, t->seq);
+	Bprint(b, "\", \"");
+	for(i=0; i<256; i++)
+		if(t->r[i])
+			cprintchar(b, i);
+	Bprint(b, "\",\t");
+	if(rflag) {
+		Bprint(b, "{");
 		for(i=0; i<256; i++)
 			if(t->r[i])
-				cprintchar(b, i);
-		Bprint(b, "\",\t");
-		if(rflag) {
-			Bprint(b, "{");
-			for(i=0; i<256; i++)
-				if(t->r[i])
-					Bprint(b, " 0x%.4ux,", t->r[i]);
-			Bprint(b, " }");
-		} else {
-			Bprint(b, "L\"");
-			for(i=0; i<256; i++)
-				if(t->r[i])
-					Bprint(b, "%C", t->r[i]);
-			Bprint(b, "\"");
-		}
-		Bprint(b, ",\n");
-	}	
+				Bprint(b, " 0x%.4ux,", t->r[i]);
+		Bprint(b, " }");
+	} else {
+		Bprint(b, "L\"");
+		for(i=0; i<256; i++)
+			if(t->r[i])
+				Bprint(b, "%C", t->r[i]);
+		Bprint(b, "\"");
+	}
+	Bprint(b, ",\n");
 }
 
 void
@@ -207,14 +225,20 @@ usage(void)
 	exits("usage");
 }
 
+int kfmt(Fmt*);
+
 void
 main(int argc, char **argv)
 {
+	int i;
 	Biobuf bout;
 
 	ARGBEGIN{
 	case 'r':	/* print rune values */
 		rflag = 1;
+		break;
+	case 'x':
+		xflag = 1;
 		break;
 	default:
 		usage();
@@ -223,10 +247,72 @@ main(int argc, char **argv)
 	if(argc > 1)
 		usage();
 
-	readfile(argc == 1 ? argv[0] : "/fd/0");
+	fmtinstall('k', kfmt);
+	readfile(argc == 1 ? argv[0] : "/dev/stdin");
 
 	Binit(&bout, 1, OWRITE);
+	if(xflag) {
+		Bprint(&bout, "# Generated by mklatinkbd -x; do not edit.\n");
+		for(i=0x20; i<0x10000; i++)
+			Bprint(&bout, "<Multi_key> <X> <%x> <%x> <%x> <%x> : \"%C\" U%04X\n",
+				(i>>12)&0xf, (i>>8)&0xf, (i>>4)&0xf, i&0xf, i, i);
+	}
 	if(root)
 		printtrie(&bout, root);
 	exits(0);
 }
+
+// X11 key names
+
+struct {
+	int c;
+	char *s;
+} xkey[] = {
+	' ', "space",
+	'!',  "exclam",
+	'"',  "quotedbl",
+	'#',  "numbersign",
+	'$',  "dollar",
+	'%',  "percent",
+	'&',  "ampersand",
+	'\'', "apostrophe",
+	'(',  "parenleft",
+	')',  "parenright",
+	'*',  "asterisk",
+	'+',  "plus",
+	',',  "comma",
+	'-',  "minus",
+	'.',  "period",
+	'/',  "slash",
+	':',  "colon",
+	';',  "semicolon",
+	'<',  "less",
+	'=',  "equal",
+	'>',  "greater",
+	'?',  "question",
+	'@',  "at",
+	'[',  "bracketleft",
+	'\\', "backslash",
+	',',  "bracketright",
+	'^',  "asciicircum",
+	'_',  "underscore",
+	'`',  "grave",
+	'{',  "braceleft",
+	'|',  "bar",
+	'}',  "braceright",
+	'~',  "asciitilde",
+};
+
+int
+kfmt(Fmt *f)
+{
+	int i, c;
+
+	c = va_arg(f->args, int);
+	for(i=0; xkey[i].s; i++)
+		if(xkey[i].c == c)
+			return fmtprint(f, "<%s>", xkey[i].s);
+	return fmtprint(f, "<%c>", c);
+}
+
+
blob - a753fb6fdb902885276a43661ed5c465747068ef
blob + ff127c040b20727e16f2e786295863bf71f909c3
--- src/cmd/devdraw/x11-itrans.c
+++ src/cmd/devdraw/x11-itrans.c
@@ -37,7 +37,7 @@ __xtoplan9kbd(XEvent *e)
 	needstack(64*1024);	/* X has some *huge* buffers in openobject */
 		/* and they're even bigger on SuSE */
 	XLookupString((XKeyEvent*)e,NULL,0,&k,NULL);
-	if(k == XK_Multi_key || k == NoSymbol)
+	if(k == k == NoSymbol)
 		return -1;
 
 	if(k&0xFF00){
@@ -113,6 +113,7 @@ __xtoplan9kbd(XEvent *e)
 		case XK_Meta_L:	/* Shift Alt on PCs */
 		case XK_Alt_R:
 		case XK_Meta_R:	/* Shift Alt on PCs */
+		case XK_Multi_key:
 			k = Kalt;
 			break;
 		default:		/* not ISO-1 or tty control */