/* * 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); }
/* * 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; } }