Browse Source

Plan 9 from Bell Labs 2004-04-26

David du Colombier 20 years ago
parent
commit
5801bb8a2c

+ 2 - 0
acme/bin/source/win/main.c

@@ -70,6 +70,8 @@ threadmain(int argc, char *argv[])
 	tag = estrdup(dir);
 	tag = eappend(estrdup(tag), "/-", name);
 	win = newwindow();
+	snprint(buf, sizeof buf, "%d", win->id);
+	putenv("winid", buf);
 	winname(win, tag);
 	wintagwrite(win, "Send Noscroll", 5+8);
 	threadcreate(mainctl, win, STACK);

+ 14 - 14
dist/replica/plan9.db

@@ -27,7 +27,7 @@
 386/bin/9660srv - 775 sys sys 1064598019 104963
 386/bin/aan - 775 sys sys 1064598020 128816
 386/bin/acid - 775 sys sys 1081825815 379877
-386/bin/acme - 775 sys sys 1081480397 424667
+386/bin/acme - 775 sys sys 1082924480 429258
 386/bin/ape - 20000000775 sys sys 1016944144 0
 386/bin/ape/basename - 775 sys sys 1071245280 133877
 386/bin/ape/cc - 775 sys sys 1064598025 68790
@@ -305,7 +305,7 @@
 386/bin/lnfs - 775 sys sys 1064598250 100511
 386/bin/look - 775 sys sys 1064598250 64212
 386/bin/ls - 775 sys sys 1073851233 81182
-386/bin/mc - 775 sys sys 1071245338 129548
+386/bin/mc - 775 sys sys 1082924486 131746
 386/bin/md5sum - 775 sys sys 1064598252 59465
 386/bin/mk - 775 sys sys 1064598253 143638
 386/bin/mkdir - 775 sys sys 1082603187 59419
@@ -531,7 +531,7 @@
 386/lib/libcomplete.a - 664 sys sys 1076817073 6312
 386/lib/libcontrol.a - 664 sys sys 1073851267 242856
 386/lib/libdisk.a - 664 sys sys 1073851267 43536
-386/lib/libdraw.a - 664 sys sys 1073851268 372528
+386/lib/libdraw.a - 664 sys sys 1082924460 373342
 386/lib/libflate.a - 664 sys sys 1073851268 77194
 386/lib/libframe.a - 664 sys sys 1073851269 65534
 386/lib/libgeometry.a - 664 sys sys 1073851269 50732
@@ -619,7 +619,7 @@ acme/bin/386/acd - 775 sys sys 1032232412 137068
 acme/bin/386/adict - 775 sys sys 1015011247 99806
 acme/bin/386/mkwnew - 775 sys sys 1064598458 39207
 acme/bin/386/spout - 775 sys sys 1064598459 60029
-acme/bin/386/win - 775 sys sys 1064598460 180032
+acme/bin/386/win - 775 sys sys 1082922246 180754
 acme/bin/Battery - 775 sys sys 1017457907 451
 acme/bin/Isspam - 775 sys sys 1063951165 235
 acme/bin/Perl - 775 sys sys 1015011260 230
@@ -671,7 +671,7 @@ acme/bin/source/spout.c - 664 sys sys 1015011255 1868
 acme/bin/source/win - 20000000775 sys sys 1015011255 0
 acme/bin/source/win/dat.h - 664 sys sys 1017679345 1992
 acme/bin/source/win/fs.c - 664 sys sys 1045503982 2713
-acme/bin/source/win/main.c - 664 sys sys 1046654935 12544
+acme/bin/source/win/main.c - 664 sys sys 1082922243 12609
 acme/bin/source/win/mkfile - 664 sys sys 1046654934 309
 acme/bin/source/win/pipe.c - 664 sys sys 1017679345 2807
 acme/bin/source/win/util.c - 664 sys sys 1017679346 1169
@@ -6816,7 +6816,7 @@ sys/src/cmd/acid/print.c - 664 sys sys 984756705 6840
 sys/src/cmd/acid/proc.c - 664 sys sys 1014924908 4513
 sys/src/cmd/acid/util.c - 664 sys sys 944960738 4297
 sys/src/cmd/acme - 20000000775 sys sys 969511023 0
-sys/src/cmd/acme/acme.c - 664 sys sys 1079044031 19192
+sys/src/cmd/acme/acme.c - 664 sys sys 1082924469 19212
 sys/src/cmd/acme/addr.c - 664 sys sys 1018553456 4787
 sys/src/cmd/acme/buff.c - 664 sys sys 1014926092 5573
 sys/src/cmd/acme/cols.c - 664 sys sys 1079102914 11126
@@ -6838,7 +6838,7 @@ sys/src/cmd/acme/scrl.c - 664 sys sys 1014926095 3072
 sys/src/cmd/acme/text.c - 664 sys sys 1081200110 27335
 sys/src/cmd/acme/time.c - 664 sys sys 1014926095 1783
 sys/src/cmd/acme/util.c - 664 sys sys 1079102916 7412
-sys/src/cmd/acme/wind.c - 664 sys sys 1073566950 11094
+sys/src/cmd/acme/wind.c - 664 sys sys 1082924470 11115
 sys/src/cmd/acme/xfid.c - 664 sys sys 1079044030 19175
 sys/src/cmd/ar.c - 664 sys sys 1046643027 23717
 sys/src/cmd/archfs.c - 664 sys sys 1014925694 3871
@@ -9725,7 +9725,7 @@ sys/src/cmd/map/mkfile - 664 sys sys 944961024 461
 sys/src/cmd/map/route.c - 644 sys sys 964456085 2718
 sys/src/cmd/map/sqrt.c - 664 sys sys 944961024 675
 sys/src/cmd/map/symbol.c - 664 sys sys 964456085 3310
-sys/src/cmd/mc.c - 664 sys sys 957920262 4978
+sys/src/cmd/mc.c - 664 sys sys 1082924484 5520
 sys/src/cmd/md5sum.c - 664 sys sys 1014926238 1009
 sys/src/cmd/mk - 20000000775 sys sys 988249988 0
 sys/src/cmd/mk/acid - 664 sys sys 1055698806 10395
@@ -11859,7 +11859,7 @@ sys/src/libdraw/bytesperline.c - 664 sys sys 1014927873 617
 sys/src/libdraw/chan.c - 664 sys sys 1014927873 1148
 sys/src/libdraw/cloadimage.c - 664 sys sys 1014927873 933
 sys/src/libdraw/computil.c - 664 sys sys 1014927873 680
-sys/src/libdraw/creadimage.c - 664 sys sys 1014927874 2252
+sys/src/libdraw/creadimage.c - 664 sys sys 1082924457 2379
 sys/src/libdraw/debug.c - 664 sys sys 1014927874 206
 sys/src/libdraw/defont.c - 664 sys sys 944961724 30537
 sys/src/libdraw/draw.c - 664 sys sys 1040442971 1321
@@ -11869,11 +11869,11 @@ sys/src/libdraw/ellipse.c - 664 sys sys 1040442971 1936
 sys/src/libdraw/emenuhit.c - 664 sys sys 1014927874 7136
 sys/src/libdraw/event.c - 664 sys sys 1014927875 8985
 sys/src/libdraw/fmt.c - 664 sys sys 1070344369 270
-sys/src/libdraw/font.c - 664 sys sys 1078466654 7542
+sys/src/libdraw/font.c - 664 sys sys 1082924457 7594
 sys/src/libdraw/freesubfont.c - 664 sys sys 984709664 259
 sys/src/libdraw/getdefont.c - 664 sys sys 944961724 1082
 sys/src/libdraw/getrect.c - 664 sys sys 1014927875 3046
-sys/src/libdraw/getsubfont.c - 664 sys sys 1014927875 757
+sys/src/libdraw/getsubfont.c - 664 sys sys 1082924458 772
 sys/src/libdraw/icossin.c - 664 sys sys 944961724 2117
 sys/src/libdraw/icossin2.c - 664 sys sys 944961724 4587
 sys/src/libdraw/init.c - 664 sys sys 1071692552 9082
@@ -11889,8 +11889,8 @@ sys/src/libdraw/newwindow.c - 664 sys sys 1035232036 424
 sys/src/libdraw/openfont.c - 664 sys sys 1014927876 495
 sys/src/libdraw/poly.c - 664 sys sys 1040442974 1689
 sys/src/libdraw/readcolmap.c - 664 sys sys 1014927877 745
-sys/src/libdraw/readimage.c - 664 sys sys 1014927877 2292
-sys/src/libdraw/readsubfont.c - 664 sys sys 944961725 1022
+sys/src/libdraw/readimage.c - 664 sys sys 1082924458 2431
+sys/src/libdraw/readsubfont.c - 664 sys sys 1082924458 1053
 sys/src/libdraw/rectclip.c - 664 sys sys 944961725 571
 sys/src/libdraw/replclipr.c - 664 sys sys 944961725 363
 sys/src/libdraw/rgb.c - 664 sys sys 984709666 1679
@@ -11899,7 +11899,7 @@ sys/src/libdraw/stringbg.c - 664 sys sys 1040442975 1611
 sys/src/libdraw/stringsubfont.c - 664 sys sys 944961725 960
 sys/src/libdraw/stringwidth.c - 664 sys sys 1080400060 1589
 sys/src/libdraw/subfont.c - 664 sys sys 984709666 495
-sys/src/libdraw/subfontcache.c - 664 sys sys 984709666 745
+sys/src/libdraw/subfontcache.c - 664 sys sys 1082924459 752
 sys/src/libdraw/subfontname.c - 664 sys sys 1014927877 762
 sys/src/libdraw/test.c - 664 sys sys 944961725 201
 sys/src/libdraw/unloadimage.c - 664 sys sys 944961725 1000

+ 14 - 0
dist/replica/plan9.log

@@ -14932,3 +14932,17 @@
 1082604707 2 c sys/src/9/ip/ipv6.h - 664 sys sys 1082604125 4260
 1082777540 0 c 386/lib/libmp.a - 664 sys sys 1082776286 81428
 1082862156 0 c 386/lib/libmp.a - 664 sys sys 1082862011 77700
+1082923320 0 c acme/bin/386/win - 775 sys sys 1082922246 180754
+1082923320 1 c acme/bin/source/win/main.c - 664 sys sys 1082922243 12609
+1082925120 0 c 386/bin/acme - 775 sys sys 1082924480 429258
+1082925120 1 c 386/bin/mc - 775 sys sys 1082924486 131746
+1082925120 2 c 386/lib/libdraw.a - 664 sys sys 1082924460 373342
+1082925120 3 c sys/src/cmd/acme/acme.c - 664 sys sys 1082924469 19212
+1082925120 4 c sys/src/cmd/acme/wind.c - 664 sys sys 1082924470 11115
+1082925120 5 c sys/src/cmd/mc.c - 664 sys sys 1082924484 5520
+1082925120 6 c sys/src/libdraw/creadimage.c - 664 sys sys 1082924457 2379
+1082925120 7 c sys/src/libdraw/font.c - 664 sys sys 1082924457 7594
+1082925120 8 c sys/src/libdraw/getsubfont.c - 664 sys sys 1082924458 772
+1082925120 9 c sys/src/libdraw/readimage.c - 664 sys sys 1082924458 2431
+1082925120 10 c sys/src/libdraw/readsubfont.c - 664 sys sys 1082924458 1053
+1082925120 11 c sys/src/libdraw/subfontcache.c - 664 sys sys 1082924459 752

+ 1 - 0
sys/src/cmd/acme/acme.c

@@ -105,6 +105,7 @@ threadmain(int argc, char *argv[])
 		exits("usage");
 	}ARGEND
 
+	quotefmtinstall();
 	cputype = getenv("cputype");
 	objtype = getenv("objtype");
 	home = getenv("home");

+ 1 - 1
sys/src/cmd/acme/wind.c

@@ -532,7 +532,7 @@ winctlprint(Window *w, char *buf, int fonts)
 	n = sprint(buf, "%11d %11d %11d %11d %11d ", w->id, w->tag.file->nc,
 		w->body.file->nc, w->isdir, w->dirty);
 	if(fonts)
-		sprint(buf+n, "%11d %s" , Dx(w->body.r), w->body.reffont->f->name);
+		sprint(buf+n, "%11d %q %11d" , Dx(w->body.r), w->body.reffont->f->name, w->body.maxtab);
 }
 
 void

+ 86 - 53
sys/src/cmd/mc.c

@@ -18,6 +18,7 @@
 #define	ALLOC_QUANTA		4096
 
 int linewidth=WIDTH;
+int mintab=1;
 int colonflag=0;
 int tabflag=0;	/* -t flag turned off forever */
 Rune *cbuf, *cbufp;
@@ -27,11 +28,15 @@ int nalloc=ALLOC_QUANTA;
 int nwalloc=WORD_ALLOC_QUANTA;
 int nchars=0;
 int nwords=0;
+int tabwidth=0;
+Font *font;
 Biobuf	bin;
 Biobuf	bout;
 
 void getwidth(void), readbuf(int), error(char *);
 void scanwords(void), columnate(void), morechars(void);
+int wordwidth(Rune*, int);
+int nexttab(int);
 
 void
 main(int argc, char *argv[])
@@ -59,8 +64,14 @@ main(int argc, char *argv[])
 			break;
 		}
 	}
-	if(lineset == 0)
+	if(lineset == 0){
 		getwidth();
+		if(linewidth <= 1){
+			linewidth = WIDTH;
+			font = nil;
+		}
+	}
+
 	cbuf = cbufp = malloc(ALLOC_QUANTA*(sizeof *cbuf));
 	word = malloc(WORD_ALLOC_QUANTA*(sizeof *word));
 	if(word == 0 || cbuf == 0)
@@ -136,7 +147,7 @@ void
 scanwords(void)
 {
 	Rune *p, *q;
-	int i;
+	int i, w;
 
 	nwords=0;
 	maxwidth=0;
@@ -149,8 +160,9 @@ scanwords(void)
 			}
 			word[nwords++] = q;
 			p[-1] = L'\0';
-			if(p-q > maxwidth)
-				maxwidth = p-q;
+			w = wordwidth(q, p-q-1);
+			if(w > maxwidth)
+				maxwidth = w;
 			q = p;
 		}
 	}
@@ -169,6 +181,7 @@ columnate(void)
 	scanwords();
 	if(nwords==0)
 		return;
+	maxwidth = nexttab(maxwidth+mintab-1);
 	words_per_line = linewidth/maxwidth;
 	if(words_per_line <= 0)
 		words_per_line = 1;
@@ -178,19 +191,18 @@ columnate(void)
 		for(j = i; j < nwords; j += nlines){
 			endcol += maxwidth;
 			Bprint(&bout, "%S", word[j]);
-			col += word[j+1]-word[j]-1;
+			col += wordwidth(word[j], runestrlen(word[j]));
 			if(j+nlines < nwords){
 				if(tabflag) {
-					int tabcol = (col|(TAB-1))+1;
-					while(tabcol <= endcol){
+					while(col < endcol){
 						Bputc(&bout, '\t');
-						col = tabcol;
-						tabcol += TAB;
+						col = nexttab(col);
+					}
+				}else{
+					while(col < endcol){
+						Bputc(&bout, ' ');
+						col++;
 					}
-				}
-				while(col < endcol){
-					Bputc(&bout, ' ');
-					col++;
 				}
 			}
 		}
@@ -198,6 +210,25 @@ columnate(void)
 	}
 }
 
+int
+wordwidth(Rune *w, int nw)
+{
+	if(font)
+		return runestringnwidth(font, w, nw);
+	return nw;
+}
+
+int
+nexttab(int col)
+{
+	if(tabwidth){
+		col += tabwidth;
+		col -= col%tabwidth;
+		return col;
+	}
+	return col+1;
+}
+
 void
 morechars(void)
 {
@@ -222,55 +253,51 @@ terror(Display*, char*)
 	longjmp(drawjmp, 1);
 }
 
-Image*
-window(void)
-{
-	int n, fd;
-	char buf[128];
-
-	/* under acme, don't want to read whole screen width */
-	if(access("/dev/acme", OREAD) == 0)
-		return nil;
-	display = initdisplay("/dev", "/dev", terror);
-	if(display == nil)
-		return nil;
-	snprint(buf, sizeof buf, "%s/winname", display->windir);
-	fd = open(buf, OREAD);
-	if(fd<0 || (n=read(fd, buf, 64))<=0){
-		return nil;
-	}
-	close(fd);
-	buf[n] = 0;
-	return namedimage(display, buf);
-}
-
 void
 getwidth(void)
 {
-	Image *w;
-	int width, fd, n;
-	char fontname[256];
+	int n, fd;
+	char buf[128], *f[10], *p;
 
-	if(setjmp(drawjmp))
+	if(access("/dev/acme", OREAD) >= 0){
+		if((fd = open("/dev/acme/ctl", OREAD)) < 0)
+			return;
+		n = read(fd, buf, sizeof buf-1);
+		close(fd);
+		if(n <= 0)
+			return;
+		buf[n] = 0;
+		n = tokenize(buf, f, nelem(f));
+		if(n < 7)
+			return;
+		if((font = openfont(nil, f[6])) == nil)
+			return;
+		if(n >= 8)
+			tabwidth = atoi(f[7]);
+		else
+			tabwidth = 4*stringwidth(font, "0");
+		mintab = stringwidth(font, "0");
+		linewidth = atoi(f[5]);
+		tabflag = 1;
 		return;
+	}
 
-	w = window();
-	if(w == nil)
-		return;
-	fd = open("/env/font", OREAD);
-	if(fd < 0)
+	if((p = getenv("font")) == nil)
 		return;
-	n = read(fd, fontname, sizeof(fontname)-1);
-	close(fd);
-	if(n < 0)
+	if((font = openfont(nil, p)) == nil)
 		return;
-	fontname[n] = 0;
-	if(fontname[0] == 0)
+	if((fd = open("/dev/window", OREAD)) < 0){
+		font = nil;
 		return;
-	font = openfont(display, fontname);
-	if(font == nil)
+	}
+	n = read(fd, buf, 5*12);
+	close(fd);
+	if(n < 5*12){
+		font = nil;
 		return;
-	width = stringwidth(font, " ");
+	}
+	buf[n] = 0;
+	
 	/* window stucture:
 		4 bit left edge
 		1 bit gap
@@ -279,5 +306,11 @@ getwidth(void)
 		text
 		4 bit right edge
 	*/
-	linewidth = (Dx(w->r)-(4+1+12+4+4))/width;
+	linewidth = atoi(buf+3*12) - atoi(buf+1*12) - (4+1+12+4+4);
+	mintab = stringwidth(font, "0");
+	if((p = getenv("tabstop")) != nil)
+		tabwidth = atoi(p)*stringwidth(font, "0");
+	if(tabwidth == 0)
+		tabwidth = 4*stringwidth(font, "0");
+	tabflag = 1;
 }

+ 32 - 24
sys/src/libdraw/creadimage.c

@@ -54,14 +54,20 @@ creadimage(Display *d, int fd, int dolock)
 		return nil;
 	}
 
-	if(dolock)
-		lockdisplay(d);
-	i = allocimage(d, r, chan, 0, 0);
-	if(dolock)
-		unlockdisplay(d);
-	if(i == nil)
-		return nil;
-	ncblock = _compblocksize(r, i->depth);
+	if(d){
+		if(dolock)
+			lockdisplay(d);
+		i = allocimage(d, r, chan, 0, 0);
+		if(dolock)
+			unlockdisplay(d);
+		if(i == nil)
+			return nil;
+	}else{
+		i = mallocz(sizeof(Image), 1);
+		if(i == nil)
+			return nil;
+	}
+	ncblock = _compblocksize(r, chantodepth(chan));
 	buf = malloc(ncblock);
 	if(buf == nil)
 		goto Errout;
@@ -90,22 +96,24 @@ creadimage(Display *d, int fd, int dolock)
 		}
 		if(readn(fd, buf, nb)!=nb)
 			goto Errout;
-		if(dolock)
-			lockdisplay(d);
-		a = bufimage(i->display, 21+nb);
-		if(a == nil)
-			goto Erroutlock;
-		a[0] = 'Y';
-		BPLONG(a+1, i->id);
-		BPLONG(a+5, r.min.x);
-		BPLONG(a+9, miny);
-		BPLONG(a+13, r.max.x);
-		BPLONG(a+17, maxy);
-		if(!new)	/* old image: flip the data bits */
-			_twiddlecompressed(buf, nb);
-		memmove(a+21, buf, nb);
-		if(dolock)
-			unlockdisplay(d);
+		if(d){
+			if(dolock)
+				lockdisplay(d);
+			a = bufimage(i->display, 21+nb);
+			if(a == nil)
+				goto Erroutlock;
+			a[0] = 'Y';
+			BPLONG(a+1, i->id);
+			BPLONG(a+5, r.min.x);
+			BPLONG(a+9, miny);
+			BPLONG(a+13, r.max.x);
+			BPLONG(a+17, maxy);
+			if(!new)	/* old image: flip the data bits */
+				_twiddlecompressed(buf, nb);
+			memmove(a+21, buf, nb);
+			if(dolock)
+				unlockdisplay(d);
+		}
 		miny = maxy;
 	}
 	free(buf);

+ 10 - 5
sys/src/libdraw/font.c

@@ -156,11 +156,10 @@ cf2subfont(Cachefont *cf, Font *f)
 	if(name == nil){
 		depth = 0;
 		if(f->display){
-			if(f->display->image)
-				depth = f->display->image->depth;
 			if(f->display->screenimage)
 				depth = f->display->screenimage->depth;
-		}
+		}else
+			depth = 8;
 		name = subfontname(cf->name, f->name, depth);
 		if(name == nil)
 			return nil;
@@ -243,7 +242,7 @@ loadchar(Font *f, Rune r, Cacheinfo *c, int h, int noflush, char **subfontname)
 	}
 
 	subf->cf = cf;
-	if(subf->f->ascent > f->ascent){
+	if(subf->f->ascent > f->ascent && f->display){
 		/* should print something? this is a mistake in the font file */
 		/* must prevent c->top from going negative when loading cache */
 		Image *b;
@@ -296,6 +295,8 @@ loadchar(Font *f, Rune r, Cacheinfo *c, int h, int noflush, char **subfontname)
 	c->width = fi->width;
 	c->x = h*f->width;
 	c->left = fi->left;
+	if(f->display == nil)
+		return 1;
 	flushimage(f->display, 0);	/* flush any pending errors */
 	b = bufimage(f->display, 37);
 	if(b == 0)
@@ -352,10 +353,13 @@ fontresize(Font *f, int wid, int ncache, int depth)
 	Display *d;
 
 	ret = 0;
-	d = f->display;
 	if(depth <= 0)
 		depth = 1;
 
+	d = f->display;
+	if(d == nil)
+		goto Nodisplay;
+
 	new = allocimage(d, Rect(0, 0, ncache*wid, f->height), CHAN1(CGrey, depth), 0, 0);
 	if(new == nil){
 		fprint(2, "font cache resize failed: %r\n");
@@ -379,6 +383,7 @@ fontresize(Font *f, int wid, int ncache, int depth)
 	}
 	freeimage(f->cacheimage);
 	f->cacheimage = new;
+    Nodisplay:
 	f->width = wid;
 	f->maxdepth = depth;
 	ret = 1;

+ 3 - 3
sys/src/libdraw/getsubfont.c

@@ -24,10 +24,10 @@ _getsubfont(Display *d, char *name)
 	 * _getsubfont is called only from string.c and stringwidth.c,
 	 * which are known to be safe to have this done.
 	 */
-	if(d->locking == 0)
+	if(d && d->locking == 0)
 		unlockdisplay(d);
-	f = readsubfont(d, name, fd, d->locking==0);
-	if(d->locking == 0)
+	f = readsubfont(d, name, fd, d && d->locking==0);
+	if(d && d->locking == 0)
 		lockdisplay(d);
 	if(f == 0)
 		fprint(2, "getsubfont: can't read %s: %r\n", name);

+ 26 - 14
sys/src/libdraw/readimage.c

@@ -23,7 +23,10 @@ readimage(Display *d, int fd, int dolock)
 		return creadimage(d, fd, dolock);
 	if(readn(fd, hdr+11, 5*12-11) != 5*12-11)
 		return nil;
-	chunk = d->bufsize - 32;	/* a little room for header */
+	if(d)
+		chunk = d->bufsize - 32;	/* a little room for header */
+	else
+		chunk = 8192;
 
 	/*
 	 * distinguish new channel descriptor from old ldepth.
@@ -69,13 +72,20 @@ readimage(Display *d, int fd, int dolock)
 	maxy = r.max.y;
 
 	l = bytesperline(r, chantodepth(chan));
-	if(dolock)
-		lockdisplay(d);
-	i = allocimage(d, r, chan, 0, -1);
-	if(dolock)
-		unlockdisplay(d);
-	if(i == nil)
-		return nil;
+	if(d){
+		if(dolock)
+			lockdisplay(d);
+		i = allocimage(d, r, chan, 0, -1);
+		if(dolock)
+			unlockdisplay(d);
+		if(i == nil)
+			return nil;
+	}else{
+		i = mallocz(sizeof(Image), 1);
+		if(i == nil)
+			return nil;
+	}
+
 	tmp = malloc(chunk);
 	if(tmp == nil)
 		goto Err;
@@ -105,12 +115,14 @@ readimage(Display *d, int fd, int dolock)
 			for(j=0; j<chunk; j++)
 				tmp[j] ^= 0xFF;
 
-		if(dolock)
-			lockdisplay(d);
-		if(loadimage(i, Rect(r.min.x, miny, r.max.x, miny+dy), tmp, chunk) <= 0)
-			goto Err1;
-		if(dolock)
-			unlockdisplay(d);
+		if(d){
+			if(dolock)
+				lockdisplay(d);
+			if(loadimage(i, Rect(r.min.x, miny, r.max.x, miny+dy), tmp, chunk) <= 0)
+				goto Err1;
+			if(dolock)
+				unlockdisplay(d);
+		}
 		miny += dy;
 	}
 	free(tmp);

+ 3 - 1
sys/src/libdraw/readsubfont.c

@@ -27,10 +27,12 @@ readsubfonti(Display*d, char *name, int fd, Image *ai, int dolock)
 	n = atoi(hdr);
 	p = malloc(6*(n+1));
 	if(p == nil)
-		return nil;
+		goto Err;
 	if(read(fd, p, 6*(n+1)) != 6*(n+1)){
 		werrstr("rdsubfonfile: fontchar read error: %r");
     Err:
+		if(ai == nil)
+			freeimage(i);
 		free(p);
 		return nil;
 	}

+ 3 - 2
sys/src/libdraw/subfontcache.c

@@ -12,9 +12,10 @@ Subfont	*lastsubfont;
 Subfont*
 lookupsubfont(Display *d, char *name)
 {
-	if(strcmp(name, "*default*") == 0)
+	if(d && strcmp(name, "*default*") == 0)
 		return d->defaultsubfont;
-	if(lastname && strcmp(name, lastname)==0 && d==lastsubfont->bits->display){
+	if(lastname && strcmp(name, lastname)==0)
+	if(d==lastsubfont->bits->display){
 		lastsubfont->ref++;
 		return lastsubfont;
 	}