#include #include "x11-inc.h" #include #include #include #include #include #include "x11-memdraw.h" /* * Should change this to support etimer and estartfn again. * The main eread() would prepare a select mask from the keys * and then call select() to wait for input. Then it would read an * event from the readied fd and return it. Use XCheckWindowEvent * to poll the X connection. */ 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; } } xmask |= EnterWindowMask|LeaveWindowMask; 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: goto again; } } 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); }