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

📄 srvevent.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 2 页
字号:
 * window is a descendant of the focus window), or else just the focus window. * The lowest window in that tree which has enabled for the event gets it. * If a window with the correct noprop mask is reached, or if no window selects * for the event, then the event is discarded. */void GsDeliverKeyboardEvent(GR_WINDOW_ID wid, GR_EVENT_TYPE type,	GR_KEY keyvalue, GR_KEYMOD modifiers, GR_SCANCODE scancode){	GR_EVENT_KEYSTROKE	*ep;		/* keystroke event */	GR_WINDOW		*wp;		/* current window */	GR_WINDOW		*tempwp;	/* temporary window pointer */	GR_EVENT_CLIENT		*ecp;		/* current event client */	GR_WINDOW_ID		subwid;		/* subwindow id event is for */	GR_EVENT_MASK		eventmask;	/* event mask */	GR_WINDOW		*kwp;	eventmask = GR_EVENTMASK(type);	if (eventmask == 0)		return;	GsResetScreenSaver();	/* if window id passed, use it, otherwise focus window*/	if (wid) {		kwp = GsFindWindow(wid);		if (!kwp)			return;	} else		kwp = focuswp;	wp = mousewp;	subwid = wp->id;	/*	 * See if the actual window the pointer is in is a descendant of	 * the focus window.  If not, then ignore it, and force the input	 * into the focus window itself.	 */	tempwp = wp;	while ((tempwp != kwp) && (tempwp != rootwp))		tempwp = tempwp->parent;	if (tempwp != kwp) {		wp = kwp;		subwid = wp->id;	}	/*	 * Now walk upwards looking for the first window which will accept	 * the keyboard event.  However, do not go beyond the focus window,	 * and only give the event to one client.	 */	for (;;) {		for (ecp = wp->eventclients; ecp; ecp = ecp->next) {			if ((ecp->eventmask & eventmask) == 0)				continue;			ep = (GR_EVENT_KEYSTROKE *) GsAllocEvent(ecp->client);			if (ep == NULL)				return;			ep->type = type;			ep->wid = wp->id;			ep->subwid = subwid;			ep->rootx = cursorx;			ep->rooty = cursory;			ep->x = cursorx - wp->x;			ep->y = cursory - wp->y;			ep->buttons = curbuttons;			ep->modifiers = modifiers;			ep->ch = keyvalue;			ep->scancode = scancode;			return;			/* only one client gets it */		}		if ((wp == rootwp) || (wp == kwp) ||			(wp->nopropmask & eventmask))				return;		wp = wp->parent;	}}/* * Try to deliver a exposure event to the clients which have selected for it. * This does not send exposure events for unmapped or input-only windows. * Exposure events do not propagate upwards. */voidGsDeliverExposureEvent(GR_WINDOW *wp, GR_COORD x, GR_COORD y,	GR_SIZE width, GR_SIZE height){	GR_EVENT_EXPOSURE	*ep;		/* exposure event */	GR_EVENT_CLIENT		*ecp;		/* current event client */	if (wp->unmapcount || !wp->output)		return;	for (ecp = wp->eventclients; ecp; ecp = ecp->next) {		if ((ecp->eventmask & GR_EVENT_MASK_EXPOSURE) == 0)			continue;		GsFreeExposureEvent(ecp->client, wp->id, x, y, width, height);		ep = (GR_EVENT_EXPOSURE *) GsAllocEvent(ecp->client);		if (ep == NULL)			continue;		ep->type = GR_EVENT_TYPE_EXPOSURE;		ep->wid = wp->id;		ep->x = x;		ep->y = y;		ep->width = width;		ep->height = height;	}}/* * Search for an enclosed expose event in the specified client's * event queue, and remove it.  This is used to prevent multiple expose * events from being delivered, thus providing a more pleasing visual * redraw effect than if the events were all sent. */voidGsFreeExposureEvent(GR_CLIENT *client, GR_WINDOW_ID wid, GR_COORD x,	GR_COORD y, GR_SIZE width, GR_SIZE height){	GR_EVENT_LIST	*elp;		/* current element list */	GR_EVENT_LIST	*prevelp;	/* previous element list */	prevelp = NULL;	for (elp = client->eventhead; elp; prevelp = elp, elp = elp->next) {		if (elp->event.type != GR_EVENT_TYPE_EXPOSURE ||		    elp->event.exposure.wid != wid)			continue;		if (elp->event.exposure.x < x || elp->event.exposure.y < y ||		    elp->event.exposure.x+elp->event.exposure.width > x+width ||		    elp->event.exposure.y+elp->event.exposure.height > y+height)			continue;		/*		 * Found one, remove it and put it back on the free list.		 */		if (prevelp)			prevelp->next = elp->next;		else			client->eventhead = elp->next;		if (client->eventtail == elp)			client->eventtail = prevelp;		elp->next = eventfree;		eventfree = elp;		return;	}}/* * Try to deliver an update event to the clients which have selected for it. */void GsDeliverUpdateEvent(GR_WINDOW *wp, GR_UPDATE_TYPE utype, GR_COORD x,			GR_COORD y, GR_SIZE width, GR_SIZE height){	GR_EVENT_MASK		cmask = GR_EVENT_MASK_UPDATE;	GR_EVENT_UPDATE		*ep;		/* update event */	GR_EVENT_CLIENT		*ecp;		/* current event client */	GR_WINDOW_ID		id = wp->id;	int			lcount = 0;	/* adjust reported x,y to be parent-relative*/	if (wp->parent) {		x -= wp->parent->x;		y -= wp->parent->y;	}update_again:	for (ecp = wp->eventclients; ecp; ecp = ecp->next) {		if ((ecp->eventmask & cmask) == 0)			continue;		ep = (GR_EVENT_UPDATE *) GsAllocEvent(ecp->client);		if (ep == NULL)			continue;		ep->type = lcount? 			GR_EVENT_TYPE_CHLD_UPDATE: GR_EVENT_TYPE_UPDATE;		ep->utype = utype;		ep->wid = wp->id;	/* GrSelectEvents window id*/		ep->subwid = id;	/* update window id*/		ep->x = x;		ep->y = y;		ep->width = width;		ep->height = height;	}	/* If we are currently checking the window updated, go back and 	 * check its parent too */	if (!lcount++) {			wp = wp->parent;		/* check for NULL on root window id*/		if (wp == NULL)			return;		cmask = GR_EVENT_MASK_CHLD_UPDATE;		goto update_again;	}}/* * Try to deliver a general event such as focus in, focus out, mouse enter, * or mouse exit to the clients which have selected for it.  These events * only have the window id as data, and do not propagate upwards. */void GsDeliverGeneralEvent(GR_WINDOW *wp, GR_EVENT_TYPE type, GR_WINDOW *other){	GR_EVENT_GENERAL	*gp;		/* general event */	GR_EVENT_CLIENT		*ecp;		/* current event client */	GR_EVENT_MASK		eventmask;	/* event mask */	eventmask = GR_EVENTMASK(type);	if (eventmask == 0)		return;	for (ecp = wp->eventclients; ecp; ecp = ecp->next) {		if ((ecp->eventmask & eventmask) == 0)			continue;		gp = (GR_EVENT_GENERAL *) GsAllocEvent(ecp->client);		if (gp == NULL)			continue;		gp->type = type;		gp->wid = wp->id;		if (other)			gp->otherid = other->id;		else gp->otherid = 0;	}}/* * Deliver a portrait mode changed event to all windows which * have selected for it. */void GsDeliverPortraitChangedEvent(void){	GR_WINDOW		*wp;	GR_EVENT_GENERAL	*gp;	GR_EVENT_CLIENT		*ecp;	for (wp=listwp; wp; wp=wp->next) {		for (ecp = wp->eventclients; ecp; ecp = ecp->next) {			if ((ecp->eventmask & GR_EVENT_MASK_PORTRAIT_CHANGED) == 0)				continue;			gp = (GR_EVENT_GENERAL *) GsAllocEvent(ecp->client);			if (gp == NULL)				continue;			gp->type = GR_EVENT_TYPE_PORTRAIT_CHANGED;			gp->wid = wp->id;			gp->otherid = 0;		}	}}/* * Deliver a Screen Saver event. There is only one parameter- activate the * screen saver or deactivate it. We only deliver it to the root window, * but we do send it to every client which has selected for it (because the * program which starts the screen saver on an activate event might not also * be the screen saver program which wants to catch the deactivate event). */void GsDeliverScreenSaverEvent(GR_BOOL activate){	GR_EVENT_SCREENSAVER	*gp;		/* screensaver event */	GR_EVENT_CLIENT		*ecp;		/* current event client */	for (ecp = rootwp->eventclients; ecp; ecp = ecp->next) {		if ((ecp->eventmask & GR_EVENT_MASK_SCREENSAVER) == 0)			continue;		gp = (GR_EVENT_SCREENSAVER *) GsAllocEvent(ecp->client);		if (gp == NULL)			continue;		gp->type = GR_EVENT_TYPE_SCREENSAVER;		gp->activate = activate;	}}/* * Deliver a client data request event. Delivered to the clients who have * selected for this event on the specified window only. */voidGsDeliverClientDataReqEvent(GR_WINDOW_ID wid, GR_WINDOW_ID rid,			GR_SERIALNO serial, GR_MIMETYPE mimetype){	GR_EVENT_CLIENT_DATA_REQ *gp;		/* client data request event */	GR_EVENT_CLIENT		*ecp;		/* current event client */	GR_WINDOW *wp;	if(!(wp = GsFindWindow(wid))) return;	for (ecp = wp->eventclients; ecp; ecp = ecp->next) {		if ((ecp->eventmask & GR_EVENT_MASK_CLIENT_DATA_REQ) == 0)			continue;		gp = (GR_EVENT_CLIENT_DATA_REQ *) GsAllocEvent(ecp->client);		if (gp == NULL)			continue;		gp->type = GR_EVENT_TYPE_CLIENT_DATA_REQ;		gp->wid = wid;		gp->rid = rid;		gp->serial = serial;		gp->mimetype = mimetype;		continue;	}}/* * Deliver a client data event. Delivered to the clients who have selected for * this event on the specified window only. */voidGsDeliverClientDataEvent(GR_WINDOW_ID wid, GR_WINDOW_ID rid,	GR_SERIALNO serial, GR_LENGTH len, GR_LENGTH thislen, void *data){	GR_EVENT_CLIENT_DATA *gp;		/* client data request event */	GR_EVENT_CLIENT		*ecp;		/* current event client */	GR_WINDOW *wp;	if(!(wp = GsFindWindow(wid))) return;	for (ecp = wp->eventclients; ecp; ecp = ecp->next) {		if ((ecp->eventmask & GR_EVENT_MASK_CLIENT_DATA) == 0)			continue;		gp = (GR_EVENT_CLIENT_DATA *) GsAllocEvent(ecp->client);		if (gp == NULL)			continue;		gp->type = GR_EVENT_TYPE_CLIENT_DATA;		gp->wid = wid;		gp->rid = rid;		gp->serial = serial;		gp->len = len;		gp->datalen = thislen;		if(!(gp->data = malloc(thislen))) {			GsError(GR_ERROR_MALLOC_FAILED, wid);			return;		}		memcpy(gp->data, data, thislen);		continue;	}}/* * Search for a matching mouse position event in the specified client's * event queue, and remove it.  This is used to prevent multiple position * events from being delivered, thus providing a more efficient rubber- * banding effect than if the mouse motion events were all sent. */voidGsFreePositionEvent(GR_CLIENT *client, GR_WINDOW_ID wid, GR_WINDOW_ID subwid){	GR_EVENT_LIST	*elp;		/* current element list */	GR_EVENT_LIST	*prevelp;	/* previous element list */	prevelp = NULL;	for (elp = client->eventhead; elp; prevelp = elp, elp = elp->next) {		if (elp->event.type != GR_EVENT_TYPE_MOUSE_POSITION)			continue;		if (elp->event.mouse.wid != wid)			continue;		if (elp->event.mouse.subwid != subwid)			continue;		/*		 * Found one, remove it and put it back on the free list.		 */		if (prevelp)			prevelp->next = elp->next;		else			client->eventhead = elp->next;		if (client->eventtail == elp)			client->eventtail = prevelp;		elp->next = eventfree;		eventfree = elp;		return;	}}/* * Deliver a "selection owner changed" event to all windows which have * selected for it. We deliver this event to all clients which have selected * to receive GR_EVENT_TYPE_SELECTION_CHANGED events for the window of the * _previous_ selection owner. */void GsDeliverSelectionChangedEvent(GR_WINDOW_ID old_owner,					GR_WINDOW_ID new_owner){	GR_EVENT_SELECTION_CHANGED *gp;		/* selection changed event */	GR_EVENT_CLIENT		*ecp;		/* current event client */	GR_WINDOW *wp;	if(!(wp = GsFindWindow(old_owner))) return;	for (ecp = wp->eventclients; ecp; ecp = ecp->next) {		if ((ecp->eventmask & GR_EVENT_MASK_SELECTION_CHANGED) == 0)			continue;		fprintf(stderr, "Delivering a selection changed event\n");		gp = (GR_EVENT_SELECTION_CHANGED *) GsAllocEvent(ecp->client);		if (gp == NULL)			continue;		gp->type = GR_EVENT_TYPE_SELECTION_CHANGED;		gp->new_owner = new_owner;	}}void GsDeliverTimerEvent (GR_CLIENT *client, GR_WINDOW_ID wid, GR_TIMER_ID tid){    GR_EVENT_TIMER    *event;           /* general event */    GR_EVENT_CLIENT   *ecp;             /* current event client */    GR_WINDOW         *wp;              /* current window */        if ((wp = GsFindWindow (wid)) == NULL)    {        return;    }    for (ecp = wp->eventclients; ecp != NULL; ecp = ecp->next)     {        if ((ecp->client == client) && ((ecp->eventmask & GR_EVENT_MASK_TIMER) != 0))        {            event = (GR_EVENT_TIMER*) GsAllocEvent (client);            if (event == NULL)            {                break;            }                    event->type = GR_EVENT_TYPE_TIMER;            event->wid  = wid;            event->tid  = tid;        }    }}

⌨️ 快捷键说明

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