/*
 * the actual viewer that handles screen stuff
 */

#include <u.h>
#include <libc.h>
#include <draw.h>
#include <cursor.h>
#include <event.h>
#include <bio.h>
#include <plumb.h>
#include <ctype.h>
#include <keyboard.h>
#include "page.h"

Document *doc;
Image *im;
int page;
int upside = 0;
int showbottom = 0;		/* on the next showpage, move the image so the bottom is visible. */

Rectangle ulrange;	/* the upper left corner of the image must be in this rectangle */
Point ul;			/* the upper left corner of the image is at this point on the screen */

Point pclip(Point, Rectangle);
Rectangle mkrange(Rectangle screenr, Rectangle imr);
void redraw(Image*);

Cursor reading={
	{-1, -1},
	{0xff, 0x80, 0xff, 0x80, 0xff, 0x00, 0xfe, 0x00, 
	 0xff, 0x00, 0xff, 0x80, 0xff, 0xc0, 0xef, 0xe0, 
	 0xc7, 0xf0, 0x03, 0xf0, 0x01, 0xe0, 0x00, 0xc0, 
	 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, },
	{0x00, 0x00, 0x7f, 0x00, 0x7e, 0x00, 0x7c, 0x00, 
	 0x7e, 0x00, 0x7f, 0x00, 0x6f, 0x80, 0x47, 0xc0, 
	 0x03, 0xe0, 0x01, 0xf0, 0x00, 0xe0, 0x00, 0x40, 
	 0x00, 0x00, 0x01, 0xb6, 0x01, 0xb6, 0x00, 0x00, }
};

Cursor query = {
	{-7,-7},
	{0x0f, 0xf0, 0x1f, 0xf8, 0x3f, 0xfc, 0x7f, 0xfe, 
	 0x7c, 0x7e, 0x78, 0x7e, 0x00, 0xfc, 0x01, 0xf8, 
	 0x03, 0xf0, 0x07, 0xe0, 0x07, 0xc0, 0x07, 0xc0, 
	 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xc0, },
	{0x00, 0x00, 0x0f, 0xf0, 0x1f, 0xf8, 0x3c, 0x3c, 
	 0x38, 0x1c, 0x00, 0x3c, 0x00, 0x78, 0x00, 0xf0, 
	 0x01, 0xe0, 0x03, 0xc0, 0x03, 0x80, 0x03, 0x80, 
	 0x00, 0x00, 0x03, 0x80, 0x03, 0x80, 0x00, 0x00, }
};

enum {
	Left = 1,
	Middle = 2,
	Right = 4,

	RMenu = 3,
};

void
unhide(void)
{
	static int wctl = -1;

	if(wctl < 0)
		wctl = open("/dev/wctl", OWRITE);
	if(wctl < 0)
		return;

	write(wctl, "unhide", 6);
}

int 
max(int a, int b)
{
	return a > b ? a : b;
}

int 
min(int a, int b)
{
	return a < b ? a : b;
}


char*
menugen(int n)
{
	static char menustr[32];
	char *p;
	int len;

	if(n == doc->npage)
		return "exit";
	if(n > doc->npage)
		return nil;

	if(reverse)
		n = doc->npage-1-n;

	p = doc->pagename(doc, n);
	len = (sizeof menustr)-2;

	if(strlen(p) > len && strrchr(p, '/'))
		p = strrchr(p, '/')+1;
	if(strlen(p) > len)
		p = p+strlen(p)-len;

	strcpy(menustr+1, p);
	if(page == n)
		menustr[0] = '>';
	else
		menustr[0] = ' ';
	return menustr;
}

void
showpage(int page, Menu *m)
{
	Image *tmp;

	if(doc->fwdonly)
		m->lasthit = 0;	/* this page */
	else
		m->lasthit = reverse ? doc->npage-1-page : page;
	
	esetcursor(&reading);
	freeimage(im);
	if((page < 0 || page >= doc->npage) && !doc->fwdonly){
		im = nil;
		return;
	}
	im = doc->drawpage(doc, page);
	if(im == nil) {
		if(doc->fwdonly)	/* this is how we know we're out of pages */
			wexits(0);

		im = xallocimage(display, Rect(0,0,50,50), GREY1, 1, DBlack);
		if(im == nil) {
			fprint(2, "out of memory: %r\n");
			wexits("memory");
		}
		string(im, ZP, display->white, ZP, display->defaultfont, "?");
	}else if(resizing){
		resize(Dx(im->r), Dy(im->r));
	}
	if(im->r.min.x > 0 || im->r.min.y > 0) {
		tmp = xallocimage(display, Rect(0, 0, Dx(im->r), Dy(im->r)), im->chan, 0, DNofill);
		if(tmp == nil) {
			fprint(2, "out of memory during showpage: %r\n");
			wexits("memory");
		}
		drawop(tmp, tmp->r, im, nil, im->r.min, S);
		freeimage(im);
		im = tmp;
	}

	if(upside)
		rot180(im);

	esetcursor(nil);
	if(showbottom){
		ul.y = screen->r.max.y - Dy(im->r);
		showbottom = 0;
	}

	redraw(screen);
	flushimage(display, 1);
}

char*
writebitmap(void)
{
	char basename[64];
	char name[64+30];
	static char result[200];
	char *p, *q;
	int fd;

	if(im == nil)
		return "no image";

	memset(basename, 0, sizeof basename);
	if(doc->docname)
		strncpy(basename, doc->docname, sizeof(basename)-1);
	else if((p = menugen(page)) && p[0] != '\0')
		strncpy(basename, p+1, sizeof(basename)-1);

	if(basename[0]) {
		if(q = strrchr(basename, '/'))
			q++;
		else
			q = basename;
		if(p = strchr(q, '.'))
			*p = 0;
		
		memset(name, 0, sizeof name);
		snprint(name, sizeof(name)-1, "%s.%d.bit", q, page+1);
		if(access(name, 0) >= 0) {
			strcat(name, "XXXX");
			mktemp(name);
		}
		if(access(name, 0) >= 0)
			return "couldn't think of a name for bitmap";
	} else {
		strcpy(name, "bitXXXX");
		mktemp(name);
		if(access(name, 0) >= 0) 
			return "couldn't think of a name for bitmap";
	}

	if((fd = create(name, OWRITE, 0666)) < 0) {
		snprint(result, sizeof result, "cannot create %s: %r", name);
		return result;
	}

	if(writeimage(fd, im, 0) < 0) {
		snprint(result, sizeof result, "cannot writeimage: %r");
		close(fd);
		return result;
	}
	close(fd);

	snprint(result, sizeof result, "wrote %s", name);
	return result;
}

static void translate(Point);

static int
showdata(Plumbmsg *msg)
{
	char *s;

	s = plumblookup(msg->attr, "action");
	return s && strcmp(s, "showdata")==0;
}

/* correspond to entries in miditems[] below,
 * changing one means you need to change
 */
enum{
	Restore = 0,
	Zin,
	Fit,
	Rot,
	Upside,
	Empty1,
	Next,
	Prev,
	Zerox,
	Empty2,
	Reverse,
	Del,
	Write,
	Empty3,
	Exit,
};
 
void
viewer(Document *dd)
{
	int i, fd, n, oldpage;
	int nxt;
	Menu menu, midmenu;
	Mouse m;
	Event e;
	Point dxy, oxy, xy0;
	Rectangle r;
	Image *tmp;
	static char *fwditems[] = { "this page", "next page", "exit", 0 };
 	static char *miditems[] = {
 		"orig size",
 		"zoom in",
 		"fit window",
 		"rotate 90",
 		"upside down",
 		"",
 		"next",
 		"prev",
		"zerox",
 		"", 
 		"reverse",
 		"discard",
 		"write",
 		"", 
 		"quit", 
 		0 
 	};
	char *s;
	enum { Eplumb = 4 };
	Plumbmsg *pm;

	doc = dd;    /* save global for menuhit */
	ul = screen->r.min;
	einit(Emouse|Ekeyboard);
	if(doc->addpage != nil)
		eplumb(Eplumb, "image");

	esetcursor(&reading);
	r.min = ZP;

	/*
	 * im is a global pointer to the current image.
	 * eventually, i think we will have a layer between
	 * the display routines and the ps/pdf/whatever routines
	 * to perhaps cache and handle images of different
	 * sizes, etc.
	 */
	im = 0;
	page = reverse ? doc->npage-1 : 0;

	if(doc->fwdonly) {
		menu.item = fwditems;
		menu.gen = 0;
		menu.lasthit = 0;
	} else {
		menu.item = 0;
		menu.gen = menugen;
		menu.lasthit = 0;
	}

	midmenu.item = miditems;
	midmenu.gen = 0;
	midmenu.lasthit = Next;

	showpage(page, &menu);
	esetcursor(nil);

	nxt = 0;
	for(;;) {
		/*
		 * throughout, if doc->fwdonly is set, we restrict the functionality
		 * a fair amount.  we don't care about doc->npage anymore, and
		 * all that can be done is select the next page.
		 */
		switch(eread(Emouse|Ekeyboard|Eplumb, &e)){
		case Ekeyboard:
			if(e.kbdc <= 0xFF && isdigit(e.kbdc)) {
				nxt = nxt*10+e.kbdc-'0';
				break;
			} else if(e.kbdc != '\n')
				nxt = 0;
			switch(e.kbdc) {
			case 'r':	/* reverse page order */
				if(doc->fwdonly)
					break;
				reverse = !reverse;
				menu.lasthit = doc->npage-1-menu.lasthit;

				/*
				 * the theory is that if we are reversing the
				 * document order and are on the first or last
				 * page then we're just starting and really want
		 	 	 * to view the other end.  maybe the if
				 * should be dropped and this should happen always.
				 */
				if(page == 0 || page == doc->npage-1) {
					page = doc->npage-1-page;
					showpage(page, &menu);
				}
				break;
			case 'w':	/* write bitmap of current screen */
				esetcursor(&reading);
				s = writebitmap();
				if(s)
					string(screen, addpt(screen->r.min, Pt(5,5)), display->black, ZP,
						display->defaultfont, s);
				esetcursor(nil);
				flushimage(display, 1);
				break;
			case 'd':	/* remove image from working set */
				if(doc->rmpage && page < doc->npage) {
					if(doc->rmpage(doc, page) >= 0) {
						if(doc->npage < 0)
							wexits(0);
						if(page >= doc->npage)
							page = doc->npage-1;
						showpage(page, &menu);
					}
				}
				break;
			case 'q':
			case 0x04: /* ctrl-d */
				wexits(0);
			case 'u':
				if(im==nil)
					break;
				esetcursor(&reading);
				rot180(im);
				esetcursor(nil);
				upside = !upside;
				redraw(screen);
				flushimage(display, 1);
				break;
			case '-':
			case '\b':
			case Kleft:
				if(page > 0 && !doc->fwdonly) {
					--page;
					showpage(page, &menu);
				}
				break;
			case '\n':
				if(nxt) {
					nxt--;
					if(nxt >= 0 && nxt < doc->npage && !doc->fwdonly)
						showpage(page=nxt, &menu);
					nxt = 0;
					break;
				}
				goto Gotonext;
			case Kright:
			case ' ':
			Gotonext:
				if(doc->npage && ++page >= doc->npage && !doc->fwdonly)
					wexits(0);
				showpage(page, &menu);
				break;

			/*
			 * The upper y coordinate of the image is at ul.y in screen->r.
			 * Panning up means moving the upper left corner down.  If the
			 * upper left corner is currently visible, we need to go back a page.
			 */
			case Kup:
				if(screen->r.min.y <= ul.y && ul.y < screen->r.max.y){
					if(page > 0 && !doc->fwdonly){
						--page;
						showbottom = 1;
						showpage(page, &menu);
					}
				} else {
					i = Dy(screen->r)/2;
					if(i > 10)
						i -= 10;
					if(i+ul.y > screen->r.min.y)
						i = screen->r.min.y - ul.y;
					translate(Pt(0, i));
				}
				break;

			/*
			 * If the lower y coordinate is on the screen, we go to the next page.
			 * The lower y coordinate is at ul.y + Dy(im->r).
			 */
			case Kdown:
				i = ul.y + Dy(im->r);
				if(screen->r.min.y <= i && i <= screen->r.max.y){
					ul.y = screen->r.min.y;
					goto Gotonext;
				} else {
					i = -Dy(screen->r)/2;
					if(i < -10)
						i += 10;
					if(i+ul.y+Dy(im->r) <= screen->r.max.y)
						i = screen->r.max.y - Dy(im->r) - ul.y - 1;
					translate(Pt(0, i));
				}
				break;
			default:
				esetcursor(&query);
				sleep(1000);
				esetcursor(nil);
				break;	
			}
			break;

		case Emouse:
			m = e.mouse;
			switch(m.buttons){
			case Left:
				oxy = m.xy;
				xy0 = oxy;
				do {
					dxy = subpt(m.xy, oxy);
					oxy = m.xy;	
					translate(dxy);
					m = emouse();
				} while(m.buttons == Left);
				if(m.buttons) {
					dxy = subpt(xy0, oxy);
					translate(dxy);
				}
				break;
	
			case Middle:
				if(doc->npage == 0)
					break;

				n = emenuhit(Middle, &m, &midmenu);
				if(n == -1)
					break;
				switch(n){
				case Next: 	/* next */
					if(reverse)
						page--;
					else
						page++;
					if(page < 0) {
						if(reverse) return;
						else page = 0;
					}

					if((page >= doc->npage) && !doc->fwdonly)
						return;
	
					showpage(page, &menu);
					nxt = 0;
					break;
				case Prev:	/* prev */
					if(reverse)
						page++;
					else
						page--;
					if(page < 0) {
						if(reverse) return;
						else page = 0;
					}

					if((page >= doc->npage) && !doc->fwdonly && !reverse)
						return;
	
					showpage(page, &menu);
					nxt = 0;
					break;
				case Zerox:	/* prev */
					zerox();
					break;
				case Zin:	/* zoom in */
					{
						double delta;
						Rectangle r;

						r = egetrect(Middle, &m);
						if((rectclip(&r, rectaddpt(im->r, ul)) == 0) ||
							Dx(r) == 0 || Dy(r) == 0)
							break;
						/* use the smaller side to expand */
						if(Dx(r) < Dy(r))
							delta = (double)Dx(im->r)/(double)Dx(r);
						else
							delta = (double)Dy(im->r)/(double)Dy(r);

						esetcursor(&reading);
						tmp = xallocimage(display, 
								Rect(0, 0, (int)((double)Dx(im->r)*delta), (int)((double)Dy(im->r)*delta)), 
								im->chan, 0, DBlack);
						if(tmp == nil) {
							fprint(2, "out of memory during zoom: %r\n");
							wexits("memory");
						}
						resample(im, tmp);
						freeimage(im);
						im = tmp;
						esetcursor(nil);
						ul = screen->r.min;
						redraw(screen);
						flushimage(display, 1);
						break;
					}
				case Fit:	/* fit */
					{
						double delta;
						Rectangle r;
						
						delta = (double)Dx(screen->r)/(double)Dx(im->r);
						if((double)Dy(im->r)*delta > Dy(screen->r))
							delta = (double)Dy(screen->r)/(double)Dy(im->r);

						r = Rect(0, 0, (int)((double)Dx(im->r)*delta), (int)((double)Dy(im->r)*delta));
						esetcursor(&reading);
						tmp = xallocimage(display, r, im->chan, 0, DBlack);
						if(tmp == nil) {
							fprint(2, "out of memory during fit: %r\n");
							wexits("memory");
						}
						resample(im, tmp);
						freeimage(im);
						im = tmp;
						esetcursor(nil);
						ul = screen->r.min;
						redraw(screen);
						flushimage(display, 1);
						break;
					}
				case Rot:	/* rotate 90 */
					esetcursor(&reading);
					im = rot90(im);
					esetcursor(nil);
					redraw(screen);
					flushimage(display, 1);
					break;
				case Upside: 	/* upside-down */
					if(im==nil)
						break;
					esetcursor(&reading);
					rot180(im);
					esetcursor(nil);
					upside = !upside;
					redraw(screen);
					flushimage(display, 1);
					break;
				case Restore:	/* restore */
					showpage(page, &menu);
					break;
				case Reverse:	/* reverse */
					if(doc->fwdonly)
						break;
					reverse = !reverse;
					menu.lasthit = doc->npage-1-menu.lasthit;
	
					if(page == 0 || page == doc->npage-1) {
						page = doc->npage-1-page;
						showpage(page, &menu);
					}
					break;
				case Write: /* write */
					esetcursor(&reading);
					s = writebitmap();
					if(s)
						string(screen, addpt(screen->r.min, Pt(5,5)), display->black, ZP,
							display->defaultfont, s);
					esetcursor(nil);
					flushimage(display, 1);
					break;
				case Del: /* delete */
					if(doc->rmpage && page < doc->npage) {
						if(doc->rmpage(doc, page) >= 0) {
							if(doc->npage < 0)
								wexits(0);
							if(page >= doc->npage)
								page = doc->npage-1;
							showpage(page, &menu);
						}
					}
					break;
				case Exit:	/* exit */
					return;
				case Empty1:
				case Empty2:
				case Empty3:
					break;

				}; 

	
	
			case Right:
				if(doc->npage == 0)
					break;

				oldpage = page;
				n = emenuhit(RMenu, &m, &menu);
				if(n == -1)
					break;
	
				if(doc->fwdonly) {
					switch(n){
					case 0:	/* this page */
						break;
					case 1:	/* next page */
						showpage(++page, &menu);
						break;
					case 2:	/* exit */
						return;
					}
					break;
				}
	
				if(n == doc->npage)
					return;
				else
					page = reverse ? doc->npage-1-n : n;
	
				if(oldpage != page)
					showpage(page, &menu);
				nxt = 0;
				break;
			}
			break;

		case Eplumb:
			pm = e.v;
			if(pm->ndata <= 0){
				plumbfree(pm);
				break;
			}
			if(showdata(pm)) {
				s = estrdup("/tmp/pageplumbXXXXXXX");
				fd = opentemp(s);
				write(fd, pm->data, pm->ndata);
				/* lose fd reference on purpose; the file is open ORCLOSE */
			} else if(pm->data[0] == '/') {
				s = estrdup(pm->data);
			} else {
				s = emalloc(strlen(pm->wdir)+1+pm->ndata+1);
				sprint(s, "%s/%s", pm->wdir, pm->data);
				cleanname(s);
			}
			if((i = doc->addpage(doc, s)) >= 0) {
				page = i;
				unhide();
				showpage(page, &menu);
			}
			free(s);
			plumbfree(pm);
			break;
		}
	}
}

Image *gray;

/*
 * A draw operation that touches only the area contained in bot but not in top.
 * mp and sp get aligned with bot.min.
 */
static void
gendrawdiff(Image *dst, Rectangle bot, Rectangle top, 
	Image *src, Point sp, Image *mask, Point mp, int op)
{
	Rectangle r;
	Point origin;
	Point delta;

	USED(op);

	if(Dx(bot)*Dy(bot) == 0)
		return;

	/* no points in bot - top */
	if(rectinrect(bot, top))
		return;

	/* bot - top ≡ bot */
	if(Dx(top)*Dy(top)==0 || rectXrect(bot, top)==0){
		gendrawop(dst, bot, src, sp, mask, mp, op);
		return;
	}

	origin = bot.min;
	/* split bot into rectangles that don't intersect top */
	/* left side */
	if(bot.min.x < top.min.x){
		r = Rect(bot.min.x, bot.min.y, top.min.x, bot.max.y);
		delta = subpt(r.min, origin);
		gendrawop(dst, r, src, addpt(sp, delta), mask, addpt(mp, delta), op);
		bot.min.x = top.min.x;
	}

	/* right side */
	if(bot.max.x > top.max.x){
		r = Rect(top.max.x, bot.min.y, bot.max.x, bot.max.y);
		delta = subpt(r.min, origin);
		gendrawop(dst, r, src, addpt(sp, delta), mask, addpt(mp, delta), op);
		bot.max.x = top.max.x;
	}

	/* top */
	if(bot.min.y < top.min.y){
		r = Rect(bot.min.x, bot.min.y, bot.max.x, top.min.y);
		delta = subpt(r.min, origin);
		gendrawop(dst, r, src, addpt(sp, delta), mask, addpt(mp, delta), op);
		bot.min.y = top.min.y;
	}

	/* bottom */
	if(bot.max.y > top.max.y){
		r = Rect(bot.min.x, top.max.y, bot.max.x, bot.max.y);
		delta = subpt(r.min, origin);
		gendrawop(dst, r, src, addpt(sp, delta), mask, addpt(mp, delta), op);
		bot.max.y = top.max.y;
	}
}

static void
drawdiff(Image *dst, Rectangle bot, Rectangle top, Image *src, Image *mask, Point p, int op)
{
	gendrawdiff(dst, bot, top, src, p, mask, p, op);
}

/*
 * Translate the image in the window by delta.
 */
static void
translate(Point delta)
{
	Point u;
	Rectangle r, or;

	if(im == nil)
		return;

	u = pclip(addpt(ul, delta), ulrange);
	delta = subpt(u, ul);
	if(delta.x == 0 && delta.y == 0)
		return;

	/*
	 * The upper left corner of the image is currently at ul.
	 * We want to move it to u.
	 */
	or = rectaddpt(Rpt(ZP, Pt(Dx(im->r), Dy(im->r))), ul);
	r = rectaddpt(or, delta);

	drawop(screen, r, screen, nil, ul, S);
	ul = u;

	/* fill in gray where image used to be but isn't. */
	drawdiff(screen, insetrect(or, -2), insetrect(r, -2), gray, nil, ZP, S);

	/* fill in black border */
	drawdiff(screen, insetrect(r, -2), r, display->black, nil, ZP, S);

	/* fill in image where it used to be off the screen. */
	if(rectclip(&or, screen->r))
		drawdiff(screen, r, rectaddpt(or, delta), im, nil, im->r.min, S);
	else
		drawop(screen, r, im, nil, im->r.min, S);
	flushimage(display, 1);
}

void
redraw(Image *screen)
{
	Rectangle r;

	if(im == nil)
		return;

	ulrange.max = screen->r.max;
	ulrange.min = subpt(screen->r.min, Pt(Dx(im->r), Dy(im->r)));

	ul = pclip(ul, ulrange);
	drawop(screen, screen->r, im, nil, subpt(im->r.min, subpt(ul, screen->r.min)), S);

	if(im->repl)
		return;

	/* fill in any outer edges */
	/* black border */
	r = rectaddpt(im->r, subpt(ul, im->r.min));
	border(screen, r, -2, display->black, ZP);
	r.min = subpt(r.min, Pt(2,2));
	r.max = addpt(r.max, Pt(2,2));

	/* gray for the rest */
	if(gray == nil) {
		gray = xallocimage(display, Rect(0,0,1,1), RGB24, 1, 0x888888FF);
		if(gray == nil) {
			fprint(2, "g out of memory: %r\n");
			wexits("mem");
		}
	}
	border(screen, r, -4000, gray, ZP);
//	flushimage(display, 0);	
}

void
eresized(int new)
{
	Rectangle r;
	r = screen->r;
	if(new && getwindow(display, Refnone) < 0)
		fprint(2,"can't reattach to window");
	ul = addpt(ul, subpt(screen->r.min, r.min));
	redraw(screen);
}

/* clip p to be in r */
Point
pclip(Point p, Rectangle r)
{
	if(p.x < r.min.x)
		p.x = r.min.x;
	else if(p.x >= r.max.x)
		p.x = r.max.x-1;

	if(p.y < r.min.y)
		p.y = r.min.y;
	else if(p.y >= r.max.y)
		p.y = r.max.y-1;

	return p;
}

/*
 * resize is perhaps a misnomer. 
 * this really just grows the window to be at least dx across
 * and dy high.  if the window hits the bottom or right edge,
 * it is backed up until it hits the top or left edge.
 */
void
resize(int dx, int dy)
{
	static Rectangle sr;
	Rectangle r, or;

	dx += 2*Borderwidth;
	dy += 2*Borderwidth;
	if(wctlfd < 0){
		wctlfd = open("/dev/wctl", OWRITE);
		if(wctlfd < 0)
			return;
	}

	r = insetrect(screen->r, -Borderwidth);
	if(Dx(r) >= dx && Dy(r) >= dy)
		return;

	if(Dx(sr)*Dy(sr) == 0)
		sr = screenrect();

	or = r;

	r.max.x = max(r.min.x+dx, r.max.x);
	r.max.y = max(r.min.y+dy, r.max.y);
	if(r.max.x > sr.max.x){
		if(Dx(r) > Dx(sr)){
			r.min.x = 0;
			r.max.x = sr.max.x;
		}else
			r = rectaddpt(r, Pt(sr.max.x-r.max.x, 0));
	}
	if(r.max.y > sr.max.y){
		if(Dy(r) > Dy(sr)){
			r.min.y = 0;
			r.max.y = sr.max.y;
		}else
			r = rectaddpt(r, Pt(0, sr.max.y-r.max.y));
	}

	/*
	 * Sometimes we can't actually grow the window big enough,
	 * and resizing it to the same shape makes it flash.
	 */
	if(Dx(r) == Dx(or) && Dy(r) == Dy(or))
		return;

	fprint(wctlfd, "resize -minx %d -miny %d -maxx %d -maxy %d\n",
		r.min.x, r.min.y, r.max.x, r.max.y);
}

/*
 * If we allocimage after a resize but before flushing the draw buffer,
 * we won't have seen the reshape event, and we won't have called
 * getwindow, and allocimage will fail.  So we flushimage before every alloc.
 */
Image*
xallocimage(Display *d, Rectangle r, ulong chan, int repl, ulong val)
{
	flushimage(display, 0);
	return allocimage(d, r, chan, repl, val);
}

/* all code below this line should be in the library, but is stolen from colors instead */
static char*
rdenv(char *name)
{
	char *v;
	int fd, size;

	fd = open(name, OREAD);
	if(fd < 0)
		return 0;
	size = seek(fd, 0, 2);
	v = malloc(size+1);
	if(v == 0){
		fprint(2, "page: can't malloc: %r\n");
		wexits("no mem");
	}
	seek(fd, 0, 0);
	read(fd, v, size);
	v[size] = 0;
	close(fd);
	return v;
}

Rectangle
screenrect(void)
{
	int fd;
	char buf[12*5];

	fd = open("/dev/screen", OREAD);
	if(fd == -1)
		fd=open("/mnt/term/dev/screen", OREAD);
	if(fd == -1){
		fprint(2, "page: can't open /dev/screen: %r\n");
		wexits("window read");
	}
	if(read(fd, buf, sizeof buf) != sizeof buf){
		fprint(2, "page: can't read /dev/screen: %r\n");
		wexits("screen read");
	}
	close(fd);
	return Rect(atoi(buf+12), atoi(buf+24), atoi(buf+36), atoi(buf+48));
}

void
zerox(void)
{
	int pfd[2];

	pipe(pfd);
	switch(rfork(RFFDG|RFPROC)) {
		case -1:
			wexits("cannot fork in zerox: %r");
		case 0: 
			dup(pfd[1], 0);
			close(pfd[0]);
			execl("/bin/page", "page", "-w", 0);
			wexits("cannot exec in zerox: %r\n");
		default:
			close(pfd[1]);
			writeimage(pfd[0], im, 0);
			close(pfd[0]);
			break;
	}
}
