Home | History | Annotate | Line # | Download | only in src
      1 /***********************************************************
      2 Copyright (c) 1993, Oracle and/or its affiliates.
      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
     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
    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
    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
    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     memset(&request, 0, sizeof(request));
    543     request.request_mode = CWWidth | CWHeight;
    544     request.width = (Dimension) width;
    545     request.height = (Dimension) height;
    546 
    547     if (XtHasCallbacks(hookobj, XtNgeometryHook) == XtCallbackHasSome) {
    548         call_data.type = XtHpreGeometry;
    549         call_data.widget = widget;
    550         call_data.request = &request;
    551         XtCallCallbackList(hookobj,
    552                            ((HookObject) hookobj)->hooks.geometryhook_callbacks,
    553                            (XtPointer) &call_data);
    554         call_data.result = r =
    555             _XtMakeGeometryRequest(widget, &request, &reply, &junk);
    556         call_data.type = XtHpostGeometry;
    557         call_data.reply = &reply;
    558         XtCallCallbackList(hookobj,
    559                            ((HookObject) hookobj)->hooks.geometryhook_callbacks,
    560                            (XtPointer) &call_data);
    561     }
    562     else {
    563         r = _XtMakeGeometryRequest(widget, &request, &reply, &junk);
    564     }
    565     if (replyWidth != NULL) {
    566         if (r == XtGeometryAlmost && reply.request_mode & CWWidth)
    567             *replyWidth = reply.width;
    568         else
    569             *replyWidth = (Dimension) width;
    570     }
    571     if (replyHeight != NULL) {
    572         if (r == XtGeometryAlmost && reply.request_mode & CWHeight)
    573             *replyHeight = reply.height;
    574         else
    575             *replyHeight = (Dimension) height;
    576     }
    577     UNLOCK_APP(app);
    578     return ((r == XtGeometryDone) ? XtGeometryYes : r);
    579 }                               /* XtMakeResizeRequest */
    580 
    581 void
    582 XtResizeWindow(Widget w)
    583 {
    584     XtConfigureHookDataRec req;
    585 
    586     WIDGET_TO_APPCON(w);
    587 
    588     LOCK_APP(app);
    589     if (XtIsRealized(w)) {
    590         Widget hookobj;
    591 
    592         req.changes.width = w->core.width;
    593         req.changes.height = w->core.height;
    594         req.changes.border_width = w->core.border_width;
    595         req.changeMask = CWWidth | CWHeight | CWBorderWidth;
    596         XConfigureWindow(XtDisplay(w), XtWindow(w),
    597                          (unsigned) req.changeMask, &req.changes);
    598         hookobj = XtHooksOfDisplay(XtDisplayOfObject(w));
    599         if (XtHasCallbacks(hookobj, XtNconfigureHook) == XtCallbackHasSome) {
    600             req.type = XtHconfigure;
    601             req.widget = w;
    602             XtCallCallbackList(hookobj,
    603                                ((HookObject) hookobj)->hooks.
    604                                confighook_callbacks, (XtPointer) &req);
    605         }
    606     }
    607     UNLOCK_APP(app);
    608 }                               /* XtResizeWindow */
    609 
    610 void
    611 XtResizeWidget(Widget w,
    612                _XtDimension width,
    613                _XtDimension height,
    614                _XtDimension borderWidth)
    615 {
    616     XtConfigureWidget(w, w->core.x, w->core.y, width, height, borderWidth);
    617 }                               /* XtResizeWidget */
    618 
    619 void
    620 XtConfigureWidget(Widget w,
    621                   _XtPosition x,
    622                   _XtPosition y,
    623                   _XtDimension width,
    624                   _XtDimension height,
    625                   _XtDimension borderWidth)
    626 {
    627     XtConfigureHookDataRec req;
    628     XWindowChanges old;
    629 
    630     WIDGET_TO_APPCON(w);
    631 
    632     CALLGEOTAT(_XtGeoTrace(w,
    633                            "\"%s\" is being configured by its parent \"%s\"\n",
    634                            XtName(w),
    635                            (XtParent(w)) ? XtName(XtParent(w)) : "Root"));
    636     CALLGEOTAT(_XtGeoTab(1));
    637 
    638     LOCK_APP(app);
    639     req.changeMask = 0;
    640     if ((old.x = w->core.x) != x) {
    641         CALLGEOTAT(_XtGeoTrace(w, "x move from %d to %d\n", w->core.x, x));
    642         req.changes.x = w->core.x = (Position) x;
    643         req.changeMask |= CWX;
    644     }
    645 
    646     if ((old.y = w->core.y) != y) {
    647         CALLGEOTAT(_XtGeoTrace(w, "y move from %d to %d\n", w->core.y, y));
    648         req.changes.y = w->core.y = (Position) y;
    649         req.changeMask |= CWY;
    650     }
    651 
    652     if ((old.width = w->core.width) != width) {
    653         CALLGEOTAT(_XtGeoTrace(w,
    654                                "width move from %d to %d\n", w->core.width,
    655                                width));
    656         req.changes.width = w->core.width = (Dimension) width;
    657         req.changeMask |= CWWidth;
    658     }
    659 
    660     if ((old.height = w->core.height) != height) {
    661         CALLGEOTAT(_XtGeoTrace(w,
    662                                "height move from %d to %d\n", w->core.height,
    663                                height));
    664         req.changes.height = w->core.height = (Dimension) height;
    665         req.changeMask |= CWHeight;
    666     }
    667 
    668     if ((old.border_width = w->core.border_width) != borderWidth) {
    669         CALLGEOTAT(_XtGeoTrace(w, "border_width move from %d to %d\n",
    670                                w->core.border_width, borderWidth));
    671         req.changes.border_width = w->core.border_width =
    672             (Dimension) borderWidth;
    673         req.changeMask |= CWBorderWidth;
    674     }
    675 
    676     if (req.changeMask != 0) {
    677         Widget hookobj;
    678 
    679         if (XtIsRealized(w)) {
    680             if (XtIsWidget(w)) {
    681                 CALLGEOTAT(_XtGeoTrace(w,
    682                                        "XConfigure \"%s\"'s window\n",
    683                                        XtName(w)));
    684                 XConfigureWindow(XtDisplay(w), XtWindow(w), req.changeMask,
    685                                  &req.changes);
    686             }
    687             else {
    688                 CALLGEOTAT(_XtGeoTrace(w,
    689                                        "ClearRectObj called on \"%s\"\n",
    690                                        XtName(w)));
    691                 ClearRectObjAreas((RectObj) w, &old);
    692             }
    693         }
    694         hookobj = XtHooksOfDisplay(XtDisplayOfObject(w));
    695         if (XtHasCallbacks(hookobj, XtNconfigureHook) == XtCallbackHasSome) {
    696             req.type = XtHconfigure;
    697             req.widget = w;
    698             XtCallCallbackList(hookobj,
    699                                ((HookObject) hookobj)->hooks.
    700                                confighook_callbacks, (XtPointer) &req);
    701         }
    702         {
    703             XtWidgetProc resize;
    704 
    705             LOCK_PROCESS;
    706             resize = XtClass(w)->core_class.resize;
    707             UNLOCK_PROCESS;
    708             if ((req.changeMask & (CWWidth | CWHeight)) &&
    709                 resize != (XtWidgetProc) NULL) {
    710                 CALLGEOTAT(_XtGeoTrace(w, "Resize proc is called.\n"));
    711                 (*resize) (w);
    712             }
    713         }
    714     }
    715     else {
    716         CALLGEOTAT(_XtGeoTrace(w, "No change in configuration\n"));
    717     }
    718 
    719     CALLGEOTAT(_XtGeoTab(-1));
    720     UNLOCK_APP(app);
    721 }                               /* XtConfigureWidget */
    722 
    723 void
    724 XtMoveWidget(Widget w, _XtPosition x, _XtPosition y)
    725 {
    726     XtConfigureWidget(w, x, y, w->core.width, w->core.height,
    727                       w->core.border_width);
    728 }                               /* XtMoveWidget */
    729 
    730 void
    731 XtTranslateCoords(register Widget w,
    732                   _XtPosition x,
    733                   _XtPosition y,
    734                   register Position *rootx, /* return */
    735                   register Position *rooty) /* return */
    736 {
    737     Position garbagex, garbagey;
    738     XtAppContext app = XtWidgetToApplicationContext(w);
    739 
    740     LOCK_APP(app);
    741     if (rootx == NULL)
    742         rootx = &garbagex;
    743     if (rooty == NULL)
    744         rooty = &garbagey;
    745 
    746     *rootx = (Position) x;
    747     *rooty = (Position) y;
    748 
    749     for (; w != NULL && !XtIsShell(w); w = w->core.parent) {
    750         *rootx = (Position) (*rootx + w->core.x + w->core.border_width);
    751         *rooty = (Position) (*rooty + w->core.y + w->core.border_width);
    752     }
    753 
    754     if (w == NULL)
    755         XtAppWarningMsg(app,
    756                         "invalidShell", "xtTranslateCoords", XtCXtToolkitError,
    757                         "Widget has no shell ancestor", NULL, NULL);
    758     else {
    759         Position x2, y2;
    760 
    761         _XtShellGetCoordinates(w, &x2, &y2);
    762         *rootx = (Position) (*rootx + x2 + w->core.border_width);
    763         *rooty = (Position) (*rooty + y2 + w->core.border_width);
    764     }
    765     UNLOCK_APP(app);
    766 }
    767 
    768 XtGeometryResult XtQueryGeometry(Widget widget,
    769                                  register XtWidgetGeometry *intended, /* parent's changes; may be NULL */
    770                                  XtWidgetGeometry *reply) {    /* child's preferred geometry; never NULL */
    771     XtWidgetGeometry null_intended;
    772     XtGeometryHandler query;
    773     XtGeometryResult result;
    774 
    775     WIDGET_TO_APPCON(widget);
    776 
    777     CALLGEOTAT(_XtGeoTrace(widget,
    778                            "\"%s\" is asking its preferred geometry to \"%s\".\n",
    779                            (XtParent(widget)) ? XtName(XtParent(widget)) :
    780                            "Root", XtName(widget)));
    781     CALLGEOTAT(_XtGeoTab(1));
    782 
    783     LOCK_APP(app);
    784     LOCK_PROCESS;
    785     query = XtClass(widget)->core_class.query_geometry;
    786     UNLOCK_PROCESS;
    787     reply->request_mode = 0;
    788     if (query != NULL) {
    789         if (intended == NULL) {
    790             null_intended.request_mode = 0;
    791             intended = &null_intended;
    792 #ifdef XT_GEO_TATTLER
    793             CALLGEOTAT(_XtGeoTrace(widget, "without any constraint.\n"));
    794         }
    795         else {
    796             CALLGEOTAT(_XtGeoTrace(widget,
    797                                    "with the following constraints:\n"));
    798 
    799             if (intended->request_mode & CWX) {
    800                 CALLGEOTAT(_XtGeoTrace(widget, " x = %d\n", intended->x));
    801             }
    802             if (intended->request_mode & CWY) {
    803                 CALLGEOTAT(_XtGeoTrace(widget, " y = %d\n", intended->y));
    804             }
    805             if (intended->request_mode & CWWidth) {
    806                 CALLGEOTAT(_XtGeoTrace(widget,
    807                                        " width = %d\n", intended->width));
    808             }
    809             if (intended->request_mode & CWHeight) {
    810                 CALLGEOTAT(_XtGeoTrace(widget,
    811                                        " height = %d\n", intended->height));
    812             }
    813             if (intended->request_mode & CWBorderWidth) {
    814                 CALLGEOTAT(_XtGeoTrace(widget,
    815                                        " border_width = %d\n",
    816                                        intended->border_width));
    817             }
    818 #endif
    819         }
    820 
    821         result = (*query) (widget, intended, reply);
    822     }
    823     else {
    824         CALLGEOTAT(_XtGeoTrace
    825                    (widget,
    826                     "\"%s\" has no QueryGeometry proc, return the current state\n",
    827                     XtName(widget)));
    828 
    829         result = XtGeometryYes;
    830     }
    831 
    832 #ifdef XT_GEO_TATTLER
    833 #define FillIn(mask, field) \
    834         if (!(reply->request_mode & mask)) {\
    835               reply->field = widget->core.field;\
    836               _XtGeoTrace(widget," using core %s = %d.\n","field",\
    837                                                        widget->core.field);\
    838         } else {\
    839               _XtGeoTrace(widget," replied %s = %d\n","field",\
    840                                                    reply->field);\
    841         }
    842 #else
    843 #define FillIn(mask, field) \
    844         if (!(reply->request_mode & mask)) reply->field = widget->core.field;
    845 #endif
    846 
    847     FillIn(CWX, x);
    848     FillIn(CWY, y);
    849     FillIn(CWWidth, width);
    850     FillIn(CWHeight, height);
    851     FillIn(CWBorderWidth, border_width);
    852 
    853     CALLGEOTAT(_XtGeoTab(-1));
    854 #undef FillIn
    855 
    856     if (!(reply->request_mode & CWStackMode))
    857         reply->stack_mode = XtSMDontChange;
    858     UNLOCK_APP(app);
    859     return result;
    860 }
    861