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
75 #include <X11/Xos_r.h>
78 * MotifBc - index value for this class is superclass' value + 1
81 #define XmMonthPanelIndex (XmManagerIndex + 1)
85 * MotifBc - dynamic offset tables
88 static XmOffsetPtr ipot; /* Instance part offset table */
89 static XmOffsetPtr cpot; /* Constraint part offset table */
93 * MotifBc - macros for accessing instance and constraint fields
96 #define Year(w) XmField(w, ipot, XmMonthPanel, year, int)
97 #define Month(w) XmField(w, ipot, XmMonthPanel, month, int)
98 #define Callback(w) XmField(w, ipot, XmMonthPanel, callback, XtCallbackList)
99 #define TitleFormat(w) XmField(w, ipot, XmMonthPanel, title_format, String)
100 #define Header(w) XmField(w, ipot, XmMonthPanel, header, Widget)
101 #define DayLabels(w) XmField(w, ipot, XmMonthPanel, day_labels, Widget *)
102 #define Days(w) XmField(w, ipot, XmMonthPanel, days, Widget *)
103 #endif /* MOTIF_BC */
106 /******** Static Function Declarations ********/
107 static void scale_components(XmMonthPanelWidget);
109 static void ClassPartInitialize(WidgetClass) ;
110 static void Initialize(Widget, Widget, ArgList, Cardinal *) ;
111 static void Redisplay(Widget, XEvent *, Region);
112 static void DoLayout(XmMonthPanelWidget) ;
113 static void Resize(Widget) ;
114 static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal *) ;
115 static XtGeometryResult QueryProc(Widget, XtWidgetGeometry*, XtWidgetGeometry*);
116 static XtGeometryResult GeometryManager( Widget, XtWidgetGeometry *, XtWidgetGeometry *);
117 static void DayCallback(Widget, XtPointer, XtPointer);
118 static void MonthCallback(Widget, XtPointer, XtPointer);
119 static void set_header_string(XmMonthPanelWidget);
120 static Boolean clipped(Widget);
121 /******** End Static Function Declarations ********/
125 * These arrays are implemented in calendarA.c. They are arrays
126 * of the local strings for day names and month names. The day
127 * arrays start from 0, the month array starts from 1; no particular
128 * reason for this difference that I can see.
130 extern char *days3[]; /* eg: "S" */
131 extern char *months[]; /* eg: "January" */
134 * widget instance names for column header labels in panel
136 static char *col_hdr[] = { "sunday", "monday", "tuesday", "wednesday",
137 "thursday", "friday", "saturday" };
140 /************************************************************************
142 * Month Panel Resources *
144 ************************************************************************/
146 static XtResource resources[] =
148 { XmNyear, XmCYear, XmRInt, sizeof(int),
149 XtOffsetOf( struct _XmMonthPanelRec, month_panel.year),
150 XmRImmediate, (XtPointer)NULL },
151 { XmNmonth, XmCMonth, XmRInt, sizeof(int),
152 XtOffsetOf( struct _XmMonthPanelRec, month_panel.month),
153 XmRImmediate, (XtPointer)NULL },
154 { XmNactivateCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
155 XtOffsetOf( struct _XmMonthPanelRec, month_panel.callback),
156 XmRImmediate, (XtPointer)NULL },
157 { XmNtitleFormat, XmCTitleFormat, XmRString, sizeof(char *),
158 XtOffsetOf( struct _XmMonthPanelRec, month_panel.title_format),
159 XtRString, (XtPointer)"%B %Y" },
160 { XmNactiveHeader, XmCActiveHeader, XmRBoolean, sizeof(Boolean),
161 XtOffsetOf( struct _XmMonthPanelRec, month_panel.active_header),
162 XtRImmediate, (XtPointer)False },
163 { XmNactiveDays, XmCActiveDays, XmRBoolean, sizeof(Boolean),
164 XtOffsetOf( struct _XmMonthPanelRec, month_panel.active_days),
165 XtRImmediate, (XtPointer)False },
166 { XmNshowPanelHeader, XmCShowPanelHeader, XmRBoolean, sizeof(Boolean),
167 XtOffsetOf( struct _XmMonthPanelRec, month_panel.show_panel_header),
168 XtRImmediate, (XtPointer)True },
169 { XmNshowColumnHeaders, XmCShowColumnHeaders, XmRBoolean, sizeof(Boolean),
170 XtOffsetOf( struct _XmMonthPanelRec, month_panel.show_column_headers),
171 XtRImmediate, (XtPointer)True },
172 { XmNshowSeparator, XmCShowSeparator, XmRBoolean, sizeof(Boolean),
173 XtOffsetOf( struct _XmMonthPanelRec, month_panel.show_separator),
174 XtRImmediate, (XtPointer)True }
179 /****************************************************************
181 * Full class record constant
183 ****************************************************************/
185 externaldef(xmmonthpanelclassrec) XmMonthPanelClassRec
186 xmMonthPanelClassRec = {
188 /* core_class fields */
189 /* superclass */ (WidgetClass) &xmManagerClassRec,
190 /* class_name */ "XmMonthPanel",
191 /* widget_size */ sizeof(XmMonthPanelRec),
192 /* class_initialize */ NULL,
193 /* class_partinit */ ClassPartInitialize,
194 /* class_inited */ FALSE,
195 /* initialize */ Initialize,
196 /* Init hook */ NULL,
197 /* realize */ XtInheritRealize,
200 /* resources */ resources,
201 /* num_resources */ XtNumber(resources),
202 /* xrm_class */ NULLQUARK,
203 /* compress_motion */ TRUE,
204 /* compress_exposure */ XtExposeCompressMaximal,
205 /* compress_enterleave*/ TRUE,
206 /* visible_interest */ FALSE,
209 /* expose */ Redisplay,
210 /* set_values */ SetValues,
211 /* set values hook */ NULL,
212 /* set values almost */ XtInheritSetValuesAlmost,
213 /* get values hook */ NULL,
214 /* accept_focus */ NULL,
215 /* Version */ XtVersion,
216 /* PRIVATE cb list */ NULL,
217 /* tm_table */ XtInheritTranslations,
218 /* query_geometry */ XtInheritQueryGeometry,
219 /* display_accelerator*/ NULL,
220 /* extension */ NULL,
223 /* composite_class fields */
224 /* geometry_manager */ GeometryManager,
225 /* change_managed */ XtInheritChangeManaged,
226 /* insert_child */ XtInheritInsertChild,
227 /* delete_child */ XtInheritDeleteChild, /* Inherit from superclass */
228 /* Extension */ NULL,
230 /* Constraint class Init */
242 XtInheritTranslations, /* translations */
243 NULL, /* get resources */
244 0, /* num get_resources */
245 NULL, /* get_cont_resources */
246 0, /* num_get_cont_resources */
247 XmInheritParentProcess, /* parent_process */
248 NULL, /* extension */
252 /* Month Panel class - none */
257 externaldef(xmmonthpanelwidgetclass) WidgetClass
258 xmMonthPanelWidgetClass = (WidgetClass)&xmMonthPanelClassRec;
263 /************************************************************************
265 * ClassPartInitialize - Set up the fast subclassing. *
267 ************************************************************************/
269 ClassPartInitialize( WidgetClass wc )
272 _XmFastSubclassInit (wc, XmMONTH_PANEL_BIT);
277 /************************************************************************
281 ************************************************************************/
284 Initialize( Widget rw, Widget nw, ArgList args, Cardinal *num_args )
293 _Xltimeparams localtime_buf;
295 XmMonthPanelWidget request = (XmMonthPanelWidget) rw ;
296 XmMonthPanelWidget new_w = (XmMonthPanelWidget) nw ;
300 new_w->month_panel.display_rows = 6; /* minimum to show all days */
303 * create and cache panel header ( eg. "January") (depends on format resource)
305 * Whether XmLabels or XmPushButton gadgets are used is selectable via
306 * the boolean "activeDays" and "activeHeader" resource. True gets you buttons.
309 if (new_w->month_panel.active_header) {
310 new_w->month_panel.header =
311 XmCreatePushButtonGadget((Widget)new_w, "header", NULL, 0);
312 XtAddCallback(new_w->month_panel.header, XmNactivateCallback,
313 MonthCallback, NULL);
314 new_w->month_panel.separator = (Widget) NULL;
317 new_w->month_panel.header =
318 XmCreateLabelGadget((Widget)new_w, "header", NULL, 0);
319 new_w->month_panel.separator =
320 XmCreateSeparatorGadget((Widget)new_w, "separator", NULL, 0);
321 /* Managing of separator is switchable */
322 if (new_w->month_panel.show_separator) {
323 XtManageChild(new_w->month_panel.separator);
324 /* separator takes another row to display */
325 (new_w->month_panel.display_rows)++;
329 /* set header label */
332 ** Problem in set_header_string. It references month_panel.month
333 ** and month_panel.year, which aren't initialized in when it is called
334 ** in the Initialize function. Set them to today.
337 tm_ret = _XLocaltime(&timer, localtime_buf);
338 new_w->month_panel.month = tm_ret->tm_mon + 1;
339 new_w->month_panel.year = 1900 + tm_ret->tm_year;
341 set_header_string(new_w);
343 /* Managing of header is switchable */
344 if (new_w->month_panel.show_panel_header) {
345 XtManageChild(new_w->month_panel.header);
346 /* header takes another row to display */
347 (new_w->month_panel.display_rows)++;
351 * create and cache id's of, column header day names
353 new_w->month_panel.day_labels =
354 (Widget *) XtMalloc( 7 * sizeof(Widget) );
355 for (i=0; i < 7; i++) {
359 /* I18N:next line: wrap the string & fetch from catalog */
360 str = XmStringCreateLocalized(days3[i]);
361 XtSetArg(wargs[0], XmNlabelString, str);
362 label = XmCreateLabelGadget((Widget) new_w, col_hdr[i], wargs, 1);
363 /* Managing of column headers is switchable */
364 if (new_w->month_panel.show_column_headers)
365 XtManageChild(label);
366 new_w->month_panel.day_labels[i] = label; /* cache in panel inst. */
370 /* column headers take another row to display */
371 if (new_w->month_panel.show_column_headers)
372 (new_w->month_panel.display_rows)++;
375 * create and cache id's of, 31 buttons for days
377 new_w->month_panel.days = (Widget *) XtMalloc( 31 * sizeof(Widget) );
378 for (i=0; i < 31; i++) {
383 sprintf(buf, "%d", i+1);
384 str = XmStringCreateLocalized(buf);
385 XtSetArg(wargs[0], XmNlabelString, str);
386 sprintf(buf, "day%d", i+1);
388 /* choose between buttons or labels for day objects */
389 if (new_w->month_panel.active_days) {
390 btn = XmCreatePushButtonGadget((Widget)new_w, buf, wargs, 1);
391 XtAddCallback(btn, XmNactivateCallback, DayCallback,
395 btn = XmCreateLabelGadget((Widget) new_w, buf, wargs, 1);
397 new_w->month_panel.days[i] = btn;/* cache id in panel instance */
400 XtManageChildren((WidgetList)new_w->month_panel.days, 31);
403 * Set all these components to the appropriate size for the container
404 * Then position them correctly.
406 scale_components(new_w);
412 Redisplay(Widget w, XEvent *ev, Region region)
414 XmMonthPanelWidget panel = (XmMonthPanelWidget) w;
416 XmeRedisplayGadgets( w, ev, region) ;
420 /************************************************************************
422 * DoLayout - Layout the month panel. *
424 ************************************************************************/
426 DoLayout( XmMonthPanelWidget mw )
428 XmMonthPanelPart *mpp = &(mw->month_panel);
429 Dimension w = mw->core.width;
430 Dimension h = mw->core.height;
431 int col_w = (int) w/7;
436 int days_in_month = monthlength(monthdayyear(mpp->month,1,mpp->year));
437 int first = fdom(monthdayyear(mpp->month,1,mpp->year));
441 if (!mw->month_panel.active_days && mw->month_panel.active_header) {
443 row_h = (int) h/(mpp->display_rows + 1);
447 row_h = (int) h/(mpp->display_rows);
451 * Make sure the variable buttons are correctly [un]managed.
452 * (the "variable" buttons are those for 29th, 30th and 31st)
454 for (i=28; i < 31; i++) {
455 Widget this_widget = (mpp->days)[i];
456 if (days_in_month > i) {
457 if (!XtIsManaged(this_widget))
458 XtManageChild(this_widget);
461 if (XtIsManaged(this_widget))
462 XtUnmanageChild(this_widget);
467 * position the panel header
469 XtMoveWidget(mpp->header, 0, 0);
472 * position the separator, if any
474 if (mpp->separator != NULL) {
476 XtMoveWidget(mpp->separator,
477 (Position) w/8, (Position) 2 * row_h);
479 XtMoveWidget(mpp->separator,
480 (Position) w/8, (Position) row_h);
484 * position the day labels
487 y = (Position) (mw->month_panel.display_rows -
488 (tall_header ? 6 : 7)) * row_h;
492 this_widget = mw->month_panel.day_labels[i];
493 XtMoveWidget(this_widget, x, y);
499 * position the day buttons
501 x = (Position) first * col_w;
502 y = (Position) (mw->month_panel.display_rows -
503 (tall_header ? 5 : 6)) * row_h;
507 this_widget = mw->month_panel.days[i];
509 /* don't bother with unmanaged buttons */
510 if (XtIsManaged(this_widget))
511 XtMoveWidget(this_widget, x, y);
514 /* take new row after each 7 buttons */
515 if ( ( (i+first) % 7 ) == 0 ) {
526 /************************************************************************
528 * scale_components - Make all the labels, buttons correct size for this
531 * [4/12/94] - Check whether new size causes labels
532 * to be clipped. If it does, set labelType
533 * to PIXMAP. A suitable labelPixmap should be
534 * set to indicate "label too small".
535 ************************************************************************/
538 scale_components(XmMonthPanelWidget mw) {
540 XmMonthPanelPart *mpp = &(mw->month_panel);
541 Dimension w=mw->core.width;
542 Dimension h=mw->core.height;
545 int col_w = (int) w/7;
550 Pixmap head_pm, col_head_pm, btn_pm;
552 if (!mw->month_panel.active_days && mw->month_panel.active_header) {
554 row_h = (int) h/(mpp->display_rows + 1);
558 row_h = (int) h/(mpp->display_rows);
561 /******************************************************************
562 * get pixmap in colors needed - used to replace text when clipped.
564 * NOTE1: Don't need to release the pixmaps, because they come from
565 * the Motif-owned image cache.
567 * NOTE2: setting the pixmaps should be in redisplay rather than
568 * here - only done here because this is where labelType is toggled.
569 ******************************************************************/
570 XtVaGetValues(XtParent(mw), XmNforeground, &fg, XmNbackground, &bg, NULL);
571 head_pm = XmGetPixmap(XtScreen(mw), "slant_right", fg, bg);
572 col_head_pm = XmGetPixmap(XtScreen(mw), "slant_left", fg, bg);
573 btn_pm = XmGetPixmap(XtScreen(mw), "50_foreground", fg, bg);
576 /*********************************************************************
577 * This algorithm allocates equal header, label and button heights;
578 * equal label and button widths; header spans container width.
579 *********************************************************************/
581 /**************************
582 * set panel header size
583 **************************/
586 XtResizeWidget(mpp->header, w, 2 * row_h, mpp->header->core.border_width);
588 XtResizeWidget(mpp->header, w, row_h, mpp->header->core.border_width);
590 if (clipped(mpp->header)) {
591 XtVaSetValues(mpp->header,
592 XmNlabelType, XmPIXMAP,
593 XmNlabelPixmap, head_pm,
597 XtVaSetValues(mpp->header,
598 XmNlabelType, XmSTRING,
601 /**************************
603 **************************/
604 if (mpp->separator != NULL) {
605 XtResizeWidget(mpp->separator, 3*(int)w/4, row_h, 0);
608 /**************************
609 * set column-heading label sizes
610 **************************/
611 for (i=0; i<7; i++) {
612 this_widget = (mpp->day_labels)[i];
613 XtResizeWidget(this_widget, col_w, row_h, 0);
615 /* display pixmap if clipped, string otherwise */
616 this_widget = (mpp->day_labels)[6];
617 XtVaGetValues(this_widget, XmNlabelType, <ype, NULL);
618 if (clipped(this_widget)) {
619 if (ltype == XmSTRING) {
620 for (i=0; i<7; i++) {
621 XtVaSetValues((mpp->day_labels)[i],
622 XmNlabelType, XmPIXMAP,
623 XmNlabelPixmap, col_head_pm,
629 if (ltype == XmPIXMAP) {
630 for (i=0; i<7; i++) {
631 XtVaSetValues((mpp->day_labels)[i], XmNlabelType, XmSTRING, NULL);
636 /**************************
638 **************************/
639 for (i=0; i<31; i++) {
640 this_widget = (mpp->days)[i];
641 XtResizeWidget(this_widget, col_w, row_h, 0);
644 /*************************************************************
645 * If any of the button labels are clipped, replace the
646 * entire set with their pixmap equivalents. The labelPixmap
647 * resource should be set to something that means "not big enough"
649 * This check should really be done in above loop, but it
650 * slows things down to catch the edge case (different fonts
651 * in different labels, so this is thought "good enough".
652 * 28th button picked at random for test - at least it's always a
654 *************************************************************/
655 this_widget = (mpp->days)[27];
656 XtVaGetValues(this_widget, XmNlabelType, <ype, NULL);
657 if (clipped(this_widget)) {
658 if (ltype == XmSTRING) {
659 for (i=0; i<31; i++) {
660 XtVaSetValues((mpp->days)[i],
661 XmNlabelType, XmPIXMAP,
662 XmNlabelPixmap, btn_pm,
668 if (ltype == XmPIXMAP) {
669 for (i=0; i<31; i++) {
670 XtVaSetValues((mpp->days)[i], XmNlabelType, XmSTRING, NULL);
677 * Determine whether labelString requires more space
678 * than its widget currently has. This information
679 * can be used to display clipped information differently
686 Dimension req_w, req_h, act_w, act_h, shd_w, hlt_w;
691 XmNlabelString, &str,
693 XmNhighlightThickness, &hlt_w,
694 XmNshadowThickness, &shd_w,
699 XmStringExtent(fl, str, &req_w, &req_h);
701 /* adjust actual width/height available for shadow and highlight */
702 act_w -= ( (2*hlt_w) + (2*shd_w) );
703 act_h -= ( (2*hlt_w) + (2*shd_w) );
705 if ((req_w > act_w) || (req_h > act_h))
711 /************************************************************************
713 * Recompute the size of the month panel. *
715 ************************************************************************/
719 XmMonthPanelWidget mw = (XmMonthPanelWidget) wid ;
720 XmManagerWidgetClass super = (XmManagerWidgetClass) xmManagerWidgetClass;
722 scale_components(mw);
724 (*super->core_class.resize)((Widget) mw);
727 /***************************************************************************
731 ***************************************************************************/
732 static XtGeometryResult
733 GeometryManager( Widget w, XtWidgetGeometry *request, XtWidgetGeometry *reply )
735 return (XtGeometryYes);
738 /***************************************************************************
740 * QueryProc (stub for now) *
742 ***************************************************************************/
743 static XtGeometryResult
744 QueryProc( Widget w, XtWidgetGeometry *request, XtWidgetGeometry *reply )
746 /* XmMonthPanelWidget mw = (XmMonthPanelWidget) w;*/
747 return(XtGeometryYes);
752 /***************************************************************************
754 * CalcSize (stub for now- to be called by QueryProc) *
756 ***************************************************************************/
758 CalcSize(XmMonthPanelWidget mw, Dimension *replyWidth , Dimension *replyHeight)
760 *replyWidth = mw->core.width;
761 *replyHeight = mw->core.height;
766 /************************************************************************
770 ************************************************************************/
772 SetValues( Widget cw, Widget rw, Widget nw, ArgList args, Cardinal *num_args )
774 XmMonthPanelWidget current = (XmMonthPanelWidget) cw ;
775 XmMonthPanelWidget request = (XmMonthPanelWidget) rw ;
776 XmMonthPanelWidget new_w = (XmMonthPanelWidget) nw ;
777 Boolean relayout = FALSE;
778 Boolean new_date = FALSE;
780 if (request->month_panel.show_panel_header != current->month_panel.show_panel_header) {
781 if (request->month_panel.show_panel_header) {
782 XtManageChild(request->month_panel.header);
783 (request->month_panel.display_rows)++;
786 XtUnmanageChild(request->month_panel.header);
787 (request->month_panel.display_rows)--;
792 if (request->month_panel.show_column_headers != current->month_panel.show_column_headers) {
793 if (request->month_panel.show_column_headers) {
796 XtManageChild(request->month_panel.day_labels[col]);
799 (request->month_panel.display_rows)++;
804 XtUnmanageChild(request->month_panel.day_labels[col]);
807 (request->month_panel.display_rows)--;
812 if (request->month_panel.show_separator != current->month_panel.show_separator) {
813 if (request->month_panel.show_separator) {
814 XtManageChild(request->month_panel.separator);
815 (request->month_panel.display_rows)++;
818 XtUnmanageChild(request->month_panel.separator);
819 (request->month_panel.display_rows)--;
824 if (request->month_panel.month != current->month_panel.month) {
826 /* range check - quietly force to nearest valid value */
827 if (request->month_panel.month < 1)
828 new_w->month_panel.month = 1;
829 else if (request->month_panel.month > 12)
830 new_w->month_panel.month = 12;
835 if (request->month_panel.year != current->month_panel.year) {
837 /* range check - quietly force to nearest valid value */
838 if (request->month_panel.year < 1)
839 new_w->month_panel.year = 1970;
840 else if (request->month_panel.year > 2037)
841 new_w->month_panel.year = 2037;
846 if ((request->core.width != current->core.width) ||
847 (request->core.height != current->core.height)) {
851 if (strcmp(request->month_panel.title_format,
852 new_w->month_panel.title_format) != 0) {
853 set_header_string(new_w);
857 set_header_string(new_w);
870 * Sets label in month button of panel, according to the
871 * setting of the titleFormat resource, which is assumed to
872 * be a valid format string for stftime(3)
875 set_header_string(XmMonthPanelWidget mw)
882 _Xltimeparams localtime_buf;
885 monthdayyear(mw->month_panel.month, 1 ,mw->month_panel.year);
886 tm_ret = _XLocaltime(&tmptick, localtime_buf);
887 (void) strftime(buf, BUFSIZ, mw->month_panel.title_format, tm_ret);
889 str = XmStringCreateLocalized(buf);
890 XtSetArg(wargs[0], XmNlabelString, str);
891 XtSetValues(mw->month_panel.header, wargs, 1);
896 /************************************************************************
897 * DayCallback is invoked from day button children.
898 * It invokes MonthPanel's own callbac list, setting the type in the
899 * callback struct to DAY_SELECTION, and the day field to the index of the
900 * button that was pressed.
902 ************************************************************************/
903 static void DayCallback(Widget w, XtPointer client, XtPointer call)
905 XmMonthPanelWidget mp = (XmMonthPanelWidget) XtParent(w);
906 XmMonthPanelCallbackStruct data;
908 data.type = DAY_SELECTION;
909 data.day = (int) client;
911 XtCallCallbackList((Widget) mp, mp->month_panel.callback, &data);
914 /************************************************************************
915 * MonthCallback is invoked from the header button.
916 * It invokes MonthPanel's own callback list, setting the type in the
917 * callback struct to MONTH_SELECTION, and zeroing out the day field.
918 ************************************************************************/
919 static void MonthCallback(Widget w, XtPointer client, XtPointer call)
921 XmMonthPanelWidget mp = (XmMonthPanelWidget) XtParent(w);
922 XmMonthPanelCallbackStruct data;
924 data.type = MONTH_SELECTION;
927 XtCallCallbackList((Widget) mp, mp->month_panel.callback, &data);
930 /************************************************************************
932 * XmCreateMonthPanel - convenience interface to XtCreateWidget. *
934 ************************************************************************/
936 XmCreateMonthPanel( Widget parent, char *name, ArgList args, Cardinal argCount )
939 return ( XtCreateWidget( name,
940 xmMonthPanelWidgetClass,