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