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