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