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

#include <u.h>
#include <libc.h>
#include <9pclient.h>
#include <draw.h>
#include <cursor.h>
#include <mouse.h>
#include <keyboard.h>
#include <thread.h>
#include <bio.h>
#include <plumb.h>
#include <ctype.h>
#include "page.h"

Document *doc;
Mousectl *mc;
Image *im;
Image *tofree;
int page;
int angle = 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*);
void plumbproc(void*);

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,
};

static void
delayfreeimage(Image *m)
{
	if(m == tofree)
		return;
	if(tofree)
		freeimage(tofree);
	tofree = m;
}

void
unhide(void)
{
	USED(nil);
}

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)
{
	if(doc->fwdonly)
		m->lasthit = 0;	/* this page */
	else
		m->lasthit = reverse ? doc->npage-1-page : page;
	
	setcursor(mc, &reading);
	delayfreeimage(nil);
	im = cachedpage(doc, angle, page);
	if(im == nil)
		wexits(0);
	if(resizing)
		resize(Dx(im->r), Dy(im->r));

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

	if((doc->type == Tgfx) && fitwin)
		fit();
	else{
		redraw(screen);
	 	flushimage(display, 1);
	}
}

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

	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");
			fd = mkstemp(name);
		}
		if(fd < 0)
			return "couldn't think of a name for bitmap";
	} else {
		strcpy(name, "bitXXXX");
		mkstemp(name);
		if(fd < 0)
			return "couldn't think of a name for bitmap";
	}

	if(fd < 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, a;
	Channel *cp;
	Menu menu, midmenu;
	Mouse m;
	Keyboardctl *kc;
	Point dxy, oxy, xy0;
	Rune run;
	Rectangle r;
	int size[2];
	Image *tmp;
	PDFInfo *pdf;
	PSInfo *ps;
	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 {
	    CMouse,
	    CResize,
	    CKeyboard,
	    CPlumb,
	    CN
	};
	Alt alts[CN+1];
	Plumbmsg *pm;
	
	cp = chancreate(sizeof pm, 0);
	assert(cp);

	doc = dd;    /* save global for menuhit */
	ul = screen->r.min;
	mc = initmouse(nil, screen);
	kc = initkeyboard(nil);
	alts[CMouse].c = mc->c;
	alts[CMouse].v = &m;
	alts[CMouse].op = CHANRCV;
	alts[CResize].c = mc->resizec;
	alts[CResize].v = &size;
	alts[CResize].op = CHANRCV;
	alts[CKeyboard].c = kc->c;
	alts[CKeyboard].v = &run;
	alts[CKeyboard].op = CHANRCV;
	alts[CPlumb].c = cp;
	alts[CPlumb].v = &pm;
	alts[CPlumb].op = CHANNOP;
	alts[CN].op = CHANEND;

	/* XXX: Event */
	if(doc->addpage != nil) {
		alts[CPlumb].op = CHANRCV;
		proccreate(plumbproc, cp, 16384);
	}

	setcursor(mc, &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);
	setcursor(mc, 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.
		 */
		unlockdisplay(display);
		a = alt(alts);
		lockdisplay(display);
		switch(a) {
		case CKeyboard:
			if(run <= 0xFF && isdigit(run)) {
				nxt = nxt*10+run-'0';
				break;
			} else if(run != '\n')
				nxt = 0;
			switch(run) {
			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 */
				setcursor(mc, &reading);
				s = writebitmap();
				if(s)
					string(screen, addpt(screen->r.min, Pt(5,5)), display->black, ZP,
						display->defaultfont, s);
				setcursor(mc, 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;
				setcursor(mc, &reading);
				rot180(im);
				setcursor(mc, nil);
				angle = (angle+180) % 360;
				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:
				setcursor(mc, &query);
				sleep(1000);
				setcursor(mc, nil);
				break;	
			}
			break;

		case CMouse:
			switch(m.buttons){
			case Left:
				oxy = m.xy;
				xy0 = oxy;
				do {
					dxy = subpt(m.xy, oxy);
					oxy = m.xy;	
					translate(dxy);
					recv(mc->c, &m);
				} while(m.buttons == Left);
				if(m.buttons) {
					dxy = subpt(xy0, oxy);
					translate(dxy);
				}
				break;
	
			case Middle:
				if(doc->npage == 0)
					break;

				n = menuhit(Middle, mc, &midmenu, nil);
				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 */
					if (dd->type == Tpdf){		/* pdf */
						pdf = (PDFInfo *) dd->extra;
						if (pdf != nil){
							ppi+= 50;
							setdim(&pdf->gs, Rect(0,0,0,0), ppi, 0);
							showpage(page, &menu);
						}
						break;
					}
					if (dd->type == Tps){		/* ps */
						ps = (PSInfo *) dd->extra;
						if (ps != nil){
							ppi+= 50;
							setdim(&ps->gs, Rect(0,0,0,0), ppi, 0);
							showpage(page, &menu);
						}
						break;
					}				
					else{ 	/* image */
						double delta;
						Rectangle r;

						r = getrect(Middle, mc);
						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);

						setcursor(mc, &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);
						im = tmp;
						delayfreeimage(tmp);
						setcursor(mc, nil);
						ul = screen->r.min;
						redraw(screen);
						flushimage(display, 1);
						break;
					}
				case Fit:	/* fit */
					/* no op if pdf or ps*/
					if (dd->type == Tgfx){
						fitwin = 1;
						fit();
					}
					break;
				case Rot:	/* rotate 90 */
					angle = (angle+90) % 360;
					showpage(page, &menu);
					break;
				case Upside: 	/* upside-down */
					angle = (angle+180) % 360;
					showpage(page, &menu);
					break;
				case Restore:	/* restore */
					if (dd->type == Tpdf){		/* pdf */
						pdf = (PDFInfo *) dd->extra;
						if (pdf != nil){
							ppi = 100;
							setdim(&pdf->gs, Rect(0,0,0,0), ppi, 0);
						}
						showpage(page, &menu);
						break;
					}
					if (dd->type == Tps){		/* ps */
						ps = (PSInfo *) dd->extra;
						if (ps != nil){
							ppi = 100;
							setdim(&ps->gs, Rect(0,0,0,0), ppi, 0);
						}
						showpage(page, &menu);
						break;
					}
					fitwin = 0;
					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 */
					setcursor(mc, &reading);
					s = writebitmap();
					if(s)
						string(screen, addpt(screen->r.min, Pt(5,5)), display->black, ZP,
							display->defaultfont, s);
					setcursor(mc, 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 = menuhit(RMenu, mc, &menu, nil);
				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 CResize:
			r = screen->r;
			if(getwindow(display, Refnone) < 0)
				fprint(2,"can't reattach to window");
			ul = addpt(ul, subpt(screen->r.min, r.min));
			redraw(screen);
			flushimage(display, 1);
			break;
		case CPlumb:
			if(pm->ndata <= 0){
				plumbfree(pm);
				break;
			}
			if(showdata(pm)) {
				s = estrdup("/tmp/pageplumbXXXXXXX");
				fd = opentemp(s, ORDWR|ORCLOSE);
				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);	
}

/* 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;

	r = screen->r;
	if(Dx(sr)*Dy(sr) == 0) {
		sr = screenrect();
		/* Start with the size of the first image */
		r.max.x = r.min.x;
		r.max.y = r.min.y;
	}

	if(Dx(r) >= dx && Dy(r) >= dy)
		return;

	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;

	drawresizewindow(r);
}

/*
 * 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);
}

void
plumbproc(void *c)
{
	Channel *cp;
	CFid *fd;

	cp = c;
	fd = plumbopenfid("image", OREAD|OCEXEC);
	if(fd == nil) {
		fprint(2, "Cannot connect to the plumber");
		threadexits("plumber");
	}
	for(;;) {
		send(cp, plumbrecvfid(fd));
	}
}

/* XXX: This function is ugly and hacky. There may be a better way... or not */
Rectangle
screenrect(void)
{
	int fd[3], pfd[2];
	int n, w, h;
	char buf[64];
	char *p, *pr;

	if(pipe(pfd) < 0)
		wexits("pipe failed");

	fd[0] = open("/dev/null", OREAD);
	fd[1] = pfd[1];
	fd[2] = dup(2, -1);
	if(threadspawnl(fd, "rc", "rc", "-c", "xdpyinfo | grep 'dimensions:'", nil) == -1)
		wexits("threadspawnl failed");

	if((n = read(pfd[0], buf, 63)) <= 0)
		wexits("read xdpyinfo failed");
	close(fd[0]);

	buf[n] = '\0';
	for(p = buf; *p; p++)
		if(*p >= '0' && *p <= '9') break;
	if(*p == '\0')
		wexits("xdpyinfo parse failed");

	w = strtoul(p, &pr, 10);
	if(p == pr || *pr == '\0' || *(++pr) == '\0')
		wexits("xdpyinfo parse failed");
	h = strtoul(pr, &p, 10);
	if(p == pr)
		wexits("xdpyinfo parse failed");

	return Rect(0, 0, w, h);
}

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

	pipe(pfd);
	fd[0] = pfd[0];
	fd[1] = dup(1, -1);
	fd[2] = dup(2, -1);
	threadspawnl(fd, "page", "page", "-R", nil);

	writeimage(pfd[1], im, 0);
	close(pfd[1]);
}

void
fit()
{
	double delta;
	Rectangle r;
	Image* tmp;

	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));
	setcursor(mc, &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);
	im = tmp;
	delayfreeimage(tmp);
	setcursor(mc, nil);
	ul = screen->r.min;
	redraw(screen);
	flushimage(display, 1);
}
