Geometry.c revision 444c061a
1444c061aSmrg/* $Xorg: Geometry.c,v 1.5 2001/02/09 02:03:54 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
36444c061aSmrg/*
37444c061aSmrg
38444c061aSmrgCopyright 1987, 1988, 1994, 1998  The Open Group
39444c061aSmrg
40444c061aSmrgPermission to use, copy, modify, distribute, and sell this software and its
41444c061aSmrgdocumentation for any purpose is hereby granted without fee, provided that
42444c061aSmrgthe above copyright notice appear in all copies and that both that
43444c061aSmrgcopyright notice and this permission notice appear in supporting
44444c061aSmrgdocumentation.
45444c061aSmrg
46444c061aSmrgThe above copyright notice and this permission notice shall be included in
47444c061aSmrgall copies or substantial portions of the Software.
48444c061aSmrg
49444c061aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50444c061aSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51444c061aSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
52444c061aSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
53444c061aSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
54444c061aSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
55444c061aSmrg
56444c061aSmrgExcept as contained in this notice, the name of The Open Group shall not be
57444c061aSmrgused in advertising or otherwise to promote the sale, use or other dealings
58444c061aSmrgin this Software without prior written authorization from The Open Group.
59444c061aSmrg
60444c061aSmrg*/
61444c061aSmrg/* $XFree86: xc/lib/Xt/Geometry.c,v 1.12 2001/12/14 19:56:15 dawes Exp $ */
62444c061aSmrg
63444c061aSmrg#ifdef HAVE_CONFIG_H
64444c061aSmrg#include <config.h>
65444c061aSmrg#endif
66444c061aSmrg#include "IntrinsicI.h"
67444c061aSmrg#include "ShellP.h"
68444c061aSmrg#include "ShellI.h"
69444c061aSmrg
70444c061aSmrgstatic void ClearRectObjAreas(
71444c061aSmrg    RectObj r,
72444c061aSmrg    XWindowChanges* old)
73444c061aSmrg{
74444c061aSmrg    Widget pw = _XtWindowedAncestor((Widget)r);
75444c061aSmrg    int bw2;
76444c061aSmrg
77444c061aSmrg    bw2 = old->border_width << 1;
78444c061aSmrg    XClearArea( XtDisplay(pw), XtWindow(pw),
79444c061aSmrg		old->x, old->y,
80444c061aSmrg		old->width + bw2, old->height + bw2,
81444c061aSmrg		TRUE );
82444c061aSmrg
83444c061aSmrg    bw2 = r->rectangle.border_width << 1;
84444c061aSmrg    XClearArea( XtDisplay(pw), XtWindow(pw),
85444c061aSmrg		(int)r->rectangle.x, (int)r->rectangle.y,
86444c061aSmrg		(unsigned int)(r->rectangle.width + bw2),
87444c061aSmrg	        (unsigned int)(r->rectangle.height + bw2),
88444c061aSmrg		TRUE );
89444c061aSmrg}
90444c061aSmrg
91444c061aSmrg/*
92444c061aSmrg * Internal function used by XtMakeGeometryRequest and XtSetValues.
93444c061aSmrg * Returns more data than the public interface.  Does not convert
94444c061aSmrg * XtGeometryDone to XtGeometryYes.
95444c061aSmrg *
96444c061aSmrg * clear_rect_obj - *** RETURNED ***
97444c061aSmrg *		    TRUE if the rect obj has been cleared, false otherwise.
98444c061aSmrg */
99444c061aSmrg
100444c061aSmrgXtGeometryResult
101444c061aSmrg_XtMakeGeometryRequest (
102444c061aSmrg    Widget widget,
103444c061aSmrg    XtWidgetGeometry *request,
104444c061aSmrg    XtWidgetGeometry *reply,
105444c061aSmrg    Boolean * clear_rect_obj)
106444c061aSmrg{
107444c061aSmrg    XtWidgetGeometry    junk;
108444c061aSmrg    XtGeometryHandler manager = (XtGeometryHandler) NULL;
109444c061aSmrg    XtGeometryResult returnCode;
110444c061aSmrg    Widget parent = widget->core.parent;
111444c061aSmrg    Boolean managed, parentRealized, rgm = False;
112444c061aSmrg    XtConfigureHookDataRec req;
113444c061aSmrg    Widget hookobj;
114444c061aSmrg
115444c061aSmrg    *clear_rect_obj = FALSE;
116444c061aSmrg
117444c061aSmrg    CALLGEOTAT(_XtGeoTrace(widget,
118444c061aSmrg	"\"%s\" is making a %sgeometry request to its parent \"%s\".\n",
119444c061aSmrg		   XtName(widget),
120444c061aSmrg		   ((request->request_mode & XtCWQueryOnly))? "query only ":"",
121444c061aSmrg		   (XtParent(widget))?XtName(XtParent(widget)):"Root"));
122444c061aSmrg    CALLGEOTAT(_XtGeoTab(1));
123444c061aSmrg
124444c061aSmrg    if (XtIsShell(widget)) {
125444c061aSmrg	ShellClassExtension ext;
126444c061aSmrg	LOCK_PROCESS;
127444c061aSmrg	for (ext = (ShellClassExtension)((ShellWidgetClass)XtClass(widget))
128444c061aSmrg		   ->shell_class.extension;
129444c061aSmrg	     ext != NULL && ext->record_type != NULLQUARK;
130444c061aSmrg	     ext = (ShellClassExtension)ext->next_extension);
131444c061aSmrg
132444c061aSmrg	if (ext != NULL) {
133444c061aSmrg	    if (  ext->version == XtShellExtensionVersion
134444c061aSmrg		  && ext->record_size == sizeof(ShellClassExtensionRec)) {
135444c061aSmrg		manager = ext->root_geometry_manager;
136444c061aSmrg		rgm = True;
137444c061aSmrg	    } else {
138444c061aSmrg		String params[1];
139444c061aSmrg		Cardinal num_params = 1;
140444c061aSmrg		params[0] = XtClass(widget)->core_class.class_name;
141444c061aSmrg		XtAppErrorMsg(XtWidgetToApplicationContext(widget),
142444c061aSmrg		     "invalidExtension", "xtMakeGeometryRequest",
143444c061aSmrg		     XtCXtToolkitError,
144444c061aSmrg		     "widget class %s has invalid ShellClassExtension record",
145444c061aSmrg		     params, &num_params);
146444c061aSmrg	    }
147444c061aSmrg	} else {
148444c061aSmrg	    XtAppErrorMsg(XtWidgetToApplicationContext(widget),
149444c061aSmrg			  "internalError", "xtMakeGeometryRequest",
150444c061aSmrg			  XtCXtToolkitError,
151444c061aSmrg			  "internal error; ShellClassExtension is NULL",
152444c061aSmrg			  NULL, NULL);
153444c061aSmrg	}
154444c061aSmrg	managed = True;
155444c061aSmrg	parentRealized = TRUE;
156444c061aSmrg	UNLOCK_PROCESS;
157444c061aSmrg    } else /* not shell */ {
158444c061aSmrg	if (parent == NULL)
159444c061aSmrg	    XtAppErrorMsg(XtWidgetToApplicationContext(widget),
160444c061aSmrg			  "invalidParent","xtMakeGeometryRequest",
161444c061aSmrg			  XtCXtToolkitError,
162444c061aSmrg			  "non-shell has no parent in XtMakeGeometryRequest",
163444c061aSmrg			  (String *)NULL, (Cardinal *)NULL);
164444c061aSmrg
165444c061aSmrg	managed = XtIsManaged(widget);
166444c061aSmrg	parentRealized = XtIsRealized(parent);
167444c061aSmrg	if (XtIsComposite(parent))
168444c061aSmrg	{
169444c061aSmrg	    LOCK_PROCESS;
170444c061aSmrg	    manager = ((CompositeWidgetClass) (parent->core.widget_class))
171444c061aSmrg		      ->composite_class.geometry_manager;
172444c061aSmrg	    UNLOCK_PROCESS;
173444c061aSmrg	}
174444c061aSmrg    }
175444c061aSmrg
176444c061aSmrg#if 0
177444c061aSmrg    /*
178444c061aSmrg     * The Xt spec says that these conditions must generate
179444c061aSmrg     * error messages (not warnings), but many Xt applications
180444c061aSmrg     * and toolkits (including parts of Xaw, Motif and Netscape)
181444c061aSmrg     * depend on the previous Xt behaviour.  Thus, these tests
182444c061aSmrg     * should probably remain disabled.
183444c061aSmrg     */
184444c061aSmrg    if (parentRealized && managed) {
185444c061aSmrg	if (parent && !XtIsComposite(parent))
186444c061aSmrg	{
187444c061aSmrg	    /*
188444c061aSmrg	     * This shouldn't ever happen, we only test for this to pass
189444c061aSmrg	     * VSW5.  Normally managing the widget will catch this, but VSW5
190444c061aSmrg	     * does some really screwy stuff to get here.
191444c061aSmrg	     */
192444c061aSmrg	    XtAppErrorMsg(XtWidgetToApplicationContext(widget),
193444c061aSmrg			  "invalidParent", "xtMakeGeometryRequest",
194444c061aSmrg			  XtCXtToolkitError,
195444c061aSmrg			  "XtMakeGeometryRequest - parent not composite",
196444c061aSmrg			  (String *)NULL, (Cardinal *)NULL);
197444c061aSmrg	}
198444c061aSmrg	else if (manager == (XtGeometryHandler) NULL)
199444c061aSmrg	{
200444c061aSmrg	    XtAppErrorMsg(XtWidgetToApplicationContext(widget),
201444c061aSmrg			  "invalidGeometryManager","xtMakeGeometryRequest",
202444c061aSmrg			  XtCXtToolkitError,
203444c061aSmrg			  "XtMakeGeometryRequest - parent has no geometry manager",
204444c061aSmrg			  (String *)NULL, (Cardinal *)NULL);
205444c061aSmrg	}
206444c061aSmrg    }
207444c061aSmrg#else
208444c061aSmrg    if (!manager)
209444c061aSmrg	managed = False;
210444c061aSmrg#endif
211444c061aSmrg
212444c061aSmrg    if (widget->core.being_destroyed) {
213444c061aSmrg	CALLGEOTAT(_XtGeoTab(-1));
214444c061aSmrg	CALLGEOTAT(_XtGeoTrace(widget,
215444c061aSmrg		       "It is being destroyed, just return XtGeometryNo.\n"));
216444c061aSmrg	return XtGeometryNo;
217444c061aSmrg    }
218444c061aSmrg
219444c061aSmrg    /* see if requesting anything to change */
220444c061aSmrg    req.changeMask = 0;
221444c061aSmrg    if (request->request_mode & CWStackMode
222444c061aSmrg	&& request->stack_mode != XtSMDontChange) {
223444c061aSmrg	    req.changeMask |= CWStackMode;
224444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(widget,
225444c061aSmrg				   "Asking for a change in StackMode!\n"));
226444c061aSmrg	    if (request->request_mode & CWSibling) {
227444c061aSmrg		XtCheckSubclass(request->sibling, rectObjClass,
228444c061aSmrg				"XtMakeGeometryRequest");
229444c061aSmrg		req.changeMask |= CWSibling;
230444c061aSmrg	    }
231444c061aSmrg    }
232444c061aSmrg    if (request->request_mode & CWX
233444c061aSmrg	&& widget->core.x != request->x) {
234444c061aSmrg	CALLGEOTAT(_XtGeoTrace(widget,
235444c061aSmrg			       "Asking for a change in x: from %d to %d.\n",
236444c061aSmrg			       widget->core.x, request->x));
237444c061aSmrg	req.changeMask |= CWX;
238444c061aSmrg    }
239444c061aSmrg    if (request->request_mode & CWY
240444c061aSmrg	&& widget->core.y != request->y) {
241444c061aSmrg	CALLGEOTAT(_XtGeoTrace(widget,
242444c061aSmrg			       "Asking for a change in y: from %d to %d.\n",
243444c061aSmrg			       widget->core.y, request->y));
244444c061aSmrg	req.changeMask |= CWY;
245444c061aSmrg    }
246444c061aSmrg    if (request->request_mode & CWWidth
247444c061aSmrg	&& widget->core.width != request->width) {
248444c061aSmrg	CALLGEOTAT(_XtGeoTrace(widget,"Asking for a change in width: from %d to %d.\n",
249444c061aSmrg		       widget->core.width, request->width));
250444c061aSmrg	req.changeMask |= CWWidth;
251444c061aSmrg    }
252444c061aSmrg    if (request->request_mode & CWHeight
253444c061aSmrg	&& widget->core.height != request->height) {
254444c061aSmrg	CALLGEOTAT(_XtGeoTrace(widget,
255444c061aSmrg			    "Asking for a change in height: from %d to %d.\n",
256444c061aSmrg			       widget->core.height, request->height));
257444c061aSmrg	req.changeMask |= CWHeight;
258444c061aSmrg    }
259444c061aSmrg    if (request->request_mode & CWBorderWidth
260444c061aSmrg	&& widget->core.border_width != request->border_width){
261444c061aSmrg	CALLGEOTAT(_XtGeoTrace(widget,
262444c061aSmrg		       "Asking for a change in border_width: from %d to %d.\n",
263444c061aSmrg		       widget->core.border_width, request->border_width));
264444c061aSmrg	req.changeMask |= CWBorderWidth;
265444c061aSmrg    }
266444c061aSmrg    if (! req.changeMask) {
267444c061aSmrg	CALLGEOTAT(_XtGeoTrace(widget,
268444c061aSmrg		       "Asking for nothing new,\n"));
269444c061aSmrg	CALLGEOTAT(_XtGeoTab(-1));
270444c061aSmrg	CALLGEOTAT(_XtGeoTrace(widget,
271444c061aSmrg		       "just return XtGeometryYes.\n"));
272444c061aSmrg	return XtGeometryYes;
273444c061aSmrg    }
274444c061aSmrg    req.changeMask |= (request->request_mode & XtCWQueryOnly);
275444c061aSmrg
276444c061aSmrg    if ( !(req.changeMask & XtCWQueryOnly) && XtIsRealized(widget) ) {
277444c061aSmrg	/* keep record of the current geometry so we know what's changed */
278444c061aSmrg	req.changes.x = widget->core.x ;
279444c061aSmrg	req.changes.y = widget->core.y ;
280444c061aSmrg	req.changes.width = widget->core.width ;
281444c061aSmrg	req.changes.height = widget->core.height ;
282444c061aSmrg	req.changes.border_width = widget->core.border_width ;
283444c061aSmrg    }
284444c061aSmrg
285444c061aSmrg    if (!managed || !parentRealized) {
286444c061aSmrg	CALLGEOTAT(_XtGeoTrace(widget,
287444c061aSmrg			       "Not Managed or Parent not realized.\n"));
288444c061aSmrg	/* Don't get parent's manager involved--assume the answer is yes */
289444c061aSmrg	if (req.changeMask & XtCWQueryOnly) {
290444c061aSmrg	    /* He was just asking, don't change anything, just tell him yes */
291444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(widget,"QueryOnly request\n"));
292444c061aSmrg	    CALLGEOTAT(_XtGeoTab(-1));
293444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(widget,"just return XtGeometryYes.\n"));
294444c061aSmrg	    return XtGeometryYes;
295444c061aSmrg	} else {
296444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(widget,
297444c061aSmrg				   "Copy values from request to widget.\n"));
298444c061aSmrg	    /* copy values from request to widget */
299444c061aSmrg	    if (request->request_mode & CWX)
300444c061aSmrg		widget->core.x = request->x;
301444c061aSmrg	    if (request->request_mode & CWY)
302444c061aSmrg		widget->core.y = request->y;
303444c061aSmrg	    if (request->request_mode & CWWidth)
304444c061aSmrg		widget->core.width = request->width;
305444c061aSmrg	    if (request->request_mode & CWHeight)
306444c061aSmrg		widget->core.height = request->height;
307444c061aSmrg	    if (request->request_mode & CWBorderWidth)
308444c061aSmrg		widget->core.border_width = request->border_width;
309444c061aSmrg	    if (!parentRealized) {
310444c061aSmrg		CALLGEOTAT(_XtGeoTab(-1));
311444c061aSmrg		CALLGEOTAT(_XtGeoTrace(widget,"and return XtGeometryYes.\n"));
312444c061aSmrg		return XtGeometryYes;
313444c061aSmrg	    }
314444c061aSmrg	    else returnCode = XtGeometryYes;
315444c061aSmrg	}
316444c061aSmrg    } else {
317444c061aSmrg	/* go ask the widget's geometry manager */
318444c061aSmrg	CALLGEOTAT(_XtGeoTrace(widget,
319444c061aSmrg			       "Go ask the parent geometry manager.\n"));
320444c061aSmrg	if (reply == (XtWidgetGeometry *) NULL) {
321444c061aSmrg	    returnCode = (*manager)(widget, request, &junk);
322444c061aSmrg	} else {
323444c061aSmrg	    returnCode = (*manager)(widget, request, reply);
324444c061aSmrg	}
325444c061aSmrg    }
326444c061aSmrg
327444c061aSmrg    /*
328444c061aSmrg     * If Unrealized, not a XtGeometryYes, or a query-only then we are done.
329444c061aSmrg     */
330444c061aSmrg
331444c061aSmrg    if ((returnCode != XtGeometryYes) ||
332444c061aSmrg	(req.changeMask & XtCWQueryOnly) || !XtIsRealized(widget)) {
333444c061aSmrg
334444c061aSmrg#ifdef XT_GEO_TATTLER
335444c061aSmrg	switch(returnCode){
336444c061aSmrg	case XtGeometryNo:
337444c061aSmrg	    CALLGEOTAT(_XtGeoTab(-1));
338444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(widget,"\"%s\" returns XtGeometryNo.\n",
339444c061aSmrg			  (XtParent(widget))?XtName(XtParent(widget)):"Root"));
340444c061aSmrg            /* check for no change */
341444c061aSmrg            break ;
342444c061aSmrg	case XtGeometryDone:
343444c061aSmrg	    CALLGEOTAT(_XtGeoTab(-1));
344444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(widget,"\"%s\" returns XtGeometryDone.\n",
345444c061aSmrg		        (XtParent(widget))?XtName(XtParent(widget)):"Root"));
346444c061aSmrg            /* check for no change in queryonly */
347444c061aSmrg            break ;
348444c061aSmrg	case XtGeometryAlmost:
349444c061aSmrg	    CALLGEOTAT(_XtGeoTab(-1));
350444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(widget,"\"%s\" returns XtGeometryAlmost.\n",
351444c061aSmrg			 (XtParent(widget))?XtName(XtParent(widget)):"Root"));
352444c061aSmrg	    CALLGEOTAT(_XtGeoTab(1));
353444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(widget,"Proposal: width %d height %d.\n",
354444c061aSmrg			   (reply)?reply->width:junk.width,
355444c061aSmrg			   (reply)?reply->height:junk.height));
356444c061aSmrg	    CALLGEOTAT(_XtGeoTab(-1));
357444c061aSmrg
358444c061aSmrg            /* check for no change */
359444c061aSmrg            break ;
360444c061aSmrg	case XtGeometryYes:
361444c061aSmrg	    if (req.changeMask & XtCWQueryOnly) {
362444c061aSmrg		CALLGEOTAT(_XtGeoTrace(widget,
363444c061aSmrg				"QueryOnly specified, no configuration.\n"));
364444c061aSmrg	    }
365444c061aSmrg            if (!XtIsRealized(widget)) {
366444c061aSmrg		CALLGEOTAT(_XtGeoTrace(widget,
367444c061aSmrg				 "\"%s\" not realized, no configuration.\n",
368444c061aSmrg				 XtName(widget)));
369444c061aSmrg	    }
370444c061aSmrg	    CALLGEOTAT(_XtGeoTab(-1));
371444c061aSmrg            CALLGEOTAT(_XtGeoTrace(widget,"\"%s\" returns XtGeometryYes.\n",
372444c061aSmrg                         (XtParent(widget))?XtName(XtParent(widget)):"Root"));
373444c061aSmrg	    break ;
374444c061aSmrg	}
375444c061aSmrg#endif
376444c061aSmrg	return returnCode;
377444c061aSmrg    }
378444c061aSmrg
379444c061aSmrg    CALLGEOTAT(_XtGeoTab(-1));
380444c061aSmrg    CALLGEOTAT(_XtGeoTrace(widget,"\"%s\" returns XtGeometryYes.\n",
381444c061aSmrg		   (XtParent(widget))?XtName(XtParent(widget)):"Root"));
382444c061aSmrg
383444c061aSmrg    if (XtIsWidget(widget)) {	/* reconfigure the window (if needed) */
384444c061aSmrg
385444c061aSmrg	if (rgm) return returnCode;
386444c061aSmrg
387444c061aSmrg	if (req.changes.x != widget->core.x) {
388444c061aSmrg 	    req.changeMask |= CWX;
389444c061aSmrg 	    req.changes.x = widget->core.x;
390444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(widget,
391444c061aSmrg				   "x changing to %d\n",widget->core.x));
392444c061aSmrg 	}
393444c061aSmrg 	if (req.changes.y != widget->core.y) {
394444c061aSmrg 	    req.changeMask |= CWY;
395444c061aSmrg 	    req.changes.y = widget->core.y;
396444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(widget,
397444c061aSmrg				   "y changing to %d\n",widget->core.y));
398444c061aSmrg 	}
399444c061aSmrg 	if (req.changes.width != widget->core.width) {
400444c061aSmrg 	    req.changeMask |= CWWidth;
401444c061aSmrg 	    req.changes.width = widget->core.width;
402444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(widget,
403444c061aSmrg				 "width changing to %d\n",widget->core.width));
404444c061aSmrg 	}
405444c061aSmrg 	if (req.changes.height != widget->core.height) {
406444c061aSmrg 	    req.changeMask |= CWHeight;
407444c061aSmrg 	    req.changes.height = widget->core.height;
408444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(widget,
409444c061aSmrg                               "height changing to %d\n",widget->core.height));
410444c061aSmrg 	}
411444c061aSmrg 	if (req.changes.border_width != widget->core.border_width) {
412444c061aSmrg 	    req.changeMask |= CWBorderWidth;
413444c061aSmrg 	    req.changes.border_width = widget->core.border_width;
414444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(widget,
415444c061aSmrg				   "border_width changing to %d\n",
416444c061aSmrg				   widget->core.border_width));
417444c061aSmrg 	}
418444c061aSmrg	if (req.changeMask & CWStackMode) {
419444c061aSmrg	    req.changes.stack_mode = request->stack_mode;
420444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(widget,"stack_mode changing\n"));
421444c061aSmrg	    if (req.changeMask & CWSibling) {
422444c061aSmrg		if (XtIsWidget(request->sibling))
423444c061aSmrg		    req.changes.sibling = XtWindow(request->sibling);
424444c061aSmrg		else
425444c061aSmrg		    req.changeMask &= ~(CWStackMode | CWSibling);
426444c061aSmrg	    }
427444c061aSmrg	}
428444c061aSmrg
429444c061aSmrg#ifdef XT_GEO_TATTLER
430444c061aSmrg        if (req.changeMask) {
431444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(widget,
432444c061aSmrg				   "XConfigure \"%s\"'s window.\n",
433444c061aSmrg				   XtName(widget)));
434444c061aSmrg	} else {
435444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(widget,
436444c061aSmrg			     "No window configuration needed for \"%s\".\n",
437444c061aSmrg			     XtName(widget)));
438444c061aSmrg	}
439444c061aSmrg#endif
440444c061aSmrg
441444c061aSmrg	XConfigureWindow(XtDisplay(widget), XtWindow(widget),
442444c061aSmrg			 req.changeMask, &req.changes);
443444c061aSmrg    }
444444c061aSmrg    else {			/* RectObj child of realized Widget */
445444c061aSmrg	*clear_rect_obj = TRUE;
446444c061aSmrg	CALLGEOTAT(_XtGeoTrace(widget,
447444c061aSmrg			       "ClearRectObj on \"%s\".\n",XtName(widget)));
448444c061aSmrg
449444c061aSmrg	ClearRectObjAreas((RectObj)widget, &req.changes);
450444c061aSmrg    }
451444c061aSmrg    hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));;
452444c061aSmrg    if (XtHasCallbacks(hookobj, XtNconfigureHook) == XtCallbackHasSome) {
453444c061aSmrg	req.type = XtHconfigure;
454444c061aSmrg	req.widget = widget;
455444c061aSmrg	XtCallCallbackList(hookobj,
456444c061aSmrg		((HookObject)hookobj)->hooks.confighook_callbacks,
457444c061aSmrg		(XtPointer)&req);
458444c061aSmrg    }
459444c061aSmrg
460444c061aSmrg    return returnCode;
461444c061aSmrg} /* _XtMakeGeometryRequest */
462444c061aSmrg
463444c061aSmrg
464444c061aSmrg/* Public routines */
465444c061aSmrg
466444c061aSmrgXtGeometryResult XtMakeGeometryRequest (
467444c061aSmrg    Widget         widget,
468444c061aSmrg    XtWidgetGeometry *request,
469444c061aSmrg    XtWidgetGeometry *reply)
470444c061aSmrg{
471444c061aSmrg    Boolean junk;
472444c061aSmrg    XtGeometryResult r;
473444c061aSmrg    XtGeometryHookDataRec call_data;
474444c061aSmrg    Widget hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
475444c061aSmrg    WIDGET_TO_APPCON(widget);
476444c061aSmrg
477444c061aSmrg    LOCK_APP(app);
478444c061aSmrg    if (XtHasCallbacks(hookobj, XtNgeometryHook) == XtCallbackHasSome) {
479444c061aSmrg	call_data.type = XtHpreGeometry;
480444c061aSmrg	call_data.widget = widget;
481444c061aSmrg	call_data.request = request;
482444c061aSmrg	XtCallCallbackList(hookobj,
483444c061aSmrg		((HookObject)hookobj)->hooks.geometryhook_callbacks,
484444c061aSmrg		(XtPointer)&call_data);
485444c061aSmrg	call_data.result = r =
486444c061aSmrg	    _XtMakeGeometryRequest(widget, request, reply, &junk);
487444c061aSmrg	call_data.type = XtHpostGeometry;
488444c061aSmrg	call_data.reply = reply;
489444c061aSmrg	XtCallCallbackList(hookobj,
490444c061aSmrg		((HookObject)hookobj)->hooks.geometryhook_callbacks,
491444c061aSmrg		(XtPointer)&call_data);
492444c061aSmrg    } else {
493444c061aSmrg	r = _XtMakeGeometryRequest(widget, request, reply, &junk);
494444c061aSmrg    }
495444c061aSmrg    UNLOCK_APP(app);
496444c061aSmrg
497444c061aSmrg    return ((r == XtGeometryDone) ? XtGeometryYes : r);
498444c061aSmrg}
499444c061aSmrg
500444c061aSmrgXtGeometryResult
501444c061aSmrgXtMakeResizeRequest(
502444c061aSmrg    Widget	widget,
503444c061aSmrg    _XtDimension width,
504444c061aSmrg    _XtDimension height,
505444c061aSmrg    Dimension	*replyWidth,
506444c061aSmrg    Dimension	*replyHeight)
507444c061aSmrg{
508444c061aSmrg    XtWidgetGeometry request, reply;
509444c061aSmrg    XtGeometryResult r;
510444c061aSmrg    XtGeometryHookDataRec call_data;
511444c061aSmrg    Boolean junk;
512444c061aSmrg    Widget hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
513444c061aSmrg    WIDGET_TO_APPCON(widget);
514444c061aSmrg
515444c061aSmrg    LOCK_APP(app);
516444c061aSmrg    request.request_mode = CWWidth | CWHeight;
517444c061aSmrg    request.width = width;
518444c061aSmrg    request.height = height;
519444c061aSmrg
520444c061aSmrg    if (XtHasCallbacks(hookobj, XtNgeometryHook) == XtCallbackHasSome) {
521444c061aSmrg	call_data.type = XtHpreGeometry;
522444c061aSmrg	call_data.widget = widget;
523444c061aSmrg	call_data.request = &request;
524444c061aSmrg	XtCallCallbackList(hookobj,
525444c061aSmrg		((HookObject)hookobj)->hooks.geometryhook_callbacks,
526444c061aSmrg		(XtPointer)&call_data);
527444c061aSmrg	call_data.result = r =
528444c061aSmrg	    _XtMakeGeometryRequest(widget, &request, &reply, &junk);
529444c061aSmrg	call_data.type = XtHpostGeometry;
530444c061aSmrg	call_data.reply = &reply;
531444c061aSmrg	XtCallCallbackList(hookobj,
532444c061aSmrg		((HookObject)hookobj)->hooks.geometryhook_callbacks,
533444c061aSmrg		(XtPointer)&call_data);
534444c061aSmrg    } else {
535444c061aSmrg	r = _XtMakeGeometryRequest(widget, &request, &reply, &junk);
536444c061aSmrg    }
537444c061aSmrg    if (replyWidth != NULL) {
538444c061aSmrg	if (r == XtGeometryAlmost && reply.request_mode & CWWidth)
539444c061aSmrg	    *replyWidth = reply.width;
540444c061aSmrg	else
541444c061aSmrg	    *replyWidth = width;
542444c061aSmrg    }
543444c061aSmrg    if (replyHeight != NULL) {
544444c061aSmrg	if (r == XtGeometryAlmost && reply.request_mode & CWHeight)
545444c061aSmrg	    *replyHeight = reply.height;
546444c061aSmrg	else
547444c061aSmrg	    *replyHeight = height;
548444c061aSmrg    }
549444c061aSmrg    UNLOCK_APP(app);
550444c061aSmrg    return ((r == XtGeometryDone) ? XtGeometryYes : r);
551444c061aSmrg} /* XtMakeResizeRequest */
552444c061aSmrg
553444c061aSmrgvoid XtResizeWindow(
554444c061aSmrg    Widget w)
555444c061aSmrg{
556444c061aSmrg    XtConfigureHookDataRec req;
557444c061aSmrg    Widget hookobj;
558444c061aSmrg    WIDGET_TO_APPCON(w);
559444c061aSmrg
560444c061aSmrg    LOCK_APP(app);
561444c061aSmrg    if (XtIsRealized(w)) {
562444c061aSmrg	req.changes.width = w->core.width;
563444c061aSmrg	req.changes.height = w->core.height;
564444c061aSmrg	req.changes.border_width = w->core.border_width;
565444c061aSmrg	req.changeMask = CWWidth | CWHeight | CWBorderWidth;
566444c061aSmrg	XConfigureWindow(XtDisplay(w), XtWindow(w),
567444c061aSmrg	    (unsigned) req.changeMask, &req.changes);
568444c061aSmrg	hookobj = XtHooksOfDisplay(XtDisplayOfObject(w));;
569444c061aSmrg	if (XtHasCallbacks(hookobj, XtNconfigureHook) == XtCallbackHasSome) {
570444c061aSmrg	    req.type = XtHconfigure;
571444c061aSmrg	    req.widget = w;
572444c061aSmrg	    XtCallCallbackList(hookobj,
573444c061aSmrg			((HookObject)hookobj)->hooks.confighook_callbacks,
574444c061aSmrg			(XtPointer)&req);
575444c061aSmrg	}
576444c061aSmrg    }
577444c061aSmrg    UNLOCK_APP(app);
578444c061aSmrg} /* XtResizeWindow */
579444c061aSmrg
580444c061aSmrgvoid XtResizeWidget(
581444c061aSmrg    Widget w,
582444c061aSmrg    _XtDimension width,
583444c061aSmrg    _XtDimension height,
584444c061aSmrg    _XtDimension borderWidth)
585444c061aSmrg{
586444c061aSmrg    XtConfigureWidget(w, w->core.x, w->core.y, width, height, borderWidth);
587444c061aSmrg} /* XtResizeWidget */
588444c061aSmrg
589444c061aSmrgvoid XtConfigureWidget(
590444c061aSmrg    Widget w,
591444c061aSmrg    _XtPosition x,
592444c061aSmrg    _XtPosition y,
593444c061aSmrg    _XtDimension width,
594444c061aSmrg    _XtDimension height,
595444c061aSmrg    _XtDimension borderWidth)
596444c061aSmrg{
597444c061aSmrg    XtConfigureHookDataRec req;
598444c061aSmrg    Widget hookobj;
599444c061aSmrg    XWindowChanges old;
600444c061aSmrg    WIDGET_TO_APPCON(w);
601444c061aSmrg
602444c061aSmrg    CALLGEOTAT(_XtGeoTrace(w,
603444c061aSmrg                   "\"%s\" is being configured by its parent \"%s\"\n",
604444c061aSmrg		   XtName(w),
605444c061aSmrg		   (XtParent(w))?XtName(XtParent(w)):"Root"));
606444c061aSmrg    CALLGEOTAT(_XtGeoTab(1));
607444c061aSmrg
608444c061aSmrg    LOCK_APP(app);
609444c061aSmrg    req.changeMask = 0;
610444c061aSmrg    if ((old.x = w->core.x) != x) {
611444c061aSmrg	CALLGEOTAT(_XtGeoTrace(w,"x move from %d to %d\n",w->core.x, x));
612444c061aSmrg	req.changes.x = w->core.x = x;
613444c061aSmrg	req.changeMask |= CWX;
614444c061aSmrg    }
615444c061aSmrg
616444c061aSmrg    if ((old.y = w->core.y) != y) {
617444c061aSmrg	CALLGEOTAT(_XtGeoTrace(w,"y move from %d to %d\n",w->core.y, y));
618444c061aSmrg	req.changes.y = w->core.y = y;
619444c061aSmrg	req.changeMask |= CWY;
620444c061aSmrg    }
621444c061aSmrg
622444c061aSmrg    if ((old.width = w->core.width) != width) {
623444c061aSmrg	CALLGEOTAT(_XtGeoTrace(w,
624444c061aSmrg			 "width move from %d to %d\n",w->core.width, width));
625444c061aSmrg	req.changes.width = w->core.width = width;
626444c061aSmrg	req.changeMask |= CWWidth;
627444c061aSmrg    }
628444c061aSmrg
629444c061aSmrg    if ((old.height = w->core.height) != height) {
630444c061aSmrg	CALLGEOTAT(_XtGeoTrace(w,
631444c061aSmrg		       "height move from %d to %d\n",w->core.height, height));
632444c061aSmrg	req.changes.height = w->core.height = height;
633444c061aSmrg	req.changeMask |= CWHeight;
634444c061aSmrg    }
635444c061aSmrg
636444c061aSmrg    if ((old.border_width = w->core.border_width) != borderWidth) {
637444c061aSmrg	CALLGEOTAT(_XtGeoTrace(w,"border_width move from %d to %d\n",
638444c061aSmrg		    w->core.border_width,borderWidth ));
639444c061aSmrg	req.changes.border_width = w->core.border_width = borderWidth;
640444c061aSmrg	req.changeMask |= CWBorderWidth;
641444c061aSmrg    }
642444c061aSmrg
643444c061aSmrg    if (req.changeMask != 0) {
644444c061aSmrg	if (XtIsRealized(w)) {
645444c061aSmrg	    if (XtIsWidget(w)) {
646444c061aSmrg		CALLGEOTAT(_XtGeoTrace(w,
647444c061aSmrg                                  "XConfigure \"%s\"'s window\n",XtName(w)));
648444c061aSmrg		XConfigureWindow(XtDisplay(w), XtWindow(w),
649444c061aSmrg				 req.changeMask, &req.changes);
650444c061aSmrg	    } else {
651444c061aSmrg		CALLGEOTAT(_XtGeoTrace(w,
652444c061aSmrg			       "ClearRectObj called on \"%s\"\n",XtName(w)));
653444c061aSmrg		ClearRectObjAreas((RectObj)w, &old);
654444c061aSmrg	    }
655444c061aSmrg	}
656444c061aSmrg	hookobj = XtHooksOfDisplay(XtDisplayOfObject(w));;
657444c061aSmrg	if (XtHasCallbacks(hookobj, XtNconfigureHook) == XtCallbackHasSome) {
658444c061aSmrg	    req.type = XtHconfigure;
659444c061aSmrg	    req.widget = w;
660444c061aSmrg	    XtCallCallbackList(hookobj,
661444c061aSmrg			((HookObject)hookobj)->hooks.confighook_callbacks,
662444c061aSmrg			(XtPointer)&req);
663444c061aSmrg	}
664444c061aSmrg	{
665444c061aSmrg	XtWidgetProc resize;
666444c061aSmrg
667444c061aSmrg	LOCK_PROCESS;
668444c061aSmrg	resize = XtClass(w)->core_class.resize;
669444c061aSmrg	UNLOCK_PROCESS;
670444c061aSmrg	if ((req.changeMask & (CWWidth | CWHeight)) &&
671444c061aSmrg	    resize != (XtWidgetProc) NULL) {
672444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(w,"Resize proc is called.\n"));
673444c061aSmrg	    (*resize)(w);
674444c061aSmrg	 }
675444c061aSmrg	}
676444c061aSmrg    } else {
677444c061aSmrg	CALLGEOTAT(_XtGeoTrace(w,"No change in configuration\n"));
678444c061aSmrg    }
679444c061aSmrg
680444c061aSmrg    CALLGEOTAT(_XtGeoTab(-1));
681444c061aSmrg    UNLOCK_APP(app);
682444c061aSmrg} /* XtConfigureWidget */
683444c061aSmrg
684444c061aSmrgvoid XtMoveWidget(
685444c061aSmrg    Widget w,
686444c061aSmrg    _XtPosition x,
687444c061aSmrg    _XtPosition y)
688444c061aSmrg{
689444c061aSmrg    XtConfigureWidget(w, x, y, w->core.width, w->core.height,
690444c061aSmrg		      w->core.border_width);
691444c061aSmrg} /* XtMoveWidget */
692444c061aSmrg
693444c061aSmrgvoid XtTranslateCoords(
694444c061aSmrg    register Widget w,
695444c061aSmrg    _XtPosition x,
696444c061aSmrg    _XtPosition y,
697444c061aSmrg    register Position *rootx,	/* return */
698444c061aSmrg    register Position *rooty)	/* return */
699444c061aSmrg{
700444c061aSmrg    Position garbagex, garbagey;
701444c061aSmrg    XtAppContext app = XtWidgetToApplicationContext(w);
702444c061aSmrg
703444c061aSmrg    LOCK_APP(app);
704444c061aSmrg    if (rootx == NULL) rootx = &garbagex;
705444c061aSmrg    if (rooty == NULL) rooty = &garbagey;
706444c061aSmrg
707444c061aSmrg    *rootx = x;
708444c061aSmrg    *rooty = y;
709444c061aSmrg
710444c061aSmrg    for (; w != NULL && ! XtIsShell(w); w = w->core.parent) {
711444c061aSmrg	*rootx += w->core.x + w->core.border_width;
712444c061aSmrg	*rooty += w->core.y + w->core.border_width;
713444c061aSmrg    }
714444c061aSmrg
715444c061aSmrg    if (w == NULL)
716444c061aSmrg        XtAppWarningMsg(app,
717444c061aSmrg		"invalidShell","xtTranslateCoords",XtCXtToolkitError,
718444c061aSmrg                "Widget has no shell ancestor",
719444c061aSmrg		(String *)NULL, (Cardinal *)NULL);
720444c061aSmrg    else {
721444c061aSmrg	Position x, y;
722444c061aSmrg	_XtShellGetCoordinates( w, &x, &y );
723444c061aSmrg	*rootx += x + w->core.border_width;
724444c061aSmrg	*rooty += y + w->core.border_width;
725444c061aSmrg    }
726444c061aSmrg    UNLOCK_APP(app);
727444c061aSmrg}
728444c061aSmrg
729444c061aSmrgXtGeometryResult XtQueryGeometry(
730444c061aSmrg    Widget widget,
731444c061aSmrg    register XtWidgetGeometry *intended, /* parent's changes; may be NULL */
732444c061aSmrg    XtWidgetGeometry *reply)	/* child's preferred geometry; never NULL */
733444c061aSmrg{
734444c061aSmrg    XtWidgetGeometry null_intended;
735444c061aSmrg    XtGeometryHandler query;
736444c061aSmrg    XtGeometryResult result;
737444c061aSmrg    WIDGET_TO_APPCON(widget);
738444c061aSmrg
739444c061aSmrg    CALLGEOTAT(_XtGeoTrace(widget,
740444c061aSmrg		     "\"%s\" is asking its preferred geometry to \"%s\".\n",
741444c061aSmrg		     (XtParent(widget))?XtName(XtParent(widget)):"Root",
742444c061aSmrg		     XtName(widget)));
743444c061aSmrg    CALLGEOTAT(_XtGeoTab(1));
744444c061aSmrg
745444c061aSmrg    LOCK_APP(app);
746444c061aSmrg    LOCK_PROCESS;
747444c061aSmrg    query = XtClass(widget)->core_class.query_geometry;
748444c061aSmrg    UNLOCK_PROCESS;
749444c061aSmrg    reply->request_mode = 0;
750444c061aSmrg    if (query != NULL) {
751444c061aSmrg	if (intended == NULL) {
752444c061aSmrg	    null_intended.request_mode = 0;
753444c061aSmrg	    intended = &null_intended;
754444c061aSmrg#ifdef XT_GEO_TATTLER
755444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(widget,"without any constraint.\n"));
756444c061aSmrg	} else {
757444c061aSmrg	    CALLGEOTAT(_XtGeoTrace(widget,
758444c061aSmrg				   "with the following constraints:\n"));
759444c061aSmrg
760444c061aSmrg	    if (intended->request_mode & CWX) {
761444c061aSmrg		CALLGEOTAT(_XtGeoTrace(widget," x = %d\n",intended->x));
762444c061aSmrg	    }
763444c061aSmrg	    if (intended->request_mode & CWY) {
764444c061aSmrg		CALLGEOTAT(_XtGeoTrace(widget," y = %d\n",intended->y));
765444c061aSmrg	    }
766444c061aSmrg	    if (intended->request_mode & CWWidth) {
767444c061aSmrg		CALLGEOTAT(_XtGeoTrace(widget,
768444c061aSmrg				       " width = %d\n",intended->width));
769444c061aSmrg	    }
770444c061aSmrg	    if (intended->request_mode & CWHeight) {
771444c061aSmrg		CALLGEOTAT(_XtGeoTrace(widget,
772444c061aSmrg				       " height = %d\n",intended->height));
773444c061aSmrg	    }
774444c061aSmrg	    if (intended->request_mode & CWBorderWidth) {
775444c061aSmrg		CALLGEOTAT(_XtGeoTrace(widget,
776444c061aSmrg			       " border_width = %d\n",intended->border_width));
777444c061aSmrg	    }
778444c061aSmrg#endif
779444c061aSmrg	}
780444c061aSmrg
781444c061aSmrg	result = (*query) (widget, intended, reply);
782444c061aSmrg    }
783444c061aSmrg    else {
784444c061aSmrg	CALLGEOTAT(_XtGeoTrace(widget,"\"%s\" has no QueryGeometry proc, return the current state\n",XtName(widget)));
785444c061aSmrg
786444c061aSmrg	result = XtGeometryYes;
787444c061aSmrg    }
788444c061aSmrg
789444c061aSmrg#ifdef XT_GEO_TATTLER
790444c061aSmrg#define FillIn(mask, field) \
791444c061aSmrg	if (!(reply->request_mode & mask)) {\
792444c061aSmrg	      reply->field = widget->core.field;\
793444c061aSmrg	      _XtGeoTrace(widget," using core %s = %d.\n","field",\
794444c061aSmrg			                               widget->core.field);\
795444c061aSmrg	} else {\
796444c061aSmrg	      _XtGeoTrace(widget," replied %s = %d\n","field",\
797444c061aSmrg			                           reply->field);\
798444c061aSmrg	}
799444c061aSmrg#else
800444c061aSmrg#define FillIn(mask, field) \
801444c061aSmrg	if (!(reply->request_mode & mask)) reply->field = widget->core.field;
802444c061aSmrg#endif
803444c061aSmrg
804444c061aSmrg    FillIn(CWX, x);
805444c061aSmrg    FillIn(CWY, y);
806444c061aSmrg    FillIn(CWWidth, width);
807444c061aSmrg    FillIn(CWHeight, height);
808444c061aSmrg    FillIn(CWBorderWidth, border_width);
809444c061aSmrg
810444c061aSmrg    CALLGEOTAT(_XtGeoTab(-1));
811444c061aSmrg#undef FillIn
812444c061aSmrg
813444c061aSmrg    if (!(reply->request_mode & CWStackMode))
814444c061aSmrg	reply->stack_mode = XtSMDontChange;
815444c061aSmrg    UNLOCK_APP(app);
816444c061aSmrg    return result;
817444c061aSmrg}
818