192 lines · 3.8 KB · C
RawDownload
#include <lib9.h>#include <draw.h>#include <memdraw.h>#include <memlayer.h>#include <cursor.h>#include "dat.h"#include "fns.h"#include "inc.h"#include "x.h" #define debugev(...) if(1) debug(__VA_ARGS__) void configevent(Window*, XEvent);void exposeevent(Window*, XEvent);void kbdevent(Window*, XEvent);void mouseevent(Window*, XEvent); voidxnextevent(void) {	int i;	Window *w;	Xwin *xw;	XEvent xev; 	xw = nil; NextEvent:	XNextEvent(xconn.display, &xev);	if(xev.xany.window == xconn.w){		if(xev.type == SelectionRequest)			xselect(&xev);		if(XPending(xconn.display))			goto NextEvent;		return;	}	for(i = 0; i < nwindow; i++){		xw = window[i]->x;		if(xw && xw->drawable == xev.xany.window)			break;	}	if(i == nwindow || window[i]->deleted){		if(XPending(xconn.display))			goto NextEvent;		// print("XXX event received in wrong window\n");		return;	}	w = window[i];// print("XXX event at window %d (%p)\n", w->id, w);	switch(xev.type){	case ClientMessage:		if(xev.xclient.data.l[0] == xw->wmdelmsg)			deletewin(w);		break; 	case ConfigureNotify:		configevent(w, xev);		break; 	case Expose:		exposeevent(w, xev);		break;		case DestroyNotify:		/* Nop */		break; 	case ButtonPress:	case ButtonRelease:	case MotionNotify:		mouseevent(w, xev);		break; 	case KeyPress:		kbdevent(w, xev);		break;		case FocusOut:		/*		 * Stop alting when		 * window losts focus.		 */		writekbd(w, -1);;		break;		default:		break;	}	if(XPending(xconn.display))		goto NextEvent;} voidconfigevent(Window *w, XEvent xev){	int rx, ry;	Mouse m;	Rectangle r;	Xwin *xw;	XConfigureEvent *xe; 	xe = (XConfigureEvent*)&xev;	xw = w->x;	if(!w->fullscreen){		XWindow xwin;		if(XTranslateCoordinates(xconn.display, xw->drawable, DefaultRootWindow(xconn.display), 0, 0, &rx, &ry, &xwin)) {			w->orig.x = rx;			w->orig.y = ry;		}	} 	if(xe->width == Dx(xconn.screenrect) && xe->height == Dy(xconn.screenrect))		return;	if(Dx(w->screenr) == xe->width && Dy(w->screenr) == xe->height)		return;	w->screenr = Rect(rx, ry, rx+xe->width, ry+xe->height);	r = Rect(0, 0, xe->width, xe->height); 	// qlock(&_x.screenlock);	if(xw->screenpm != xw->nextscreenpm){		XCopyArea(xconn.display, xw->screenpm, xw->drawable, xconn.gccopy, r.min.x, r.min.y,			Dx(r), Dy(r), r.min.x, r.min.y);		XSync(xconn.display, False);	}	// qunlock(&_x.screenlock);	w->newscreenr = r; 	m.xy.x = Dx(r);	m.xy.y = Dy(r);	drawreplacescreenimage(w);	debugev("Configure event at window %d: w=%d h=%d\n", w->id, m.xy.x, m.xy.y);	w->resized = 1;	/* XXX TODO	 * we should send a resize event, and then	 * respond with a normal 'm' mouse event if	 * the window has already been resized, but	 * IxpPending does not let us to do that.	 */	writemouse(w, m, 1);} voidexposeevent(Window *w, XEvent xev){	XExposeEvent *xe;	Rectangle r;	Xwin *xw; 	debugev("Expose event at window %d\n", w->id);	xw = w->x;	// qlock(&_x.screenlock);	if(xw->screenpm != xw->nextscreenpm){		// qunlock(&_x.screenlock);		return;	}	xe = (XExposeEvent*)&xev;	r.min.x = xe->x;	r.min.y = xe->y;	r.max.x = xe->x+xe->width;	r.max.y = xe->y+xe->height;	XCopyArea(xconn.display, xw->screenpm, xw->drawable, xconn.gccopy, r.min.x, r.min.y,		Dx(r), Dy(r), r.min.x, r.min.y);	XSync(xconn.display, False);	// qunlock(&_x.screenlock);} voidkbdevent(Window *w, XEvent xev){	KeySym k; 	XLookupString((XKeyEvent*)&xev, NULL, 0, &k, NULL);	if(k == XK_F11){		w->fullscreen = !w->fullscreen;		xmovewindow(w, w->fullscreen ? xconn.screenrect : w->screenr);		return;	} 	k = xtoplan9kbd(&xev);	debugev("Keyboard event at window %d. rune=%C (%d)\n", w->id, k, k);	writekbd(w, k);} voidmouseevent(Window *w, XEvent xev){	Mouse m; 	if(xtoplan9mouse(&xev, &m) < 0)		return;	// debugev("Mouse event at window %d: x=%d y=%d b=%d\n", w->id, m.xy.x, m.xy.y, m.buttons);	writemouse(w, m, 0);}