Manage.c revision 0568f49b
1444c061aSmrg/***********************************************************
2249c3046SmrgCopyright (c) 1993, Oracle and/or its affiliates. All rights reserved.
31477040fSmrg
41477040fSmrgPermission is hereby granted, free of charge, to any person obtaining a
51477040fSmrgcopy of this software and associated documentation files (the "Software"),
61477040fSmrgto deal in the Software without restriction, including without limitation
71477040fSmrgthe rights to use, copy, modify, merge, publish, distribute, sublicense,
81477040fSmrgand/or sell copies of the Software, and to permit persons to whom the
91477040fSmrgSoftware is furnished to do so, subject to the following conditions:
101477040fSmrg
111477040fSmrgThe above copyright notice and this permission notice (including the next
121477040fSmrgparagraph) shall be included in all copies or substantial portions of the
131477040fSmrgSoftware.
141477040fSmrg
151477040fSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
161477040fSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
171477040fSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
181477040fSmrgTHE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
191477040fSmrgLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
201477040fSmrgFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
211477040fSmrgDEALINGS IN THE SOFTWARE.
221477040fSmrg
231477040fSmrgCopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
24444c061aSmrg
25444c061aSmrg                        All Rights Reserved
26444c061aSmrg
27444c061aSmrgPermission to use, copy, modify, and distribute this software and its
28444c061aSmrgdocumentation for any purpose and without fee is hereby granted,
29444c061aSmrgprovided that the above copyright notice appear in all copies and that
30444c061aSmrgboth that copyright notice and this permission notice appear in
311477040fSmrgsupporting documentation, and that the name of Digital not be
32444c061aSmrgused in advertising or publicity pertaining to distribution of the
33444c061aSmrgsoftware without specific, written prior permission.
34444c061aSmrg
35444c061aSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
36444c061aSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
37444c061aSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
38444c061aSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
39444c061aSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
40444c061aSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
41444c061aSmrgSOFTWARE.
42444c061aSmrg
43444c061aSmrg******************************************************************/
44444c061aSmrg
45444c061aSmrg/*
46444c061aSmrg
47444c061aSmrgCopyright 1987, 1988, 1994, 1998  The Open Group
48444c061aSmrg
49444c061aSmrgPermission to use, copy, modify, distribute, and sell this software and its
50444c061aSmrgdocumentation for any purpose is hereby granted without fee, provided that
51444c061aSmrgthe above copyright notice appear in all copies and that both that
52444c061aSmrgcopyright notice and this permission notice appear in supporting
53444c061aSmrgdocumentation.
54444c061aSmrg
55444c061aSmrgThe above copyright notice and this permission notice shall be included in
56444c061aSmrgall copies or substantial portions of the Software.
57444c061aSmrg
58444c061aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59444c061aSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60444c061aSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
61444c061aSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
62444c061aSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
63444c061aSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
64444c061aSmrg
65444c061aSmrgExcept as contained in this notice, the name of The Open Group shall not be
66444c061aSmrgused in advertising or otherwise to promote the sale, use or other dealings
67444c061aSmrgin this Software without prior written authorization from The Open Group.
68444c061aSmrg
69444c061aSmrg*/
70444c061aSmrg
71444c061aSmrg#ifdef HAVE_CONFIG_H
72444c061aSmrg#include <config.h>
73444c061aSmrg#endif
74444c061aSmrg#include "IntrinsicI.h"
75444c061aSmrg
760568f49bSmrgstatic _Xconst _XtString XtNinvalidChild = "invalidChild";
770568f49bSmrgstatic _Xconst _XtString XtNxtUnmanageChildren = "xtUnmanageChildren";
780568f49bSmrgstatic _Xconst _XtString XtNxtManageChildren = "xtManageChildren";
790568f49bSmrgstatic _Xconst _XtString XtNxtChangeManagedSet = "xtChangeManagedSet";
80444c061aSmrg
81444c061aSmrgstatic void UnmanageChildren(
82444c061aSmrg    WidgetList children,
83444c061aSmrg    Cardinal num_children,
84444c061aSmrg    Widget parent,
85444c061aSmrg    Cardinal* num_unique_children,
86444c061aSmrg    Boolean call_change_managed,
870568f49bSmrg    _Xconst _XtString caller_func)
88444c061aSmrg{
89444c061aSmrg    Widget		child;
90444c061aSmrg    Cardinal		i;
91444c061aSmrg    XtWidgetProc	change_managed = NULL;
92444c061aSmrg    Bool		parent_realized = False;
93444c061aSmrg
94444c061aSmrg    *num_unique_children = 0;
95444c061aSmrg
96444c061aSmrg    if (XtIsComposite((Widget) parent)) {
97444c061aSmrg	LOCK_PROCESS;
98444c061aSmrg        change_managed = ((CompositeWidgetClass) parent->core.widget_class)
99444c061aSmrg		    ->composite_class.change_managed;
100444c061aSmrg	UNLOCK_PROCESS;
101444c061aSmrg	parent_realized = XtIsRealized((Widget)parent);
102444c061aSmrg    } else {
103444c061aSmrg        XtAppErrorMsg(XtWidgetToApplicationContext((Widget)parent),
104444c061aSmrg		      "invalidParent",caller_func, XtCXtToolkitError,
105444c061aSmrg		   "Attempt to unmanage a child when parent is not Composite",
1060568f49bSmrg		      NULL, NULL);
107444c061aSmrg    }
108444c061aSmrg
109444c061aSmrg    for (i = 0; i < num_children; i++) {
110444c061aSmrg	child = children[i];
111444c061aSmrg	if (child == NULL) {
112444c061aSmrg	    XtAppWarningMsg(XtWidgetToApplicationContext(parent),
113444c061aSmrg		  XtNinvalidChild,caller_func,XtCXtToolkitError,
114444c061aSmrg                  "Null child passed to XtUnmanageChildren",
1150568f49bSmrg		  NULL, NULL);
116444c061aSmrg	    return;
117444c061aSmrg	}
118444c061aSmrg        if (child->core.parent != parent) {
119444c061aSmrg	   XtAppWarningMsg(XtWidgetToApplicationContext(parent),
120444c061aSmrg		   "ambiguousParent",caller_func,XtCXtToolkitError,
121444c061aSmrg           "Not all children have same parent in UnmanageChildren",
1220568f49bSmrg             NULL, NULL);
123444c061aSmrg	} else
124444c061aSmrg        if (child->core.managed) {
125444c061aSmrg            (*num_unique_children)++;
126444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(child,"Child \"%s\" is marked unmanaged\n",
127444c061aSmrg			   XtName(child)));
128444c061aSmrg	    child->core.managed = FALSE;
129444c061aSmrg            if (XtIsWidget(child)
130444c061aSmrg		&& XtIsRealized(child)
131444c061aSmrg		&& child->core.mapped_when_managed)
132444c061aSmrg                    XtUnmapWidget(child);
133444c061aSmrg            else
134444c061aSmrg	    { /* RectObj child */
135444c061aSmrg		Widget pw = child->core.parent;
136444c061aSmrg		RectObj r = (RectObj) child;
137444c061aSmrg		while ((pw!=NULL) && (!XtIsWidget(pw))) pw = pw->core.parent;
138444c061aSmrg		if ((pw!=NULL) && XtIsRealized (pw))
139444c061aSmrg		    XClearArea (XtDisplay (pw), XtWindow (pw),
140444c061aSmrg			r->rectangle.x, r->rectangle.y,
1410568f49bSmrg			(unsigned) (r->rectangle.width + (r->rectangle.border_width << 1)),
1420568f49bSmrg			(unsigned) (r->rectangle.height + (r->rectangle.border_width << 1)),
143444c061aSmrg			TRUE);
144444c061aSmrg	    }
145444c061aSmrg
146444c061aSmrg        }
147444c061aSmrg    }
148444c061aSmrg    if (call_change_managed && *num_unique_children != 0 &&
149444c061aSmrg	change_managed != NULL && parent_realized) {
150444c061aSmrg	CALLGEOTAT(_XtGeoTrace((Widget)parent,
151444c061aSmrg		       "Call parent: \"%s\"[%d,%d]'s changemanaged proc\n",
152444c061aSmrg		       XtName((Widget)parent),
153444c061aSmrg		       parent->core.width,parent->core.height));
154444c061aSmrg	(*change_managed) (parent);
155444c061aSmrg    }
156444c061aSmrg} /* UnmanageChildren */
157444c061aSmrg
158444c061aSmrgvoid XtUnmanageChildren (
159444c061aSmrg    WidgetList children,
160444c061aSmrg    Cardinal num_children)
161444c061aSmrg{
162444c061aSmrg    Widget parent, hookobj;
163444c061aSmrg    Cardinal ii;
164444c061aSmrg#ifdef XTHREADS
165444c061aSmrg    XtAppContext app;
166444c061aSmrg#endif
167444c061aSmrg
168444c061aSmrg    if (num_children == 0) return;
169444c061aSmrg    if (children[0] == NULL) {
170444c061aSmrg	XtWarningMsg(XtNinvalidChild,XtNxtUnmanageChildren,XtCXtToolkitError,
171444c061aSmrg		     "Null child found in argument list to unmanage",
1720568f49bSmrg		     NULL, NULL);
173444c061aSmrg	return;
174444c061aSmrg    }
175444c061aSmrg#ifdef XTHREADS
176444c061aSmrg    app = XtWidgetToApplicationContext(children[0]);
177444c061aSmrg#endif
178444c061aSmrg    LOCK_APP(app);
179444c061aSmrg    parent = children[0]->core.parent;
180444c061aSmrg    if (parent->core.being_destroyed) {
181444c061aSmrg	UNLOCK_APP(app);
182444c061aSmrg	return;
183444c061aSmrg    }
184444c061aSmrg    UnmanageChildren(children, num_children, parent, &ii,
185444c061aSmrg		     (Boolean)True, XtNxtUnmanageChildren);
186444c061aSmrg    hookobj = XtHooksOfDisplay(XtDisplayOfObject(children[0]));
187444c061aSmrg    if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
188444c061aSmrg	XtChangeHookDataRec call_data;
189444c061aSmrg
190444c061aSmrg	call_data.type = XtHunmanageChildren;
191444c061aSmrg	call_data.widget = parent;
192444c061aSmrg	call_data.event_data = (XtPointer) children;
193444c061aSmrg	call_data.num_event_data = num_children;
194444c061aSmrg	XtCallCallbackList(hookobj,
195444c061aSmrg		((HookObject)hookobj)->hooks.changehook_callbacks,
196444c061aSmrg		(XtPointer)&call_data);
197444c061aSmrg    }
198444c061aSmrg    UNLOCK_APP(app);
199444c061aSmrg} /* XtUnmanageChildren */
200444c061aSmrg
201444c061aSmrgvoid XtUnmanageChild(
202444c061aSmrg    Widget child)
203444c061aSmrg{
204444c061aSmrg    XtUnmanageChildren(&child, (Cardinal)1);
205444c061aSmrg} /* XtUnmanageChild */
206444c061aSmrg
207444c061aSmrg
208444c061aSmrgstatic void ManageChildren(
209444c061aSmrg    WidgetList  children,
210444c061aSmrg    Cardinal    num_children,
211444c061aSmrg    Widget	parent,
212444c061aSmrg    Boolean	call_change_managed,
2130568f49bSmrg    _Xconst _XtString	caller_func)
214444c061aSmrg{
215444c061aSmrg#define MAXCHILDREN 100
216444c061aSmrg    Widget		child;
217444c061aSmrg    Cardinal		num_unique_children, i;
218444c061aSmrg    XtWidgetProc	change_managed = NULL;
219444c061aSmrg    WidgetList		unique_children;
220444c061aSmrg    Widget		cache[MAXCHILDREN];
221444c061aSmrg    Bool		parent_realized = False;
222444c061aSmrg
223444c061aSmrg    if (XtIsComposite((Widget) parent)) {
224444c061aSmrg	LOCK_PROCESS;
225444c061aSmrg        change_managed = ((CompositeWidgetClass) parent->core.widget_class)
226444c061aSmrg		    ->composite_class.change_managed;
227444c061aSmrg	UNLOCK_PROCESS;
228444c061aSmrg	parent_realized = XtIsRealized((Widget)parent);
229444c061aSmrg    } else {
230444c061aSmrg	XtAppErrorMsg(XtWidgetToApplicationContext((Widget)parent),
231444c061aSmrg		"invalidParent",caller_func, XtCXtToolkitError,
232444c061aSmrg	    "Attempt to manage a child when parent is not Composite",
2330568f49bSmrg	    NULL, NULL);
234444c061aSmrg    }
235444c061aSmrg
236444c061aSmrg    /* Construct new list of children that really need to be operated upon. */
237444c061aSmrg    if (num_children <= MAXCHILDREN) {
238444c061aSmrg	unique_children = cache;
239444c061aSmrg    } else {
2400568f49bSmrg	unique_children = (WidgetList) __XtMalloc((Cardinal) ((size_t)num_children * sizeof(Widget)));
241444c061aSmrg    }
242444c061aSmrg    num_unique_children = 0;
243444c061aSmrg    for (i = 0; i < num_children; i++) {
244444c061aSmrg	child = children[i];
245444c061aSmrg	if (child == NULL) {
246444c061aSmrg	    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)parent),
247444c061aSmrg		XtNinvalidChild,caller_func,XtCXtToolkitError,
248444c061aSmrg		"null child passed to ManageChildren",
2490568f49bSmrg		NULL, NULL);
250444c061aSmrg	    if (unique_children != cache) XtFree((char *) unique_children);
251444c061aSmrg	    return;
252444c061aSmrg	}
253444c061aSmrg#ifdef DEBUG
254444c061aSmrg	if (!XtIsRectObj(child)) {
255444c061aSmrg	    String params[2];
256444c061aSmrg	    Cardinal num_params = 2;
257444c061aSmrg	    params[0] = XtName(child);
258444c061aSmrg	    params[1] = child->core.widget_class->core_class.class_name;
259444c061aSmrg	    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)parent),
260444c061aSmrg			    "notRectObj",caller_func,XtCXtToolkitError,
261444c061aSmrg			    "child \"%s\", class %s is not a RectObj",
262444c061aSmrg			    params, &num_params);
263444c061aSmrg	    continue;
264444c061aSmrg	}
265444c061aSmrg#endif /*DEBUG*/
266444c061aSmrg        if (child->core.parent != parent) {
267444c061aSmrg	    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)parent),
268444c061aSmrg		    "ambiguousParent",caller_func,XtCXtToolkitError,
269444c061aSmrg		"Not all children have same parent in XtManageChildren",
2700568f49bSmrg		NULL, NULL);
271444c061aSmrg	} else if (! child->core.managed && !child->core.being_destroyed) {
272444c061aSmrg	    unique_children[num_unique_children++] = child;
273444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(child,
274444c061aSmrg			   "Child \"%s\"[%d,%d] is marked managed\n",
275444c061aSmrg			   XtName(child),
276444c061aSmrg			   child->core.width,child->core.height));
277444c061aSmrg	    child->core.managed = TRUE;
278444c061aSmrg	}
279444c061aSmrg    }
280444c061aSmrg
281444c061aSmrg    if ((call_change_managed || num_unique_children != 0) && parent_realized) {
282444c061aSmrg	/* Compute geometry of new managed set of children. */
283444c061aSmrg	if (change_managed != NULL) {
284444c061aSmrg	    CALLGEOTAT(_XtGeoTrace((Widget)parent,
285444c061aSmrg			   "Call parent: \"%s\"[%d,%d]'s changemanaged\n",
286444c061aSmrg			   XtName((Widget)parent),
287444c061aSmrg			   parent->core.width,parent->core.height));
288444c061aSmrg	    (*change_managed) ((Widget)parent);
289444c061aSmrg	}
290444c061aSmrg
291444c061aSmrg	/* Realize each child if necessary, then map if necessary */
292444c061aSmrg	for (i = 0; i < num_unique_children; i++) {
293444c061aSmrg	    child = unique_children[i];
294444c061aSmrg	    if (XtIsWidget(child)) {
295444c061aSmrg		if (! XtIsRealized(child)) XtRealizeWidget(child);
296444c061aSmrg		if (child->core.mapped_when_managed) XtMapWidget(child);
297444c061aSmrg	    } else { /* RectObj child */
298444c061aSmrg		Widget pw = child->core.parent;
299444c061aSmrg		RectObj r = (RectObj) child;
300444c061aSmrg		while ((pw!=NULL) && (!XtIsWidget(pw)))
301444c061aSmrg		    pw = pw->core.parent;
302444c061aSmrg		if (pw != NULL)
303444c061aSmrg		    XClearArea (XtDisplay (pw), XtWindow (pw),
304444c061aSmrg		    r->rectangle.x, r->rectangle.y,
3050568f49bSmrg		    (unsigned) (r->rectangle.width + (r->rectangle.border_width << 1)),
3060568f49bSmrg		    (unsigned) (r->rectangle.height + (r->rectangle.border_width << 1)),
307444c061aSmrg		    TRUE);
308444c061aSmrg            }
309444c061aSmrg        }
310444c061aSmrg    }
311444c061aSmrg
312444c061aSmrg    if (unique_children != cache) XtFree((char *) unique_children);
313444c061aSmrg} /* ManageChildren */
314444c061aSmrg
315444c061aSmrgvoid XtManageChildren(
316444c061aSmrg    WidgetList children,
317444c061aSmrg    Cardinal num_children)
318444c061aSmrg{
319444c061aSmrg    Widget parent, hookobj;
320444c061aSmrg#ifdef XTHREADS
321444c061aSmrg    XtAppContext app;
322444c061aSmrg#endif
323444c061aSmrg
324444c061aSmrg    if (num_children == 0) return;
325444c061aSmrg    if (children[0] == NULL) {
326444c061aSmrg	XtWarningMsg(XtNinvalidChild, XtNxtManageChildren, XtCXtToolkitError,
327444c061aSmrg		     "null child passed to XtManageChildren",
3280568f49bSmrg		     NULL, NULL);
329444c061aSmrg	return;
330444c061aSmrg    }
331444c061aSmrg#ifdef XTHREADS
332444c061aSmrg    app = XtWidgetToApplicationContext(children[0]);
333444c061aSmrg#endif
334444c061aSmrg    LOCK_APP(app);
335444c061aSmrg    parent = children[0]->core.parent;
336444c061aSmrg    if (parent->core.being_destroyed) {
337444c061aSmrg	UNLOCK_APP(app);
338444c061aSmrg	return;
339444c061aSmrg    }
340444c061aSmrg    ManageChildren(children, num_children, parent, (Boolean)False,
341444c061aSmrg		   XtNxtManageChildren);
342444c061aSmrg    hookobj = XtHooksOfDisplay(XtDisplayOfObject(children[0]));
343444c061aSmrg    if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
344444c061aSmrg	XtChangeHookDataRec call_data;
345444c061aSmrg
346444c061aSmrg	call_data.type = XtHmanageChildren;
347444c061aSmrg	call_data.widget = parent;
348444c061aSmrg	call_data.event_data = (XtPointer) children;
349444c061aSmrg	call_data.num_event_data = num_children;
350444c061aSmrg	XtCallCallbackList(hookobj,
351444c061aSmrg		((HookObject)hookobj)->hooks.changehook_callbacks,
352444c061aSmrg		(XtPointer)&call_data);
353444c061aSmrg    }
354444c061aSmrg    UNLOCK_APP(app);
355444c061aSmrg} /* XtManageChildren */
356444c061aSmrg
357444c061aSmrgvoid XtManageChild(
358444c061aSmrg    Widget child)
359444c061aSmrg{
360444c061aSmrg    XtManageChildren(&child, (Cardinal) 1);
361444c061aSmrg} /* XtManageChild */
362444c061aSmrg
363444c061aSmrg
364444c061aSmrgvoid XtSetMappedWhenManaged(
365444c061aSmrg    Widget widget,
366444c061aSmrg    _XtBoolean mapped_when_managed)
367444c061aSmrg{
368444c061aSmrg    Widget hookobj;
369444c061aSmrg    WIDGET_TO_APPCON(widget);
370444c061aSmrg
371444c061aSmrg    LOCK_APP(app);
372444c061aSmrg    if (widget->core.mapped_when_managed == mapped_when_managed) {
373444c061aSmrg	UNLOCK_APP(app);
374444c061aSmrg	return;
375444c061aSmrg    }
3760568f49bSmrg    widget->core.mapped_when_managed = (Boolean) mapped_when_managed;
377444c061aSmrg
378444c061aSmrg    hookobj = XtHooksOfDisplay(XtDisplay(widget));
379444c061aSmrg    if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
380444c061aSmrg	XtChangeHookDataRec call_data;
381444c061aSmrg
382444c061aSmrg	call_data.type = XtHsetMappedWhenManaged;
383444c061aSmrg	call_data.widget = widget;
384444c061aSmrg	call_data.event_data = (XtPointer) (unsigned long) mapped_when_managed;
385444c061aSmrg	XtCallCallbackList(hookobj,
386444c061aSmrg		((HookObject)hookobj)->hooks.changehook_callbacks,
387444c061aSmrg		(XtPointer)&call_data);
388444c061aSmrg    }
389444c061aSmrg
390444c061aSmrg    if (! XtIsManaged(widget)) {
391444c061aSmrg	UNLOCK_APP(app);
392444c061aSmrg	return;
393444c061aSmrg    }
394444c061aSmrg
395444c061aSmrg    if (mapped_when_managed) {
396444c061aSmrg	/* Didn't used to be mapped when managed.		*/
397444c061aSmrg	if (XtIsRealized(widget)) XtMapWidget(widget);
398444c061aSmrg    } else {
399444c061aSmrg	/* Used to be mapped when managed.			*/
400444c061aSmrg	if (XtIsRealized(widget)) XtUnmapWidget(widget);
401444c061aSmrg    }
402444c061aSmrg    UNLOCK_APP(app);
403444c061aSmrg} /* XtSetMappedWhenManaged */
404444c061aSmrg
405444c061aSmrg
406444c061aSmrgvoid XtChangeManagedSet(
407444c061aSmrg    WidgetList unmanage_children,
408444c061aSmrg    Cardinal num_unmanage,
409444c061aSmrg    XtDoChangeProc do_change_proc,
410444c061aSmrg    XtPointer client_data,
411444c061aSmrg    WidgetList manage_children,
412444c061aSmrg    Cardinal num_manage)
413444c061aSmrg{
414444c061aSmrg    WidgetList childp;
415444c061aSmrg    Widget parent;
416444c061aSmrg    int i;
417444c061aSmrg    Cardinal some_unmanaged;
418444c061aSmrg    Boolean call_out;
419444c061aSmrg    XtAppContext app;
420444c061aSmrg    Widget hookobj;
421444c061aSmrg    XtChangeHookDataRec call_data;
422444c061aSmrg
423444c061aSmrg    if (num_unmanage == 0 && num_manage == 0)
424444c061aSmrg	return;
425444c061aSmrg
426444c061aSmrg    /* specification doesn't state that library will check for NULL in list */
427444c061aSmrg
428444c061aSmrg    childp = num_unmanage ? unmanage_children : manage_children;
429444c061aSmrg    app = XtWidgetToApplicationContext(*childp);
430444c061aSmrg    LOCK_APP(app);
431444c061aSmrg
432444c061aSmrg    parent = XtParent(*childp);
433444c061aSmrg    childp = unmanage_children;
4340568f49bSmrg    for (i = (int) num_unmanage; --i >= 0 && XtParent(*childp) == parent; childp++);
435444c061aSmrg    call_out = (i >= 0);
436444c061aSmrg    childp = manage_children;
4370568f49bSmrg    for (i = (int) num_manage;   --i >= 0 && XtParent(*childp) == parent; childp++);
438444c061aSmrg    if (call_out || i >= 0) {
439444c061aSmrg	XtAppWarningMsg(app, "ambiguousParent", XtNxtChangeManagedSet,
440444c061aSmrg			XtCXtToolkitError, "Not all children have same parent",
4410568f49bSmrg			NULL, NULL);
442444c061aSmrg    }
443444c061aSmrg    if (! XtIsComposite(parent)) {
444444c061aSmrg	UNLOCK_APP(app);
445444c061aSmrg	XtAppErrorMsg(app, "invalidParent", XtNxtChangeManagedSet,
446444c061aSmrg		      XtCXtToolkitError,
447444c061aSmrg		      "Attempt to manage a child when parent is not Composite",
4480568f49bSmrg		      NULL, NULL);
449444c061aSmrg    }
450444c061aSmrg    if (parent->core.being_destroyed) {
451444c061aSmrg	UNLOCK_APP(app);
452444c061aSmrg	return;
453444c061aSmrg    }
454444c061aSmrg
455444c061aSmrg    call_out = False;
456444c061aSmrg    if (do_change_proc) {
4570568f49bSmrg	CompositeClassExtension ext = (CompositeClassExtension)
458444c061aSmrg	    XtGetClassExtension(parent->core.widget_class,
459444c061aSmrg				XtOffsetOf(CompositeClassRec,
460444c061aSmrg					   composite_class.extension),
461444c061aSmrg				NULLQUARK, XtCompositeExtensionVersion,
462444c061aSmrg				sizeof(CompositeClassExtensionRec));
463444c061aSmrg	if (!ext || !ext->allows_change_managed_set)
464444c061aSmrg	    call_out = True;
465444c061aSmrg    }
466444c061aSmrg
467444c061aSmrg    UnmanageChildren(unmanage_children, num_unmanage, parent,
468444c061aSmrg		     &some_unmanaged, call_out, XtNxtChangeManagedSet);
469444c061aSmrg
470444c061aSmrg    hookobj = XtHooksOfDisplay(XtDisplay(parent));
471444c061aSmrg    if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
472444c061aSmrg	call_data.type = XtHunmanageSet;
473444c061aSmrg	call_data.widget = parent;
474444c061aSmrg	call_data.event_data = (XtPointer) unmanage_children;
475444c061aSmrg	call_data.num_event_data = num_unmanage;
476444c061aSmrg	XtCallCallbackList(hookobj,
477444c061aSmrg		((HookObject)hookobj)->hooks.changehook_callbacks,
478444c061aSmrg		(XtPointer) &call_data);
479444c061aSmrg    }
480444c061aSmrg
481444c061aSmrg    if (do_change_proc)
482444c061aSmrg	(*do_change_proc)(parent, unmanage_children, &num_unmanage,
483444c061aSmrg			  manage_children, &num_manage, client_data);
484444c061aSmrg
485444c061aSmrg    call_out = (some_unmanaged && !call_out);
486444c061aSmrg    ManageChildren(manage_children, num_manage, parent, call_out,
487444c061aSmrg		   XtNxtChangeManagedSet);
488444c061aSmrg
489444c061aSmrg    if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
490444c061aSmrg	call_data.type = XtHmanageSet;
491444c061aSmrg	call_data.event_data = (XtPointer) manage_children;
492444c061aSmrg	call_data.num_event_data = num_manage;
493444c061aSmrg	XtCallCallbackList(hookobj,
494444c061aSmrg		((HookObject)hookobj)->hooks.changehook_callbacks,
495444c061aSmrg		(XtPointer) &call_data);
496444c061aSmrg    }
497444c061aSmrg    UNLOCK_APP(app);
498444c061aSmrg} /* XtChangeManagedSet */
499