⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nextevent.c

📁 Nxlib,一个模拟xlib的程序。使用microwindows的库来运行需要xlib支持的程序。
💻 C
字号:
#include "nxlib.h"#include <stdlib.h>#include <string.h>//#define DEBUG#ifdef DEBUG#define FUNC_ENTER printf("ENTER [%s]\n", __FUNCTION__)#define FUNC_EXIT printf("LEAVE [%s]\n", __FUNCTION__)#else#define FUNC_ENTER#define FUNC_EXIT#endifstatic GR_UPDATE_TYPEtranslateSubtype(int xtype){	switch (xtype) {	case MapNotify:		return GR_UPDATE_MAP;	case UnmapNotify:		return GR_UPDATE_UNMAP;	case ReparentNotify:		return GR_UPDATE_REPARENT;	case DestroyNotify:		return GR_UPDATE_DESTROY;	case ConfigureNotify:		return GR_UPDATE_MOVE;	/* FIXME: | GR_UPDATE_SIZE*/	}	return 0;}static GR_EVENT_MASKtranslateXEventType(int xtype){	switch (xtype) {	case EnterNotify:		return GR_EVENT_MASK_MOUSE_ENTER;	case LeaveNotify:		return GR_EVENT_MASK_MOUSE_EXIT;	case ButtonPress:		return GR_EVENT_MASK_BUTTON_DOWN;	case ButtonRelease:		return GR_EVENT_MASK_BUTTON_UP;	case KeyPress:		return GR_EVENT_MASK_KEY_DOWN;	case KeyRelease:		return GR_EVENT_MASK_KEY_UP;	case Expose:		return GR_EVENT_MASK_EXPOSURE;	case MapNotify:	case UnmapNotify:	case ReparentNotify:	case DestroyNotify:	case ConfigureNotify:		return GR_EVENT_MASK_UPDATE | GR_EVENT_MASK_CHLD_UPDATE;	case MotionNotify:		return GR_EVENT_MASK_MOUSE_MOTION;	case FocusIn:		return GR_EVENT_MASK_FOCUS_IN;	case FocusOut:		return GR_EVENT_MASK_FOCUS_OUT;	}	return GR_EVENT_MASK_NONE;}/* translate nano-X event to X11 event*/static voidtranslateNXEvent(Display *dpy, GR_EVENT * ev, XEvent * event){	static GR_TIMEOUT lasttime = 0;	memset(event, 0, sizeof(*event)); /* for unhandled events...*/	event->xany.display = dpy;	switch (ev->type) {	case GR_EVENT_TYPE_MOUSE_ENTER:	case GR_EVENT_TYPE_MOUSE_EXIT:		if (ev->type == GR_EVENT_TYPE_MOUSE_ENTER)			event->type = EnterNotify;		else			event->type = LeaveNotify;		{			GR_EVENT_MOUSE *pev = (GR_EVENT_MOUSE *) ev;			event->xcrossing.window = pev->wid;			event->xcrossing.root = GR_ROOT_WINDOW_ID;			//event->xcrossing.subwindow =			event->xcrossing.time = lasttime; /* FIXME*/			event->xcrossing.x = pev->x;			event->xcrossing.y = pev->y;			event->xcrossing.x_root = pev->rootx;			event->xcrossing.y_root = pev->rooty;			event->xcrossing.mode = NotifyNormal;			//event->xcrossing.detail =			//event->xcrossing.focus =			event->xcrossing.same_screen = True;			/* FIXME:  Add in the keyboard modifiers*/			if (pev->buttons & GR_BUTTON_L)				event->xcrossing.state |= Button1Mask;			if (pev->buttons & GR_BUTTON_M)				event->xcrossing.state |= Button2Mask;			if (pev->buttons & GR_BUTTON_R)				event->xcrossing.state |= Button3Mask;		}		break;	case GR_EVENT_TYPE_MOUSE_MOTION:		event->type = MotionNotify;		{			GR_EVENT_MOUSE *pev = (GR_EVENT_MOUSE *) ev;			event->xmotion.window = pev->wid;			event->xmotion.root = GR_ROOT_WINDOW_ID;			event->xmotion.subwindow = pev->subwid;			event->xmotion.time = lasttime; /* FIXME*/			event->xmotion.x = pev->x;			event->xmotion.y = pev->y;			event->xmotion.x_root = pev->rootx;			event->xmotion.y_root = pev->rooty;			event->xmotion.is_hint = NotifyNormal;			event->xmotion.same_screen = True;			/* FIXME:  Add keyboard modifiers */			if (pev->buttons & GR_BUTTON_L)				event->xmotion.state |= Button1Mask;			if (pev->buttons & GR_BUTTON_M)				event->xmotion.state |= Button2Mask;			if (pev->buttons & GR_BUTTON_R)				event->xmotion.state |= Button3Mask;		}		break;	case GR_EVENT_TYPE_BUTTON_DOWN:		event->type = ButtonPress;		{			GR_EVENT_BUTTON *pev = (GR_EVENT_BUTTON *) ev;			event->xbutton.window = pev->wid;			event->xbutton.root = GR_ROOT_WINDOW_ID;			event->xbutton.subwindow = pev->subwid;			event->xbutton.time = lasttime = pev->time;			event->xbutton.x = pev->x;			event->xbutton.y = pev->y;			event->xbutton.x_root = pev->rootx;			event->xbutton.y_root = pev->rooty;			event->xbutton.same_screen = True;			/* FIXME: What about the whole OwnerGrabButton thing? */			/* FIXME:  Add in the keyboard modifiers */			if (pev->changebuttons & GR_BUTTON_L)				event->xbutton.button = Button1;			else if (pev->changebuttons & GR_BUTTON_M)				event->xbutton.button = Button2;			else if (pev->changebuttons & GR_BUTTON_R)				event->xbutton.button = Button3;			if (pev->buttons & GR_BUTTON_L)				event->xbutton.state |= Button1Mask;			if (pev->buttons & GR_BUTTON_M)				event->xbutton.state |= Button2Mask;			if (pev->buttons & GR_BUTTON_R)				event->xbutton.state |= Button3Mask;		}		break;	case GR_EVENT_TYPE_BUTTON_UP:		event->type = ButtonRelease;		{			GR_EVENT_BUTTON *pev = (GR_EVENT_BUTTON *) ev;			event->xbutton.window = pev->wid;			event->xbutton.root = GR_ROOT_WINDOW_ID;			event->xbutton.subwindow = pev->subwid;			event->xbutton.time = lasttime = pev->time;			event->xbutton.x = pev->x;			event->xbutton.y = pev->y;			event->xbutton.x_root = pev->rootx;			event->xbutton.y_root = pev->rooty;			event->xbutton.same_screen = True;			/* FIXME:  Add in the keyboard modifiers */			event->xbutton.button = 0;			if (pev->changebuttons & GR_BUTTON_L)				event->xbutton.button = Button1;			else if (pev->changebuttons & GR_BUTTON_M)				event->xbutton.button = Button2;			else if (pev->changebuttons & GR_BUTTON_R)				event->xbutton.button = Button3;			if (pev->buttons & GR_BUTTON_L)				event->xbutton.state |= Button1Mask;			if (pev->buttons & GR_BUTTON_M)				event->xbutton.state |= Button2Mask;			if (pev->buttons & GR_BUTTON_R)				event->xbutton.state |= Button3Mask;		}		break;	case GR_EVENT_TYPE_KEY_DOWN:	case GR_EVENT_TYPE_KEY_UP:		event->type = (ev->type == GR_EVENT_TYPE_KEY_DOWN) ?			KeyPress : KeyRelease;		{			GR_EVENT_KEYSTROKE *pev = (GR_EVENT_KEYSTROKE *) ev;			event->xkey.window = pev->wid;			event->xkey.root = GR_ROOT_WINDOW_ID;			event->xkey.subwindow = pev->subwid;			event->xkey.time = lasttime; /* FIXME*/			event->xkey.x = pev->x;			event->xkey.y = pev->y;;			event->xkey.x_root = pev->rootx;			event->xkey.y_root = pev->rooty;			event->xkey.keycode = pev->scancode; /* note: not mwkey value*/			event->xkey.same_screen = True;			if (pev->modifiers & MWKMOD_CTRL)				event->xkey.state |= ControlMask;			if (pev->modifiers & MWKMOD_SHIFT)				event->xkey.state |= ShiftMask;			if (pev->modifiers & MWKMOD_ALT)				event->xkey.state |= Mod1Mask;			if (pev->modifiers & MWKMOD_CAPS)				event->xkey.state |= ShiftMask;			if (pev->modifiers & MWKMOD_SCR)				event->xkey.state |= Mod5Mask;			if (pev->modifiers & MWKMOD_NUM)				event->xkey.state |= Mod2Mask;		}		break;	case GR_EVENT_TYPE_EXPOSURE:		event->type = Expose;		{			GR_EVENT_EXPOSURE *pev = (GR_EVENT_EXPOSURE *) ev;			event->xexpose.window = pev->wid;			event->xexpose.x = pev->x;			event->xexpose.y = pev->y;			event->xexpose.width = pev->width;			event->xexpose.height = pev->height;			event->xexpose.count = 0;	// FIXME?		}		break;	case GR_EVENT_TYPE_UPDATE:	case GR_EVENT_TYPE_CHLD_UPDATE:		{			GR_EVENT_UPDATE *pev = (GR_EVENT_UPDATE *) ev;			if (pev->utype == GR_UPDATE_MAP) {				event->type = MapNotify;				event->xmap.event = pev->wid;				event->xmap.window = pev->subwid;				//event->xmap.override_redirect = 			} else if (pev->utype == GR_UPDATE_UNMAP) {				event->type = UnmapNotify;				event->xunmap.event = pev->wid;				event->xunmap.window = pev->subwid;				event->xany.window = pev->wid;				//event->xunmap.from_configure = #if 0 /* temp handled below*/			} else if (pev->utype == GR_UPDATE_REPARENT) {				event->type = ReparentNotify;				event->xreparent.event = pev->wid;				event->xreparent.window = pev->subwid;				event->xreparent.x = pev->x;				event->xreparent.y = pev->y;				//event->xreparent.parent = pev->subwid;				//event->xreparent.override_redirect = #endif			} else if (pev->utype == GR_UPDATE_DESTROY) {				event->type = DestroyNotify;				event->xdestroywindow.event = pev->wid;				event->xdestroywindow.window = pev->subwid;			} else if (pev->utype == GR_UPDATE_MOVE ||				   pev->utype == GR_UPDATE_SIZE ||				   pev->utype == GR_UPDATE_REPARENT) {				/*				 * FIXME: FLTK hack - for the time being, we				 * handle GR_UPDATE_REPARENT as a ConfigureNotify				 * event because the Microwindows window manager				 * doesn't send an UPDATE_MOVE event when				 * a window is decorated, and FLTK requires it.				 */				event->type = ConfigureNotify;				event->xconfigure.event = pev->wid;				event->xconfigure.window = pev->subwid;				event->xconfigure.x = pev->x;				event->xconfigure.y = pev->y;				event->xconfigure.width = pev->width;				event->xconfigure.height = pev->height;				//event->xconfigure.border_width = 				//event->xconfigure.above = 				//event->xconfigure.override_redirect = 			} else				printf("translateNXEvent: unhandled update event subtype %d\n", pev->utype);			break;		}	case GR_EVENT_TYPE_FOCUS_IN:		event->type = FocusIn;		{			GR_EVENT_GENERAL *pev = (GR_EVENT_GENERAL *) ev;			event->xfocus.window = pev->wid;			event->xfocus.mode = NotifyNormal;			event->xfocus.detail = NotifyDetailNone;  //FIXME?		}		break;	case GR_EVENT_TYPE_FOCUS_OUT:		event->type = FocusOut;		{			GR_EVENT_GENERAL *pev = (GR_EVENT_GENERAL *) ev;			event->xfocus.window = pev->wid;			event->xfocus.mode = NotifyNormal;			event->xfocus.detail = NotifyDetailNone;  //FIXME?		}		break;	default:		printf("translateNXEvent: UNHANDLED EVENT %d\n", ev->type);	}}static XEvent saved_event;static int saved = 0;intXPutBackEvent(Display *display, XEvent *event){	if (saved) {		printf("XPutBackEvent: lost event\n");		return 0;	}	saved = 1;	saved_event = *event;	return 0;}intXEventsQueued(Display * display, int mode){	int ret;	GR_EVENT temp;	FUNC_ENTER;	ret = GrQueueLength();	/* check hack for local saved event*/	if (saved)		return ret+1;	if (!ret && mode != QueuedAlready) {		if (mode == QueuedAfterFlush)			GrFlush();		if (GrPeekEvent(&temp))			ret = 1;	}#ifdef DEBUG	if (ret)		printf("Returning %d events ready\n", ret);#endif	return ret;}intXPending(Display * dpy){#ifdef DEBUG	printf("XPending ");#endif	return XEventsQueued(dpy, QueuedAfterFlush);}intXQLength(Display * dpy){	FUNC_ENTER;	/* FIXME?	 * FLTK hack: FLTK spins calling XQLength and	 * then select().  Since Microwindows won't return	 * an event without having called GrPeekEvent,	 * using QueuedAfterReading rather than QueuedAlready	 * makes FLTK work.	 */	/*return XEventsQueued(dpy, QueuedAlready);*/	return XEventsQueued(dpy, QueuedAfterReading);}/*  * Return next event in queue, or if none, flush output and wait for * events. */intXNextEvent(Display * dpy, XEvent * event){	GR_EVENT ev;	FUNC_ENTER;	if (saved) {		*event = saved_event;		saved = 0;	} else {		GrGetNextEvent(&ev);		translateNXEvent(dpy, &ev, event);	}	FUNC_EXIT;	return 1;}intXPeekEvent(Display * dpy, XEvent * event){	GR_EVENT ev;	FUNC_ENTER;	if (saved) {		*event = saved_event;	} else {		GrPeekWaitEvent(&ev);		translateNXEvent(dpy, &ev, event);	}	FUNC_EXIT;	return 1;}intXFilterEvent(XEvent * event, Window w){	return False;}typedef Bool(*PredFunc) (Display *, XEvent *, XPointer);typedef struct {	Display *display;	XEvent *event;	XPointer arg;	PredFunc func;} XIfEventParm;static GR_BOOL_XIfEventCallback(GR_WINDOW_ID wid, GR_EVENT_MASK mask,	GR_UPDATE_TYPE update, GR_EVENT *ep, void *arg){	XIfEventParm *p = (XIfEventParm *) arg;	translateNXEvent(p->display, ep, p->event);	return (*p->func) (p->display, p->event, p->arg);}Bool_XIfEvent(Display * display, XEvent * ev, PredFunc predicate, XPointer arg,	int block){	XIfEventParm p;	GR_EVENT event;	p.display = display;	p.event = ev;	p.func = predicate;	p.arg = arg;	FUNC_ENTER;	/* note: event not returned directly but translated in callback routine*/	return GrGetTypedEventPred(0, 0, 0, &event, block, _XIfEventCallback, &p);}BoolXIfEvent(Display * display, XEvent * ev, PredFunc predicate, XPointer arg){#ifdef DEBUGprintf("XIfEvent ");#endif	return _XIfEvent(display, ev, predicate, arg, 1);}BoolXCheckIfEvent(Display * display, XEvent * ev, PredFunc predicate, XPointer arg){#ifdef DEBUGprintf("XCheckIfEvent ");#endif	return _XIfEvent(display, ev, predicate, arg, 0);}/* Check masked events*/BoolXCheckWindowEvent(Display * display, Window w, long event_mask, XEvent * ev){	GR_EVENT event;	FUNC_ENTER;	if (GrGetTypedEvent(w, _nxTranslateEventMask(event_mask), 0, &event, GR_FALSE)) {		translateNXEvent(display, &event, ev);		FUNC_EXIT;		return True;	}	FUNC_EXIT;	return False;}BoolXCheckMaskEvent(Display * display, long event_mask, XEvent * ev){	GR_EVENT event;	FUNC_ENTER;	if (GrGetTypedEvent(0, _nxTranslateEventMask(event_mask), 0, &event, GR_FALSE)) {		translateNXEvent(display, &event, ev);		FUNC_EXIT;		return True;	}	FUNC_EXIT;	return False;}/* Check typed events*/BoolXCheckTypedEvent(Display * display, int event_type, XEvent * ev){	GR_EVENT event;	FUNC_ENTER;	if (GrGetTypedEvent(0, translateXEventType(event_type),	    translateSubtype(event_type), &event, GR_FALSE)) {		translateNXEvent(display, &event, ev);		FUNC_EXIT;		return True;	}	FUNC_EXIT;	return False;}BoolXCheckTypedWindowEvent(Display * display, Window w, int event_type, XEvent * ev){	GR_EVENT event;	FUNC_ENTER;	if (GrGetTypedEvent(w, translateXEventType(event_type),			    translateSubtype(event_type), &event, GR_FALSE)) {		translateNXEvent(display, &event, ev);		FUNC_EXIT;		return True;	}	FUNC_EXIT;	return False;}/* Blocking calls*/intXWindowEvent(Display * display, Window w, long event_mask, XEvent * ev){	GR_BOOL block = GR_TRUE;	GR_EVENT event;	FUNC_ENTER;	/*	 * FIXME: FLTK is coded assuming at least a NoExpose event will	 * be returned after an XCopyArea.  Since Microwindows doesn't	 * do this, we check for ExposureMask, don't block, and return	 * NoExpose in order to get FLTK to work. (fltk/test/scroll demo)	 */	if (event_mask == ExposureMask)		block = GR_FALSE;	if (GrGetTypedEvent(w, _nxTranslateEventMask(event_mask), 0, &event, block)) {		translateNXEvent(display, &event, ev);		FUNC_EXIT;		return ev->type;	}	FUNC_EXIT;	/* FLTK hack*/	if (event_mask == ExposureMask)		ev->type = NoExpose;	return 0;}intXMaskEvent(Display * display, long event_mask, XEvent * ev){	GR_EVENT event;	FUNC_ENTER;	if (GrGetTypedEvent(0, _nxTranslateEventMask(event_mask), 0, &event, GR_TRUE)) {		translateNXEvent(display, &event, ev);		FUNC_EXIT;		return ev->type;	}	FUNC_EXIT;	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -