| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 | |
| 20 | |
| 21 | |
| 22 | |
| 23 | |
| 24 | |
| 25 | |
| 26 | |
| 27 | |
| 28 | |
| 29 | |
| 30 | |
| 31 | |
| 32 | |
| 33 | |
| 34 | |
| 35 | |
| 36 | |
| 37 | |
| 38 | |
| 39 | |
| 40 | |
| 41 | |
| 42 | |
| 43 | |
| 44 | |
| 45 | |
| 46 | |
| 47 | |
| 48 | |
| 49 | #ifdef HAVE_CONFIG_H1 |
| 50 | #include "config.h" |
| 51 | #endif |
| 52 | |
| 53 | |
| 54 | |
| 55 | |
| 56 | |
| 57 | |
| 58 | #include <X11/IntrinsicP.h> |
| 59 | #include <X11/StringDefs.h> |
| 60 | #include <X11/Xmu/Misc.h> |
| 61 | #include <X11/Xaw3d/XawInit.h> |
| 62 | #include <X11/Xaw3d/BoxP.h> |
| 63 | |
| 64 | |
| 65 | |
| 66 | |
| 67 | |
| 68 | |
| 69 | |
| 70 | static XtResource resources[] = { |
| 71 | { XtNhSpace((char*)&XtStrings[251]), XtCHSpace((char*)&XtStrings[1058]), XtRDimension((char*)&XtStrings[1618]), sizeof(Dimension), |
| 72 | XtOffsetOf(BoxRec, box.h_space)__builtin_offsetof(BoxRec, box.h_space), |
| 73 | XtRImmediate((char*)&XtStrings[1695]), (XtPointer)4 }, |
| 74 | { XtNvSpace((char*)&XtStrings[865]), XtCVSpace((char*)&XtStrings[1503]), XtRDimension((char*)&XtStrings[1618]), sizeof(Dimension), |
| 75 | XtOffsetOf(BoxRec, box.v_space)__builtin_offsetof(BoxRec, box.v_space), |
| 76 | XtRImmediate((char*)&XtStrings[1695]), (XtPointer)4 }, |
| 77 | { XtNorientation((char*)&XtStrings[505]), XtCOrientation((char*)&XtStrings[1206]), XtROrientation((char*)&XtStrings[1742]), sizeof(XtOrientation), |
| 78 | XtOffsetOf(BoxRec, box.orientation)__builtin_offsetof(BoxRec, box.orientation), |
| 79 | XtRImmediate((char*)&XtStrings[1695]), (XtPointer)XtorientVertical }, |
| 80 | }; |
| 81 | |
| 82 | |
| 83 | |
| 84 | |
| 85 | |
| 86 | |
| 87 | |
| 88 | static void ClassInitialize(void); |
| 89 | static void Initialize(Widget, Widget, ArgList, Cardinal *); |
| 90 | static void Realize(Widget, Mask *, XSetWindowAttributes *); |
| 91 | static void Resize(Widget); |
| 92 | static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal *); |
| 93 | static XtGeometryResult GeometryManager(Widget, XtWidgetGeometry *, XtWidgetGeometry *); |
| 94 | static void ChangeManaged(Widget); |
| 95 | static XtGeometryResult PreferredSize(Widget, XtWidgetGeometry *, XtWidgetGeometry *); |
| 96 | |
| 97 | BoxClassRec boxClassRec = { |
| 98 | { |
| 99 | |
| 100 | (WidgetClass) &compositeClassRec, |
| 101 | "Box", |
| 102 | sizeof(BoxRec), |
| 103 | ClassInitialize, |
| 104 | NULL((void*)0), |
| 105 | FALSE0, |
| 106 | Initialize, |
| 107 | NULL((void*)0), |
| 108 | Realize, |
| 109 | NULL((void*)0), |
| 110 | 0, |
| 111 | resources, |
| 112 | XtNumber(resources)((Cardinal) (sizeof(resources) / sizeof(resources[0]))), |
| 113 | NULLQUARK((XrmQuark) 0), |
| 114 | TRUE1, |
| 115 | TRUE1, |
| 116 | TRUE1, |
| 117 | FALSE0, |
| 118 | NULL((void*)0), |
| 119 | Resize, |
| 120 | NULL((void*)0), |
| 121 | SetValues, |
| 122 | NULL((void*)0), |
| 123 | XtInheritSetValuesAlmost((XtAlmostProc) _XtInherit), |
| 124 | NULL((void*)0), |
| 125 | NULL((void*)0), |
| 126 | XtVersion(11 * 1000 + 6), |
| 127 | NULL((void*)0), |
| 128 | NULL((void*)0), |
| 129 | PreferredSize, |
| 130 | XtInheritDisplayAccelerator((XtStringProc) _XtInherit), |
| 131 | NULL((void*)0) |
| 132 | },{ |
| 133 | |
| 134 | GeometryManager, |
| 135 | ChangeManaged, |
| 136 | XtInheritInsertChild((XtWidgetProc) _XtInherit), |
| 137 | XtInheritDeleteChild((XtWidgetProc) _XtInherit), |
| 138 | NULL((void*)0) |
| 139 | },{ |
| 140 | |
| 141 | 0, |
| 142 | } |
| 143 | }; |
| 144 | |
| 145 | WidgetClass boxWidgetClass = (WidgetClass)&boxClassRec; |
| 146 | |
| 147 | |
| 148 | |
| 149 | |
| 150 | |
| 151 | |
| 152 | |
| 153 | |
| 154 | |
| 155 | |
| 156 | |
| 157 | |
| 158 | |
| 159 | |
| 160 | |
| 161 | static void |
| 162 | DoLayout(BoxWidget bbw, Dimension width, Dimension height, |
| 163 | Dimension *reply_width, Dimension *reply_height, Boolean position) |
| 164 | { |
| 165 | Boolean vbox = (bbw->box.orientation == XtorientVertical); |
| 166 | Cardinal i; |
| 167 | Dimension w, h; |
| 168 | Dimension lw, lh; |
| 169 | Dimension bw, bh; |
| 170 | Dimension h_space; |
| 171 | Widget widget; |
| 172 | int num_mapped_children = 0; |
| 173 | |
| 174 | |
| 175 | h_space = bbw->box.h_space; |
| 176 | |
| 177 | w = 0; |
| 178 | for (i = 0; i < bbw->composite.num_children; i++) { |
| 179 | if ( bbw->composite.children[i]->core.width > w ) |
| 180 | w = bbw->composite.children[i]->core.width; |
| 181 | } |
| 182 | w += h_space; |
| 183 | if ( w > width ) width = w; |
| 184 | h = bbw->box.v_space; |
| 185 | |
| 186 | |
| 187 | lh = 0; |
| 188 | lw = h_space; |
| 189 | |
| 190 | for (i = 0; i < bbw->composite.num_children; i++) { |
| 191 | widget = bbw->composite.children[i]; |
| 192 | if (widget->core.managed) { |
| 193 | if (widget->core.mapped_when_managed) num_mapped_children++; |
| 194 | |
| 195 | bw = widget->core.width + 2*widget->core.border_width + h_space; |
| 196 | if ((Dimension)(lw + bw) > width) { |
| 197 | if (lw > h_space) { |
| 198 | |
| 199 | |
| 200 | |
| 201 | AssignMax(w, lw){if ((lw) > (w)) w = (lw);}; |
| 202 | if (vbox) { |
| 203 | h += lh + bbw->box.v_space; |
| 204 | lh = 0; |
| 205 | lw = h_space; |
| 206 | } |
| 207 | } |
| 208 | else if (!position) { |
| 209 | |
| 210 | DoLayout(bbw, lw + bw, height, reply_width, |
| 211 | reply_height, position); |
| 212 | return; |
| 213 | } |
| 214 | } |
| 215 | if (position && (lw != (Dimension)widget->core.x || h != (Dimension)widget->core.y)) { |
| 216 | |
| 217 | |
| 218 | |
| 219 | |
| 220 | |
| 221 | |
| 222 | |
| 223 | |
| 224 | |
| 225 | |
| 226 | |
| 227 | |
| 228 | if (XtIsRealized(widget)(XtWindowOfObject(widget) != 0L) && widget->core.mapped_when_managed) |
| 229 | XUnmapWindow( XtDisplay(widget)(((widget)->core.screen)->display), XtWindow(widget)((widget)->core.window) ); |
| 230 | XtMoveWidget(widget, (int)lw, (int)h); |
| 231 | } |
| 232 | lw += bw; |
| 233 | bh = widget->core.height + 2*widget->core.border_width; |
| 234 | AssignMax(lh, bh){if ((bh) > (lh)) lh = (bh);}; |
| 235 | } |
| 236 | } |
| 237 | |
| 238 | if (!vbox && width && lw > width && lh < height) { |
| 239 | |
| 240 | Dimension sw = lw, sh = lh; |
| 241 | Dimension width_needed = 0; |
| 242 | XtOrientation orientation = bbw->box.orientation; |
| 243 | bbw->box.orientation = XtorientVertical; |
| 244 | while (sh < height && sw > width) { |
| 245 | width_needed = sw; |
| 246 | DoLayout(bbw, sw-1, height, &sw, &sh, False0); |
| 247 | } |
| 248 | if (sh < height) width_needed = sw; |
| 249 | if (width_needed != lw) { |
| 250 | DoLayout(bbw,width_needed,height,reply_width,reply_height,position); |
| 251 | bbw->box.orientation = orientation; |
| 252 | return; |
| 253 | } |
| 254 | bbw->box.orientation = orientation; |
| 255 | } |
| 256 | if ( vbox && ( ( width < w ) || ( width < lw ) ) ) { |
| 257 | AssignMax(w, lw){if ((lw) > (w)) w = (lw);}; |
| 258 | DoLayout( bbw, w, height, reply_width, reply_height, position ); |
| 259 | return; |
| 260 | } |
| 261 | if (position && XtIsRealized((Widget)bbw)(XtWindowOfObject((Widget)bbw) != 0L)) { |
| 262 | if (bbw->composite.num_children == num_mapped_children) |
| 263 | XMapSubwindows( XtDisplay((Widget)bbw)((((Widget)bbw)->core.screen)->display), XtWindow((Widget)bbw)(((Widget)bbw)->core.window) ); |
| 264 | else { |
| 265 | int j = bbw->composite.num_children; |
| 266 | Widget *childP = bbw->composite.children; |
| 267 | for (; j > 0; childP++, j--) |
| 268 | if (XtIsRealized(*childP)(XtWindowOfObject(*childP) != 0L) && XtIsManaged(*childP) && |
| 269 | (*childP)->core.mapped_when_managed) |
| 270 | XtMapWidget(*childP)XMapWindow((((*childP)->core.screen)->display), ((*childP )->core.window)); |
| 271 | } |
| 272 | } |
| 273 | |
| 274 | |
| 275 | if (lw > h_space) { |
| 276 | AssignMax(w, lw){if ((lw) > (w)) w = (lw);}; |
| 277 | h += lh + bbw->box.v_space; |
| 278 | } |
| 279 | |
| 280 | *reply_width = Max(w, 1)(((w) > (1)) ? (w) : (1)); |
| 281 | *reply_height = Max(h, 1)(((h) > (1)) ? (h) : (1)); |
| 282 | } |
| 283 | |
| 284 | |
| 285 | |
| 286 | |
| 287 | |
| 288 | |
| 289 | |
| 290 | static XtGeometryResult |
| 291 | PreferredSize(Widget widget, XtWidgetGeometry *constraint, XtWidgetGeometry *preferred) |
| 292 | { |
| 293 | BoxWidget w = (BoxWidget)widget; |
| 294 | Dimension width ; |
| 295 | Dimension preferred_width = w->box.preferred_width; |
| 296 | Dimension preferred_height = w->box.preferred_height; |
| 297 | |
| 298 | constraint->request_mode &= CWWidth(1<<2) | CWHeight(1<<3); |
| 299 | |
| 300 | if (constraint->request_mode == 0) |
| |
| 301 | |
| 302 | return XtGeometryYes; |
| 303 | |
| 304 | if (constraint->request_mode == w->box.last_query_mode && |
| 305 | (!(constraint->request_mode & CWWidth(1<<2)) || |
| 306 | constraint->width == w->box.last_query_width) && |
| 307 | (!(constraint->request_mode & CWHeight(1<<3)) || |
| 308 | constraint->height == w->box.last_query_height)) { |
| 309 | |
| 310 | preferred->request_mode = CWWidth(1<<2) | CWHeight(1<<3); |
| 311 | preferred->width = preferred_width; |
| 312 | preferred->height = preferred_height; |
| 313 | if (constraint->request_mode == (CWWidth(1<<2) | CWHeight(1<<3)) && |
| 314 | constraint->width == preferred_width && |
| 315 | constraint->height == preferred_height) |
| 316 | return XtGeometryYes; |
| 317 | else |
| 318 | return XtGeometryAlmost; |
| 319 | } |
| 320 | |
| 321 | |
| 322 | |
| 323 | |
| 324 | |
| 325 | |
| 326 | w->box.last_query_mode = constraint->request_mode; |
| 327 | w->box.last_query_width = constraint->width; |
| 6 | | Assigned value is garbage or undefined |
|
| 328 | w->box.last_query_height= constraint->height; |
| 329 | |
| 330 | if (constraint->request_mode & CWWidth(1<<2)) |
| 331 | width = constraint->width; |
| 332 | else { |
| 333 | |
| 334 | width = 0; |
| 335 | constraint->width = 65535; |
| 336 | } |
| 337 | |
| 338 | |
| 339 | |
| 340 | |
| 341 | |
| 342 | DoLayout(w, width, (Dimension)0, |
| 343 | &preferred_width, &preferred_height, FALSE0); |
| 344 | |
| 345 | if (constraint->request_mode & CWHeight(1<<3) && |
| 346 | preferred_height > constraint->height) { |
| 347 | |
| 348 | if (preferred_width > constraint->width) { |
| 349 | |
| 350 | } |
| 351 | else { |
| 352 | width = preferred_width; |
| 353 | do { |
| 354 | if (width > (constraint->width >> 1)) |
| 355 | width = constraint->width; |
| 356 | else |
| 357 | width <<= 1; |
| 358 | DoLayout(w, width, 0, &preferred_width, &preferred_height, FALSE0); |
| 359 | } while (preferred_height > constraint->height |
| 360 | && width < constraint->width); |
| 361 | if (width != constraint->width) { |
| 362 | do { |
| 363 | width = preferred_width; |
| 364 | DoLayout(w, preferred_width-1, 0, |
| 365 | &preferred_width, &preferred_height, FALSE0); |
| 366 | } while (preferred_height < constraint->height); |
| 367 | |
| 368 | DoLayout(w, width, 0, &preferred_width, &preferred_height, FALSE0); |
| 369 | } |
| 370 | } |
| 371 | } |
| 372 | |
| 373 | preferred->request_mode = CWWidth(1<<2) | CWHeight(1<<3); |
| 374 | preferred->width = w->box.preferred_width = preferred_width; |
| 375 | preferred->height = w->box.preferred_height = preferred_height; |
| 376 | |
| 377 | if (constraint->request_mode == (CWWidth(1<<2)|CWHeight(1<<3)) |
| 378 | && constraint->width == preferred_width |
| 379 | && constraint->height == preferred_height) |
| 380 | return XtGeometryYes; |
| 381 | else |
| 382 | return XtGeometryAlmost; |
| 383 | |
| 384 | } |
| 385 | |
| 386 | |
| 387 | |
| 388 | |
| 389 | |
| 390 | |
| 391 | |
| 392 | static void |
| 393 | Resize(Widget w) |
| 394 | { |
| 395 | Dimension junk; |
| 396 | |
| 397 | DoLayout((BoxWidget)w, w->core.width, w->core.height, &junk, &junk, TRUE1); |
| 398 | |
| 399 | } |
| 400 | |
| 401 | |
| 402 | |
| 403 | |
| 404 | |
| 405 | |
| 406 | |
| 407 | |
| 408 | |
| 409 | |
| 410 | static Boolean |
| 411 | TryNewLayout(BoxWidget bbw) |
| 412 | { |
| 413 | Dimension preferred_width, preferred_height; |
| 414 | Dimension proposed_width, proposed_height; |
| 415 | int iterations; |
| 416 | |
| 417 | DoLayout( bbw, bbw->core.width, bbw->core.height, |
| 418 | &preferred_width, &preferred_height, FALSE0 ); |
| 419 | |
| 420 | |
| 421 | |
| 422 | |
| 423 | |
| 424 | if ((bbw->core.width == preferred_width) && |
| 425 | (bbw->core.height == preferred_height)) { |
| 426 | |
| 427 | return (TRUE1); |
| 428 | } |
| 429 | |
| 430 | |
| 431 | iterations = 0; |
| 432 | proposed_width = preferred_width; |
| 433 | proposed_height = preferred_height; |
| 434 | do { |
| 435 | switch (XtMakeResizeRequest((Widget)bbw,proposed_width,proposed_height, |
| 2 | | Control jumps to 'case XtGeometryAlmost:' at line 452 | |
|
| 436 | &proposed_width, &proposed_height)) |
| 437 | { |
| 438 | case XtGeometryYes: |
| 439 | return (TRUE1); |
| 440 | |
| 441 | case XtGeometryNo: |
| 442 | if (iterations > 0) |
| 443 | |
| 444 | DoLayout( bbw, bbw->core.width, bbw->core.height, |
| 445 | &preferred_width, &preferred_height, FALSE0 ); |
| 446 | if ((preferred_width <= bbw->core.width) && |
| 447 | (preferred_height <= bbw->core.height)) |
| 448 | return (TRUE1); |
| 449 | else |
| 450 | return (FALSE0); |
| 451 | |
| 452 | case XtGeometryAlmost: |
| 453 | if (proposed_height >= preferred_height && |
| 454 | proposed_width >= preferred_width) { |
| 455 | |
| 456 | |
| 457 | |
| 458 | |
| 459 | |
| 460 | |
| 461 | |
| 462 | |
| 463 | (void) XtMakeResizeRequest( (Widget)bbw, |
| 464 | proposed_width, proposed_height, |
| 465 | &proposed_width, &proposed_height); |
| 466 | return(TRUE1); |
| 467 | } |
| 468 | else if (proposed_width != preferred_width) { |
| |
| 469 | |
| 470 | DoLayout(bbw, proposed_width, 0, |
| 471 | &preferred_width, &preferred_height, FALSE0); |
| 472 | proposed_height = preferred_height; |
| 473 | } |
| 474 | else { |
| 475 | XtWidgetGeometry constraints, reply; |
| 476 | constraints.request_mode = CWHeight(1<<3); |
| 477 | constraints.height = proposed_height; |
| 478 | (void)PreferredSize((Widget)bbw, &constraints, &reply); |
| |
| 479 | proposed_width = preferred_width; |
| 480 | } |
| 481 | break; |
| 482 | |
| 483 | case XtGeometryDone: |
| 484 | default: |
| 485 | break; |
| 486 | } |
| 487 | iterations++; |
| 488 | } while (iterations < 10); |
| 489 | return (FALSE0); |
| 490 | } |
| 491 | |
| 492 | |
| 493 | |
| 494 | |
| 495 | |
| 496 | |
| 497 | |
| 498 | |
| 499 | |
| 500 | |
| 501 | static XtGeometryResult |
| 502 | GeometryManager(Widget w, XtWidgetGeometry *request, XtWidgetGeometry *reply) |
| 503 | { |
| 504 | Dimension width, height, borderWidth; |
| 505 | BoxWidget bbw; |
| 506 | |
| 507 | |
| 508 | if ((request->request_mode & CWX(1<<0) && request->x != w->core.x) || |
| 509 | (request->request_mode & CWY(1<<1) && request->y != w->core.y)) |
| 510 | return (XtGeometryNo); |
| 511 | |
| 512 | |
| 513 | if (request->request_mode & (CWWidth(1<<2) | CWHeight(1<<3) | CWBorderWidth(1<<4))) { |
| 514 | |
| 515 | |
| 516 | if ((request->request_mode & CWWidth(1<<2)) == 0) |
| 517 | request->width = w->core.width; |
| 518 | if ((request->request_mode & CWHeight(1<<3)) == 0) |
| 519 | request->height = w->core.height; |
| 520 | if ((request->request_mode & CWBorderWidth(1<<4)) == 0) |
| 521 | request->border_width = w->core.border_width; |
| 522 | |
| 523 | |
| 524 | width = w->core.width; |
| 525 | height = w->core.height; |
| 526 | borderWidth = w->core.border_width; |
| 527 | w->core.width = request->width; |
| 528 | w->core.height = request->height; |
| 529 | w->core.border_width = request->border_width; |
| 530 | |
| 531 | |
| 532 | |
| 533 | |
| 534 | |
| 535 | bbw = (BoxWidget) w->core.parent; |
| 536 | |
| 537 | |
| 538 | |
| 539 | |
| 540 | |
| 541 | |
| 542 | |
| 543 | |
| 544 | |
| 545 | if (TryNewLayout(bbw)) { |
| 546 | |
| 547 | (*XtClass((Widget)bbw)(((Widget)bbw)->core.widget_class)->core_class.resize)((Widget)bbw); |
| 548 | return (XtGeometryYes); |
| 549 | } else { |
| 550 | |
| 551 | w->core.width = width; |
| 552 | w->core.height = height; |
| 553 | w->core.border_width = borderWidth; |
| 554 | return (XtGeometryNo); |
| 555 | } |
| 556 | }; |
| 557 | |
| 558 | |
| 559 | return (XtGeometryYes); |
| 560 | } |
| 561 | |
| 562 | static void |
| 563 | ChangeManaged(Widget w) |
| 564 | { |
| 565 | |
| 566 | (void) TryNewLayout((BoxWidget)w); |
| |
| 567 | Resize(w); |
| 568 | } |
| 569 | |
| 570 | static void |
| 571 | ClassInitialize(void) |
| 572 | { |
| 573 | XawInitializeWidgetSet(); |
| 574 | XtAddConverter( XtRString((char*)&XtStrings[1797]), XtROrientation((char*)&XtStrings[1742]), XmuCvtStringToOrientation, |
| 575 | (XtConvertArgList)NULL((void*)0), (Cardinal)0 ); |
| 576 | } |
| 577 | |
| 578 | |
| 579 | static void |
| 580 | Initialize(Widget request, Widget new, ArgList args, Cardinal *num_args) |
| 581 | { |
| 582 | BoxWidget newbbw = (BoxWidget)new; |
| 583 | |
| 584 | newbbw->box.last_query_mode = CWWidth(1<<2) | CWHeight(1<<3); |
| 585 | newbbw->box.last_query_width = newbbw->box.last_query_height = 0; |
| 586 | newbbw->box.preferred_width = Max(newbbw->box.h_space, 1)(((newbbw->box.h_space) > (1)) ? (newbbw->box.h_space ) : (1)); |
| 587 | newbbw->box.preferred_height = Max(newbbw->box.v_space, 1)(((newbbw->box.v_space) > (1)) ? (newbbw->box.v_space ) : (1)); |
| 588 | |
| 589 | if (newbbw->core.width == 0) |
| 590 | newbbw->core.width = newbbw->box.preferred_width; |
| 591 | |
| 592 | if (newbbw->core.height == 0) |
| 593 | newbbw->core.height = newbbw->box.preferred_height; |
| 594 | |
| 595 | } |
| 596 | |
| 597 | static void |
| 598 | Realize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes) |
| 599 | { |
| 600 | attributes->bit_gravity = NorthWestGravity1; |
| 601 | *valueMask |= CWBitGravity(1L<<4); |
| 602 | |
| 603 | XtCreateWindow( w, (unsigned)InputOutput1, (Visual *)CopyFromParent0L, |
| 604 | *valueMask, attributes); |
| 605 | } |
| 606 | |
| 607 | |
| 608 | static Boolean |
| 609 | SetValues(Widget current, Widget request, Widget new, ArgList args, Cardinal *num_args) |
| 610 | { |
| 611 | |
| 612 | |
| 613 | return False0; |
| 614 | } |