plan9port/src/libdraw/x11-event.c

180 lines
2.8 KiB
C
Raw Normal View History

2003-09-30 17:47:42 +00:00
#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);
}
2003-09-30 17:47:42 +00:00
ulong
eread(ulong keys, Event *e)
{
int r;
2003-09-30 17:47:42 +00:00
ulong xmask;
XEvent xevent;
xmask = ExposureMask;
eflush();
2003-09-30 17:47:42 +00:00
if(keys&Emouse)
xmask |= MouseMask|StructureNotifyMask;
if(keys&Ekeyboard){
2003-09-30 17:47:42 +00:00
xmask |= KeyPressMask;
if((r = _xtoplan9kbd(nil)) >= 0){
e->kbdc = r;
return Ekeyboard;
}
}
2003-09-30 17:47:42 +00:00
XSelectInput(_x.display, _x.drawable, xmask);
again:
XWindowEvent(_x.display, _x.drawable, xmask, &xevent);
switch(xevent.type){
case Expose:
_xexpose(&xevent, _x.display);
2003-09-30 17:47:42 +00:00
goto again;
case DestroyNotify:
if(_xdestroy(&xevent, _x.display))
postnote(PNGROUP, getpgrp(), "hangup");
goto again;
2003-09-30 17:47:42 +00:00
case ConfigureNotify:
if(_xconfigure(&xevent, _x.display))
2003-09-30 17:47:42 +00:00
eresized(1);
goto again;
case ButtonPress:
case ButtonRelease:
case MotionNotify:
if(_xtoplan9mouse(_x.display, &xevent, &e->mouse) < 0)
2003-09-30 17:47:42 +00:00
goto again;
return Emouse;
case KeyPress:
e->kbdc = _xtoplan9kbd(&xevent);
2003-09-30 17:47:42 +00:00
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();
2003-09-30 17:47:42 +00:00
again:
if(XCheckWindowEvent(_x.display, _x.drawable, MouseMask, &xe)){
if(_xtoplan9mouse(_x.display, &xe, &m) < 0)
2003-09-30 17:47:42 +00:00
goto again;
XPutBackEvent(_x.display, &xe);
return 1;
}
return 0;
}
int
ecankbd(void)
{
XEvent xe;
int r;
2003-09-30 17:47:42 +00:00
eflush();
if((r = _xtoplan9kbd(nil)) >= 0){
_xtoplan9kbd((XEvent*)-1);
return 1;
}
2003-09-30 17:47:42 +00:00
again:
if(XCheckWindowEvent(_x.display, _x.drawable, KeyPressMask, &xe)){
if(_xtoplan9kbd(&xe) == -1)
2003-09-30 17:47:42 +00:00
goto again;
XPutBackEvent(_x.display, &xe);
return 1;
}
return 0;
}
void
emoveto(Point p)
{
_xmoveto(p);
2003-09-30 17:47:42 +00:00
}
void
esetcursor(Cursor *c)
{
_xsetcursor(c);
}