Geometry.c revision a3bd7f05
1/*********************************************************** 2Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved. 3 4Permission is hereby granted, free of charge, to any person obtaining a 5copy of this software and associated documentation files (the "Software"), 6to deal in the Software without restriction, including without limitation 7the rights to use, copy, modify, merge, publish, distribute, sublicense, 8and/or sell copies of the Software, and to permit persons to whom the 9Software is furnished to do so, subject to the following conditions: 10 11The above copyright notice and this permission notice (including the next 12paragraph) shall be included in all copies or substantial portions of the 13Software. 14 15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21DEALINGS IN THE SOFTWARE. 22 23Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. 24 25 All Rights Reserved 26 27Permission to use, copy, modify, and distribute this software and its 28documentation for any purpose and without fee is hereby granted, 29provided that the above copyright notice appear in all copies and that 30both that copyright notice and this permission notice appear in 31supporting documentation, and that the name of Digital not be 32used in advertising or publicity pertaining to distribution of the 33software without specific, written prior permission. 34 35DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 36ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 37DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 38ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 39WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 40ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 41SOFTWARE. 42 43******************************************************************/ 44 45/* 46 47Copyright 1987, 1988, 1994, 1998 The Open Group 48 49Permission to use, copy, modify, distribute, and sell this software and its 50documentation for any purpose is hereby granted without fee, provided that 51the above copyright notice appear in all copies and that both that 52copyright notice and this permission notice appear in supporting 53documentation. 54 55The above copyright notice and this permission notice shall be included in 56all copies or substantial portions of the Software. 57 58THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 59IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 60FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 61OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 62AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 63CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 64 65Except as contained in this notice, the name of The Open Group shall not be 66used in advertising or otherwise to promote the sale, use or other dealings 67in this Software without prior written authorization from The Open Group. 68 69*/ 70 71#ifdef HAVE_CONFIG_H 72#include <config.h> 73#endif 74#include "IntrinsicI.h" 75#include "ShellP.h" 76#include "ShellI.h" 77 78static void 79ClearRectObjAreas(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 106XtGeometryResult 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 490XtGeometryResult 491XtMakeGeometryRequest(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 526XtGeometryResult 527XtMakeResizeRequest(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 580void 581XtResizeWindow(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 609void 610XtResizeWidget(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 618void 619XtConfigureWidget(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 722void 723XtMoveWidget(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 729void 730XtTranslateCoords(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 767XtGeometryResult 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