aboutsummaryrefslogtreecommitdiff
path: root/libXt/src/Destroy.c
diff options
context:
space:
mode:
Diffstat (limited to 'libXt/src/Destroy.c')
-rw-r--r--libXt/src/Destroy.c764
1 files changed, 382 insertions, 382 deletions
diff --git a/libXt/src/Destroy.c b/libXt/src/Destroy.c
index e952bccc5..89b6e6a21 100644
--- a/libXt/src/Destroy.c
+++ b/libXt/src/Destroy.c
@@ -1,382 +1,382 @@
-/***********************************************************
-Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice (including the next
-paragraph) shall be included in all copies or substantial portions of the
-Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-
-Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-/*
-
-Copyright 1987, 1988, 1994, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "IntrinsicI.h"
-
-struct _DestroyRec {
- int dispatch_level;
- Widget widget;
-};
-
-static void Recursive(Widget widget, XtWidgetProc proc)
-{
- register Cardinal i;
- CompositePart *cwp;
-
- /* Recurse down normal children */
- if (XtIsComposite(widget)) {
- cwp = &(((CompositeWidget) widget)->composite);
- for (i = 0; i < cwp->num_children; i++) {
- Recursive(cwp->children[i], proc);
- }
- }
-
- /* Recurse down popup children */
- if (XtIsWidget(widget)) {
- for (i = 0; i < widget->core.num_popups; i++) {
- Recursive(widget->core.popup_list[i], proc);
- }
- }
-
- /* Finally, apply procedure to this widget */
- (*proc) (widget);
-} /* Recursive */
-
-static void Phase1Destroy (Widget widget)
-{
- Widget hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
-
- widget->core.being_destroyed = TRUE;
- if (XtHasCallbacks(hookobj, XtNdestroyHook) == XtCallbackHasSome) {
- XtDestroyHookDataRec call_data;
-
- call_data.type = XtHdestroy;
- call_data.widget = widget;
- XtCallCallbackList(hookobj,
- ((HookObject)hookobj)->hooks.destroyhook_callbacks,
- (XtPointer) &call_data);
- }
-} /* Phase1Destroy */
-
-static void Phase2Callbacks(Widget widget)
-{
- if (widget->core.destroy_callbacks != NULL) {
- XtCallCallbackList(widget,
- widget->core.destroy_callbacks, (XtPointer) NULL);
- }
-} /* Phase2Callbacks */
-
-static void Phase2Destroy(register Widget widget)
-{
- register WidgetClass class;
- register ConstraintWidgetClass cwClass;
- ObjectClassExtension ext;
-
- /* Call constraint destroy procedures */
- if (XtParent(widget) != NULL && !XtIsShell(widget) && XtIsConstraint(XtParent(widget))) {
- LOCK_PROCESS;
- cwClass = (ConstraintWidgetClass)XtParent(widget)->core.widget_class;
- UNLOCK_PROCESS;
- for (;;) {
- XtWidgetProc destroy;
-
- LOCK_PROCESS;
- destroy = cwClass->constraint_class.destroy;
- UNLOCK_PROCESS;
- if (destroy)
- (*destroy) (widget);
- if (cwClass == (ConstraintWidgetClass)constraintWidgetClass) break;
- LOCK_PROCESS;
- cwClass = (ConstraintWidgetClass) cwClass->core_class.superclass;
- UNLOCK_PROCESS;
- }
- }
-
- /* Call widget destroy procedures */
- LOCK_PROCESS;
- for (class = widget->core.widget_class;
- class != NULL;
- class = class->core_class.superclass) {
- XtWidgetProc destroy;
-
- destroy = class->core_class.destroy;
- UNLOCK_PROCESS;
- if (destroy)
- (*destroy) (widget);
- LOCK_PROCESS;
- }
-
- /* Call widget deallocate procedure */
- ext = (ObjectClassExtension)
- XtGetClassExtension(widget->core.widget_class,
- XtOffsetOf(CoreClassPart, extension),
- NULLQUARK, XtObjectExtensionVersion,
- sizeof(ObjectClassExtensionRec));
- if (ext && ext->deallocate) {
- XtDeallocateProc deallocate;
- deallocate = ext->deallocate;
- UNLOCK_PROCESS;
- (*deallocate)(widget, NULL);
- } else {
- UNLOCK_PROCESS;
- XtFree((char *)widget);
- }
-} /* Phase2Destroy */
-
-static Boolean IsDescendant(Widget widget, Widget root)
-{
- while ((widget = XtParent(widget)) != root) {
- if (widget == NULL) return False;
- }
- return True;
-}
-
-static void XtPhase2Destroy (Widget widget)
-{
- Display *display = NULL;
- Window window;
- Widget parent;
- XtAppContext app = XtWidgetToApplicationContext(widget);
- Widget outerInPhase2Destroy = app->in_phase2_destroy;
- int starting_count = app->destroy_count;
- Boolean isPopup = False;
-
- /* invalidate focus trace cache for this display */
- _XtGetPerDisplay(XtDisplayOfObject(widget))->pdi.traceDepth = 0;
-
- parent = widget->core.parent;
-
- if (parent && XtIsWidget(parent) && parent->core.num_popups) {
- Cardinal i;
- for (i = 0; i < parent->core.num_popups; i++) {
- if (parent->core.popup_list[i] == widget) {
- isPopup = True;
- break;
- }
- }
- }
-
- if (!isPopup && parent && XtIsComposite(parent)) {
- XtWidgetProc delete_child;
-
- LOCK_PROCESS;
- delete_child =
- ((CompositeWidgetClass) parent->core.widget_class)->
- composite_class.delete_child;
- UNLOCK_PROCESS;
- if (XtIsRectObj(widget)) {
- XtUnmanageChild(widget);
- }
- if (delete_child == NULL) {
- String param;
- Cardinal num_params = 1;
-
- LOCK_PROCESS;
- param = parent->core.widget_class->core_class.class_name;
- UNLOCK_PROCESS;
- XtAppWarningMsg(XtWidgetToApplicationContext(widget),
- "invalidProcedure","deleteChild",XtCXtToolkitError,
- "null delete_child procedure for class %s in XtDestroy",
- &param, &num_params);
- } else {
- (*delete_child) (widget);
- }
- }
-
- /* widget is freed in Phase2Destroy, so retrieve window now.
- * Shells destroy their own windows, to prevent window leaks in
- * popups; this test is practical only when XtIsShell() is cheap.
- */
- if (XtIsShell(widget) || !XtIsWidget(widget)) {
- window = 0;
- }
- else {
- display = XtDisplay(widget);
- window = widget->core.window;
- }
-
- Recursive(widget, Phase2Callbacks);
- if (app->destroy_count > starting_count) {
- int i = starting_count;
- while (i < app->destroy_count) {
-
- DestroyRec * dr = app->destroy_list + i;
- if (IsDescendant(dr->widget, widget)) {
- Widget descendant = dr->widget;
- register int j;
- app->destroy_count--;
- for (j = app->destroy_count - i; --j >= 0; dr++)
- *dr = *(dr + 1);
- XtPhase2Destroy(descendant);
- }
- else i++;
- }
- }
-
- app->in_phase2_destroy = widget;
- Recursive(widget, Phase2Destroy);
- app->in_phase2_destroy = outerInPhase2Destroy;
-
- if (isPopup) {
- Cardinal i;
- for (i = 0; i < parent->core.num_popups; i++)
- if (parent->core.popup_list[i] == widget) {
- parent->core.num_popups--;
- while (i < parent->core.num_popups) {
- parent->core.popup_list[i] = parent->core.popup_list[i+1];
- i++;
- }
- break;
- }
- }
-
- /* %%% the following parent test hides a more serious problem,
- but it avoids breaking those who depended on the old bug
- until we have time to fix it properly. */
-
- if (window && (parent == NULL || !parent->core.being_destroyed))
- XDestroyWindow(display, window);
-} /* XtPhase2Destroy */
-
-
-void _XtDoPhase2Destroy(XtAppContext app, int dispatch_level)
-{
- /* Phase 2 must occur in fifo order. List is not necessarily
- * contiguous in dispatch_level.
- */
-
- int i = 0;
- while (i < app->destroy_count) {
-
- /* XtPhase2Destroy can result in calls to XtDestroyWidget,
- * and these could cause app->destroy_list to be reallocated.
- */
-
- DestroyRec* dr = app->destroy_list + i;
- if (dr->dispatch_level >= dispatch_level) {
- Widget w = dr->widget;
- register int j;
- app->destroy_count--;
- for (j = app->destroy_count - i; --j >=0; dr++)
- *dr = *(dr + 1);
- XtPhase2Destroy(w);
- }
- else i++;
- }
-}
-
-
-void XtDestroyWidget (Widget widget)
-{
- XtAppContext app;
- DestroyRec *dr, *dr2;
-
- app = XtWidgetToApplicationContext(widget);
- LOCK_APP(app);
- if (widget->core.being_destroyed) {
- UNLOCK_APP(app);
- return;
- }
- Recursive(widget, Phase1Destroy);
-
- if (app->in_phase2_destroy &&
- IsDescendant(widget, app->in_phase2_destroy))
- {
- XtPhase2Destroy(widget);
- UNLOCK_APP(app);
- return;
- }
-
- if (app->destroy_count == app->destroy_list_size) {
- app->destroy_list_size += 10;
- app->destroy_list = (DestroyRec*)
- XtRealloc( (char*)app->destroy_list,
- (unsigned)sizeof(DestroyRec)*app->destroy_list_size
- );
- }
- dr = app->destroy_list + app->destroy_count++;
- dr->dispatch_level = app->dispatch_level;
- dr->widget = widget;
-
- if (app->dispatch_level > 1) {
- int i;
- for (i = app->destroy_count - 1; i;) {
- /* this handles only one case of nesting difficulties */
- dr = app->destroy_list + (--i);
- if (dr->dispatch_level < app->dispatch_level &&
- IsDescendant(dr->widget, widget)) {
- dr2 = app->destroy_list + (app->destroy_count-1);
- dr2->dispatch_level = dr->dispatch_level;
- break;
- }
- }
- }
-
- if (_XtSafeToDestroy(app)) {
- app->dispatch_level = 1; /* avoid nested _XtDoPhase2Destroy */
- _XtDoPhase2Destroy(app, 0);
- app->dispatch_level = 0;
- }
- UNLOCK_APP(app);
-
-} /* XtDestroyWidget */
+/***********************************************************
+Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/*
+
+Copyright 1987, 1988, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "IntrinsicI.h"
+
+struct _DestroyRec {
+ int dispatch_level;
+ Widget widget;
+};
+
+static void Recursive(Widget widget, XtWidgetProc proc)
+{
+ register Cardinal i;
+ CompositePart *cwp;
+
+ /* Recurse down normal children */
+ if (XtIsComposite(widget)) {
+ cwp = &(((CompositeWidget) widget)->composite);
+ for (i = 0; i < cwp->num_children; i++) {
+ Recursive(cwp->children[i], proc);
+ }
+ }
+
+ /* Recurse down popup children */
+ if (XtIsWidget(widget)) {
+ for (i = 0; i < widget->core.num_popups; i++) {
+ Recursive(widget->core.popup_list[i], proc);
+ }
+ }
+
+ /* Finally, apply procedure to this widget */
+ (*proc) (widget);
+} /* Recursive */
+
+static void Phase1Destroy (Widget widget)
+{
+ Widget hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
+
+ widget->core.being_destroyed = TRUE;
+ if (XtHasCallbacks(hookobj, XtNdestroyHook) == XtCallbackHasSome) {
+ XtDestroyHookDataRec call_data;
+
+ call_data.type = XtHdestroy;
+ call_data.widget = widget;
+ XtCallCallbackList(hookobj,
+ ((HookObject)hookobj)->hooks.destroyhook_callbacks,
+ (XtPointer) &call_data);
+ }
+} /* Phase1Destroy */
+
+static void Phase2Callbacks(Widget widget)
+{
+ if (widget->core.destroy_callbacks != NULL) {
+ XtCallCallbackList(widget,
+ widget->core.destroy_callbacks, (XtPointer) NULL);
+ }
+} /* Phase2Callbacks */
+
+static void Phase2Destroy(register Widget widget)
+{
+ register WidgetClass class;
+ register ConstraintWidgetClass cwClass;
+ ObjectClassExtension ext;
+
+ /* Call constraint destroy procedures */
+ if (XtParent(widget) != NULL && !XtIsShell(widget) && XtIsConstraint(XtParent(widget))) {
+ LOCK_PROCESS;
+ cwClass = (ConstraintWidgetClass)XtParent(widget)->core.widget_class;
+ UNLOCK_PROCESS;
+ for (;;) {
+ XtWidgetProc destroy;
+
+ LOCK_PROCESS;
+ destroy = cwClass->constraint_class.destroy;
+ UNLOCK_PROCESS;
+ if (destroy)
+ (*destroy) (widget);
+ if (cwClass == (ConstraintWidgetClass)constraintWidgetClass) break;
+ LOCK_PROCESS;
+ cwClass = (ConstraintWidgetClass) cwClass->core_class.superclass;
+ UNLOCK_PROCESS;
+ }
+ }
+
+ /* Call widget destroy procedures */
+ LOCK_PROCESS;
+ for (class = widget->core.widget_class;
+ class != NULL;
+ class = class->core_class.superclass) {
+ XtWidgetProc destroy;
+
+ destroy = class->core_class.destroy;
+ UNLOCK_PROCESS;
+ if (destroy)
+ (*destroy) (widget);
+ LOCK_PROCESS;
+ }
+
+ /* Call widget deallocate procedure */
+ ext = (ObjectClassExtension)
+ XtGetClassExtension(widget->core.widget_class,
+ XtOffsetOf(CoreClassPart, extension),
+ NULLQUARK, XtObjectExtensionVersion,
+ sizeof(ObjectClassExtensionRec));
+ if (ext && ext->deallocate) {
+ XtDeallocateProc deallocate;
+ deallocate = ext->deallocate;
+ UNLOCK_PROCESS;
+ (*deallocate)(widget, NULL);
+ } else {
+ UNLOCK_PROCESS;
+ XtFree((char *)widget);
+ }
+} /* Phase2Destroy */
+
+static Boolean IsDescendant(Widget widget, Widget root)
+{
+ while ((widget = XtParent(widget)) != root) {
+ if (widget == NULL) return False;
+ }
+ return True;
+}
+
+static void XtPhase2Destroy (Widget widget)
+{
+ Display *display = NULL;
+ Window window;
+ Widget parent;
+ XtAppContext app = XtWidgetToApplicationContext(widget);
+ Widget outerInPhase2Destroy = app->in_phase2_destroy;
+ int starting_count = app->destroy_count;
+ Boolean isPopup = False;
+
+ /* invalidate focus trace cache for this display */
+ _XtGetPerDisplay(XtDisplayOfObject(widget))->pdi.traceDepth = 0;
+
+ parent = widget->core.parent;
+
+ if (parent && XtIsWidget(parent) && parent->core.num_popups) {
+ Cardinal i;
+ for (i = 0; i < parent->core.num_popups; i++) {
+ if (parent->core.popup_list[i] == widget) {
+ isPopup = True;
+ break;
+ }
+ }
+ }
+
+ if (!isPopup && parent && XtIsComposite(parent)) {
+ XtWidgetProc delete_child;
+
+ LOCK_PROCESS;
+ delete_child =
+ ((CompositeWidgetClass) parent->core.widget_class)->
+ composite_class.delete_child;
+ UNLOCK_PROCESS;
+ if (XtIsRectObj(widget)) {
+ XtUnmanageChild(widget);
+ }
+ if (delete_child == NULL) {
+ String param;
+ Cardinal num_params = 1;
+
+ LOCK_PROCESS;
+ param = parent->core.widget_class->core_class.class_name;
+ UNLOCK_PROCESS;
+ XtAppWarningMsg(XtWidgetToApplicationContext(widget),
+ "invalidProcedure","deleteChild",XtCXtToolkitError,
+ "null delete_child procedure for class %s in XtDestroy",
+ &param, &num_params);
+ } else {
+ (*delete_child) (widget);
+ }
+ }
+
+ /* widget is freed in Phase2Destroy, so retrieve window now.
+ * Shells destroy their own windows, to prevent window leaks in
+ * popups; this test is practical only when XtIsShell() is cheap.
+ */
+ if (XtIsShell(widget) || !XtIsWidget(widget)) {
+ window = 0;
+ }
+ else {
+ display = XtDisplay(widget);
+ window = widget->core.window;
+ }
+
+ Recursive(widget, Phase2Callbacks);
+ if (app->destroy_count > starting_count) {
+ int i = starting_count;
+ while (i < app->destroy_count) {
+
+ DestroyRec * dr = app->destroy_list + i;
+ if (IsDescendant(dr->widget, widget)) {
+ Widget descendant = dr->widget;
+ register int j;
+ app->destroy_count--;
+ for (j = app->destroy_count - i; --j >= 0; dr++)
+ *dr = *(dr + 1);
+ XtPhase2Destroy(descendant);
+ }
+ else i++;
+ }
+ }
+
+ app->in_phase2_destroy = widget;
+ Recursive(widget, Phase2Destroy);
+ app->in_phase2_destroy = outerInPhase2Destroy;
+
+ if (isPopup) {
+ Cardinal i;
+ for (i = 0; i < parent->core.num_popups; i++)
+ if (parent->core.popup_list[i] == widget) {
+ parent->core.num_popups--;
+ while (i < parent->core.num_popups) {
+ parent->core.popup_list[i] = parent->core.popup_list[i+1];
+ i++;
+ }
+ break;
+ }
+ }
+
+ /* %%% the following parent test hides a more serious problem,
+ but it avoids breaking those who depended on the old bug
+ until we have time to fix it properly. */
+
+ if (window && (parent == NULL || !parent->core.being_destroyed))
+ XDestroyWindow(display, window);
+} /* XtPhase2Destroy */
+
+
+void _XtDoPhase2Destroy(XtAppContext app, int dispatch_level)
+{
+ /* Phase 2 must occur in fifo order. List is not necessarily
+ * contiguous in dispatch_level.
+ */
+
+ int i = 0;
+ while (i < app->destroy_count) {
+
+ /* XtPhase2Destroy can result in calls to XtDestroyWidget,
+ * and these could cause app->destroy_list to be reallocated.
+ */
+
+ DestroyRec* dr = app->destroy_list + i;
+ if (dr->dispatch_level >= dispatch_level) {
+ Widget w = dr->widget;
+ register int j;
+ app->destroy_count--;
+ for (j = app->destroy_count - i; --j >=0; dr++)
+ *dr = *(dr + 1);
+ XtPhase2Destroy(w);
+ }
+ else i++;
+ }
+}
+
+
+void XtDestroyWidget (Widget widget)
+{
+ XtAppContext app;
+ DestroyRec *dr, *dr2;
+
+ app = XtWidgetToApplicationContext(widget);
+ LOCK_APP(app);
+ if (widget->core.being_destroyed) {
+ UNLOCK_APP(app);
+ return;
+ }
+ Recursive(widget, Phase1Destroy);
+
+ if (app->in_phase2_destroy &&
+ IsDescendant(widget, app->in_phase2_destroy))
+ {
+ XtPhase2Destroy(widget);
+ UNLOCK_APP(app);
+ return;
+ }
+
+ if (app->destroy_count == app->destroy_list_size) {
+ app->destroy_list_size += 10;
+ app->destroy_list = (DestroyRec*)
+ XtRealloc( (char*)app->destroy_list,
+ (unsigned)sizeof(DestroyRec)*app->destroy_list_size
+ );
+ }
+ dr = app->destroy_list + app->destroy_count++;
+ dr->dispatch_level = app->dispatch_level;
+ dr->widget = widget;
+
+ if (app->dispatch_level > 1) {
+ int i;
+ for (i = app->destroy_count - 1; i;) {
+ /* this handles only one case of nesting difficulties */
+ dr = app->destroy_list + (--i);
+ if (dr->dispatch_level < app->dispatch_level &&
+ IsDescendant(dr->widget, widget)) {
+ dr2 = app->destroy_list + (app->destroy_count-1);
+ dr2->dispatch_level = dr->dispatch_level;
+ break;
+ }
+ }
+ }
+
+ if (_XtSafeToDestroy(app)) {
+ app->dispatch_level = 1; /* avoid nested _XtDoPhase2Destroy */
+ _XtDoPhase2Destroy(app, 0);
+ app->dispatch_level = 0;
+ }
+ UNLOCK_APP(app);
+
+} /* XtDestroyWidget */