1
/* $Xorg: Manage.c,v 1.4 2001/02/09 02:03:55 xorgcvs Exp $ */
3
/***********************************************************
4
Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
5
Copyright 1993 by Sun Microsystems, Inc. Mountain View, CA.
9
Permission to use, copy, modify, and distribute this software and its
10
documentation for any purpose and without fee is hereby granted,
11
provided that the above copyright notice appear in all copies and that
12
both that copyright notice and this permission notice appear in
13
supporting documentation, and that the names of Digital or Sun not be
14
used in advertising or publicity pertaining to distribution of the
15
software without specific, written prior permission.
17
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
18
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
19
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
20
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
25
SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
26
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
27
NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
28
ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
29
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
30
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
31
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
32
THE USE OR PERFORMANCE OF THIS SOFTWARE.
34
******************************************************************/
35
/* $XFree86: xc/lib/Xt/Manage.c,v 3.8 2001/12/14 19:56:26 dawes Exp $ */
39
Copyright 1987, 1988, 1994, 1998 The Open Group
41
Permission to use, copy, modify, distribute, and sell this software and its
42
documentation for any purpose is hereby granted without fee, provided that
43
the above copyright notice appear in all copies and that both that
44
copyright notice and this permission notice appear in supporting
47
The above copyright notice and this permission notice shall be included in
48
all copies or substantial portions of the Software.
50
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
51
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
52
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
53
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
54
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
55
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
57
Except as contained in this notice, the name of The Open Group shall not be
58
used in advertising or otherwise to promote the sale, use or other dealings
59
in this Software without prior written authorization from The Open Group.
63
#include "IntrinsicI.h"
65
static String XtNinvalidChild = "invalidChild";
66
static String XtNxtUnmanageChildren = "xtUnmanageChildren";
67
static String XtNxtManageChildren = "xtManageChildren";
68
static String XtNxtChangeManagedSet = "xtChangeManagedSet";
70
static void UnmanageChildren(
72
Cardinal num_children,
74
Cardinal* num_unique_children,
75
Boolean call_change_managed,
80
XtWidgetProc change_managed = NULL;
81
Bool parent_realized = False;
83
*num_unique_children = 0;
85
if (XtIsComposite((Widget) parent)) {
87
change_managed = ((CompositeWidgetClass) parent->core.widget_class)
88
->composite_class.change_managed;
90
parent_realized = XtIsRealized((Widget)parent);
92
XtAppErrorMsg(XtWidgetToApplicationContext((Widget)parent),
93
"invalidParent",caller_func, XtCXtToolkitError,
94
"Attempt to unmanage a child when parent is not Composite",
95
(String *) NULL, (Cardinal *) NULL);
98
for (i = 0; i < num_children; i++) {
101
XtAppWarningMsg(XtWidgetToApplicationContext(parent),
102
XtNinvalidChild,caller_func,XtCXtToolkitError,
103
"Null child passed to XtUnmanageChildren",
104
(String *)NULL, (Cardinal *)NULL);
107
if (child->core.parent != parent) {
108
XtAppWarningMsg(XtWidgetToApplicationContext(parent),
109
"ambiguousParent",caller_func,XtCXtToolkitError,
110
"Not all children have same parent in UnmanageChildren",
111
(String *)NULL, (Cardinal *)NULL);
113
if (child->core.managed) {
114
(*num_unique_children)++;
115
CALLGEOTAT(_XtGeoTrace(child,"Child \"%s\" is marked unmanaged\n",
117
child->core.managed = FALSE;
118
if (XtIsWidget(child)
119
&& XtIsRealized(child)
120
&& child->core.mapped_when_managed)
121
XtUnmapWidget(child);
123
{ /* RectObj child */
124
Widget pw = child->core.parent;
125
RectObj r = (RectObj) child;
126
while ((pw!=NULL) && (!XtIsWidget(pw))) pw = pw->core.parent;
127
if ((pw!=NULL) && XtIsRealized (pw))
128
XClearArea (XtDisplay (pw), XtWindow (pw),
129
r->rectangle.x, r->rectangle.y,
130
r->rectangle.width + (r->rectangle.border_width << 1),
131
r->rectangle.height + (r->rectangle.border_width << 1),
137
if (call_change_managed && *num_unique_children != 0 &&
138
change_managed != NULL && parent_realized) {
139
CALLGEOTAT(_XtGeoTrace((Widget)parent,
140
"Call parent: \"%s\"[%d,%d]'s changemanaged proc\n",
141
XtName((Widget)parent),
142
parent->core.width,parent->core.height));
143
(*change_managed) (parent);
145
} /* UnmanageChildren */
147
void XtUnmanageChildren (children, num_children)
149
Cardinal num_children;
151
Widget parent, hookobj;
155
if (num_children == 0) return;
156
if (children[0] == NULL) {
157
XtWarningMsg(XtNinvalidChild,XtNxtUnmanageChildren,XtCXtToolkitError,
158
"Null child found in argument list to unmanage",
159
(String *)NULL, (Cardinal *)NULL);
162
app = XtWidgetToApplicationContext(children[0]);
164
parent = children[0]->core.parent;
165
if (parent->core.being_destroyed) {
169
UnmanageChildren(children, num_children, parent, &ii,
170
(Boolean)True, XtNxtUnmanageChildren);
171
hookobj = XtHooksOfDisplay(XtDisplayOfObject(children[0]));
172
if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
173
XtChangeHookDataRec call_data;
175
call_data.type = XtHunmanageChildren;
176
call_data.widget = parent;
177
call_data.event_data = (XtPointer) children;
178
call_data.num_event_data = num_children;
179
XtCallCallbackList(hookobj,
180
((HookObject)hookobj)->hooks.changehook_callbacks,
181
(XtPointer)&call_data);
184
} /* XtUnmanageChildren */
186
void XtUnmanageChild(child)
189
XtUnmanageChildren(&child, (Cardinal)1);
190
} /* XtUnmanageChild */
193
static void ManageChildren(
195
Cardinal num_children,
197
Boolean call_change_managed,
200
#define MAXCHILDREN 100
202
Cardinal num_unique_children, i;
203
XtWidgetProc change_managed = NULL;
204
WidgetList unique_children;
205
Widget cache[MAXCHILDREN];
206
Bool parent_realized = False;
208
if (XtIsComposite((Widget) parent)) {
210
change_managed = ((CompositeWidgetClass) parent->core.widget_class)
211
->composite_class.change_managed;
213
parent_realized = XtIsRealized((Widget)parent);
215
XtAppErrorMsg(XtWidgetToApplicationContext((Widget)parent),
216
"invalidParent",caller_func, XtCXtToolkitError,
217
"Attempt to manage a child when parent is not Composite",
218
(String *) NULL, (Cardinal *) NULL);
221
/* Construct new list of children that really need to be operated upon. */
222
if (num_children <= MAXCHILDREN) {
223
unique_children = cache;
225
unique_children = (WidgetList) __XtMalloc(num_children * sizeof(Widget));
227
num_unique_children = 0;
228
for (i = 0; i < num_children; i++) {
231
XtAppWarningMsg(XtWidgetToApplicationContext((Widget)parent),
232
XtNinvalidChild,caller_func,XtCXtToolkitError,
233
"null child passed to ManageChildren",
234
(String *)NULL, (Cardinal *)NULL);
235
if (unique_children != cache) XtFree((char *) unique_children);
239
if (!XtIsRectObj(child)) {
241
Cardinal num_params = 2;
242
params[0] = XtName(child);
243
params[1] = child->core.widget_class->core_class.class_name;
244
XtAppWarningMsg(XtWidgetToApplicationContext((Widget)parent),
245
"notRectObj",caller_func,XtCXtToolkitError,
246
"child \"%s\", class %s is not a RectObj",
247
params, &num_params);
251
if (child->core.parent != parent) {
252
XtAppWarningMsg(XtWidgetToApplicationContext((Widget)parent),
253
"ambiguousParent",caller_func,XtCXtToolkitError,
254
"Not all children have same parent in XtManageChildren",
255
(String *)NULL, (Cardinal *)NULL);
256
} else if (! child->core.managed && !child->core.being_destroyed) {
257
unique_children[num_unique_children++] = child;
258
CALLGEOTAT(_XtGeoTrace(child,
259
"Child \"%s\"[%d,%d] is marked managed\n",
261
child->core.width,child->core.height));
262
child->core.managed = TRUE;
266
if ((call_change_managed || num_unique_children != 0) && parent_realized) {
267
/* Compute geometry of new managed set of children. */
268
if (change_managed != NULL) {
269
CALLGEOTAT(_XtGeoTrace((Widget)parent,
270
"Call parent: \"%s\"[%d,%d]'s changemanaged\n",
271
XtName((Widget)parent),
272
parent->core.width,parent->core.height));
273
(*change_managed) ((Widget)parent);
276
/* Realize each child if necessary, then map if necessary */
277
for (i = 0; i < num_unique_children; i++) {
278
child = unique_children[i];
279
if (XtIsWidget(child)) {
280
if (! XtIsRealized(child)) XtRealizeWidget(child);
281
if (child->core.mapped_when_managed) XtMapWidget(child);
282
} else { /* RectObj child */
283
Widget pw = child->core.parent;
284
RectObj r = (RectObj) child;
285
while ((pw!=NULL) && (!XtIsWidget(pw)))
286
pw = pw->core.parent;
288
XClearArea (XtDisplay (pw), XtWindow (pw),
289
r->rectangle.x, r->rectangle.y,
290
r->rectangle.width + (r->rectangle.border_width << 1),
291
r->rectangle.height + (r->rectangle.border_width << 1),
297
if (unique_children != cache) XtFree((char *) unique_children);
298
} /* ManageChildren */
300
void XtManageChildren(children, num_children)
302
Cardinal num_children;
304
Widget parent, hookobj;
307
if (num_children == 0) return;
308
if (children[0] == NULL) {
309
XtWarningMsg(XtNinvalidChild, XtNxtManageChildren, XtCXtToolkitError,
310
"null child passed to XtManageChildren",
311
(String*)NULL, (Cardinal*)NULL);
314
app = XtWidgetToApplicationContext(children[0]);
316
parent = children[0]->core.parent;
317
if (parent->core.being_destroyed) {
321
ManageChildren(children, num_children, parent, (Boolean)False,
322
XtNxtManageChildren);
323
hookobj = XtHooksOfDisplay(XtDisplayOfObject(children[0]));
324
if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
325
XtChangeHookDataRec call_data;
327
call_data.type = XtHmanageChildren;
328
call_data.widget = parent;
329
call_data.event_data = (XtPointer) children;
330
call_data.num_event_data = num_children;
331
XtCallCallbackList(hookobj,
332
((HookObject)hookobj)->hooks.changehook_callbacks,
333
(XtPointer)&call_data);
336
} /* XtManageChildren */
338
void XtManageChild(child)
341
XtManageChildren(&child, (Cardinal) 1);
342
} /* XtManageChild */
345
#if NeedFunctionPrototypes
346
void XtSetMappedWhenManaged(
348
_XtBoolean mapped_when_managed
351
void XtSetMappedWhenManaged(widget, mapped_when_managed)
353
Boolean mapped_when_managed;
357
WIDGET_TO_APPCON(widget);
360
if (widget->core.mapped_when_managed == mapped_when_managed) {
364
widget->core.mapped_when_managed = mapped_when_managed;
366
hookobj = XtHooksOfDisplay(XtDisplay(widget));
367
if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
368
XtChangeHookDataRec call_data;
370
call_data.type = XtHsetMappedWhenManaged;
371
call_data.widget = widget;
372
call_data.event_data = (XtPointer) (unsigned long) mapped_when_managed;
373
XtCallCallbackList(hookobj,
374
((HookObject)hookobj)->hooks.changehook_callbacks,
375
(XtPointer)&call_data);
378
if (! XtIsManaged(widget)) {
383
if (mapped_when_managed) {
384
/* Didn't used to be mapped when managed. */
385
if (XtIsRealized(widget)) XtMapWidget(widget);
387
/* Used to be mapped when managed. */
388
if (XtIsRealized(widget)) XtUnmapWidget(widget);
391
} /* XtSetMappedWhenManaged */
394
#if NeedFunctionPrototypes
395
void XtChangeManagedSet(
396
WidgetList unmanage_children,
397
Cardinal num_unmanage,
398
XtDoChangeProc do_change_proc,
399
XtPointer client_data,
400
WidgetList manage_children,
404
void XtChangeManagedSet(unmanage_children, num_unmanage, do_change_proc,
405
client_data, manage_children, num_manage)
406
WidgetList unmanage_children;
407
Cardinal num_unmanage;
408
XtDoChangeProc do_change_proc;
409
XtPointer client_data;
410
WidgetList manage_children;
417
Cardinal some_unmanaged;
419
CompositeClassExtension ext;
422
XtChangeHookDataRec call_data;
424
if (num_unmanage == 0 && num_manage == 0)
427
/* specification doesn't state that library will check for NULL in list */
429
childp = num_unmanage ? unmanage_children : manage_children;
430
app = XtWidgetToApplicationContext(*childp);
433
parent = XtParent(*childp);
434
childp = unmanage_children;
435
for (i = num_unmanage; --i >= 0 && XtParent(*childp) == parent; childp++);
437
childp = manage_children;
438
for (i = num_manage; --i >= 0 && XtParent(*childp) == parent; childp++);
439
if (call_out || i >= 0) {
440
XtAppWarningMsg(app, "ambiguousParent", XtNxtChangeManagedSet,
441
XtCXtToolkitError, "Not all children have same parent",
442
(String *)NULL, (Cardinal *)NULL);
444
if (! XtIsComposite(parent)) {
446
XtAppErrorMsg(app, "invalidParent", XtNxtChangeManagedSet,
448
"Attempt to manage a child when parent is not Composite",
449
(String *) NULL, (Cardinal *) NULL);
451
if (parent->core.being_destroyed) {
457
if (do_change_proc) {
458
ext = (CompositeClassExtension)
459
XtGetClassExtension(parent->core.widget_class,
460
XtOffsetOf(CompositeClassRec,
461
composite_class.extension),
462
NULLQUARK, XtCompositeExtensionVersion,
463
sizeof(CompositeClassExtensionRec));
464
if (!ext || !ext->allows_change_managed_set)
468
UnmanageChildren(unmanage_children, num_unmanage, parent,
469
&some_unmanaged, call_out, XtNxtChangeManagedSet);
471
hookobj = XtHooksOfDisplay(XtDisplay(parent));
472
if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
473
call_data.type = XtHunmanageSet;
474
call_data.widget = parent;
475
call_data.event_data = (XtPointer) unmanage_children;
476
call_data.num_event_data = num_unmanage;
477
XtCallCallbackList(hookobj,
478
((HookObject)hookobj)->hooks.changehook_callbacks,
479
(XtPointer) &call_data);
483
(*do_change_proc)(parent, unmanage_children, &num_unmanage,
484
manage_children, &num_manage, client_data);
486
call_out = (some_unmanaged && !call_out);
487
ManageChildren(manage_children, num_manage, parent, call_out,
488
XtNxtChangeManagedSet);
490
if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
491
call_data.type = XtHmanageSet;
492
call_data.event_data = (XtPointer) manage_children;
493
call_data.num_event_data = num_manage;
494
XtCallCallbackList(hookobj,
495
((HookObject)hookobj)->hooks.changehook_callbacks,
496
(XtPointer) &call_data);
499
} /* XtChangeManagedSet */