xref: /plan9/sys/src/cmd/acme/rows.c (revision 348c7de82bbd3bc66571af32702d3d82531de21a)
17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier #include <thread.h>
57dd7cddfSDavid du Colombier #include <cursor.h>
67dd7cddfSDavid du Colombier #include <mouse.h>
77dd7cddfSDavid du Colombier #include <keyboard.h>
87dd7cddfSDavid du Colombier #include <frame.h>
97dd7cddfSDavid du Colombier #include <fcall.h>
107dd7cddfSDavid du Colombier #include <bio.h>
117dd7cddfSDavid du Colombier #include <plumb.h>
127dd7cddfSDavid du Colombier #include "dat.h"
137dd7cddfSDavid du Colombier #include "fns.h"
147dd7cddfSDavid du Colombier 
157dd7cddfSDavid du Colombier void
rowinit(Row * row,Rectangle r)167dd7cddfSDavid du Colombier rowinit(Row *row, Rectangle r)
177dd7cddfSDavid du Colombier {
187dd7cddfSDavid du Colombier 	Rectangle r1;
197dd7cddfSDavid du Colombier 	Text *t;
207dd7cddfSDavid du Colombier 
217dd7cddfSDavid du Colombier 	draw(screen, r, display->white, nil, ZP);
227dd7cddfSDavid du Colombier 	row->r = r;
237dd7cddfSDavid du Colombier 	row->col = nil;
247dd7cddfSDavid du Colombier 	row->ncol = 0;
257dd7cddfSDavid du Colombier 	r1 = r;
267dd7cddfSDavid du Colombier 	r1.max.y = r1.min.y + font->height;
277dd7cddfSDavid du Colombier 	t = &row->tag;
287dd7cddfSDavid du Colombier 	textinit(t, fileaddtext(nil, t), r1, rfget(FALSE, FALSE, FALSE, nil), tagcols);
297dd7cddfSDavid du Colombier 	t->what = Rowtag;
307dd7cddfSDavid du Colombier 	t->row = row;
317dd7cddfSDavid du Colombier 	t->w = nil;
327dd7cddfSDavid du Colombier 	t->col = nil;
337dd7cddfSDavid du Colombier 	r1.min.y = r1.max.y;
347dd7cddfSDavid du Colombier 	r1.max.y += Border;
357dd7cddfSDavid du Colombier 	draw(screen, r1, display->black, nil, ZP);
367dd7cddfSDavid du Colombier 	textinsert(t, 0, L"Newcol Kill Putall Dump Exit ", 29, TRUE);
377dd7cddfSDavid du Colombier 	textsetselect(t, t->file->nc, t->file->nc);
387dd7cddfSDavid du Colombier }
397dd7cddfSDavid du Colombier 
407dd7cddfSDavid du Colombier Column*
rowadd(Row * row,Column * c,int x)417dd7cddfSDavid du Colombier rowadd(Row *row, Column *c, int x)
427dd7cddfSDavid du Colombier {
437dd7cddfSDavid du Colombier 	Rectangle r, r1;
447dd7cddfSDavid du Colombier 	Column *d;
457dd7cddfSDavid du Colombier 	int i;
467dd7cddfSDavid du Colombier 
477dd7cddfSDavid du Colombier 	d = nil;
487dd7cddfSDavid du Colombier 	r = row->r;
497dd7cddfSDavid du Colombier 	r.min.y = row->tag.r.max.y+Border;
507dd7cddfSDavid du Colombier 	if(x<r.min.x && row->ncol>0){	/*steal 40% of last column by default */
517dd7cddfSDavid du Colombier 		d = row->col[row->ncol-1];
527dd7cddfSDavid du Colombier 		x = d->r.min.x + 3*Dx(d->r)/5;
537dd7cddfSDavid du Colombier 	}
547dd7cddfSDavid du Colombier 	/* look for column we'll land on */
557dd7cddfSDavid du Colombier 	for(i=0; i<row->ncol; i++){
567dd7cddfSDavid du Colombier 		d = row->col[i];
577dd7cddfSDavid du Colombier 		if(x < d->r.max.x)
587dd7cddfSDavid du Colombier 			break;
597dd7cddfSDavid du Colombier 	}
607dd7cddfSDavid du Colombier 	if(row->ncol > 0){
617dd7cddfSDavid du Colombier 		if(i < row->ncol)
627dd7cddfSDavid du Colombier 			i++;	/* new column will go after d */
637dd7cddfSDavid du Colombier 		r = d->r;
647dd7cddfSDavid du Colombier 		if(Dx(r) < 100)
657dd7cddfSDavid du Colombier 			return nil;
667dd7cddfSDavid du Colombier 		draw(screen, r, display->white, nil, ZP);
677dd7cddfSDavid du Colombier 		r1 = r;
687dd7cddfSDavid du Colombier 		r1.max.x = min(x, r.max.x-50);
697dd7cddfSDavid du Colombier 		if(Dx(r1) < 50)
707dd7cddfSDavid du Colombier 			r1.max.x = r1.min.x+50;
717dd7cddfSDavid du Colombier 		colresize(d, r1);
727dd7cddfSDavid du Colombier 		r1.min.x = r1.max.x;
737dd7cddfSDavid du Colombier 		r1.max.x = r1.min.x+Border;
747dd7cddfSDavid du Colombier 		draw(screen, r1, display->black, nil, ZP);
757dd7cddfSDavid du Colombier 		r.min.x = r1.max.x;
767dd7cddfSDavid du Colombier 	}
777dd7cddfSDavid du Colombier 	if(c == nil){
787dd7cddfSDavid du Colombier 		c = emalloc(sizeof(Column));
797dd7cddfSDavid du Colombier 		colinit(c, r);
807dd7cddfSDavid du Colombier 		incref(&reffont);
817dd7cddfSDavid du Colombier 	}else
827dd7cddfSDavid du Colombier 		colresize(c, r);
837dd7cddfSDavid du Colombier 	c->row = row;
847dd7cddfSDavid du Colombier 	c->tag.row = row;
857dd7cddfSDavid du Colombier 	row->col = realloc(row->col, (row->ncol+1)*sizeof(Column*));
867dd7cddfSDavid du Colombier 	memmove(row->col+i+1, row->col+i, (row->ncol-i)*sizeof(Column*));
877dd7cddfSDavid du Colombier 	row->col[i] = c;
887dd7cddfSDavid du Colombier 	row->ncol++;
897dd7cddfSDavid du Colombier 	clearmouse();
907dd7cddfSDavid du Colombier 	return c;
917dd7cddfSDavid du Colombier }
927dd7cddfSDavid du Colombier 
937dd7cddfSDavid du Colombier void
rowresize(Row * row,Rectangle r)947dd7cddfSDavid du Colombier rowresize(Row *row, Rectangle r)
957dd7cddfSDavid du Colombier {
967dd7cddfSDavid du Colombier 	int i, dx, odx;
977dd7cddfSDavid du Colombier 	Rectangle r1, r2;
987dd7cddfSDavid du Colombier 	Column *c;
997dd7cddfSDavid du Colombier 
1007dd7cddfSDavid du Colombier 	dx = Dx(r);
1017dd7cddfSDavid du Colombier 	odx = Dx(row->r);
1027dd7cddfSDavid du Colombier 	row->r = r;
1037dd7cddfSDavid du Colombier 	r1 = r;
1047dd7cddfSDavid du Colombier 	r1.max.y = r1.min.y + font->height;
1057dd7cddfSDavid du Colombier 	textresize(&row->tag, r1);
1067dd7cddfSDavid du Colombier 	r1.min.y = r1.max.y;
1077dd7cddfSDavid du Colombier 	r1.max.y += Border;
1087dd7cddfSDavid du Colombier 	draw(screen, r1, display->black, nil, ZP);
1097dd7cddfSDavid du Colombier 	r.min.y = r1.max.y;
1107dd7cddfSDavid du Colombier 	r1 = r;
1117dd7cddfSDavid du Colombier 	r1.max.x = r1.min.x;
1127dd7cddfSDavid du Colombier 	for(i=0; i<row->ncol; i++){
1137dd7cddfSDavid du Colombier 		c = row->col[i];
1147dd7cddfSDavid du Colombier 		r1.min.x = r1.max.x;
1157dd7cddfSDavid du Colombier 		if(i == row->ncol-1)
1167dd7cddfSDavid du Colombier 			r1.max.x = r.max.x;
1177dd7cddfSDavid du Colombier 		else
1187dd7cddfSDavid du Colombier 			r1.max.x = r1.min.x+Dx(c->r)*dx/odx;
1197dd7cddfSDavid du Colombier 		if(i > 0){
1207dd7cddfSDavid du Colombier 			r2 = r1;
1217dd7cddfSDavid du Colombier 			r2.max.x = r2.min.x+Border;
1227dd7cddfSDavid du Colombier 			draw(screen, r2, display->black, nil, ZP);
1237dd7cddfSDavid du Colombier 			r1.min.x = r2.max.x;
1247dd7cddfSDavid du Colombier 		}
1257dd7cddfSDavid du Colombier 		colresize(c, r1);
1267dd7cddfSDavid du Colombier 	}
1277dd7cddfSDavid du Colombier }
1287dd7cddfSDavid du Colombier 
1297dd7cddfSDavid du Colombier void
rowdragcol(Row * row,Column * c,int)1307dd7cddfSDavid du Colombier rowdragcol(Row *row, Column *c, int)
1317dd7cddfSDavid du Colombier {
1327dd7cddfSDavid du Colombier 	Rectangle r;
1337dd7cddfSDavid du Colombier 	int i, b, x;
1347dd7cddfSDavid du Colombier 	Point p, op;
1357dd7cddfSDavid du Colombier 	Column *d;
1367dd7cddfSDavid du Colombier 
1377dd7cddfSDavid du Colombier 	clearmouse();
1387dd7cddfSDavid du Colombier 	setcursor(mousectl, &boxcursor);
1397dd7cddfSDavid du Colombier 	b = mouse->buttons;
1407dd7cddfSDavid du Colombier 	op = mouse->xy;
1417dd7cddfSDavid du Colombier 	while(mouse->buttons == b)
1427dd7cddfSDavid du Colombier 		readmouse(mousectl);
1437dd7cddfSDavid du Colombier 	setcursor(mousectl, nil);
1447dd7cddfSDavid du Colombier 	if(mouse->buttons){
1457dd7cddfSDavid du Colombier 		while(mouse->buttons)
1467dd7cddfSDavid du Colombier 			readmouse(mousectl);
1477dd7cddfSDavid du Colombier 		return;
1487dd7cddfSDavid du Colombier 	}
1497dd7cddfSDavid du Colombier 
1507dd7cddfSDavid du Colombier 	for(i=0; i<row->ncol; i++)
1517dd7cddfSDavid du Colombier 		if(row->col[i] == c)
1527dd7cddfSDavid du Colombier 			goto Found;
1537dd7cddfSDavid du Colombier 	error("can't find column");
1547dd7cddfSDavid du Colombier 
1557dd7cddfSDavid du Colombier   Found:
1567dd7cddfSDavid du Colombier 	p = mouse->xy;
1577dd7cddfSDavid du Colombier 	if((abs(p.x-op.x)<5 && abs(p.y-op.y)<5))
1587dd7cddfSDavid du Colombier 		return;
1597dd7cddfSDavid du Colombier 	if((i>0 && p.x<row->col[i-1]->r.min.x) || (i<row->ncol-1 && p.x>c->r.max.x)){
1607dd7cddfSDavid du Colombier 		/* shuffle */
1617dd7cddfSDavid du Colombier 		x = c->r.min.x;
1627dd7cddfSDavid du Colombier 		rowclose(row, c, FALSE);
1637dd7cddfSDavid du Colombier 		if(rowadd(row, c, p.x) == nil)	/* whoops! */
1647dd7cddfSDavid du Colombier 		if(rowadd(row, c, x) == nil)		/* WHOOPS! */
1657dd7cddfSDavid du Colombier 		if(rowadd(row, c, -1)==nil){		/* shit! */
1667dd7cddfSDavid du Colombier 			rowclose(row, c, TRUE);
1677dd7cddfSDavid du Colombier 			return;
1687dd7cddfSDavid du Colombier 		}
1697dd7cddfSDavid du Colombier 		colmousebut(c);
1707dd7cddfSDavid du Colombier 		return;
1717dd7cddfSDavid du Colombier 	}
172*348c7de8SDavid du Colombier 	if(i == 0)
173*348c7de8SDavid du Colombier 		return;
1747dd7cddfSDavid du Colombier 	d = row->col[i-1];
1757dd7cddfSDavid du Colombier 	if(p.x < d->r.min.x+80+Scrollwid)
1767dd7cddfSDavid du Colombier 		p.x = d->r.min.x+80+Scrollwid;
1777dd7cddfSDavid du Colombier 	if(p.x > c->r.max.x-80-Scrollwid)
1787dd7cddfSDavid du Colombier 		p.x = c->r.max.x-80-Scrollwid;
1797dd7cddfSDavid du Colombier 	r = d->r;
1807dd7cddfSDavid du Colombier 	r.max.x = c->r.max.x;
1817dd7cddfSDavid du Colombier 	draw(screen, r, display->white, nil, ZP);
1827dd7cddfSDavid du Colombier 	r.max.x = p.x;
1837dd7cddfSDavid du Colombier 	colresize(d, r);
1847dd7cddfSDavid du Colombier 	r = c->r;
1857dd7cddfSDavid du Colombier 	r.min.x = p.x;
1867dd7cddfSDavid du Colombier 	r.max.x = r.min.x;
1877dd7cddfSDavid du Colombier 	r.max.x += Border;
1887dd7cddfSDavid du Colombier 	draw(screen, r, display->black, nil, ZP);
1897dd7cddfSDavid du Colombier 	r.min.x = r.max.x;
1907dd7cddfSDavid du Colombier 	r.max.x = c->r.max.x;
1917dd7cddfSDavid du Colombier 	colresize(c, r);
1927dd7cddfSDavid du Colombier 	colmousebut(c);
1937dd7cddfSDavid du Colombier }
1947dd7cddfSDavid du Colombier 
1957dd7cddfSDavid du Colombier void
rowclose(Row * row,Column * c,int dofree)1967dd7cddfSDavid du Colombier rowclose(Row *row, Column *c, int dofree)
1977dd7cddfSDavid du Colombier {
1987dd7cddfSDavid du Colombier 	Rectangle r;
1997dd7cddfSDavid du Colombier 	int i;
2007dd7cddfSDavid du Colombier 
2017dd7cddfSDavid du Colombier 	for(i=0; i<row->ncol; i++)
2027dd7cddfSDavid du Colombier 		if(row->col[i] == c)
2037dd7cddfSDavid du Colombier 			goto Found;
2047dd7cddfSDavid du Colombier 	error("can't find column");
2057dd7cddfSDavid du Colombier   Found:
2067dd7cddfSDavid du Colombier 	r = c->r;
2077dd7cddfSDavid du Colombier 	if(dofree)
2087dd7cddfSDavid du Colombier 		colcloseall(c);
2097dd7cddfSDavid du Colombier 	memmove(row->col+i, row->col+i+1, (row->ncol-i)*sizeof(Column*));
2107dd7cddfSDavid du Colombier 	row->ncol--;
2117dd7cddfSDavid du Colombier 	row->col = realloc(row->col, row->ncol*sizeof(Column*));
2127dd7cddfSDavid du Colombier 	if(row->ncol == 0){
2137dd7cddfSDavid du Colombier 		draw(screen, r, display->white, nil, ZP);
2147dd7cddfSDavid du Colombier 		return;
2157dd7cddfSDavid du Colombier 	}
2167dd7cddfSDavid du Colombier 	if(i == row->ncol){		/* extend last column right */
2177dd7cddfSDavid du Colombier 		c = row->col[i-1];
2187dd7cddfSDavid du Colombier 		r.min.x = c->r.min.x;
2197dd7cddfSDavid du Colombier 		r.max.x = row->r.max.x;
2207dd7cddfSDavid du Colombier 	}else{			/* extend next window left */
2217dd7cddfSDavid du Colombier 		c = row->col[i];
2227dd7cddfSDavid du Colombier 		r.max.x = c->r.max.x;
2237dd7cddfSDavid du Colombier 	}
2247dd7cddfSDavid du Colombier 	draw(screen, r, display->white, nil, ZP);
2257dd7cddfSDavid du Colombier 	colresize(c, r);
2267dd7cddfSDavid du Colombier }
2277dd7cddfSDavid du Colombier 
2287dd7cddfSDavid du Colombier Column*
rowwhichcol(Row * row,Point p)2297dd7cddfSDavid du Colombier rowwhichcol(Row *row, Point p)
2307dd7cddfSDavid du Colombier {
2317dd7cddfSDavid du Colombier 	int i;
2327dd7cddfSDavid du Colombier 	Column *c;
2337dd7cddfSDavid du Colombier 
2347dd7cddfSDavid du Colombier 	for(i=0; i<row->ncol; i++){
2357dd7cddfSDavid du Colombier 		c = row->col[i];
2367dd7cddfSDavid du Colombier 		if(ptinrect(p, c->r))
2377dd7cddfSDavid du Colombier 			return c;
2387dd7cddfSDavid du Colombier 	}
2397dd7cddfSDavid du Colombier 	return nil;
2407dd7cddfSDavid du Colombier }
2417dd7cddfSDavid du Colombier 
2427dd7cddfSDavid du Colombier Text*
rowwhich(Row * row,Point p)2437dd7cddfSDavid du Colombier rowwhich(Row *row, Point p)
2447dd7cddfSDavid du Colombier {
2457dd7cddfSDavid du Colombier 	Column *c;
2467dd7cddfSDavid du Colombier 
2477dd7cddfSDavid du Colombier 	if(ptinrect(p, row->tag.all))
2487dd7cddfSDavid du Colombier 		return &row->tag;
2497dd7cddfSDavid du Colombier 	c = rowwhichcol(row, p);
2507dd7cddfSDavid du Colombier 	if(c)
2517dd7cddfSDavid du Colombier 		return colwhich(c, p);
2527dd7cddfSDavid du Colombier 	return nil;
2537dd7cddfSDavid du Colombier }
2547dd7cddfSDavid du Colombier 
2557dd7cddfSDavid du Colombier Text*
rowtype(Row * row,Rune r,Point p)2567dd7cddfSDavid du Colombier rowtype(Row *row, Rune r, Point p)
2577dd7cddfSDavid du Colombier {
2587dd7cddfSDavid du Colombier 	Window *w;
2597dd7cddfSDavid du Colombier 	Text *t;
2607dd7cddfSDavid du Colombier 
2617dd7cddfSDavid du Colombier 	clearmouse();
2627dd7cddfSDavid du Colombier 	qlock(row);
2637dd7cddfSDavid du Colombier 	if(bartflag)
2647dd7cddfSDavid du Colombier 		t = barttext;
2657dd7cddfSDavid du Colombier 	else
2667dd7cddfSDavid du Colombier 		t = rowwhich(row, p);
2677dd7cddfSDavid du Colombier 	if(t!=nil && !(t->what==Tag && ptinrect(p, t->scrollr))){
2687dd7cddfSDavid du Colombier 		w = t->w;
2697dd7cddfSDavid du Colombier 		if(w == nil)
2707dd7cddfSDavid du Colombier 			texttype(t, r);
2717dd7cddfSDavid du Colombier 		else{
2727dd7cddfSDavid du Colombier 			winlock(w, 'K');
2737dd7cddfSDavid du Colombier 			wintype(w, t, r);
2747dd7cddfSDavid du Colombier 			winunlock(w);
2757dd7cddfSDavid du Colombier 		}
2767dd7cddfSDavid du Colombier 	}
2777dd7cddfSDavid du Colombier 	qunlock(row);
2787dd7cddfSDavid du Colombier 	return t;
2797dd7cddfSDavid du Colombier }
2807dd7cddfSDavid du Colombier 
2817dd7cddfSDavid du Colombier int
rowclean(Row * row)2827dd7cddfSDavid du Colombier rowclean(Row *row)
2837dd7cddfSDavid du Colombier {
2847dd7cddfSDavid du Colombier 	int clean;
2857dd7cddfSDavid du Colombier 	int i;
2867dd7cddfSDavid du Colombier 
2877dd7cddfSDavid du Colombier 	clean = TRUE;
2887dd7cddfSDavid du Colombier 	for(i=0; i<row->ncol; i++)
2897dd7cddfSDavid du Colombier 		clean &= colclean(row->col[i]);
2907dd7cddfSDavid du Colombier 	return clean;
2917dd7cddfSDavid du Colombier }
2927dd7cddfSDavid du Colombier 
2937dd7cddfSDavid du Colombier void
rowdump(Row * row,char * file)2947dd7cddfSDavid du Colombier rowdump(Row *row, char *file)
2957dd7cddfSDavid du Colombier {
2967dd7cddfSDavid du Colombier 	int i, j, fd, m, n, dumped;
2977dd7cddfSDavid du Colombier 	uint q0, q1;
2987dd7cddfSDavid du Colombier 	Biobuf *b;
2997dd7cddfSDavid du Colombier 	char *buf, *a, *fontname;
3007dd7cddfSDavid du Colombier 	Rune *r;
3017dd7cddfSDavid du Colombier 	Column *c;
3027dd7cddfSDavid du Colombier 	Window *w, *w1;
3037dd7cddfSDavid du Colombier 	Text *t;
3047dd7cddfSDavid du Colombier 
3057dd7cddfSDavid du Colombier 	if(row->ncol == 0)
3067dd7cddfSDavid du Colombier 		return;
3077dd7cddfSDavid du Colombier 	buf = fbufalloc();
3087dd7cddfSDavid du Colombier 	if(file == nil){
3097dd7cddfSDavid du Colombier 		if(home == nil){
3107dd7cddfSDavid du Colombier 			warning(nil, "can't find file for dump: $home not defined\n");
3117dd7cddfSDavid du Colombier 			goto Rescue;
3127dd7cddfSDavid du Colombier 		}
3137dd7cddfSDavid du Colombier 		sprint(buf, "%s/acme.dump", home);
3147dd7cddfSDavid du Colombier 		file = buf;
3157dd7cddfSDavid du Colombier 	}
3167dd7cddfSDavid du Colombier 	fd = create(file, OWRITE, 0600);
3177dd7cddfSDavid du Colombier 	if(fd < 0){
3187dd7cddfSDavid du Colombier 		warning(nil, "can't open %s: %r\n", file);
3197dd7cddfSDavid du Colombier 		goto Rescue;
3207dd7cddfSDavid du Colombier 	}
3217dd7cddfSDavid du Colombier 	b = emalloc(sizeof(Biobuf));
3227dd7cddfSDavid du Colombier 	Binit(b, fd, OWRITE);
3237dd7cddfSDavid du Colombier 	r = fbufalloc();
3247dd7cddfSDavid du Colombier 	Bprint(b, "%s\n", wdir);
3257dd7cddfSDavid du Colombier 	Bprint(b, "%s\n", fontnames[0]);
3267dd7cddfSDavid du Colombier 	Bprint(b, "%s\n", fontnames[1]);
3277dd7cddfSDavid du Colombier 	for(i=0; i<row->ncol; i++){
3287dd7cddfSDavid du Colombier 		c = row->col[i];
3297dd7cddfSDavid du Colombier 		Bprint(b, "%11d", 100*(c->r.min.x-row->r.min.x)/Dx(row->r));
3307dd7cddfSDavid du Colombier 		if(i == row->ncol-1)
3317dd7cddfSDavid du Colombier 			Bputc(b, '\n');
3327dd7cddfSDavid du Colombier 		else
3337dd7cddfSDavid du Colombier 			Bputc(b, ' ');
3347dd7cddfSDavid du Colombier 	}
3357dd7cddfSDavid du Colombier 	for(i=0; i<row->ncol; i++){
3367dd7cddfSDavid du Colombier 		c = row->col[i];
3377dd7cddfSDavid du Colombier 		for(j=0; j<c->nw; j++)
3387dd7cddfSDavid du Colombier 			c->w[j]->body.file->dumpid = 0;
3397dd7cddfSDavid du Colombier 	}
3407dd7cddfSDavid du Colombier 	for(i=0; i<row->ncol; i++){
3417dd7cddfSDavid du Colombier 		c = row->col[i];
3427dd7cddfSDavid du Colombier 		for(j=0; j<c->nw; j++){
3437dd7cddfSDavid du Colombier 			w = c->w[j];
3447dd7cddfSDavid du Colombier 			wincommit(w, &w->tag);
3457dd7cddfSDavid du Colombier 			t = &w->body;
3467dd7cddfSDavid du Colombier 			/* windows owned by others get special treatment */
3477dd7cddfSDavid du Colombier 			if(w->nopen[QWevent] > 0)
3487dd7cddfSDavid du Colombier 				if(w->dumpstr == nil)
3497dd7cddfSDavid du Colombier 					continue;
3507dd7cddfSDavid du Colombier 			/* zeroxes of external windows are tossed */
3517dd7cddfSDavid du Colombier 			if(t->file->ntext > 1)
3527dd7cddfSDavid du Colombier 				for(n=0; n<t->file->ntext; n++){
3537dd7cddfSDavid du Colombier 					w1 = t->file->text[n]->w;
3547dd7cddfSDavid du Colombier 					if(w == w1)
3557dd7cddfSDavid du Colombier 						continue;
3567dd7cddfSDavid du Colombier 					if(w1->nopen[QWevent])
3577dd7cddfSDavid du Colombier 						goto Continue2;
3587dd7cddfSDavid du Colombier 				}
3597dd7cddfSDavid du Colombier 			fontname = "";
3607dd7cddfSDavid du Colombier 			if(t->reffont->f != font)
3617dd7cddfSDavid du Colombier 				fontname = t->reffont->f->name;
3627dd7cddfSDavid du Colombier 			if(t->file->nname)
3637dd7cddfSDavid du Colombier 				a = runetobyte(t->file->name, t->file->nname);
3647dd7cddfSDavid du Colombier 			else
3657dd7cddfSDavid du Colombier 				a = emalloc(1);
3667dd7cddfSDavid du Colombier 			if(t->file->dumpid){
3677dd7cddfSDavid du Colombier 				dumped = FALSE;
3687dd7cddfSDavid du Colombier 				Bprint(b, "x%11d %11d %11d %11d %11d %s\n", i, t->file->dumpid,
3697dd7cddfSDavid du Colombier 					w->body.q0, w->body.q1,
3707dd7cddfSDavid du Colombier 					100*(w->r.min.y-c->r.min.y)/Dy(c->r),
3717dd7cddfSDavid du Colombier 					fontname);
3727dd7cddfSDavid du Colombier 			}else if(w->dumpstr){
3737dd7cddfSDavid du Colombier 				dumped = FALSE;
3747dd7cddfSDavid du Colombier 				Bprint(b, "e%11d %11d %11d %11d %11d %s\n", i, t->file->dumpid,
3757dd7cddfSDavid du Colombier 					0, 0,
3767dd7cddfSDavid du Colombier 					100*(w->r.min.y-c->r.min.y)/Dy(c->r),
3777dd7cddfSDavid du Colombier 					fontname);
3787dd7cddfSDavid du Colombier 			}else if((w->dirty==FALSE && access(a, 0)==0) || w->isdir){
3797dd7cddfSDavid du Colombier 				dumped = FALSE;
3807dd7cddfSDavid du Colombier 				t->file->dumpid = w->id;
3817dd7cddfSDavid du Colombier 				Bprint(b, "f%11d %11d %11d %11d %11d %s\n", i, w->id,
3827dd7cddfSDavid du Colombier 					w->body.q0, w->body.q1,
3837dd7cddfSDavid du Colombier 					100*(w->r.min.y-c->r.min.y)/Dy(c->r),
3847dd7cddfSDavid du Colombier 					fontname);
3857dd7cddfSDavid du Colombier 			}else{
3867dd7cddfSDavid du Colombier 				dumped = TRUE;
3877dd7cddfSDavid du Colombier 				t->file->dumpid = w->id;
3887dd7cddfSDavid du Colombier 				Bprint(b, "F%11d %11d %11d %11d %11d %11d %s\n", i, j,
3897dd7cddfSDavid du Colombier 					w->body.q0, w->body.q1,
3907dd7cddfSDavid du Colombier 					100*(w->r.min.y-c->r.min.y)/Dy(c->r),
3917dd7cddfSDavid du Colombier 					w->body.file->nc, fontname);
3927dd7cddfSDavid du Colombier 			}
3937dd7cddfSDavid du Colombier 			free(a);
3949a747e4fSDavid du Colombier 			winctlprint(w, buf, 0);
3957dd7cddfSDavid du Colombier 			Bwrite(b, buf, strlen(buf));
3967dd7cddfSDavid du Colombier 			m = min(RBUFSIZE, w->tag.file->nc);
3977dd7cddfSDavid du Colombier 			bufread(w->tag.file, 0, r, m);
3987dd7cddfSDavid du Colombier 			n = 0;
3997dd7cddfSDavid du Colombier 			while(n<m && r[n]!='\n')
4007dd7cddfSDavid du Colombier 				n++;
4017dd7cddfSDavid du Colombier 			r[n++] = '\n';
4027dd7cddfSDavid du Colombier 			Bprint(b, "%.*S", n, r);
4037dd7cddfSDavid du Colombier 			if(dumped){
4047dd7cddfSDavid du Colombier 				q0 = 0;
4057dd7cddfSDavid du Colombier 				q1 = t->file->nc;
4067dd7cddfSDavid du Colombier 				while(q0 < q1){
4077dd7cddfSDavid du Colombier 					n = q1 - q0;
4087dd7cddfSDavid du Colombier 					if(n > BUFSIZE/UTFmax)
4097dd7cddfSDavid du Colombier 						n = BUFSIZE/UTFmax;
4107dd7cddfSDavid du Colombier 					bufread(t->file, q0, r, n);
4117dd7cddfSDavid du Colombier 					Bprint(b, "%.*S", n, r);
4127dd7cddfSDavid du Colombier 					q0 += n;
4137dd7cddfSDavid du Colombier 				}
4147dd7cddfSDavid du Colombier 			}
4157dd7cddfSDavid du Colombier 			if(w->dumpstr){
4167dd7cddfSDavid du Colombier 				if(w->dumpdir)
4177dd7cddfSDavid du Colombier 					Bprint(b, "%s\n%s\n", w->dumpdir, w->dumpstr);
4187dd7cddfSDavid du Colombier 				else
4197dd7cddfSDavid du Colombier 					Bprint(b, "\n%s\n", w->dumpstr);
4207dd7cddfSDavid du Colombier 			}
4217dd7cddfSDavid du Colombier     Continue2:;
4227dd7cddfSDavid du Colombier 		}
4237dd7cddfSDavid du Colombier 	}
4247dd7cddfSDavid du Colombier 	Bterm(b);
4257dd7cddfSDavid du Colombier 	close(fd);
4267dd7cddfSDavid du Colombier 	free(b);
4277dd7cddfSDavid du Colombier 	fbuffree(r);
4287dd7cddfSDavid du Colombier 
4297dd7cddfSDavid du Colombier    Rescue:
4307dd7cddfSDavid du Colombier 	fbuffree(buf);
4317dd7cddfSDavid du Colombier }
4327dd7cddfSDavid du Colombier 
4337dd7cddfSDavid du Colombier static
4347dd7cddfSDavid du Colombier char*
rdline(Biobuf * b,int * linep)4357dd7cddfSDavid du Colombier rdline(Biobuf *b, int *linep)
4367dd7cddfSDavid du Colombier {
4377dd7cddfSDavid du Colombier 	char *l;
4387dd7cddfSDavid du Colombier 
4397dd7cddfSDavid du Colombier 	l = Brdline(b, '\n');
4407dd7cddfSDavid du Colombier 	if(l)
4417dd7cddfSDavid du Colombier 		(*linep)++;
4427dd7cddfSDavid du Colombier 	return l;
4437dd7cddfSDavid du Colombier }
4447dd7cddfSDavid du Colombier 
4459a747e4fSDavid du Colombier /*
4469a747e4fSDavid du Colombier  * Get font names from load file so we don't load fonts we won't use
4479a747e4fSDavid du Colombier  */
4489a747e4fSDavid du Colombier void
rowloadfonts(char * file)4499a747e4fSDavid du Colombier rowloadfonts(char *file)
4509a747e4fSDavid du Colombier {
4519a747e4fSDavid du Colombier 	int i;
4529a747e4fSDavid du Colombier 	Biobuf *b;
4539a747e4fSDavid du Colombier 	char *l;
4549a747e4fSDavid du Colombier 
4559a747e4fSDavid du Colombier 	b = Bopen(file, OREAD);
4569a747e4fSDavid du Colombier 	if(b == nil)
4579a747e4fSDavid du Colombier 		return;
4589a747e4fSDavid du Colombier 	/* current directory */
4599a747e4fSDavid du Colombier 	l = Brdline(b, '\n');
4609a747e4fSDavid du Colombier 	if(l == nil)
4619a747e4fSDavid du Colombier 		goto Return;
4629a747e4fSDavid du Colombier 	/* global fonts */
4639a747e4fSDavid du Colombier 	for(i=0; i<2; i++){
4649a747e4fSDavid du Colombier 		l = Brdline(b, '\n');
4659a747e4fSDavid du Colombier 		if(l == nil)
4669a747e4fSDavid du Colombier 			goto Return;
4679a747e4fSDavid du Colombier 		l[Blinelen(b)-1] = 0;
4686d0d1481SDavid du Colombier 		if(*l && strcmp(l, fontnames[i])!=0){
4696d0d1481SDavid du Colombier 			free(fontnames[i]);
4709a747e4fSDavid du Colombier 			fontnames[i] = estrdup(l);
4719a747e4fSDavid du Colombier 		}
4726d0d1481SDavid du Colombier 	}
4739a747e4fSDavid du Colombier     Return:
4749a747e4fSDavid du Colombier 	Bterm(b);
4759a747e4fSDavid du Colombier }
4769a747e4fSDavid du Colombier 
4774b30ca09SDavid du Colombier int
rowload(Row * row,char * file,int initing)4787dd7cddfSDavid du Colombier rowload(Row *row, char *file, int initing)
4797dd7cddfSDavid du Colombier {
4807dd7cddfSDavid du Colombier 	int i, j, line, percent, y, nr, nfontr, n, ns, ndumped, dumpid, x, fd;
4817dd7cddfSDavid du Colombier 	Biobuf *b, *bout;
4827dd7cddfSDavid du Colombier 	char *buf, *l, *t, *fontname;
4837dd7cddfSDavid du Colombier 	Rune *r, rune, *fontr;
4847dd7cddfSDavid du Colombier 	Column *c, *c1, *c2;
4857dd7cddfSDavid du Colombier 	uint q0, q1;
4867dd7cddfSDavid du Colombier 	Rectangle r1, r2;
4877dd7cddfSDavid du Colombier 	Window *w;
4887dd7cddfSDavid du Colombier 
4897dd7cddfSDavid du Colombier 	buf = fbufalloc();
4907dd7cddfSDavid du Colombier 	if(file == nil){
4917dd7cddfSDavid du Colombier 		if(home == nil){
4927dd7cddfSDavid du Colombier 			warning(nil, "can't find file for load: $home not defined\n");
4937dd7cddfSDavid du Colombier 			goto Rescue1;
4947dd7cddfSDavid du Colombier 		}
4957dd7cddfSDavid du Colombier 		sprint(buf, "%s/acme.dump", home);
4967dd7cddfSDavid du Colombier 		file = buf;
4977dd7cddfSDavid du Colombier 	}
4987dd7cddfSDavid du Colombier 	b = Bopen(file, OREAD);
4997dd7cddfSDavid du Colombier 	if(b == nil){
5007dd7cddfSDavid du Colombier 		warning(nil, "can't open load file %s: %r\n", file);
5017dd7cddfSDavid du Colombier 		goto Rescue1;
5027dd7cddfSDavid du Colombier 	}
5037dd7cddfSDavid du Colombier 	/* current directory */
5047dd7cddfSDavid du Colombier 	line = 0;
5057dd7cddfSDavid du Colombier 	l = rdline(b, &line);
5067dd7cddfSDavid du Colombier 	if(l == nil)
5077dd7cddfSDavid du Colombier 		goto Rescue2;
5087dd7cddfSDavid du Colombier 	l[Blinelen(b)-1] = 0;
5097dd7cddfSDavid du Colombier 	if(chdir(l) < 0){
5107dd7cddfSDavid du Colombier 		warning(nil, "can't chdir %s\n", l);
5117dd7cddfSDavid du Colombier 		goto Rescue2;
5127dd7cddfSDavid du Colombier 	}
5137dd7cddfSDavid du Colombier 	/* global fonts */
5147dd7cddfSDavid du Colombier 	for(i=0; i<2; i++){
5157dd7cddfSDavid du Colombier 		l = rdline(b, &line);
5167dd7cddfSDavid du Colombier 		if(l == nil)
5177dd7cddfSDavid du Colombier 			goto Rescue2;
5187dd7cddfSDavid du Colombier 		l[Blinelen(b)-1] = 0;
5197dd7cddfSDavid du Colombier 		if(*l && strcmp(l, fontnames[i])!=0)
5206d0d1481SDavid du Colombier 			rfget(i, TRUE, i==0 && initing, l);
5217dd7cddfSDavid du Colombier 	}
5227dd7cddfSDavid du Colombier 	if(initing && row->ncol==0)
5237dd7cddfSDavid du Colombier 		rowinit(row, screen->clipr);
5247dd7cddfSDavid du Colombier 	l = rdline(b, &line);
5257dd7cddfSDavid du Colombier 	if(l == nil)
5267dd7cddfSDavid du Colombier 		goto Rescue2;
5277dd7cddfSDavid du Colombier 	j = Blinelen(b)/12;
5287dd7cddfSDavid du Colombier 	if(j<=0 || j>10)
5297dd7cddfSDavid du Colombier 		goto Rescue2;
5307dd7cddfSDavid du Colombier 	for(i=0; i<j; i++){
5317dd7cddfSDavid du Colombier 		percent = atoi(l+i*12);
5327dd7cddfSDavid du Colombier 		if(percent<0 || percent>=100)
5337dd7cddfSDavid du Colombier 			goto Rescue2;
5347dd7cddfSDavid du Colombier 		x = row->r.min.x+percent*Dx(row->r)/100;
5357dd7cddfSDavid du Colombier 		if(i < row->ncol){
5367dd7cddfSDavid du Colombier 			if(i == 0)
5377dd7cddfSDavid du Colombier 				continue;
5387dd7cddfSDavid du Colombier 			c1 = row->col[i-1];
5397dd7cddfSDavid du Colombier 			c2 = row->col[i];
5407dd7cddfSDavid du Colombier 			r1 = c1->r;
5417dd7cddfSDavid du Colombier 			r2 = c2->r;
5427dd7cddfSDavid du Colombier 			r1.max.x = x;
5437dd7cddfSDavid du Colombier 			r2.min.x = x+Border;
5447dd7cddfSDavid du Colombier 			if(Dx(r1) < 50 || Dx(r2) < 50)
5457dd7cddfSDavid du Colombier 				continue;
5467dd7cddfSDavid du Colombier 			draw(screen, Rpt(r1.min, r2.max), display->white, nil, ZP);
5477dd7cddfSDavid du Colombier 			colresize(c1, r1);
5487dd7cddfSDavid du Colombier 			colresize(c2, r2);
5497dd7cddfSDavid du Colombier 			r2.min.x = x;
5507dd7cddfSDavid du Colombier 			r2.max.x = x+Border;
5517dd7cddfSDavid du Colombier 			draw(screen, r2, display->black, nil, ZP);
5527dd7cddfSDavid du Colombier 		}
5537dd7cddfSDavid du Colombier 		if(i >= row->ncol)
5547dd7cddfSDavid du Colombier 			rowadd(row, nil, x);
5557dd7cddfSDavid du Colombier 	}
5567dd7cddfSDavid du Colombier 	for(;;){
5577dd7cddfSDavid du Colombier 		l = rdline(b, &line);
5587dd7cddfSDavid du Colombier 		if(l == nil)
5597dd7cddfSDavid du Colombier 			break;
5607dd7cddfSDavid du Colombier 		dumpid = 0;
5617dd7cddfSDavid du Colombier 		switch(l[0]){
5627dd7cddfSDavid du Colombier 		case 'e':
5637dd7cddfSDavid du Colombier 			if(Blinelen(b) < 1+5*12+1)
5647dd7cddfSDavid du Colombier 				goto Rescue2;
5657dd7cddfSDavid du Colombier 			l = rdline(b, &line);	/* ctl line; ignored */
5667dd7cddfSDavid du Colombier 			if(l == nil)
5677dd7cddfSDavid du Colombier 				goto Rescue2;
5687dd7cddfSDavid du Colombier 			l = rdline(b, &line);	/* directory */
5697dd7cddfSDavid du Colombier 			if(l == nil)
5707dd7cddfSDavid du Colombier 				goto Rescue2;
5717dd7cddfSDavid du Colombier 			l[Blinelen(b)-1] = 0;
5727dd7cddfSDavid du Colombier 			if(*l == '\0'){
5737dd7cddfSDavid du Colombier 				if(home == nil)
5747dd7cddfSDavid du Colombier 					r = bytetorune("./", &nr);
5757dd7cddfSDavid du Colombier 				else{
5767dd7cddfSDavid du Colombier 					t = emalloc(strlen(home)+1+1);
5777dd7cddfSDavid du Colombier 					sprint(t, "%s/", home);
5787dd7cddfSDavid du Colombier 					r = bytetorune(t, &nr);
5797dd7cddfSDavid du Colombier 					free(t);
5807dd7cddfSDavid du Colombier 				}
5817dd7cddfSDavid du Colombier 			}else
5827dd7cddfSDavid du Colombier 				r = bytetorune(l, &nr);
5837dd7cddfSDavid du Colombier 			l = rdline(b, &line);	/* command */
5847dd7cddfSDavid du Colombier 			if(l == nil)
5857dd7cddfSDavid du Colombier 				goto Rescue2;
5867dd7cddfSDavid du Colombier 			t = emalloc(Blinelen(b)+1);
5877dd7cddfSDavid du Colombier 			memmove(t, l, Blinelen(b));
58859cc4ca5SDavid du Colombier 			run(nil, t, r, nr, TRUE, nil, nil, FALSE);
5897dd7cddfSDavid du Colombier 			/* r is freed in run() */
5907dd7cddfSDavid du Colombier 			continue;
5917dd7cddfSDavid du Colombier 		case 'f':
5927dd7cddfSDavid du Colombier 			if(Blinelen(b) < 1+5*12+1)
5937dd7cddfSDavid du Colombier 				goto Rescue2;
5947dd7cddfSDavid du Colombier 			fontname = l+1+5*12;
5957dd7cddfSDavid du Colombier 			ndumped = -1;
5967dd7cddfSDavid du Colombier 			break;
5977dd7cddfSDavid du Colombier 		case 'F':
5987dd7cddfSDavid du Colombier 			if(Blinelen(b) < 1+6*12+1)
5997dd7cddfSDavid du Colombier 				goto Rescue2;
6007dd7cddfSDavid du Colombier 			fontname = l+1+6*12;
6017dd7cddfSDavid du Colombier 			ndumped = atoi(l+1+5*12+1);
6027dd7cddfSDavid du Colombier 			break;
6037dd7cddfSDavid du Colombier 		case 'x':
6047dd7cddfSDavid du Colombier 			if(Blinelen(b) < 1+5*12+1)
6057dd7cddfSDavid du Colombier 				goto Rescue2;
6067dd7cddfSDavid du Colombier 			fontname = l+1+5*12;
6077dd7cddfSDavid du Colombier 			ndumped = -1;
6087dd7cddfSDavid du Colombier 			dumpid = atoi(l+1+1*12);
6097dd7cddfSDavid du Colombier 			break;
6107dd7cddfSDavid du Colombier 		default:
6117dd7cddfSDavid du Colombier 			goto Rescue2;
6127dd7cddfSDavid du Colombier 		}
6137dd7cddfSDavid du Colombier 		l[Blinelen(b)-1] = 0;
6147dd7cddfSDavid du Colombier 		fontr = nil;
6157dd7cddfSDavid du Colombier 		nfontr = 0;
6167dd7cddfSDavid du Colombier 		if(*fontname)
6177dd7cddfSDavid du Colombier 			fontr = bytetorune(fontname, &nfontr);
6187dd7cddfSDavid du Colombier 		i = atoi(l+1+0*12);
6197dd7cddfSDavid du Colombier 		j = atoi(l+1+1*12);
6207dd7cddfSDavid du Colombier 		q0 = atoi(l+1+2*12);
6217dd7cddfSDavid du Colombier 		q1 = atoi(l+1+3*12);
6227dd7cddfSDavid du Colombier 		percent = atoi(l+1+4*12);
6237dd7cddfSDavid du Colombier 		if(i<0 || i>10)
6247dd7cddfSDavid du Colombier 			goto Rescue2;
6257dd7cddfSDavid du Colombier 		if(i > row->ncol)
6267dd7cddfSDavid du Colombier 			i = row->ncol;
6277dd7cddfSDavid du Colombier 		c = row->col[i];
6287dd7cddfSDavid du Colombier 		y = c->r.min.y+(percent*Dy(c->r))/100;
6297dd7cddfSDavid du Colombier 		if(y<c->r.min.y || y>=c->r.max.y)
6307dd7cddfSDavid du Colombier 			y = -1;
6317dd7cddfSDavid du Colombier 		if(dumpid == 0)
6327dd7cddfSDavid du Colombier 			w = coladd(c, nil, nil, y);
6337dd7cddfSDavid du Colombier 		else
6347dd7cddfSDavid du Colombier 			w = coladd(c, nil, lookid(dumpid, TRUE), y);
6357dd7cddfSDavid du Colombier 		if(w == nil)
6367dd7cddfSDavid du Colombier 			continue;
6377dd7cddfSDavid du Colombier 		w->dumpid = j;
6387dd7cddfSDavid du Colombier 		l = rdline(b, &line);
6397dd7cddfSDavid du Colombier 		if(l == nil)
6407dd7cddfSDavid du Colombier 			goto Rescue2;
6417dd7cddfSDavid du Colombier 		l[Blinelen(b)-1] = 0;
6427dd7cddfSDavid du Colombier 		r = bytetorune(l+5*12, &nr);
6437dd7cddfSDavid du Colombier 		ns = -1;
6447dd7cddfSDavid du Colombier 		for(n=0; n<nr; n++){
6457dd7cddfSDavid du Colombier 			if(r[n] == '/')
6467dd7cddfSDavid du Colombier 				ns = n;
6477dd7cddfSDavid du Colombier 			if(r[n] == ' ')
6487dd7cddfSDavid du Colombier 				break;
6497dd7cddfSDavid du Colombier 		}
6507dd7cddfSDavid du Colombier 		if(dumpid == 0)
6517dd7cddfSDavid du Colombier 			winsetname(w, r, n);
6527dd7cddfSDavid du Colombier 		for(; n<nr; n++)
6537dd7cddfSDavid du Colombier 			if(r[n] == '|')
6547dd7cddfSDavid du Colombier 				break;
6557dd7cddfSDavid du Colombier 		wincleartag(w);
6567dd7cddfSDavid du Colombier 		textinsert(&w->tag, w->tag.file->nc, r+n+1, nr-(n+1), TRUE);
6577dd7cddfSDavid du Colombier 		if(ndumped >= 0){
6587dd7cddfSDavid du Colombier 			/* simplest thing is to put it in a file and load that */
6597dd7cddfSDavid du Colombier 			sprint(buf, "/tmp/d%d.%.4sacme", getpid(), getuser());
6607dd7cddfSDavid du Colombier 			fd = create(buf, OWRITE|ORCLOSE, 0600);
6617dd7cddfSDavid du Colombier 			if(fd < 0){
6622af003dfSDavid du Colombier 				free(r);
6637dd7cddfSDavid du Colombier 				warning(nil, "can't create temp file: %r\n");
6647dd7cddfSDavid du Colombier 				goto Rescue2;
6657dd7cddfSDavid du Colombier 			}
6667dd7cddfSDavid du Colombier 			bout = emalloc(sizeof(Biobuf));
6677dd7cddfSDavid du Colombier 			Binit(bout, fd, OWRITE);
6687dd7cddfSDavid du Colombier 			for(n=0; n<ndumped; n++){
6697dd7cddfSDavid du Colombier 				rune = Bgetrune(b);
6707dd7cddfSDavid du Colombier 				if(rune == '\n')
6717dd7cddfSDavid du Colombier 					line++;
67229b83c63SDavid du Colombier 				if(rune == (Rune)Beof){
6732af003dfSDavid du Colombier 					free(r);
6747dd7cddfSDavid du Colombier 					Bterm(bout);
6757dd7cddfSDavid du Colombier 					free(bout);
6767dd7cddfSDavid du Colombier 					close(fd);
6777dd7cddfSDavid du Colombier 					goto Rescue2;
6787dd7cddfSDavid du Colombier 				}
6797dd7cddfSDavid du Colombier 				Bputrune(bout, rune);
6807dd7cddfSDavid du Colombier 			}
6817dd7cddfSDavid du Colombier 			Bterm(bout);
6827dd7cddfSDavid du Colombier 			free(bout);
6837dd7cddfSDavid du Colombier 			textload(&w->body, 0, buf, 1);
6847dd7cddfSDavid du Colombier 			close(fd);
6857dd7cddfSDavid du Colombier 			w->body.file->mod = TRUE;
6867dd7cddfSDavid du Colombier 			for(n=0; n<w->body.file->ntext; n++)
6877dd7cddfSDavid du Colombier 				w->body.file->text[n]->w->dirty = TRUE;
6887dd7cddfSDavid du Colombier 			winsettag(w);
6897dd7cddfSDavid du Colombier 		}else if(dumpid==0 && r[ns+1]!='+' && r[ns+1]!='-')
6907dd7cddfSDavid du Colombier 			get(&w->body, nil, nil, FALSE, XXX, nil, 0);
6917dd7cddfSDavid du Colombier 		if(fontr){
6927dd7cddfSDavid du Colombier 			fontx(&w->body, nil, nil, 0, 0, fontr, nfontr);
6937dd7cddfSDavid du Colombier 			free(fontr);
6947dd7cddfSDavid du Colombier 		}
6952af003dfSDavid du Colombier 		free(r);
6967dd7cddfSDavid du Colombier 		if(q0>w->body.file->nc || q1>w->body.file->nc || q0>q1)
6977dd7cddfSDavid du Colombier 			q0 = q1 = 0;
6989a747e4fSDavid du Colombier 		textshow(&w->body, q0, q1, 1);
6997dd7cddfSDavid du Colombier 		w->maxlines = min(w->body.nlines, max(w->maxlines, w->body.maxlines));
7007dd7cddfSDavid du Colombier 	}
7017dd7cddfSDavid du Colombier 	Bterm(b);
7027dd7cddfSDavid du Colombier 	fbuffree(buf);
7034b30ca09SDavid du Colombier 	return TRUE;
7047dd7cddfSDavid du Colombier 
7057dd7cddfSDavid du Colombier Rescue2:
7067dd7cddfSDavid du Colombier 	warning(nil, "bad load file %s:%d\n", file, line);
7077dd7cddfSDavid du Colombier 	Bterm(b);
7084b30ca09SDavid du Colombier Rescue1:
7094b30ca09SDavid du Colombier 	fbuffree(buf);
7104b30ca09SDavid du Colombier 	return FALSE;
7117dd7cddfSDavid du Colombier }
71259cc4ca5SDavid du Colombier 
71359cc4ca5SDavid du Colombier void
allwindows(void (* f)(Window *,void *),void * arg)71459cc4ca5SDavid du Colombier allwindows(void (*f)(Window*, void*), void *arg)
71559cc4ca5SDavid du Colombier {
71659cc4ca5SDavid du Colombier 	int i, j;
71759cc4ca5SDavid du Colombier 	Column *c;
71859cc4ca5SDavid du Colombier 
71959cc4ca5SDavid du Colombier 	for(i=0; i<row.ncol; i++){
72059cc4ca5SDavid du Colombier 		c = row.col[i];
72159cc4ca5SDavid du Colombier 		for(j=0; j<c->nw; j++)
72259cc4ca5SDavid du Colombier 			(*f)(c->w[j], arg);
72359cc4ca5SDavid du Colombier 	}
72459cc4ca5SDavid du Colombier }
725