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

📄 srvevent.c

📁 一个linux下的根文件系统的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		/* Find the window that has the grab */		wp = GsFindWindow(keygrab->wid);		if (wp == NULL)			return; /* Key is reserved by window that doesn't exist. */		/* See if the grabbing window is an ancestor of the focussed window. */		kwp = focuswp;		while (kwp != wp && kwp != rootwp)			kwp = kwp->parent;		/* Want to send event if:		 * GR_GRAB_EXCLUSIVE: grabbing window is an ancestor of focussed window		 * GR_GRAB_EXCLUSIVE_MOUSE: same as GR_GRAB_EXCLUSIVE OR		 *                    the mouse is in the grabbing window.		 */		if (kwp != wp && (keygrab->type != GR_GRAB_EXCLUSIVE_MOUSE || wp != mousewp))			return;		subwid = wp->id;	} else {		/* 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;			ep->hotkey = GR_FALSE;			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->realized || !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. */voidGsDeliverUpdateEvent(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. */voidGsDeliverGeneralEvent(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. */voidGsDeliverPortraitChangedEvent(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). */voidGsDeliverScreenSaverEvent(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. */voidGsDeliverSelectionChangedEvent(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;		gp = (GR_EVENT_SELECTION_CHANGED *) GsAllocEvent(ecp->client);		if (gp == NULL)			continue;		gp->type = GR_EVENT_TYPE_SELECTION_CHANGED;		gp->new_owner = new_owner;	}}/* This is a bit of a misnomer - this will deliver the normal events   but it doesn't bother doing any sort of bounds checking or anything,   we just start at the "focus" window and try to deliver events to the path*/voidGsDeliverRawMouseEvent(int rx, int ry, int buttons, int modifiers){	int i;	GR_WINDOW *wp;		/* current window */	GR_CLIENT *client;	/* current client */	GR_WINDOW_ID subwid;	/* subwindow id event is for */	GR_EVENT_CLIENT *ecp;	/* Start with the "focus" window and move up */	/* Since the raw mouse position doesn't match the actual	   geometry, this is all we can do */	wp = mousewp;	subwid = wp->id;	for (ecp = wp->eventclients; ecp; ecp = ecp->next) {		GR_EVENT_MOUSE *ep;		if ((ecp->eventmask & GR_EVENT_MASK_MOUSE_POSITION) == 0)			continue;		client = ecp->client;		GsFreePositionEvent(client, wp->id, subwid);		ep = (GR_EVENT_MOUSE *) GsAllocEvent(client);		if (ep == NULL)			continue;		ep->type = GR_EVENT_TYPE_MOUSE_POSITION;		ep->wid = wp->id;		ep->subwid = subwid;		ep->rootx = rx;		ep->rooty = ry;		ep->x = 0;	/* These make no sense in raw mode */		ep->y = 0;		ep->buttons = buttons;		ep->modifiers = modifiers;		if ((wp == rootwp)		    || (wp->nopropmask & GR_EVENT_MASK_MOUSE_POSITION))			break;		wp = wp->parent;	}	/* Deliver button events if we have to */	for (i = 0; i < 2; i++) {		GR_EVENT_BUTTON *gp;		unsigned long cbuttons = 0;		GR_EVENT_TYPE etype = (i == 0) ? GR_EVENT_TYPE_BUTTON_DOWN :			GR_EVENT_TYPE_BUTTON_UP;		if (i == 0)			cbuttons = (curbuttons & ~buttons);		else			cbuttons = (~buttons & curbuttons);		if (!cbuttons)			continue;		wp = mousewp;		subwid = wp->id;		for (ecp = wp->eventclients; ecp; ecp = ecp->next) {			client = ecp->client;			if ((ecp->eventmask & GR_EVENTMASK(etype)) == 0)				continue;			gp = (GR_EVENT_BUTTON *) GsAllocEvent(ecp->client);			if (gp == NULL)				continue;			gp->type = etype;			gp->wid = wp->id;			gp->subwid = subwid;			gp->rootx = rx;			gp->rooty = ry;			gp->x = 0;			gp->y = 0;			gp->buttons = buttons;			gp->changebuttons = cbuttons;			gp->modifiers = modifiers;			gp->time = GsGetTickCount();			if ((wp == rootwp) || (wp->nopropmask & GR_EVENTMASK(etype)))				break;			wp = wp->parent;		}	}	curbuttons = buttons;}voidGsDeliverTimerEvent(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 + -