/*
 * /dev/draw simulator -- handles the messages prepared by the draw library.
 * Includes all the memlayer code even though most programs don't use it.
 * This whole approach is overkill, but cpu is cheap and it keeps things simple.
 */

#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#include <memlayer.h>

#define NHASH (1<<5)
#define HASHMASK (NHASH-1)

extern void flushmemscreen(Rectangle);

typedef struct Client Client;
typedef struct Draw Draw;
typedef struct DImage DImage;
typedef struct DScreen DScreen;
typedef struct CScreen CScreen;
typedef struct FChar FChar;
typedef struct Refresh Refresh;
typedef struct Refx Refx;
typedef struct DName DName;

struct Draw
{
	QLock		lk;
	int		clientid;
	int		nclient;
	Client*		client[1];
	int		nname;
	DName*		name;
	int		vers;
	int		softscreen;
};

struct Client
{
	/*Ref		r;*/
	DImage*		dimage[NHASH];
	CScreen*	cscreen;
	Refresh*	refresh;
	Rendez		refrend;
	uchar*		readdata;
	int		nreaddata;
	int		busy;
	int		clientid;
	int		slot;
	int		refreshme;
	int		infoid;
	int		op;
};

struct Refresh
{
	DImage*		dimage;
	Rectangle	r;
	Refresh*	next;
};

struct Refx
{
	Client*		client;
	DImage*		dimage;
};

struct DName
{
	char			*name;
	Client	*client;
	DImage*		dimage;
	int			vers;
};

struct FChar
{
	int		minx;	/* left edge of bits */
	int		maxx;	/* right edge of bits */
	uchar		miny;	/* first non-zero scan-line */
	uchar		maxy;	/* last non-zero scan-line + 1 */
	schar		left;	/* offset of baseline */
	uchar		width;	/* width of baseline */
};

/*
 * Reference counts in DImages:
 *	one per open by original client
 *	one per screen image or fill
 * 	one per image derived from this one by name
 */
struct DImage
{
	int		id;
	int		ref;
	char		*name;
	int		vers;
	Memimage*	image;
	int		ascent;
	int		nfchar;
	FChar*		fchar;
	DScreen*	dscreen;	/* 0 if not a window */
	DImage*	fromname;	/* image this one is derived from, by name */
	DImage*		next;
};

struct CScreen
{
	DScreen*	dscreen;
	CScreen*	next;
};

struct DScreen
{
	int		id;
	int		public;
	int		ref;
	DImage	*dimage;
	DImage	*dfill;
	Memscreen*	screen;
	Client*		owner;
	DScreen*	next;
};

static	Draw		sdraw;
static	Client		*client0;
static	Memimage	*screenimage;
static	Rectangle	flushrect;
static	int		waste;
static	DScreen*	dscreen;
static	int		drawuninstall(Client*, int);
static	Memimage*	drawinstall(Client*, int, Memimage*, DScreen*);
static	void		drawfreedimage(DImage*);

void
_initdisplaymemimage(Display *d, Memimage *m)
{
	screenimage = m;
	client0 = mallocz(sizeof(Client), 1);
	if(client0 == nil){
		fprint(2, "initdraw: allocating client0: out of memory");
		abort();
	}
	client0->slot = 0;
	client0->clientid = ++sdraw.clientid;
	client0->op = SoverD;
	sdraw.client[0] = client0;
	sdraw.nclient = 1;
}

void
_drawreplacescreenimage(Memimage *m)
{
	/*
	 * Replace the screen image because the screen
	 * was resized.
	 * 
	 * In theory there should only be one reference
	 * to the current screen image, and that's through
	 * client0's image 0, installed a few lines above.
	 * Once the client drops the image, the underlying backing 
	 * store freed properly.  The client is being notified
	 * about the resize through external means, so all we
	 * need to do is this assignment.
	 */
	screenimage = m;
}

static
void
drawrefreshscreen(DImage *l, Client *client)
{
	while(l != nil && l->dscreen == nil)
		l = l->fromname;
	if(l != nil && l->dscreen->owner != client)
		l->dscreen->owner->refreshme = 1;
}

static
void
drawrefresh(Memimage *m, Rectangle r, void *v)
{
	Refx *x;
	DImage *d;
	Client *c;
	Refresh *ref;

	USED(m);

	if(v == 0)
		return;
	x = v;
	c = x->client;
	d = x->dimage;
	for(ref=c->refresh; ref; ref=ref->next)
		if(ref->dimage == d){
			combinerect(&ref->r, r);
			return;
		}
	ref = mallocz(sizeof(Refresh), 1);
	if(ref){
		ref->dimage = d;
		ref->r = r;
		ref->next = c->refresh;
		c->refresh = ref;
	}
}

static void
addflush(Rectangle r)
{
	int abb, ar, anbb;
	Rectangle nbb;

	if(sdraw.softscreen==0 || !rectclip(&r, screenimage->r))
		return;

	if(flushrect.min.x >= flushrect.max.x){
		flushrect = r;
		waste = 0;
		return;
	}
	nbb = flushrect;
	combinerect(&nbb, r);
	ar = Dx(r)*Dy(r);
	abb = Dx(flushrect)*Dy(flushrect);
	anbb = Dx(nbb)*Dy(nbb);
	/*
	 * Area of new waste is area of new bb minus area of old bb,
	 * less the area of the new segment, which we assume is not waste.
	 * This could be negative, but that's OK.
	 */
	waste += anbb-abb - ar;
	if(waste < 0)
		waste = 0;
	/*
	 * absorb if:
	 *	total area is small
	 *	waste is less than half total area
	 * 	rectangles touch
	 */
	if(anbb<=1024 || waste*2<anbb || rectXrect(flushrect, r)){
		flushrect = nbb;
		return;
	}
	/* emit current state */
	if(flushrect.min.x < flushrect.max.x)
		flushmemscreen(flushrect);
	flushrect = r;
	waste = 0;
}

static
void
dstflush(int dstid, Memimage *dst, Rectangle r)
{
	Memlayer *l;

	if(dstid == 0){
		combinerect(&flushrect, r);
		return;
	}
	/* how can this happen? -rsc, dec 12 2002 */
	if(dst == 0){
		print("nil dstflush\n");
		return;
	}
	l = dst->layer;
	if(l == nil)
		return;
	do{
		if(l->screen->image->data != screenimage->data)
			return;
		r = rectaddpt(r, l->delta);
		l = l->screen->image->layer;
	}while(l);
	addflush(r);
}

static
void
drawflush(void)
{
	if(flushrect.min.x < flushrect.max.x)
		flushmemscreen(flushrect);
	flushrect = Rect(10000, 10000, -10000, -10000);
}

static
int
drawcmp(char *a, char *b, int n)
{
	if(strlen(a) != n)
		return 1;
	return memcmp(a, b, n);
}

static
DName*
drawlookupname(int n, char *str)
{
	DName *name, *ename;

	name = sdraw.name;
	ename = &name[sdraw.nname];
	for(; name<ename; name++)
		if(drawcmp(name->name, str, n) == 0)
			return name;
	return 0;
}

static
int
drawgoodname(DImage *d)
{
	DName *n;

	/* if window, validate the screen's own images */
	if(d->dscreen)
		if(drawgoodname(d->dscreen->dimage) == 0
		|| drawgoodname(d->dscreen->dfill) == 0)
			return 0;
	if(d->name == nil)
		return 1;
	n = drawlookupname(strlen(d->name), d->name);
	if(n==nil || n->vers!=d->vers)
		return 0;
	return 1;
}

static
DImage*
drawlookup(Client *client, int id, int checkname)
{
	DImage *d;

	d = client->dimage[id&HASHMASK];
	while(d){
		if(d->id == id){
			/*
			 * BUG: should error out but too hard.
			 * Return 0 instead.
			 */
			if(checkname && !drawgoodname(d))
				return 0;
			return d;
		}
		d = d->next;
	}
	return 0;
}

static
DScreen*
drawlookupdscreen(int id)
{
	DScreen *s;

	s = dscreen;
	while(s){
		if(s->id == id)
			return s;
		s = s->next;
	}
	return 0;
}

static
DScreen*
drawlookupscreen(Client *client, int id, CScreen **cs)
{
	CScreen *s;

	s = client->cscreen;
	while(s){
		if(s->dscreen->id == id){
			*cs = s;
			return s->dscreen;
		}
		s = s->next;
	}
	/* caller must check! */
	return 0;
}

static
Memimage*
drawinstall(Client *client, int id, Memimage *i, DScreen *dscreen)
{
	DImage *d;

	d = mallocz(sizeof(DImage), 1);
	if(d == 0)
		return 0;
	d->id = id;
	d->ref = 1;
	d->name = 0;
	d->vers = 0;
	d->image = i;
	d->nfchar = 0;
	d->fchar = 0;
	d->fromname = 0;
	d->dscreen = dscreen;
	d->next = client->dimage[id&HASHMASK];
	client->dimage[id&HASHMASK] = d;
	return i;
}

static
Memscreen*
drawinstallscreen(Client *client, DScreen *d, int id, DImage *dimage, DImage *dfill, int public)
{
	Memscreen *s;
	CScreen *c;

	c = mallocz(sizeof(CScreen), 1);
	if(dimage && dimage->image && dimage->image->chan == 0){
		print("bad image %p in drawinstallscreen", dimage->image);
		abort();
	}

	if(c == 0)
		return 0;
	if(d == 0){
		d = mallocz(sizeof(DScreen), 1);
		if(d == 0){
			free(c);
			return 0;
		}
		s = mallocz(sizeof(Memscreen), 1);
		if(s == 0){
			free(c);
			free(d);
			return 0;
		}
		s->frontmost = 0;
		s->rearmost = 0;
		d->dimage = dimage;
		if(dimage){
			s->image = dimage->image;
			dimage->ref++;
		}
		d->dfill = dfill;
		if(dfill){
			s->fill = dfill->image;
			dfill->ref++;
		}
		d->ref = 0;
		d->id = id;
		d->screen = s;
		d->public = public;
		d->next = dscreen;
		d->owner = client;
		dscreen = d;
	}
	c->dscreen = d;
	d->ref++;
	c->next = client->cscreen;
	client->cscreen = c;
	return d->screen;
}

static
void
drawdelname(DName *name)
{
	int i;

	i = name-sdraw.name;
	memmove(name, name+1, (sdraw.nname-(i+1))*sizeof(DName));
	sdraw.nname--;
}

static
void
drawfreedscreen(DScreen *this)
{
	DScreen *ds, *next;

	this->ref--;
	if(this->ref < 0)
		print("negative ref in drawfreedscreen\n");
	if(this->ref > 0)
		return;
	ds = dscreen;
	if(ds == this){
		dscreen = this->next;
		goto Found;
	}
	while(next = ds->next){	/* assign = */
		if(next == this){
			ds->next = this->next;
			goto Found;
		}
		ds = next;
	}
	/*
	 * Should signal Enodrawimage, but too hard.
	 */
	return;

    Found:
	if(this->dimage)
		drawfreedimage(this->dimage);
	if(this->dfill)
		drawfreedimage(this->dfill);
	free(this->screen);
	free(this);
}

static
void
drawfreedimage(DImage *dimage)
{
	int i;
	Memimage *l;
	DScreen *ds;

	dimage->ref--;
	if(dimage->ref < 0)
		print("negative ref in drawfreedimage\n");
	if(dimage->ref > 0)
		return;

	/* any names? */
	for(i=0; i<sdraw.nname; )
		if(sdraw.name[i].dimage == dimage)
			drawdelname(sdraw.name+i);
		else
			i++;
	if(dimage->fromname){	/* acquired by name; owned by someone else*/
		drawfreedimage(dimage->fromname);
		goto Return;
	}
	//if(dimage->image == screenimage)	/* don't free the display */
	//	goto Return;
	ds = dimage->dscreen;
	if(ds){
		l = dimage->image;
		if(l->data == screenimage->data)
			addflush(l->layer->screenr);
		if(l->layer->refreshfn == drawrefresh)	/* else true owner will clean up */
			free(l->layer->refreshptr);
		l->layer->refreshptr = nil;
		if(drawgoodname(dimage))
			memldelete(l);
		else
			memlfree(l);
		drawfreedscreen(ds);
	}else
		freememimage(dimage->image);
    Return:
	free(dimage->fchar);
	free(dimage);
}

static
void
drawuninstallscreen(Client *client, CScreen *this)
{
	CScreen *cs, *next;

	cs = client->cscreen;
	if(cs == this){
		client->cscreen = this->next;
		drawfreedscreen(this->dscreen);
		free(this);
		return;
	}
	while(next = cs->next){	/* assign = */
		if(next == this){
			cs->next = this->next;
			drawfreedscreen(this->dscreen);
			free(this);
			return;
		}
		cs = next;
	}
}

static
int
drawuninstall(Client *client, int id)
{
	DImage *d, *next;

	d = client->dimage[id&HASHMASK];
	if(d == 0)
		return -1;
	if(d->id == id){
		client->dimage[id&HASHMASK] = d->next;
		drawfreedimage(d);
		return 0;
	}
	while(next = d->next){	/* assign = */
		if(next->id == id){
			d->next = next->next;
			drawfreedimage(next);
			return 0;
		}
		d = next;
	}
	return -1;
}

static
int
drawaddname(Client *client, DImage *di, int n, char *str, char **err)
{
	DName *name, *ename, *new, *t;
	char *ns;

	name = sdraw.name;
	ename = &name[sdraw.nname];
	for(; name<ename; name++)
		if(drawcmp(name->name, str, n) == 0){
			*err = "image name in use";
			return -1;
		}
	t = mallocz((sdraw.nname+1)*sizeof(DName), 1);
	ns = malloc(n+1);
	if(t == nil || ns == nil){
		free(t);
		free(ns);
		*err = "out of memory";
		return -1;
	}
	memmove(t, sdraw.name, sdraw.nname*sizeof(DName));
	free(sdraw.name);
	sdraw.name = t;
	new = &sdraw.name[sdraw.nname++];
	new->name = ns;
	memmove(new->name, str, n);
	new->name[n] = 0;
	new->dimage = di;
	new->client = client;
	new->vers = ++sdraw.vers;
	return 0;
}

static int
drawclientop(Client *cl)
{
	int op;

	op = cl->op;
	cl->op = SoverD;
	return op;
}

static
Memimage*
drawimage(Client *client, uchar *a)
{
	DImage *d;

	d = drawlookup(client, BGLONG(a), 1);
	if(d == nil)
		return nil;	/* caller must check! */
	return d->image;
}

static
void
drawrectangle(Rectangle *r, uchar *a)
{
	r->min.x = BGLONG(a+0*4);
	r->min.y = BGLONG(a+1*4);
	r->max.x = BGLONG(a+2*4);
	r->max.y = BGLONG(a+3*4);
}

static
void
drawpoint(Point *p, uchar *a)
{
	p->x = BGLONG(a+0*4);
	p->y = BGLONG(a+1*4);
}

static
Point
drawchar(Memimage *dst, Point p, Memimage *src, Point *sp, DImage *font, int index, int op)
{
	FChar *fc;
	Rectangle r;
	Point sp1;

	fc = &font->fchar[index];
	r.min.x = p.x+fc->left;
	r.min.y = p.y-(font->ascent-fc->miny);
	r.max.x = r.min.x+(fc->maxx-fc->minx);
	r.max.y = r.min.y+(fc->maxy-fc->miny);
	sp1.x = sp->x+fc->left;
	sp1.y = sp->y+fc->miny;
	memdraw(dst, r, src, sp1, font->image, Pt(fc->minx, fc->miny), op);
	p.x += fc->width;
	sp->x += fc->width;
	return p;
}

static
uchar*
drawcoord(uchar *p, uchar *maxp, int oldx, int *newx)
{
	int b, x;

	if(p >= maxp)
		return nil;
	b = *p++;
	x = b & 0x7F;
	if(b & 0x80){
		if(p+1 >= maxp)
			return nil;
		x |= *p++ << 7;
		x |= *p++ << 15;
		if(x & (1<<22))
			x |= ~0<<23;
	}else{
		if(b & 0x40)
			x |= ~0<<7;
		x += oldx;
	}
	*newx = x;
	return p;
}

int
_drawmsgread(Display *d, void *a, int n)
{
	int inbuf;

	inbuf = d->obufp - d->obuf; 
	if(n > inbuf)
		n = inbuf;
	memmove(a, d->obuf, n);
	inbuf -= n;
	if(inbuf)
		memmove(d->obuf, d->obufp-inbuf, inbuf);
	d->obufp = d->obuf+inbuf;
	return n;
}

static void
drawmsgsquirrel(Display *d, void *a, int n)
{
	uchar *ep;

	ep = d->obuf + d->obufsize;
	if(d->obufp + n > ep)
		abort();
	memmove(d->obufp, a, n);
	d->obufp += n;
}

int
_drawmsgwrite(Display *d, void *v, int n)
{
	char cbuf[40], *err, ibuf[12*12+1], *s;
	int c, ci, doflush, dstid, e0, e1, esize, j, m;
	int ni, nw, oesize, oldn, op, ox, oy, repl, scrnid, y; 
	uchar *a, refresh, *u;
	u32int chan, value;
	Client *client;
	CScreen *cs;
	DImage *di, *ddst, *dsrc, *font, *ll;
	DName *dn;
	DScreen *dscrn;
	FChar *fc;
	Memimage *dst, *i, *l, **lp, *mask, *src;
	Memscreen *scrn;
	Point p, *pp, q, sp;
	Rectangle clipr, r;
	Refreshfn reffn;
	Refx *refx;

	d->obufp = d->obuf;
	a = v;
	m = 0;
	oldn = n;
	client = client0;

	while((n-=m) > 0){
		a += m;
//fprint(2, "msgwrite %d(%d)...", n, *a);
		switch(*a){
		default:
//fprint(2, "bad command %d\n", *a);
			err = "bad draw command";
			goto error;

		/* allocate: 'b' id[4] screenid[4] refresh[1] chan[4] repl[1]
			R[4*4] clipR[4*4] rrggbbaa[4]
		 */
		case 'b':
			m = 1+4+4+1+4+1+4*4+4*4+4;
			if(n < m)
				goto Eshortdraw;
			dstid = BGLONG(a+1);
			scrnid = BGSHORT(a+5);
			refresh = a[9];
			chan = BGLONG(a+10);
			repl = a[14];
			drawrectangle(&r, a+15);
			drawrectangle(&clipr, a+31);
			value = BGLONG(a+47);
			if(drawlookup(client, dstid, 0))
				goto Eimageexists;
			if(scrnid){
				dscrn = drawlookupscreen(client, scrnid, &cs);
				if(!dscrn)
					goto Enodrawscreen;
				scrn = dscrn->screen;
				if(repl || chan!=scrn->image->chan){
					err = "image parameters incompatibile with screen";
					goto error;
				}
				reffn = nil;
				switch(refresh){
				case Refbackup:
					break;
				case Refnone:
					reffn = memlnorefresh;
					break;
				case Refmesg:
					reffn = drawrefresh;
					break;
				default:
					err = "unknown refresh method";
					goto error;
				}
				l = memlalloc(scrn, r, reffn, 0, value);
				if(l == 0)
					goto Edrawmem;
				addflush(l->layer->screenr);
				l->clipr = clipr;
				rectclip(&l->clipr, r);
				if(drawinstall(client, dstid, l, dscrn) == 0){
					memldelete(l);
					goto Edrawmem;
				}
				dscrn->ref++;
				if(reffn){
					refx = nil;
					if(reffn == drawrefresh){
						refx = mallocz(sizeof(Refx), 1);
						if(refx == 0){
							if(drawuninstall(client, dstid) < 0)
								goto Enodrawimage;
							goto Edrawmem;
						}
						refx->client = client;
						refx->dimage = drawlookup(client, dstid, 1);
					}
					memlsetrefresh(l, reffn, refx);
				}
				continue;
			}
			i = allocmemimage(r, chan);
			if(i == 0)
				goto Edrawmem;
			if(repl)
				i->flags |= Frepl;
			i->clipr = clipr;
			if(!repl)
				rectclip(&i->clipr, r);
			if(drawinstall(client, dstid, i, 0) == 0){
				freememimage(i);
				goto Edrawmem;
			}
			memfillcolor(i, value);
			continue;

		/* allocate screen: 'A' id[4] imageid[4] fillid[4] public[1] */
		case 'A':
			m = 1+4+4+4+1;
			if(n < m)
				goto Eshortdraw;
			dstid = BGLONG(a+1);
			if(dstid == 0)
				goto Ebadarg;
			if(drawlookupdscreen(dstid))
				goto Escreenexists;
			ddst = drawlookup(client, BGLONG(a+5), 1);
			dsrc = drawlookup(client, BGLONG(a+9), 1);
			if(ddst==0 || dsrc==0)
				goto Enodrawimage;
			if(drawinstallscreen(client, 0, dstid, ddst, dsrc, a[13]) == 0)
				goto Edrawmem;
			continue;

		/* set repl and clip: 'c' dstid[4] repl[1] clipR[4*4] */
		case 'c':
			m = 1+4+1+4*4;
			if(n < m)
				goto Eshortdraw;
			ddst = drawlookup(client, BGLONG(a+1), 1);
			if(ddst == nil)
				goto Enodrawimage;
			if(ddst->name){
				err = "can't change repl/clipr of shared image";
				goto error;
			}
			dst = ddst->image;
			if(a[5])
				dst->flags |= Frepl;
			drawrectangle(&dst->clipr, a+6);
			continue;

		/* draw: 'd' dstid[4] srcid[4] maskid[4] R[4*4] P[2*4] P[2*4] */
		case 'd':
			m = 1+4+4+4+4*4+2*4+2*4;
			if(n < m)
				goto Eshortdraw;
			dst = drawimage(client, a+1);
			dstid = BGLONG(a+1);
			src = drawimage(client, a+5);
			mask = drawimage(client, a+9);
			if(!dst || !src || !mask)
				goto Enodrawimage;
			drawrectangle(&r, a+13);
			drawpoint(&p, a+29);
			drawpoint(&q, a+37);
			op = drawclientop(client);
			memdraw(dst, r, src, p, mask, q, op);
			dstflush(dstid, dst, r);
			continue;

		/* toggle debugging: 'D' val[1] */
		case 'D':
			m = 1+1;
			if(n < m)
				goto Eshortdraw;
			drawdebug = a[1];
			continue;

		/* ellipse: 'e' dstid[4] srcid[4] center[2*4] a[4] b[4] thick[4] sp[2*4] alpha[4] phi[4]*/
		case 'e':
		case 'E':
			m = 1+4+4+2*4+4+4+4+2*4+2*4;
			if(n < m)
				goto Eshortdraw;
			dst = drawimage(client, a+1);
			dstid = BGLONG(a+1);
			src = drawimage(client, a+5);
			if(!dst || !src)
				goto Enodrawimage;
			drawpoint(&p, a+9);
			e0 = BGLONG(a+17);
			e1 = BGLONG(a+21);
			if(e0<0 || e1<0){
				err = "invalid ellipse semidiameter";
				goto error;
			}
			j = BGLONG(a+25);
			if(j < 0){
				err = "negative ellipse thickness";
				goto error;
			}
			
			drawpoint(&sp, a+29);
			c = j;
			if(*a == 'E')
				c = -1;
			ox = BGLONG(a+37);
			oy = BGLONG(a+41);
			op = drawclientop(client);
			/* high bit indicates arc angles are present */
			if(ox & (1<<31)){
				if((ox & (1<<30)) == 0)
					ox &= ~(1<<31);
				memarc(dst, p, e0, e1, c, src, sp, ox, oy, op);
			}else
				memellipse(dst, p, e0, e1, c, src, sp, op);
			dstflush(dstid, dst, Rect(p.x-e0-j, p.y-e1-j, p.x+e0+j+1, p.y+e1+j+1));
			continue;

		/* free: 'f' id[4] */
		case 'f':
			m = 1+4;
			if(n < m)
				goto Eshortdraw;
			ll = drawlookup(client, BGLONG(a+1), 0);
			if(ll && ll->dscreen && ll->dscreen->owner != client)
				ll->dscreen->owner->refreshme = 1;
			if(drawuninstall(client, BGLONG(a+1)) < 0)
				goto Enodrawimage;
			continue;

		/* free screen: 'F' id[4] */
		case 'F':
			m = 1+4;
			if(n < m)
				goto Eshortdraw;
			if(!drawlookupscreen(client, BGLONG(a+1), &cs))
				goto Enodrawscreen;
			drawuninstallscreen(client, cs);
			continue;

		/* initialize font: 'i' fontid[4] nchars[4] ascent[1] */
		case 'i':
			m = 1+4+4+1;
			if(n < m)
				goto Eshortdraw;
			dstid = BGLONG(a+1);
			if(dstid == 0){
				err = "can't use display as font";
				goto error;
			}
			font = drawlookup(client, dstid, 1);
			if(font == 0)
				goto Enodrawimage;
			if(font->image->layer){
				err = "can't use window as font";
				goto error;
			}
			ni = BGLONG(a+5);
			if(ni<=0 || ni>4096){
				err = "bad font size (4096 chars max)";
				goto error;
			}
			free(font->fchar);	/* should we complain if non-zero? */
			font->fchar = mallocz(ni*sizeof(FChar), 1);
			if(font->fchar == 0){
				err = "no memory for font";
				goto error;
			}
			memset(font->fchar, 0, ni*sizeof(FChar));
			font->nfchar = ni;
			font->ascent = a[9];
			continue;

		/* set image 0 to screen image */
		case 'J':
			m = 1;
			if(n < m)
				goto Eshortdraw;
			drawinstall(client, 0, screenimage, 0);
			client->infoid = 0;
			continue;

		/* get image info: 'I' */
		case 'I':
			m = 1;
			if(n < m)
				goto Eshortdraw;
			if(client->infoid < 0)
				goto Enodrawimage;
			if(client->infoid == 0){
				i = screenimage;
				if(i == nil)
					goto Enodrawimage;
			}else{
				di = drawlookup(client, client->infoid, 1);
				if(di == nil)
					goto Enodrawimage;
				i = di->image;
			}
			ni = sprint(ibuf, "%11d %11d %11s %11d %11d %11d %11d %11d"
					" %11d %11d %11d %11d ",
					client->clientid,
					client->infoid,	
					chantostr(cbuf, i->chan),
					(i->flags&Frepl)==Frepl,
					i->r.min.x, i->r.min.y, i->r.max.x, i->r.max.y,
					i->clipr.min.x, i->clipr.min.y, 
					i->clipr.max.x, i->clipr.max.y);
			drawmsgsquirrel(d, ibuf, ni);
			client->infoid = -1;
			continue;	

		/* load character: 'l' fontid[4] srcid[4] index[2] R[4*4] P[2*4] left[1] width[1] */
		case 'l':
			m = 1+4+4+2+4*4+2*4+1+1;
			if(n < m)
				goto Eshortdraw;
			font = drawlookup(client, BGLONG(a+1), 1);
			if(font == 0)
				goto Enodrawimage;
			if(font->nfchar == 0)
				goto Enotfont;
			src = drawimage(client, a+5);
			if(!src)
				goto Enodrawimage;
			ci = BGSHORT(a+9);
			if(ci >= font->nfchar)
				goto Eindex;
			drawrectangle(&r, a+11);
			drawpoint(&p, a+27);
			memdraw(font->image, r, src, p, memopaque, p, S);
			fc = &font->fchar[ci];
			fc->minx = r.min.x;
			fc->maxx = r.max.x;
			fc->miny = r.min.y;
			fc->maxy = r.max.y;
			fc->left = a[35];
			fc->width = a[36];
			continue;

		/* draw line: 'L' dstid[4] p0[2*4] p1[2*4] end0[4] end1[4] radius[4] srcid[4] sp[2*4] */
		case 'L':
			m = 1+4+2*4+2*4+4+4+4+4+2*4;
			if(n < m)
				goto Eshortdraw;
			dst = drawimage(client, a+1);
			dstid = BGLONG(a+1);
			drawpoint(&p, a+5);
			drawpoint(&q, a+13);
			e0 = BGLONG(a+21);
			e1 = BGLONG(a+25);
			j = BGLONG(a+29);
			if(j < 0){
				err = "negative line width";
				goto error;
			}
			src = drawimage(client, a+33);
			if(!dst || !src)
				goto Enodrawimage;
			drawpoint(&sp, a+37);
			op = drawclientop(client);
			memline(dst, p, q, e0, e1, j, src, sp, op);
			/* avoid memlinebbox if possible */
			if(dstid==0 || dst->layer!=nil){
				/* BUG: this is terribly inefficient: update maximal containing rect*/
				r = memlinebbox(p, q, e0, e1, j);
				dstflush(dstid, dst, insetrect(r, -(1+1+j)));
			}
			continue;

		/* create image mask: 'm' newid[4] id[4] */
/*
 *
		case 'm':
			m = 4+4;
			if(n < m)
				goto Eshortdraw;
			break;
 *
 */

		/* attach to a named image: 'n' dstid[4] j[1] name[j] */
		case 'n':
			m = 1+4+1;
			if(n < m)
				goto Eshortdraw;
			j = a[5];
			if(j == 0)	/* give me a non-empty name please */
				goto Eshortdraw;
			m += j;
			if(n < m)
				goto Eshortdraw;
			dstid = BGLONG(a+1);
			if(drawlookup(client, dstid, 0))
				goto Eimageexists;
			dn = drawlookupname(j, (char*)a+6);
			if(dn == nil)
				goto Enoname;
			s = malloc(j+1);
			if(s == nil)
				goto Enomem;
			if(drawinstall(client, dstid, dn->dimage->image, 0) == 0)
				goto Edrawmem;
			di = drawlookup(client, dstid, 0);
			if(di == 0)
				goto Eoldname;
			di->vers = dn->vers;
			di->name = s;
			di->fromname = dn->dimage;
			di->fromname->ref++;
			memmove(di->name, a+6, j);
			di->name[j] = 0;
			client->infoid = dstid;
			continue;

		/* name an image: 'N' dstid[4] in[1] j[1] name[j] */
		case 'N':
			m = 1+4+1+1;
			if(n < m)
				goto Eshortdraw;
			c = a[5];
			j = a[6];
			if(j == 0)	/* give me a non-empty name please */
				goto Eshortdraw;
			m += j;
			if(n < m)
				goto Eshortdraw;
			di = drawlookup(client, BGLONG(a+1), 0);
			if(di == 0)
				goto Enodrawimage;
			if(di->name)
				goto Enamed;
			if(c)
				if(drawaddname(client, di, j, (char*)a+7, &err) < 0)
					goto error;
			else{
				dn = drawlookupname(j, (char*)a+7);
				if(dn == nil)
					goto Enoname;
				if(dn->dimage != di)
					goto Ewrongname;
				drawdelname(dn);
			}
			continue;

		/* position window: 'o' id[4] r.min [2*4] screenr.min [2*4] */
		case 'o':
			m = 1+4+2*4+2*4;
			if(n < m)
				goto Eshortdraw;
			dst = drawimage(client, a+1);
			if(!dst)
				goto Enodrawimage;
			if(dst->layer){
				drawpoint(&p, a+5);
				drawpoint(&q, a+13);
				r = dst->layer->screenr;
				ni = memlorigin(dst, p, q);
				if(ni < 0){
					err = "image origin failed";
					goto error;
				}
				if(ni > 0){
					addflush(r);
					addflush(dst->layer->screenr);
					ll = drawlookup(client, BGLONG(a+1), 1);
					drawrefreshscreen(ll, client);
				}
			}
			continue;

		/* set compositing operator for next draw operation: 'O' op */
		case 'O':
			m = 1+1;
			if(n < m)
				goto Eshortdraw;
			client->op = a[1];
			continue;

		/* filled polygon: 'P' dstid[4] n[2] wind[4] ignore[2*4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */
		/* polygon: 'p' dstid[4] n[2] end0[4] end1[4] radius[4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */
		case 'p':
		case 'P':
			m = 1+4+2+4+4+4+4+2*4;
			if(n < m)
				goto Eshortdraw;
			dstid = BGLONG(a+1);
			dst = drawimage(client, a+1);
			ni = BGSHORT(a+5);
			if(ni < 0){
				err = "negative cout in polygon";
				goto error;
			}
			e0 = BGLONG(a+7);
			e1 = BGLONG(a+11);
			j = 0;
			if(*a == 'p'){
				j = BGLONG(a+15);
				if(j < 0){
					err = "negative polygon line width";
					goto error;
				}
			}
			src = drawimage(client, a+19);
			if(!dst || !src)
				goto Enodrawimage;
			drawpoint(&sp, a+23);
			drawpoint(&p, a+31);
			ni++;
			pp = mallocz(ni*sizeof(Point), 1);
			if(pp == nil)
				goto Enomem;
			doflush = 0;
			if(dstid==0 || (dst->layer && dst->layer->screen->image->data == screenimage->data))
				doflush = 1;	/* simplify test in loop */
			ox = oy = 0;
			esize = 0;
			u = a+m;
			for(y=0; y<ni; y++){
				q = p;
				oesize = esize;
				u = drawcoord(u, a+n, ox, &p.x);
				if(!u)
					goto Eshortdraw;
				u = drawcoord(u, a+n, oy, &p.y);
				if(!u)
					goto Eshortdraw;
				ox = p.x;
				oy = p.y;
				if(doflush){
					esize = j;
					if(*a == 'p'){
						if(y == 0){
							c = memlineendsize(e0);
							if(c > esize)
								esize = c;
						}
						if(y == ni-1){
							c = memlineendsize(e1);
							if(c > esize)
								esize = c;
						}
					}
					if(*a=='P' && e0!=1 && e0 !=~0)
						r = dst->clipr;
					else if(y > 0){
						r = Rect(q.x-oesize, q.y-oesize, q.x+oesize+1, q.y+oesize+1);
						combinerect(&r, Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1));
					}
					if(rectclip(&r, dst->clipr))		/* should perhaps be an arg to dstflush */
						dstflush(dstid, dst, r);
				}
				pp[y] = p;
			}
			if(y == 1)
				dstflush(dstid, dst, Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1));
			op = drawclientop(client);
			if(*a == 'p')
				mempoly(dst, pp, ni, e0, e1, j, src, sp, op);
			else
				memfillpoly(dst, pp, ni, e0, src, sp, op);
			free(pp);
			m = u-a;
			continue;

		/* read: 'r' id[4] R[4*4] */
		case 'r':
			m = 1+4+4*4;
			if(n < m)
				goto Eshortdraw;
			i = drawimage(client, a+1);
			if(!i)
				goto Enodrawimage;
			drawrectangle(&r, a+5);
			if(!rectinrect(r, i->r))
				goto Ereadoutside;
			c = bytesperline(r, i->depth);
			c *= Dy(r);
			free(client->readdata);
			client->readdata = mallocz(c, 0);
			if(client->readdata == nil){
				err = "readimage malloc failed";
				goto error;
			}
			client->nreaddata = memunload(i, r, client->readdata, c);
			if(client->nreaddata < 0){
				free(client->readdata);
				client->readdata = nil;
				err = "bad readimage call";
				goto error;
			}
			continue;

		/* string: 's' dstid[4] srcid[4] fontid[4] P[2*4] clipr[4*4] sp[2*4] ni[2] ni*(index[2]) */
		/* stringbg: 'x' dstid[4] srcid[4] fontid[4] P[2*4] clipr[4*4] sp[2*4] ni[2] bgid[4] bgpt[2*4] ni*(index[2]) */
		case 's':
		case 'x':
			m = 1+4+4+4+2*4+4*4+2*4+2;
			if(*a == 'x')
				m += 4+2*4;
			if(n < m)
				goto Eshortdraw;

			dst = drawimage(client, a+1);
			dstid = BGLONG(a+1);
			src = drawimage(client, a+5);
			if(!dst || !src)
				goto Enodrawimage;
			font = drawlookup(client, BGLONG(a+9), 1);
			if(font == 0)
				goto Enodrawimage;
			if(font->nfchar == 0)
				goto Enotfont;
			drawpoint(&p, a+13);
			drawrectangle(&r, a+21);
			drawpoint(&sp, a+37);
			ni = BGSHORT(a+45);
			u = a+m;
			m += ni*2;
			if(n < m)
				goto Eshortdraw;
			clipr = dst->clipr;
			dst->clipr = r;
			op = drawclientop(client);
			if(*a == 'x'){
				/* paint background */
				l = drawimage(client, a+47);
				if(!l)
					goto Enodrawimage;
				drawpoint(&q, a+51);
				r.min.x = p.x;
				r.min.y = p.y-font->ascent;
				r.max.x = p.x;
				r.max.y = r.min.y+Dy(font->image->r);
				j = ni;
				while(--j >= 0){
					ci = BGSHORT(u);
					if(ci<0 || ci>=font->nfchar){
						dst->clipr = clipr;
						goto Eindex;
					}
					r.max.x += font->fchar[ci].width;
					u += 2;
				}
				memdraw(dst, r, l, q, memopaque, ZP, op);
				u -= 2*ni;
			}
			q = p;
			while(--ni >= 0){
				ci = BGSHORT(u);
				if(ci<0 || ci>=font->nfchar){
					dst->clipr = clipr;
					goto Eindex;
				}
				q = drawchar(dst, q, src, &sp, font, ci, op);
				u += 2;
			}
			dst->clipr = clipr;
			p.y -= font->ascent;
			dstflush(dstid, dst, Rect(p.x, p.y, q.x, p.y+Dy(font->image->r)));
			continue;

		/* use public screen: 'S' id[4] chan[4] */
		case 'S':
			m = 1+4+4;
			if(n < m)
				goto Eshortdraw;
			dstid = BGLONG(a+1);
			if(dstid == 0)
				goto Ebadarg;
			dscrn = drawlookupdscreen(dstid);
			if(dscrn==0 || (dscrn->public==0 && dscrn->owner!=client))
				goto Enodrawscreen;
			if(dscrn->screen->image->chan != BGLONG(a+5)){
				err = "inconsistent chan";
				goto error;
			}
			if(drawinstallscreen(client, dscrn, 0, 0, 0, 0) == 0)
				goto Edrawmem;
			continue;

		/* top or bottom windows: 't' top[1] nw[2] n*id[4] */
		case 't':
			m = 1+1+2;
			if(n < m)
				goto Eshortdraw;
			nw = BGSHORT(a+2);
			if(nw < 0)
				goto Ebadarg;
			if(nw == 0)
				continue;
			m += nw*4;
			if(n < m)
				goto Eshortdraw;
			lp = mallocz(nw*sizeof(Memimage*), 1);
			if(lp == 0)
				goto Enomem;
			for(j=0; j<nw; j++){
				lp[j] = drawimage(client, a+1+1+2+j*4);
				if(lp[j] == nil){
					free(lp);
					goto Enodrawimage;
				}
			}
			if(lp[0]->layer == 0){
				err = "images are not windows";
				free(lp);
				goto error;
			}
			for(j=1; j<nw; j++)
				if(lp[j]->layer->screen != lp[0]->layer->screen){
					err = "images not on same screen";
					free(lp);
					goto error;
				}
			if(a[1])
				memltofrontn(lp, nw);
			else
				memltorearn(lp, nw);
			if(lp[0]->layer->screen->image->data == screenimage->data)
				for(j=0; j<nw; j++)
					addflush(lp[j]->layer->screenr);
			free(lp);
			ll = drawlookup(client, BGLONG(a+1+1+2), 1);
			drawrefreshscreen(ll, client);
			continue;

		/* visible: 'v' */
		case 'v':
			m = 1;
			drawflush();
			continue;

		/* write: 'y' id[4] R[4*4] data[x*1] */
		/* write from compressed data: 'Y' id[4] R[4*4] data[x*1] */
		case 'y':
		case 'Y':
			m = 1+4+4*4;
			if(n < m)
				goto Eshortdraw;
			dstid = BGLONG(a+1);
			dst = drawimage(client, a+1);
			if(!dst)
				goto Enodrawimage;
			drawrectangle(&r, a+5);
			if(!rectinrect(r, dst->r))
				goto Ewriteoutside;
			y = memload(dst, r, a+m, n-m, *a=='Y');
			if(y < 0){
				err = "bad writeimage call";
				goto error;
			}
			dstflush(dstid, dst, r);
			m += y;
			continue;
		}
	}
	return oldn - n;

Enodrawimage:
	err = "unknown id for draw image";
	goto error;
Enodrawscreen:
	err = "unknown id for draw screen";
	goto error;
Eshortdraw:
	err = "short draw message";
	goto error;
Eshortread:
	err = "draw read too short";
	goto error;
Eimageexists:
	err = "image id in use";
	goto error;
Escreenexists:
	err = "screen id in use";
	goto error;
Edrawmem:
	err = "image memory allocation failed";
	goto error;
Ereadoutside:
	err = "readimage outside image";
	goto error;
Ewriteoutside:
	err = "writeimage outside image";
	goto error;
Enotfont:
	err = "image not a font";
	goto error;
Eindex:
	err = "character index out of range";
	goto error;
Enoclient:
	err = "no such draw client";
	goto error;
Edepth:
	err = "image has bad depth";
	goto error;
Enameused:
	err = "image name in use";
	goto error;
Enoname:
	err = "no image with that name";
	goto error;
Eoldname:
	err = "named image no longer valid";
	goto error;
Enamed:
	err = "image already has name";
	goto error;
Ewrongname:
	err = "wrong name for image";
	goto error;
Enomem:
	err = "out of memory";
	goto error;
Ebadarg:
	err = "bad argument in draw message";
	goto error;

error:
	drawerror(display, err);
	return -1;
}


