#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(par->dst, par->r);

	/* always fetch source and mask */
	_xgetxdata(par->src, par->sr);
	_xgetxdata(par->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(par->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|Fullsrc|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.
	 * This is disabled because Ubuntu Precise seems to ship with
	 * a buggy X server that sometimes drops the XCopyArea
	 * requests on the floor.
	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;
}

