#include <u.h>
#include "x11-inc.h"
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#include "x11-memdraw.h"

static int xdraw(Memdrawparam*);

/*
 * The X acceleration doesn't fit into the standard hwaccel
 * model because we have the extra steps of pulling the image
 * data off the server and putting it back when we're done.
 */
void
memimagedraw(Memimage *dst, Rectangle r, Memimage *src, Point sp,
	Memimage *mask, Point mp, int op)
{
	Memdrawparam *par;

	if((par = _memimagedrawsetup(dst, r, src, sp, mask, mp, op)) == nil)
		return;

	/* only fetch dst data if we need it */
	if((par->state&(Simplemask|Fullmask)) != (Simplemask|Fullmask))
		_xgetxdata(dst, par->r);

	/* always fetch source and mask */
	_xgetxdata(src, par->sr);
	_xgetxdata(mask, par->mr);

	/* now can run memimagedraw on the in-memory bits */
	_memimagedraw(par);

	if(xdraw(par))
		return;

	/* put bits back on x server */
	_xputxdata(dst, par->r);
}

static int
xdraw(Memdrawparam *par)
{
	u32int sdval;
	uint m, state;
	Memimage *src, *dst, *mask;
	Point dp, mp, sp;
	Rectangle r;
	Xmem *xdst, *xmask, *xsrc;
	XGC gc;

	if(par->dst->X == nil)
		return 0;

	dst   = par->dst;
	mask  = par->mask;
	r     = par->r;
	src   = par->src;
	state = par->state;

	/*
	 * If we have an opaque mask and source is one opaque pixel,
	 * we can convert to the destination format and just XFillRectangle.
	 */
	m = Simplesrc|Simplemask|Fullmask;
	if((state&m) == m){
		_xfillcolor(dst, r, par->sdval);
	//	xdirtyxdata(dst, r);
		return 1;
	}

	/*
	 * If no source alpha and an opaque mask, we can just copy
	 * the source onto the destination.  If the channels are the
	 * same and the source is not replicated, XCopyArea works.
	 */
	m = Simplemask|Fullmask;
	if((state&(m|Replsrc))==m && src->chan==dst->chan && src->X){
		xdst = dst->X;
		xsrc = src->X;
		dp = subpt(r.min,       dst->r.min);
		sp = subpt(par->sr.min, src->r.min);
		gc = dst->chan==GREY1 ?  _x.gccopy0 : _x.gccopy;

		XCopyArea(_x.display, xsrc->pixmap, xdst->pixmap, gc,
			sp.x, sp.y, Dx(r), Dy(r), dp.x, dp.y);
	//	xdirtyxdata(dst, r);
		return 1;
	}

	/*
	 * If no source alpha, a 1-bit mask, and a simple source,
	 * we can copy through the mask onto the destination.
	 */
	if(dst->X && mask->X && !(mask->flags&Frepl)
	&& mask->chan==GREY1 && (state&Simplesrc)){
		xdst = dst->X;
		xmask = mask->X;
		sdval = par->sdval;

		dp = subpt(r.min, dst->r.min);
		mp = subpt(r.min, subpt(par->mr.min, mask->r.min));

		if(dst->chan == GREY1){
			gc = _x.gcsimplesrc0;
			if(_x.gcsimplesrc0color != sdval){
				XSetForeground(_x.display, gc, sdval);
				_x.gcsimplesrc0color = sdval;
			}
			if(_x.gcsimplesrc0pixmap != xmask->pixmap){
				XSetStipple(_x.display, gc, xmask->pixmap);
				_x.gcsimplesrc0pixmap = xmask->pixmap;
			}
		}else{
			/* this doesn't work on rob's mac?  */
			return 0;
			gc = _x.gcsimplesrc;
			if(dst->chan == CMAP8 && _x.usetable)
				sdval = _x.tox11[sdval];

			if(_x.gcsimplesrccolor != sdval){
				XSetForeground(_x.display, gc, sdval);
				_x.gcsimplesrccolor = sdval;
			}
			if(_x.gcsimplesrcpixmap != xmask->pixmap){
				XSetStipple(_x.display, gc, xmask->pixmap);
				_x.gcsimplesrcpixmap = xmask->pixmap;
			}
		}
		XSetTSOrigin(_x.display, gc, mp.x, mp.y);
		XFillRectangle(_x.display, xdst->pixmap, gc, dp.x, dp.y,
			Dx(r), Dy(r));
	//	xdirtyxdata(dst, r);
		return 1;
	}

	/*
	 * Can't accelerate.
	 */
	return 0;
}

