Geometry.c revision 0568f49b
1/***********************************************************
2Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved.
3
4Permission is hereby granted, free of charge, to any person obtaining a
5copy of this software and associated documentation files (the "Software"),
6to deal in the Software without restriction, including without limitation
7the rights to use, copy, modify, merge, publish, distribute, sublicense,
8and/or sell copies of the Software, and to permit persons to whom the
9Software is furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice (including the next
12paragraph) shall be included in all copies or substantial portions of the
13Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21DEALINGS IN THE SOFTWARE.
22
23Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
24
25                        All Rights Reserved
26
27Permission to use, copy, modify, and distribute this software and its
28documentation for any purpose and without fee is hereby granted,
29provided that the above copyright notice appear in all copies and that
30both that copyright notice and this permission notice appear in
31supporting documentation, and that the name of Digital not be
32used in advertising or publicity pertaining to distribution of the
33software without specific, written prior permission.
34
35DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
36ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
37DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
38ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
39WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
40ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
41SOFTWARE.
42
43******************************************************************/
44
45/*
46
47Copyright 1987, 1988, 1994, 1998  The Open Group
48
49Permission to use, copy, modify, distribute, and sell this software and its
50documentation for any purpose is hereby granted without fee, provided that
51the above copyright notice appear in all copies and that both that
52copyright notice and this permission notice appear in supporting
53documentation.
54
55The above copyright notice and this permission notice shall be included in
56all copies or substantial portions of the Software.
57
58THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
61OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
62AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
63CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
64
65Except as contained in this notice, the name of The Open Group shall not be
66used in advertising or otherwise to promote the sale, use or other dealings
67in this Software without prior written authorization from The Open Group.
68
69*/
70
71#ifdef HAVE_CONFIG_H
72#include <config.h>
73#endif
74#include "IntrinsicI.h"
75#include "ShellP.h"
76#include "ShellI.h"
77
78static void ClearRectObjAreas(
79    RectObj r,
80    XWindowChanges* old)
81{
82    Widget pw = _XtWindowedAncestor((Widget)r);
83    int bw2;
84
85    bw2 = old->border_width << 1;
86    XClearArea( XtDisplay(pw), XtWindow(pw),
87		old->x, old->y,
88		(unsigned)(old->width + bw2), (unsigned)(old->height + bw2),
89		TRUE );
90
91    bw2 = r->rectangle.border_width << 1;
92    XClearArea( XtDisplay(pw), XtWindow(pw),
93		(int)r->rectangle.x, (int)r->rectangle.y,
94		(unsigned int)(r->rectangle.width + bw2),
95	        (unsigned int)(r->rectangle.height + bw2),
96		TRUE );
97}
98
99/*
100 * Internal function used by XtMakeGeometryRequest and XtSetValues.
101 * Returns more data than the public interface.  Does not convert
102 * XtGeometryDone to XtGeometryYes.
103 *
104 * clear_rect_obj - *** RETURNED ***
105 *		    TRUE if the rect obj has been cleared, false otherwise.
106 */
107
108XtGeometryResult
109_XtMakeGeometryRequest (
110    Widget widget,
111    XtWidgetGeometry *request,
112    XtWidgetGeometry *reply,
113    Boolean * clear_rect_obj)
114{
115    XtWidgetGeometry    junk;
116    XtGeometryHandler manager = (XtGeometryHandler) NULL;
117    XtGeometryResult returnCode;
118    Widget parent = widget->core.parent;
119    Boolean managed;
120    Boolean parentRealized = False;
121    Boolean rgm = False;
122    XtConfigureHookDataRec req;
123    Widget hookobj;
124
125    *clear_rect_obj = FALSE;
126
127    CALLGEOTAT(_XtGeoTrace(widget,
128	"\"%s\" is making a %sgeometry request to its parent \"%s\".\n",
129		   XtName(widget),
130		   ((request->request_mode & XtCWQueryOnly))? "query only ":"",
131		   (XtParent(widget))?XtName(XtParent(widget)):"Root"));
132    CALLGEOTAT(_XtGeoTab(1));
133
134    if (XtIsShell(widget)) {
135	ShellClassExtension ext;
136	LOCK_PROCESS;
137	for (ext = (ShellClassExtension)((ShellWidgetClass)XtClass(widget))
138		   ->shell_class.extension;
139	     ext != NULL && ext->record_type != NULLQUARK;
140	     ext = (ShellClassExtension)ext->next_extension);
141
142	if (ext != NULL) {
143	    if (  ext->version == XtShellExtensionVersion
144		  && ext->record_size == sizeof(ShellClassExtensionRec)) {
145		manager = ext->root_geometry_manager;
146		rgm = True;
147	    } else {
148		String params[1];
149		Cardinal num_params = 1;
150		params[0] = XtClass(widget)->core_class.class_name;
151		XtAppErrorMsg(XtWidgetToApplicationContext(widget),
152		     "invalidExtension", "xtMakeGeometryRequest",
153		     XtCXtToolkitError,
154		     "widget class %s has invalid ShellClassExtension record",
155		     params, &num_params);
156	    }
157	} else {
158	    XtAppErrorMsg(XtWidgetToApplicationContext(widget),
159			  "internalError", "xtMakeGeometryRequest",
160			  XtCXtToolkitError,
161			  "internal error; ShellClassExtension is NULL",
162			  NULL, NULL);
163	}
164	managed = True;
165	parentRealized = TRUE;
166	UNLOCK_PROCESS;
167    } else /* not shell */ {
168	if (parent == NULL) {
169	    XtAppErrorMsg(XtWidgetToApplicationContext(widget),
170			  "invalidParent","xtMakeGeometryRequest",
171			  XtCXtToolkitError,
172			  "non-shell has no parent in XtMakeGeometryRequest",
173			  NULL, NULL);
174	} else {
175	    managed = XtIsManaged(widget);
176	    parentRealized = XtIsRealized(parent);
177	    if (XtIsComposite(parent))
178	    {
179		LOCK_PROCESS;
180		manager = ((CompositeWidgetClass) (parent->core.widget_class))
181			  ->composite_class.geometry_manager;
182		UNLOCK_PROCESS;
183	    }
184	}
185    }
186
187#if 0
188    /*
189     * The Xt spec says that these conditions must generate
190     * error messages (not warnings), but many Xt applications
191     * and toolkits (including parts of Xaw, Motif and Netscape)
192     * depend on the previous Xt behaviour.  Thus, these tests
193     * should probably remain disabled.
194     */
195    if (parentRealized && managed) {
196	if (parent && !XtIsComposite(parent))
197	{
198	    /*
199	     * This shouldn't ever happen, we only test for this to pass
200	     * VSW5.  Normally managing the widget will catch this, but VSW5
201	     * does some really screwy stuff to get here.
202	     */
203	    XtAppErrorMsg(XtWidgetToApplicationContext(widget),
204			  "invalidParent", "xtMakeGeometryRequest",
205			  XtCXtToolkitError,
206			  "XtMakeGeometryRequest - parent not composite",
207			  NULL, NULL);
208	}
209	else if (manager == (XtGeometryHandler) NULL)
210	{
211	    XtAppErrorMsg(XtWidgetToApplicationContext(widget),
212			  "invalidGeometryManager","xtMakeGeometryRequest",
213			  XtCXtToolkitError,
214			  "XtMakeGeometryRequest - parent has no geometry manager",
215			  NULL, NULL);
216	}
217    }
218#else
219    if (!manager)
220	managed = False;
221#endif
222
223    if (widget->core.being_destroyed) {
224	CALLGEOTAT(_XtGeoTab(-1));
225	CALLGEOTAT(_XtGeoTrace(widget,
226		       "It is being destroyed, just return XtGeometryNo.\n"));
227	return XtGeometryNo;
228    }
229
230    /* see if requesting anything to change */
231    req.changeMask = 0;
232    if (request->request_mode & CWStackMode
233	&& request->stack_mode != XtSMDontChange) {
234	    req.changeMask |= CWStackMode;
235	    CALLGEOTAT(_XtGeoTrace(widget,
236				   "Asking for a change in StackMode!\n"));
237	    if (request->request_mode & CWSibling) {
238		XtCheckSubclass(request->sibling, rectObjClass,
239				"XtMakeGeometryRequest");
240		req.changeMask |= CWSibling;
241	    }
242    }
243    if (request->request_mode & CWX
244	&& widget->core.x != request->x) {
245	CALLGEOTAT(_XtGeoTrace(widget,
246			       "Asking for a change in x: from %d to %d.\n",
247			       widget->core.x, request->x));
248	req.changeMask |= CWX;
249    }
250    if (request->request_mode & CWY
251	&& widget->core.y != request->y) {
252	CALLGEOTAT(_XtGeoTrace(widget,
253			       "Asking for a change in y: from %d to %d.\n",
254			       widget->core.y, request->y));
255	req.changeMask |= CWY;
256    }
257    if (request->request_mode & CWWidth
258	&& widget->core.width != request->width) {
259	CALLGEOTAT(_XtGeoTrace(widget,"Asking for a change in width: from %d to %d.\n",
260		       widget->core.width, request->width));
261	req.changeMask |= CWWidth;
262    }
263    if (request->request_mode & CWHeight
264	&& widget->core.height != request->height) {
265	CALLGEOTAT(_XtGeoTrace(widget,
266			    "Asking for a change in height: from %d to %d.\n",
267			       widget->core.height, request->height));
268	req.changeMask |= CWHeight;
269    }
270    if (request->request_mode & CWBorderWidth
271	&& widget->core.border_width != request->border_width){
272	CALLGEOTAT(_XtGeoTrace(widget,
273		       "Asking for a change in border_width: from %d to %d.\n",
274		       widget->core.border_width, request->border_width));
275	req.changeMask |= CWBorderWidth;
276    }
277    if (! req.changeMask) {
278	CALLGEOTAT(_XtGeoTrace(widget,
279		       "Asking for nothing new,\n"));
280	CALLGEOTAT(_XtGeoTab(-1));
281	CALLGEOTAT(_XtGeoTrace(widget,
282		       "just return XtGeometryYes.\n"));
283	return XtGeometryYes;
284    }
285    req.changeMask |= (request->request_mode & XtCWQueryOnly);
286
287    if ( !(req.changeMask & XtCWQueryOnly) && XtIsRealized(widget) ) {
288	/* keep record of the current geometry so we know what's changed */
289	req.changes.x = widget->core.x ;
290	req.changes.y = widget->core.y ;
291	req.changes.width = widget->core.width ;
292	req.changes.height = widget->core.height ;
293	req.changes.border_width = widget->core.border_width ;
294    }
295
296    if (!managed || !parentRealized) {
297	CALLGEOTAT(_XtGeoTrace(widget,
298			       "Not Managed or Parent not realized.\n"));
299	/* Don't get parent's manager involved--assume the answer is yes */
300	if (req.changeMask & XtCWQueryOnly) {
301	    /* He was just asking, don't change anything, just tell him yes */
302	    CALLGEOTAT(_XtGeoTrace(widget,"QueryOnly request\n"));
303	    CALLGEOTAT(_XtGeoTab(-1));
304	    CALLGEOTAT(_XtGeoTrace(widget,"just return XtGeometryYes.\n"));
305	    return XtGeometryYes;
306	} else {
307	    CALLGEOTAT(_XtGeoTrace(widget,
308				   "Copy values from request to widget.\n"));
309	    /* copy values from request to widget */
310	    if (request->request_mode & CWX)
311		widget->core.x = request->x;
312	    if (request->request_mode & CWY)
313		widget->core.y = request->y;
314	    if (request->request_mode & CWWidth)
315		widget->core.width = request->width;
316	    if (request->request_mode & CWHeight)
317		widget->core.height = request->height;
318	    if (request->request_mode & CWBorderWidth)
319		widget->core.border_width = request->border_width;
320	    if (!parentRealized) {
321		CALLGEOTAT(_XtGeoTab(-1));
322		CALLGEOTAT(_XtGeoTrace(widget,"and return XtGeometryYes.\n"));
323		return XtGeometryYes;
324	    }
325	    else returnCode = XtGeometryYes;
326	}
327    } else {
328	/* go ask the widget's geometry manager */
329	CALLGEOTAT(_XtGeoTrace(widget,
330			       "Go ask the parent geometry manager.\n"));
331	if (reply == (XtWidgetGeometry *) NULL) {
332	    returnCode = (*manager)(widget, request, &junk);
333	} else {
334	    returnCode = (*manager)(widget, request, reply);
335	}
336    }
337
338    /*
339     * If Unrealized, not a XtGeometryYes, or a query-only then we are done.
340     */
341
342    if ((returnCode != XtGeometryYes) ||
343	(req.changeMask & XtCWQueryOnly) || !XtIsRealized(widget)) {
344
345#ifdef XT_GEO_TATTLER
346	switch(returnCode){
347	case XtGeometryNo:
348	    CALLGEOTAT(_XtGeoTab(-1));
349	    CALLGEOTAT(_XtGeoTrace(widget,"\"%s\" returns XtGeometryNo.\n",
350			  (XtParent(widget))?XtName(XtParent(widget)):"Root"));
351            /* check for no change */
352            break ;
353	case XtGeometryDone:
354	    CALLGEOTAT(_XtGeoTab(-1));
355	    CALLGEOTAT(_XtGeoTrace(widget,"\"%s\" returns XtGeometryDone.\n",
356		        (XtParent(widget))?XtName(XtParent(widget)):"Root"));
357            /* check for no change in queryonly */
358            break ;
359	case XtGeometryAlmost:
360	    CALLGEOTAT(_XtGeoTab(-1));
361	    CALLGEOTAT(_XtGeoTrace(widget,"\"%s\" returns XtGeometryAlmost.\n",
362			 (XtParent(widget))?XtName(XtParent(widget)):"Root"));
363	    CALLGEOTAT(_XtGeoTab(1));
364	    CALLGEOTAT(_XtGeoTrace(widget,"Proposal: width %d height %d.\n",
365			   (reply)?reply->width:junk.width,
366			   (reply)?reply->height:junk.height));
367	    CALLGEOTAT(_XtGeoTab(-1));
368
369            /* check for no change */
370            break ;
371	case XtGeometryYes:
372	    if (req.changeMask & XtCWQueryOnly) {
373		CALLGEOTAT(_XtGeoTrace(widget,
374				"QueryOnly specified, no configuration.\n"));
375	    }
376            if (!XtIsRealized(widget)) {
377		CALLGEOTAT(_XtGeoTrace(widget,
378				 "\"%s\" not realized, no configuration.\n",
379				 XtName(widget)));
380	    }
381	    CALLGEOTAT(_XtGeoTab(-1));
382            CALLGEOTAT(_XtGeoTrace(widget,"\"%s\" returns XtGeometryYes.\n",
383                         (XtParent(widget))?XtName(XtParent(widget)):"Root"));
384	    break ;
385	}
386#endif
387	return returnCode;
388    }
389
390    CALLGEOTAT(_XtGeoTab(-1));
391    CALLGEOTAT(_XtGeoTrace(widget,"\"%s\" returns XtGeometryYes.\n",
392		   (XtParent(widget))?XtName(XtParent(widget)):"Root"));
393
394    if (XtIsWidget(widget)) {	/* reconfigure the window (if needed) */
395
396	if (rgm) return returnCode;
397
398	if (req.changes.x != widget->core.x) {
399 	    req.changeMask |= CWX;
400 	    req.changes.x = widget->core.x;
401	    CALLGEOTAT(_XtGeoTrace(widget,
402				   "x changing to %d\n",widget->core.x));
403 	}
404 	if (req.changes.y != widget->core.y) {
405 	    req.changeMask |= CWY;
406 	    req.changes.y = widget->core.y;
407	    CALLGEOTAT(_XtGeoTrace(widget,
408				   "y changing to %d\n",widget->core.y));
409 	}
410 	if (req.changes.width != widget->core.width) {
411 	    req.changeMask |= CWWidth;
412 	    req.changes.width = widget->core.width;
413	    CALLGEOTAT(_XtGeoTrace(widget,
414				 "width changing to %d\n",widget->core.width));
415 	}
416 	if (req.changes.height != widget->core.height) {
417 	    req.changeMask |= CWHeight;
418 	    req.changes.height = widget->core.height;
419	    CALLGEOTAT(_XtGeoTrace(widget,
420                               "height changing to %d\n",widget->core.height));
421 	}
422 	if (req.changes.border_width != widget->core.border_width) {
423 	    req.changeMask |= CWBorderWidth;
424 	    req.changes.border_width = widget->core.border_width;
425	    CALLGEOTAT(_XtGeoTrace(widget,
426				   "border_width changing to %d\n",
427				   widget->core.border_width));
428 	}
429	if (req.changeMask & CWStackMode) {
430	    req.changes.stack_mode = request->stack_mode;
431	    CALLGEOTAT(_XtGeoTrace(widget,"stack_mode changing\n"));
432	    if (req.changeMask & CWSibling) {
433		if (XtIsWidget(request->sibling))
434		    req.changes.sibling = XtWindow(request->sibling);
435		else
436		    req.changeMask = (XtGeometryMask) (req.changeMask & (unsigned long) (~(CWStackMode | CWSibling)));
437	    }
438	}
439
440#ifdef XT_GEO_TATTLER
441        if (req.changeMask) {
442	    CALLGEOTAT(_XtGeoTrace(widget,
443				   "XConfigure \"%s\"'s window.\n",
444				   XtName(widget)));
445	} else {
446	    CALLGEOTAT(_XtGeoTrace(widget,
447			     "No window configuration needed for \"%s\".\n",
448			     XtName(widget)));
449	}
450#endif
451
452	XConfigureWindow(XtDisplay(widget), XtWindow(widget),
453			 req.changeMask, &req.changes);
454    }
455    else {			/* RectObj child of realized Widget */
456	*clear_rect_obj = TRUE;
457	CALLGEOTAT(_XtGeoTrace(widget,
458			       "ClearRectObj on \"%s\".\n",XtName(widget)));
459
460	ClearRectObjAreas((RectObj)widget, &req.changes);
461    }
462    hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
463    if (XtHasCallbacks(hookobj, XtNconfigureHook) == XtCallbackHasSome) {
464	req.type = XtHconfigure;
465	req.widget = widget;
466	XtCallCallbackList(hookobj,
467		((HookObject)hookobj)->hooks.confighook_callbacks,
468		(XtPointer)&req);
469    }
470
471    return returnCode;
472} /* _XtMakeGeometryRequest */
473
474
475/* Public routines */
476
477XtGeometryResult XtMakeGeometryRequest (
478    Widget         widget,
479    XtWidgetGeometry *request,
480    XtWidgetGeometry *reply)
481{
482    Boolean junk;
483    XtGeometryResult r;
484    XtGeometryHookDataRec call_data;
485    Widget hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
486    WIDGET_TO_APPCON(widget);
487
488    LOCK_APP(app);
489    if (XtHasCallbacks(hookobj, XtNgeometryHook) == XtCallbackHasSome) {
490	call_data.type = XtHpreGeometry;
491	call_data.widget = widget;
492	call_data.request = request;
493	XtCallCallbackList(hookobj,
494		((HookObject)hookobj)->hooks.geometryhook_callbacks,
495		(XtPointer)&call_data);
496	call_data.result = r =
497	    _XtMakeGeometryRequest(widget, request, reply, &junk);
498	call_data.type = XtHpostGeometry;
499	call_data.reply = reply;
500	XtCallCallbackList(hookobj,
501		((HookObject)hookobj)->hooks.geometryhook_callbacks,
502		(XtPointer)&call_data);
503    } else {
504	r = _XtMakeGeometryRequest(widget, request, reply, &junk);
505    }
506    UNLOCK_APP(app);
507
508    return ((r == XtGeometryDone) ? XtGeometryYes : r);
509}
510
511XtGeometryResult
512XtMakeResizeRequest(
513    Widget	widget,
514    _XtDimension width,
515    _XtDimension height,
516    Dimension	*replyWidth,
517    Dimension	*replyHeight)
518{
519    XtWidgetGeometry request, reply;
520    XtGeometryResult r;
521    XtGeometryHookDataRec call_data;
522    Boolean junk;
523    Widget hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
524    WIDGET_TO_APPCON(widget);
525
526    LOCK_APP(app);
527    request.request_mode = CWWidth | CWHeight;
528    request.width = (Dimension) width;
529    request.height = (Dimension) height;
530
531    if (XtHasCallbacks(hookobj, XtNgeometryHook) == XtCallbackHasSome) {
532	call_data.type = XtHpreGeometry;
533	call_data.widget = widget;
534	call_data.request = &request;
535	XtCallCallbackList(hookobj,
536		((HookObject)hookobj)->hooks.geometryhook_callbacks,
537		(XtPointer)&call_data);
538	call_data.result = r =
539	    _XtMakeGeometryRequest(widget, &request, &reply, &junk);
540	call_data.type = XtHpostGeometry;
541	call_data.reply = &reply;
542	XtCallCallbackList(hookobj,
543		((HookObject)hookobj)->hooks.geometryhook_callbacks,
544		(XtPointer)&call_data);
545    } else {
546	r = _XtMakeGeometryRequest(widget, &request, &reply, &junk);
547    }
548    if (replyWidth != NULL) {
549	if (r == XtGeometryAlmost && reply.request_mode & CWWidth)
550	    *replyWidth = reply.width;
551	else
552	    *replyWidth = (Dimension) width;
553    }
554    if (replyHeight != NULL) {
555	if (r == XtGeometryAlmost && reply.request_mode & CWHeight)
556	    *replyHeight = reply.height;
557	else
558	    *replyHeight = (Dimension) height;
559    }
560    UNLOCK_APP(app);
561    return ((r == XtGeometryDone) ? XtGeometryYes : r);
562} /* XtMakeResizeRequest */
563
564void XtResizeWindow(
565    Widget w)
566{
567    XtConfigureHookDataRec req;
568    WIDGET_TO_APPCON(w);
569
570    LOCK_APP(app);
571    if (XtIsRealized(w)) {
572        Widget hookobj;
573
574	req.changes.width = w->core.width;
575	req.changes.height = w->core.height;
576	req.changes.border_width = w->core.border_width;
577	req.changeMask = CWWidth | CWHeight | CWBorderWidth;
578	XConfigureWindow(XtDisplay(w), XtWindow(w),
579	    (unsigned) req.changeMask, &req.changes);
580	hookobj = XtHooksOfDisplay(XtDisplayOfObject(w));
581	if (XtHasCallbacks(hookobj, XtNconfigureHook) == XtCallbackHasSome) {
582	    req.type = XtHconfigure;
583	    req.widget = w;
584	    XtCallCallbackList(hookobj,
585			((HookObject)hookobj)->hooks.confighook_callbacks,
586			(XtPointer)&req);
587	}
588    }
589    UNLOCK_APP(app);
590} /* XtResizeWindow */
591
592void XtResizeWidget(
593    Widget w,
594    _XtDimension width,
595    _XtDimension height,
596    _XtDimension borderWidth)
597{
598    XtConfigureWidget(w, w->core.x, w->core.y, width, height, borderWidth);
599} /* XtResizeWidget */
600
601void XtConfigureWidget(
602    Widget w,
603    _XtPosition x,
604    _XtPosition y,
605    _XtDimension width,
606    _XtDimension height,
607    _XtDimension borderWidth)
608{
609    XtConfigureHookDataRec req;
610    XWindowChanges old;
611    WIDGET_TO_APPCON(w);
612
613    CALLGEOTAT(_XtGeoTrace(w,
614                   "\"%s\" is being configured by its parent \"%s\"\n",
615		   XtName(w),
616		   (XtParent(w))?XtName(XtParent(w)):"Root"));
617    CALLGEOTAT(_XtGeoTab(1));
618
619    LOCK_APP(app);
620    req.changeMask = 0;
621    if ((old.x = w->core.x) != x) {
622	CALLGEOTAT(_XtGeoTrace(w,"x move from %d to %d\n",w->core.x, x));
623	req.changes.x = w->core.x = (Position) x;
624	req.changeMask |= CWX;
625    }
626
627    if ((old.y = w->core.y) != y) {
628	CALLGEOTAT(_XtGeoTrace(w,"y move from %d to %d\n",w->core.y, y));
629	req.changes.y = w->core.y = (Position) y;
630	req.changeMask |= CWY;
631    }
632
633    if ((old.width = w->core.width) != width) {
634	CALLGEOTAT(_XtGeoTrace(w,
635			 "width move from %d to %d\n",w->core.width, width));
636	req.changes.width = w->core.width = (Dimension) width;
637	req.changeMask |= CWWidth;
638    }
639
640    if ((old.height = w->core.height) != height) {
641	CALLGEOTAT(_XtGeoTrace(w,
642		       "height move from %d to %d\n",w->core.height, height));
643	req.changes.height = w->core.height = (Dimension) height;
644	req.changeMask |= CWHeight;
645    }
646
647    if ((old.border_width = w->core.border_width) != borderWidth) {
648	CALLGEOTAT(_XtGeoTrace(w,"border_width move from %d to %d\n",
649		    w->core.border_width,borderWidth ));
650	req.changes.border_width = w->core.border_width = (Dimension) borderWidth;
651	req.changeMask |= CWBorderWidth;
652    }
653
654    if (req.changeMask != 0) {
655        Widget hookobj;
656
657	if (XtIsRealized(w)) {
658	    if (XtIsWidget(w)) {
659		CALLGEOTAT(_XtGeoTrace(w,
660                                  "XConfigure \"%s\"'s window\n",XtName(w)));
661		XConfigureWindow(XtDisplay(w), XtWindow(w),
662				 req.changeMask, &req.changes);
663	    } else {
664		CALLGEOTAT(_XtGeoTrace(w,
665			       "ClearRectObj called on \"%s\"\n",XtName(w)));
666		ClearRectObjAreas((RectObj)w, &old);
667	    }
668	}
669	hookobj = XtHooksOfDisplay(XtDisplayOfObject(w));
670	if (XtHasCallbacks(hookobj, XtNconfigureHook) == XtCallbackHasSome) {
671	    req.type = XtHconfigure;
672	    req.widget = w;
673	    XtCallCallbackList(hookobj,
674			((HookObject)hookobj)->hooks.confighook_callbacks,
675			(XtPointer)&req);
676	}
677	{
678	XtWidgetProc resize;
679
680	LOCK_PROCESS;
681	resize = XtClass(w)->core_class.resize;
682	UNLOCK_PROCESS;
683	if ((req.changeMask & (CWWidth | CWHeight)) &&
684	    resize != (XtWidgetProc) NULL) {
685	    CALLGEOTAT(_XtGeoTrace(w,"Resize proc is called.\n"));
686	    (*resize)(w);
687	 }
688	}
689    } else {
690	CALLGEOTAT(_XtGeoTrace(w,"No change in configuration\n"));
691    }
692
693    CALLGEOTAT(_XtGeoTab(-1));
694    UNLOCK_APP(app);
695} /* XtConfigureWidget */
696
697void XtMoveWidget(
698    Widget w,
699    _XtPosition x,
700    _XtPosition y)
701{
702    XtConfigureWidget(w, x, y, w->core.width, w->core.height,
703		      w->core.border_width);
704} /* XtMoveWidget */
705
706void XtTranslateCoords(
707    register Widget w,
708    _XtPosition x,
709    _XtPosition y,
710    register Position *rootx,	/* return */
711    register Position *rooty)	/* return */
712{
713    Position garbagex, garbagey;
714    XtAppContext app = XtWidgetToApplicationContext(w);
715
716    LOCK_APP(app);
717    if (rootx == NULL) rootx = &garbagex;
718    if (rooty == NULL) rooty = &garbagey;
719
720    *rootx = (Position) x;
721    *rooty = (Position) y;
722
723    for (; w != NULL && ! XtIsShell(w); w = w->core.parent) {
724	*rootx = (Position) (*rootx + w->core.x + w->core.border_width);
725	*rooty = (Position) (*rooty + w->core.y + w->core.border_width);
726    }
727
728    if (w == NULL)
729        XtAppWarningMsg(app,
730		"invalidShell","xtTranslateCoords",XtCXtToolkitError,
731                "Widget has no shell ancestor",
732		NULL, NULL);
733    else {
734	Position x2, y2;
735	_XtShellGetCoordinates( w, &x2, &y2 );
736	*rootx = (Position) (*rootx + x2 + w->core.border_width);
737	*rooty = (Position) (*rooty + y2 + w->core.border_width);
738    }
739    UNLOCK_APP(app);
740}
741
742XtGeometryResult XtQueryGeometry(
743    Widget widget,
744    register XtWidgetGeometry *intended, /* parent's changes; may be NULL */
745    XtWidgetGeometry *reply)	/* child's preferred geometry; never NULL */
746{
747    XtWidgetGeometry null_intended;
748    XtGeometryHandler query;
749    XtGeometryResult result;
750    WIDGET_TO_APPCON(widget);
751
752    CALLGEOTAT(_XtGeoTrace(widget,
753		     "\"%s\" is asking its preferred geometry to \"%s\".\n",
754		     (XtParent(widget))?XtName(XtParent(widget)):"Root",
755		     XtName(widget)));
756    CALLGEOTAT(_XtGeoTab(1));
757
758    LOCK_APP(app);
759    LOCK_PROCESS;
760    query = XtClass(widget)->core_class.query_geometry;
761    UNLOCK_PROCESS;
762    reply->request_mode = 0;
763    if (query != NULL) {
764	if (intended == NULL) {
765	    null_intended.request_mode = 0;
766	    intended = &null_intended;
767#ifdef XT_GEO_TATTLER
768	    CALLGEOTAT(_XtGeoTrace(widget,"without any constraint.\n"));
769	} else {
770	    CALLGEOTAT(_XtGeoTrace(widget,
771				   "with the following constraints:\n"));
772
773	    if (intended->request_mode & CWX) {
774		CALLGEOTAT(_XtGeoTrace(widget," x = %d\n",intended->x));
775	    }
776	    if (intended->request_mode & CWY) {
777		CALLGEOTAT(_XtGeoTrace(widget," y = %d\n",intended->y));
778	    }
779	    if (intended->request_mode & CWWidth) {
780		CALLGEOTAT(_XtGeoTrace(widget,
781				       " width = %d\n",intended->width));
782	    }
783	    if (intended->request_mode & CWHeight) {
784		CALLGEOTAT(_XtGeoTrace(widget,
785				       " height = %d\n",intended->height));
786	    }
787	    if (intended->request_mode & CWBorderWidth) {
788		CALLGEOTAT(_XtGeoTrace(widget,
789			       " border_width = %d\n",intended->border_width));
790	    }
791#endif
792	}
793
794	result = (*query) (widget, intended, reply);
795    }
796    else {
797	CALLGEOTAT(_XtGeoTrace(widget,"\"%s\" has no QueryGeometry proc, return the current state\n",XtName(widget)));
798
799	result = XtGeometryYes;
800    }
801
802#ifdef XT_GEO_TATTLER
803#define FillIn(mask, field) \
804	if (!(reply->request_mode & mask)) {\
805	      reply->field = widget->core.field;\
806	      _XtGeoTrace(widget," using core %s = %d.\n","field",\
807			                               widget->core.field);\
808	} else {\
809	      _XtGeoTrace(widget," replied %s = %d\n","field",\
810			                           reply->field);\
811	}
812#else
813#define FillIn(mask, field) \
814	if (!(reply->request_mode & mask)) reply->field = widget->core.field;
815#endif
816
817    FillIn(CWX, x);
818    FillIn(CWY, y);
819    FillIn(CWWidth, width);
820    FillIn(CWHeight, height);
821    FillIn(CWBorderWidth, border_width);
822
823    CALLGEOTAT(_XtGeoTab(-1));
824#undef FillIn
825
826    if (!(reply->request_mode & CWStackMode))
827	reply->stack_mode = XtSMDontChange;
828    UNLOCK_APP(app);
829    return result;
830}
831