tAdd drawsetlabel(Display*, char*). Turn window destruction into "hangup" note.… | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 16a709666981e77a00a88a87b286b586ac77ffdc | |
parent 986b36bccd134726eea42f2cfabff2943d729ac4 | |
Author: rsc <devnull@localhost> | |
Date: Sun, 23 Nov 2003 18:15:43 +0000 | |
Add drawsetlabel(Display*, char*). | |
Turn window destruction into "hangup" note. | |
Fix (?) snarf buffer management. | |
Add latin1 keyboard translation. | |
Diffstat: | |
M include/draw.h | 4 +++- | |
D src/libdraw/Makefile | 123 -----------------------------… | |
A src/libdraw/latin1.c | 178 +++++++++++++++++++++++++++++… | |
A src/libdraw/mkfile | 124 +++++++++++++++++++++++++++++… | |
M src/libdraw/x11-event.c | 21 ++++++++++++++++++--- | |
M src/libdraw/x11-init.c | 62 +++++++++++++++++++++++++++++… | |
M src/libdraw/x11-itrans.c | 130 +++++++++++++++++++++++++++--… | |
M src/libdraw/x11-keyboard.c | 4 ++++ | |
M src/libdraw/x11-memdraw.h | 7 ++++++- | |
M src/libdraw/x11-mouse.c | 12 +++++++++++- | |
10 files changed, 518 insertions(+), 147 deletions(-) | |
--- | |
diff --git a/include/draw.h b/include/draw.h | |
t@@ -219,7 +219,7 @@ struct RGB | |
* | |
* given char c, Subfont *f, Fontchar *i, and Point p, one says | |
* i = f->info+c; | |
- * draw(b, Rect(p.x+i->left, p.y+i->top, | |
+ * void(b, Rect(p.x+i->left, p.y+i->top, | |
* p.x+i->left+((i+1)->x-i->x), p.y+i->bottom), | |
* color, f->bits, Pt(i->x, i->top)); | |
* p.x += i->width; | |
t@@ -336,6 +336,7 @@ extern int writeimage(int, Image*, int); | |
extern Image* namedimage(Display*, char*); | |
extern int nameimage(Image*, char*, int); | |
extern Image* allocimagemix(Display*, u32int, u32int); | |
+extern int drawsetlabel(Display*, char*); | |
/* | |
* Colors | |
t@@ -529,3 +530,4 @@ void drawtopwindow(void); | |
*/ | |
int _drawmsgread(Display*, void*, int); | |
int _drawmsgwrite(Display*, void*, int); | |
+int _latin1(Rune*, int); | |
diff --git a/src/libdraw/Makefile b/src/libdraw/Makefile | |
t@@ -1,123 +0,0 @@ | |
-PLAN9=../.. | |
-include $(PLAN9)/src/Makehdr | |
- | |
-LIB=libdraw.a | |
- | |
-OFILES=\ | |
- alloc.$O\ | |
- allocimagemix.$O\ | |
- arith.$O\ | |
- bezier.$O\ | |
- border.$O\ | |
- buildfont.$O\ | |
- bytesperline.$O\ | |
- chan.$O\ | |
- cloadimage.$O\ | |
- computil.$O\ | |
- creadimage.$O\ | |
- debug.$O\ | |
- defont.$O\ | |
- draw.$O\ | |
- drawrepl.$O\ | |
- egetrect.$O\ | |
- ellipse.$O\ | |
- emenuhit.$O\ | |
- font.$O\ | |
- freesubfont.$O\ | |
- getdefont.$O\ | |
- getrect.$O\ | |
- getsubfont.$O\ | |
- icossin.$O\ | |
- icossin2.$O\ | |
- init.$O\ | |
- line.$O\ | |
- loadimage.$O\ | |
- menuhit.$O\ | |
- mkfont.$O\ | |
- openfont.$O\ | |
- poly.$O\ | |
- readcolmap.$O\ | |
- readimage.$O\ | |
- readsubfont.$O\ | |
- rectclip.$O\ | |
- replclipr.$O\ | |
- rgb.$O\ | |
- string.$O\ | |
- stringbg.$O\ | |
- stringsubfont.$O\ | |
- stringwidth.$O\ | |
- subfont.$O\ | |
- subfontcache.$O\ | |
- subfontname.$O\ | |
- unloadimage.$O\ | |
- window.$O\ | |
- writecolmap.$O\ | |
- writeimage.$O\ | |
- writesubfont.$O\ | |
- md-alloc.$O\ | |
- md-arc.$O\ | |
- md-cload.$O\ | |
- md-cmap.$O\ | |
- md-cread.$O\ | |
- md-defont.$O\ | |
- md-draw.$O\ | |
- md-ellipse.$O\ | |
- md-fillpoly.$O\ | |
- md-hwdraw.$O\ | |
- md-iprint.$O\ | |
- md-line.$O\ | |
- md-load.$O\ | |
- md-openmemsubfont.$O\ | |
- md-poly.$O\ | |
- md-read.$O\ | |
- md-string.$O\ | |
- md-subfont.$O\ | |
- md-unload.$O\ | |
- md-write.$O\ | |
- ml-draw.$O\ | |
- ml-lalloc.$O\ | |
- ml-layerop.$O\ | |
- ml-ldelete.$O\ | |
- ml-lhide.$O\ | |
- ml-line.$O\ | |
- ml-load.$O\ | |
- ml-lorigin.$O\ | |
- ml-lsetrefresh.$O\ | |
- ml-ltofront.$O\ | |
- ml-ltorear.$O\ | |
- ml-unload.$O\ | |
- x11-alloc.$O\ | |
- x11-cload.$O\ | |
- x11-draw.$O\ | |
- x11-event.$O\ | |
- x11-fill.$O\ | |
- x11-get.$O\ | |
- x11-init.$O\ | |
- x11-itrans.$O\ | |
- x11-keyboard.$O\ | |
- x11-load.$O\ | |
- x11-mouse.$O\ | |
- x11-pixelbits.$O\ | |
- x11-unload.$O\ | |
- x11-wsys.$O\ | |
- devdraw.$O\ | |
- unix.$O\ | |
- | |
-HFILES=\ | |
- $(PLAN9)/include/draw.h\ | |
- $(PLAN9)/include/memdraw.h\ | |
- $(PLAN9)/include/memlayer.h\ | |
- $(PLAN9)/include/event.h\ | |
- $(PLAN9)/include/cursor.h\ | |
- $(PLAN9)/include/mouse.h\ | |
- $(PLAN9)/include/keyboard.h\ | |
- x11-inc.h\ | |
- x11-memdraw.h\ | |
- | |
-CFLAGS+=-I$(X11)/include | |
- | |
-include $(PLAN9)/src/Makesyslib | |
- | |
-test: test.o $(LIB) | |
- gcc -o test test.o -L$(PLAN9) -ldraw -l9 -lfmt -lutf -L$(X11)/lib -lX1… | |
- | |
diff --git a/src/libdraw/latin1.c b/src/libdraw/latin1.c | |
t@@ -0,0 +1,178 @@ | |
+#include <u.h> | |
+#include <libc.h> | |
+#include <draw.h> | |
+ | |
+/* | |
+ * The code makes two assumptions: strlen(ld) is 1 or 2; latintab[i].ld can be… | |
+ * prefix of latintab[j].ld only when j<i. | |
+ */ | |
+static struct cvlist | |
+{ | |
+ char *ld; /* must be seen before using this conv… | |
+ char *si; /* options for last input characters */ | |
+ Rune so[50]; /* the corresponding Rune for each … | |
+} latintab[] = { | |
+ " ", " i", { 0x2423, 0x0131 }, | |
+ "w", "kqrbnp", { 0x2654, 0x2655, 0x2656, 0x2657, 0x2658, 0x2659, }, | |
+ "x", "O", { 0x2297, }, | |
+ "f", "a", { 0x2200, }, | |
+ "=", "V:=O<>", { 0x21D2, 0x2255, 0x2261, 0x229C, 0x22DC, 0x22DD, }, | |
+ "V", "=", { 0x21D0, }, | |
+ "7", "8", { 0x215E, }, | |
+ "5", "68", { 0x215A, 0x215D, }, | |
+ "4", "5", { 0x2158, }, | |
+ "R", "R", { 0x211D, }, | |
+ "Q", "Q", { 0x211A, }, | |
+ "P", "P", { 0x2119, }, | |
+ "C", "CAU", { 0x2102, 0x22C2, 0x22C3, }, | |
+ "e", "nmsl", { 0x2013, 0x2014, 0x2205, 0x22EF, }, | |
+ "b", "u0123456789+-=()kqrbnp", { 0x2022, 0x2080, 0x2081, 0x2082, 0x208… | |
+ "@e", "h", { 0x44D, }, | |
+ "@\'", "\'", { 0x44A, }, | |
+ "@s", "hc", { 0x448, 0x449, }, | |
+ "@c", "h", { 0x447, }, | |
+ "@t", "s", { 0x446, }, | |
+ "@k", "h", { 0x445, }, | |
+ "@z", "h", { 0x436, }, | |
+ "@y", "euao", { 0x435, 0x44E, 0x44F, 0x451, }, | |
+ "@E", "Hh", { 0x42D, 0x42D, }, | |
+ "@S", "HhCc", { 0x428, 0x428, 0x429, 0x429, }, | |
+ "@C", "Hh", { 0x427, 0x427, }, | |
+ "@T", "Ss", { 0x426, 0x426, }, | |
+ "@K", "Hh", { 0x425, 0x425, }, | |
+ "@Z", "Hh", { 0x416, 0x416, }, | |
+ "@@", "EZKSTYezksty\'", { 0x415, 0x417, 0x41A, 0x421, 0x422, 0x42B, 0x… | |
+ "@Y", "OoEeUuAa", { 0x401, 0x401, 0x415, 0x415, 0x42E, 0x42E, 0x42F, 0… | |
+ "@", "ABVGDIJLMNOPRUFXabvgdijlmnoprufx", { 0x410, 0x411, 0x412, 0x413,… | |
+ "*", "ABGDEZYHIKLMNCOPRSTUFXQWabgdezyhiklmncoprstufxqw*", { 0x391, 0x3… | |
+ "G", "-", { 0x1E4, }, | |
+ "N", "JjN", { 0x1CA, 0x1CB, 0x2115, }, | |
+ "2", "-35", { 0x1BB, 0x2154, 0x2156, }, | |
+ "z", "-", { 0x1B6, }, | |
+ "Z", "-Z", { 0x1B5, 0x2124, }, | |
+ "Y", "R", { 0x1A6, }, | |
+ "h", "v-", { 0x195, 0x210F, }, | |
+ "$*", "hfk", { 0x3D1, 0x3D5, 0x3F0, }, | |
+ "$", "fVavgHILlpRBeEFMo", { 0x192, 0x1B2, 0x251, 0x28B, 0x210A, 0x210B… | |
+ "t", "-smefu", { 0x167, 0x3C2, 0x2122, 0x2203, 0x2234, 0x22A2, }, | |
+ "T", "-u", { 0x166, 0x22A8, }, | |
+ "L", "-Jj&|", { 0x141, 0x1C7, 0x1C8, 0x22C0, 0x22C1, }, | |
+ "i", "j-fsbp", { 0x133, 0x268, 0x221E, 0x222B, 0x2286, 0x2287, }, | |
+ "I", "J-", { 0x132, 0x197, }, | |
+ "H", "-H", { 0x126, 0x210D, }, | |
+ "v\"", "Uu", { 0x1D9, 0x1DA, }, | |
+ "v", "CcDdEeLlNnRrSsTtZzAaIiOoUuGgKkj", { 0x10C, 0x10D, 0x10E, 0x10F, … | |
+ "u", "AEeGgIiOoUu-a", { 0x102, 0x114, 0x115, 0x11E, 0x11F, 0x12C, 0x12… | |
+ ":", "-=)", { 0xF7, 0x2254, 0x263A, }, | |
+ "a", "ebn", { 0xE6, 0x2194, 0x2220, }, | |
+ "/", "Oo", { 0xD8, 0xF8, }, | |
+ "Dv", "Zz", { 0x1C4, 0x1C5, }, | |
+ "D", "-e", { 0xD0, 0x2206, }, | |
+ "A", "E", { 0xC6, }, | |
+ "o", "AaeUuiO", { 0xC5, 0xE5, 0x153, 0x16E, 0x16F, 0x1A3, 0x229A, }, | |
+ "~!", "=", { 0x2246, }, | |
+ "~", "ANOanoIiUu-=~", { 0xC3, 0xD1, 0xD5, 0xE3, 0xF1, 0xF5, 0x128, 0x1… | |
+ "^", "AEIOUaeiouCcGgHhJjSsWwYy", { 0xC2, 0xCA, 0xCE, 0xD4, 0xDB, 0xE2,… | |
+ "`\"", "Uu", { 0x1DB, 0x1DC, }, | |
+ "`", "AEIOUaeiou", { 0xC0, 0xC8, 0xCC, 0xD2, 0xD9, 0xE0, 0xE8, 0xEC, 0… | |
+ "?", "?!", { 0xBF, 0x203D, }, | |
+ "3", "458", { 0xBE, 0x2157, 0x215C, }, | |
+ "1", "423568", { 0xBC, 0xBD, 0x2153, 0x2155, 0x2159, 0x215B, }, | |
+ ">!", "=~", { 0x2269, 0x22E7, }, | |
+ ">", ">=~<", { 0xBB, 0x2265, 0x2273, 0x2277, }, | |
+ ",", ",CcAaEeGgIiKkLlNnRrSsTtUuOo", { 0xB8, 0xC7, 0xE7, 0x104, 0x105, … | |
+ ".", ".CcEeGgILlZzO", { 0xB7, 0x10A, 0x10B, 0x116, 0x117, 0x120, 0x121… | |
+ "p", "gOdrt", { 0xB6, 0x2117, 0x2202, 0x220F, 0x221D, }, | |
+ "m", "iuo", { 0xB5, 0xD7, 0x2208, }, | |
+ "\'\"", "Uu", { 0x1D7, 0x1D8, }, | |
+ "\'", "\'AEIOUYaeiouyCcgLlNnRrSsZz", { 0xB4, 0xC1, 0xC9, 0xCD, 0xD3, 0… | |
+ "+", "-O", { 0xB1, 0x2295, }, | |
+ "dv", "z", { 0x1C6, }, | |
+ "d", "e-zgda", { 0xB0, 0xF0, 0x2A3, 0x2020, 0x2021, 0x2193, }, | |
+ "_,", "Oo", { 0x1EC, 0x1ED, }, | |
+ "_.", "Aa", { 0x1E0, 0x1E1, }, | |
+ "_\"", "UuAa", { 0x1D5, 0x1D6, 0x1DE, 0x1DF, }, | |
+ "_", "_AaEeIiOoUu", { 0xAF, 0x100, 0x101, 0x112, 0x113, 0x12A, 0x12B, … | |
+ "r", "O\'\"", { 0xAE, 0x2019, 0x201D, }, | |
+ "-*", "l", { 0x19B, }, | |
+ "-", "-Dd:HLlTtbIZz2Ggiuh>+~O", { 0xAD, 0xD0, 0xF0, 0xF7, 0x126, 0x141… | |
+ "n", "oj", { 0xAC, 0x1CC, }, | |
+ "<!", "=~", { 0x2268, 0x22E6, }, | |
+ "<", "<-=~>", { 0xAB, 0x2190, 0x2264, 0x2272, 0x2276, }, | |
+ "s", "a231os0456789+-=()nturbp", { 0xAA, 0xB2, 0xB3, 0xB9, 0xBA, 0xDF,… | |
+ "O", "crEIp+-x/.o*=", { 0xA9, 0xAE, 0x152, 0x1A2, 0x2117, 0x2295, 0x22… | |
+ "\"*", "IUiu", { 0x3AA, 0x3AB, 0x3CA, 0x3CB, }, | |
+ "\"", "\"AEIOUaeiouyY", { 0xA8, 0xC4, 0xCB, 0xCF, 0xD6, 0xDC, 0xE4, 0x… | |
+ "S", "S", { 0xA7, }, | |
+ "|", "|Pp", { 0xA6, 0xDE, 0xFE, }, | |
+ "y", "$", { 0xA5, }, | |
+ "g", "$-r", { 0xA4, 0x1E5, 0x2207, }, | |
+ "l", "$-j\'\"&|z", { 0xA3, 0x142, 0x1C9, 0x2018, 0x201C, 0x2227, 0x222… | |
+ "c", "$Oaug", { 0xA2, 0xA9, 0x2229, 0x222A, 0x2245, }, | |
+ "!~", "-=~", { 0x2244, 0x2247, 0x2249, }, | |
+ "!", "!?m=<>bp", { 0xA1, 0x203D, 0x2209, 0x2260, 0x226E, 0x226F, 0x228… | |
+ 0, 0, { 0, } | |
+}; | |
+ | |
+/* | |
+ * Given 5 characters k[0]..k[4], find the rune or return -1 for failure. | |
+ */ | |
+static long | |
+unicode(Rune *k) | |
+{ | |
+ long i, c; | |
+ | |
+ k++; /* skip 'X' */ | |
+ c = 0; | |
+ for(i=0; i<4; i++,k++){ | |
+ c <<= 4; | |
+ if('0'<=*k && *k<='9') | |
+ c += *k-'0'; | |
+ else if('a'<=*k && *k<='f') | |
+ c += 10 + *k-'a'; | |
+ else if('A'<=*k && *k<='F') | |
+ c += 10 + *k-'A'; | |
+ else | |
+ return -1; | |
+ } | |
+ return c; | |
+} | |
+ | |
+/* | |
+ * Given n characters k[0]..k[n-1], find the corresponding rune or return -1 f… | |
+ * failure, or something < -1 if n is too small. In the latter case, the resu… | |
+ * is minus the required n. | |
+ */ | |
+int | |
+_latin1(Rune *k, int n) | |
+{ | |
+ struct cvlist *l; | |
+ int c; | |
+ char* p; | |
+ | |
+ if(k[0] == 'X'){ | |
+ if(n>=5) | |
+ return unicode(k); | |
+ else | |
+ return -5; | |
+ } | |
+ | |
+ for(l=latintab; l->ld!=0; l++) | |
+ if(k[0] == l->ld[0]){ | |
+ if(n == 1) | |
+ return -2; | |
+ if(l->ld[1] == 0) | |
+ c = k[1]; | |
+ else if(l->ld[1] != k[1]) | |
+ continue; | |
+ else if(n == 2) | |
+ return -3; | |
+ else | |
+ c = k[2]; | |
+ for(p=l->si; *p!=0; p++) | |
+ if(*p == c) | |
+ return l->so[p - l->si]; | |
+ return -1; | |
+ } | |
+ return -1; | |
+} | |
diff --git a/src/libdraw/mkfile b/src/libdraw/mkfile | |
t@@ -0,0 +1,124 @@ | |
+PLAN9=../.. | |
+<$PLAN9/src/mkhdr | |
+ | |
+LIB=libdraw.a | |
+ | |
+OFILES=\ | |
+ alloc.$O\ | |
+ allocimagemix.$O\ | |
+ arith.$O\ | |
+ bezier.$O\ | |
+ border.$O\ | |
+ buildfont.$O\ | |
+ bytesperline.$O\ | |
+ chan.$O\ | |
+ cloadimage.$O\ | |
+ computil.$O\ | |
+ creadimage.$O\ | |
+ debug.$O\ | |
+ defont.$O\ | |
+ draw.$O\ | |
+ drawrepl.$O\ | |
+ egetrect.$O\ | |
+ ellipse.$O\ | |
+ emenuhit.$O\ | |
+ font.$O\ | |
+ freesubfont.$O\ | |
+ getdefont.$O\ | |
+ getrect.$O\ | |
+ getsubfont.$O\ | |
+ icossin.$O\ | |
+ icossin2.$O\ | |
+ init.$O\ | |
+ line.$O\ | |
+ latin1.$O\ | |
+ loadimage.$O\ | |
+ menuhit.$O\ | |
+ mkfont.$O\ | |
+ openfont.$O\ | |
+ poly.$O\ | |
+ readcolmap.$O\ | |
+ readimage.$O\ | |
+ readsubfont.$O\ | |
+ rectclip.$O\ | |
+ replclipr.$O\ | |
+ rgb.$O\ | |
+ string.$O\ | |
+ stringbg.$O\ | |
+ stringsubfont.$O\ | |
+ stringwidth.$O\ | |
+ subfont.$O\ | |
+ subfontcache.$O\ | |
+ subfontname.$O\ | |
+ unloadimage.$O\ | |
+ window.$O\ | |
+ writecolmap.$O\ | |
+ writeimage.$O\ | |
+ writesubfont.$O\ | |
+ md-alloc.$O\ | |
+ md-arc.$O\ | |
+ md-cload.$O\ | |
+ md-cmap.$O\ | |
+ md-cread.$O\ | |
+ md-defont.$O\ | |
+ md-draw.$O\ | |
+ md-ellipse.$O\ | |
+ md-fillpoly.$O\ | |
+ md-hwdraw.$O\ | |
+ md-iprint.$O\ | |
+ md-line.$O\ | |
+ md-load.$O\ | |
+ md-openmemsubfont.$O\ | |
+ md-poly.$O\ | |
+ md-read.$O\ | |
+ md-string.$O\ | |
+ md-subfont.$O\ | |
+ md-unload.$O\ | |
+ md-write.$O\ | |
+ ml-draw.$O\ | |
+ ml-lalloc.$O\ | |
+ ml-layerop.$O\ | |
+ ml-ldelete.$O\ | |
+ ml-lhide.$O\ | |
+ ml-line.$O\ | |
+ ml-load.$O\ | |
+ ml-lorigin.$O\ | |
+ ml-lsetrefresh.$O\ | |
+ ml-ltofront.$O\ | |
+ ml-ltorear.$O\ | |
+ ml-unload.$O\ | |
+ x11-alloc.$O\ | |
+ x11-cload.$O\ | |
+ x11-draw.$O\ | |
+ x11-event.$O\ | |
+ x11-fill.$O\ | |
+ x11-get.$O\ | |
+ x11-init.$O\ | |
+ x11-itrans.$O\ | |
+ x11-keyboard.$O\ | |
+ x11-load.$O\ | |
+ x11-mouse.$O\ | |
+ x11-pixelbits.$O\ | |
+ x11-unload.$O\ | |
+ x11-wsys.$O\ | |
+ devdraw.$O\ | |
+ unix.$O\ | |
+ | |
+HFILES=\ | |
+ $PLAN9/include/draw.h\ | |
+ $PLAN9/include/memdraw.h\ | |
+ $PLAN9/include/memlayer.h\ | |
+ $PLAN9/include/event.h\ | |
+ $PLAN9/include/cursor.h\ | |
+ $PLAN9/include/mouse.h\ | |
+ $PLAN9/include/keyboard.h\ | |
+ x11-inc.h\ | |
+ x11-memdraw.h\ | |
+ | |
+CFLAGS=$CFLAGS -I$X11/include | |
+ | |
+<$PLAN9/src/mksyslib | |
+ | |
+test: test.o $LIB | |
+ gcc -o test test.o -L$PLAN9 -ldraw -l9 -lfmt -lutf -L$X11/lib -lX11 -lm | |
+ | |
diff --git a/src/libdraw/x11-event.c b/src/libdraw/x11-event.c | |
t@@ -36,6 +36,7 @@ eflush(void) | |
ulong | |
eread(ulong keys, Event *e) | |
{ | |
+ int r; | |
ulong xmask; | |
XEvent xevent; | |
t@@ -45,8 +46,13 @@ eread(ulong keys, Event *e) | |
if(keys&Emouse) | |
xmask |= MouseMask|StructureNotifyMask; | |
- if(keys&Ekeyboard) | |
+ if(keys&Ekeyboard){ | |
xmask |= KeyPressMask; | |
+ if((r = xtoplan9kbd(nil)) >= 0){ | |
+ e->kbdc = r; | |
+ return Ekeyboard; | |
+ } | |
+ } | |
XSelectInput(_x.display, _x.drawable, xmask); | |
again: | |
t@@ -56,6 +62,10 @@ again: | |
case Expose: | |
xexpose(&xevent, _x.display); | |
goto again; | |
+ case DestroyNotify: | |
+ if(xdestroy(&xevent, _x.display)) | |
+ postnote(PNGROUP, getpgrp(), "hangup"); | |
+ goto again; | |
case ConfigureNotify: | |
if(xconfigure(&xevent, _x.display)) | |
eresized(1); | |
t@@ -63,7 +73,7 @@ again: | |
case ButtonPress: | |
case ButtonRelease: | |
case MotionNotify: | |
- if(xtoplan9mouse(&xevent, &e->mouse) < 0) | |
+ if(xtoplan9mouse(_x.display, &xevent, &e->mouse) < 0) | |
goto again; | |
return Emouse; | |
case KeyPress: | |
t@@ -126,7 +136,7 @@ ecanmouse(void) | |
eflush(); | |
again: | |
if(XCheckWindowEvent(_x.display, _x.drawable, MouseMask, &xe)){ | |
- if(xtoplan9mouse(&xe, &m) < 0) | |
+ if(xtoplan9mouse(_x.display, &xe, &m) < 0) | |
goto again; | |
XPutBackEvent(_x.display, &xe); | |
return 1; | |
t@@ -138,8 +148,13 @@ int | |
ecankbd(void) | |
{ | |
XEvent xe; | |
+ int r; | |
eflush(); | |
+ if((r = xtoplan9kbd(nil)) >= 0){ | |
+ xtoplan9kbd((XEvent*)-1); | |
+ return 1; | |
+ } | |
again: | |
if(XCheckWindowEvent(_x.display, _x.drawable, KeyPressMask, &xe)){ | |
if(xtoplan9kbd(&xe) == -1) | |
diff --git a/src/libdraw/x11-init.c b/src/libdraw/x11-init.c | |
t@@ -100,6 +100,8 @@ getwindow(Display *d, int ref) | |
{ | |
Image *i; | |
+ if(_x.destroyed) | |
+ postnote(PNGROUP, getpgrp(), "hangup"); | |
if(xreplacescreenimage() == 0) | |
return 0; | |
freeimage(d->screenimage); | |
t@@ -124,7 +126,7 @@ static int | |
xioerror(XDisplay *d) | |
{ | |
print("X I/O error\n"); | |
- exit(1); | |
+ abort(); | |
return -1; | |
} | |
t@@ -365,6 +367,11 @@ xattach(char *label) | |
XFlush(_x.display); | |
/* | |
+ * Look up clipboard atom. | |
+ */ | |
+ _x.clipboard = XInternAtom(_x.display, "CLIPBOARD", True); | |
+ | |
+ /* | |
* Lots of display connections for various procs. | |
*/ | |
_x.kbdcon = XOpenDisplay(NULL); | |
t@@ -388,6 +395,46 @@ fprint(2, "%r\n"); | |
return nil; | |
} | |
+int | |
+drawsetlabel(Display *d, char *label) | |
+{ | |
+ char *argv[2]; | |
+ XClassHint classhint; | |
+ XTextProperty name; | |
+ | |
+ /* | |
+ * Label and other properties required by ICCCCM. | |
+ */ | |
+ memset(&name, 0, sizeof name); | |
+ if(label == nil) | |
+ label = "pjw-face-here"; | |
+ name.value = (uchar*)label; | |
+ name.encoding = XA_STRING; | |
+ name.format = 8; | |
+ name.nitems = strlen(name.value); | |
+ | |
+ memset(&classhint, 0, sizeof classhint); | |
+ classhint.res_name = label; | |
+ classhint.res_class = label; | |
+ | |
+ argv[0] = label; | |
+ argv[1] = nil; | |
+ | |
+ XSetWMProperties( | |
+ _x.display, /* display */ | |
+ _x.drawable, /* window */ | |
+ &name, /* XA_WM_NAME property */ | |
+ &name, /* XA_WM_ICON_NAME property */ | |
+ argv, /* XA_WM_COMMAND */ | |
+ 1, /* argc */ | |
+ nil, /* XA_WM_NORMAL_HINTS */ | |
+ nil, /* XA_WM_HINTS */ | |
+ &classhint /* XA_WM_CLASSHINTS */ | |
+ ); | |
+ XFlush(_x.display); | |
+ return 0; | |
+} | |
+ | |
/* | |
* Create a GC with a particular fill style and XXX. | |
* Disable generation of GraphicsExpose/NoExpose events in the GC. | |
t@@ -604,6 +651,19 @@ xexpose(XEvent *e, XDisplay *xd) | |
} | |
int | |
+xdestroy(XEvent *e, XDisplay *xd) | |
+{ | |
+ XDestroyWindowEvent *xe; | |
+ | |
+ xe = (XDestroyWindowEvent*)e; | |
+ if(xe->window == _x.drawable){ | |
+ _x.destroyed = 1; | |
+ return 1; | |
+ } | |
+ return 0; | |
+} | |
+ | |
+int | |
xconfigure(XEvent *e, XDisplay *xd) | |
{ | |
Rectangle r; | |
diff --git a/src/libdraw/x11-itrans.c b/src/libdraw/x11-itrans.c | |
t@@ -11,8 +11,8 @@ | |
#include <keyboard.h> | |
#include "x11-memdraw.h" | |
-int | |
-xtoplan9kbd(XEvent *e) | |
+static int | |
+_xtoplan9kbd(XEvent *e) | |
{ | |
int ind, k, md; | |
t@@ -117,16 +117,82 @@ xtoplan9kbd(XEvent *e) | |
return k; | |
} | |
+static Rune* | |
+xtoplan9latin1(XEvent *e) | |
+{ | |
+ static Rune k[10]; | |
+ static int alting, nk; | |
+ int n; | |
+ int r; | |
+ | |
+ r = _xtoplan9kbd(e); | |
+ if(r < 0) | |
+ return nil; | |
+ if(alting){ | |
+ k[nk++] = r; | |
+ n = _latin1(k, nk); | |
+ if(n > 0){ | |
+ alting = 0; | |
+ k[0] = n; | |
+ k[1] = 0; | |
+ return k; | |
+ } | |
+ if(n == -1){ | |
+ alting = 0; | |
+ k[nk] = 0; | |
+ return k; | |
+ } | |
+ /* n < -1, need more input */ | |
+ return nil; | |
+ }else if(r == Kalt){ | |
+ alting = 1; | |
+ nk = 0; | |
+ return nil; | |
+ }else{ | |
+ k[0] = r; | |
+ k[1] = 0; | |
+ return k; | |
+ } | |
+} | |
+ | |
+int | |
+xtoplan9kbd(XEvent *e) | |
+{ | |
+ static Rune *r; | |
+ | |
+ if(e == (XEvent*)-1){ | |
+ assert(r); | |
+ r--; | |
+ return 0; | |
+ } | |
+ if(e) | |
+ r = xtoplan9latin1(e); | |
+ if(r && *r) | |
+ return *r++; | |
+ return -1; | |
+} | |
+ | |
int | |
-xtoplan9mouse(XEvent *e, Mouse *m) | |
+xtoplan9mouse(XDisplay *xd, XEvent *e, Mouse *m) | |
{ | |
int s; | |
XButtonEvent *be; | |
XMotionEvent *me; | |
+ if(_x.putsnarf != _x.assertsnarf){ | |
+ _x.assertsnarf = _x.putsnarf; | |
+ XSetSelectionOwner(_x.mousecon, XA_PRIMARY, _x.drawable, Curre… | |
+ if(_x.clipboard != None) | |
+ XSetSelectionOwner(_x.mousecon, _x.clipboard, _x.drawa… | |
+ XFlush(xd); | |
+ } | |
+ | |
switch(e->type){ | |
case ButtonPress: | |
be = (XButtonEvent*)e; | |
+ /* Fake message, just sent to make us announce snarf. */ | |
+ if(be->send_event && be->state==~0 && be->button==~0) | |
+ return -1; | |
/* BUG? on mac need to inherit these from elsewhere? */ | |
m->xy.x = be->x; | |
m->xy.y = be->y; | |
t@@ -265,34 +331,55 @@ char* | |
xgetsnarf(XDisplay *xd) | |
{ | |
uchar *data, *xdata; | |
- Atom type; | |
+ Atom clipboard, type, prop; | |
ulong len, lastlen, dummy; | |
int fmt, i; | |
XWindow w; | |
qlock(&clip.lk); | |
+ /* | |
+ * Is there a primary selection (highlighted text in an xterm)? | |
+ */ | |
+ clipboard = XA_PRIMARY; | |
w = XGetSelectionOwner(xd, XA_PRIMARY); | |
if(w == _x.drawable){ | |
+ mine: | |
data = (uchar*)strdup(clip.buf); | |
goto out; | |
} | |
+ | |
+ /* | |
+ * If not, is there a clipboard selection? | |
+ */ | |
+ if(w == None && _x.clipboard != None){ | |
+ clipboard = _x.clipboard; | |
+ w = XGetSelectionOwner(xd, _x.clipboard); | |
+ if(w == _x.drawable) | |
+ goto mine; | |
+ } | |
+ | |
+ /* | |
+ * If not, give up. | |
+ */ | |
if(w == None){ | |
data = nil; | |
goto out; | |
} | |
+ | |
/* | |
* We should be waiting for SelectionNotify here, but it might never | |
- * come, and we have no way to time out. Instead, we will zero the | |
- * property, request our buddy to fill it in for us, and wait until | |
- * he's done. | |
+ * come, and we have no way to time out. Instead, we will clear | |
+ * local property #1, request our buddy to fill it in for us, and poll | |
+ * until he's done or we get tired of waiting. | |
*/ | |
- XChangeProperty(xd, _x.drawable, XA_PRIMARY, XA_STRING, 8, PropModeRep… | |
- XConvertSelection(xd, XA_PRIMARY, XA_STRING, None, _x.drawable, Curren… | |
+ prop = 1; | |
+ XChangeProperty(xd, _x.drawable, prop, XA_STRING, 8, PropModeReplace, … | |
+ XConvertSelection(xd, clipboard, XA_STRING, prop, _x.drawable, Current… | |
XFlush(xd); | |
lastlen = 0; | |
- for(i=0; i<30; i++){ | |
+ for(i=0; i<10 || (lastlen!=0 && i<30); i++){ | |
usleep(100*1000); | |
- XGetWindowProperty(xd, _x.drawable, XA_STRING, 0, 0, 0, AnyPro… | |
+ XGetWindowProperty(xd, _x.drawable, prop, 0, 0, 0, AnyProperty… | |
&type, &fmt, &dummy, &len, &data); | |
if(lastlen == len && len > 0) | |
break; | |
t@@ -304,7 +391,7 @@ xgetsnarf(XDisplay *xd) | |
} | |
/* get the property */ | |
data = nil; | |
- XGetWindowProperty(xd, _x.drawable, XA_STRING, 0, SnarfSize/4, 0, | |
+ XGetWindowProperty(xd, _x.drawable, prop, 0, SnarfSize/sizeof(ulong), … | |
AnyPropertyType, &type, &fmt, &len, &dummy, &xdata); | |
if(type != XA_STRING || len == 0){ | |
if(xdata) | |
t@@ -325,16 +412,25 @@ out: | |
void | |
xputsnarf(XDisplay *xd, char *data) | |
{ | |
+ XButtonEvent e; | |
+ | |
if(strlen(data) >= SnarfSize) | |
return; | |
qlock(&clip.lk); | |
strcpy(clip.buf, data); | |
- /* | |
- * BUG: This is wrong. Instead, we should send an event to the | |
- * mouse connection telling it to call XSetSelectionOwner. | |
- */ | |
- XSetSelectionOwner(_x.mousecon, XA_PRIMARY, _x.drawable, CurrentTime); | |
+ | |
+ /* leave note for mouse proc to assert selection ownership */ | |
+ _x.putsnarf++; | |
+ | |
+ /* send mouse a fake event so snarf is announced */ | |
+ memset(&e, 0, sizeof e); | |
+ e.type = ButtonPress; | |
+ e.window = _x.drawable; | |
+ e.state = ~0; | |
+ e.button = ~0; | |
+ XSendEvent(xd, _x.drawable, True, ButtonPressMask, (XEvent*)&e); | |
XFlush(xd); | |
+ | |
qunlock(&clip.lk); | |
} | |
diff --git a/src/libdraw/x11-keyboard.c b/src/libdraw/x11-keyboard.c | |
t@@ -51,6 +51,10 @@ _ioproc(void *arg) | |
continue; | |
r = i; | |
send(kc->c, &r); | |
+ while((i=xtoplan9kbd(nil)) >= 0){ | |
+ r = i; | |
+ send(kc->c, &r); | |
+ } | |
break; | |
} | |
} | |
diff --git a/src/libdraw/x11-memdraw.h b/src/libdraw/x11-memdraw.h | |
t@@ -64,6 +64,10 @@ struct Xprivate { | |
int usetable; | |
XVisual *vis; | |
u32int white; | |
+ Atom clipboard; | |
+ uint putsnarf; | |
+ uint assertsnarf; | |
+ int destroyed; | |
}; | |
extern Xprivate _x; | |
t@@ -78,11 +82,12 @@ extern void xputxdata(Memimage*, Rectangle); | |
extern void _initdisplaymemimage(Display*, Memimage*); | |
struct Mouse; | |
-extern int xtoplan9mouse(XEvent*, struct Mouse*); | |
+extern int xtoplan9mouse(XDisplay*, XEvent*, struct Mouse*); | |
extern int xtoplan9kbd(XEvent*); | |
extern void xexpose(XEvent*, XDisplay*); | |
extern int xselect(XEvent*, XDisplay*); | |
extern int xconfigure(XEvent*, XDisplay*); | |
+extern int xdestroy(XEvent*, XDisplay*); | |
extern void flushmemscreen(Rectangle); | |
extern void xmoveto(Point); | |
struct Cursor; | |
diff --git a/src/libdraw/x11-mouse.c b/src/libdraw/x11-mouse.c | |
t@@ -66,6 +66,16 @@ _ioproc(void *arg) | |
case Expose: | |
xexpose(&xevent, _x.mousecon); | |
continue; | |
+ case DestroyNotify: | |
+ if(xdestroy(&xevent, _x.mousecon)){ | |
+ /* drain it before sending */ | |
+ /* apps that care can notice we sent a 0 */ | |
+ /* otherwise we'll have getwindow send SIGHUP … | |
+ nbrecv(mc->resizec, 0); | |
+ nbrecv(mc->resizec, 0); | |
+ send(mc->resizec, 0); | |
+ } | |
+ continue; | |
case ConfigureNotify: | |
if(xconfigure(&xevent, _x.mousecon)) | |
nbsend(mc->resizec, &one); | |
t@@ -76,7 +86,7 @@ _ioproc(void *arg) | |
case ButtonPress: | |
case ButtonRelease: | |
case MotionNotify: | |
- if(xtoplan9mouse(&xevent, &m) < 0) | |
+ if(xtoplan9mouse(_x.mousecon, &xevent, &m) < 0) | |
continue; | |
send(mc->c, &m); | |
/* |