#include <u.h>
#include <libc.h>
#include <draw.h>
#include <cursor.h>
#include <event.h>
#include <bio.h>

typedef struct	Thing	Thing;

struct Thing
{
	Image	*b;
	Subfont 	*s;
	char		*name;	/* file name */
	int		face;		/* is 48x48 face file or cursor file*/
	Rectangle r;		/* drawing region */
	Rectangle tr;		/* text region */
	Rectangle er;		/* entire region */
	long		c;		/* character number in subfont */
	int		mod;	/* modified */
	int		mag;		/* magnification */
	Rune		off;		/* offset for subfont indices */
	Thing	*parent;	/* thing of which i'm an edit */
	Thing	*next;
};

enum
{
	Border	= 1,
	Up		= 1,
	Down	= 0,
	Mag		= 4,
	Maxmag	= 10
};

enum
{
	NORMAL	=0,
	FACE	=1,
	CURSOR	=2
};

enum
{
	Mopen,
	Mread,
	Mwrite,
	Mcopy,
	Mchar,
	Mpixels,
	Mclose,
	Mexit
};

enum
{
	Blue	= 54
};

char	*menu3str[] = {
	"open",
	"read",
	"write",
	"copy",
	"char",
	"pixels",
	"close",
	"exit",
	0
};

Menu	menu3 = {
	menu3str
};

Cursor sweep0 = {
	{-7, -7},
	{0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0,
	 0x03, 0xC0, 0x03, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF,
	 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xC0, 0x03, 0xC0,
	 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0},
	{0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
	 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x7F, 0xFE,
	 0x7F, 0xFE, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
	 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x00, 0x00}
};

Cursor box = {
	{-7, -7},
	{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	 0xFF, 0xFF, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F,
	 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xFF, 0xFF,
	 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
	{0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE,
	 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E,
	 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E,
	 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x00, 0x00}
};

Cursor sight = {
	{-7, -7},
	{0x1F, 0xF8, 0x3F, 0xFC, 0x7F, 0xFE, 0xFB, 0xDF,
	 0xF3, 0xCF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF,
	 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xF3, 0xCF,
	 0x7B, 0xDF, 0x7F, 0xFE, 0x3F, 0xFC, 0x1F, 0xF8,},
	{0x00, 0x00, 0x0F, 0xF0, 0x31, 0x8C, 0x21, 0x84,
	 0x41, 0x82, 0x41, 0x82, 0x41, 0x82, 0x7F, 0xFE,
	 0x7F, 0xFE, 0x41, 0x82, 0x41, 0x82, 0x41, 0x82,
	 0x21, 0x84, 0x31, 0x8C, 0x0F, 0xF0, 0x00, 0x00,}
};

Cursor pixel = {
	{-7, -7},
	{0x1f, 0xf8, 0x3f, 0xfc,  0x7f, 0xfe,  0xf8, 0x1f,
	0xf0, 0x0f,  0xe0, 0x07, 0xe0, 0x07, 0xfe, 0x7f, 
	0xfe, 0x7f, 0xe0, 0x07, 0xe0, 0x07, 0xf0, 0x0f, 
	0x78, 0x1f, 0x7f, 0xfe, 0x3f, 0xfc, 0x1f, 0xf8, },
	{0x00, 0x00, 0x0f, 0xf0, 0x31, 0x8c, 0x21, 0x84, 
	0x41, 0x82, 0x41, 0x82, 0x41, 0x82, 0x40, 0x02, 
	0x40, 0x02, 0x41, 0x82, 0x41, 0x82, 0x41, 0x82, 
	0x21, 0x84, 0x31, 0x8c, 0x0f, 0xf0, 0x00, 0x00, }
};

Cursor busy = {
	{-7, -7},
	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	 0x00, 0x00, 0x00, 0x0c, 0x00, 0x8e, 0x1d, 0xc7,
	 0xff, 0xe3, 0xff, 0xf3, 0xff, 0xff, 0x7f, 0xfe, 
	 0x3f, 0xf8, 0x17, 0xf0, 0x03, 0xe0, 0x00, 0x00,},
	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x82,
	 0x04, 0x41, 0xff, 0xe1, 0x5f, 0xf1, 0x3f, 0xfe, 
	 0x17, 0xf0, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00,}
};

Cursor skull = {
	{-7,-7},
	{0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0xe7, 0xe7, 
	 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfc, 0x1f, 0xf8, 
	 0x0f, 0xf0, 0x3f, 0xfc, 0xff, 0xff, 0xff, 0xff, 
	 0xef, 0xf7, 0xc7, 0xe3, 0x00, 0x00, 0x00, 0x00,},
	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03,
	 0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0,
	 0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27,
	 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}
};

Rectangle	cntlr;		/* control region */
Rectangle	editr;		/* editing region */
Rectangle	textr;		/* text region */
Thing		*thing;
Mouse		mouse;
char		hex[] = "0123456789abcdefABCDEF";
jmp_buf		err;
char		*file;
int		mag;
int		but1val = 0;
int		but2val = 255;
int		invert = 0;
Image		*values[256];
Image		*greyvalues[256];
uchar		data[8192];

Thing*	tget(char*);
void	mesg(char*, ...);
void	drawthing(Thing*, int);
void	xselect(void);
void	menu(void);
void	error(Display*, char*);
void	buttons(int);
void	drawall(void);
void	tclose1(Thing*);

void
usage(void)
{
	fprint(2, "usage: tweak [-W winsize] file...\n");
	exits("usage");
}

void
main(volatile int argc, char **volatile argv)
{
	volatile int i;
	Event e;
	Thing *t;

	ARGBEGIN{
	case 'W':
		winsize = EARGF(usage());
		break;
	default:
		usage();
	}ARGEND
	mag = Mag;
	if(initdraw(error, 0, "tweak") < 0){
		fprint(2, "tweak: initdraw failed: %r\n");
		exits("initdraw");
	}
	for(i=0; i<256; i++){
		values[i] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, cmap2rgba(i));
		greyvalues[i] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, (i<<24)|(i<<16)|(i<<8)|0xFF);
		if(values[i] == 0 || greyvalues[i] == 0)
			drawerror(display, "can't allocate image");
	}
	einit(Emouse|Ekeyboard);
	eresized(0);
	i = 0;
	setjmp(err);
	for(; i<argc; i++){
		file = argv[i];
		t = tget(argv[i]);
		if(t)
			drawthing(t, 1);
		flushimage(display, 1);
	}
	file = 0;
	setjmp(err);
	for(;;)
		switch(event(&e)){
		case Ekeyboard:
			break;
		case Emouse:
			mouse = e.mouse;
			if(mouse.buttons & 3){
				xselect();
				break;
			}
			if(mouse.buttons & 4)
				menu();
		}
}

int
xlog2(int n)
{
	int i;

	for(i=0; (1<<i) <= n; i++)
		if((1<<i) == n)
			return i;
	fprint(2, "log2 %d = 0\n", n);
	return 0;
}

void
error(Display *d, char *s)
{
	USED(d);

	if(file)
		mesg("can't read %s: %s: %r", file, s);
	else
		mesg("/dev/bitblt error: %s", s);
	if(err[0])
		longjmp(err, 1);
	exits(s);
}

void
redraw(Thing *t)
{
	Thing *nt;
	Point p;

	if(thing==0 || thing==t)
		draw(screen, editr, display->white, nil, ZP);
	if(thing == 0)
		return;
	if(thing != t){
		for(nt=thing; nt->next!=t; nt=nt->next)
			;
		draw(screen, Rect(screen->r.min.x, nt->er.max.y, editr.max.x, editr.max.y),
			display->white, nil, ZP);
	}
	for(nt=t; nt; nt=nt->next){
		drawthing(nt, 0);
		if(nt->next == 0){
			p = Pt(editr.min.x, nt->er.max.y);
			draw(screen, Rpt(p, editr.max), display->white, nil, ZP);
		}
	}
	mesg("");
}

void
eresized(int new)
{
	if(new && getwindow(display, Refnone) < 0)
		error(display, "can't reattach to window");
	cntlr = insetrect(screen->clipr, 1);
	editr = cntlr;
	textr = editr;
	textr.min.y = textr.max.y - font->height;
	cntlr.max.y = cntlr.min.y + font->height;
	editr.min.y = cntlr.max.y+1;
	editr.max.y = textr.min.y-1;
	draw(screen, screen->clipr, display->white, nil, ZP);
	draw(screen, Rect(editr.min.x, editr.max.y, editr.max.x+1, editr.max.y+1), display->black, nil, ZP);
	replclipr(screen, 0, editr);
	drawall();
}

void
mesgstr(Point p, int line, char *s)
{
	Rectangle c, r;

	r.min = p;
	r.min.y += line*font->height;
	r.max.y = r.min.y+font->height;
	r.max.x = editr.max.x;
	c = screen->clipr;
	replclipr(screen, 0, r);
	draw(screen, r, values[0xDD], nil, ZP);
	r.min.x++;
	string(screen, r.min, display->black, ZP, font, s);
	replclipr(screen, 0, c);
	flushimage(display, 1);
}

void
mesg(char *fmt, ...)
{
	char buf[1024];
	va_list arg;

	va_start(arg, fmt);
	vseprint(buf, buf+sizeof(buf), fmt, arg);
	va_end(arg);
	mesgstr(textr.min, 0, buf);
}

void
tmesg(Thing *t, int line, char *fmt, ...)
{
	char buf[1024];
	va_list arg;

	va_start(arg, fmt);
	vseprint(buf, buf+sizeof(buf), fmt, arg);
	va_end(arg);
	mesgstr(t->tr.min, line, buf);
}


void
scntl(char *l)
{
	sprint(l, "mag: %d  but1: %d  but2: %d  invert-on-copy: %c", mag, but1val, but2val, "ny"[invert]);
}

void
cntl(void)
{
	char buf[256];

	scntl(buf);
	mesgstr(cntlr.min, 0, buf);
}

void
stext(Thing *t, char *l0, char *l1)
{
	Fontchar *fc;
	char buf[256];

	l1[0] = 0;
	sprint(buf, "depth:%d r:%d %d  %d %d ", 
		t->b->depth, t->b->r.min.x, t->b->r.min.y,
		t->b->r.max.x, t->b->r.max.y);
	if(t->parent)
		sprint(buf+strlen(buf), "mag: %d ", t->mag);
	sprint(l0, "%s file: %s", buf, t->name);
	if(t->c >= 0){
		fc = &t->parent->s->info[t->c];
		sprint(l1, "c(hex): %x c(char): %C x: %d "
			   "top: %d bottom: %d left: %d width: %d iwidth: %d",
			(int)(t->c+t->parent->off), (int)(t->c+t->parent->off),
			fc->x, fc->top, fc->bottom, fc->left,
			fc->width, Dx(t->b->r));
	}else if(t->s)
		sprint(l1, "offset(hex): %ux n:%d  height:%d  ascent:%d",
			t->off, t->s->n, t->s->height, t->s->ascent);
}

void
text(Thing *t)
{
	char l0[256], l1[256];

	stext(t, l0, l1);
	tmesg(t, 0, l0);
	if(l1[0])
		tmesg(t, 1, l1);
}

void
drawall(void)
{
	Thing *t;

	cntl();
	for(t=thing; t; t=t->next)
		drawthing(t, 0);
}

int
value(Image *b, int x)
{
	int v, l, w;
	uchar mask;

	w = b->depth;
	if(w > 8){
		mesg("ldepth too large");
		return 0;
	}
	l = xlog2(w);
	mask = (1<<w)-1;		/* ones at right end of word */
	x -= b->r.min.x&~(7>>l);	/* adjust x relative to first pixel */
	v = data[x>>(3-l)];
	v >>= ((7>>l)<<l) - ((x&(7>>l))<<l);	/* pixel at right end of word */
	v &= mask;			/* pixel at right end of word */
	return v;
}

int
bvalue(int v, int d)
{
	v &= (1<<d)-1;
	if(d > screen->depth)
		v >>= d - screen->depth;
	else
		while(d < screen->depth && d < 8){
			v |= v << d;
			d <<= 1;
		}
	if(v<0 || v>255){
		mesg("internal error: bad color");
		return Blue;
	}
	return v;
}

void
drawthing(Thing *nt, int link)
{
	int n, nl, nf, i, x, y, sx, sy, fdx, dx, dy, v;
	Thing *t;
	Subfont *s;
	Image *b, *col;
	Point p, p1, p2;

	if(link){
		nt->next = 0;
		if(thing == 0){
			thing = nt;
			y = editr.min.y;
		}else{
			for(t=thing; t->next; t=t->next)
				;
			t->next = nt;
			y = t->er.max.y;
		}
	}else{
		if(thing == nt)
			y = editr.min.y;
		else{
			for(t=thing; t->next!=nt; t=t->next)
				;
			y = t->er.max.y;
		}
	}
	s = nt->s;
	b = nt->b;
	nl = font->height;
	if(s || nt->c>=0)
		nl += font->height;
	fdx = Dx(editr) - 2*Border;
	dx = Dx(b->r);
	dy = Dy(b->r);
	if(nt->mag > 1){
		dx *= nt->mag;
		dy *= nt->mag;
		fdx -= fdx%nt->mag;
	}
	nf = 1 + dx/fdx;
	nt->er.min.y = y;
	nt->er.min.x = editr.min.x;
	nt->er.max.x = nt->er.min.x + Border + dx + Border;
	if(nt->er.max.x > editr.max.x)
		nt->er.max.x = editr.max.x;
	nt->er.max.y = nt->er.min.y + Border + nf*(dy+Border);
	nt->r = insetrect(nt->er, Border);
	nt->er.max.x = editr.max.x;
	draw(screen, nt->er, display->white, nil, ZP);
	for(i=0; i<nf; i++){
		p1 = Pt(nt->r.min.x-1, nt->r.min.y+i*(Border+dy));
		/* draw portion of bitmap */
		p = Pt(p1.x+1, p1.y);
		if(nt->mag == 1)
			draw(screen, Rect(p.x, p.y, p.x+fdx+Dx(b->r), p.y+Dy(b->r)),
				b, nil, Pt(b->r.min.x+i*fdx, b->r.min.y));
		else{
			for(y=b->r.min.y; y<b->r.max.y; y++){
				sy = p.y+(y-b->r.min.y)*nt->mag;
				if((n=unloadimage(b, Rect(b->r.min.x, y, b->r.max.x, y+1), data, sizeof data)) < 0)
					fprint(2, "unloadimage: %r\n");
				for(x=b->r.min.x+i*(fdx/nt->mag); x<b->r.max.x; x++){
					sx = p.x+(x-i*(fdx/nt->mag)-b->r.min.x)*nt->mag;
					if(sx >= nt->r.max.x)
						break;
					v = bvalue(value(b, x), b->depth);
					if(v == 255)
						continue;
					if(b->chan == GREY8)
						draw(screen, Rect(sx, sy, sx+nt->mag, sy+nt->mag),
							greyvalues[v], nil, ZP);
					else
						draw(screen, Rect(sx, sy, sx+nt->mag, sy+nt->mag),
							values[v], nil, ZP);
				}

			}
		}
		/* line down left */
		if(i == 0)
			col = display->black;
		else
			col = display->white;
		draw(screen, Rect(p1.x, p1.y, p1.x+1, p1.y+dy+Border), col, nil, ZP);
		/* line across top */
		draw(screen, Rect(p1.x, p1.y-1, nt->r.max.x+Border, p1.y), display->black, nil, ZP);
		p2 = p1;
		if(i == nf-1){
			p2.x += 1 + dx%fdx;
			col = display->black;
		}else{
			p2.x = nt->r.max.x;
			col = display->white;
		}
		/* line down right */
		draw(screen, Rect(p2.x, p2.y, p2.x+1, p2.y+dy+Border), col, nil, ZP);
		/* line across bottom */
		if(i == nf-1){
			p1.y += Border+dy;
			draw(screen, Rect(p1.x, p1.y-1, p2.x,p1.y), display->black, nil, ZP);
		}
	}
	nt->tr.min.x = editr.min.x;
	nt->tr.max.x = editr.max.x;
	nt->tr.min.y = nt->er.max.y + Border;
	nt->tr.max.y = nt->tr.min.y + nl;
	nt->er.max.y = nt->tr.max.y + Border;
	text(nt);
}

int
tohex(int c)
{
	if('0'<=c && c<='9')
		return c - '0';
	if('a'<=c && c<='f')
		return 10 + (c - 'a');
	if('A'<=c && c<='F')
		return 10 + (c - 'A');
	return 0;
}

Thing*
tget(char *file)
{
	int i, j, fd, face, x, y, c, chan;
	Image *b;
	Subfont *s;
	Thing *t;
	Dir *volatile d;
	jmp_buf oerr;
	uchar buf[256];
	char *data;

	buf[0] = '\0';
	errstr((char*)buf, sizeof buf);	/* flush pending error message */
	memmove(oerr, err, sizeof err);
	d = nil;
	if(setjmp(err)){
   Err:
		free(d);
		memmove(err, oerr, sizeof err);
		return 0;
	}
	fd = open(file, OREAD);
	if(fd < 0){
		mesg("can't open %s: %r", file);
		goto Err;
	}
	d = dirfstat(fd);
	if(d == nil){
		mesg("can't stat bitmap file %s: %r", file);
		close(fd);
		goto Err;
	}
	if(read(fd, buf, 11) != 11){
		mesg("can't read %s: %r", file);
		close(fd);
		goto Err;
	}
	seek(fd, 0, 0);
	data = (char*)buf;
	if(*data == '{')
		data++;
	if(memcmp(data, "0x", 2)==0 && data[4]==','){
		/*
		 * cursor file
		 */
		face = CURSOR;
		s = 0;
		data = malloc(d->length+1);
		if(data == 0){
			mesg("can't malloc buffer: %r");
			close(fd);
			goto Err;
		}
		data[d->length] = 0;
		if(read(fd, data, d->length) != d->length){
			mesg("can't read cursor file %s: %r", file);
			close(fd);
			goto Err;
		}
		b = allocimage(display, Rect(0, 0, 16, 32), GREY1, 0, DNofill);
		if(b == 0){
			mesg("image alloc failed file %s: %r", file);
			free(data);
			close(fd);
			goto Err;
		}
		i = 0;
		for(x=0;x<64; ){
			if((c=data[i]) == '\0')
				goto ill;
			if(c=='0' && data[i+1] == 'x'){
				i += 2;
				continue;
			}
			if(strchr(hex, c)){
				buf[x++] = (tohex(c)<<4) | tohex(data[i+1]);
				i += 2;
				continue;
			}
			i++;
		}
		loadimage(b, Rect(0, 0, 16, 32), buf, sizeof buf);
		free(data);
	}else if(memcmp(buf, "0x", 2)==0){
		/*
		 * face file
		 */
		face = FACE;
		s = 0;
		data = malloc(d->length+1);
		if(data == 0){
			mesg("can't malloc buffer: %r");
			close(fd);
			goto Err;
		}
		data[d->length] = 0;
		if(read(fd, data, d->length) != d->length){
			mesg("can't read bitmap file %s: %r", file);
			close(fd);
			goto Err;
		}
		for(y=0,i=0; i<d->length; i++)
			if(data[i] == '\n')
				y++;
		if(y == 0){
	ill:
			mesg("ill-formed face file %s", file);
			close(fd);
			free(data);
			goto Err;
		}
		for(x=0,i=0; (c=data[i])!='\n'; ){
			if(c==',' || c==' ' || c=='\t'){
				i++;
				continue;
			}
			if(c=='0' && data[i+1] == 'x'){
				i += 2;
				continue;
			}
			if(strchr(hex, c)){
				x += 4;
				i++;
				continue;
			}
			goto ill;
		}
		if(x % y)
			goto ill;
		switch(x / y){
		default:
			goto ill;
		case 1:
			chan = GREY1;
			break;
		case 2:
			chan = GREY2;
			break;
		case 4:
			chan = GREY4;
			break;
		case 8:
			chan = CMAP8;
			break;
		}
		b = allocimage(display, Rect(0, 0, y, y), chan, 0, -1);
		if(b == 0){
			mesg("image alloc failed file %s: %r", file);
			free(data);
			close(fd);
			goto Err;
		}
		i = 0;
		for(j=0; j<y; j++){
			for(x=0; (c=data[i])!='\n'; ){
				if(c=='0' && data[i+1] == 'x'){
					i += 2;
					continue;
				}
				if(strchr(hex, c)){
					buf[x++] = ~((tohex(c)<<4) | tohex(data[i+1]));
					i += 2;
					continue;
				}
				i++;
			}
			i++;
			loadimage(b, Rect(0, j, y, j+1), buf, sizeof buf);
		}
		free(data);
	}else{
		face = NORMAL;
		s = 0;
		b = readimage(display, fd, 0);
		if(b == 0){
			mesg("can't read bitmap file %s: %r", file);
			close(fd);
			goto Err;
		}
		if(seek(fd, 0, 1) < d->length)
			s = readsubfonti(display, file, fd, b, 0);
	}
	close(fd);
	t = malloc(sizeof(Thing));
	if(t == 0){
   nomem:
		mesg("malloc failed: %r");
		if(s)
			freesubfont(s);
		else
			freeimage(b);
		goto Err;
	}
	t->name = strdup(file);
	if(t->name == 0){
		free(t);
		goto nomem;
	}
	t->b = b;
	t->s = s;
	t->face = face;
	t->mod = 0;
	t->parent = 0;
	t->c = -1;
	t->mag = 1;
	t->off = 0;
	memmove(err, oerr, sizeof err);
	return t;
}

int
atline(int x, Point p, char *line, char *buf)
{
	char *s, *c, *word, *hit;
	int w, wasblank;
	Rune r;

	wasblank = 1;
	hit = 0;
	word = 0;
	for(s=line; *s; s+=w){
		w = chartorune(&r, s);
		x += runestringnwidth(font, &r, 1);
		if(wasblank && r!=' ')
			word = s;
		wasblank = 0;
		if(r == ' '){
			if(x >= p.x)
				break;
			wasblank = 1;
		}
		if(r == ':')
			hit = word;
	}
	if(x < p.x)
		return 0;
	c = utfrune(hit, ':');
	strncpy(buf, hit, c-hit);
	buf[c-hit] = 0;
	return 1;
}

int
attext(Thing *t, Point p, char *buf)
{
	char l0[256], l1[256];

	if(!ptinrect(p, t->tr))
		return 0;
	stext(t, l0, l1);
	if(p.y < t->tr.min.y+font->height)
		return atline(t->r.min.x, p, l0, buf);
	else
		return atline(t->r.min.x, p, l1, buf);
}

int
type(char *buf, char *tag)
{
	Rune r;
	char *p;

	esetcursor(&busy);
	p = buf;
	for(;;){
		*p = 0;
		mesg("%s: %s", tag, buf);
		r = ekbd();
		switch(r){
		case '\n':
			mesg("");
			esetcursor(0);
			return p-buf;
		case 0x15:	/* control-U */
			p = buf;
			break;
		case '\b':
			if(p > buf)
				--p;
			break;
		default:
			p += runetochar(p, &r);
		}
	}
	/* return 0;	shut up compiler */
}

void
textedit(Thing *t, char *tag)
{
	char buf[256];
	char *s;
	Image *b;
	Subfont *f;
	Fontchar *fc, *nfc;
	Rectangle r;
	ulong chan;
	int i, ld, d, w, c, doredraw, fdx, x;
	Thing *nt;

	buttons(Up);
	if(type(buf, tag) == 0)
		return;
	if(strcmp(tag, "file") == 0){
		for(s=buf; *s; s++)
			if(*s <= ' '){
				mesg("illegal file name");
				return;
			}
		if(strcmp(t->name, buf) != 0){
			if(t->parent)
				t->parent->mod = 1;
			else
				t->mod = 1;
		}
		for(nt=thing; nt; nt=nt->next)
			if(t==nt || t->parent==nt || nt->parent==t){
				free(nt->name);
				nt->name = strdup(buf);
				if(nt->name == 0){
					mesg("malloc failed: %r");
					return;
				}
				text(nt);
			}
		return;
	}
	if(strcmp(tag, "depth") == 0){
		if(buf[0]<'0' || '9'<buf[0] || (d=atoi(buf))<0 || d>8 || xlog2(d)<0){
			mesg("illegal ldepth");
			return;
		}
		if(d == t->b->depth)
			return;
		if(t->parent)
			t->parent->mod = 1;
		else
			t->mod = 1;
		if(d == 8)
			chan = CMAP8;
		else
			chan = CHAN1(CGrey, d);
		for(nt=thing; nt; nt=nt->next){
			if(nt!=t && nt!=t->parent && nt->parent!=t)
				continue;
			b = allocimage(display, nt->b->r, chan, 0, 0);
			if(b == 0){
	nobmem:
				mesg("image alloc failed: %r");
				return;
			}
			draw(b, b->r, nt->b, nil, nt->b->r.min);
			freeimage(nt->b);
			nt->b = b;
			if(nt->s){
				b = allocimage(display, nt->b->r, chan, 0, -1);
				if(b == 0)
					goto nobmem;
				draw(b, b->r, nt->b, nil, nt->b->r.min);
				f = allocsubfont(t->name, nt->s->n, nt->s->height, nt->s->ascent, nt->s->info, b);
				if(f == 0){
	nofmem:
					freeimage(b);
					mesg("can't make subfont: %r");
					return;
				}
				nt->s->info = 0;	/* prevent it being freed */
				nt->s->bits = 0;
				freesubfont(nt->s);
				nt->s = f;
			}
			drawthing(nt, 0);
		}
		return;
	}
	if(strcmp(tag, "mag") == 0){
		if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<=0 || ld>Maxmag){
			mesg("illegal magnification");
			return;
		}
		if(t->mag == ld)
			return;
		t->mag = ld;
		redraw(t);
		return;
	}
	if(strcmp(tag, "r") == 0){
		if(t->s){
			mesg("can't change rectangle of subfont\n");
			return;
		}
		s = buf;
		r.min.x = strtoul(s, &s, 0);
		r.min.y = strtoul(s, &s, 0);
		r.max.x = strtoul(s, &s, 0);
		r.max.y = strtoul(s, &s, 0);
		if(Dx(r)<=0 || Dy(r)<=0){
			mesg("illegal rectangle");
			return;
		}
		if(t->parent)
			t = t->parent;
		for(nt=thing; nt; nt=nt->next){
			if(nt->parent==t && !rectinrect(nt->b->r, r))
				tclose1(nt);
		}
		b = allocimage(display, r, t->b->chan, 0, 0);
		if(b == 0)
			goto nobmem;
		draw(b, r, t->b, nil, r.min);
		freeimage(t->b);
		t->b = b;
		b = allocimage(display, r, t->b->chan, 0, 0);
		if(b == 0)
			goto nobmem;
		redraw(t);
		t->mod = 1;
		return;
	}
	if(strcmp(tag, "ascent") == 0){
		if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<0 || ld>t->s->height){
			mesg("illegal ascent");
			return;
		}
		if(t->s->ascent == ld)
			return;
		t->s->ascent = ld;
		text(t);
		t->mod = 1;
		return;
	}
	if(strcmp(tag, "height") == 0){
		if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<0){
			mesg("illegal height");
			return;
		}
		if(t->s->height == ld)
			return;
		t->s->height = ld;
		text(t);
		t->mod = 1;
		return;
	}
	if(strcmp(tag, "left")==0 || strcmp(tag, "width") == 0){
		if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<0){
			mesg("illegal value");
			return;
		}
		fc = &t->parent->s->info[t->c];
		if(strcmp(tag, "left")==0){
			if(fc->left == ld)
				return;
			fc->left = ld;
		}else{
			if(fc->width == ld)
				return;
			fc->width = ld;
		}
		text(t);
		t->parent->mod = 1;
		return;
	}
	if(strcmp(tag, "offset(hex)") == 0){
		if(!strchr(hex, buf[0])){
	illoff:
			mesg("illegal offset");
			return;
		}
		s = 0;
		ld = strtoul(buf, &s, 16);
		if(*s)
			goto illoff;
		t->off = ld;
		text(t);
		for(nt=thing; nt; nt=nt->next)
			if(nt->parent == t)
				text(nt);
		return;
	}
	if(strcmp(tag, "n") == 0){
		if(buf[0]<'0' || '9'<buf[0] || (w=atoi(buf))<=0){
			mesg("illegal n");
			return;
		}
		f = t->s;
		if(w == f->n)
			return;
		doredraw = 0;
	again:
		for(nt=thing; nt; nt=nt->next)
			if(nt->parent == t){
				doredraw = 1;
				tclose1(nt);
				goto again;
			}
		r = t->b->r;
		if(w < f->n)
			r.max.x = f->info[w].x;
		b = allocimage(display, r, t->b->chan, 0, 0);
		if(b == 0)
			goto nobmem;
		draw(b, b->r, t->b, nil, r.min);
		fdx = Dx(editr) - 2*Border;
		if(Dx(t->b->r)/fdx != Dx(b->r)/fdx)
			doredraw = 1;
		freeimage(t->b);
		t->b = b;
		b = allocimage(display, r, t->b->chan, 0, 0);
		if(b == 0)
			goto nobmem;
		draw(b, b->r, t->b, nil, r.min);
		nfc = malloc((w+1)*sizeof(Fontchar));
		if(nfc == 0){
			mesg("malloc failed");
			freeimage(b);
			return;
		}
		fc = f->info;
		for(i=0; i<=w && i<=f->n; i++)
			nfc[i] = fc[i];
		if(w+1 < i)
			memset(nfc+i, 0, ((w+1)-i)*sizeof(Fontchar));
		x = fc[f->n].x;
		for(; i<=w; i++)
			nfc[i].x = x;
		f = allocsubfont(t->name, w, f->height, f->ascent, nfc, b);
		if(f == 0)
			goto nofmem;
		t->s->bits = nil;	/* don't free it */
		freesubfont(t->s);
		f->info = nfc;
		t->s = f;
		if(doredraw)
			redraw(thing);
		else
			drawthing(t, 0);
		t->mod = 1;
		return;
	}
	if(strcmp(tag, "iwidth") == 0){
		if(buf[0]<'0' || '9'<buf[0] || (w=atoi(buf))<0){
			mesg("illegal iwidth");
			return;
		}
		w -= Dx(t->b->r);
		if(w == 0)
			return;
		r = t->parent->b->r;
		r.max.x += w;
		c = t->c;
		t = t->parent;
		f = t->s;
		b = allocimage(display, r, t->b->chan, 0, 0);
		if(b == 0)
			goto nobmem;
		fc = &f->info[c];
		draw(b, Rect(b->r.min.x, b->r.min.y,
				b->r.min.x+(fc[1].x-t->b->r.min.x), b->r.min.y+Dy(t->b->r)),
				t->b, nil, t->b->r.min);
		draw(b, Rect(fc[1].x+w, b->r.min.y, w+t->b->r.max.x, b->r.min.y+Dy(t->b->r)),
			t->b, nil, Pt(fc[1].x, t->b->r.min.y));
		fdx = Dx(editr) - 2*Border;
		doredraw = 0;
		if(Dx(t->b->r)/fdx != Dx(b->r)/fdx)
			doredraw = 1;
		freeimage(t->b);
		t->b = b;
		b = allocimage(display, r, t->b->chan, 0, 0);
		if(b == 0)
			goto nobmem;
		draw(b, b->r, t->b, nil, t->b->r.min);
		fc = &f->info[c+1];
		for(i=c+1; i<=f->n; i++, fc++)
			fc->x += w;
		f = allocsubfont(t->name, f->n, f->height, f->ascent,
			f->info, b);
		if(f == 0)
			goto nofmem;
		/* t->s and f share info; free carefully */
		fc = f->info;
		t->s->bits = nil;
		t->s->info = 0;
		freesubfont(t->s);
		f->info = fc;
		t->s = f;
		if(doredraw)
			redraw(t);
		else
			drawthing(t, 0);
		/* redraw all affected chars */
		for(nt=thing; nt; nt=nt->next){
			if(nt->parent!=t || nt->c<c)
				continue;
			fc = &f->info[nt->c];
			r.min.x = fc[0].x;
			r.min.y = nt->b->r.min.y;
			r.max.x = fc[1].x;
			r.max.y = nt->b->r.max.y;
			b = allocimage(display, r, nt->b->chan, 0, 0);
			if(b == 0)
				goto nobmem;
			draw(b, r, t->b, nil, r.min);
			doredraw = 0;
			if(Dx(nt->b->r)/fdx != Dx(b->r)/fdx)
				doredraw = 1;
			freeimage(nt->b);
			nt->b = b;
			if(c != nt->c)
				text(nt);
			else{
				if(doredraw)
					redraw(nt);
				else
					drawthing(nt, 0);
			}
		}
		t->mod = 1;
		return;
	}
	mesg("cannot edit %s in file %s", tag, t->name);
}

void
cntledit(char *tag)
{
	char buf[256];
	ulong l;

	buttons(Up);
	if(type(buf, tag) == 0)
		return;
	if(strcmp(tag, "mag") == 0){
		if(buf[0]<'0' || '9'<buf[0] || (l=atoi(buf))<=0 || l>Maxmag){
			mesg("illegal magnification");
			return;
		}
		mag = l;
		cntl();
		return;
	}
	if(strcmp(tag, "but1")==0
	|| strcmp(tag, "but2")==0){
		if(buf[0]<'0' || '9'<buf[0] || (long)(l=atoi(buf))<0 || l>255){
			mesg("illegal value");
			return;
		}
		if(strcmp(tag, "but1") == 0)
			but1val = l;
		else if(strcmp(tag, "but2") == 0)
			but2val = l;
		cntl();
		return;
	}
	if(strcmp(tag, "invert-on-copy")==0){
		if(buf[0]=='y' || buf[0]=='1')
			invert = 1;
		else if(buf[0]=='n' || buf[0]=='0')
			invert = 0;
		else{
			mesg("illegal value");
			return;
		}
		cntl();
		return;
	}
	mesg("cannot edit %s", tag);
}

void
buttons(int ud)
{
	while((mouse.buttons==0) != ud)
		mouse = emouse();
}

Point
screenpt(Thing *t, Point realp)
{
	int fdx, n;
	Point p;

	fdx = Dx(editr)-2*Border;
	if(t->mag > 1)
		fdx -= fdx%t->mag;
	p = mulpt(subpt(realp, t->b->r.min), t->mag);
	if(fdx < Dx(t->b->r)*t->mag){
		n = p.x/fdx;
		p.y += n * (Dy(t->b->r)*t->mag+Border);
		p.x -= n * fdx;
	}
	p = addpt(p, t->r.min);
	return p;
}

Point
realpt(Thing *t, Point screenp)
{
	int fdx, n, dy;
	Point p;

	fdx = (Dx(editr)-2*Border);
	if(t->mag > 1)
		fdx -= fdx%t->mag;
	p.y = screenp.y-t->r.min.y;
	p.x = 0;
	if(fdx < Dx(t->b->r)*t->mag){
		dy = Dy(t->b->r)*t->mag+Border;
		n = (p.y/dy);
		p.x = n * fdx;
		p.y -= n * dy;
	}
	p.x += screenp.x-t->r.min.x;
	p = addpt(divpt(p, t->mag), t->b->r.min);
	return p;
}

int
sweep(int but, Rectangle *r)
{
	Thing *t;
	Point p, q, lastq;

	esetcursor(&sweep0);
	buttons(Down);
	if(mouse.buttons != (1<<(but-1))){
		buttons(Up);
		esetcursor(0);
		return 0;
	}
	p = mouse.xy;
	for(t=thing; t; t=t->next)
		if(ptinrect(p, t->r))
			break;
	if(t)
		p = screenpt(t, realpt(t, p));
	r->min = p;
	r->max = p;
	esetcursor(&box);
	lastq = ZP;
	while(mouse.buttons == (1<<(but-1))){
		edrawgetrect(insetrect(*r, -Borderwidth), 1);
		mouse = emouse();
		edrawgetrect(insetrect(*r, -Borderwidth), 0);
		q = mouse.xy;
		if(t)
			q = screenpt(t, realpt(t, q));
		if(eqpt(q, lastq))
			continue;
		*r = canonrect(Rpt(p, q));
		lastq = q;
	}
	esetcursor(0);
	if(mouse.buttons){
		buttons(Up);
		return 0;
	}
	return 1;
}

void
openedit(Thing *t, Point pt, int c)
{
	int x, y;
	Point p;
	Rectangle r;
	Rectangle br;
	Fontchar *fc;
	Thing *nt;

	if(t->b->depth > 8){
		mesg("image has depth %d; can't handle >8", t->b->depth);
		return;
	}
	br = t->b->r;
	if(t->s == 0){
		c = -1; 
		/* if big enough to bother, sweep box */
		if(Dx(br)<=16 && Dy(br)<=16)
			r = br;
		else{
			if(!sweep(1, &r))
				return;
			r = rectaddpt(r, subpt(br.min, t->r.min));
			if(!rectclip(&r, br))
				return;
			if(Dx(br) <= 8){
				r.min.x = br.min.x;
				r.max.x = br.max.x;
			}else if(Dx(r) < 4){
	    toosmall:
				mesg("rectangle too small");
				return;
			}
			if(Dy(br) <= 8){
				r.min.y = br.min.y;
				r.max.y = br.max.y;
			}else if(Dy(r) < 4)
				goto toosmall;
		}
	}else if(c >= 0){
		fc = &t->s->info[c];
		r.min.x = fc[0].x;
		r.min.y = br.min.y;
		r.max.x = fc[1].x;
		r.max.y = br.min.y + Dy(br);
	}else{
		/* just point at character */
		fc = t->s->info;
		p = addpt(pt, subpt(br.min, t->r.min));
		x = br.min.x;
		y = br.min.y;
		for(c=0; c<t->s->n; c++,fc++){
	    again:
			r.min.x = x;
			r.min.y = y;
			r.max.x = x + fc[1].x - fc[0].x;
			r.max.y = y + Dy(br);
			if(ptinrect(p, r))
				goto found;
			if(r.max.x >= br.min.x+Dx(t->r)){
				x -= Dx(t->r);
				y += t->s->height;
				if(fc[1].x > fc[0].x)
					goto again;
			}
			x += fc[1].x - fc[0].x;
		}
		return;
	   found:
		r = br;
		r.min.x = fc[0].x;
		r.max.x = fc[1].x;
	}
	nt = malloc(sizeof(Thing));
	if(nt == 0){
   nomem:
		mesg("can't allocate: %r");
		return;
	}
	memset(nt, 0, sizeof(Thing));
	nt->c = c;
	nt->b = allocimage(display, r, t->b->chan, 0, DNofill);
	if(nt->b == 0){
		free(nt);
		goto nomem;
	}
	draw(nt->b, r, t->b, nil, r.min);
	nt->name = strdup(t->name);
	if(nt->name == 0){
		freeimage(nt->b);
		free(nt);
		goto nomem;
	}
	nt->parent = t;
	nt->mag = mag;
	drawthing(nt, 1);
}

void
ckinfo(Thing *t, Rectangle mod)
{
	int i, j, k, top, bot, n, zero;
	Fontchar *fc;
	Rectangle r;
	Image *b;
	Thing *nt;

	if(t->parent)
		t = t->parent;
	if(t->s==0 || Dy(t->b->r)==0)
		return;
	b = 0;
	/* check bounding boxes */
	fc = &t->s->info[0];
	r.min.y = t->b->r.min.y;
	r.max.y = t->b->r.max.y;
	for(i=0; i<t->s->n; i++, fc++){
		r.min.x = fc[0].x;
		r.max.x = fc[1].x;
		if(!rectXrect(mod, r))
			continue;
		if(b==0 || Dx(b->r)<Dx(r)){
			if(b)
				freeimage(b);
			b = allocimage(display, rectsubpt(r, r.min), t->b->chan, 0, 0);
			if(b == 0){
				mesg("can't alloc image");
				break;
			}
		}
		draw(b, b->r, display->white, nil, ZP);
		draw(b, b->r, t->b, nil, r.min);
		top = 100000;
		bot = 0;
		n = 2+((Dx(r)/8)*t->b->depth);
		for(j=0; j<b->r.max.y; j++){
			memset(data, 0, n);
			unloadimage(b, Rect(b->r.min.x, j, b->r.max.x, j+1), data, sizeof data);
			zero = 1;
			for(k=0; k<n; k++)
				if(data[k]){
					zero = 0;
					break;
				}
			if(!zero){
				if(top > j)
					top = j;
				bot = j+1;
			}
		}
		if(top > j)
			top = 0;
		if(top!=fc->top || bot!=fc->bottom){
			fc->top = top;
			fc->bottom = bot;
			for(nt=thing; nt; nt=nt->next)
				if(nt->parent==t && nt->c==i)
					text(nt);
		}
	}
	if(b)
		freeimage(b);
}

void
twidpix(Thing *t, Point p, int set)
{
	Image *b, *v;
	int c;

	b = t->b;
	if(!ptinrect(p, b->r))
		return;
	if(set)
		c = but1val;
	else
		c = but2val;
	if(b->chan == GREY8)
		v = greyvalues[c];
	else
		v = values[c];
	draw(b, Rect(p.x, p.y, p.x+1, p.y+1), v, nil, ZP);
	p = screenpt(t, p);
	draw(screen, Rect(p.x, p.y, p.x+t->mag, p.y+t->mag), v, nil, ZP);
}

void
twiddle(Thing *t)
{
	int set;
	Point p, lastp;
	Image *b;
	Thing *nt;
	Rectangle mod;

	if(mouse.buttons!=1 && mouse.buttons!=2){
		buttons(Up);
		return;
	}
	set = mouse.buttons==1;
	b = t->b;
	lastp = addpt(b->r.min, Pt(-1, -1));
	mod = Rpt(addpt(b->r.max, Pt(1, 1)), lastp);
	while(mouse.buttons){
		p = realpt(t, mouse.xy);
		if(!eqpt(p, lastp)){
			lastp = p;
			if(ptinrect(p, b->r)){
				for(nt=thing; nt; nt=nt->next)
					if(nt->parent==t->parent || nt==t->parent)
						twidpix(nt, p, set);
				if(t->parent)
					t->parent->mod = 1;
				else
					t->mod = 1;
				if(p.x < mod.min.x)
					mod.min.x = p.x;
				if(p.y < mod.min.y)
					mod.min.y = p.y;
				if(p.x >= mod.max.x)
					mod.max.x = p.x+1;
				if(p.y >= mod.max.y)
					mod.max.y = p.y+1;
			}
		}
		mouse = emouse();
	}
	ckinfo(t, mod);
}

void
xselect(void)
{
	Thing *t;
	char line[128], buf[128];
	Point p;

	if(ptinrect(mouse.xy, cntlr)){
		scntl(line);
		if(atline(cntlr.min.x, mouse.xy, line, buf)){
			if(mouse.buttons == 1)
				cntledit(buf);
			else
				buttons(Up);
			return;
		}
		return;
	}
	for(t=thing; t; t=t->next){
		if(attext(t, mouse.xy, buf)){
			if(mouse.buttons == 1)
				textedit(t, buf);
			else
				buttons(Up);
			return;
		}
		if(ptinrect(mouse.xy, t->r)){
			if(t->parent == 0){
				if(mouse.buttons == 1){
					p = mouse.xy;
					buttons(Up);
					openedit(t, p, -1);
				}else
					buttons(Up);
				return;
			}
			twiddle(t);
			return;
		}
	}
}

void
twrite(Thing *t)
{
	int i, j, x, y, fd, ws, ld;
	Biobuf buf;
	Rectangle r;

	if(t->parent)
		t = t->parent;
	esetcursor(&busy);
	fd = create(t->name, OWRITE, 0666);
	if(fd < 0){
		mesg("can't write %s: %r", t->name);
		return;
	}
	if(t->face && t->b->depth <= 4){
		r = t->b->r;
		ld = xlog2(t->b->depth);
		/* This heuristic reflects peculiarly different formats */
		ws = 4;
		if(t->face == 2)	/* cursor file */
			ws = 1;
		else if(Dx(r)<32 || ld==0)
			ws = 2;
		Binit(&buf, fd, OWRITE);
		if(t->face == CURSOR)
			Bprint(&buf, "{");
		for(y=r.min.y; y<r.max.y; y++){
			unloadimage(t->b, Rect(r.min.x, y, r.max.x, y+1), data, sizeof data);
			j = 0;
			for(x=r.min.x; x<r.max.x; j+=ws,x+=ws*8>>ld){
				Bprint(&buf, "0x");
				for(i=0; i<ws; i++)
					Bprint(&buf, "%.2x", data[i+j]);
				Bprint(&buf, ", ");
			}
			if(t->face == CURSOR){
				switch(y){
				case 3: case 7: case 11: case 19: case 23: case 27:
					Bprint(&buf, "\n ");
					break;
				case 15:
					Bprint(&buf, "},\n{");
					break;
				case 31:
					Bprint(&buf, "}\n");
					break;
				}
			}else
				Bprint(&buf, "\n");
		}
		Bterm(&buf);
	}else
		if(writeimage(fd, t->b, 0)<0 || (t->s && writesubfont(fd, t->s)<0)){
			close(fd);
			mesg("can't write %s: %r", t->name);
		}
	t->mod = 0;
	close(fd);
	mesg("wrote %s", t->name);
}

void
tpixels(void)
{
	Thing *t;
	Point p, lastp;

	esetcursor(&pixel);
	for(;;){
		buttons(Down);
		if(mouse.buttons != 4)
			break;
		for(t=thing; t; t=t->next){
			lastp = Pt(-1, -1);
			if(ptinrect(mouse.xy, t->r)){
				while(ptinrect(mouse.xy, t->r) && mouse.buttons==4){
					p = realpt(t, mouse.xy);
					if(!eqpt(p, lastp)){
						if(p.y != lastp.y)
							unloadimage(t->b, Rect(t->b->r.min.x, p.y, t->b->r.max.x, p.y+1), data, sizeof data);
						mesg("[%d,%d] = %d=0x%ux", p.x, p.y, value(t->b, p.x), value(t->b, p.x));
						lastp = p;
					}
					mouse = emouse();
				}
				goto Continue;
			}
		}
		mouse = emouse();
    Continue:;
	}
	buttons(Up);
	esetcursor(0);
}

void
tclose1(Thing *t)
{
	Thing *nt;

	if(t == thing)
		thing = t->next;
	else{
		for(nt=thing; nt->next!=t; nt=nt->next)
			;
		nt->next = t->next;
	}
	do
		for(nt=thing; nt; nt=nt->next)
			if(nt->parent == t){
				tclose1(nt);
				break;
			}
	while(nt);
	if(t->s)
		freesubfont(t->s);
	else
		freeimage(t->b);
	free(t->name);
	free(t);
}

void
tclose(Thing *t)
{
	Thing *ct;

	if(t->mod){
		mesg("%s modified", t->name);
		t->mod = 0;
		return;
	}
	/* fiddle to save redrawing unmoved things */
	if(t == thing)
		ct = 0;
	else
		for(ct=thing; ct; ct=ct->next)
			if(ct->next==t || ct->next->parent==t)
				break;
	tclose1(t);
	if(ct)
		ct = ct->next;
	else
		ct = thing;
	redraw(ct);
}

void
tread(Thing *t)
{
	Thing *nt, *new;
	Fontchar *i;
	Rectangle r;
	int nclosed;

	if(t->parent)
		t = t->parent;
	new = tget(t->name);
	if(new == 0)
		return;
	nclosed = 0;
    again:
	for(nt=thing; nt; nt=nt->next)
		if(nt->parent == t){
			if(!rectinrect(nt->b->r, new->b->r)
			|| new->b->depth!=nt->b->depth){
    closeit:
				nclosed++;
				nt->parent = 0;
				tclose1(nt);
				goto again;
			}
			if((t->s==0) != (new->s==0))
				goto closeit;
			if((t->face==0) != (new->face==0))
				goto closeit;
			if(t->s){	/* check same char */
				if(nt->c >= new->s->n)
					goto closeit;
				i = &new->s->info[nt->c];
				r.min.x = i[0].x;
				r.max.x = i[1].x;
				r.min.y = new->b->r.min.y;
				r.max.y = new->b->r.max.y;
				if(!eqrect(r, nt->b->r))
					goto closeit;
			}
			nt->parent = new;
			draw(nt->b, nt->b->r, new->b, nil, nt->b->r.min);
		}
	new->next = t->next;
	if(t == thing)
		thing = new;
	else{
		for(nt=thing; nt->next!=t; nt=nt->next)
			;
		nt->next = new;
	}
	if(t->s)
		freesubfont(t->s);
	else
		freeimage(t->b);
	free(t->name);
	free(t);
	for(nt=thing; nt; nt=nt->next)
		if(nt==new || nt->parent==new)
			if(nclosed == 0)
				drawthing(nt, 0);	/* can draw in place */
			else{
				redraw(nt);	/* must redraw all below */
				break;
			}
}

void
tchar(Thing *t)
{
	char buf[256], *p;
	Rune r;
	ulong c, d;

	if(t->s == 0){
		t = t->parent;
		if(t==0 || t->s==0){
			mesg("not a subfont");
			return;
		}
	}
	if(type(buf, "char (hex or character or hex-hex)") == 0)
		return;
	if(utflen(buf) == 1){
		chartorune(&r, buf);
		c = r;
		d = r;
	}else{
		if(!strchr(hex, buf[0])){
			mesg("illegal hex character");
			return;
		}
		c = strtoul(buf, 0, 16);
		d = c;
		p = utfrune(buf, '-');
		if(p){
			d = strtoul(p+1, 0, 16);
			if(d < c){
				mesg("invalid range");
				return;
			}
		}
	}
	c -= t->off;
	d -= t->off;
	while(c <= d){
		if((long)c<0 || c>=t->s->n){
			mesg("0x%lux not in font %s", c+t->off, t->name);
			return;
		}
		openedit(t, Pt(0, 0), c);
		c++;
	}
}

void
apply(void (*f)(Thing*))
{
	Thing *t;

	esetcursor(&sight);
	buttons(Down);
	if(mouse.buttons == 4)
		for(t=thing; t; t=t->next)
			if(ptinrect(mouse.xy, t->er)){
				buttons(Up);
				f(t);
				break;
			}
	buttons(Up);
	esetcursor(0);
}

int
complement(Image *t)
{
	int i, n;
	uchar *buf;

	n = Dy(t->r)*bytesperline(t->r, t->depth);
	buf = malloc(n);
	if(buf == 0)
		return 0;
	unloadimage(t, t->r, buf, n);
	for(i=0; i<n; i++)
		buf[i] = ~buf[i];
	loadimage(t, t->r, buf, n);
	free(buf);
	return 1;
}

void
copy(void)
{
	Thing *st, *dt, *nt;
	Rectangle sr, dr, fr;
	Image *tmp;
	Point p1, p2;
	int but, up;

	if(!sweep(3, &sr))
		return;
	for(st=thing; st; st=st->next)
		if(rectXrect(sr, st->r))
			break;
	if(st == 0)
		return;
	/* click gives full rectangle */
	if(Dx(sr)<4 && Dy(sr)<4)
		sr = st->r;
	rectclip(&sr, st->r);
	p1 = realpt(st, sr.min);
	p2 = realpt(st, Pt(sr.min.x, sr.max.y));
	up = 0;
	if(p1.x != p2.x){	/* swept across a fold */
   onafold:
		mesg("sweep spans a fold");
		goto Return;
	}
	p2 = realpt(st, sr.max);
	sr.min = p1;
	sr.max = p2;
	fr.min = screenpt(st, sr.min);
	fr.max = screenpt(st, sr.max);
	p1 = subpt(p2, p1);	/* diagonal */
	if(p1.x==0 || p1.y==0)
		return;
	border(screen, fr, -1, values[Blue], ZP);
	esetcursor(&box);
	for(; mouse.buttons==0; mouse=emouse()){
		for(dt=thing; dt; dt=dt->next)
			if(ptinrect(mouse.xy, dt->er))
				break;
		if(up)
			edrawgetrect(insetrect(dr, -Borderwidth), 0);
		up = 0;
		if(dt == 0)
			continue;
		dr.max = screenpt(dt, realpt(dt, mouse.xy));
		dr.min = subpt(dr.max, mulpt(p1, dt->mag));
		if(!rectXrect(dr, dt->r))
			continue;
		edrawgetrect(insetrect(dr, -Borderwidth), 1);
		up = 1;
	}
	/* if up==1, we had a hit */
	esetcursor(0);
	if(up)
		edrawgetrect(insetrect(dr, -Borderwidth), 0);
	but = mouse.buttons;
	buttons(Up);
	if(!up || but!=4)
		goto Return;
	dt = 0;
	for(nt=thing; nt; nt=nt->next)
		if(rectXrect(dr, nt->r)){
			if(dt){
				mesg("ambiguous sweep");
				return;
			}
			dt = nt;
		}
	if(dt == 0)
		goto Return;
	p1 = realpt(dt, dr.min);
	p2 = realpt(dt, Pt(dr.min.x, dr.max.y));
	if(p1.x != p2.x)
		goto onafold;
	p2 = realpt(dt, dr.max);
	dr.min = p1;
	dr.max = p2;

	if(invert){
		tmp = allocimage(display, dr, dt->b->chan, 0, 255);
		if(tmp == 0){
    nomem:
			mesg("can't allocate temporary");
			goto Return;
		}
		draw(tmp, dr, st->b, nil, sr.min);
		if(!complement(tmp))
			goto nomem;
		draw(dt->b, dr, tmp, nil, dr.min);
		freeimage(tmp);
	}else
		draw(dt->b, dr, st->b, nil, sr.min);
	if(dt->parent){
		draw(dt->parent->b, dr, dt->b, nil, dr.min);
		dt = dt->parent;
	}
	drawthing(dt, 0);
	for(nt=thing; nt; nt=nt->next)
		if(nt->parent==dt && rectXrect(dr, nt->b->r)){
			draw(nt->b, dr, dt->b, nil, dr.min);
			drawthing(nt, 0);
		}
	ckinfo(dt, dr);
	dt->mod = 1;

Return:
	/* clear blue box */
	drawthing(st, 0);
}

void
menu(void)
{
	Thing *t;
	char *mod;
	int sel;
	char buf[256];

	sel = emenuhit(3, &mouse, &menu3);
	switch(sel){
	case Mopen:
		if(type(buf, "file")){
			t = tget(buf);
			if(t)
				drawthing(t, 1);
		}
		break;
	case Mwrite:
		apply(twrite);
		break;
	case Mread:
		apply(tread);
		break;
	case Mchar:
		apply(tchar);
		break;
	case Mcopy:
		copy();
		break;
	case Mpixels:
		tpixels();
		break;
	case Mclose:
		apply(tclose);
		break;
	case Mexit:
		mod = 0;
		for(t=thing; t; t=t->next)
			if(t->mod){
				mod = t->name;
				t->mod = 0;
			}
		if(mod){
			mesg("%s modified", mod);
			break;
		}
		esetcursor(&skull);
		buttons(Down);
		if(mouse.buttons == 4){
			buttons(Up);
			exits(0);
		}
		buttons(Up);
		esetcursor(0);
		break;
	}
}
