/* * Map the window to possibly make it and its children visible on the screen. * This is a recursive routine which decrements the unmapcount values for * this window and all of its children, and causes exposure events for * those windows which become visible. * If temp is set, then window is being mapped again after a temporary * unmap, so don't reset focus or generate mouse/focus events. */ void GsWpMapWindow(GR_WINDOW *wp, GR_BOOL temp) { if (wp == rootwp) { GsError(GR_ERROR_ILLEGAL_ON_ROOT_WINDOW, wp->id); return; } if (wp->unmapcount) --wp->unmapcount; if (!temp && wp->unmapcount == 0) { GsCheckMouseWindow(); GsCheckFocusWindow(); GsCheckCursor(); } /* send update event if just mapped*/ if (wp->unmapcount == 0) { GsDeliverUpdateEvent(wp, GR_UPDATE_MAP, wp->x, wp->y, wp->width, wp->height); } /* * If the window is an output window and just became visible, * then draw its border, clear it to the background color, and * generate an exposure event. */ if (wp->output && (wp->unmapcount == 0)) { GsDrawBorder(wp); GsWpClearWindow(wp, 0, 0, wp->width, wp->height, GR_TRUE); } /* * Do the same thing for the children. */ for (wp = wp->children; wp; wp = wp->siblings) GsWpMapWindow(wp, temp); }
/* * Unmap the window to make it and its children invisible on the screen. * This is a recursive routine which increments the unmapcount values for * this window and all of its children, and causes exposure events for * windows which are newly uncovered. * If temp_unmap set, don't reset focus or generate mouse/focus events, * as window will be mapped again momentarily (window move, resize, etc) */ void GsWpUnmapWindow(GR_WINDOW *wp, GR_BOOL temp_unmap) { GR_WINDOW *pwp; /* parent window */ GR_WINDOW *sibwp; /* sibling window */ GR_WINDOW *childwp; /* child window */ GR_SIZE bs; /* border size of this window */ if (wp == rootwp) { GsError(GR_ERROR_ILLEGAL_ON_ROOT_WINDOW, wp->id); return; } if (wp == clipwp) clipwp = NULL; ++wp->unmapcount; for (childwp = wp->children; childwp; childwp = childwp->siblings) GsWpUnmapWindow(childwp, temp_unmap); if (!temp_unmap && wp == mousewp) { GsCheckMouseWindow(); GsCheckCursor(); } if (!temp_unmap && wp == focuswp) { if (focusfixed) /* don't revert to mouse enter/leave focus if fixed*/ focuswp = rootwp; else { focusfixed = GR_FALSE; GsCheckFocusWindow(); } } /* Send update event if just unmapped*/ if (wp->unmapcount == 1) { GsDeliverUpdateEvent(wp, (temp_unmap? GR_UPDATE_UNMAPTEMP: GR_UPDATE_UNMAP), 0, 0, 0, 0); } /* * If this is an input-only window or the parent window is * still unmapped, then we are all done. */ if (!wp->output || wp->parent->unmapcount) return; /* * Clear the area in the parent for this window, causing an * exposure event for it. Take into account the border size. */ bs = wp->bordersize; pwp = wp->parent; GsWpClearWindow(pwp, wp->x - pwp->x - bs, wp->y - pwp->y - bs, wp->width + bs * 2, wp->height + bs * 2, GR_TRUE); /* * Finally clear and redraw all parts of our lower sibling * windows that were covered by this window. */ sibwp = wp; while (sibwp->siblings) { sibwp = sibwp->siblings; GsExposeArea(sibwp, wp->x - bs, wp->y - bs, wp->width + bs * 2, wp->height + bs * 2, NULL); } }
/* * Destroy the specified window, and all of its children. * This is a recursive routine. */ void GsWpDestroyWindow(GR_WINDOW *wp) { GR_WINDOW *prevwp; /* previous window pointer */ GR_EVENT_CLIENT *ecp; /* selections for window */ GR_WINDOW_ID oldwid; /* old selection owner */ 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); GsDeliverSelectionChangedEvent(oldwid, 0); } /* * Unmap the window first. */ if (wp->unmapcount == 0) GsWpUnmapWindow(wp, GR_FALSE); /* send update event*/ GsDeliverUpdateEvent(wp, GR_UPDATE_DESTROY, wp->x, wp->y, wp->width, wp->height); /* * Destroy all children. */ while (wp->children) GsWpDestroyWindow(wp->children); /* * Free all client selection structures. */ while (wp->eventclients) { ecp = wp->eventclients; wp->eventclients = ecp->next; 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(); if(wp->title) free(wp->title); free(wp); }
/* * 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); }
/* * Map the window to possibly make it and its children visible on the screen. * This is a recursive routine which realizes this window and all of its * children, and causes exposure events for those windows which become visible. * If temp is set, then window is being mapped again after a temporary * unmap, so don't reset focus or generate mouse/focus events. */ void GsRealizeWindow(GR_WINDOW *wp, GR_BOOL temp) { if (wp == rootwp) { GsError(GR_ERROR_ILLEGAL_ON_ROOT_WINDOW, wp->id); return; } /*printf("RealizeWindow %d, map %d realized %d, parent_realized %d\n", wp->id, wp->mapped, wp->realized, wp->parent->realized);*/ #define OLDWAY 0 #if OLDWAY /* old way, doesn't quite work with unmap/map yourself*/ /* * If window is already realized, or if window * isn't set to be mapped, or parent isn't * realized, then we're done */ if (wp->realized || !wp->mapped || !wp->parent->realized) return; #else /* new way, still small bug with xfreecell and popup windows*/ /* if window is already realized, we're done*/ if (wp->realized) return; /* * Send map update event for window manager or others */ /* send map update event if not temp unmap/map*/ if (!temp) { GsDeliverUpdateEvent(wp, GR_UPDATE_MAP, wp->x, wp->y, wp->width, wp->height); } /* * If window isn't set to be mapped, or parent isn't * realized, then we're done */ if (!wp->mapped || !wp->parent->realized) return; #endif /* set window visible flag*/ wp->realized = GR_TRUE; if (!temp) { GsCheckMouseWindow(); GsCheckFocusWindow(); GsCheckCursor(); } #if OLDWAY /* send map update event if not temp unmap/map*/ if (!temp) { GsDeliverUpdateEvent(wp, GR_UPDATE_MAP, wp->x, wp->y, wp->width, wp->height); } #endif /* * If the window is an output window, then draw its border, * clear it to the background color, and generate an exposure event. */ if (wp->output) { GsDrawBorder(wp); GsClearWindow(wp, 0, 0, wp->width, wp->height, 1); } /* * Do the same thing for the children. */ for (wp = wp->children; wp; wp = wp->siblings) GsRealizeWindow(wp, temp); }