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

#include <memdraw.h>
#include "x11-memdraw.h"

ulong
event(Event *e)
{
	return eread(~0UL, e);
}

static void
eflush(void)
{
	/* avoid generating a message if there's nothing to show. */
	/* this test isn't perfect, though; could do flushimage(display, 0) then call extract */
	/* also: make sure we don't interfere if we're multiprocessing the display */
	if(display->locking){
		/* if locking is being done by program, this means it can't depend on automatic flush in emouse() etc. */
		if(canqlock(&display->qlock)){
			if(display->bufp > display->buf)
				flushimage(display, 1);
			unlockdisplay(display);
		}
	}else
		if(display->bufp > display->buf)
			flushimage(display, 1);
}

ulong
eread(ulong keys, Event *e)
{
	int r;
	ulong xmask;
	XEvent xevent;

	xmask = ExposureMask;

	eflush();

	if(keys&Emouse)
		xmask |= MouseMask|StructureNotifyMask;
	if(keys&Ekeyboard){
		xmask |= KeyPressMask;
		if((r = _xtoplan9kbd(nil)) >= 0){
			e->kbdc = r;
			return Ekeyboard;
		}
	}

	XSelectInput(_x.display, _x.drawable, xmask);
again:
	XWindowEvent(_x.display, _x.drawable, xmask, &xevent);

	switch(xevent.type){
	case Expose:
		_xexpose(&xevent, _x.display);
		goto again;
	case DestroyNotify:
		if(_xdestroy(&xevent, _x.display))
			postnote(PNGROUP, getpgrp(), "hangup");
		goto again;
	case ConfigureNotify:
		if(_xconfigure(&xevent, _x.display))
			eresized(1);
		goto again;
	case ButtonPress:
	case ButtonRelease:
	case MotionNotify:
		if(_xtoplan9mouse(_x.display, &xevent, &e->mouse) < 0)
			goto again;
		return Emouse;
	case KeyPress:
		e->kbdc = _xtoplan9kbd(&xevent);
		if(e->kbdc == -1)
			goto again;
		return Ekeyboard;
	default:
		return 0;
	}
}

void
einit(ulong keys)
{
	keys &= ~(Emouse|Ekeyboard);
	if(keys){
		fprint(2, "unknown keys in einit\n");
		abort();
	}
}

int
ekbd(void)
{
	Event e;

	eread(Ekeyboard, &e);
	return e.kbdc;
}

Mouse
emouse(void)
{
	Event e;

	eread(Emouse, &e);
	return e.mouse;
}

int
ecanread(ulong keys)
{
	int can;

	can = 0;
	if(keys&Emouse)
		can |= ecanmouse();
	if(keys&Ekeyboard)
		can |= ecankbd();
	return can;
}

int
ecanmouse(void)
{
	XEvent xe;
	Mouse m;

	eflush();
again:
	if(XCheckWindowEvent(_x.display, _x.drawable, MouseMask, &xe)){
		if(_xtoplan9mouse(_x.display, &xe, &m) < 0)
			goto again;
		XPutBackEvent(_x.display, &xe);
		return 1;
	}
	return 0;
}

int
ecankbd(void)
{
	XEvent xe;
	int r;

	eflush();
	if((r = _xtoplan9kbd(nil)) >= 0){
		_xtoplan9kbd((XEvent*)-1);
		return 1;
	}
again:
	if(XCheckWindowEvent(_x.display, _x.drawable, KeyPressMask, &xe)){
		if(_xtoplan9kbd(&xe) == -1)
			goto again;
		XPutBackEvent(_x.display, &xe);
		return 1;
	}
	return 0;
}

void
emoveto(Point p)
{
	_xmoveto(p);
}

void
esetcursor(Cursor *c)
{
	_xsetcursor(c);
}

