Exemplo n.º 1
0
/*
 * Destroy the specified window, and all of its children.
 * This is a recursive routine.
 */
void
GsDestroyWindow(GR_WINDOW *wp)
{
	GR_WINDOW	*prevwp;	/* previous window pointer */
	GR_EVENT_CLIENT	*ecp;		/* selections for window */
	GR_WINDOW_ID	oldwid;		/* old selection owner */
	GR_GRABBED_KEY *keygrab;
	GR_GRABBED_KEY **keygrab_prev_next;

	if (wp == rootwp) {
		GsError(GR_ERROR_ILLEGAL_ON_ROOT_WINDOW, wp->id);
		return;
	}

	/* Disable selection if this window is the owner */
	if(selection_owner.wid == wp->id) {
		oldwid = selection_owner.wid;
		selection_owner.wid = 0;
		if(selection_owner.typelist)
			free(selection_owner.typelist);
		selection_owner.typelist = NULL;
		GsDeliverSelectionChangedEvent(oldwid, 0);
	}

	/*
	 * Unmap the window first.
	 */
	if (wp->realized)
		GsUnrealizeWindow(wp, GR_FALSE);

	/* send destroy update event*/
	GsDeliverUpdateEvent(wp, GR_UPDATE_DESTROY, wp->x, wp->y,
		wp->width, wp->height);

	/*
	 * Destroy all children.
	 */
	while (wp->children)
		GsDestroyWindow(wp->children);

	/*
	 * Free all client selection structures.
	 */
	while (wp->eventclients) {
		ecp = wp->eventclients;
		wp->eventclients = ecp->next;
DPRINTF("FREE 1 %lx\n", (long)ecp);			// FIXME
		free(ecp);
	}

	/*
	 * Remove this window from the child list of its parent.
	 */
	prevwp = wp->parent->children;
	if (prevwp == wp)
		wp->parent->children = wp->siblings;
	else {
		while (prevwp->siblings != wp)
			prevwp = prevwp->siblings;
		prevwp->siblings = wp->siblings;
	}
	wp->siblings = NULL;

	/*
	 * Remove this window from the complete list of windows.
	 */
	prevwp = listwp;
	if (prevwp == wp)
		listwp = wp->next;
	else {
		while (prevwp->next != wp)
			prevwp = prevwp->next;
		prevwp->next = wp->next;
	}
	wp->next = NULL;

	/*
	 * Forget various information if they related to this window.
	 * Then finally free the structure.
	 */
	if (wp == clipwp)
		clipwp = NULL;
	if (wp == grabbuttonwp)
		grabbuttonwp = NULL;
	if (wp == cachewp) {
		cachewindowid = 0;
		cachewp = NULL;
	}
	if (wp == focuswp) {
		/* don't revert to mouse enter/leave focus if fixed*/
		/*focusfixed = GR_FALSE;*/
		focuswp = rootwp;
	}

	GsCheckMouseWindow();

	/*
	 * Free title, pixmaps and clipregions associated with window.
	 */
	if (wp->title)
		free(wp->title);
	if (wp->bgpixmap)
		GsDestroyPixmap(wp->bgpixmap);
	if (wp->buffer)
		GsDestroyPixmap(wp->buffer);
#if DYNAMICREGIONS
	if (wp->clipregion)
		GdDestroyRegion(wp->clipregion);
#endif

	/* Remove any grabbed keys for this window. */
	keygrab_prev_next = &list_grabbed_keys;
	keygrab           =  list_grabbed_keys;
	while (keygrab != NULL) {
		if (keygrab->wid == wp->id){
			/* Delete keygrab. */
			*keygrab_prev_next = keygrab->next;
			free(keygrab);
			keygrab = *keygrab_prev_next;
		} else {
			keygrab_prev_next = &keygrab->next;
			keygrab           =  keygrab->next;
		}
	}

	free(wp);
}
Exemplo n.º 2
0
/*
 * Destroy windows and eventclient structures used by client.
 * Called by GsDropClient after a client has exited to clean
 * up resources.
 */
void
GsDestroyClientResources (GR_CLIENT *client)
{
	GR_WINDOW	*wp, *nwp;
	GR_PIXMAP	*pp, *npp;
	GR_GC		*gp, *ngp;
	GR_REGION	*rp, *nrp;
	GR_FONT		*fp, *nfp;
	GR_CURSOR	*cp, *ncp;
	GR_EVENT_CLIENT *ecp, *necp, *pecp = NULL;
	GR_EVENT_LIST	*evp;
	GR_GRABBED_KEY	*kp, *nkp;
	GR_IMAGE	*ip, *nip;
	GR_TIMER	*tp, *ntp;

	/*debug_printf ("Destroy client %d resources\n", client->id);*/

	/* search window list, destroy windows owned by client*/
	for(wp=listwp; wp; wp=nwp) {
		nwp = wp->next;
		/*
		 * Remove eventclient structures for this client
		 */
		ecp = wp->eventclients;
		while (ecp) {
			necp = ecp->next;
			if (ecp->client == client) {
				/*debug_printf ( "  Destroy window %d eventclient mask %08lx\n", wp->id, ecp->eventmask);*/
				if (ecp == wp->eventclients)
					wp->eventclients = ecp->next;
				else
					pecp->next = ecp->next;
				free(ecp);
			} else
				pecp = ecp;
			ecp = necp;
		}
		if (wp->owner == client) {
			/*debug_printf ("  Destroy window %d\n", wp->id);*/
			GsDestroyWindow(wp->id);
		}
	}
	/* search pixmap list, destroy pixmaps owned by client*/
	for(pp=listpp; pp; pp=npp) {
		npp = pp->next;
		if (pp->owner == client) {
			/*debug_printf ("  Destroy pixmap %d\n", pp->id);*/
			GsDestroyWindow(pp->id);
		}
	}
	/* free gc's owned by client*/
	for(gp=listgcp; gp; gp=ngp) {
		ngp = gp->next;
		if (gp->owner == client) {
			/*debug_printf ("  Destroy gc %d\n", gp->id);*/
			GsDestroyGC(gp->id);
		}
	}
	/* free fonts owned by client*/
	for(fp=listfontp; fp; fp=nfp) {
		nfp = fp->next;
		if (fp->owner == client) {
			/*debug_printf ("  Destroy font %d\n", fp->id);*/
			GsDestroyFont(fp->id);
		}
	}
	/* free regions owned by client*/
	for(rp=listregionp; rp; rp=nrp) {
		nrp = rp->next;
		if (rp->owner == client) {
			/*debug_printf ("  Destroy region %d\n", rp->id);*/
			GsDestroyRegion(rp->id);
		}
	}
	/* free images owned by client*/
	for(ip=listimagep; ip; ip=nip) {
		nip = ip->next;
		if (ip->owner == client) {
			/*debug_printf ("  Destroy image %d\n", ip->id);*/
			GsFreeImage(ip->id);
		}
	}
	/* free timers owned by client*/
	for(tp=list_timer; tp; tp=ntp) {
		ntp = tp->next;
		if (tp->owner == client) {
			/*debug_printf ("  Destroy timer %d\n", tp->id);*/
			GsDestroyTimer(tp->id);
		}
	}
	/* free cursors owned by client*/
	for(cp=listcursorp; cp; cp=ncp) {
		ncp = cp->next;
		if (cp->owner == client) {
			/*debug_printf ("  Destroy cursor %d\n", cp->id);*/
			GsDestroyCursor(cp->id);
		}
	}
	/* Free key grabs associated with client*/
	for (kp=list_grabbed_keys; kp; kp = nkp) {
		nkp = kp->next;
		if (kp->owner == curclient) {
			/*debug_printf ("  Destroy grabkey %d,%d\n", kp->wid, kp->key);*/
			GsUngrabKey(kp->wid, kp->key);
		}
	}
	/* Free events associated with client*/
	evp = client->eventhead;
	while (evp) {
		/*debug_printf ("  Destroy event %d\n", evp->event.type);*/
		client->eventhead = evp->next;
		evp->next = eventfree;
		eventfree = evp;
		evp = client->eventhead;
	}
}