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