1 /*---------------------------------------------------------------------------- 2 -- 3 -- Module: XitRwPixButton 4 -- 5 -- Project: XitRw - Rogge's Motif widgets 6 -- System: <> 7 -- Subsystem: <> 8 -- Function block: <> 9 -- 10 -- Description: 11 -- This is the implementation file for the widget. 12 -- A Pix button can display both a text and a pixmap. 13 -- 14 -- Filename: xitRwPixB.c 15 -- 16 -- Authors: Roger Larsson, Ulrika Bornetun 17 -- Creation date: 1992-10-17 18 -- 19 -- 20 -- (C) Copyright Ulrika Bornetun, Roger Larsson (1995) 21 -- All rights reserved 22 -- 23 -- Permission to use, copy, modify, and distribute this software and its 24 -- documentation for any purpose and without fee is hereby granted, 25 -- provided that the above copyright notice appear in all copies. Ulrika 26 -- Bornetun and Roger Larsson make no representations about the usability 27 -- of this software for any purpose. It is provided "as is" without express 28 -- or implied warranty. 29 ----------------------------------------------------------------------------*/ 30 31 /* SCCS module identifier. */ 32 static char SCCSID[] = "@(#) Module: xitRwPixB.c, Version: 1.1, Date: 95/02/18 15:10:46"; 33 34 35 /*---------------------------------------------------------------------------- 36 -- Include files 37 ----------------------------------------------------------------------------*/ 38 39 #include <stdio.h> 40 41 #include <X11/IntrinsicP.h> 42 #include <X11/StringDefs.h> 43 44 #include <Xm/XmP.h> 45 #include <xitTools.h> 46 47 #if XmVersion > 1001 48 # include <Xm/PrimitiveP.h> 49 #endif 50 51 #include "xitRwPixBP.h" 52 53 54 /*---------------------------------------------------------------------------- 55 -- Macro definitions 56 ----------------------------------------------------------------------------*/ 57 58 #define max( a, b ) ((a) < (b) ? (b) : (a) ) 59 60 #define DEFAULT_MARGIN 2 61 #define DEFAULT_MARGIN_NULL 0 62 #define INSENS_WIDTH 10 63 #define INSENS_HEIGHT 10 64 65 #define XmRPixmapPosition "PixmapPosition" 66 67 68 /*---------------------------------------------------------------------------- 69 -- Type declarations 70 ----------------------------------------------------------------------------*/ 71 72 typedef int pixmapPosition; 73 74 75 /*---------------------------------------------------------------------------- 76 -- Global definitions 77 ----------------------------------------------------------------------------*/ 78 79 static void 80 Activate( Widget w, 81 XEvent *event ); 82 83 static void 84 Arm( Widget w, 85 XEvent *event ); 86 87 static void 88 ArmAndActivate( Widget w, 89 XEvent *event ); 90 91 static void 92 Disarm( Widget w, 93 XEvent *event, 94 String *params, 95 Cardinal num_params ); 96 97 static void 98 Enter( Widget w, 99 XEvent *event, 100 String *params, 101 Cardinal num_params ); 102 103 static void 104 PixButFocusIn( Widget w, 105 XEvent *event, 106 String *params, 107 Cardinal num_params ); 108 109 static void 110 PixButFocusOut( Widget w, 111 XEvent *event, 112 String *params, 113 Cardinal num_params ); 114 115 static void 116 Leave( Widget w, 117 XEvent *event, 118 String *params, 119 Cardinal num_params ); 120 121 static void 122 TraverseNextTabGroup( Widget w, 123 XEvent *event, 124 String *params, 125 Cardinal num_params ); 126 127 static void 128 TraversePrevTabGroup( Widget w, 129 XEvent *event, 130 String *params, 131 Cardinal num_params ); 132 133 static void 134 TraverseDown( Widget w, 135 XEvent *event, 136 String *params, 137 Cardinal num_params ); 138 static void 139 TraverseHome( Widget w, 140 XEvent *event, 141 String *params, 142 Cardinal num_params ); 143 static void 144 TraverseLeft( Widget w, 145 XEvent *event, 146 String *params, 147 Cardinal num_params ); 148 static void 149 TraverseRight( Widget w, 150 XEvent *event, 151 String *params, 152 Cardinal num_params ); 153 static void 154 TraverseUp( Widget w, 155 XEvent *event, 156 String *params, 157 Cardinal num_params ); 158 159 static void 160 Unmap( Widget w, 161 XEvent *event, 162 String *params, 163 Cardinal num_params ); 164 165 166 /* Resource converters. */ 167 static void 168 ConvertToPixmapPosition( XrmValue *args, 169 Cardinal *num_args, 170 XrmValue *from, 171 XrmValue *to ); 172 173 /* Resource list. */ 174 static XtResource resources[] = { 175 { 176 XmNactivateCallback, 177 XmCCallback, 178 XmRCallback, sizeof( XtCallbackList ), 179 XtOffset( XitRwPixButtonWidget, pixBut.activate_callback ), 180 XmRPointer, 181 (XtPointer) NULL 182 }, 183 { 184 XmNalignment, 185 XmCAlignment, 186 XmRAlignment, sizeof( unsigned char ), 187 XtOffset( XitRwPixButtonWidget, pixBut.alignment ), 188 XmRImmediate, 189 (XtPointer) XmALIGNMENT_CENTER 190 }, 191 { 192 XmNarmCallback, 193 XmCCallback, 194 XmRCallback, sizeof( XtCallbackList ), 195 XtOffset( XitRwPixButtonWidget, pixBut.arm_callback ), 196 XmRPointer, 197 (XtPointer) NULL 198 }, 199 { 200 XmNdisarmCallback, 201 XmCCallback, 202 XmRCallback, sizeof( XtCallbackList ), 203 XtOffset( XitRwPixButtonWidget, pixBut.disarm_callback ), 204 XmRPointer, 205 (XtPointer) NULL 206 }, 207 { 208 XmNfontList, 209 XmCFontList, 210 XmRFontList, sizeof( XmFontList ), 211 XtOffset( XitRwPixButtonWidget, pixBut.font_list ), 212 XmRString, 213 (XtPointer) "Fixed" 214 }, 215 { 216 XmNlabelPixmap, 217 XmCLabelPixmap, 218 XmRInt, sizeof( Pixmap ), 219 XtOffset( XitRwPixButtonWidget, pixBut.pixmap ), 220 XtRImmediate, 221 (XtPointer) XmUNSPECIFIED_PIXMAP 222 }, 223 { 224 XmNlabelString, 225 XmCLabelString, 226 XmRString, sizeof( XmString ), 227 XtOffset( XitRwPixButtonWidget, pixBut.label ), 228 XtRImmediate, 229 NULL 230 }, 231 { 232 XmNmarginHeight, 233 XmCMarginHeight, 234 XtRInt, sizeof( int ), 235 XtOffset( XitRwPixButtonWidget, pixBut.margin_height ), 236 XtRImmediate, 237 (XtPointer) DEFAULT_MARGIN 238 }, 239 { 240 XmNmarginWidth, 241 XmCMarginWidth, 242 XtRInt, sizeof( int ), 243 XtOffset( XitRwPixButtonWidget, pixBut.margin_width ), 244 XtRImmediate, 245 (XtPointer) DEFAULT_MARGIN 246 }, 247 { 248 XmNmarginTop, 249 XmCMarginTop, 250 XtRInt, sizeof( int ), 251 XtOffset( XitRwPixButtonWidget, pixBut.top_margin ), 252 XtRImmediate, 253 (XtPointer) DEFAULT_MARGIN_NULL 254 }, 255 { 256 XmNmarginLeft, 257 XmCMarginLeft, 258 XtRInt, sizeof( int ), 259 XtOffset( XitRwPixButtonWidget, pixBut.left_margin ), 260 XtRImmediate, 261 (XtPointer) DEFAULT_MARGIN_NULL 262 }, 263 { 264 XmNmarginRight, 265 XmCMarginRight, 266 XtRInt, sizeof( int ), 267 XtOffset( XitRwPixButtonWidget, pixBut.right_margin ), 268 XtRImmediate, 269 (XtPointer) DEFAULT_MARGIN_NULL 270 }, 271 { 272 XmNmarginBottom, 273 XmCMarginBottom, 274 XtRInt, sizeof( int ), 275 XtOffset( XitRwPixButtonWidget, pixBut.bottom_margin ), 276 XtRImmediate, 277 (XtPointer) DEFAULT_MARGIN_NULL 278 }, 279 { 280 XitRwNoppositeAlignment, 281 XmCAlignment, 282 XmRAlignment, sizeof( unsigned char ), 283 XtOffset( XitRwPixButtonWidget, pixBut.opposite_alignment ), 284 XmRImmediate, 285 (XtPointer) XmALIGNMENT_CENTER 286 }, 287 { 288 XitRwNpixmapPosition, 289 XitRwCPixmapPosition, 290 XmRPixmapPosition, sizeof( int ), 291 XtOffset( XitRwPixButtonWidget, pixBut.pixmap_position ), 292 XtRImmediate, 293 (XtPointer) XitRwLEFT 294 }, 295 { 296 XmNrecomputeSize, 297 XmCRecomputeSize, 298 XtRBoolean, sizeof( Boolean ), 299 XtOffset( XitRwPixButtonWidget, pixBut.recompute_size ), 300 XtRImmediate, 301 (XtPointer) True 302 }, 303 { 304 XmNshadowType, 305 XmCShadowType, 306 XmRShadowType, sizeof( unsigned char ), 307 XtOffset( XitRwPixButtonWidget, pixBut.shadow_type ), 308 XmRImmediate, 309 (XtPointer) XmSHADOW_OUT 310 }, 311 { 312 XmNspacing, 313 XmCSpacing, 314 XtRInt, sizeof( int ), 315 XtOffset( XitRwPixButtonWidget, pixBut.spacing ), 316 XtRImmediate, 317 (XtPointer) DEFAULT_MARGIN 318 }, 319 }; 320 321 322 /* Pixmap for insensitive pixmap. */ 323 static unsigned char insens_bits[] = { 324 0x55, 0x01, 0xaa, 0x02, 0x55, 0x01, 0xaa, 0x02, 0x55, 0x01, 0xaa, 0x02, 325 0x55, 0x01, 0xaa, 0x02, 0x55, 0x01, 0xaa, 0x02}; 326 327 /* Action list. */ 328 static XtActionsRec actionsList[] = 329 { 330 { "Activate", (XtActionProc) Activate }, 331 { "Arm", (XtActionProc) Arm }, 332 { "ArmAndActivate", (XtActionProc) ArmAndActivate }, 333 { "PrimitiveNextTabGroup", (XtActionProc) TraverseNextTabGroup }, 334 { "PrimitivePrevTabGroup", (XtActionProc) TraversePrevTabGroup }, 335 { "PrimitiveTabDown", (XtActionProc) TraverseDown }, 336 { "PrimitiveTabHome", (XtActionProc) TraverseHome }, 337 { "PrimitiveTabLeft", (XtActionProc) TraverseLeft }, 338 { "PrimitiveTabRight", (XtActionProc) TraverseRight }, 339 { "PrimitiveTabUp", (XtActionProc) TraverseUp }, 340 { "Disarm", (XtActionProc) Disarm }, 341 { "Enter", (XtActionProc) Enter }, 342 { "FocusIn", (XtActionProc) PixButFocusIn }, 343 { "FocusOut", (XtActionProc) PixButFocusOut }, 344 { "Leave", (XtActionProc) Leave }, 345 { "Unmap", (XtActionProc) Unmap }, 346 }; 347 348 349 /* Default translation list. */ 350 static char defaultTranslations[] = 351 "<Btn1Down>: Arm() \n\ 352 <Btn1Up>: Activate() Disarm() \n\ 353 <EnterWindow>: Enter() \n\ 354 <FocusIn>: FocusIn() \n\ 355 <FocusOut>: FocusOut() \n\ 356 <LeaveWindow>: Leave() \n\ 357 <Key>Return: ArmAndActivate() \n\ 358 <Key>space: ArmAndActivate() \n\ 359 <Key>Home: PrimitiveTabHome() \n\ 360 <Key>Down: PrimitiveTabDown() \n\ 361 <Key>Left: PrimitiveTabLeft() \n\ 362 <Key>Right: PrimitiveTabRight() \n\ 363 <Key>Up: PrimitiveTabUp() \n\ 364 <Key>osfDown: PrimitiveTabDown() \n\ 365 <Key>osfLeft: PrimitiveTabLeft() \n\ 366 <Key>osfRight: PrimitiveTabRight() \n\ 367 <Key>osfUp: PrimitiveTabUp() \n\ 368 ~Ctrl ~Alt ~Meta ~Shift<Key>Tab: PrimitiveNextTabGroup() \n\ 369 ~Ctrl ~Alt ~Meta Shift<Key>Tab: PrimitivePrevTabGroup() \n\ 370 <Unmap>: Unmap()"; 371 372 373 /* Quarks. */ 374 static XrmQuark quark_bottom; 375 static XrmQuark quark_left; 376 static XrmQuark quark_right; 377 static XrmQuark quark_top; 378 379 380 381 /*---------------------------------------------------------------------------- 382 -- Function prototypes 383 ----------------------------------------------------------------------------*/ 384 385 /* Core methods. */ 386 static void 387 ClassInitialize(); 388 389 static void 390 Destroy( Widget widget ); 391 392 static void 393 ExposeIt( Widget widget, 394 XEvent *event, 395 Region region ); 396 397 static void 398 Initialize( Widget treq, 399 Widget tnew, 400 ArgList args, 401 Cardinal *num_args ); 402 403 static XtGeometryResult 404 QueryGeometry( Widget widget, 405 XtWidgetGeometry *proposed, 406 XtWidgetGeometry *answer ); 407 408 static void 409 Resize( Widget widget ); 410 411 static Boolean 412 SetValues( Widget current, 413 Widget request, 414 Widget new, 415 ArgList args, 416 Cardinal *num_args ); 417 418 /* These core methods are not needed. 419 -- 420 -- static void Realize(); 421 -- 422 */ 423 424 /* Local functions. */ 425 static void 426 DesiredDimensions( Widget widget, 427 Boolean override_no_recompute, 428 Dimension *width, 429 Dimension *height ); 430 431 static void 432 DrawButton( Widget widget, 433 Boolean draw_as_armed ); 434 435 static void 436 DrawShadow( Widget widget, 437 Boolean armed ); 438 439 static void 440 GetDrawingGC( Widget widget ); 441 442 static void 443 SetComponentDimensions( Widget widget ); 444 445 static void 446 SetComponentPositions( Widget widget ); 447 448 449 /*---------------------------------------------------------------------------- 450 -- Initialization of the class record. 451 ----------------------------------------------------------------------------*/ 452 453 /* This initialization has to be done after the methods have been declared. */ 454 XitRwPixButtonClassRec xitRwPixButtonClassRec = { 455 456 { /* Core class fields. */ 457 /* superclass */ (WidgetClass) &xmPrimitiveClassRec, 458 /* class_name */ "XitRwPixButton", 459 /* widget_size */ sizeof( XitRwPixButtonRec ), 460 /* class_initialize */ ClassInitialize, 461 /* class_part_initialize */ NULL, 462 /* class_inited */ False, 463 /* initialize */ Initialize, 464 /* initialize_hook */ NULL, 465 /* realize */ XtInheritRealize, 466 /* actions */ actionsList, 467 /* num_actions */ XtNumber( actionsList ), 468 /* resources */ resources, 469 /* num_resources */ XtNumber( resources ), 470 /* xrm_class */ NULLQUARK, 471 /* compress_motion */ True, 472 /* compress_exposure */ True, 473 /* compress_enterleave */ True, 474 /* visible_interest */ False, 475 /* destroy */ Destroy, 476 /* resize */ Resize, 477 /* expose */ ExposeIt, 478 /* set_values */ SetValues, 479 /* set_values_hook */ NULL, 480 /* set_values_almost */ XtInheritSetValuesAlmost, 481 /* get_values_hook */ NULL, 482 /* accept_focus */ NULL, 483 /* version */ XtVersion, 484 /* callback_private */ NULL, 485 /* tm_table */ defaultTranslations, 486 /* query_geometry */ QueryGeometry, 487 /* display_accelerator */ XtInheritDisplayAccelerator, 488 /* extension */ NULL 489 }, 490 { /* Primitive class part. */ 491 /* border_highlight */ (XtWidgetProc) _XtInherit, 492 /* border_unhighlight */ (XtWidgetProc) _XtInherit, 493 /* translations */ NULL, 494 #if XmVersion < 1002 495 /* arm_and_activate */ (XmArmAndActivate) ArmAndActivate, 496 #else 497 /* arm_and_activate */ (XtActionProc) ArmAndActivate, 498 #endif 499 /* get_resources */ NULL, 500 /* num_get_resources */ 0, 501 /* extension */ NULL 502 }, 503 { /* PixBut button class part. */ 504 /* extension */ NULL 505 }, 506 507 }; /* XitRwPixButtonClassRec */ 508 509 510 /* Class record pointer. */ 511 WidgetClass 512 xitRwPixButtonWidgetClass = (WidgetClass) &xitRwPixButtonClassRec; 513 514 515 /*---------------------------------------------------------------------------- 516 -- Functions 517 ----------------------------------------------------------------------------*/ 518 519 static void Activate(Widget w,XEvent * event)520 Activate( Widget w, 521 XEvent *event ) 522 { 523 524 /* Variables. */ 525 XitRwPixButtonWidget cb; 526 XmAnyCallbackStruct callback_info; 527 528 529 /* Code. */ 530 531 cb = (XitRwPixButtonWidget) w; 532 533 /* Event outside window? */ 534 if( ((event->type == ButtonPress) || 535 (event->type == ButtonRelease)) && 536 ((event->xbutton.x > cb -> core.width) || 537 (event->xbutton.y > cb -> core.height )) ) 538 return; 539 540 541 /* Callback. */ 542 if( cb -> pixBut.activate_callback != NULL ) { 543 544 /* Prepare callback data. */ 545 callback_info.reason = XmCR_ACTIVATE; 546 callback_info.event = event; 547 548 /* Call the activate callback. */ 549 XtCallCallbacks( (Widget) cb, XmNactivateCallback, 550 (XtPointer) &callback_info ); 551 552 } 553 554 return; 555 556 } /* Activate */ 557 558 559 /*---------------------------------------------------------------------------*/ 560 561 static void Arm(Widget w,XEvent * event)562 Arm( Widget w, 563 XEvent *event ) 564 { 565 566 /* Variables. */ 567 XitRwPixButtonWidget cb; 568 XmAnyCallbackStruct callback_info; 569 570 571 /* Code. */ 572 573 cb = (XitRwPixButtonWidget) w; 574 575 /* Grab traversal. */ 576 /* Grab focus. */ 577 XmProcessTraversal( w, XmTRAVERSE_CURRENT ); 578 579 cb -> pixBut.armed = True; 580 DrawButton( (Widget) cb, True ); 581 582 if( cb -> pixBut.arm_callback != NULL ) { 583 XFlush( XtDisplay( (Widget) cb ) ); 584 585 /* Prepare callback data. */ 586 callback_info.reason = XmCR_ARM; 587 callback_info.event = event; 588 589 XtCallCallbacks( (Widget) cb, XmNarmCallback, (XtPointer) &callback_info ); 590 } 591 592 593 return; 594 595 } /* Arm */ 596 597 598 /*---------------------------------------------------------------------------*/ 599 600 static void ArmAndActivate(Widget w,XEvent * event)601 ArmAndActivate( Widget w, 602 XEvent *event ) 603 { 604 605 /* Variables. */ 606 XitRwPixButtonWidget cb; 607 608 /* Code. */ 609 cb = (XitRwPixButtonWidget) w; 610 611 /* Activate called by keyboard event. Arm during callback. */ 612 Arm( w, event ); 613 614 Activate( w, event ); 615 616 /* Disarm and draw it. */ 617 cb -> pixBut.armed = False; 618 DrawButton( (Widget) cb, False ); 619 620 XFlush( XtDisplay( (Widget) cb )); 621 622 623 return; 624 625 } /* ArmAndActivate */ 626 627 628 /*---------------------------------------------------------------------------*/ 629 630 static void ClassInitialize()631 ClassInitialize() 632 { 633 634 /* Code. */ 635 636 /* Convert quarks for comparison. */ 637 quark_bottom = XrmStringToQuark( "BOTTOM" ); 638 quark_left = XrmStringToQuark( "LEFT" ); 639 quark_right = XrmStringToQuark( "RIGHT" ); 640 quark_top = XrmStringToQuark( "TOP" ); 641 642 /* Register type converter for XitRwCPixmapPosition. */ 643 XtAddConverter( XmRString, XmRPixmapPosition, ConvertToPixmapPosition, 644 NULL, 0 ); 645 646 647 return; 648 649 } /* ClassInitialize */ 650 651 652 /*---------------------------------------------------------------------------*/ 653 654 static void ConvertToPixmapPosition(XrmValue * args,Cardinal * num_args,XrmValue * from,XrmValue * to)655 ConvertToPixmapPosition( XrmValue *args, 656 Cardinal *num_args, 657 XrmValue *from, 658 XrmValue *to ) 659 { 660 661 /* Variables. */ 662 XrmQuark quark_resource; 663 static int pixmap_value; 664 665 666 /* Code. */ 667 668 if( *num_args != 0 ) 669 XtWarningMsg( "wrongParameters", "ConvertToPixmapPosition", 670 "XtToolkitError", "Conversion needs no extra arguments", 671 (String *) NULL, (Cardinal *) NULL ); 672 673 /* Convert argument. */ 674 quark_resource = XrmStringToQuark( from -> addr ); 675 676 if( quark_resource == quark_bottom ) 677 pixmap_value = XitRwBOTTOM; 678 else if( quark_resource == quark_left ) 679 pixmap_value = XitRwLEFT; 680 else if( quark_resource == quark_right ) 681 pixmap_value = XitRwRIGHT; 682 else if( quark_resource == quark_top ) 683 pixmap_value = XitRwTOP; 684 else { 685 XtWarningMsg( "wrongParameters", "ConvertToPixmapPosition", 686 "XtToolkitError", "Cannot convert to type pixmapPosition", 687 (String *) NULL, (Cardinal *) 0 ); 688 pixmap_value = XitRwLEFT; 689 } 690 691 (*to).size = sizeof( int ); 692 (*to).addr = (XtPointer) &pixmap_value; 693 694 695 return; 696 697 } /* ConvertToPixmapPosition */ 698 699 700 /*---------------------------------------------------------------------------*/ 701 702 static void DesiredDimensions(Widget widget,Boolean override_no_recompute,Dimension * width,Dimension * height)703 DesiredDimensions( Widget widget, 704 Boolean override_no_recompute, 705 Dimension *width, 706 Dimension *height ) 707 { 708 709 /* Variables. */ 710 XitRwPixButtonWidget cb; 711 712 713 /* Code. */ 714 715 cb = (XitRwPixButtonWidget) widget; 716 717 if( cb -> pixBut.user_set_width || 718 ( !cb -> pixBut.recompute_size && !override_no_recompute ) ) 719 *width = cb -> core.width; 720 721 /* Adapt size to contents. */ 722 else { 723 /* Basic margins are always counted. */ 724 *width = (Dimension)( 2 * cb -> pixBut.margin_width + 725 cb -> pixBut.left_margin + 726 cb -> pixBut.right_margin + 727 2 * (int) cb -> primitive.shadow_thickness + 728 2 * (int) cb -> primitive.highlight_thickness ); 729 730 switch( cb -> pixBut.pixmap_position ) { 731 732 case XitRwLEFT: 733 case XitRwRIGHT: 734 /* Horizontal organization. */ 735 *width += (Dimension) ( cb -> pixBut.spacing + 736 cb -> pixBut.pixmap_width + 737 cb -> pixBut.string_width ); 738 break; 739 740 case XitRwTOP: 741 case XitRwBOTTOM: 742 /* Vertical organization. */ 743 *width += max( (Dimension) cb -> pixBut.string_width, 744 (Dimension) cb -> pixBut.pixmap_width ); 745 break; 746 747 } /* switch */ 748 } 749 750 if( cb -> pixBut.user_set_height || 751 ( !cb -> pixBut.recompute_size && !override_no_recompute ) ) 752 *height = cb -> core.height; 753 754 /* Adapt size to contents. */ 755 else { 756 *height = (Dimension)( 2 * cb -> pixBut.margin_height + 757 cb -> pixBut.top_margin + 758 cb -> pixBut.bottom_margin + 759 2 * (int) cb -> primitive.shadow_thickness + 760 2 * (int) cb -> primitive.highlight_thickness ); 761 762 switch( cb -> pixBut.pixmap_position ) { 763 764 case XitRwLEFT: 765 case XitRwRIGHT: 766 /* Horizontal organization. */ 767 *height += max( (Dimension) cb -> pixBut.string_height, 768 (Dimension) cb -> pixBut.pixmap_height ); 769 break; 770 771 case XitRwTOP: 772 case XitRwBOTTOM: 773 /* Vertical organization. */ 774 *height += (Dimension) ( cb -> pixBut.spacing + 775 cb -> pixBut.pixmap_height + 776 cb -> pixBut.string_height ); 777 break; 778 779 } /* switch */ 780 781 } 782 783 784 return; 785 786 } /* DesiredDimensions */ 787 788 789 /*---------------------------------------------------------------------------*/ 790 791 static void Destroy(Widget widget)792 Destroy( Widget widget ) 793 { 794 795 /* Variables. */ 796 XitRwPixButtonWidget cb; 797 798 799 /* Code. */ 800 801 cb = (XitRwPixButtonWidget) widget; 802 803 /* Free gc's */ 804 if( cb -> pixBut.gc != NULL ) 805 XtReleaseGC( (Widget) cb, cb -> pixBut.gc ); 806 807 if( cb -> pixBut.clear_gc != NULL ) 808 XtReleaseGC( (Widget) cb, cb -> pixBut.clear_gc ); 809 810 if( cb -> pixBut.select_gc != NULL ) 811 XtReleaseGC( (Widget) cb, cb -> pixBut.select_gc ); 812 813 if( cb -> pixBut.select_clear_gc != NULL ) 814 XtReleaseGC( (Widget) cb, cb -> pixBut.select_clear_gc ); 815 816 if( cb -> pixBut.insensitive_gc != NULL ) 817 XtReleaseGC( (Widget) cb, cb -> pixBut.insensitive_gc ); 818 819 /* Free allocated string. */ 820 if( cb -> pixBut.label != NULL ) 821 XmStringFree( cb -> pixBut.label ); 822 823 /* Free insensitive pixmap. */ 824 if( cb -> pixBut.insensitive_pixmap != (XID) NULL ) 825 XFreePixmap( XtDisplay( (Widget) cb ), cb -> pixBut.insensitive_pixmap ); 826 827 828 return; 829 830 } /* Destroy */ 831 832 833 /*---------------------------------------------------------------------------*/ 834 835 static void Disarm(Widget w,XEvent * event,String * params,Cardinal num_params)836 Disarm( Widget w, 837 XEvent *event, 838 String *params, 839 Cardinal num_params ) 840 { 841 842 /* Variables. */ 843 XitRwPixButtonWidget cb; 844 XmAnyCallbackStruct callback_info; 845 846 847 /* Code. */ 848 849 cb = (XitRwPixButtonWidget) w; 850 851 if( cb -> pixBut.armed ) { 852 cb -> pixBut.armed = False; 853 DrawButton( (Widget) cb, False ); 854 } 855 856 if( cb -> pixBut.disarm_callback != NULL ) { 857 XFlush( XtDisplay( (Widget) cb ) ); 858 859 /* Prepare callback data. */ 860 callback_info.reason = XmCR_DISARM; 861 callback_info.event = event; 862 863 XtCallCallbacks( (Widget) cb, XmNdisarmCallback, 864 (XtPointer) &callback_info ); 865 } 866 867 868 return; 869 870 } /* Disarm */ 871 872 873 /*---------------------------------------------------------------------------*/ 874 875 static void DrawButton(Widget widget,Boolean draw_as_armed)876 DrawButton( Widget widget, 877 Boolean draw_as_armed ) 878 { 879 #if XmVERSION > 1 880 /* these Motif 1.1 calls are obsoleted in Motif 2.0 */ 881 /* they aren't declared by any Motif 2.0 header file */ 882 /* 040597 RXTN */ 883 extern void _XmHighlightBorder( Widget ); 884 extern void _XmUnhighlightBorder( Widget ); 885 #endif 886 887 /* Variables. */ 888 GC clear_gc; 889 GC normal_gc; 890 XitRwPixButtonWidget cb; 891 892 893 /* Code. */ 894 895 cb = (XitRwPixButtonWidget) widget; 896 897 clear_gc = ( draw_as_armed ? cb -> pixBut.select_clear_gc : 898 cb -> pixBut.clear_gc ); 899 normal_gc = ( draw_as_armed ? cb -> pixBut.select_gc : 900 cb -> pixBut.gc ); 901 902 903 /* Clear the button for redraw. */ 904 XFillRectangle( XtDisplay( widget ), cb -> core.window, 905 clear_gc, 0, 0, 906 (unsigned int) cb -> core.width, 907 (unsigned int) cb -> core.height ); 908 909 /* Draw pixmap. */ 910 if( cb -> pixBut.pixmap != XmUNSPECIFIED_PIXMAP ) 911 XCopyArea( XtDisplay( widget ), cb -> pixBut.pixmap, 912 cb -> core.window, normal_gc, 0, 0, 913 cb -> pixBut.pixmap_width, 914 cb -> pixBut.pixmap_height, 915 cb -> pixBut.x_pixmap, 916 cb -> pixBut.y_pixmap ); 917 918 /* Draw string. */ 919 if( cb -> pixBut.label != NULL ) 920 XmStringDraw( XtDisplay( widget ), 921 cb -> core.window, cb -> pixBut.font_list, 922 cb -> pixBut.label, normal_gc, 923 cb -> pixBut.x_string, cb -> pixBut.y_string, 924 (Dimension) cb -> pixBut.string_width, 925 XmALIGNMENT_BEGINNING, 926 XmSTRING_DIRECTION_L_TO_R, NULL ); 927 928 /* Insensitive state. Stipple it. */ 929 if( ! cb -> core.sensitive ) 930 XFillRectangle( XtDisplay( widget ), cb -> core.window, 931 cb -> pixBut.insensitive_gc, 932 0, 0, 933 (unsigned int) cb -> core.width, 934 (unsigned int) cb -> core.height ); 935 936 /* Shadows. */ 937 DrawShadow( (Widget) cb, draw_as_armed ); 938 939 /* Highlight? */ 940 if( cb -> primitive.highlighted ) 941 _XmHighlightBorder( (Widget) cb ); 942 else 943 _XmUnhighlightBorder( (Widget) cb ); 944 945 946 } /* DrawButton */ 947 948 949 /*---------------------------------------------------------------------------*/ 950 951 static void DrawShadow(Widget widget,Boolean armed)952 DrawShadow( Widget widget, 953 Boolean armed ) 954 { 955 956 /* Variables. */ 957 Boolean shadow_in; 958 GC bottom_gc; 959 GC top_gc; 960 XitRwPixButtonWidget cb; 961 962 963 /* Code. */ 964 965 if( ! xitIsRealized( widget ) ) 966 return; 967 968 cb = (XitRwPixButtonWidget) widget; 969 970 if( cb -> primitive.shadow_thickness == 0 ) 971 return; 972 973 974 /* Find out shadow type. */ 975 shadow_in = (( cb -> pixBut.shadow_type == XmSHADOW_IN ) && !armed ) || 976 (( cb -> pixBut.shadow_type == XmSHADOW_OUT ) && armed ); 977 978 if( shadow_in ) { 979 top_gc = cb -> primitive.bottom_shadow_GC; 980 bottom_gc = cb -> primitive.top_shadow_GC; 981 } else { 982 top_gc = cb -> primitive.top_shadow_GC; 983 bottom_gc = cb -> primitive.bottom_shadow_GC; 984 } 985 986 /* _XmDrawShadow is superseded in Motif 2.0 */ 987 _XmDrawShadow( XtDisplay( widget ), XtWindow( widget ), 988 top_gc, bottom_gc, 989 cb -> primitive.shadow_thickness, 990 cb -> primitive.highlight_thickness, 991 cb -> primitive.highlight_thickness, 992 (int) cb -> core.width - 993 2 * cb -> primitive.highlight_thickness, 994 (int) cb -> core.height - 995 2 * cb -> primitive.highlight_thickness ); 996 997 return; 998 999 } /* DrawShadow */ 1000 1001 1002 /*---------------------------------------------------------------------------*/ 1003 1004 static void Enter(Widget w,XEvent * event,String * params,Cardinal num_params)1005 Enter( Widget w, 1006 XEvent *event, 1007 String *params, 1008 Cardinal num_params ) 1009 { 1010 1011 /* Variables. */ 1012 XitRwPixButtonWidget cb; 1013 1014 1015 /* Code. */ 1016 1017 cb = (XitRwPixButtonWidget) w; 1018 1019 #if XmVersion > 1001 1020 _XmPrimitiveEnter( (Widget) cb, event, NULL, NULL ); 1021 #else 1022 _XmPrimitiveEnter( (XmPrimitiveWidget) cb, event ); 1023 #endif 1024 1025 /* Only bother to redraw if the widget is armed. */ 1026 if( cb -> pixBut.armed ) 1027 DrawButton( (Widget) cb, True ); 1028 1029 1030 return; 1031 1032 } /* Enter */ 1033 1034 1035 /*---------------------------------------------------------------------------*/ 1036 1037 static void ExposeIt(Widget widget,XEvent * event,Region region)1038 ExposeIt( Widget widget, 1039 XEvent *event, 1040 Region region ) 1041 { 1042 1043 /* Variables. */ 1044 XitRwPixButtonWidget cb; 1045 1046 1047 /* Code. */ 1048 1049 cb = (XitRwPixButtonWidget) widget; 1050 1051 DrawButton( (Widget) cb, cb -> pixBut.armed ); 1052 1053 1054 return; 1055 1056 } /* ExposeIt */ 1057 1058 1059 /*---------------------------------------------------------------------------*/ 1060 1061 static void PixButFocusIn(Widget w,XEvent * event,String * params,Cardinal num_params)1062 PixButFocusIn( Widget w, 1063 XEvent *event, 1064 String *params, 1065 Cardinal num_params ) 1066 { 1067 1068 XitRwPixButtonWidget cb; 1069 1070 /* Code. */ 1071 1072 cb = (XitRwPixButtonWidget) w; 1073 1074 #if XmVersion > 1001 1075 _XmPrimitiveFocusIn( (Widget) w, event, NULL, NULL ); 1076 #else 1077 _XmPrimitiveFocusIn( (XmPrimitiveWidget) w, event ); 1078 #endif 1079 1080 DrawButton( (Widget) cb, cb -> pixBut.armed ); 1081 1082 1083 return; 1084 1085 } /* PixButFocusIn */ 1086 1087 1088 /*---------------------------------------------------------------------------*/ 1089 1090 static void PixButFocusOut(Widget w,XEvent * event,String * params,Cardinal num_params)1091 PixButFocusOut( Widget w, 1092 XEvent *event, 1093 String *params, 1094 Cardinal num_params ) 1095 { 1096 1097 XitRwPixButtonWidget cb; 1098 1099 /* Code. */ 1100 1101 cb = (XitRwPixButtonWidget) w; 1102 1103 DrawButton( (Widget) cb, cb -> pixBut.armed ); 1104 1105 #if XmVersion > 1001 1106 _XmPrimitiveFocusOut( (Widget) w, event, NULL, NULL ); 1107 #else 1108 _XmPrimitiveFocusOut( (XmPrimitiveWidget) w, event ); 1109 #endif 1110 1111 1112 return; 1113 1114 } /* PixButFocusOut */ 1115 1116 1117 /*---------------------------------------------------------------------------*/ 1118 1119 static void GetDrawingGC(Widget widget)1120 GetDrawingGC( Widget widget ) 1121 { 1122 1123 /* Variables. */ 1124 XFontStruct *font; 1125 XGCValues gc_values; 1126 XitRwPixButtonWidget cb; 1127 Pixel select_color; 1128 1129 1130 /* Code. */ 1131 1132 cb = (XitRwPixButtonWidget) widget; 1133 1134 /* Get font for GC, Take first font in list. */ 1135 { 1136 XmFontContext context; 1137 XmStringCharSet char_set; 1138 1139 (void) XmFontListInitFontContext( &context, cb -> pixBut.font_list ); 1140 (void) XmFontListGetNextFont( context, &char_set, &font ); 1141 XmFontListFreeFontContext( context ); 1142 XtFree( char_set ); 1143 } /* block */ 1144 1145 /* Get the background color for armed state. */ 1146 { 1147 Pixel dummy; 1148 1149 XmGetColors( XtScreen( (Widget) cb ), 1150 DefaultColormapOfScreen( XtScreen( (Widget) cb )), 1151 cb -> core.background_pixel, &dummy, &dummy, &dummy, 1152 &select_color ); 1153 } 1154 1155 /* Use a shareable GC. */ 1156 if( cb -> pixBut.gc != NULL ) 1157 XtReleaseGC( (Widget) cb, cb -> pixBut.gc ); 1158 1159 gc_values.foreground = cb -> primitive.foreground; 1160 gc_values.background = cb -> core.background_pixel; 1161 gc_values.font = font -> fid; 1162 1163 cb -> pixBut.gc = XtGetGC( (Widget) cb, 1164 GCForeground | GCBackground | GCFont, 1165 &gc_values ); 1166 1167 1168 /* The clear_gc for clearing the window. */ 1169 if( cb -> pixBut.clear_gc != NULL ) 1170 XtReleaseGC( (Widget) cb, cb -> pixBut.clear_gc ); 1171 1172 gc_values.foreground = cb -> core.background_pixel; 1173 gc_values.background = cb -> primitive.foreground; 1174 gc_values.fill_style = FillSolid; 1175 1176 cb -> pixBut.clear_gc = XtGetGC( (Widget) cb, 1177 GCForeground | GCBackground | GCFillStyle, 1178 &gc_values ); 1179 1180 /* The select_gc for drawing the button in its armed state. */ 1181 if( cb -> pixBut.select_gc != NULL ) 1182 XtReleaseGC( (Widget) cb, cb -> pixBut.select_gc ); 1183 1184 gc_values.foreground = cb -> primitive.foreground; 1185 gc_values.background = select_color; 1186 gc_values.font = font -> fid; 1187 cb -> pixBut.select_gc = XtGetGC( (Widget) cb, 1188 GCForeground | GCBackground | GCFont, 1189 &gc_values ); 1190 1191 /* The select_clear_gc for clearing the pixmap when armed. */ 1192 if( cb -> pixBut.select_clear_gc != NULL ) 1193 XtReleaseGC( (Widget) cb, cb -> pixBut.select_clear_gc ); 1194 1195 gc_values.foreground = select_color; 1196 gc_values.background = cb -> primitive.foreground; 1197 gc_values.fill_style = FillSolid; 1198 cb -> pixBut.select_clear_gc = XtGetGC( (Widget) cb, 1199 GCForeground | GCBackground, 1200 &gc_values ); 1201 1202 /* The insensitive GC for insensitive state. */ 1203 if( cb -> pixBut.insensitive_gc != NULL ) 1204 XtReleaseGC( (Widget) cb, cb -> pixBut.insensitive_gc ); 1205 1206 gc_values.foreground = cb -> core.background_pixel; 1207 gc_values.stipple = cb -> pixBut.insensitive_pixmap; 1208 gc_values.fill_style = FillStippled; 1209 1210 cb -> pixBut.insensitive_gc = 1211 XtGetGC( (Widget) cb, 1212 GCForeground | GCStipple | GCFillStyle, 1213 &gc_values ); 1214 1215 return; 1216 1217 } /* GetDrawingGC */ 1218 1219 1220 /*---------------------------------------------------------------------------*/ 1221 1222 static void Initialize(Widget treq,Widget tnew,ArgList args,Cardinal * num_args)1223 Initialize( Widget treq, 1224 Widget tnew, 1225 ArgList args, 1226 Cardinal *num_args ) 1227 { 1228 1229 /* Variables. */ 1230 XitRwPixButtonWidget new; 1231 XmString tmp_label; 1232 1233 1234 /* Code. */ 1235 1236 new = (XitRwPixButtonWidget) tnew; 1237 1238 /* Reset all private fields. */ 1239 new -> pixBut.gc = NULL; 1240 new -> pixBut.clear_gc = NULL; 1241 new -> pixBut.select_gc = NULL; 1242 new -> pixBut.select_clear_gc = NULL; 1243 new -> pixBut.insensitive_gc = NULL; 1244 new -> pixBut.pixmap_width = 0; 1245 new -> pixBut.pixmap_height = 0; 1246 new -> pixBut.string_width = 0; 1247 new -> pixBut.string_height = 0; 1248 new -> pixBut.x_pixmap = 0; 1249 new -> pixBut.y_pixmap = 0; 1250 new -> pixBut.x_string = 0; 1251 new -> pixBut.y_string = 0; 1252 new -> pixBut.user_set_width = False; 1253 new -> pixBut.user_set_height = False; 1254 new -> pixBut.armed = False; 1255 1256 /* Copy label string. */ 1257 if( new -> pixBut.label != NULL ){ 1258 1259 tmp_label = XmStringCopy( new -> pixBut.label ); 1260 new -> pixBut.label = tmp_label; 1261 } 1262 1263 /* Check the dimensions of the stuff to be displayed. */ 1264 SetComponentDimensions( (Widget) new ); 1265 1266 /* Get our initial size. */ 1267 DesiredDimensions( (Widget) new, True, &new -> core.width, 1268 &new -> core.height ); 1269 1270 /* Avoid trying to create a widget with zero width and/or height. */ 1271 if( new -> core.width <= 0 ) 1272 new -> core.width = 10; 1273 if( new -> core.height <= 0 ) 1274 new -> core.height = 10; 1275 1276 /* Lay out components within the window. */ 1277 SetComponentPositions( (Widget) new ); 1278 1279 /* Create insensitive pixmap. */ 1280 new -> pixBut.insensitive_pixmap = 1281 XCreateBitmapFromData( XtDisplay( (Widget) new ), 1282 RootWindowOfScreen( XtScreen( (Widget) new )), 1283 (char *) insens_bits, 1284 INSENS_WIDTH, INSENS_HEIGHT ); 1285 1286 /* Create GC for drawing. */ 1287 GetDrawingGC( (Widget) new ); 1288 1289 1290 return; 1291 1292 } /* Initialize */ 1293 1294 1295 /*---------------------------------------------------------------------------*/ 1296 1297 static void Leave(Widget w,XEvent * event,String * params,Cardinal num_params)1298 Leave( Widget w, 1299 XEvent *event, 1300 String *params, 1301 Cardinal num_params ) 1302 { 1303 1304 /* Variables. */ 1305 XitRwPixButtonWidget cb; 1306 1307 1308 /* Code. */ 1309 1310 cb = (XitRwPixButtonWidget) w; 1311 1312 #if XmVersion > 1001 1313 _XmPrimitiveLeave( (Widget) cb, event, NULL, NULL ); 1314 #else 1315 _XmPrimitiveLeave( (XmPrimitiveWidget) cb, event ); 1316 #endif 1317 1318 /* Only bother to redraw if the widget is armed. */ 1319 if( cb -> pixBut.armed ) 1320 DrawButton( (Widget) cb, False ); 1321 1322 1323 return; 1324 1325 } /* Leave */ 1326 1327 1328 /*---------------------------------------------------------------------------*/ 1329 1330 static XtGeometryResult QueryGeometry(Widget widget,XtWidgetGeometry * proposed,XtWidgetGeometry * answer)1331 QueryGeometry( Widget widget, 1332 XtWidgetGeometry *proposed, 1333 XtWidgetGeometry *answer ) 1334 { 1335 1336 /* Variables. */ 1337 XitRwPixButtonWidget cb; 1338 1339 1340 /* Code. */ 1341 1342 cb = (XitRwPixButtonWidget) widget; 1343 1344 /* Suggest the calculated width and height. */ 1345 answer -> request_mode = CWWidth | CWHeight; 1346 1347 DesiredDimensions( (Widget) cb, False, &answer -> width, &answer -> height ); 1348 1349 /* Check if our calculated dimensions correspond to the propsed ones. */ 1350 if( (( proposed -> request_mode & ( CWWidth | CWHeight )) == 1351 ( CWWidth | CWHeight )) && 1352 ( proposed -> width == answer -> width ) && 1353 ( proposed -> height == answer -> height ) ) 1354 return( XtGeometryYes ); 1355 1356 else if( ( answer -> width == cb -> core.width ) && 1357 ( answer -> height == cb -> core.height ) ) 1358 return( XtGeometryNo ); 1359 1360 else 1361 return( XtGeometryAlmost ); 1362 1363 1364 } /* QueryGeometry */ 1365 1366 1367 /*---------------------------------------------------------------------------*/ 1368 1369 static void Resize(Widget widget)1370 Resize( Widget widget ) 1371 { 1372 1373 /* Variables. */ 1374 XitRwPixButtonWidget cb; 1375 1376 1377 /* Code. */ 1378 1379 cb = (XitRwPixButtonWidget) widget; 1380 1381 /* When this method is called, the parameter widget structure contains the 1382 new values for width, height and border width. We must obey. */ 1383 1384 /* Calculate positions of the components. */ 1385 SetComponentPositions( (Widget) cb ); 1386 1387 /* X will generate an expose event and we can draw the button in the 1388 expose method. */ 1389 1390 return; 1391 1392 1393 } /* Resize */ 1394 1395 1396 /*---------------------------------------------------------------------------*/ 1397 1398 static void SetComponentDimensions(Widget widget)1399 SetComponentDimensions( Widget widget ) 1400 { 1401 1402 /* Variables. */ 1403 int x; 1404 int y; 1405 unsigned int border_width; 1406 unsigned int depth; 1407 unsigned int pixmap_height; 1408 unsigned int pixmap_width; 1409 Dimension string_height; 1410 Dimension string_width; 1411 Window root_window; 1412 XitRwPixButtonWidget cb; 1413 1414 1415 /* Code. */ 1416 1417 cb = (XitRwPixButtonWidget) widget; 1418 1419 /* Get the dimensions of the stuff that shall be displayed. */ 1420 1421 /* Pixmap. */ 1422 if( cb -> pixBut.pixmap != XmUNSPECIFIED_PIXMAP ) 1423 XGetGeometry( XtDisplay( widget ), cb -> pixBut.pixmap, &root_window, 1424 &x, &y, &pixmap_width, &pixmap_height, &border_width, 1425 &depth ); 1426 else { 1427 pixmap_height = 0; 1428 pixmap_width = 0; 1429 } 1430 1431 1432 /* String. */ 1433 if( cb -> pixBut.label != NULL ){ 1434 string_height = XmStringHeight( cb -> pixBut.font_list, 1435 cb -> pixBut.label ); 1436 string_width = XmStringWidth( cb -> pixBut.font_list, 1437 cb -> pixBut.label ); 1438 } else { 1439 string_height = 0; 1440 string_width = 0; 1441 } 1442 1443 cb -> pixBut.pixmap_height = (int) pixmap_height; 1444 cb -> pixBut.pixmap_width = (int) pixmap_width; 1445 cb -> pixBut.string_height = (int) string_height; 1446 cb -> pixBut.string_width = (int) string_width; 1447 1448 1449 return; 1450 1451 } /* SetComponentDimensions */ 1452 1453 1454 /*---------------------------------------------------------------------------*/ 1455 1456 static void SetComponentPositions(Widget widget)1457 SetComponentPositions( Widget widget ) 1458 { 1459 1460 /* Variables. */ 1461 int basic_bottom_offset; 1462 int basic_left_offset; 1463 int basic_right_offset; 1464 int basic_top_offset; 1465 int middle_x_pos; 1466 int middle_y_pos; 1467 XitRwPixButtonWidget cb; 1468 1469 1470 /* Code. */ 1471 1472 cb = (XitRwPixButtonWidget) widget; 1473 1474 basic_left_offset = cb -> primitive.shadow_thickness + 1475 cb -> primitive.highlight_thickness + 1476 cb -> pixBut.margin_width + 1477 cb -> pixBut.left_margin; 1478 1479 basic_top_offset = cb -> primitive.shadow_thickness + 1480 cb -> primitive.highlight_thickness + 1481 cb -> pixBut.margin_height + 1482 cb -> pixBut.top_margin; 1483 1484 basic_right_offset = cb -> primitive.shadow_thickness + 1485 cb -> primitive.highlight_thickness + 1486 cb -> pixBut.margin_width + 1487 cb -> pixBut.right_margin; 1488 1489 basic_bottom_offset = cb -> primitive.shadow_thickness + 1490 cb -> primitive.highlight_thickness + 1491 cb -> pixBut.margin_height + 1492 cb -> pixBut.bottom_margin; 1493 1494 middle_x_pos = (( cb -> core.width - basic_left_offset - 1495 basic_right_offset ) / 2 ) + basic_left_offset; 1496 1497 middle_y_pos = (( cb -> core.height - basic_top_offset - 1498 basic_bottom_offset ) / 2 ) + basic_top_offset; 1499 1500 1501 /* X position. */ 1502 switch( cb -> pixBut.pixmap_position ){ 1503 1504 case XitRwLEFT: 1505 /* Horizontal layout. Pixmap to the left. */ 1506 1507 switch( cb -> pixBut.alignment ){ 1508 case XmALIGNMENT_BEGINNING: 1509 cb -> pixBut.x_pixmap = basic_left_offset; 1510 cb -> pixBut.x_string = cb -> pixBut.x_pixmap + 1511 cb -> pixBut.pixmap_width + 1512 cb -> pixBut.spacing; 1513 break; 1514 1515 case XmALIGNMENT_END: 1516 cb -> pixBut.x_string = cb -> core.width - basic_right_offset - 1517 cb -> pixBut.string_width; 1518 cb -> pixBut.x_pixmap = cb -> pixBut.x_string - 1519 cb -> pixBut.spacing - 1520 cb -> pixBut.pixmap_width; 1521 break; 1522 1523 case XmALIGNMENT_CENTER: 1524 cb -> pixBut.x_pixmap = middle_x_pos - ( cb -> pixBut.pixmap_width + 1525 cb -> pixBut.spacing + 1526 cb -> pixBut.string_width ) / 2; 1527 cb -> pixBut.x_string = cb -> pixBut.x_pixmap + 1528 cb -> pixBut.pixmap_width + 1529 cb -> pixBut.spacing; 1530 break; 1531 } 1532 1533 break; 1534 1535 case XitRwRIGHT: 1536 /* Horizontal layout. Pixmap to the right. */ 1537 1538 switch( cb -> pixBut.alignment ){ 1539 case XmALIGNMENT_BEGINNING: 1540 cb -> pixBut.x_string = basic_left_offset; 1541 cb -> pixBut.x_pixmap = cb -> pixBut.x_string + 1542 cb -> pixBut.string_width + 1543 cb -> pixBut.spacing; 1544 break; 1545 1546 case XmALIGNMENT_END: 1547 cb -> pixBut.x_pixmap = cb -> core.width - basic_right_offset - 1548 cb -> pixBut.pixmap_width; 1549 cb -> pixBut.x_string = cb -> pixBut.x_pixmap - 1550 cb -> pixBut.spacing - 1551 cb -> pixBut.string_width; 1552 break; 1553 1554 case XmALIGNMENT_CENTER: 1555 /* Center the components. */ 1556 cb -> pixBut.x_string = middle_x_pos - 1557 (cb -> pixBut.pixmap_width + 1558 cb -> pixBut.spacing + 1559 cb -> pixBut.string_width) / 2; 1560 cb -> pixBut.x_pixmap = cb -> pixBut.x_string + 1561 cb -> pixBut.string_width + 1562 cb -> pixBut.spacing; 1563 break; 1564 } 1565 1566 break; 1567 1568 case XitRwTOP: 1569 case XitRwBOTTOM: 1570 /* Vertical organization. */ 1571 1572 /* Components should be centered in the horizontal dimension. */ 1573 cb -> pixBut.x_string = middle_x_pos - (cb -> pixBut.string_width / 2); 1574 cb -> pixBut.x_pixmap = middle_x_pos - (cb -> pixBut.pixmap_width / 2); 1575 1576 break; 1577 1578 } 1579 1580 /* Y position. */ 1581 switch( cb -> pixBut.pixmap_position ){ 1582 1583 case XitRwTOP: 1584 /* Vertical layout. Pixmap over string. */ 1585 1586 switch( cb -> pixBut.alignment ){ 1587 case XmALIGNMENT_BEGINNING: 1588 cb -> pixBut.y_pixmap = basic_top_offset; 1589 cb -> pixBut.y_string = cb -> pixBut.y_pixmap + 1590 cb -> pixBut.pixmap_height + 1591 cb -> pixBut.spacing; 1592 break; 1593 1594 case XmALIGNMENT_END: 1595 /* As low as possible. */ 1596 cb -> pixBut.y_string = cb -> core.height - basic_bottom_offset - 1597 cb -> pixBut.string_height; 1598 cb -> pixBut.y_pixmap = cb -> pixBut.y_string - 1599 cb -> pixBut.spacing - 1600 cb -> pixBut.pixmap_height; 1601 break; 1602 1603 case XmALIGNMENT_CENTER: 1604 /* Center the components. */ 1605 cb -> pixBut.y_pixmap = middle_y_pos - 1606 (cb -> pixBut.pixmap_height + 1607 cb -> pixBut.spacing + 1608 cb -> pixBut.string_height) / 2; 1609 cb -> pixBut.y_string = cb -> pixBut.y_pixmap + 1610 cb -> pixBut.pixmap_height + 1611 cb -> pixBut.spacing; 1612 break; 1613 } 1614 1615 break; 1616 1617 case XitRwBOTTOM: 1618 /* Vertical layout. Pixmap under string. */ 1619 1620 switch( cb -> pixBut.alignment ){ 1621 case XmALIGNMENT_BEGINNING: 1622 cb -> pixBut.y_string = basic_top_offset; 1623 cb -> pixBut.y_pixmap = cb -> pixBut.y_string + 1624 cb -> pixBut.string_height + 1625 cb -> pixBut.spacing; 1626 break; 1627 1628 case XmALIGNMENT_END: 1629 cb -> pixBut.y_pixmap = cb -> core.height - basic_bottom_offset - 1630 cb -> pixBut.pixmap_height; 1631 cb -> pixBut.y_string = cb -> pixBut.y_pixmap - 1632 cb -> pixBut.spacing - 1633 cb -> pixBut.string_height; 1634 break; 1635 1636 case XmALIGNMENT_CENTER: 1637 cb -> pixBut.y_string = middle_y_pos - 1638 (cb -> pixBut.pixmap_height + 1639 cb -> pixBut.spacing + 1640 cb -> pixBut.string_height) / 2; 1641 cb -> pixBut.y_pixmap = cb -> pixBut.y_string + 1642 cb -> pixBut.string_height + 1643 cb -> pixBut.spacing; 1644 break; 1645 } 1646 1647 break; 1648 1649 case XitRwLEFT: 1650 case XitRwRIGHT: 1651 /* Horizontal organization. */ 1652 if( cb -> pixBut.string_height > cb -> core.height || 1653 cb -> pixBut.opposite_alignment == XmALIGNMENT_BEGINNING ) 1654 cb -> pixBut.y_string = basic_top_offset; 1655 else 1656 cb -> pixBut.y_string = middle_y_pos - 1657 (cb -> pixBut.string_height / 2); 1658 1659 cb -> pixBut.y_pixmap = middle_y_pos - (cb -> pixBut.pixmap_height / 2); 1660 1661 break; 1662 1663 } 1664 1665 1666 return; 1667 1668 } /* SetComponentPositions */ 1669 1670 1671 /*---------------------------------------------------------------------------*/ 1672 1673 static Boolean SetValues(Widget current,Widget request,Widget new,ArgList args,Cardinal * num_args)1674 SetValues( Widget current, 1675 Widget request, 1676 Widget new, 1677 ArgList args, 1678 Cardinal *num_args ) 1679 { 1680 1681 /* Variables. */ 1682 Boolean new_size; 1683 Boolean redraw = False; 1684 Dimension desired_height; 1685 Dimension desired_width; 1686 XitRwPixButtonWidget curW; 1687 XitRwPixButtonWidget newW; 1688 XmString tmp_label; 1689 1690 1691 /* Code. */ 1692 1693 curW = (XitRwPixButtonWidget) current; 1694 newW = (XitRwPixButtonWidget) new; 1695 1696 /* Initialize. */ 1697 new_size = False; 1698 1699 if( newW -> core.width != curW -> core.width ) { 1700 if( newW -> core.width == 0 ) { 1701 if( newW -> pixBut.user_set_width ) { 1702 newW -> pixBut.user_set_width = False; 1703 new_size = True; 1704 } else { 1705 newW -> core.width = curW -> core.width; 1706 } 1707 } else { 1708 newW -> pixBut.user_set_width = True; 1709 } 1710 } 1711 1712 if( newW -> core.height != curW -> core.height ) { 1713 if( newW -> core.height == 0 ) { 1714 if( newW -> pixBut.user_set_height ) { 1715 newW -> pixBut.user_set_height = False; 1716 new_size = True; 1717 } else { 1718 newW -> core.height = curW -> core.height; 1719 } 1720 } else { 1721 newW -> pixBut.user_set_height = True; 1722 } 1723 } 1724 1725 if( newW -> pixBut.font_list != curW -> pixBut.font_list ) 1726 new_size = True; 1727 1728 1729 if( newW -> pixBut.label != curW -> pixBut.label ) { 1730 if( curW -> pixBut.label != NULL ) 1731 XmStringFree( curW -> pixBut.label ); 1732 1733 tmp_label = XmStringCopy( newW -> pixBut.label ); 1734 newW -> pixBut.label = tmp_label; 1735 1736 new_size = True; 1737 } 1738 1739 1740 if( newW -> pixBut.pixmap != curW -> pixBut.pixmap ) 1741 new_size = True; 1742 1743 1744 /* Check if any resource values were changed that may affect other fields 1745 or require that the picture be redrawn. */ 1746 1747 if( ( newW -> pixBut.top_margin != curW -> pixBut.top_margin ) || 1748 ( newW -> pixBut.left_margin != curW -> pixBut.left_margin ) || 1749 ( newW -> pixBut.right_margin != curW -> pixBut.right_margin ) || 1750 ( newW -> pixBut.bottom_margin != curW -> pixBut.bottom_margin ) || 1751 ( newW -> pixBut.margin_width != curW -> pixBut.margin_width ) || 1752 ( newW -> pixBut.margin_height != curW -> pixBut.margin_height ) || 1753 ( newW -> pixBut.spacing != curW -> pixBut.spacing ) ) 1754 new_size = True; 1755 1756 if( newW -> core.sensitive != curW -> core.sensitive ) 1757 redraw = True; 1758 1759 /* Color change affects only gc and redraw. */ 1760 if( ( newW -> primitive.foreground != curW -> primitive.foreground ) || 1761 ( newW -> core.background_pixel != curW -> core.background_pixel ) || 1762 ( newW -> pixBut.font_list != curW -> pixBut.font_list ) ) { 1763 GetDrawingGC( (Widget) new ); 1764 redraw = True; 1765 } 1766 1767 /* Check if we want to resize ourselves. */ 1768 if( new_size ) { 1769 1770 redraw = True; 1771 1772 /* Size request must be based on new values. */ 1773 SetComponentDimensions( (Widget) new ); 1774 1775 DesiredDimensions( (Widget) new, False, &desired_width, &desired_height ); 1776 1777 SetComponentPositions( (Widget) new ); 1778 1779 1780 /* Only request new size if really needed. */ 1781 if( desired_width != curW -> core.width || 1782 desired_height != curW -> core.height || 1783 newW -> core.height == 0 || 1784 newW -> core.width == 0 ) { 1785 1786 new -> core.width = desired_width; 1787 new -> core.height = desired_height; 1788 1789 /* Should not change these according to the Xt documentation, but try. */ 1790 request -> core.width = desired_width; 1791 request -> core.height = desired_height; 1792 1793 } 1794 1795 } /* if */ 1796 1797 /* Redraw ourselves? */ 1798 return( redraw ); 1799 1800 1801 } /* SetValues */ 1802 1803 1804 /*---------------------------------------------------------------------------*/ 1805 1806 static void TraverseNextTabGroup(Widget w,XEvent * event,String * params,Cardinal num_params)1807 TraverseNextTabGroup( Widget w, 1808 XEvent *event, 1809 String *params, 1810 Cardinal num_params ) 1811 { 1812 /* Code. */ 1813 1814 XmProcessTraversal( w, XmTRAVERSE_NEXT_TAB_GROUP ); 1815 1816 1817 return; 1818 1819 } /* TraverseNextTabGroup */ 1820 1821 /*---------------------------------------------------------------------------*/ 1822 1823 static void TraversePrevTabGroup(Widget w,XEvent * event,String * params,Cardinal num_params)1824 TraversePrevTabGroup( Widget w, 1825 XEvent *event, 1826 String *params, 1827 Cardinal num_params ) 1828 { 1829 /* Code. */ 1830 1831 XmProcessTraversal( w, XmTRAVERSE_PREV_TAB_GROUP ); 1832 1833 1834 return; 1835 1836 } /* TraversePrevTabGroup */ 1837 1838 /*---------------------------------------------------------------------------*/ 1839 1840 static void TraverseDown(Widget w,XEvent * event,String * params,Cardinal num_params)1841 TraverseDown( Widget w, 1842 XEvent *event, 1843 String *params, 1844 Cardinal num_params ) 1845 { 1846 /* Code. */ 1847 1848 XmProcessTraversal( w, XmTRAVERSE_DOWN ); 1849 1850 1851 return; 1852 1853 } /* TraverseDown */ 1854 1855 /*---------------------------------------------------------------------------*/ 1856 1857 static void TraverseHome(Widget w,XEvent * event,String * params,Cardinal num_params)1858 TraverseHome( Widget w, 1859 XEvent *event, 1860 String *params, 1861 Cardinal num_params ) 1862 { 1863 /* Code. */ 1864 1865 XmProcessTraversal( w, XmTRAVERSE_HOME ); 1866 1867 1868 return; 1869 1870 } /* TraverseHome */ 1871 1872 /*---------------------------------------------------------------------------*/ 1873 1874 static void TraverseLeft(Widget w,XEvent * event,String * params,Cardinal num_params)1875 TraverseLeft( Widget w, 1876 XEvent *event, 1877 String *params, 1878 Cardinal num_params ) 1879 { 1880 /* Code. */ 1881 1882 XmProcessTraversal( w, XmTRAVERSE_LEFT ); 1883 1884 1885 return; 1886 1887 } /* TraverseLeft */ 1888 1889 /*---------------------------------------------------------------------------*/ 1890 1891 static void TraverseRight(Widget w,XEvent * event,String * params,Cardinal num_params)1892 TraverseRight( Widget w, 1893 XEvent *event, 1894 String *params, 1895 Cardinal num_params ) 1896 { 1897 /* Code. */ 1898 1899 XmProcessTraversal( w, XmTRAVERSE_RIGHT ); 1900 1901 1902 return; 1903 1904 } /* TraverseRight */ 1905 1906 /*---------------------------------------------------------------------------*/ 1907 1908 static void TraverseUp(Widget w,XEvent * event,String * params,Cardinal num_params)1909 TraverseUp( Widget w, 1910 XEvent *event, 1911 String *params, 1912 Cardinal num_params ) 1913 { 1914 /* Code. */ 1915 1916 XmProcessTraversal( w, XmTRAVERSE_UP ); 1917 1918 1919 return; 1920 1921 } /* TraverseUp */ 1922 1923 /*---------------------------------------------------------------------------*/ 1924 1925 static void Unmap(Widget w,XEvent * event,String * params,Cardinal num_params)1926 Unmap( Widget w, 1927 XEvent *event, 1928 String *params, 1929 Cardinal num_params ) 1930 { 1931 1932 /* Variables. */ 1933 XitRwPixButtonWidget cb; 1934 1935 1936 /* Code. */ 1937 1938 cb = (XitRwPixButtonWidget) w; 1939 1940 #if XmVersion > 1001 1941 _XmPrimitiveUnmap( (Widget) cb, event, NULL, NULL ); 1942 #else 1943 _XmPrimitiveUnmap( (XmPrimitiveWidget) cb, event ); 1944 #endif 1945 1946 /* We cannot allow the widget to stay armed if it disappears. */ 1947 cb -> pixBut.armed = False; 1948 1949 1950 return; 1951 1952 } /* Unmap */ 1953 1954 1955 /*---------------------------------------------------------------------------*/ 1956 1957 Boolean xitRwPixButIsArmed(Widget w)1958 xitRwPixButIsArmed( Widget w ) 1959 { 1960 1961 /* Code. */ 1962 1963 1964 return( ((XitRwPixButtonWidget) w) -> pixBut.armed ); 1965 1966 } /* xitRwPixButIsArmed */ 1967