#include "x11-inc.h"

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

