1 /*---------------------------------------------------------------------------- 2 -- 3 -- Module: XmUbMonthDisplay 4 -- 5 -- Project: XmUb - Ulle's Motif widgets 6 -- System: 7 -- Subsystem: <> 8 -- Function block: <> 9 -- 10 -- Description: 11 -- This is the implementation of the widget. 12 -- 13 -- Filename: XmUbMonthD.c 14 -- 15 -- Authors: Roger Larsson, Ulrika Bornetun 16 -- Creation date: 1993-09-26 17 -- 18 -- 19 -- (C) Copyright Ulrika Bornetun, Roger Larsson (1995) 20 -- All rights reserved 21 -- 22 -- Permission to use, copy, modify, and distribute this software and its 23 -- documentation for any purpose and without fee is hereby granted, 24 -- provided that the above copyright notice appear in all copies. Ulrika 25 -- Bornetun and Roger Larsson make no representations about the usability 26 -- of this software for any purpose. It is provided "as is" without express 27 -- or implied warranty. 28 ----------------------------------------------------------------------------*/ 29 30 /* SCCS module identifier. */ 31 static char SCCSID[] = "@(#) Module: XmUbMonthD.c, Version: 1.2, Date: 95/06/21 20:47:47"; 32 33 34 /*---------------------------------------------------------------------------- 35 -- Include files 36 ----------------------------------------------------------------------------*/ 37 38 #include <stdio.h> 39 #include <string.h> 40 #include <assert.h> 41 #include <X11/Intrinsic.h> 42 #include <X11/StringDefs.h> 43 #include <X11/Xatom.h> 44 #include <Xm/XmP.h> 45 46 #if XmVersion > 1001 47 #include <Xm/AtomMgr.h> 48 #include <Xm/DragDrop.h> 49 #endif 50 51 #include <Xm/Label.h> 52 #include <Xm/PushB.h> 53 #include <Xm/RowColumn.h> 54 #include <Xm/Separator.h> 55 56 /* Rogge's tools. */ 57 #include "TimDate.h" 58 59 /* Private widget header file. */ 60 #include "XmUbMonthDP.h" 61 62 /* Other widgets. */ 63 #include "XmUbArrLab.h" 64 65 /* Drag and drop. */ 66 #if XmVersion > 1001 67 #include "XmUbDragDrop.h" 68 #include "DateDragIcon.h" 69 #include "DateDragMask.h" 70 #include "DateDragInvIcon.h" 71 #include "DateDragInvIconMask.h" 72 #endif 73 74 /*---------------------------------------------------------------------------- 75 -- Macro definitions 76 ----------------------------------------------------------------------------*/ 77 78 #ifdef MAX 79 #undef MAX 80 #endif 81 82 #ifdef MIN 83 #undef MIN 84 #endif 85 86 #define MAX( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) 87 #define MIN( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) ) 88 89 #define XmUbMD_CHILD_ERROR -1 90 91 #define LABEL_BUFFER_LENGTH 30 92 #define TEXT_BUFFER_LENGTH 20 93 94 #define PREVIOUS_MONTH_OFFSET 100 95 #define NEXT_MONTH_OFFSET 200 96 97 #define TITLE_ID_USER_DATA 1 98 99 /*---------------------------------------------------------------------------- 100 -- Type declarations 101 ----------------------------------------------------------------------------*/ 102 103 typedef struct { 104 105 Dimension width; 106 Dimension height; 107 Position x; 108 Position y; 109 110 } KidDimensionRec; 111 112 /*---------------------------------------------------------------------------- 113 -- Global definitions 114 ----------------------------------------------------------------------------*/ 115 116 /* Internal Motif functions (how do we know about this....?) */ 117 extern void 118 _XmBackgroundColorDefault(); 119 extern void 120 _XmForegroundColorDefault(); 121 122 static char default_month_string[] = "Month"; 123 static char default_year_string[] = "Year"; 124 125 /* The month display resource list. */ 126 static XtResource resources[] = { 127 { 128 XmUbNmdiDateSelectedCallback, 129 XmCCallback, 130 XmRCallback, sizeof( XtCallbackList ), 131 XtOffset( XmUbMonthDisplayWidget, md.date_selected_callback ), 132 XmRCallback, 133 NULL 134 }, 135 { 136 XmUbNmdiNewMonthCallback, 137 XmCCallback, 138 XmRCallback, sizeof( XtCallbackList ), 139 XtOffset( XmUbMonthDisplayWidget, md.new_month_callback ), 140 XmRCallback, 141 NULL 142 }, 143 { 144 XmUbNmdiTitleCallback, 145 XmCCallback, 146 XmRCallback, sizeof( XtCallbackList ), 147 XtOffset( XmUbMonthDisplayWidget, md.title_callback ), 148 XmRImmediate, 149 (XtPointer) NULL 150 }, 151 { 152 XmNmarginHeight, 153 XmCMarginHeight, 154 XtRDimension, sizeof( Dimension ), 155 XtOffset( XmUbMonthDisplayWidget, md.margin_height ), 156 XtRImmediate, 157 (XtPointer) 0 158 }, 159 { 160 XmNmarginWidth, 161 XmCMarginWidth, 162 XtRDimension, sizeof( Dimension ), 163 XtOffset( XmUbMonthDisplayWidget, md.margin_width ), 164 XtRImmediate, 165 (XtPointer) 0 166 }, 167 { 168 XmUbNmdiOtherMonthForeground, 169 XmCForeground, 170 XtRPixel, sizeof( Pixel ), 171 XtOffset( XmUbMonthDisplayWidget, md.other_month_foreground ), 172 XmRCallProc, 173 (XtPointer) _XmForegroundColorDefault 174 }, 175 { 176 XmUbNmdiArrowSpacing, 177 XmCSpacing, 178 XtRDimension, sizeof( Dimension ), 179 XtOffset( XmUbMonthDisplayWidget, md.arrow_spacing ), 180 XtRImmediate, 181 (XtPointer) 2 182 }, 183 { 184 XmUbNmdiCurrentMonth, 185 XmUbCMdiCurrentMonth, 186 XtRInt, sizeof( int ), 187 XtOffset( XmUbMonthDisplayWidget, md.current_month ), 188 XtRImmediate, 189 (XtPointer) 0 190 }, 191 { 192 XmUbNmdiCurrentYear, 193 XmUbCMdiCurrentYear, 194 XtRInt, sizeof( int ), 195 XtOffset( XmUbMonthDisplayWidget, md.current_year ), 196 XtRImmediate, 197 (XtPointer) 0 198 }, 199 { 200 XmUbNmdiDayChars, 201 XmUbCMdiDayChars, 202 XtRInt, sizeof( int ), 203 XtOffset( XmUbMonthDisplayWidget, md.day_name_characters ), 204 XtRImmediate, 205 (XtPointer) 2 206 }, 207 { 208 XmUbNmdiEnableSeparator, 209 XmUbCMdiEnableSeparator, 210 XtRBoolean, sizeof( Boolean ), 211 XtOffset( XmUbMonthDisplayWidget, md.enable_separator ), 212 XtRImmediate, 213 (XtPointer) True 214 }, 215 { 216 XmUbNmdiFillOutWeek, 217 XmUbCMdiFillOutWeek, 218 XtRBoolean, sizeof( Boolean ), 219 XtOffset( XmUbMonthDisplayWidget, md.fill_out_week ), 220 XtRImmediate, 221 (XtPointer) True 222 }, 223 { 224 XmUbNmdiLabelSpacing, 225 XmCSpacing, 226 XtRDimension, sizeof( Dimension ), 227 XtOffset( XmUbMonthDisplayWidget, md.label_spacing ), 228 XtRImmediate, 229 (XtPointer) 2 230 }, 231 { 232 XmUbNmdiMonthLabel, 233 XmUbCMdiMonthLabel, 234 XmRXmString, sizeof( XmString ), 235 XtOffset( XmUbMonthDisplayWidget, md.month_label ), 236 XtRImmediate, 237 (XtPointer) NULL 238 }, 239 { 240 XmUbNmdiMonthArrows, 241 XmUbCMdiMonthArrows, 242 XtRBoolean, sizeof( Boolean ), 243 XtOffset( XmUbMonthDisplayWidget, md.month_arrows ), 244 XtRImmediate, 245 (XtPointer) True 246 }, 247 { 248 XmUbNmdiRecomputeHeight, 249 XmUbCMdiRecomputeHeight, 250 XtRBoolean, sizeof( Boolean ), 251 XtOffset( XmUbMonthDisplayWidget, md.recompute_height ), 252 XtRImmediate, 253 (XtPointer) True 254 }, 255 { 256 XmUbNmdiRecomputeWidth, 257 XmUbCMdiRecomputeWidth, 258 XtRBoolean, sizeof( Boolean ), 259 XtOffset( XmUbMonthDisplayWidget, md.recompute_width ), 260 XtRImmediate, 261 (XtPointer) True 262 }, 263 { 264 XmUbNmdiSaturdayForeground, 265 XmCForeground, 266 XtRPixel, sizeof( Pixel ), 267 XtOffset( XmUbMonthDisplayWidget, md.sat_foreground ), 268 XmRCallProc, 269 (XtPointer) _XmForegroundColorDefault 270 }, 271 { 272 XmUbNmdiSundayForeground, 273 XmCForeground, 274 XtRPixel, sizeof( Pixel ), 275 XtOffset( XmUbMonthDisplayWidget, md.sun_foreground ), 276 XmRCallProc, 277 (XtPointer) _XmForegroundColorDefault 278 }, 279 { 280 XmUbNmdiTitleAlignment, 281 XmCAlignment, 282 XmRAlignment, sizeof( unsigned char ), 283 XtOffset( XmUbMonthDisplayWidget, md.title_alignment ), 284 XtRImmediate, 285 (XtPointer) XmALIGNMENT_CENTER 286 }, 287 { 288 XmUbNmdiTitleShadows, 289 XmUbCMdiTitleShadows, 290 XtRBoolean, sizeof( Boolean ), 291 XtOffset( XmUbMonthDisplayWidget, md.title_shadows ), 292 XtRImmediate, 293 (XtPointer) True 294 }, 295 { 296 XmUbNmdiTodayForeground, 297 XmCForeground, 298 XtRPixel, sizeof( Pixel ), 299 XtOffset( XmUbMonthDisplayWidget, md.today_foreground ), 300 XmRCallProc, 301 (XtPointer) _XmForegroundColorDefault 302 }, 303 { 304 XmUbNmdiUpdateDayCallback, 305 XmCCallback, 306 XmRCallback, sizeof( XtCallbackList ), 307 XtOffset( XmUbMonthDisplayWidget, md.update_day_callback ), 308 XmRImmediate, 309 (XtPointer) NULL 310 }, 311 { 312 XmUbNmdiUseDefaultTitleCallback, 313 XmUbCMdiUseDefaultTitleCallback, 314 XtRBoolean, sizeof( Boolean ), 315 XtOffset( XmUbMonthDisplayWidget, md.use_default_title_callback ), 316 XtRImmediate, 317 (XtPointer) True 318 }, 319 { 320 XmUbNmdiWeekLabel, 321 XmUbCMdiWeekLabel, 322 XmRXmString, sizeof( XmString ), 323 XtOffset( XmUbMonthDisplayWidget, md.week_number_label ), 324 XtRImmediate, 325 (XtPointer) NULL 326 }, 327 { 328 XmUbNmdiWeekNumberForeground, 329 XmCForeground, 330 XtRPixel, sizeof( Pixel ), 331 XtOffset( XmUbMonthDisplayWidget, md.week_number_foreground ), 332 XmRCallProc, 333 (XtPointer) _XmForegroundColorDefault 334 }, 335 { 336 XmUbNmdiWeekNumbers, 337 XmUbCMdiWeekNumbers, 338 XtRBoolean, sizeof( Boolean ), 339 XtOffset( XmUbMonthDisplayWidget, md.week_numbers ), 340 XtRImmediate, 341 (XtPointer) True 342 }, 343 { 344 XmUbNmdiWeekdayForeground, 345 XmCForeground, 346 XtRPixel, sizeof( Pixel ), 347 XtOffset( XmUbMonthDisplayWidget, md.weekday_foreground ), 348 XmRCallProc, 349 (XtPointer) _XmForegroundColorDefault 350 }, 351 { 352 XmUbNmdiYearArrows, 353 XmUbCMdiYearArrows, 354 XtRBoolean, sizeof( Boolean ), 355 XtOffset( XmUbMonthDisplayWidget, md.year_arrows ), 356 XtRImmediate, 357 (XtPointer) True 358 }, 359 { 360 XmUbNmdiYearLabel, 361 XmUbCMdiYearLabel, 362 XmRXmString, sizeof( XmString ), 363 XtOffset( XmUbMonthDisplayWidget, md.year_label ), 364 XtRImmediate, 365 (XtPointer) NULL 366 }, 367 368 }; /* resources */ 369 370 371 /*---------------------------------------------------------------------------- 372 -- Function prototypes 373 ----------------------------------------------------------------------------*/ 374 375 /* Class methods. */ 376 static void 377 ChangeManaged( Widget widget ); 378 379 static void 380 ClassInitialize(); 381 382 static void 383 DeleteChild( Widget widget ); 384 385 static void 386 Destroy( Widget widget ); 387 388 static void 389 ExposeMonthDisplay( Widget widget, 390 XEvent *event, 391 Region region ); 392 393 static XtGeometryResult 394 GeometryManager( Widget widget, 395 XtWidgetGeometry *request, 396 XtWidgetGeometry *reply ); 397 398 static void 399 GetValuesHook( Widget w, 400 ArgList args, 401 Cardinal *num_args ); 402 403 static void 404 Initialize( Widget treq, 405 Widget tnew, 406 ArgList args, 407 Cardinal *num_args ); 408 409 static void 410 InsertChild( Widget widget ); 411 412 static XtGeometryResult 413 QueryGeometry( Widget widget, 414 XtWidgetGeometry *proposed, 415 XtWidgetGeometry *answer ); 416 417 static void 418 Resize( Widget widget ); 419 420 static Boolean 421 SetValues( Widget current, 422 Widget request, 423 Widget new, 424 ArgList args, 425 Cardinal *num_args ); 426 427 428 /* Internal functions. */ 429 430 /* Gets the date that is set for a button. */ 431 static void 432 ButtonDate( XmUbMonthDisplayWidget md, 433 Widget button, 434 int *year, 435 int *month, 436 int *day ); 437 438 static void 439 CallNewMonthCallbacks( XmUbMonthDisplayWidget md ); 440 441 /* If not in the child list, returns XmUbMD_CHILD_ERROR. */ 442 static int 443 ChildIndex( XmUbMonthDisplayWidget md, 444 Widget child ); 445 446 static void 447 CreateMonthRowColumns( XmUbMonthDisplayWidget md, 448 String name ); 449 450 static void 451 CreateInternalWidgets( XmUbMonthDisplayWidget md ); 452 453 static Widget 454 DateButton( XmUbMonthDisplayWidget md, 455 int day_number ); 456 457 static int 458 DateButtonIndex( XmUbMonthDisplayWidget md, 459 int day_number ); 460 461 #if XmVersion > 1001 462 static Boolean 463 DateDragConvertProc( Widget w, 464 Atom *selection, 465 Atom *target, 466 Atom *typeRtn, 467 XtPointer *valueRtn, 468 unsigned long *lengthRtn, 469 int *formatRtn, 470 unsigned long *max_lengthRtn, 471 XtPointer client_data, 472 XtRequestId *request_id ); 473 474 static void 475 DateEnterDropSiteCB( Widget drag_context, 476 XmUbMonthDisplayWidget md, 477 XmDropSiteEnterCallbackStruct *call_data ); 478 479 static void 480 DateLeaveDropSiteCB( Widget drag_context, 481 XmUbMonthDisplayWidget md, 482 XmDropSiteLeaveCallbackStruct *call_data ); 483 #endif 484 485 static void 486 DayNumberButtonActivatedCB( Widget pb, 487 XmUbMonthDisplayWidget md, 488 XmPushButtonCallbackStruct *call_data ); 489 490 491 /* The sizes array must have been processed by GetChildPrefSizes 492 before DoLayout is called. */ 493 static void 494 DoLayout( XmUbMonthDisplayWidget md, 495 Widget initiator, 496 XtWidgetGeometry *request, 497 KidDimensionRec sizes[] ); 498 499 /* Fills in the width and height fields in the kids dimension recs. */ 500 static void 501 GetChildPrefSizes( XmUbMonthDisplayWidget md, 502 Widget initiator, 503 XtWidgetGeometry *request, 504 KidDimensionRec sizes[] ); 505 506 507 /* The sizes array must have been prepared by GetChildPrefSizes before this 508 function is called. */ 509 static void 510 GetOwnPreferredSize( XmUbMonthDisplayWidget md, 511 KidDimensionRec sizes[], 512 Dimension *pref_width, 513 Dimension *pref_height ); 514 515 static void 516 KidsPreferredGeometry( Widget kid, 517 Widget initiator, 518 XtWidgetGeometry *request, 519 XtWidgetGeometry *desired ); 520 521 static void 522 MonthScrolledCB( Widget pb, 523 XmUbMonthDisplayWidget md, 524 XmUbArrowLabelCallbackStruct *call_data ); 525 526 /* ResizeIfNeeded fills in the sizes array. Does not have to be initialized. */ 527 static Boolean 528 ResizeIfNeeded( XmUbMonthDisplayWidget md, 529 KidDimensionRec sizes[] ); 530 531 static void 532 SetDayNames( XmUbMonthDisplayWidget md ); 533 534 #if XmVersion > 1001 535 static void 536 StartDateDrag( Widget w, 537 XEvent *event, 538 String *params, 539 Cardinal num_params ); 540 #endif 541 542 static void 543 TitleBarPressedCB( Widget pb, 544 XmUbMonthDisplayWidget md, 545 XmPushButtonCallbackStruct *call_data ); 546 547 static void 548 UpdateDayButton( XmUbMonthDisplayWidget md, 549 int index, 550 int date, 551 XmUbWhichMonth which_month ); 552 553 static void 554 UpdateNewMonth( XmUbMonthDisplayWidget md ); 555 556 static void 557 UpdateWeekButton( XmUbMonthDisplayWidget md, 558 int index, 559 TIM_TIME_REF time_of_first_day, 560 Boolean mapped ); 561 562 static void 563 WarningNoResourceChange( XmUbMonthDisplayWidget md, 564 String resource ); 565 566 static void 567 WeekNumberButtonActivatedCB( Widget pb, 568 XmUbMonthDisplayWidget md, 569 XmPushButtonCallbackStruct *call_data ); 570 571 static void 572 YearScrolledCB( Widget pb, 573 XmUbMonthDisplayWidget md, 574 XmUbArrowLabelCallbackStruct *call_data ); 575 576 /*---------------------------------------------------------------------------- 577 -- Initialization of the class record. 578 ----------------------------------------------------------------------------*/ 579 580 #if XmVersion > 1001 581 582 /* Date label translation list. */ 583 static char dateTranslationTable[] = 584 "<Btn2Down>: start-date-drag()"; 585 586 static XtTranslations dateTranslations; 587 588 /* Action list. */ 589 static XtActionsRec actionsList[] = 590 { 591 { "start-date-drag", (XtActionProc) StartDateDrag }, 592 }; 593 594 #endif 595 596 /* This initialization has to be done after the methods have been declared. */ 597 XmUbMonthDisplayClassRec xmUbMonthDisplayClassRec = { 598 599 { /* Core class fields. */ 600 /* superclass */ (WidgetClass) &xmManagerClassRec, 601 /* class_name */ "XmUbMonthDisplay", 602 /* widget_size */ sizeof( XmUbMonthDisplayRec ), 603 /* class_initialize */ ClassInitialize, 604 /* class_part_initialize */ NULL, 605 /* class_inited */ False, 606 /* initialize */ Initialize, 607 /* initialize_hook */ NULL, 608 /* realize */ XtInheritRealize, 609 #if XmVersion > 1001 610 /* actions */ actionsList, 611 /* num_actions */ XtNumber( actionsList ), 612 #else 613 /* actions */ NULL, 614 /* num_actions */ 0, 615 #endif 616 /* resources */ resources, 617 /* num_resources */ XtNumber( resources ), 618 /* xrm_class */ NULLQUARK, 619 /* compress_motion */ True, 620 /* compress_exposure */ True, 621 /* compress_enterleave */ True, 622 /* visible_interest */ False, 623 /* destroy */ Destroy, 624 /* resize */ Resize, 625 /* expose */ ExposeMonthDisplay, 626 /* set_values */ SetValues, 627 /* set_values_hook */ NULL, 628 /* set_values_almost */ XtInheritSetValuesAlmost, 629 /* get_values_hook */ GetValuesHook, 630 /* accept_focus */ NULL, 631 /* version */ XtVersion, 632 /* callback_private */ NULL, 633 /* tm_table */ NULL, 634 /* query_geometry */ QueryGeometry, 635 /* display_accelerator */ XtInheritDisplayAccelerator, 636 /* extension */ NULL 637 }, 638 { /* Composite class part. */ 639 /* geometry_manager */ GeometryManager, 640 /* change_managed */ ChangeManaged, 641 /* insert_child */ InsertChild, 642 /* delete_child */ DeleteChild, 643 /* extension */ NULL 644 }, 645 { /* Constraint class fields. */ 646 /* subresources */ NULL, 647 /* subresource_count */ 0, 648 /* constraint_size */ sizeof( 649 XmUbMonthDisplayConstraintsRec ), 650 /* initialize */ NULL, 651 /* destroy */ NULL, 652 /* set_values */ NULL, 653 /* extension */ NULL 654 }, 655 { /* XmManager class part. */ 656 /* translations */ NULL, 657 /* get_resources */ NULL, 658 /* num_get_resources */ 0, 659 /* get_constraint_resources */ NULL, 660 /* num_get_constraint_resources */ 0, 661 /* extension */ NULL 662 }, 663 { /* Month display class part. */ 664 /* extension */ NULL 665 }, 666 667 }; 668 669 670 /* Class record pointer. */ 671 WidgetClass 672 xmUbMonthDisplayWidgetClass = (WidgetClass) &xmUbMonthDisplayClassRec; 673 674 675 676 /*---------------------------------------------------------------------------- 677 -- Functions 678 ----------------------------------------------------------------------------*/ 679 680 681 static void ButtonDate(XmUbMonthDisplayWidget md,Widget button,int * year,int * month,int * day)682 ButtonDate( XmUbMonthDisplayWidget md, 683 Widget button, 684 int *year, 685 int *month, 686 int *day ) 687 { 688 /* Variables. */ 689 Arg args[ 1 ]; 690 Cardinal n; 691 int user_data; 692 693 /* Code. */ 694 695 /* The date information is in the user data resource of the button. */ 696 n = 0; 697 XtSetArg( args[ n ], XmNuserData, &user_data ); n++; 698 XtGetValues( button, args, n ); 699 700 *day = user_data % 100; 701 702 if( user_data < PREVIOUS_MONTH_OFFSET ){ 703 /* Current month. */ 704 *month = md -> md.current_month; 705 *year = md -> md.current_year; 706 707 } else if( user_data < NEXT_MONTH_OFFSET ){ 708 /* Previous month. */ 709 *month = md -> md.current_month - 1; 710 *year = md -> md.current_year; 711 712 if( *month < 1 ){ 713 *month = 12; 714 (*year) --; 715 } 716 717 } else { 718 /* Next month. */ 719 *month = md -> md.current_month + 1; 720 *year = md -> md.current_year; 721 722 if( *month > 12 ){ 723 *month = 1; 724 (*year) ++; 725 } 726 } 727 728 729 return; 730 731 } /* ButtonDate */ 732 733 734 /*----------------------------------------------------------------------*/ 735 736 static void CallNewMonthCallbacks(XmUbMonthDisplayWidget md)737 CallNewMonthCallbacks( XmUbMonthDisplayWidget md ) 738 { 739 /* Variables. */ 740 XmUbMonthDisplayCallbackStruct cb; 741 742 /* Code. */ 743 744 if( md -> md.new_month_callback == NULL ) 745 return; 746 747 /* Callbacks are defined. */ 748 /* Set up the callback structure. */ 749 cb.reason = XmUbCR_NEW_MONTH; 750 cb.event = NULL; 751 cb.selected_month = md -> md.current_month; 752 cb.selected_year = md -> md.current_year; 753 754 /* Call the user callbacks. */ 755 XtCallCallbackList( (Widget) md, md -> md.new_month_callback, 756 (XtPointer) &cb ); 757 758 759 return; 760 761 } /* CallNewMonthCallbacks */ 762 763 764 /*----------------------------------------------------------------------*/ 765 766 static void ChangeManaged(Widget widget)767 ChangeManaged( Widget widget ) 768 { 769 /* Variables. */ 770 Boolean layout_done; 771 KidDimensionRec kids_sizes[ NO_INTERNAL_CHILDREN ]; 772 XmUbMonthDisplayWidget md; 773 774 775 /* Code. */ 776 777 md = (XmUbMonthDisplayWidget) widget; 778 779 /* ResizeIfNeeded checks the size of all children and resizes the widget. */ 780 layout_done = ResizeIfNeeded( md, kids_sizes ); 781 782 /* Do the layout. */ 783 if( !layout_done ) 784 DoLayout( md, NULL, NULL, kids_sizes ); 785 786 787 return; 788 789 } /* ChangeManaged */ 790 791 792 /*----------------------------------------------------------------------*/ 793 794 static int ChildIndex(XmUbMonthDisplayWidget md,Widget child)795 ChildIndex( XmUbMonthDisplayWidget md, 796 Widget child ) 797 { 798 /* Variables. */ 799 int index; 800 801 /* Code. */ 802 803 for( index = 0; index < NO_INTERNAL_CHILDREN; index ++ ){ 804 805 if( md -> md.internal_children[ index ] == child ) 806 return index; 807 808 } /* for */ 809 810 811 /* Specified child not found. */ 812 return XmUbMD_CHILD_ERROR; 813 814 } /* ChildIndex */ 815 816 817 /*----------------------------------------------------------------------*/ 818 819 static void ClassInitialize()820 ClassInitialize() 821 { 822 /* Code. */ 823 824 #if XmVersion > 1001 825 /* Parse translations tables. */ 826 dateTranslations = XtParseTranslationTable( (String) dateTranslationTable ); 827 #endif 828 829 return; 830 831 } /* ClassInitialize */ 832 833 834 /*----------------------------------------------------------------------*/ 835 836 static void CreateInternalWidgets(XmUbMonthDisplayWidget md)837 CreateInternalWidgets( XmUbMonthDisplayWidget md ) 838 { 839 /* Variables. */ 840 Arg args[ 5 ]; 841 Cardinal n; 842 char *name_buffer; 843 String wname; 844 XmString xm; 845 846 /* Code. */ 847 848 /* Get the name of the "parent" widget. */ 849 wname = XtName( (Widget)md ); 850 name_buffer = XtMalloc( strlen( wname ) + 4 ); 851 852 /* Title bar. */ 853 854 sprintf( name_buffer, "%sTi", wname ); 855 856 n = 0; 857 if( md -> md.title_shadows ){ 858 XtSetArg( args[ n ], XmNshadowThickness, 1 ); n++; 859 } else { 860 XtSetArg( args[ n ], XmNshadowThickness, 0 ); n++; 861 } 862 863 XtSetArg( args[ n ], XmNuserData, TITLE_ID_USER_DATA ); n++; 864 md -> md.internal_children[ XmUbMD_CHILD_TITLE ] = 865 XmCreatePushButton( (Widget) md, name_buffer, args, n ); 866 XtManageChild( md -> md.internal_children[ XmUbMD_CHILD_TITLE ] ); 867 868 XtAddCallback( md -> md.internal_children[ XmUbMD_CHILD_TITLE ], 869 XmNactivateCallback, 870 (XtCallbackProc) TitleBarPressedCB, (XtPointer) md ); 871 872 /* Provide some user feedback -- no pressing if no action. */ 873 if( ( md -> md.title_callback == NULL ) && 874 ! md -> md.use_default_title_callback ){ 875 876 n = 0; 877 XtSetArg( args[ n ], XmNfillOnArm, False ); n++; 878 XtSetValues( md -> md.internal_children[ XmUbMD_CHILD_TITLE ], args, n ); 879 } 880 881 #if XmVersion > 1001 882 /* We have our own processing of drag. */ 883 XtOverrideTranslations( md -> md.internal_children[ XmUbMD_CHILD_TITLE ], 884 dateTranslations ); 885 #endif 886 887 /* Month display. */ 888 889 sprintf( name_buffer, "%sRc", wname ); 890 CreateMonthRowColumns( md, name_buffer ); 891 892 XtManageChild( md -> md.internal_children[ XmUbMD_CHILD_ROW_COLUMN ] ); 893 if( md -> md.internal_children[ XmUbMD_CHILD_WEEK_RC ] != NULL ) 894 XtManageChild( md -> md.internal_children[ XmUbMD_CHILD_WEEK_RC ] ); 895 896 /* Month arrows. */ 897 if( md -> md.month_arrows ){ 898 sprintf( name_buffer, "%sMa", wname ); 899 900 n = 0; 901 902 if( md -> md.month_label == NULL ) 903 xm = XmStringCreateLtoR( default_month_string, 904 XmSTRING_DEFAULT_CHARSET ); 905 else 906 xm = md -> md.month_label; 907 908 XtSetArg( args[ n ], XmNlabelString, xm ); n++; 909 910 md -> md.internal_children[ XmUbMD_CHILD_MONTH_ARROW ] = 911 XmUbCreateArrowLabel( (Widget) md, name_buffer, args, n ); 912 913 if( md -> md.month_label == NULL ) 914 XmStringFree( xm ); 915 916 XtAddCallback( md -> md.internal_children[ XmUbMD_CHILD_MONTH_ARROW ], 917 XmNactivateCallback, 918 (XtCallbackProc) MonthScrolledCB, (XtPointer) md ); 919 920 XtManageChild( md -> md.internal_children[ XmUbMD_CHILD_MONTH_ARROW ] ); 921 } 922 923 /* Year arrows. */ 924 if( md -> md.year_arrows ){ 925 sprintf( name_buffer, "%sYa", wname ); 926 927 n = 0; 928 929 if( md -> md.year_label == NULL ) 930 xm = XmStringCreateLtoR( default_year_string, 931 XmSTRING_DEFAULT_CHARSET ); 932 else 933 xm = md -> md.year_label; 934 935 XtSetArg( args[ n ], XmNlabelString, xm ); n++; 936 937 md -> md.internal_children[ XmUbMD_CHILD_YEAR_ARROW ] = 938 XmUbCreateArrowLabel( (Widget) md, name_buffer, args, n ); 939 940 if( md -> md.year_label == NULL ) 941 XmStringFree( xm ); 942 943 XtAddCallback( md -> md.internal_children[ XmUbMD_CHILD_YEAR_ARROW ], 944 XmNactivateCallback, 945 (XtCallbackProc) YearScrolledCB, (XtPointer) md ); 946 947 XtManageChild( md -> md.internal_children[ XmUbMD_CHILD_YEAR_ARROW ] ); 948 } 949 950 /* Create separator if there are any arrow buttons. */ 951 if( ( md -> md.year_arrows || md -> md.month_arrows ) && 952 md -> md.enable_separator ){ 953 sprintf( name_buffer, "%sSp", wname ); 954 955 n = 0; 956 XtSetArg( args[ n ], XmNorientation, XmHORIZONTAL ); n++; 957 958 md -> md.internal_children[ XmUbMD_CHILD_SEPARATOR ] = 959 XmCreateSeparator( (Widget) md, name_buffer, args, n ); 960 961 XtManageChild( md -> md.internal_children[ XmUbMD_CHILD_SEPARATOR ] ); 962 } 963 964 965 XtFree( name_buffer ); 966 967 968 return; 969 970 } /* CreateInternalWidgets */ 971 972 973 /*----------------------------------------------------------------------*/ 974 975 static void CreateMonthRowColumns(XmUbMonthDisplayWidget md,String name)976 CreateMonthRowColumns( XmUbMonthDisplayWidget md, 977 String name ) 978 { 979 /* Variables. */ 980 Arg args[ 6 ]; 981 XmString empty_xm; 982 Dimension height, max_height; 983 int index; 984 Cardinal n; 985 char *name_buffer; 986 Widget rc; 987 Dimension width, max_width; 988 XmString xm; 989 990 /* Code. */ 991 992 name_buffer = XtMalloc( strlen( name ) + 5 ); 993 994 sprintf( name_buffer, "%sRc", name ); 995 996 n = 0; 997 XtSetArg( args[ n ], XmNorientation, XmHORIZONTAL ); n++; 998 XtSetArg( args[ n ], XmNpacking, XmPACK_COLUMN ); n++; 999 XtSetArg( args[ n ], XmNnumColumns, 7 ); n++; 1000 XtSetArg( args[ n ], XmNspacing, 0 ); n++; 1001 rc = XmCreateRowColumn( (Widget) md, name_buffer, args, n ); 1002 1003 /* We have to start by setting the label empty, since we look for the 1004 biggest one and don't want ghosts. */ 1005 empty_xm = XmStringCreateLtoR( "", XmSTRING_DEFAULT_CHARSET ); 1006 1007 /* Create the day name buttons. */ 1008 n = 0; 1009 XtSetArg( args[ n ], XmNshadowThickness, 0 ); n++; 1010 XtSetArg( args[ n ], XmNtraversalOn, False ); n++; 1011 XtSetArg( args[ n ], XmNlabelString, empty_xm ); n++; 1012 1013 for( index = 0; index < NO_DAY_NAME_BUTTONS; index ++ ){ 1014 sprintf( name_buffer, "%sDn%d", name, index ); 1015 md -> md.day_name_buttons[ index ] = 1016 XmCreateLabel( rc, name_buffer, args, n ); 1017 } 1018 1019 /* Create the day number buttons. */ 1020 n = 0; 1021 XtSetArg( args[ n ], XmNshadowThickness, 1 ); n++; 1022 XtSetArg( args[ n ], XmNlabelString, empty_xm ); n++; 1023 XtSetArg( args[ n ], XmNalignment, XmALIGNMENT_END ); n++; 1024 1025 for( index = 0; index < NO_DAY_BUTTONS; index ++ ){ 1026 sprintf( name_buffer, "%sDb%d", name, index ); 1027 md -> md.day_number_buttons[ index ] = 1028 XmCreatePushButton( rc, name_buffer, args, n ); 1029 1030 XtAddCallback( md -> md.day_number_buttons[ index ], XmNactivateCallback, 1031 (XtCallbackProc) DayNumberButtonActivatedCB, 1032 (XtPointer) md ); 1033 1034 #if XmVersion > 1001 1035 /* We have our own processing of drag. */ 1036 XtOverrideTranslations( md -> md.day_number_buttons[ index ], 1037 dateTranslations ); 1038 #endif 1039 } 1040 1041 /* Save the default shadow colors. */ 1042 n = 0; 1043 XtSetArg( args[ n ], XmNtopShadowColor, 1044 & md -> md.pushb_default_topshadow ); n++; 1045 XtSetArg( args[ n ], XmNbottomShadowColor, 1046 & md -> md.pushb_default_bottomshadow ); n++; 1047 XtGetValues( md -> md.day_number_buttons[ 0 ], args, n ); 1048 1049 1050 /* Create the week number row column if desired. */ 1051 if( md -> md.week_numbers ){ 1052 1053 sprintf( name_buffer, "%sWrc", name ); 1054 1055 n = 0; 1056 XtSetArg( args[ n ], XmNorientation, XmHORIZONTAL ); n++; 1057 XtSetArg( args[ n ], XmNpacking, XmPACK_COLUMN ); n++; 1058 XtSetArg( args[ n ], XmNnumColumns, 7 ); n++; 1059 XtSetArg( args[ n ], XmNspacing, 0 ); n++; 1060 md -> md.internal_children[ XmUbMD_CHILD_WEEK_RC ] = 1061 XmCreateRowColumn( (Widget) md, name_buffer, args, n ); 1062 1063 for( index = 0; index < NO_WEEK_NUMBER_BUTTONS; index ++ ){ 1064 sprintf( name_buffer, "%sWb%d", name, index ); 1065 1066 n = 0; 1067 XtSetArg( args[ n ], XmNlabelString, empty_xm ); n++; 1068 XtSetArg( args[ n ], XmNuserData, 0 ); n++; 1069 if( index == 0 ){ 1070 XtSetArg( args[ n ], XmNshadowThickness, 0 ); n++; 1071 } else { 1072 XtSetArg( args[ n ], XmNshadowThickness, 1 ); n++; 1073 } 1074 XtSetArg( args[ n ], XmNalignment, XmALIGNMENT_END ); n++; 1075 1076 if( index == 0 ) 1077 md -> md.week_number_buttons[ index ] = 1078 XmCreateLabel( md -> md.internal_children[ XmUbMD_CHILD_WEEK_RC ], 1079 name_buffer, args, n ); 1080 else { 1081 md -> md.week_number_buttons[ index ] = XmCreatePushButton( 1082 md -> md.internal_children[ XmUbMD_CHILD_WEEK_RC ], 1083 name_buffer, args, n ); 1084 1085 XtAddCallback( md -> md.week_number_buttons[ index ], 1086 XmNactivateCallback, 1087 (XtCallbackProc) WeekNumberButtonActivatedCB, 1088 (XtPointer) md ); 1089 1090 #if XmVersion > 1001 1091 /* We have our own processing of drag. */ 1092 XtOverrideTranslations( md -> md.week_number_buttons[ index ], 1093 dateTranslations ); 1094 #endif 1095 } 1096 } 1097 1098 /* Set the week number "title". */ 1099 if( md -> md.week_number_label == NULL ) 1100 xm = XmStringCreateLtoR( "W", XmSTRING_DEFAULT_CHARSET ); 1101 else 1102 xm = md -> md.week_number_label; 1103 1104 n = 0; 1105 XtSetArg( args[ n ], XmNlabelString, xm ); n++; 1106 XtSetArg( args[ n ], XmNalignment, XmALIGNMENT_CENTER ); n++; 1107 XtSetValues( md -> md.week_number_buttons[ 0 ], args, n ); 1108 1109 if( md -> md.week_number_label == NULL ) 1110 XmStringFree( xm ); 1111 } 1112 1113 /* Set the texts of the buttons and the title. */ 1114 UpdateNewMonth( md ); 1115 1116 /* Manage the created internal buttons. */ 1117 XtManageChildren( md -> md.day_name_buttons, NO_DAY_NAME_BUTTONS ); 1118 XtManageChildren( md -> md.day_number_buttons, NO_DAY_BUTTONS ); 1119 if( md -> md.week_numbers ) 1120 XtManageChildren( md -> md.week_number_buttons, NO_WEEK_NUMBER_BUTTONS ); 1121 1122 /* Find out biggest button and set all to that size. */ 1123 1124 max_height = 0; 1125 max_width = 0; 1126 1127 n = 0; 1128 XtSetArg( args[ n ], XmNwidth, &width ); n++; 1129 XtSetArg( args[ n ], XmNheight, &height ); n++; 1130 1131 for( index = 0; index < NO_DAY_NAME_BUTTONS; index ++ ){ 1132 XtGetValues( md -> md.day_name_buttons[ index ], args, n ); 1133 1134 if( height > max_height ) 1135 max_height = height; 1136 if( width > max_width ) 1137 max_width = width; 1138 1139 } /* for */ 1140 1141 for( index = 0; index < NO_DAY_BUTTONS; index ++ ){ 1142 XtGetValues( md -> md.day_number_buttons[ index ], args, n ); 1143 1144 if( height > max_height ) 1145 max_height = height; 1146 if( width > max_width ) 1147 max_width = width; 1148 1149 } /* for */ 1150 1151 if( md -> md.week_numbers ){ 1152 for( index = 0; index < NO_WEEK_NUMBER_BUTTONS; index ++ ){ 1153 XtGetValues( md -> md.week_number_buttons[ index ], args, n ); 1154 1155 if( height > max_height ) 1156 max_height = height; 1157 if( width > max_width ) 1158 max_width = width; 1159 1160 } /* for */ 1161 } 1162 1163 /* Set all to max size and hint not to resize again. */ 1164 n = 0; 1165 XtSetArg( args[ n ], XmNwidth, max_width ); n++; 1166 XtSetArg( args[ n ], XmNheight, max_height ); n++; 1167 XtSetArg( args[ n ], XmNrecomputeSize, False ); n++; 1168 XtSetArg( args[ n ], XmNalignment, XmALIGNMENT_END ); n++; 1169 1170 for( index = 0; index < NO_DAY_NAME_BUTTONS; index ++ ) 1171 XtSetValues( md -> md.day_name_buttons[ index ], args, n ); 1172 for( index = 0; index < NO_DAY_BUTTONS; index ++ ) 1173 XtSetValues( md -> md.day_number_buttons[ index ], args, n ); 1174 1175 if( md -> md.week_numbers ){ 1176 for( index = 0; index < NO_WEEK_NUMBER_BUTTONS; index ++ ) 1177 XtSetValues( md -> md.week_number_buttons[ index ], args, n ); 1178 } 1179 1180 /* Set row column geometry explicitly. */ 1181 #if XmVersion < 1002 1182 { 1183 Dimension margin_height; 1184 Dimension margin_width; 1185 Widget wrc; 1186 1187 /* Code. */ 1188 1189 n = 0; 1190 XtSetArg( args[ n ], XmNmarginWidth, &margin_width ); n++; 1191 XtSetArg( args[ n ], XmNmarginHeight, &margin_height ); n++; 1192 XtGetValues( rc, args, n ); 1193 1194 n = 0; 1195 XtSetArg( args[ n ], XmNwidth, max_width * 7 + 2 * margin_width ); n++; 1196 XtSetArg( args[ n ], XmNheight, max_height * 7 + 2 * margin_height ); n++; 1197 XtSetArg( args[ n ], XmNnumColumns, 7 ); n++; 1198 XtSetArg( args[ n ], XmNpacking, XmPACK_COLUMN ); n++; 1199 XtSetArg( args[ n ], XmNresizeHeight, False ); n++; 1200 XtSetArg( args[ n ], XmNresizeWidth, False ); n++; 1201 XtSetValues( rc, args, n ); 1202 1203 if( md -> md.week_numbers ){ 1204 wrc = md -> md.internal_children[ XmUbMD_CHILD_WEEK_RC ]; 1205 n = 0; 1206 XtSetArg( args[ n ], XmNmarginWidth, &margin_width ); n++; 1207 XtSetArg( args[ n ], XmNmarginHeight, &margin_height ); n++; 1208 XtGetValues( wrc, args, n ); 1209 1210 n = 0; 1211 XtSetArg( args[ n ], XmNwidth, max_width + 2 * margin_width ); n++; 1212 XtSetArg( args[ n ], XmNheight, 1213 max_height * 7 + 2 * margin_height ); n++; 1214 XtSetArg( args[ n ], XmNnumColumns, 7 ); n++; 1215 XtSetArg( args[ n ], XmNpacking, XmPACK_COLUMN ); n++; 1216 XtSetArg( args[ n ], XmNresizeHeight, False ); n++; 1217 XtSetArg( args[ n ], XmNresizeWidth, False ); n++; 1218 XtSetValues( wrc, args, n ); 1219 } 1220 } 1221 #endif 1222 1223 /* Cleanup. */ 1224 XtFree( name_buffer ); 1225 XmStringFree( empty_xm ); 1226 1227 1228 md -> md.internal_children[ XmUbMD_CHILD_ROW_COLUMN ] = rc; 1229 1230 1231 return; 1232 1233 } /* CreateMonthRowColumns */ 1234 1235 1236 /*----------------------------------------------------------------------*/ 1237 1238 static Widget DateButton(XmUbMonthDisplayWidget md,int day_number)1239 DateButton( XmUbMonthDisplayWidget md, 1240 int day_number ) 1241 { 1242 /* Variables. */ 1243 int day_index; 1244 1245 /* Code. */ 1246 1247 day_index = DateButtonIndex( md, day_number ); 1248 1249 if( day_index > ( NO_DAY_BUTTONS - 1 ) ) 1250 return( NULL ); 1251 1252 else 1253 return( md -> md.day_number_buttons[ day_index ] ); 1254 1255 1256 } /* DateButton */ 1257 1258 1259 /*----------------------------------------------------------------------*/ 1260 1261 static int DateButtonIndex(XmUbMonthDisplayWidget md,int day_number)1262 DateButtonIndex( XmUbMonthDisplayWidget md, 1263 int day_number ) 1264 { 1265 /* Code. */ 1266 1267 return( md -> md.first_date_index + day_number - 1 ); 1268 1269 } /* DateButtonIndex */ 1270 1271 1272 /*----------------------------------------------------------------------*/ 1273 1274 #if XmVersion > 1001 1275 1276 static Boolean DateDragConvertProc(Widget w,Atom * selection,Atom * target,Atom * typeRtn,XtPointer * valueRtn,unsigned long * lengthRtn,int * formatRtn,unsigned long * max_lengthRtn,XtPointer client_data,XtRequestId * request_id)1277 DateDragConvertProc( Widget w, 1278 Atom *selection, 1279 Atom *target, 1280 Atom *typeRtn, 1281 XtPointer *valueRtn, 1282 unsigned long *lengthRtn, 1283 int *formatRtn, 1284 unsigned long *max_lengthRtn, 1285 XtPointer client_data, 1286 XtRequestId *request_id ) 1287 { 1288 /* Variables. */ 1289 Arg args[ 5 ]; 1290 Widget button; 1291 Atom compound_text_atom; 1292 char *ctext; 1293 Atom date_transfer_atom; 1294 int day; 1295 int index; 1296 XmUbMonthDisplayWidget md; 1297 int month; 1298 Cardinal n; 1299 char *passtext; 1300 TIM_TIME_REF time; 1301 Widget tmp_widget; 1302 XmUbDateTransfer *transfer_data; 1303 Boolean week; 1304 int week_index = -1; 1305 XmString xm; 1306 int year; 1307 1308 /* Code. */ 1309 1310 compound_text_atom = XmInternAtom( XtDisplay( w ), "COMPOUND_TEXT", False ); 1311 date_transfer_atom = XmInternAtom( XtDisplay( w ), XmUbDATE_TRANSFER, 1312 False ); 1313 1314 /* Refuse incompatible transfer. */ 1315 if( ! ( ( *target == compound_text_atom ) || 1316 ( *target == date_transfer_atom ) ) ) 1317 return( False ); 1318 1319 /* The id of the button widget is set in the clientData resource of the 1320 DragContext widget. */ 1321 n = 0; 1322 XtSetArg( args[ n ], XmNclientData, &button ); n++; 1323 XtGetValues( w, args, n ); 1324 1325 /* Find month display widget. */ 1326 tmp_widget = XtParent( button ); 1327 while( ! XtIsSubclass( tmp_widget, xmUbMonthDisplayWidgetClass ) ) 1328 tmp_widget = XtParent( tmp_widget ); 1329 1330 md = (XmUbMonthDisplayWidget) tmp_widget; 1331 1332 if( *target == date_transfer_atom ){ 1333 1334 /* Transfer in special date format. */ 1335 transfer_data = 1336 (XmUbDateTransfer*) XtMalloc( sizeof( XmUbDateTransfer ) ); 1337 1338 /* The type of transfer depends on which type of button was pressed. */ 1339 if( button == md -> md.internal_children[ XmUbMD_CHILD_TITLE ] ){ 1340 /* Dragging a month. */ 1341 transfer_data -> type = XmUbTRANSFER_RANGE; 1342 1343 transfer_data -> year = md -> md.current_year; 1344 transfer_data -> month = md -> md.current_month; 1345 transfer_data -> day = 1; 1346 1347 time = TimMakeTime( md -> md.current_year, md -> md.current_month, 1, 1348 0, 0, 0 ); 1349 1350 transfer_data -> end_year = md -> md.current_year; 1351 transfer_data -> end_month = md -> md.current_month; 1352 transfer_data -> end_day = TimDaysInMonth( time ); 1353 1354 } else { 1355 1356 /* This could be a week number or a date button. Faster to loop through 1357 the week numbers. */ 1358 week = False; 1359 if( md -> md.week_numbers ){ 1360 for( index = 0; index < NO_WEEK_NUMBER_BUTTONS; index ++ ){ 1361 if( button == md -> md.week_number_buttons[ index ] ){ 1362 week = True; 1363 week_index = index; 1364 break; 1365 } 1366 } 1367 } 1368 assert( week_index != -1 ); 1369 1370 if( week ){ 1371 /* Find the first date button for the week. */ 1372 index = ( week_index - 1 ) * 7; 1373 1374 ButtonDate( md, md -> md.day_number_buttons[ index ], 1375 &year, &month, &day ); 1376 1377 transfer_data -> type = XmUbTRANSFER_RANGE; 1378 transfer_data -> year = year; 1379 transfer_data -> month = month; 1380 transfer_data -> day = day; 1381 1382 /* End date. */ 1383 index += 6; 1384 1385 ButtonDate( md, md -> md.day_number_buttons[ index ], 1386 &year, &month, &day ); 1387 1388 transfer_data -> end_year = year; 1389 transfer_data -> end_month = month; 1390 transfer_data -> end_day = day; 1391 1392 } else { 1393 /* Date transfer. */ 1394 1395 /* Get current month and year and construct string with date. */ 1396 ButtonDate( md, button, &year, &month, &day ); 1397 1398 transfer_data -> type = XmUbTRANSFER_DATE; 1399 transfer_data -> year = year; 1400 transfer_data -> month = month; 1401 transfer_data -> day = day; 1402 } 1403 } 1404 1405 /* Set up the transfer values. */ 1406 *typeRtn = date_transfer_atom; 1407 *valueRtn = (XtPointer) transfer_data; 1408 *lengthRtn = sizeof( XmUbDateTransfer ); 1409 *formatRtn = 8; 1410 1411 } else { 1412 /* We should just transfer the label string. */ 1413 1414 n = 0; 1415 XtSetArg( args[ n ], XmNlabelString, &xm ); n++; 1416 XtGetValues( button, args, n ); 1417 1418 ctext = XmCvtXmStringToCT( xm ); 1419 1420 /* We must copy the string for transfer. */ 1421 passtext = XtMalloc( strlen( ctext ) + 1 ); 1422 memcpy( passtext, ctext, strlen( ctext ) + 1 ); 1423 1424 /* Free what has been allocated here. passtext will be freed by Xt. */ 1425 XmStringFree( xm ); 1426 XtFree( ctext ); 1427 1428 /* Set up the transfer values. */ 1429 *typeRtn = compound_text_atom; 1430 *valueRtn = (XtPointer) passtext; 1431 *lengthRtn = strlen( passtext ); 1432 *formatRtn = 8; 1433 1434 } 1435 1436 return( True ); 1437 1438 } /* DateDragConvertProc */ 1439 1440 #endif 1441 1442 /*----------------------------------------------------------------------*/ 1443 1444 #if XmVersion > 1001 1445 1446 static void DateEnterDropSiteCB(Widget drag_context,XmUbMonthDisplayWidget md,XmDropSiteEnterCallbackStruct * call_data)1447 DateEnterDropSiteCB( Widget drag_context, 1448 XmUbMonthDisplayWidget md, 1449 XmDropSiteEnterCallbackStruct *call_data ) 1450 { 1451 /* Variables. */ 1452 Arg args[ 2 ]; 1453 Cardinal n; 1454 1455 /* Code. */ 1456 1457 n = 0; 1458 1459 if( call_data -> dropSiteStatus == XmVALID_DROP_SITE ){ 1460 XtSetArg( args[ n ], XmNsourcePixmapIcon, md -> md.date_icon ); n++; 1461 XtSetArg( args[ n ], XmNsourceCursorIcon, md -> md.date_icon ); n++; 1462 1463 } else { 1464 XtSetArg( args[ n ], XmNsourcePixmapIcon, md -> md.inv_date_icon ); n++; 1465 XtSetArg( args[ n ], XmNsourceCursorIcon, md -> md.inv_date_icon ); n++; 1466 } 1467 1468 XtSetValues( drag_context, args, n ); 1469 1470 1471 return; 1472 1473 } /* DateEnterDropSiteCB */ 1474 1475 1476 #endif 1477 1478 /*----------------------------------------------------------------------*/ 1479 1480 #if XmVersion > 1001 1481 1482 static void DateLeaveDropSiteCB(Widget drag_context,XmUbMonthDisplayWidget md,XmDropSiteLeaveCallbackStruct * call_data)1483 DateLeaveDropSiteCB( Widget drag_context, 1484 XmUbMonthDisplayWidget md, 1485 XmDropSiteLeaveCallbackStruct *call_data ) 1486 { 1487 /* Variables. */ 1488 Arg args[ 2 ]; 1489 Cardinal n; 1490 1491 /* Code. */ 1492 1493 n = 0; 1494 XtSetArg( args[ n ], XmNsourcePixmapIcon, md -> md.inv_date_icon ); n++; 1495 XtSetArg( args[ n ], XmNsourceCursorIcon, md -> md.inv_date_icon ); n++; 1496 XtSetValues( drag_context, args, n ); 1497 1498 1499 return; 1500 1501 } /* DateLeaveDropSiteCB */ 1502 1503 #endif 1504 1505 /*----------------------------------------------------------------------*/ 1506 1507 static void DayNumberButtonActivatedCB(Widget pb,XmUbMonthDisplayWidget md,XmPushButtonCallbackStruct * call_data)1508 DayNumberButtonActivatedCB( Widget pb, 1509 XmUbMonthDisplayWidget md, 1510 XmPushButtonCallbackStruct *call_data ) 1511 { 1512 /* Variables. */ 1513 XmUbMonthDisplayCallbackStruct cb; 1514 int day_number; 1515 int month_number; 1516 int year_number; 1517 1518 /* Code. */ 1519 1520 /* Get the day number for the button. */ 1521 ButtonDate( md, pb, &year_number, &month_number, &day_number ); 1522 1523 cb.selected_year = year_number; 1524 cb.selected_month = month_number; 1525 cb.selected_day = day_number; 1526 1527 /* Invoke the callbacks. */ 1528 1529 cb.reason = XmUbCR_DATE_SELECTED; 1530 cb.event = call_data -> event; 1531 cb.child = pb; 1532 cb.range = False; 1533 1534 XtCallCallbackList( (Widget) md, md -> md.date_selected_callback, 1535 (XtPointer) &cb ); 1536 1537 1538 return; 1539 1540 } /* DayNumberButtonActivatedCB */ 1541 1542 1543 /*----------------------------------------------------------------------*/ 1544 1545 static void DeleteChild(Widget widget)1546 DeleteChild( Widget widget ) 1547 { 1548 1549 /* Variables. */ 1550 int index; 1551 XmUbMonthDisplayWidget md; 1552 1553 /* Code. */ 1554 1555 md = (XmUbMonthDisplayWidget) XtParent( widget ); 1556 1557 /* Clear the internal reference. */ 1558 for( index = 0; index < NO_INTERNAL_CHILDREN; index ++ ){ 1559 if( md -> md.internal_children[ index ] == widget ){ 1560 md -> md.internal_children[ index ] = NULL; 1561 break; 1562 } 1563 } 1564 1565 /* Perform the actual operation */ 1566 (* ( (CompositeWidgetClass) (xmUbMonthDisplayWidgetClass -> 1567 core_class.superclass) ) -> composite_class.delete_child ) ( widget ); 1568 1569 1570 return; 1571 1572 } /* DeleteChild */ 1573 1574 1575 /*----------------------------------------------------------------------*/ 1576 1577 static void Destroy(Widget widget)1578 Destroy( Widget widget ) 1579 { 1580 /* Variables. */ 1581 XmUbMonthDisplayWidget md; 1582 1583 /* Code. */ 1584 md = (XmUbMonthDisplayWidget) widget; 1585 1586 /* Free XmStrings. */ 1587 if( md -> md.week_number_label != NULL ) 1588 XmStringFree( md -> md.week_number_label ); 1589 if( md -> md.month_label != NULL ) 1590 XmStringFree( md -> md.month_label ); 1591 if( md -> md.year_label != NULL ) 1592 XmStringFree( md -> md.year_label ); 1593 1594 /* Remove callbacks. */ 1595 XtRemoveAllCallbacks( widget, XmUbNmdiDateSelectedCallback ); 1596 XtRemoveAllCallbacks( widget, XmUbNmdiNewMonthCallback ); 1597 XtRemoveAllCallbacks( widget, XmUbNmdiTitleCallback ); 1598 XtRemoveAllCallbacks( widget, XmUbNmdiUpdateDayCallback ); 1599 1600 /* Remove pixmaps if created. */ 1601 if( md -> md.date_icon_bm != None ) 1602 XFreePixmap( XtDisplay( widget ), md -> md.date_icon_bm ); 1603 if( md -> md.date_icon_mask != None ) 1604 XFreePixmap( XtDisplay( widget ), md -> md.date_icon_mask ); 1605 if( md -> md.inv_date_icon_bm != None ) 1606 XFreePixmap( XtDisplay( widget ), md -> md.inv_date_icon_bm ); 1607 if( md -> md.inv_date_icon_mask != None ) 1608 XFreePixmap( XtDisplay( widget ), md -> md.inv_date_icon_mask ); 1609 1610 1611 return; 1612 1613 } /* Destroy */ 1614 1615 1616 /*----------------------------------------------------------------------*/ 1617 1618 static void DoLayout(XmUbMonthDisplayWidget md,Widget initiator,XtWidgetGeometry * request,KidDimensionRec sizes[])1619 DoLayout( XmUbMonthDisplayWidget md, 1620 Widget initiator, 1621 XtWidgetGeometry *request, 1622 KidDimensionRec sizes[] ) 1623 { 1624 /* Variables. */ 1625 int arrow_index; 1626 Position arrow_y_pos; 1627 int index; 1628 Widget kid; 1629 Dimension label_offset; 1630 Position rc_lowest_pos; 1631 Dimension rc_offset; 1632 Dimension rc_width; 1633 1634 /* Code. */ 1635 1636 /* Let the children keep their sizes. They will be clipped if window is too 1637 small. */ 1638 /* Let the week number rc be part of the calculations. Its width and 1639 height will be zero anyway if it is not enabled. */ 1640 1641 /* Y positions. */ 1642 sizes[ XmUbMD_CHILD_TITLE ].y = (Position) md -> md.margin_height; 1643 sizes[ XmUbMD_CHILD_ROW_COLUMN ].y = sizes[ XmUbMD_CHILD_TITLE ].y + 1644 (Position) ( sizes[ XmUbMD_CHILD_TITLE ].height + md -> md.margin_height ); 1645 sizes[ XmUbMD_CHILD_WEEK_RC ].y = sizes[ XmUbMD_CHILD_ROW_COLUMN ].y; 1646 1647 rc_lowest_pos = MAX( sizes[ XmUbMD_CHILD_ROW_COLUMN ].y + 1648 (Position) sizes[ XmUbMD_CHILD_ROW_COLUMN ].height, 1649 sizes[ XmUbMD_CHILD_WEEK_RC ].y + 1650 (Position) sizes[ XmUbMD_CHILD_WEEK_RC ].height ); 1651 1652 sizes[ XmUbMD_CHILD_SEPARATOR ].y = rc_lowest_pos; 1653 1654 arrow_y_pos = sizes[ XmUbMD_CHILD_SEPARATOR ].y + 1655 (Position) sizes[ XmUbMD_CHILD_SEPARATOR ].height + 1656 (Position) md -> md.arrow_spacing; 1657 1658 if( md -> md.month_arrows ) 1659 sizes[ XmUbMD_CHILD_MONTH_ARROW ].y = arrow_y_pos; 1660 1661 if( md -> md.year_arrows ) 1662 sizes[ XmUbMD_CHILD_YEAR_ARROW ].y = arrow_y_pos; 1663 1664 /* X positions. */ 1665 1666 /* The separator should extend to the edge of the widget. */ 1667 sizes[ XmUbMD_CHILD_SEPARATOR ].x = 0; 1668 sizes[ XmUbMD_CHILD_SEPARATOR ].width = md -> core.width; 1669 1670 rc_width = sizes[ XmUbMD_CHILD_ROW_COLUMN ].width + 1671 sizes[ XmUbMD_CHILD_WEEK_RC ].width; 1672 1673 if( md -> md.title_alignment == XmALIGNMENT_CENTER ){ 1674 1675 /* The label and row column should be centered. */ 1676 if( sizes[ XmUbMD_CHILD_TITLE ].width > rc_width ){ 1677 label_offset = 0; 1678 rc_offset = ( sizes[ XmUbMD_CHILD_TITLE ].width - rc_width ) / 2; 1679 } else { 1680 label_offset = ( rc_width - sizes[ XmUbMD_CHILD_TITLE ].width ) / 2; 1681 rc_offset = 0; 1682 } 1683 1684 sizes[ XmUbMD_CHILD_TITLE ].x = (Position) ( md -> md.margin_width + 1685 label_offset ); 1686 sizes[ XmUbMD_CHILD_WEEK_RC ].x = (Position) ( md -> md.margin_width + 1687 rc_offset ); 1688 sizes[ XmUbMD_CHILD_ROW_COLUMN ].x = sizes[ XmUbMD_CHILD_WEEK_RC ].x + 1689 (Position) sizes[ XmUbMD_CHILD_WEEK_RC ].width; 1690 1691 } else { 1692 1693 /* The row column should be centered in the widget and the title should 1694 be placed according to its alignment. */ 1695 1696 if( rc_width < md -> core. width ) 1697 sizes[ XmUbMD_CHILD_WEEK_RC ].x = (Position) ( md -> core.width - 1698 rc_width ) / 2; 1699 else 1700 sizes[ XmUbMD_CHILD_WEEK_RC ].x = 0; 1701 1702 sizes[ XmUbMD_CHILD_ROW_COLUMN ].x = sizes[ XmUbMD_CHILD_WEEK_RC ].x + 1703 (Position) sizes[ XmUbMD_CHILD_WEEK_RC ].width; 1704 1705 /* Place the label according to its defined alignment. */ 1706 if( md -> md.title_alignment == XmALIGNMENT_BEGINNING ) 1707 sizes[ XmUbMD_CHILD_TITLE ].x = (Position) md -> md.margin_width; 1708 else { 1709 if( sizes[ XmUbMD_CHILD_TITLE ].width < 1710 ( md -> core.width - md -> md.margin_width ) ) 1711 sizes[ XmUbMD_CHILD_TITLE ].x = (Position) ( md -> core.width - 1712 md -> md.margin_width - sizes[ XmUbMD_CHILD_TITLE ].width ); 1713 else 1714 sizes[ XmUbMD_CHILD_TITLE ].x = 0; 1715 } 1716 } 1717 1718 /* If both arrow buttons are enabled, they should be glued to the left 1719 and right of the bottom side of the row column. 1720 Month to the left, year to the right. */ 1721 /* The Y positions have already been set. */ 1722 1723 if( md -> md.month_arrows && md -> md.year_arrows ){ 1724 1725 sizes[ XmUbMD_CHILD_MONTH_ARROW ].x = sizes[ XmUbMD_CHILD_WEEK_RC ].x; 1726 1727 if( rc_width > sizes[ XmUbMD_CHILD_YEAR_ARROW ].width ) 1728 sizes[ XmUbMD_CHILD_YEAR_ARROW ].x = sizes[ XmUbMD_CHILD_ROW_COLUMN ].x + 1729 (Position) sizes[ XmUbMD_CHILD_ROW_COLUMN ].width - 1730 (Position) sizes[ XmUbMD_CHILD_YEAR_ARROW ].width; 1731 else 1732 sizes[ XmUbMD_CHILD_YEAR_ARROW ].x = sizes[ XmUbMD_CHILD_WEEK_RC ].x; 1733 1734 } else if ( md -> md.month_arrows || md -> md.year_arrows ){ 1735 /* One of the arrows is enabled. Center it. */ 1736 if( md -> md.month_arrows ) 1737 arrow_index = XmUbMD_CHILD_MONTH_ARROW; 1738 else 1739 arrow_index = XmUbMD_CHILD_YEAR_ARROW; 1740 1741 if( sizes[ arrow_index ].width > rc_width + 2 * md -> md.margin_width ) 1742 sizes[ arrow_index ].x = 0; 1743 else 1744 sizes[ arrow_index ].x = (Position) ( rc_width + 1745 2 * md -> md.margin_width - sizes[ arrow_index ].width ) / 2; 1746 } 1747 1748 /* Configure the children. */ 1749 /* All positions and dimensions are now in the sizes array. */ 1750 for( index = XmUbMD_FIRST_CHILD; index < NO_INTERNAL_CHILDREN; index ++ ){ 1751 1752 kid = md -> md.internal_children[ index ]; 1753 1754 if( ( kid != NULL ) && XtIsManaged( kid ) ) 1755 XtConfigureWidget( kid, sizes[ index ].x, sizes[ index ].y, 1756 sizes[ index ].width, sizes[ index ].height, 1757 kid -> core.border_width ); 1758 } 1759 1760 1761 return; 1762 1763 } /* DoLayout */ 1764 1765 1766 /*----------------------------------------------------------------------*/ 1767 1768 static void ExposeMonthDisplay(Widget widget,XEvent * event,Region region)1769 ExposeMonthDisplay( Widget widget, 1770 XEvent *event, 1771 Region region ) 1772 { 1773 /* Variables. */ 1774 XmUbMonthDisplayWidget md; 1775 1776 /* Code. */ 1777 1778 md = (XmUbMonthDisplayWidget) widget; 1779 1780 /* We don't need to draw anything, just call the month update callback the 1781 first time the widget is exposed. */ 1782 1783 if( !md -> md.exposed ){ 1784 CallNewMonthCallbacks( md ); 1785 md -> md.exposed = True; 1786 } 1787 1788 1789 return; 1790 1791 } /* ExposeMonthDisplay */ 1792 1793 1794 /*----------------------------------------------------------------------*/ 1795 1796 static XtGeometryResult GeometryManager(Widget widget,XtWidgetGeometry * request,XtWidgetGeometry * reply)1797 GeometryManager( Widget widget, 1798 XtWidgetGeometry *request, 1799 XtWidgetGeometry *reply ) 1800 { 1801 1802 XmUbMonthDisplayWidget md; 1803 XtWidgetGeometry own_request; 1804 Dimension old_width, old_height; 1805 Dimension pref_height; 1806 Dimension pref_width; 1807 KidDimensionRec kids_sizes[ NO_INTERNAL_CHILDREN ]; 1808 XtGeometryResult result; 1809 1810 /* Code. */ 1811 1812 md = (XmUbMonthDisplayWidget) XtParent( widget ); 1813 1814 /* Find out how big the widget would be if the resize were allowed. */ 1815 GetChildPrefSizes( md, NULL, request, kids_sizes ); 1816 GetOwnPreferredSize( md, kids_sizes, &pref_width, &pref_height ); 1817 1818 /* If no change in dimensions, allow the request. */ 1819 if( ( pref_width == md -> core.width ) && 1820 ( pref_height == md -> core.height )){ 1821 DoLayout( md, widget, request, kids_sizes ); 1822 return XtGeometryYes; 1823 } 1824 1825 /* We must ask our parent to resize us. */ 1826 own_request.request_mode = CWWidth | CWHeight; 1827 own_request.width = pref_width; 1828 own_request.height = pref_height; 1829 1830 /* Save dimensions. */ 1831 old_width = md -> core.width; 1832 old_height = md -> core.height; 1833 1834 md -> md.resize_called = False; 1835 1836 /* We are not interested in any compromise geometry. */ 1837 result = XtMakeGeometryRequest( (Widget) md, &own_request, NULL ); 1838 1839 /* Reset to old dimensions if request not granted. */ 1840 if( result != XtGeometryYes ){ 1841 md -> core.width = old_width; 1842 md -> core.height = old_height; 1843 1844 } else { 1845 if( !md -> md.resize_called ) 1846 Resize( (Widget) md ); 1847 } 1848 1849 /* !!!!!!!!!!!!!!!!!!!!!! */ 1850 /* Always grant child's request. */ 1851 return XtGeometryYes; 1852 1853 } /* GeometryManager */ 1854 1855 1856 /*----------------------------------------------------------------------*/ 1857 1858 static void GetChildPrefSizes(XmUbMonthDisplayWidget md,Widget initiator,XtWidgetGeometry * request,KidDimensionRec sizes[])1859 GetChildPrefSizes( XmUbMonthDisplayWidget md, 1860 Widget initiator, 1861 XtWidgetGeometry *request, 1862 KidDimensionRec sizes[] ) 1863 { 1864 /* Variables. */ 1865 XtWidgetGeometry desired; 1866 int index; 1867 Widget kid; 1868 1869 /* Code. */ 1870 1871 /* Initialize. */ 1872 for( index = 0; index < NO_INTERNAL_CHILDREN; index ++ ){ 1873 sizes[ index ].width = 0; 1874 sizes[ index ].height = 0; 1875 sizes[ index ].x = 0; 1876 sizes[ index ].y = 0; 1877 } 1878 1879 /* Get the preferred sizes for the children. */ 1880 for( index = XmUbMD_FIRST_CHILD; index < NO_INTERNAL_CHILDREN; index ++ ){ 1881 1882 kid = md -> md.internal_children[ index ]; 1883 1884 if( ( kid != NULL ) && XtIsManaged( kid ) ){ 1885 1886 KidsPreferredGeometry( kid, initiator, request, &desired ); 1887 1888 sizes[ index ].width = desired.width; 1889 sizes[ index ].height = desired.height; 1890 1891 } 1892 1893 } /* for */ 1894 1895 1896 return; 1897 1898 } /* GetChildPrefSizes */ 1899 1900 1901 /*----------------------------------------------------------------------*/ 1902 1903 static void GetOwnPreferredSize(XmUbMonthDisplayWidget md,KidDimensionRec sizes[],Dimension * pref_width,Dimension * pref_height)1904 GetOwnPreferredSize( XmUbMonthDisplayWidget md, 1905 KidDimensionRec sizes[], 1906 Dimension *pref_width, 1907 Dimension *pref_height ) 1908 { 1909 /* Code. */ 1910 1911 *pref_height = sizes[ XmUbMD_CHILD_TITLE ].height + 1912 MAX( sizes[ XmUbMD_CHILD_ROW_COLUMN ].height, 1913 sizes[ XmUbMD_CHILD_WEEK_RC ].height ) + 1914 MAX( sizes[ XmUbMD_CHILD_YEAR_ARROW ].height, 1915 sizes[ XmUbMD_CHILD_MONTH_ARROW ].height ) + 1916 2 * md -> md.margin_height + md -> md.label_spacing + 1917 ( ( md -> md.month_arrows || md -> md.year_arrows ) ? 1918 ( sizes[ XmUbMD_CHILD_SEPARATOR ].height + 1919 md -> md.arrow_spacing ) : 0 ); 1920 1921 *pref_width = MAX( MAX( sizes[ XmUbMD_CHILD_TITLE ].width, 1922 sizes[ XmUbMD_CHILD_ROW_COLUMN ].width + 1923 sizes[ XmUbMD_CHILD_WEEK_RC ].width ), 1924 MAX( sizes[ XmUbMD_CHILD_YEAR_ARROW ].width, 1925 sizes[ XmUbMD_CHILD_MONTH_ARROW ].width ) ) + 1926 2 * md -> md.margin_width; 1927 1928 1929 return; 1930 1931 } /* GetOwnPreferredSize */ 1932 1933 1934 /*----------------------------------------------------------------------*/ 1935 1936 static void GetValuesHook(Widget w,ArgList args,Cardinal * num_args)1937 GetValuesHook( Widget w, 1938 ArgList args, 1939 Cardinal *num_args ) 1940 { 1941 /* Variables. */ 1942 int index; 1943 XmUbMonthDisplayWidget md; 1944 1945 /* Code. */ 1946 1947 md = (XmUbMonthDisplayWidget) w; 1948 1949 /* Copy the XmStrings. */ 1950 for( index = 0; index < *num_args; index ++ ){ 1951 1952 if( strcmp( args[ index ].name, XmUbNmdiMonthLabel ) == 0 ){ 1953 * ( XmString *) ( args[ index ].value ) = 1954 XmStringCopy( md -> md.month_label ); 1955 1956 } else if( strcmp( args[ index ].name, XmUbNmdiWeekLabel ) == 0 ){ 1957 * ( XmString *) ( args[ index ].value ) = 1958 XmStringCopy( md -> md.week_number_label ); 1959 1960 } else if( strcmp( args[ index ].name, XmUbNmdiYearLabel ) == 0 ){ 1961 * ( XmString *) ( args[ index ].value ) = 1962 XmStringCopy( md -> md.year_label ); 1963 } 1964 1965 } 1966 1967 1968 return; 1969 1970 } /* GetValuesHook */ 1971 1972 1973 /*----------------------------------------------------------------------*/ 1974 1975 static void Initialize(Widget treq,Widget tnew,ArgList args,Cardinal * num_args)1976 Initialize( Widget treq, 1977 Widget tnew, 1978 ArgList args, 1979 Cardinal *num_args ) 1980 { 1981 /* Variables. */ 1982 int index; 1983 KidDimensionRec kids_sizes[ NO_INTERNAL_CHILDREN ]; 1984 XmUbMonthDisplayWidget new; 1985 Dimension pref_height; 1986 Dimension pref_width; 1987 XmString xm; 1988 1989 /* Code. */ 1990 1991 new = (XmUbMonthDisplayWidget) tnew; 1992 1993 /* Initialize private fields. */ 1994 /* Nullify all widget ids. */ 1995 for( index = XmUbMD_FIRST_CHILD; index < NO_INTERNAL_CHILDREN; index ++ ) 1996 new -> md.internal_children[ index ] = NULL; 1997 for( index = 0; index < NO_DAY_NAME_BUTTONS; index ++ ) 1998 new -> md.day_name_buttons[ index ] = NULL; 1999 for( index = 0; index < NO_DAY_BUTTONS; index ++ ) 2000 new -> md.day_number_buttons[ index ] = NULL; 2001 for( index = 0; index < NO_WEEK_NUMBER_BUTTONS; index ++ ) 2002 new -> md.week_number_buttons[ index ] = NULL; 2003 2004 new -> md.date_icon = NULL; 2005 new -> md.date_icon_bm = None; 2006 new -> md.date_icon_mask = None; 2007 new -> md.inv_date_icon = NULL; 2008 new -> md.inv_date_icon_bm = None; 2009 new -> md.inv_date_icon_mask = None; 2010 2011 new -> md.exposed = False; 2012 2013 /* Start size if none supplied. */ 2014 if( new -> core.width == 0 ) 2015 new -> core.width = 300; 2016 else 2017 new -> md.recompute_width = False; 2018 2019 if( new -> core.height == 0 ) 2020 new -> core.height = 100; 2021 else 2022 new -> md.recompute_height = False; 2023 2024 /* Copy XmStrings. */ 2025 if( new -> md.month_label != NULL ){ 2026 xm = XmStringCopy( new -> md.month_label ); 2027 new -> md.month_label = xm; 2028 } 2029 if( new -> md.year_label != NULL ){ 2030 xm = XmStringCopy( new -> md.year_label ); 2031 new -> md.year_label = xm; 2032 } 2033 if( new -> md.week_number_label != NULL ){ 2034 xm = XmStringCopy( new -> md.week_number_label ); 2035 new -> md.week_number_label = xm; 2036 } 2037 2038 2039 /* Set defaults for current year and month. */ 2040 if( new -> md.current_month == 0 ) 2041 new -> md.current_month = 2042 TimIndexOfMonth( TimLocalTime( TimMakeTimeNow() ) ); 2043 2044 if( new -> md.current_year == 0 ) 2045 new -> md.current_year = 2046 TimIndexOfYear( TimLocalTime( TimMakeTimeNow() ) ); 2047 2048 new -> md.first_date_index = 0; 2049 2050 2051 /* Create the internal widgets. */ 2052 new -> md.internal_widgets_created = False; 2053 2054 CreateInternalWidgets( new ); 2055 2056 new -> md.internal_widgets_created = True; 2057 2058 /* Get the preferred dimensions of the widget. */ 2059 GetChildPrefSizes( new, NULL, NULL, kids_sizes ); 2060 GetOwnPreferredSize( new, kids_sizes, &pref_width, &pref_height ); 2061 2062 /* Set the desired size in the height and width fields. */ 2063 new -> core.width = pref_width; 2064 new -> core.height = pref_height; 2065 2066 2067 return; 2068 2069 } /* Initialize */ 2070 2071 2072 /*----------------------------------------------------------------------*/ 2073 2074 static void InsertChild(Widget widget)2075 InsertChild( Widget widget ) 2076 { 2077 2078 /* Variables. */ 2079 Cardinal num_params; 2080 String params[ 1 ]; 2081 XmUbMonthDisplayWidget md; 2082 2083 /* Code. */ 2084 2085 md = (XmUbMonthDisplayWidget) XtParent( widget ); 2086 2087 /* We do not allow the application to create children. */ 2088 if( md -> md.internal_widgets_created ){ 2089 2090 params[ 0 ] = XtClass( (Widget) md ) -> core_class.class_name; 2091 num_params = 1; 2092 XtAppErrorMsg( XtWidgetToApplicationContext( widget ), 2093 "childError", "number", "WidgetError", 2094 "Applications cannot add children to %s widgets.", 2095 params, &num_params ); 2096 } 2097 2098 /* This is an internal child. Adding it is OK. */ 2099 (* ( (CompositeWidgetClass) (xmUbMonthDisplayWidgetClass -> 2100 core_class.superclass) ) -> composite_class.insert_child ) ( widget ); 2101 2102 2103 return; 2104 2105 } /* InsertChild */ 2106 2107 2108 /*----------------------------------------------------------------------*/ 2109 2110 static void KidsPreferredGeometry(Widget kid,Widget initiator,XtWidgetGeometry * request,XtWidgetGeometry * desired)2111 KidsPreferredGeometry( Widget kid, 2112 Widget initiator, 2113 XtWidgetGeometry *request, 2114 XtWidgetGeometry *desired ) 2115 { 2116 2117 /* Code. */ 2118 2119 if( ( kid == initiator ) && ( request != NULL ) ){ 2120 /* The initiator should not be queried. */ 2121 if( request -> request_mode & CWWidth ) 2122 desired -> width = request -> width; 2123 else 2124 desired -> width = (Dimension) kid -> core.width; 2125 2126 if( request -> request_mode & CWHeight ) 2127 desired -> height = request -> height; 2128 else 2129 desired -> height = (Dimension) kid -> core.height; 2130 2131 } else 2132 (void) XtQueryGeometry( kid, NULL, desired ); 2133 2134 2135 return; 2136 2137 } /* KidsPreferredGeometry */ 2138 2139 2140 /*----------------------------------------------------------------------*/ 2141 2142 static void MonthScrolledCB(Widget pb,XmUbMonthDisplayWidget md,XmUbArrowLabelCallbackStruct * call_data)2143 MonthScrolledCB( Widget pb, 2144 XmUbMonthDisplayWidget md, 2145 XmUbArrowLabelCallbackStruct *call_data ) 2146 { 2147 /* Variables. */ 2148 2149 /* Code. */ 2150 2151 switch( call_data -> reason ){ 2152 2153 case XmUbCR_BACK_ARROW_ACTIVATED: 2154 md -> md.current_month --; 2155 break; 2156 2157 case XmUbCR_FORWARD_ARROW_ACTIVATED: 2158 md -> md.current_month ++; 2159 break; 2160 2161 default: 2162 return; 2163 } 2164 2165 if( md -> md.current_month > 12 ){ 2166 md -> md.current_month = 1; 2167 md -> md.current_year ++; 2168 2169 } else if( md -> md.current_month < 1 ){ 2170 md -> md.current_month = 12; 2171 md -> md.current_year --; 2172 2173 if( md -> md.current_year < 1970 ){ 2174 md -> md.current_year = 1970; 2175 md -> md.current_month = 1; 2176 } 2177 } 2178 2179 2180 UpdateNewMonth( md ); 2181 CallNewMonthCallbacks( md ); 2182 2183 2184 return; 2185 2186 } /* MonthScrolledCB */ 2187 2188 2189 /*----------------------------------------------------------------------*/ 2190 2191 static void Resize(Widget widget)2192 Resize( Widget widget ) 2193 { 2194 /* Variables. */ 2195 KidDimensionRec kids_sizes[ NO_INTERNAL_CHILDREN ]; 2196 XmUbMonthDisplayWidget md; 2197 2198 /* Code. */ 2199 2200 md = (XmUbMonthDisplayWidget) widget; 2201 2202 md -> md.resize_called = True; 2203 2204 /* We have to get the preferred size of the children before we organize 2205 the layout. */ 2206 GetChildPrefSizes( md, NULL, NULL, kids_sizes ); 2207 DoLayout( md, NULL, NULL, kids_sizes ); 2208 2209 2210 return; 2211 2212 } /* Resize */ 2213 2214 2215 /*----------------------------------------------------------------------*/ 2216 2217 static Boolean ResizeIfNeeded(XmUbMonthDisplayWidget md,KidDimensionRec sizes[])2218 ResizeIfNeeded( XmUbMonthDisplayWidget md, 2219 KidDimensionRec sizes[] ) 2220 { 2221 2222 /* Variables. */ 2223 Boolean layout_done; 2224 Dimension pref_height; 2225 Dimension pref_width; 2226 XtWidgetGeometry request; 2227 XtGeometryResult result; 2228 2229 /* Code. */ 2230 2231 /* Initialize. */ 2232 layout_done = False; 2233 2234 /* Get the preferred dimensions of the widget. */ 2235 GetChildPrefSizes( md, NULL, NULL, sizes ); 2236 GetOwnPreferredSize( md, sizes, &pref_width, &pref_height ); 2237 2238 /* If we want the same dimensions, no resizing is needed. */ 2239 if(( pref_width == md -> core.width ) && 2240 ( pref_height == md -> core.height )) 2241 return False; 2242 2243 /* Dimensions are different. Try to resize. */ 2244 request.request_mode = CWWidth | CWHeight; 2245 2246 request.width = pref_width; 2247 request.height = pref_height; 2248 2249 md -> md.resize_called = False; 2250 2251 do { 2252 2253 result = XtMakeGeometryRequest( (Widget) md, &request, &request ); 2254 2255 } while( result == XtGeometryAlmost ); 2256 2257 if( result == XtGeometryNo ) 2258 return False; 2259 2260 /* Resize done. Core fields have already been updated. */ 2261 return( md -> md.resize_called ); 2262 2263 } /* ResizeIfNeeded */ 2264 2265 2266 /*----------------------------------------------------------------------*/ 2267 2268 static XtGeometryResult QueryGeometry(Widget widget,XtWidgetGeometry * proposed,XtWidgetGeometry * answer)2269 QueryGeometry( Widget widget, 2270 XtWidgetGeometry *proposed, 2271 XtWidgetGeometry *answer ) 2272 { 2273 2274 KidDimensionRec kids_sizes[ NO_INTERNAL_CHILDREN ]; 2275 XmUbMonthDisplayWidget md; 2276 Dimension pref_height; 2277 Dimension pref_width; 2278 2279 /* Code. */ 2280 2281 md = (XmUbMonthDisplayWidget) widget; 2282 2283 /* Get dimensions that we *really* want. */ 2284 GetChildPrefSizes( md, NULL, NULL, kids_sizes ); 2285 GetOwnPreferredSize( md, kids_sizes, &pref_width, &pref_height ); 2286 2287 answer -> request_mode = CWWidth | CWHeight; 2288 answer -> width = pref_width; 2289 answer -> height = pref_height; 2290 2291 2292 if( proposed == NULL ){ 2293 /* This is a query for the requested geometry. */ 2294 2295 if(( answer -> height == (int) md -> core.height ) && 2296 ( answer -> width == (int) md -> core.width )) 2297 return XtGeometryNo; 2298 else 2299 return XtGeometryAlmost; 2300 } 2301 2302 /* The parent supplied a geometry suggestion. */ 2303 if(( answer -> height == proposed -> height ) && 2304 ( answer -> width == proposed -> width )) 2305 return XtGeometryYes; 2306 2307 if( ( proposed -> height <= 1 ) || 2308 ( proposed -> width <= 1 ) ) 2309 /* That's too small ! */ 2310 return XtGeometryNo; 2311 2312 2313 /* Only a compromise left. */ 2314 return XtGeometryAlmost; 2315 2316 } /* QueryGeometry */ 2317 2318 2319 /*----------------------------------------------------------------------*/ 2320 2321 static void SetDayNames(XmUbMonthDisplayWidget md)2322 SetDayNames( XmUbMonthDisplayWidget md ) 2323 { 2324 /* Variables. */ 2325 Arg args[ 2 ]; 2326 char day_name_buffer[ LABEL_BUFFER_LENGTH ]; 2327 int first_day_index; 2328 int index; 2329 char label_buffer[ LABEL_BUFFER_LENGTH ]; 2330 Cardinal n; 2331 XmString old_xm; 2332 TIM_TIME_REF time; 2333 XmString xm; 2334 2335 /* Code. */ 2336 2337 /* The week title. */ 2338 if( md -> md.week_numbers ){ 2339 2340 n = 0; 2341 XtSetArg( args[ n ], XmNlabelString, &old_xm ); n++; 2342 XtGetValues( md -> md.week_number_buttons[ 0 ], args, n ); 2343 2344 if( ! XmStringCompare( old_xm, md -> md.week_number_label ) ){ 2345 n = 0; 2346 XtSetArg( args[ n ], XmNlabelString, md -> md.week_number_label ); n++; 2347 XtSetArg( args[ n ], XmNalignment, XmALIGNMENT_CENTER ); n++; 2348 XtSetValues( md -> md.week_number_buttons[ 0 ], args, n ); 2349 } 2350 } 2351 2352 2353 /* The day names. */ 2354 2355 first_day_index = TimIndexOfFirstDayInWeek(); 2356 2357 /* We need day names from the locale, so create a real time we can 2358 play with. */ 2359 2360 time = TimMakeTimeNow(); 2361 2362 /* first_day_index : 0 = Sunday, 1 = Monday. */ 2363 /* TimIndexOfDayInWeek : first day in week = 1. */ 2364 2365 /* Step forwards until we are on the first day of the week. */ 2366 while( TimIndexOfDayInWeek( time ) != 1 ) 2367 TimAddDays( &time, 1 ); 2368 2369 /* We are on the first day of a week. */ 2370 for( index = 0; index < NO_DAY_NAME_BUTTONS; index ++ ){ 2371 2372 TimFormatStrTime( time, "%a", label_buffer, LABEL_BUFFER_LENGTH - 1 ); 2373 2374 if( md -> md.day_name_characters > 0 ){ 2375 strncpy( day_name_buffer, label_buffer, 2376 MIN( md -> md.day_name_characters, LABEL_BUFFER_LENGTH ) ); 2377 day_name_buffer[ 2378 MIN( md -> md.day_name_characters, LABEL_BUFFER_LENGTH ) ] = '\0'; 2379 } else 2380 strcpy( day_name_buffer, label_buffer ); 2381 2382 xm = XmStringCreateLtoR( day_name_buffer, XmSTRING_DEFAULT_CHARSET ); 2383 2384 /* Get old string and compare to see if we need to change. */ 2385 n = 0; 2386 XtSetArg( args[ n ], XmNlabelString, &old_xm ); n++; 2387 XtGetValues( md -> md.day_name_buttons[ index ], args, n ); 2388 2389 if( ! XmStringCompare( old_xm, xm ) ){ 2390 n = 0; 2391 XtSetArg( args[ n ], XmNlabelString, xm ); n++; 2392 XtSetArg( args[ n ], XmNalignment, XmALIGNMENT_CENTER ); n++; 2393 XtSetValues( md -> md.day_name_buttons[ index ], args, n ); 2394 } 2395 2396 XmStringFree( xm ); 2397 2398 /* Next day. */ 2399 TimAddDays( &time, 1 ); 2400 2401 } 2402 2403 2404 return; 2405 2406 } /* SetDayNames */ 2407 2408 2409 /*----------------------------------------------------------------------*/ 2410 2411 static Boolean SetValues(Widget current,Widget request,Widget new,ArgList args,Cardinal * num_args)2412 SetValues( Widget current, 2413 Widget request, 2414 Widget new, 2415 ArgList args, 2416 Cardinal *num_args ) 2417 { 2418 #ifdef Differs 2419 #undef Differs 2420 #endif 2421 2422 #define Differs( field ) ( curW -> field != newW -> field ) 2423 2424 /* Variables. */ 2425 XmUbMonthDisplayWidget curW; 2426 Boolean do_layout = False; 2427 Boolean fill; 2428 int index; 2429 Arg local_args[ 3 ]; 2430 Cardinal n; 2431 Boolean new_fill; 2432 XmUbMonthDisplayWidget newW; 2433 Boolean redisplay = False; 2434 Cardinal saved_n; 2435 Boolean update_month = False; 2436 Boolean visual_changed = False; 2437 XmString xm; 2438 2439 /* Code. */ 2440 2441 curW = (XmUbMonthDisplayWidget) current; 2442 newW = (XmUbMonthDisplayWidget) new; 2443 2444 /* Width and height. */ 2445 /* Resizing is handled higher up. */ 2446 2447 if( Differs( md.recompute_width ) && newW -> md.recompute_width ) 2448 visual_changed = True; 2449 else if( Differs( core.width ) ) 2450 newW -> md.recompute_width = False; 2451 2452 if( Differs( md.recompute_height ) && newW -> md.recompute_height ) 2453 visual_changed = True; 2454 else if( Differs( core.height ) ) 2455 newW -> md.recompute_height = False; 2456 2457 /* Margins and spacings. */ 2458 if( Differs( md.margin_width ) || 2459 Differs( md.margin_height ) || 2460 Differs( md.label_spacing ) || 2461 Differs( md.arrow_spacing ) ) 2462 visual_changed = True; 2463 2464 /* These resources may only be set at creation. */ 2465 if( Differs( md.enable_separator ) ){ 2466 WarningNoResourceChange( newW, "XmUbNmdiEnableSeparator" ); 2467 newW -> md.enable_separator = curW -> md.enable_separator; 2468 } 2469 if( Differs( md.month_arrows ) ){ 2470 WarningNoResourceChange( newW, "XmUbNmdiMonthArrows" ); 2471 newW -> md.month_arrows = curW -> md.month_arrows; 2472 } 2473 if( Differs( md.year_arrows ) ){ 2474 WarningNoResourceChange( newW, "XmUbNmdiYearArrows" ); 2475 newW -> md.year_arrows = curW -> md.year_arrows; 2476 } 2477 if( Differs( md.week_numbers ) ){ 2478 WarningNoResourceChange( newW, "XmUbNmdiWeekNumbers" ); 2479 newW -> md.week_numbers = curW -> md.week_numbers; 2480 } 2481 if( Differs( md.day_name_characters ) ){ 2482 WarningNoResourceChange( newW, "XmUbNmdiDayChars" ); 2483 newW -> md.day_name_characters = curW -> md.day_name_characters; 2484 } 2485 if( Differs( md.week_number_label ) ){ 2486 WarningNoResourceChange( newW, "XmUbNmdiWeekLabel" ); 2487 newW -> md.week_number_label = curW -> md.week_number_label; 2488 } 2489 2490 /* These resources affect child widgets. */ 2491 if( Differs( md.use_default_title_callback ) || 2492 Differs( md.title_callback ) ){ 2493 2494 /* We may have to change the resources for the title bar. */ 2495 n = 0; 2496 XtSetArg( local_args[ n ], XmNfillOnArm, &fill ); n++; 2497 XtGetValues( newW -> md.internal_children[ XmUbMD_CHILD_TITLE ], 2498 local_args, n ); 2499 2500 new_fill = newW -> md.use_default_title_callback || 2501 ( newW -> md.title_callback != NULL ); 2502 2503 if( fill != new_fill ){ 2504 n = 0; 2505 XtSetArg( local_args[ n ], XmNfillOnArm, new_fill ); n++; 2506 XtSetValues( newW -> md.internal_children[ XmUbMD_CHILD_TITLE ], 2507 local_args, n ); 2508 } 2509 } 2510 2511 if( Differs( md.week_number_label ) ){ 2512 2513 if( curW -> md.week_number_label != NULL ) 2514 XmStringFree( curW -> md.week_number_label ); 2515 2516 if( newW -> md.week_number_label != NULL ){ 2517 xm = XmStringCopy( newW -> md.week_number_label ); 2518 newW -> md.week_number_label = xm; 2519 } 2520 2521 update_month = True; 2522 } 2523 2524 if( Differs( md.month_label ) || 2525 Differs( md.year_label ) || 2526 Differs( manager.foreground ) || 2527 Differs( core.background_pixel ) ){ 2528 2529 n = 0; 2530 2531 if( Differs( manager.foreground ) ){ 2532 XtSetArg( local_args[ n ], XmNforeground, 2533 newW -> manager.foreground ); n++; 2534 } 2535 if( Differs( core.background_pixel ) ){ 2536 XtSetArg( local_args[ n ], XmNbackground, 2537 newW -> core.background_pixel ); n++; 2538 2539 /* The background was changed. We must recalculate shadow colors. */ 2540 XmGetColors( XtScreen( (Widget) newW ), newW -> core.colormap, 2541 newW -> core.background_pixel, NULL, 2542 & newW -> md.pushb_default_topshadow, 2543 & newW -> md.pushb_default_bottomshadow, NULL ); 2544 } 2545 2546 /* The pushbuttons are only affected by the change in colors. */ 2547 if( n != 0 ){ 2548 XtSetValues( newW -> md.internal_children[ XmUbMD_CHILD_TITLE ], 2549 local_args, n ); 2550 if( newW -> md.week_numbers ) 2551 XtSetValues( newW -> md.week_number_buttons[ 0 ], local_args, n ); 2552 2553 for( index = 0; index < NO_DAY_NAME_BUTTONS; index ++ ) 2554 XtSetValues( newW -> md.day_name_buttons[ index ], local_args, n ); 2555 2556 update_month = True; 2557 } 2558 2559 saved_n = n; 2560 2561 if( Differs( md.month_label ) ){ 2562 if( curW -> md.month_label != NULL ) 2563 XmStringFree( curW -> md.month_label ); 2564 2565 if( newW -> md.month_label != NULL ){ 2566 xm = XmStringCopy( newW -> md.month_label ); 2567 newW -> md.month_label = xm; 2568 } 2569 2570 XtSetArg( local_args[ n ], XmNlabelString, newW -> md.month_label ); n++; 2571 } 2572 if( n != 0 ) 2573 XtSetValues( newW -> md.internal_children[ XmUbMD_CHILD_MONTH_ARROW ], 2574 local_args, n ); 2575 2576 n = saved_n; 2577 if( Differs( md.year_label ) ){ 2578 2579 if( curW -> md.year_label != NULL ) 2580 XmStringFree( curW -> md.year_label ); 2581 2582 if( newW -> md.year_label != NULL ){ 2583 xm = XmStringCopy( newW -> md.year_label ); 2584 newW -> md.year_label = xm; 2585 } 2586 2587 XtSetArg( local_args[ n ], XmNlabelString, newW -> md.year_label ); n++; 2588 } 2589 if( n != 0 ) 2590 XtSetValues( newW -> md.internal_children[ XmUbMD_CHILD_YEAR_ARROW ], 2591 local_args, n ); 2592 2593 } 2594 2595 2596 if( Differs( md.current_year ) || 2597 Differs( md.current_month ) || 2598 Differs( md.fill_out_week ) || 2599 Differs( md.weekday_foreground ) || 2600 Differs( md.sun_foreground ) || 2601 Differs( md.sat_foreground ) || 2602 Differs( md.today_foreground ) || 2603 Differs( md.other_month_foreground ) || 2604 Differs( md.week_number_foreground ) ) 2605 update_month = True; 2606 2607 if( Differs( md.title_alignment ) ) 2608 do_layout = True; 2609 2610 2611 if( update_month ){ 2612 UpdateNewMonth( newW ); 2613 CallNewMonthCallbacks( newW ); 2614 } 2615 2616 if( visual_changed || do_layout ){ 2617 2618 KidDimensionRec kids_sizes[ NO_INTERNAL_CHILDREN ]; 2619 Boolean resized; 2620 2621 /* Code. */ 2622 2623 if( visual_changed ) 2624 resized = ResizeIfNeeded( newW, kids_sizes ); 2625 else 2626 resized = False; 2627 2628 /* If the widget was resized, the layout has already been done. */ 2629 if( !resized ) 2630 DoLayout( newW, NULL, NULL, kids_sizes ); 2631 2632 } 2633 2634 return( redisplay || visual_changed || do_layout || update_month ); 2635 2636 #undef Differs 2637 2638 } /* SetValues */ 2639 2640 2641 /*----------------------------------------------------------------------*/ 2642 2643 #if XmVersion > 1001 2644 2645 static void StartDateDrag(Widget w,XEvent * event,String * params,Cardinal num_params)2646 StartDateDrag( Widget w, 2647 XEvent *event, 2648 String *params, 2649 Cardinal num_params ) 2650 { 2651 /* Variables. */ 2652 Arg args[ 8 ]; 2653 Atom compound_text_atom; 2654 Atom date_transfer_atom; 2655 Widget drag_context; 2656 Atom exportList[ 2 ]; 2657 XmUbMonthDisplayWidget md; 2658 Cardinal n; 2659 Widget tmp_widget; 2660 2661 /* Code. */ 2662 2663 compound_text_atom = XmInternAtom( XtDisplay( w ), "COMPOUND_TEXT", False ); 2664 date_transfer_atom = XmInternAtom( XtDisplay( w ), XmUbDATE_TRANSFER, 2665 False ); 2666 2667 /* Establish the list of valid target types. */ 2668 exportList[ 0 ] = date_transfer_atom; 2669 exportList[ 1 ] = compound_text_atom; 2670 2671 tmp_widget = XtParent( w ); 2672 while( ! XtIsSubclass( tmp_widget, xmUbMonthDisplayWidgetClass ) ) 2673 tmp_widget = XtParent( tmp_widget ); 2674 md = (XmUbMonthDisplayWidget) tmp_widget; 2675 2676 /* Create the drag icon if it doesn't exist. */ 2677 md -> md.internal_widgets_created = False; 2678 2679 if( md -> md.date_icon == NULL ){ 2680 2681 if( md -> md.date_icon_bm == None ) 2682 md -> md.date_icon_bm = XCreateBitmapFromData( 2683 XtDisplay( w ), XtWindow( w ), 2684 (char*) DateDragIcon_bits, DateDragIcon_width, DateDragIcon_height ); 2685 2686 if( md -> md.date_icon_mask == None ) 2687 md -> md.date_icon_mask = XCreateBitmapFromData( 2688 XtDisplay( w ), XtWindow( w ), 2689 (char*) DateDragMask_bits, DateDragMask_width, DateDragMask_height ); 2690 2691 n = 0; 2692 XtSetArg( args[ n ], XmNmask, md -> md.date_icon_mask ); n++; 2693 XtSetArg( args[ n ], XmNpixmap, md -> md.date_icon_bm ); n++; 2694 XtSetArg( args[ n ], XmNdepth, 1 ); n++; 2695 XtSetArg( args[ n ], XmNwidth, DateDragIcon_width ); n++; 2696 XtSetArg( args[ n ], XmNheight, DateDragIcon_height ); n++; 2697 md -> md.date_icon = XmCreateDragIcon( (Widget) md, "dragIcon", args, n ); 2698 } 2699 2700 if( md -> md.inv_date_icon == NULL ){ 2701 2702 if( md -> md.inv_date_icon_bm == None ) 2703 md -> md.inv_date_icon_bm = XCreateBitmapFromData( 2704 XtDisplay( w ), XtWindow( w ), 2705 (char*) DateDragInvIcon_bits, DateDragInvIcon_width, 2706 DateDragInvIcon_height ); 2707 2708 if( md -> md.inv_date_icon_mask == None ) 2709 md -> md.inv_date_icon_mask = XCreateBitmapFromData( 2710 XtDisplay( w ), XtWindow( w ), 2711 (char*) DateDragInvIconMask_bits, DateDragInvIconMask_width, 2712 DateDragInvIconMask_height ); 2713 2714 n = 0; 2715 XtSetArg( args[ n ], XmNmask, md -> md.inv_date_icon_mask ); n++; 2716 XtSetArg( args[ n ], XmNpixmap, md -> md.inv_date_icon_bm ); n++; 2717 XtSetArg( args[ n ], XmNdepth, 1 ); n++; 2718 XtSetArg( args[ n ], XmNwidth, DateDragInvIcon_width ); n++; 2719 XtSetArg( args[ n ], XmNheight, DateDragInvIcon_height ); n++; 2720 md -> md.inv_date_icon = XmCreateDragIcon( (Widget) md, "invDragIcon", 2721 args, n ); 2722 } 2723 2724 md -> md.internal_widgets_created = True; 2725 2726 n = 0; 2727 XtSetArg( args[ n ], XmNexportTargets, exportList ); n++; 2728 XtSetArg( args[ n ], XmNnumExportTargets, 2 ); n++; 2729 XtSetArg( args[ n ], XmNdragOperations, XmDROP_COPY ); n++; 2730 XtSetArg( args[ n ], XmNconvertProc, DateDragConvertProc ); n++; 2731 XtSetArg( args[ n ], XmNclientData, (XtPointer) w ); n++; 2732 XtSetArg( args[ n ], XmNsourcePixmapIcon, md -> md.inv_date_icon ); n++; 2733 XtSetArg( args[ n ], XmNsourceCursorIcon, md -> md.inv_date_icon ); n++; 2734 2735 drag_context = XmDragStart( w, event, args, n ); 2736 2737 /* Handle custom visual effects. */ 2738 XtAddCallback( drag_context, XmNdropSiteEnterCallback, 2739 (XtCallbackProc) DateEnterDropSiteCB, (XtPointer) md ); 2740 XtAddCallback( drag_context, XmNdropSiteLeaveCallback, 2741 (XtCallbackProc) DateLeaveDropSiteCB, (XtPointer) md ); 2742 2743 2744 return; 2745 2746 } /* StartDateDrag */ 2747 2748 #endif 2749 2750 /*----------------------------------------------------------------------*/ 2751 2752 static void TitleBarPressedCB(Widget pb,XmUbMonthDisplayWidget md,XmPushButtonCallbackStruct * call_data)2753 TitleBarPressedCB( Widget pb, 2754 XmUbMonthDisplayWidget md, 2755 XmPushButtonCallbackStruct *call_data ) 2756 { 2757 /* Variables. */ 2758 XmUbMonthDisplayCallbackStruct cb; 2759 int old_month; 2760 int old_year; 2761 TIM_TIME_REF time; 2762 2763 /* Code. */ 2764 2765 /* Save current year and month for later. */ 2766 old_month = md -> md.current_month; 2767 old_year = md -> md.current_year; 2768 2769 /* Default action ? */ 2770 if( md -> md.use_default_title_callback ){ 2771 2772 /* Set current year and month. */ 2773 2774 time = TimLocalTime( TimMakeTimeNow() ); 2775 2776 /* Set the current year and month. */ 2777 md -> md.current_month = TimIndexOfMonth( time ); 2778 md -> md.current_year = TimIndexOfYear( time ); 2779 } 2780 2781 /* Call user's callbacks. */ 2782 if( md -> md.title_callback != NULL ){ 2783 2784 /* Callbacks are defined. */ 2785 /* Set up the callback structure. */ 2786 cb.reason = XmUbCR_TITLE_PRESSED; 2787 cb.event = call_data -> event; 2788 cb.selected_month = md -> md.current_month; 2789 cb.selected_year = md -> md.current_year; 2790 2791 /* Call the user callbacks. */ 2792 XtCallCallbackList( (Widget) md, md -> md.title_callback, 2793 (XtPointer) &cb ); 2794 } 2795 2796 /* If the month or year was changed, we should update the display. */ 2797 if( ( old_month != md -> md.current_month ) || 2798 ( old_year != md -> md.current_year ) ){ 2799 UpdateNewMonth( md ); 2800 CallNewMonthCallbacks( md ); 2801 } 2802 2803 2804 return; 2805 2806 } /* TitleBarPressedCB */ 2807 2808 2809 /*----------------------------------------------------------------------*/ 2810 2811 static void UpdateDayButton(XmUbMonthDisplayWidget md,int index,int date,XmUbWhichMonth which_month)2812 UpdateDayButton( XmUbMonthDisplayWidget md, 2813 int index, 2814 int date, 2815 XmUbWhichMonth which_month ) 2816 { 2817 /* Variables. */ 2818 Arg args[ 10 ]; 2819 XmUbMdiUpdateDayCallbackStruct cb; 2820 char label_buffer[ 20 ]; 2821 Cardinal n; 2822 TIM_TIME_REF now; 2823 int old_date; 2824 Pixel old_fg, old_bg, old_top, old_bottom; 2825 Boolean old_mapped; 2826 TIM_TIME_REF time; 2827 int user_data = -1; 2828 Widget w; 2829 XmString xm = NULL; 2830 2831 /* Code. */ 2832 2833 w = md -> md.day_number_buttons[ index ]; 2834 2835 /* Get the current values. */ 2836 2837 n = 0; 2838 XtSetArg( args[ n ], XmNuserData, &old_date ); n++; 2839 XtSetArg( args[ n ], XmNforeground, &old_fg ); n++; 2840 XtSetArg( args[ n ], XmNbackground, &old_bg ); n++; 2841 XtSetArg( args[ n ], XmNtopShadowColor, &old_top ); n++; 2842 XtSetArg( args[ n ], XmNbottomShadowColor, &old_bottom ); n++; 2843 XtSetArg( args[ n ], XmNmappedWhenManaged, &old_mapped ); n++; 2844 XtGetValues( w, args, n ); 2845 2846 /* Fill in the callback structure. Can be used also if no callback. */ 2847 cb.reason = XmUbCR_UPDATE_DAY; 2848 cb.event = NULL; 2849 cb.day = date; 2850 cb.loop_index = index; 2851 2852 switch( which_month ){ 2853 2854 case XmUbCURRENT_MONTH: 2855 cb.month = md -> md.current_month; 2856 cb.year = md -> md.current_year; 2857 break; 2858 2859 case XmUbPREVIOUS_MONTH: 2860 cb.month = md -> md.current_month - 1; 2861 cb.year = md -> md.current_year; 2862 2863 if( cb.month < 1 ){ 2864 cb.month = 12; 2865 cb.year --; 2866 } 2867 2868 break; 2869 2870 case XmUbNEXT_MONTH: 2871 cb.month = md -> md.current_month + 1; 2872 cb.year = md -> md.current_year; 2873 2874 if( cb.month > 12 ){ 2875 cb.month = 1; 2876 cb.year ++; 2877 } 2878 2879 break; 2880 } 2881 2882 time = TimMakeTime( cb.year, cb.month, cb.day, 0, 0, 0 ); 2883 2884 cb.weekday = TimIndexOfDayInWeek( time ); 2885 if( TimIndexOfFirstDayInWeek() == 0 ) 2886 cb.weekday --; 2887 if( cb.weekday == 0 ) 2888 cb.weekday = 7; 2889 2890 cb.day_num_in_year = TimIndexOfDayInYear( time ); 2891 cb.week_number = TimIndexOfWeek( time ); 2892 cb.foreground = old_fg; 2893 cb.background = old_bg; 2894 cb.frame = old_top; 2895 cb.mapped = old_mapped; 2896 cb.use_shadows = False; 2897 2898 /* Check if the day displayed is "today". */ 2899 now = TimLocalTime( TimMakeTimeNow() ); 2900 if( ( TimIndexOfDay( time ) == TimIndexOfDay( now ) ) && 2901 ( TimIndexOfMonth( time ) == TimIndexOfMonth( now ) ) && 2902 ( TimIndexOfYear( time ) == TimIndexOfYear( now ) ) ) 2903 cb.today = True; 2904 else 2905 cb.today = False; 2906 2907 2908 /* For dates outside the current month, other_month resource overrides. */ 2909 if( which_month != XmUbCURRENT_MONTH ){ 2910 2911 cb.default_foreground = md -> md.other_month_foreground; 2912 cb.default_background = md -> core.background_pixel; 2913 cb.default_frame = md -> core.background_pixel; 2914 cb.default_mapped = md -> md.fill_out_week; 2915 2916 } else { 2917 /* This is a date in the current month. */ 2918 2919 if( cb.today ) 2920 cb.default_foreground = md -> md.today_foreground; 2921 2922 else if( cb.weekday == 7 ) 2923 cb.default_foreground = md -> md.sun_foreground; 2924 2925 else if( cb.weekday == 6 ) 2926 cb.default_foreground = md -> md.sat_foreground; 2927 2928 else 2929 cb.default_foreground = md -> md.weekday_foreground; 2930 2931 cb.default_mapped = True; 2932 } 2933 2934 cb.default_background = md -> core.background_pixel; 2935 cb.default_frame = md -> core.background_pixel; 2936 cb.which_month = which_month; 2937 2938 if( md -> md.update_day_callback ){ 2939 /* Let the user determine what should be displayed. */ 2940 2941 XtCallCallbackList( (Widget) md, md -> md.update_day_callback, 2942 (XtPointer) &cb ); 2943 2944 } else { 2945 /* We should display the defaults. */ 2946 cb.foreground = cb.default_foreground; 2947 cb.background = cb.default_background; 2948 cb.frame = cb.default_frame; 2949 cb.mapped = cb.default_mapped; 2950 } 2951 2952 /* Set the values. */ 2953 n = 0; 2954 2955 if( cb.foreground != old_fg ){ 2956 XtSetArg( args[ n ], XmNforeground, cb.foreground ); n++; 2957 } 2958 if( cb.background != old_bg ){ 2959 XtSetArg( args[ n ], XmNbackground, cb.background ); n++; 2960 } 2961 2962 if( ! cb.use_shadows ){ 2963 if( cb.frame != old_top ){ 2964 XtSetArg( args[ n ], XmNtopShadowColor, cb.frame ); n++; 2965 XtSetArg( args[ n ], XmNbottomShadowColor, cb.frame ); n++; 2966 } 2967 2968 } else { 2969 /* Pushbutton shadows on button. */ 2970 2971 if( old_top != md -> md.pushb_default_topshadow ){ 2972 XtSetArg( args[ n ], XmNtopShadowColor, 2973 md -> md.pushb_default_topshadow ); n++; 2974 } 2975 if( old_bottom != md -> md.pushb_default_bottomshadow ){ 2976 XtSetArg( args[ n ], XmNbottomShadowColor, 2977 md -> md.pushb_default_bottomshadow ); n++; 2978 } 2979 } 2980 2981 if( cb.mapped != old_mapped ){ 2982 XtSetArg( args[ n ], XmNmappedWhenManaged, cb.mapped ); n++; 2983 } 2984 2985 /* If we are lucky, we don't need to change the text... */ 2986 if( ( old_date % 100 ) != date ){ 2987 sprintf( label_buffer, "%d", date ); 2988 xm = XmStringCreateLtoR( label_buffer, XmSTRING_DEFAULT_CHARSET ); 2989 2990 XtSetArg( args[ n ], XmNlabelString, xm ); n++; 2991 2992 switch( which_month ){ 2993 2994 case XmUbCURRENT_MONTH: 2995 user_data = date; 2996 break; 2997 2998 case XmUbPREVIOUS_MONTH: 2999 user_data = date + PREVIOUS_MONTH_OFFSET; 3000 break; 3001 3002 case XmUbNEXT_MONTH: 3003 user_data = date + NEXT_MONTH_OFFSET; 3004 break; 3005 } 3006 assert( user_data != -1 ); 3007 3008 XtSetArg( args[ n ], XmNuserData, user_data ); n++; 3009 } 3010 3011 /* Update the button. */ 3012 if( n > 0 ) 3013 XtSetValues( w, args, n ); 3014 3015 /* Cleanup. */ 3016 if( xm != NULL ) 3017 XmStringFree( xm ); 3018 3019 3020 return; 3021 3022 } /* UpdateDayButton */ 3023 3024 3025 /*----------------------------------------------------------------------*/ 3026 3027 static void UpdateNewMonth(XmUbMonthDisplayWidget md)3028 UpdateNewMonth( XmUbMonthDisplayWidget md ) 3029 { 3030 /* Variables. */ 3031 Arg args[ 8 ]; 3032 int day_number; 3033 int days_in_month; 3034 int first_date_index; 3035 int index; 3036 char label_buffer[ LABEL_BUFFER_LENGTH ]; 3037 Boolean mapped; 3038 int month_number; 3039 Cardinal n; 3040 TIM_TIME_REF time; 3041 TIM_TIME_REF time_of_first_date; 3042 int year_number; 3043 XmString xm; 3044 3045 /* Code. */ 3046 3047 /* Title text. */ 3048 3049 time_of_first_date = TimMakeTime( md -> md.current_year, 3050 md -> md.current_month, 1, 0, 0, 0 ); 3051 3052 TimFormatStrTime( time_of_first_date, "%B %Y", label_buffer, 3053 LABEL_BUFFER_LENGTH - 1 ); 3054 3055 xm = XmStringCreateLtoR( label_buffer, XmSTRING_DEFAULT_CHARSET ); 3056 3057 n = 0; 3058 XtSetArg( args[ n ], XmNlabelString, xm ); n++; 3059 XtSetValues( md -> md.internal_children[ XmUbMD_CHILD_TITLE ], args, n ); 3060 XmStringFree( xm ); 3061 3062 /* The day names or the week title may have to be changed. */ 3063 SetDayNames( md ); 3064 3065 /* Set the day numbers. */ 3066 3067 /* Find out on which index we should start. */ 3068 /* first_day_index : 0 = Sunday, 1 = Monday. */ 3069 /* TimIndexOfDayInWeek : 1 for the first day of the week. */ 3070 3071 first_date_index = TimIndexOfDayInWeek( time_of_first_date ) - 1; 3072 3073 /* If no days from the previous month are displayed, we should step back a 3074 week and display the last week of the previous month. */ 3075 if( ( md -> md.fill_out_week ) && ( first_date_index == 0 ) ) 3076 first_date_index += 7; 3077 3078 md -> md.first_date_index = first_date_index; 3079 3080 /* Set the days in the preceding month. */ 3081 time = time_of_first_date; 3082 TimAddDays( &time, -1 ); 3083 days_in_month = TimDaysInMonth( time ); 3084 3085 for( index = 0, day_number = days_in_month - first_date_index + 1; 3086 index < first_date_index; 3087 index ++, day_number ++ ) 3088 UpdateDayButton( md, index, day_number, XmUbPREVIOUS_MONTH ); 3089 3090 3091 /* The current month. */ 3092 time = time_of_first_date; 3093 days_in_month = TimDaysInMonth( time ); 3094 3095 for( index = first_date_index, day_number = 1; 3096 day_number <= days_in_month; 3097 index ++, day_number ++ ) 3098 UpdateDayButton( md, index, day_number, XmUbCURRENT_MONTH ); 3099 3100 /* Fill out with the following month. */ 3101 for( day_number = 1; index < NO_DAY_BUTTONS; index ++, day_number ++ ) 3102 UpdateDayButton( md, index, day_number, XmUbNEXT_MONTH ); 3103 3104 /* Update the week numbers. */ 3105 if( md -> md.week_numbers ){ 3106 3107 /* For every week, display the week number of the first day. */ 3108 /* Converting to the time handles all problems when switching year. */ 3109 for( index = 1; index < NO_WEEK_NUMBER_BUTTONS; index ++ ){ 3110 3111 ButtonDate( md, md -> md.day_number_buttons[ ( index - 1 ) * 7 ], 3112 &year_number, &month_number, &day_number ); 3113 3114 time = TimMakeTime( year_number, month_number, day_number, 0, 0, 0 ); 3115 3116 /* We don't want to display week numbers for empty weeks. */ 3117 if( ! md -> md.fill_out_week && 3118 ( month_number != md -> md.current_month ) && 3119 ( year_number >= md -> md.current_year ) && 3120 ( time > time_of_first_date ) ) 3121 mapped = False; 3122 else 3123 mapped = True; 3124 3125 UpdateWeekButton( md, index, time, mapped ); 3126 } 3127 } 3128 3129 3130 return; 3131 3132 } /* UpdateNewMonth */ 3133 3134 3135 /*----------------------------------------------------------------------*/ 3136 3137 static void UpdateWeekButton(XmUbMonthDisplayWidget md,int index,TIM_TIME_REF time_of_first_day,Boolean mapped)3138 UpdateWeekButton( XmUbMonthDisplayWidget md, 3139 int index, 3140 TIM_TIME_REF time_of_first_day, 3141 Boolean mapped ) 3142 { 3143 /* Variables. */ 3144 Arg args[ 10 ]; 3145 XmUbMdiUpdateDayCallbackStruct cb; 3146 char label_buffer[ 20 ]; 3147 Cardinal n; 3148 Pixel old_fg, old_bg, old_top, old_bottom; 3149 Boolean old_mapped; 3150 int user_data; 3151 Widget w; 3152 XmString xm = NULL; 3153 3154 /* Code. */ 3155 3156 w = md -> md.week_number_buttons[ index ]; 3157 3158 /* Get the current values. */ 3159 3160 n = 0; 3161 XtSetArg( args[ n ], XmNuserData, &user_data ); n++; 3162 XtSetArg( args[ n ], XmNforeground, &old_fg ); n++; 3163 XtSetArg( args[ n ], XmNbackground, &old_bg ); n++; 3164 XtSetArg( args[ n ], XmNtopShadowColor, &old_top ); n++; 3165 XtSetArg( args[ n ], XmNbottomShadowColor, &old_bottom ); n++; 3166 XtSetArg( args[ n ], XmNmappedWhenManaged, &old_mapped ); n++; 3167 XtGetValues( w, args, n ); 3168 3169 /* Fill in the callback structure. Can be used also if no callback. */ 3170 cb.reason = XmUbCR_UPDATE_WEEK; 3171 cb.event = NULL; 3172 cb.day = TimIndexOfDay( time_of_first_day ); 3173 cb.month = TimIndexOfMonth( time_of_first_day ); 3174 cb.year = TimIndexOfYear( time_of_first_day ); 3175 cb.week_number = TimIndexOfWeek( time_of_first_day ); 3176 cb.foreground = old_fg; 3177 cb.background = old_bg; 3178 cb.frame = old_top; 3179 cb.use_shadows = False; 3180 cb.mapped = old_mapped; 3181 3182 cb.default_foreground = md -> md.week_number_foreground; 3183 cb.default_background = md -> core.background_pixel; 3184 cb.default_frame = md -> core.background_pixel; 3185 cb.default_mapped = mapped; 3186 cb.loop_index = index - 1; 3187 3188 if( md -> md.update_day_callback ){ 3189 /* Let the user determine what should be displayed. */ 3190 3191 XtCallCallbackList( (Widget) md, md -> md.update_day_callback, 3192 (XtPointer) &cb ); 3193 3194 } else { 3195 /* We should display the defaults. */ 3196 cb.foreground = cb.default_foreground; 3197 cb.background = cb.default_background; 3198 cb.frame = cb.default_frame; 3199 cb.mapped = cb.default_mapped; 3200 } 3201 3202 /* Set the values. */ 3203 n = 0; 3204 3205 if( cb.foreground != old_fg ){ 3206 XtSetArg( args[ n ], XmNforeground, cb.foreground ); n++; 3207 } 3208 if( cb.background != old_bg ){ 3209 XtSetArg( args[ n ], XmNbackground, cb.background ); n++; 3210 } 3211 3212 if( ! cb.use_shadows ){ 3213 if( cb.frame != old_top ){ 3214 XtSetArg( args[ n ], XmNtopShadowColor, cb.frame ); n++; 3215 XtSetArg( args[ n ], XmNbottomShadowColor, cb.frame ); n++; 3216 } 3217 3218 } else { 3219 /* Pushbutton shadows on button. */ 3220 3221 if( old_top != md -> md.pushb_default_topshadow ){ 3222 XtSetArg( args[ n ], XmNtopShadowColor, 3223 md -> md.pushb_default_topshadow ); n++; 3224 } 3225 if( old_bottom != md -> md.pushb_default_bottomshadow ){ 3226 XtSetArg( args[ n ], XmNbottomShadowColor, 3227 md -> md.pushb_default_bottomshadow ); n++; 3228 } 3229 } 3230 3231 /* If we are lucky, we don't need to change the text... */ 3232 if( user_data != cb.week_number ){ 3233 sprintf( label_buffer, "%d", cb.week_number ); 3234 xm = XmStringCreateLtoR( label_buffer, XmSTRING_DEFAULT_CHARSET ); 3235 3236 XtSetArg( args[ n ], XmNlabelString, xm ); n++; 3237 XtSetArg( args[ n ], XmNuserData, cb.week_number ); n++; 3238 } 3239 3240 /* Mapped or not? */ 3241 if( old_mapped != cb.mapped ){ 3242 XtSetArg( args[ n ], XmNmappedWhenManaged, cb.mapped ); n++; 3243 } 3244 3245 /* Update the button. */ 3246 if( n > 0 ) 3247 XtSetValues( w, args, n ); 3248 3249 /* Cleanup. */ 3250 if( xm != NULL ) 3251 XmStringFree( xm ); 3252 3253 3254 return; 3255 3256 } /* UpdateWeekButton */ 3257 3258 3259 /*----------------------------------------------------------------------*/ 3260 3261 static void WarningNoResourceChange(XmUbMonthDisplayWidget md,String resource)3262 WarningNoResourceChange( XmUbMonthDisplayWidget md, 3263 String resource ) 3264 { 3265 /* Variables. */ 3266 Cardinal num_params; 3267 String params[ 2 ]; 3268 3269 /* Code. */ 3270 3271 params[ 0 ] = resource; 3272 params[ 1 ] = XtClass( md ) -> core_class.class_name; 3273 num_params = 2; 3274 XtAppWarningMsg( XtWidgetToApplicationContext( (Widget) md ), 3275 "resourceError", "setValues", "WidgetError", 3276 "Resource %s may not be changed in %s widgets.", 3277 params, &num_params ); 3278 3279 return; 3280 3281 } /* WarningNoResourceChange */ 3282 3283 3284 /*----------------------------------------------------------------------*/ 3285 3286 static void WeekNumberButtonActivatedCB(Widget pb,XmUbMonthDisplayWidget md,XmPushButtonCallbackStruct * call_data)3287 WeekNumberButtonActivatedCB( Widget pb, 3288 XmUbMonthDisplayWidget md, 3289 XmPushButtonCallbackStruct *call_data ) 3290 { 3291 /* Variables. */ 3292 XmUbMonthDisplayCallbackStruct cb; 3293 int date_index; 3294 int day_number; 3295 int index; 3296 int month_number; 3297 int year_number; 3298 3299 /* Code. */ 3300 3301 /* Get the index of the week button. */ 3302 for( index = 0; index < NO_WEEK_NUMBER_BUTTONS; index ++ ){ 3303 if( pb == md -> md.week_number_buttons[ index ] ) 3304 break; 3305 } 3306 3307 /* The first day of that week. */ 3308 date_index = ( index - 1 ) * 7; 3309 3310 /* Get the day number for the week start button. */ 3311 ButtonDate( md, md -> md.day_number_buttons[ date_index ], 3312 &year_number, &month_number, &day_number ); 3313 3314 cb.selected_year = year_number; 3315 cb.selected_month = month_number; 3316 cb.selected_day = day_number; 3317 3318 /* End date. */ 3319 date_index += 6; 3320 3321 ButtonDate( md, md -> md.day_number_buttons[ date_index ], 3322 &year_number, &month_number, &day_number ); 3323 3324 cb.end_year = year_number; 3325 cb.end_month = month_number; 3326 cb.end_day = day_number; 3327 3328 /* Invoke the callbacks. */ 3329 3330 cb.reason = XmUbCR_DATE_SELECTED; 3331 cb.event = call_data -> event; 3332 cb.child = pb; 3333 cb.range = True; 3334 3335 XtCallCallbackList( (Widget) md, md -> md.date_selected_callback, 3336 (XtPointer) &cb ); 3337 3338 3339 return; 3340 3341 } /* WeekNumberButtonActivatedCB */ 3342 3343 3344 /*----------------------------------------------------------------------*/ 3345 3346 Widget XmUbCreateMonthDisplay(Widget parent,String name,ArgList arglist,Cardinal argcount)3347 XmUbCreateMonthDisplay( Widget parent, 3348 String name, 3349 ArgList arglist, 3350 Cardinal argcount ) 3351 { 3352 3353 /* Code. */ 3354 3355 return XtCreateWidget( name, xmUbMonthDisplayWidgetClass, 3356 parent, arglist, argcount ); 3357 3358 } /* XmUbCreateMonthDisplay */ 3359 3360 3361 /*----------------------------------------------------------------------*/ 3362 3363 Widget XmUbMonthDisplayGetChild(Widget widget,int child)3364 XmUbMonthDisplayGetChild( Widget widget, 3365 int child ) 3366 { 3367 /* Variables. */ 3368 XmUbMonthDisplayWidget md; 3369 3370 /* Code. */ 3371 3372 md = (XmUbMonthDisplayWidget) widget; 3373 3374 3375 return( md -> md.internal_children[ child ] ); 3376 3377 } /* XmUbMonthDisplayGetChild */ 3378 3379 3380 /*----------------------------------------------------------------------*/ 3381 3382 void XmUbMonthDisplaySetFocusToDay(Widget widget,int day_number)3383 XmUbMonthDisplaySetFocusToDay( Widget widget, 3384 int day_number ) 3385 { 3386 /* Variables. */ 3387 Widget button; 3388 XmUbMonthDisplayWidget md; 3389 3390 /* Code. */ 3391 3392 md = (XmUbMonthDisplayWidget) widget; 3393 3394 /* Find the widget id of the button. */ 3395 button = DateButton( md, day_number ); 3396 3397 if( button != NULL ) 3398 XmProcessTraversal( button, XmTRAVERSE_CURRENT ); 3399 3400 3401 return; 3402 3403 } /* XmUbMonthDisplaySetFocusToDay */ 3404 3405 3406 /*----------------------------------------------------------------------*/ 3407 3408 void XmUbMonthDisplaySetDateBackground(Widget widget,int day_number,Pixel bg)3409 XmUbMonthDisplaySetDateBackground( Widget widget, 3410 int day_number, 3411 Pixel bg ) 3412 { 3413 /* Variables. */ 3414 Arg args[ 2 ]; 3415 Widget button; 3416 XmUbMonthDisplayWidget md; 3417 Cardinal n; 3418 3419 /* Code. */ 3420 3421 md = (XmUbMonthDisplayWidget) widget; 3422 3423 /* Find the widget id of the button. */ 3424 button = DateButton( md, day_number ); 3425 3426 if( button != NULL ){ 3427 n = 0; 3428 XtSetArg( args[ n ], XmNbackground, bg ); n++; 3429 XtSetValues( button, args, n ); 3430 } 3431 3432 3433 return; 3434 3435 } /* XmUbMonthDisplaySetDateBackground */ 3436 3437 3438 /*----------------------------------------------------------------------*/ 3439 3440 void XmUbMonthDisplaySetDateForeground(Widget widget,int day_number,Pixel fg)3441 XmUbMonthDisplaySetDateForeground( Widget widget, 3442 int day_number, 3443 Pixel fg ) 3444 { 3445 /* Variables. */ 3446 Arg args[ 2 ]; 3447 Widget button; 3448 XmUbMonthDisplayWidget md; 3449 Cardinal n; 3450 3451 /* Code. */ 3452 3453 md = (XmUbMonthDisplayWidget) widget; 3454 3455 /* Find the widget id of the button. */ 3456 button = DateButton( md, day_number ); 3457 3458 if( button != NULL ){ 3459 n = 0; 3460 XtSetArg( args[ n ], XmNforeground, fg ); n++; 3461 XtSetValues( button, args, n ); 3462 } 3463 3464 3465 return; 3466 3467 } /* XmUbMonthDisplaySetDateForeground */ 3468 3469 3470 /*----------------------------------------------------------------------*/ 3471 3472 void XmUbMonthDisplaySetDateFrame(Widget widget,int day_number,Pixel color)3473 XmUbMonthDisplaySetDateFrame( Widget widget, 3474 int day_number, 3475 Pixel color ) 3476 { 3477 /* Variables. */ 3478 Arg args[ 2 ]; 3479 Widget button; 3480 XmUbMonthDisplayWidget md; 3481 Cardinal n; 3482 3483 /* Code. */ 3484 3485 md = (XmUbMonthDisplayWidget) widget; 3486 3487 /* Find the widget id of the button. */ 3488 button = DateButton( md, day_number ); 3489 3490 if( button != NULL ){ 3491 n = 0; 3492 XtSetArg( args[ n ], XmNtopShadowColor, color ); n++; 3493 XtSetArg( args[ n ], XmNbottomShadowColor, color ); n++; 3494 XtSetValues( button, args, n ); 3495 } 3496 3497 3498 return; 3499 3500 } /* XmUbMonthDisplaySetDateFrame */ 3501 3502 3503 /*----------------------------------------------------------------------*/ 3504 3505 void XmUbMonthDisplaySetMonth(Widget widget,int year,int month)3506 XmUbMonthDisplaySetMonth( Widget widget, 3507 int year, 3508 int month ) 3509 { 3510 /* Variables. */ 3511 XmUbMonthDisplayWidget md; 3512 3513 /* Code. */ 3514 3515 md = (XmUbMonthDisplayWidget) widget; 3516 3517 if( year != 0 ) 3518 md -> md.current_year = year; 3519 if( month != 0 ) 3520 md -> md.current_month = month; 3521 3522 3523 UpdateNewMonth( md ); 3524 3525 3526 return; 3527 3528 } /* XmUbMonthDisplaySetMonth */ 3529 3530 3531 /*----------------------------------------------------------------------*/ 3532 3533 static void YearScrolledCB(Widget pb,XmUbMonthDisplayWidget md,XmUbArrowLabelCallbackStruct * call_data)3534 YearScrolledCB( Widget pb, 3535 XmUbMonthDisplayWidget md, 3536 XmUbArrowLabelCallbackStruct *call_data ) 3537 { 3538 /* Variables. */ 3539 3540 /* Code. */ 3541 3542 switch( call_data -> reason ){ 3543 3544 case XmUbCR_BACK_ARROW_ACTIVATED: 3545 if( md -> md.current_year > 1970 ) 3546 md -> md.current_year --; 3547 else 3548 md -> md.current_month = 1; 3549 break; 3550 3551 case XmUbCR_FORWARD_ARROW_ACTIVATED: 3552 md -> md.current_year ++; 3553 break; 3554 3555 default: 3556 return; 3557 } 3558 3559 UpdateNewMonth( md ); 3560 CallNewMonthCallbacks( md ); 3561 3562 return; 3563 3564 } /* YearScrolledCB */ 3565