2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /*********************************************************************************
26 ** $XConsortium: MonthPanel.c /main/7 1996/11/21 19:41:55 drk $
28 ** RESTRICTED CONFIDENTIAL INFORMATION:
30 ** The information in this document is subject to special
31 ** restrictions in a confidential disclosure agreement between
32 ** HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
33 ** document outside HP, IBM, Sun, USL, SCO, or Univel without
34 ** Sun's specific written approval. This document and all copies
35 ** and derivative works thereof must be returned or destroyed at
38 ** Copyright 1993 Sun Microsystems, Inc. All rights reserved.
40 *******************************************************************************/
43 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
44 * (c) Copyright 1993, 1994 International Business Machines Corp. *
45 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
46 * (c) Copyright 1993, 1994 Novell, Inc. *
50 * Month Panel widget implementation (class XmMonthPanel)
52 * The XmMonthPanel widget is rigged with the Motif widget binary
53 * compatibility mechanism. All Motif-specific changes for this mechanism
54 * are preceded by a comment including the string "MotifBc"
56 * For a description of the Motif widget binary compatibility mechanism
57 * see the reference manual entry on XmResolvePartOffsets().
60 #include <EUSCompat.h>
62 #include <Xm/ManagerP.h>
63 #include <Xm/PushBG.h>
64 #include <Xm/SeparatoG.h>
65 #include <Xm/LabelG.h>
66 #include "MonthPanelP.h"
70 #define XOS_USE_XT_LOCKING
71 #define X_INCLUDE_TIME_H
72 #include <X11/Xos_r.h>
75 * MotifBc - index value for this class is superclass' value + 1
78 #define XmMonthPanelIndex (XmManagerIndex + 1)
82 * MotifBc - dynamic offset tables
85 static XmOffsetPtr ipot; /* Instance part offset table */
86 static XmOffsetPtr cpot; /* Constraint part offset table */
90 * MotifBc - macros for accessing instance and constraint fields
93 #define Year(w) XmField(w, ipot, XmMonthPanel, year, int)
94 #define Month(w) XmField(w, ipot, XmMonthPanel, month, int)
95 #define Callback(w) XmField(w, ipot, XmMonthPanel, callback, XtCallbackList)
96 #define TitleFormat(w) XmField(w, ipot, XmMonthPanel, title_format, String)
97 #define Header(w) XmField(w, ipot, XmMonthPanel, header, Widget)
98 #define DayLabels(w) XmField(w, ipot, XmMonthPanel, day_labels, Widget *)
99 #define Days(w) XmField(w, ipot, XmMonthPanel, days, Widget *)
100 #endif /* MOTIF_BC */
103 /******** Static Function Declarations ********/
104 static void scale_components(XmMonthPanelWidget);
106 static void ClassPartInitialize(WidgetClass) ;
107 static void Initialize(Widget, Widget, ArgList, Cardinal *) ;
108 static void Redisplay(Widget, XEvent *, Region);
109 static void DoLayout(XmMonthPanelWidget) ;
110 static void Resize(Widget) ;
111 static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal *) ;
112 static XtGeometryResult QueryProc(Widget, XtWidgetGeometry*, XtWidgetGeometry*);
113 static XtGeometryResult GeometryManager( Widget, XtWidgetGeometry *, XtWidgetGeometry *);
114 static void DayCallback(Widget, XtPointer, XtPointer);
115 static void MonthCallback(Widget, XtPointer, XtPointer);
116 static void set_header_string(XmMonthPanelWidget);
117 static Boolean clipped(Widget);
118 /******** End Static Function Declarations ********/
122 * These arrays are implemented in calendarA.c. They are arrays
123 * of the local strings for day names and month names. The day
124 * arrays start from 0, the month array starts from 1; no particular
125 * reason for this difference that I can see.
127 extern char *days3[]; /* eg: "S" */
128 extern char *months[]; /* eg: "January" */
131 * widget instance names for column header labels in panel
133 static char *col_hdr[] = { "sunday", "monday", "tuesday", "wednesday",
134 "thursday", "friday", "saturday" };
137 /************************************************************************
139 * Month Panel Resources *
141 ************************************************************************/
143 static XtResource resources[] =
145 { XmNyear, XmCYear, XmRInt, sizeof(int),
146 XtOffsetOf( struct _XmMonthPanelRec, month_panel.year),
147 XmRImmediate, (XtPointer)NULL },
148 { XmNmonth, XmCMonth, XmRInt, sizeof(int),
149 XtOffsetOf( struct _XmMonthPanelRec, month_panel.month),
150 XmRImmediate, (XtPointer)NULL },
151 { XmNactivateCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
152 XtOffsetOf( struct _XmMonthPanelRec, month_panel.callback),
153 XmRImmediate, (XtPointer)NULL },
154 { XmNtitleFormat, XmCTitleFormat, XmRString, sizeof(char *),
155 XtOffsetOf( struct _XmMonthPanelRec, month_panel.title_format),
156 XtRString, (XtPointer)"%B %Y" },
157 { XmNactiveHeader, XmCActiveHeader, XmRBoolean, sizeof(Boolean),
158 XtOffsetOf( struct _XmMonthPanelRec, month_panel.active_header),
159 XtRImmediate, (XtPointer)False },
160 { XmNactiveDays, XmCActiveDays, XmRBoolean, sizeof(Boolean),
161 XtOffsetOf( struct _XmMonthPanelRec, month_panel.active_days),
162 XtRImmediate, (XtPointer)False },
163 { XmNshowPanelHeader, XmCShowPanelHeader, XmRBoolean, sizeof(Boolean),
164 XtOffsetOf( struct _XmMonthPanelRec, month_panel.show_panel_header),
165 XtRImmediate, (XtPointer)True },
166 { XmNshowColumnHeaders, XmCShowColumnHeaders, XmRBoolean, sizeof(Boolean),
167 XtOffsetOf( struct _XmMonthPanelRec, month_panel.show_column_headers),
168 XtRImmediate, (XtPointer)True },
169 { XmNshowSeparator, XmCShowSeparator, XmRBoolean, sizeof(Boolean),
170 XtOffsetOf( struct _XmMonthPanelRec, month_panel.show_separator),
171 XtRImmediate, (XtPointer)True }
176 /****************************************************************
178 * Full class record constant
180 ****************************************************************/
182 externaldef(xmmonthpanelclassrec) XmMonthPanelClassRec
183 xmMonthPanelClassRec = {
185 /* core_class fields */
186 /* superclass */ (WidgetClass) &xmManagerClassRec,
187 /* class_name */ "XmMonthPanel",
188 /* widget_size */ sizeof(XmMonthPanelRec),
189 /* class_initialize */ NULL,
190 /* class_partinit */ ClassPartInitialize,
191 /* class_inited */ FALSE,
192 /* initialize */ Initialize,
193 /* Init hook */ NULL,
194 /* realize */ XtInheritRealize,
197 /* resources */ resources,
198 /* num_resources */ XtNumber(resources),
199 /* xrm_class */ NULLQUARK,
200 /* compress_motion */ TRUE,
201 /* compress_exposure */ XtExposeCompressMaximal,
202 /* compress_enterleave*/ TRUE,
203 /* visible_interest */ FALSE,
206 /* expose */ Redisplay,
207 /* set_values */ SetValues,
208 /* set values hook */ NULL,
209 /* set values almost */ XtInheritSetValuesAlmost,
210 /* get values hook */ NULL,
211 /* accept_focus */ NULL,
212 /* Version */ XtVersion,
213 /* PRIVATE cb list */ NULL,
214 /* tm_table */ XtInheritTranslations,
215 /* query_geometry */ XtInheritQueryGeometry,
216 /* display_accelerator*/ NULL,
217 /* extension */ NULL,
220 /* composite_class fields */
221 /* geometry_manager */ GeometryManager,
222 /* change_managed */ XtInheritChangeManaged,
223 /* insert_child */ XtInheritInsertChild,
224 /* delete_child */ XtInheritDeleteChild, /* Inherit from superclass */
225 /* Extension */ NULL,
227 /* Constraint class Init */
239 XtInheritTranslations, /* translations */
240 NULL, /* get resources */
241 0, /* num get_resources */
242 NULL, /* get_cont_resources */
243 0, /* num_get_cont_resources */
244 XmInheritParentProcess, /* parent_process */
245 NULL, /* extension */
249 /* Month Panel class - none */
254 externaldef(xmmonthpanelwidgetclass) WidgetClass
255 xmMonthPanelWidgetClass = (WidgetClass)&xmMonthPanelClassRec;
260 /************************************************************************
262 * ClassPartInitialize - Set up the fast subclassing. *
264 ************************************************************************/
266 ClassPartInitialize( WidgetClass wc )
269 _XmFastSubclassInit (wc, XmMONTH_PANEL_BIT);
274 /************************************************************************
278 ************************************************************************/
281 Initialize( Widget rw, Widget nw, ArgList args, Cardinal *num_args )
290 _Xltimeparams localtime_buf;
292 XmMonthPanelWidget request = (XmMonthPanelWidget) rw ;
293 XmMonthPanelWidget new_w = (XmMonthPanelWidget) nw ;
297 new_w->month_panel.display_rows = 6; /* minimum to show all days */
300 * create and cache panel header ( eg. "January") (depends on format resource)
302 * Whether XmLabels or XmPushButton gadgets are used is selectable via
303 * the boolean "activeDays" and "activeHeader" resource. True gets you buttons.
306 if (new_w->month_panel.active_header) {
307 new_w->month_panel.header =
308 XmCreatePushButtonGadget((Widget)new_w, "header", NULL, 0);
309 XtAddCallback(new_w->month_panel.header, XmNactivateCallback,
310 MonthCallback, NULL);
311 new_w->month_panel.separator = (Widget) NULL;
314 new_w->month_panel.header =
315 XmCreateLabelGadget((Widget)new_w, "header", NULL, 0);
316 new_w->month_panel.separator =
317 XmCreateSeparatorGadget((Widget)new_w, "separator", NULL, 0);
318 /* Managing of separator is switchable */
319 if (new_w->month_panel.show_separator) {
320 XtManageChild(new_w->month_panel.separator);
321 /* separator takes another row to display */
322 (new_w->month_panel.display_rows)++;
326 /* set header label */
329 ** Problem in set_header_string. It references month_panel.month
330 ** and month_panel.year, which aren't initialized in when it is called
331 ** in the Initialize function. Set them to today.
334 tm_ret = _XLocaltime(&timer, localtime_buf);
335 new_w->month_panel.month = tm_ret->tm_mon + 1;
336 new_w->month_panel.year = 1900 + tm_ret->tm_year;
338 set_header_string(new_w);
340 /* Managing of header is switchable */
341 if (new_w->month_panel.show_panel_header) {
342 XtManageChild(new_w->month_panel.header);
343 /* header takes another row to display */
344 (new_w->month_panel.display_rows)++;
348 * create and cache id's of, column header day names
350 new_w->month_panel.day_labels =
351 (Widget *) XtMalloc( 7 * sizeof(Widget) );
352 for (i=0; i < 7; i++) {
356 /* I18N:next line: wrap the string & fetch from catalog */
357 str = XmStringCreateLocalized(days3[i]);
358 XtSetArg(wargs[0], XmNlabelString, str);
359 label = XmCreateLabelGadget((Widget) new_w, col_hdr[i], wargs, 1);
360 /* Managing of column headers is switchable */
361 if (new_w->month_panel.show_column_headers)
362 XtManageChild(label);
363 new_w->month_panel.day_labels[i] = label; /* cache in panel inst. */
367 /* column headers take another row to display */
368 if (new_w->month_panel.show_column_headers)
369 (new_w->month_panel.display_rows)++;
372 * create and cache id's of, 31 buttons for days
374 new_w->month_panel.days = (Widget *) XtMalloc( 31 * sizeof(Widget) );
375 for (i=0; i < 31; i++) {
380 sprintf(buf, "%d", i+1);
381 str = XmStringCreateLocalized(buf);
382 XtSetArg(wargs[0], XmNlabelString, str);
383 sprintf(buf, "day%d", i+1);
385 /* choose between buttons or labels for day objects */
386 if (new_w->month_panel.active_days) {
387 btn = XmCreatePushButtonGadget((Widget)new_w, buf, wargs, 1);
388 XtAddCallback(btn, XmNactivateCallback, DayCallback,
392 btn = XmCreateLabelGadget((Widget) new_w, buf, wargs, 1);
394 new_w->month_panel.days[i] = btn;/* cache id in panel instance */
397 XtManageChildren((WidgetList)new_w->month_panel.days, 31);
400 * Set all these components to the appropriate size for the container
401 * Then position them correctly.
403 scale_components(new_w);
409 Redisplay(Widget w, XEvent *ev, Region region)
411 XmMonthPanelWidget panel = (XmMonthPanelWidget) w;
413 XmeRedisplayGadgets( w, ev, region) ;
417 /************************************************************************
419 * DoLayout - Layout the month panel. *
421 ************************************************************************/
423 DoLayout( XmMonthPanelWidget mw )
425 XmMonthPanelPart *mpp = &(mw->month_panel);
426 Dimension w = mw->core.width;
427 Dimension h = mw->core.height;
428 int col_w = (int) w/7;
433 int days_in_month = monthlength(monthdayyear(mpp->month,1,mpp->year));
434 int first = fdom(monthdayyear(mpp->month,1,mpp->year));
438 if (!mw->month_panel.active_days && mw->month_panel.active_header) {
440 row_h = (int) h/(mpp->display_rows + 1);
444 row_h = (int) h/(mpp->display_rows);
448 * Make sure the variable buttons are correctly [un]managed.
449 * (the "variable" buttons are those for 29th, 30th and 31st)
451 for (i=28; i < 31; i++) {
452 Widget this_widget = (mpp->days)[i];
453 if (days_in_month > i) {
454 if (!XtIsManaged(this_widget))
455 XtManageChild(this_widget);
458 if (XtIsManaged(this_widget))
459 XtUnmanageChild(this_widget);
464 * position the panel header
466 XtMoveWidget(mpp->header, 0, 0);
469 * position the separator, if any
471 if (mpp->separator != NULL) {
473 XtMoveWidget(mpp->separator,
474 (Position) w/8, (Position) 2 * row_h);
476 XtMoveWidget(mpp->separator,
477 (Position) w/8, (Position) row_h);
481 * position the day labels
484 y = (Position) (mw->month_panel.display_rows -
485 (tall_header ? 6 : 7)) * row_h;
489 this_widget = mw->month_panel.day_labels[i];
490 XtMoveWidget(this_widget, x, y);
496 * position the day buttons
498 x = (Position) first * col_w;
499 y = (Position) (mw->month_panel.display_rows -
500 (tall_header ? 5 : 6)) * row_h;
504 this_widget = mw->month_panel.days[i];
506 /* don't bother with unmanaged buttons */
507 if (XtIsManaged(this_widget))
508 XtMoveWidget(this_widget, x, y);
511 /* take new row after each 7 buttons */
512 if ( ( (i+first) % 7 ) == 0 ) {
523 /************************************************************************
525 * scale_components - Make all the labels, buttons correct size for this
528 * [4/12/94] - Check whether new size causes labels
529 * to be clipped. If it does, set labelType
530 * to PIXMAP. A suitable labelPixmap should be
531 * set to indicate "label too small".
532 ************************************************************************/
535 scale_components(XmMonthPanelWidget mw) {
537 XmMonthPanelPart *mpp = &(mw->month_panel);
538 Dimension w=mw->core.width;
539 Dimension h=mw->core.height;
542 int col_w = (int) w/7;
547 Pixmap head_pm, col_head_pm, btn_pm;
549 if (!mw->month_panel.active_days && mw->month_panel.active_header) {
551 row_h = (int) h/(mpp->display_rows + 1);
555 row_h = (int) h/(mpp->display_rows);
558 /******************************************************************
559 * get pixmap in colors needed - used to replace text when clipped.
561 * NOTE1: Don't need to release the pixmaps, because they come from
562 * the Motif-owned image cache.
564 * NOTE2: setting the pixmaps should be in redisplay rather than
565 * here - only done here because this is where labelType is toggled.
566 ******************************************************************/
567 XtVaGetValues(XtParent(mw), XmNforeground, &fg, XmNbackground, &bg, NULL);
568 head_pm = XmGetPixmap(XtScreen(mw), "slant_right", fg, bg);
569 col_head_pm = XmGetPixmap(XtScreen(mw), "slant_left", fg, bg);
570 btn_pm = XmGetPixmap(XtScreen(mw), "50_foreground", fg, bg);
573 /*********************************************************************
574 * This algorithm allocates equal header, label and button heights;
575 * equal label and button widths; header spans container width.
576 *********************************************************************/
578 /**************************
579 * set panel header size
580 **************************/
583 XtResizeWidget(mpp->header, w, 2 * row_h, mpp->header->core.border_width);
585 XtResizeWidget(mpp->header, w, row_h, mpp->header->core.border_width);
587 if (clipped(mpp->header)) {
588 XtVaSetValues(mpp->header,
589 XmNlabelType, XmPIXMAP,
590 XmNlabelPixmap, head_pm,
594 XtVaSetValues(mpp->header,
595 XmNlabelType, XmSTRING,
598 /**************************
600 **************************/
601 if (mpp->separator != NULL) {
602 XtResizeWidget(mpp->separator, 3*(int)w/4, row_h, 0);
605 /**************************
606 * set column-heading label sizes
607 **************************/
608 for (i=0; i<7; i++) {
609 this_widget = (mpp->day_labels)[i];
610 XtResizeWidget(this_widget, col_w, row_h, 0);
612 /* display pixmap if clipped, string otherwise */
613 this_widget = (mpp->day_labels)[6];
614 XtVaGetValues(this_widget, XmNlabelType, <ype, NULL);
615 if (clipped(this_widget)) {
616 if (ltype == XmSTRING) {
617 for (i=0; i<7; i++) {
618 XtVaSetValues((mpp->day_labels)[i],
619 XmNlabelType, XmPIXMAP,
620 XmNlabelPixmap, col_head_pm,
626 if (ltype == XmPIXMAP) {
627 for (i=0; i<7; i++) {
628 XtVaSetValues((mpp->day_labels)[i], XmNlabelType, XmSTRING, NULL);
633 /**************************
635 **************************/
636 for (i=0; i<31; i++) {
637 this_widget = (mpp->days)[i];
638 XtResizeWidget(this_widget, col_w, row_h, 0);
641 /*************************************************************
642 * If any of the button labels are clipped, replace the
643 * entire set with their pixmap equivalents. The labelPixmap
644 * resource should be set to something that means "not big enough"
646 * This check should really be done in above loop, but it
647 * slows things down to catch the edge case (different fonts
648 * in different labels, so this is thought "good enough".
649 * 28th button picked at random for test - at least it's always a
651 *************************************************************/
652 this_widget = (mpp->days)[27];
653 XtVaGetValues(this_widget, XmNlabelType, <ype, NULL);
654 if (clipped(this_widget)) {
655 if (ltype == XmSTRING) {
656 for (i=0; i<31; i++) {
657 XtVaSetValues((mpp->days)[i],
658 XmNlabelType, XmPIXMAP,
659 XmNlabelPixmap, btn_pm,
665 if (ltype == XmPIXMAP) {
666 for (i=0; i<31; i++) {
667 XtVaSetValues((mpp->days)[i], XmNlabelType, XmSTRING, NULL);
674 * Determine whether labelString requires more space
675 * than its widget currently has. This information
676 * can be used to display clipped information differently
683 Dimension req_w, req_h, act_w, act_h, shd_w, hlt_w;
688 XmNlabelString, &str,
690 XmNhighlightThickness, &hlt_w,
691 XmNshadowThickness, &shd_w,
696 XmStringExtent(fl, str, &req_w, &req_h);
698 /* adjust actual width/height available for shadow and highlight */
699 act_w -= ( (2*hlt_w) + (2*shd_w) );
700 act_h -= ( (2*hlt_w) + (2*shd_w) );
702 if ((req_w > act_w) || (req_h > act_h))
708 /************************************************************************
710 * Recompute the size of the month panel. *
712 ************************************************************************/
716 XmMonthPanelWidget mw = (XmMonthPanelWidget) wid ;
717 XmManagerWidgetClass super = (XmManagerWidgetClass) xmManagerWidgetClass;
719 scale_components(mw);
721 (*super->core_class.resize)((Widget) mw);
724 /***************************************************************************
728 ***************************************************************************/
729 static XtGeometryResult
730 GeometryManager( Widget w, XtWidgetGeometry *request, XtWidgetGeometry *reply )
732 return (XtGeometryYes);
735 /***************************************************************************
737 * QueryProc (stub for now) *
739 ***************************************************************************/
740 static XtGeometryResult
741 QueryProc( Widget w, XtWidgetGeometry *request, XtWidgetGeometry *reply )
743 /* XmMonthPanelWidget mw = (XmMonthPanelWidget) w;*/
744 return(XtGeometryYes);
749 /***************************************************************************
751 * CalcSize (stub for now- to be called by QueryProc) *
753 ***************************************************************************/
755 CalcSize(XmMonthPanelWidget mw, Dimension *replyWidth , Dimension *replyHeight)
757 *replyWidth = mw->core.width;
758 *replyHeight = mw->core.height;
763 /************************************************************************
767 ************************************************************************/
769 SetValues( Widget cw, Widget rw, Widget nw, ArgList args, Cardinal *num_args )
771 XmMonthPanelWidget current = (XmMonthPanelWidget) cw ;
772 XmMonthPanelWidget request = (XmMonthPanelWidget) rw ;
773 XmMonthPanelWidget new_w = (XmMonthPanelWidget) nw ;
774 Boolean relayout = FALSE;
775 Boolean new_date = FALSE;
777 if (request->month_panel.show_panel_header != current->month_panel.show_panel_header) {
778 if (request->month_panel.show_panel_header) {
779 XtManageChild(request->month_panel.header);
780 (request->month_panel.display_rows)++;
783 XtUnmanageChild(request->month_panel.header);
784 (request->month_panel.display_rows)--;
789 if (request->month_panel.show_column_headers != current->month_panel.show_column_headers) {
790 if (request->month_panel.show_column_headers) {
793 XtManageChild(request->month_panel.day_labels[col]);
796 (request->month_panel.display_rows)++;
801 XtUnmanageChild(request->month_panel.day_labels[col]);
804 (request->month_panel.display_rows)--;
809 if (request->month_panel.show_separator != current->month_panel.show_separator) {
810 if (request->month_panel.show_separator) {
811 XtManageChild(request->month_panel.separator);
812 (request->month_panel.display_rows)++;
815 XtUnmanageChild(request->month_panel.separator);
816 (request->month_panel.display_rows)--;
821 if (request->month_panel.month != current->month_panel.month) {
823 /* range check - quietly force to nearest valid value */
824 if (request->month_panel.month < 1)
825 new_w->month_panel.month = 1;
826 else if (request->month_panel.month > 12)
827 new_w->month_panel.month = 12;
832 if (request->month_panel.year != current->month_panel.year) {
834 /* range check - quietly force to nearest valid value */
835 if (request->month_panel.year < 1)
836 new_w->month_panel.year = 1970;
837 else if (request->month_panel.year > 2037)
838 new_w->month_panel.year = 2037;
843 if ((request->core.width != current->core.width) ||
844 (request->core.height != current->core.height)) {
848 if (strcmp(request->month_panel.title_format,
849 new_w->month_panel.title_format) != 0) {
850 set_header_string(new_w);
854 set_header_string(new_w);
867 * Sets label in month button of panel, according to the
868 * setting of the titleFormat resource, which is assumed to
869 * be a valid format string for stftime(3)
872 set_header_string(XmMonthPanelWidget mw)
879 _Xltimeparams localtime_buf;
882 monthdayyear(mw->month_panel.month, 1 ,mw->month_panel.year);
883 tm_ret = _XLocaltime(&tmptick, localtime_buf);
884 (void) strftime(buf, BUFSIZ, mw->month_panel.title_format, tm_ret);
886 str = XmStringCreateLocalized(buf);
887 XtSetArg(wargs[0], XmNlabelString, str);
888 XtSetValues(mw->month_panel.header, wargs, 1);
893 /************************************************************************
894 * DayCallback is invoked from day button children.
895 * It invokes MonthPanel's own callbac list, setting the type in the
896 * callback struct to DAY_SELECTION, and the day field to the index of the
897 * button that was pressed.
899 ************************************************************************/
900 static void DayCallback(Widget w, XtPointer client, XtPointer call)
902 XmMonthPanelWidget mp = (XmMonthPanelWidget) XtParent(w);
903 XmMonthPanelCallbackStruct data;
905 data.type = DAY_SELECTION;
906 data.day = (int) client;
908 XtCallCallbackList((Widget) mp, mp->month_panel.callback, &data);
911 /************************************************************************
912 * MonthCallback is invoked from the header button.
913 * It invokes MonthPanel's own callback list, setting the type in the
914 * callback struct to MONTH_SELECTION, and zeroing out the day field.
915 ************************************************************************/
916 static void MonthCallback(Widget w, XtPointer client, XtPointer call)
918 XmMonthPanelWidget mp = (XmMonthPanelWidget) XtParent(w);
919 XmMonthPanelCallbackStruct data;
921 data.type = MONTH_SELECTION;
924 XtCallCallbackList((Widget) mp, mp->month_panel.callback, &data);
927 /************************************************************************
929 * XmCreateMonthPanel - convenience interface to XtCreateWidget. *
931 ************************************************************************/
933 XmCreateMonthPanel( Widget parent, char *name, ArgList args, Cardinal argCount )
936 return ( XtCreateWidget( name,
937 xmMonthPanelWidgetClass,