#include "x11-inc.h"

#include <u.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;
}

