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 libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /*******************************************************************************
27 ** $XConsortium: monthglance.c /main/13 1996/11/21 19:43:07 drk $
29 ** RESTRICTED CONFIDENTIAL INFORMATION:
31 ** The information in this document is subject to special
32 ** restrictions in a confidential disclosure agreement between
33 ** HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
34 ** document outside HP, IBM, Sun, USL, SCO, or Univel without
35 ** Sun's specific written approval. This document and all copies
36 ** and derivative works thereof must be returned or destroyed at
39 ** Copyright 1993 Sun Microsystems, Inc. All rights reserved.
41 *******************************************************************************/
44 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
45 * (c) Copyright 1993, 1994 International Business Machines Corp. *
46 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
47 * (c) Copyright 1993, 1994 Novell, Inc. *
51 static char sccsid[] = "@(#)monthglance.c 1.82 95/07/27 Copyr 1994 Sun Microsystems, Inc.";
54 #include <EUSCompat.h>
60 #include <sys/param.h> /* MAXPATHLEN defined here */
62 #include <sys/utsname.h> /* SYS_NMLN */
70 #include <sys/resource.h>
72 #include <netinet/in.h>
74 #include <X11/IntrinsicP.h>
76 #include <Xm/DrawingA.h>
79 #include <Xm/RowColumn.h>
80 #include <Xm/ToggleBG.h>
81 #include <Dt/HourGlass.h>
85 #include "datefield.h"
86 #include "x_graphics.h"
90 #include "group_editor.h"
91 #include "monthglance.h"
92 #include "weekglance.h"
96 #include "dayglance.h"
97 #include "yearglance.h"
103 #define XOS_USE_XT_LOCKING
104 #define X_INCLUDE_TIME_H
105 #if defined(__linux__)
108 #include <X11/Xos_r.h>
110 static void paint_day_entries(Tick, int, int, int, int,
111 Paint_cache *, CSA_uint32, XRectangle *);
112 static Boolean allocated(Calendar *);
113 static void allocator(Calendar *);
114 static void deallocator(Calendar *);
115 extern void layout_children(Calendar *);
116 static void display_header(Calendar *);
117 static void quick_button_cb(Widget, XtPointer, XtPointer);
118 static Boolean print_month ( Calendar *, int,
119 void *, Tick, Props *, Boolean);
120 static int count_month_pages(Calendar *, Tick, int);
121 static void paint_daynames(Calendar *, XRectangle *);
122 static void paint_month(Calendar *, Tick, XRectangle *);
123 static void unmanage_children(Calendar *);
124 static void manage_children(Calendar *);
125 static int count_month_appts(CSA_entry_handle *, int, Calendar *);
134 CalTextExtents(pf, "1", 1, &nop, &nop, &width, &nop);
147 CSA_uint32 appt_total,
151 int i, loop, nlines = 0, maxchars;
152 Calendar *c=calendar;
153 Props *p = (Props*)c->properties;
154 DisplayType dt = get_int_prop(p, CP_DEFAULTDISP);
157 new_XContext *xc = c->xcontext;
158 Cal_Font *pf = c->fonts->viewfont;
159 XFontSetExtents fontextents;
162 Tick lower = lowerbound(day);
163 Tick upper = next_ndays(day, 1);
165 CalFontExtents(pf, &fontextents);
166 pfy = fontextents.max_ink_extent.height;
169 /* loop thru the list of appointments twice, first displaying
170 the no time appointments, and then the appointments with times
173 for (loop = 0; loop < 2; loop++) {
174 for (i = 0; i < appt_total; i++) {
175 start_tick = cache[i].start_time;
176 if (start_tick >= lower &&
177 start_tick < upper &&
178 (loop == cache[i].show_time)) {
179 if (nlines < maxlines) {
181 static int pad_width = 0;
184 text_to_lines(cache[i].summary, 1);
187 cm_strlen(lines->s) + 18);
188 pad = format_line(start_tick,
196 pad = format_line(start_tick,
202 destroy_lines(lines); lines=NULL;
206 compute_pad_width(pf);
209 maxchars = gr_nchars(
212 if (cm_strlen(buf) > maxchars)
213 buf[maxchars] = '\0';
214 (void)gr_text(xc, x + pad_width,
217 maxchars = gr_nchars(w, buf,
219 if (cm_strlen(buf) > maxchars)
220 buf[maxchars] = '\0';
221 (void)gr_text(xc, x, y, pf,
236 month_button(Widget widget, XtPointer data, XtPointer cbs)
238 Calendar *c = calendar;
240 if (c->view->glance == monthGlance)
243 XtUnmapWidget(c->canvas);
245 switch (c->view->glance) {
247 c->view->glance = monthGlance;
248 cleanup_after_dayview(c);
251 c->view->glance = monthGlance;
252 cleanup_after_weekview(c);
255 cleanup_after_yearview(c);
256 c->view->glance = monthGlance;
261 prepare_to_paint_monthview (c, NULL);
263 XtMapWidget(c->canvas);
267 * Do the actual month grid, headers and appointments
270 paint_month(Calendar *c, Tick key, XRectangle *rect)
272 Month *m = (Month *)c->view->month_info;
275 int firstdom, boxw, boxh, dayname_height, margin, default_height;
279 Dimension btn_ht=0, btn_w=0;
282 CSA_attribute *range_attrs;
283 CSA_entry_handle *list = NULL;
284 XFontSetExtents fontextents;
285 _Xltimeparams localtime_buf;
287 tm = *_XLocaltime(&key, localtime_buf);
293 day = timelocal(&tm);
295 m->ndays = ((tm.tm_mon==1) && leapyr(tm.tm_year+1900))? 29 :
296 monthdays[tm.tm_mon];
297 tm = *_XLocaltime(&day, localtime_buf);
298 firstdom = tm.tm_wday;
299 boxw = calendar->view->boxw;
300 boxh = calendar->view->boxh;
301 margin = calendar->view->outside_margin;
302 dayname_height = ((Month *) calendar->view->month_info)->dayname_height;
303 xc = calendar->xcontext;
306 if (c->paint_cache == NULL) {
307 start = (time_t) lowerbound(day);
308 stop = (time_t) last_dom(day);
309 setup_range(&range_attrs, &ops, &j, start, stop, CSA_TYPE_EVENT,
310 0, B_FALSE, c->general->version);
311 csa_list_entries(c->cal_handle, j, range_attrs, ops, &a_total, &list, NULL);
313 free_range(&range_attrs, &ops, j);
314 allocate_paint_cache(list, a_total, &c->paint_cache);
315 c->paint_cache_size = a_total;
319 CalFontExtents(c->fonts->viewfont, &fontextents);
320 default_height = fontextents.max_logical_extent.height;
323 for(i = 1; i <= m->ndays; i++) {
324 int box_origin_x=0, box_origin_y=0;
326 box_origin_x = (x * boxw) + margin;
327 box_origin_y = (y * boxh) + dayname_height + c->view->topoffset;
329 XtVaGetValues(m->hot_button[i-1], XmNheight, &btn_ht,
330 XmNwidth, &btn_w, NULL);
333 * Paint the list of calendar entries for this day
335 paint_day_entries(day,
337 box_origin_y + default_height + btn_ht,
338 boxw - 4, boxh - btn_ht - 4,
339 c->paint_cache, c->paint_cache_size, rect);
343 if (x > 6 & i != m->ndays) {
351 * Set the label header for the view to current month name
354 display_header(Calendar *c)
356 Month *m = (Month *) c->view->month_info;
361 Tick tmptick = c->view->date;
362 _Xltimeparams localtime_buf;
365 tm_ret = _XLocaltime(&tmptick, localtime_buf);
368 Attention Translator:
370 This string is used in the calendar month view. In the C locale
375 strftime conversion string: "%B, %Y" is used.
377 Use the appropriate strftime conversion for your locale.
379 sprintf( buf, "%s, %d", months[tm_ret->tm_mon+1],
380 tm_ret->tm_year + 1900 );
382 str = XmStringCreateLocalized(buf);
383 XtVaSetValues(m->month_label, XmNlabelString, str, NULL);
387 x = c->view->outside_margin; y = 15;
388 XtVaSetValues(m->month_label, XtNx, x, XtNy, y, NULL);
391 if (!XtIsManaged(m->month_label)) {
392 XtManageChild(m->month_label);
397 paint_daynames(Calendar *c, XRectangle *rect)
400 int boxw = c->view->boxw;
401 int margin = c->view->outside_margin;
403 ((Month *)c->view->month_info)->dayname_height;
404 Cal_Font *pf = c->fonts->viewfont;
405 new_XContext *xc = c->xcontext;
407 for(i = 0; i < 7; i++) {
408 gr_draw_box(xc, (boxw * i)+margin,
410 boxw, dayname_height, rect);
411 middle = gr_center(boxw, days[i], pf);
412 gr_text(xc, (boxw*i)+middle+margin,
413 c->view->topoffset+dayname_height-3,
419 paint_grid(Calendar *c, XRectangle *rect)
422 int boxh = c->view->boxh;
423 int boxw = c->view->boxw;
424 int nrows = c->view->nwks;
425 int margin = c->view->outside_margin;
426 int dayname_height = ((Month *)c->view->month_info)->dayname_height;
427 int rightmargin = margin + 7 * boxw;
428 int bottomargin = c->view->topoffset+ dayname_height+boxh*nrows;
429 new_XContext *xc = c->xcontext;
432 for (i = 1; i <= nrows; i++) {
433 gr_draw_line(xc, margin,
434 (i*boxh)+c->view->topoffset+dayname_height,
435 rightmargin, i*boxh+c->view->topoffset+dayname_height,
440 for (i = 0; i < 8; i++) {
441 gr_draw_line(xc, margin+(i*boxw),
442 c->view->topoffset+dayname_height,
443 margin+(i*boxw), bottomargin, gr_solid, rect);
445 /* embolden grid outline */
446 gr_draw_box(xc, margin-1,
447 c->view->topoffset-1, 7*boxw+2,
448 nrows*boxh+2+dayname_height, rect);
456 Month *m = (Month *)c->view->month_info;
459 boxw = calendar->view->boxw,
460 boxh = calendar->view->boxh,
461 margin = calendar->view->outside_margin,
462 dayname_height = m->dayname_height;
465 _Xltimeparams localtime_buf;
467 tm = *_XLocaltime(&date, localtime_buf);
473 day = timelocal(&tm);
475 m->ndays = ((tm.tm_mon==1) &&
476 leapyr(tm.tm_year+1900))? 29 : monthdays[tm.tm_mon];
477 tm = *_XLocaltime(&day, localtime_buf);
478 firstdom = tm.tm_wday;
482 for(i = 1; i <= m->ndays; i++) {
483 int box_origin_x = 0,
486 box_origin_x = (x * boxw) + margin;
487 box_origin_y = (y * boxh) + dayname_height + c->view->topoffset;
489 m->button_loc[i-1].x = box_origin_x + 3;
490 m->button_loc[i-1].y = box_origin_y + 3;
493 if (x > 6 & i != m->ndays) {
497 XtMoveWidget(m->hot_button[i-1],
498 m->button_loc[i-1].x, m->button_loc[i-1].y);
501 /* Unmanage any unneeded navigator buttons (ie. 29, 30, 31) */
502 for (i=m->ndays; i<31; i++)
503 if (XtIsManaged(m->hot_button[i]))
504 XtUnmanageChild(m->hot_button[i]);
508 repaint_damaged_month(
512 /* allocate Month memory & widgets if necessary */
514 XFontSetExtents boldfontextents;
517 XmToggleButtonGadgetSetState(c->month_scope, True, False);
518 CalFontExtents(c->fonts->boldfont, &boldfontextents);
519 ((Month *) c->view->month_info)->dayname_height =
520 boldfontextents.max_logical_extent.height + 6;
521 layout_month(c, c->view->date);
526 paint_daynames(c, rect);
528 paint_month(c, c->view->date, rect);
529 calendar_select(c, daySelect, (caddr_t)NULL);
533 prepare_to_paint_monthview(Calendar *c, XRectangle *rect)
538 XmToggleButtonGadgetSetState(c->month_scope, True, False);
539 XtVaGetValues(c->canvas, XmNwidth, &w, XmNheight, &h, NULL);
542 /* allocate Month memory & widgets if necessary */
544 XFontSetExtents boldfontextents;
547 CalFontExtents(c->fonts->boldfont, &boldfontextents);
548 ((Month *) c->view->month_info)->dayname_height =
549 boldfontextents.max_logical_extent.height + 6;
553 * need to unmanage buttons while drawing to avoid many exposures
554 * when they are moved
557 layout_month(c, c->view->date);
558 gr_clear_area(c->xcontext, 0, 0, c->view->winw, c->view->winh);
562 /* ADDED FOR PRINTING */
564 get_time_str (Dtcm_appointment *appt, char *buf)
566 Calendar *c = calendar;
567 Props *p = (Props*)c->properties;
568 DisplayType dt = get_int_prop(p, CP_DEFAULTDISP);
572 _Xltimeparams localtime_buf;
574 _csa_iso8601_to_tick(appt->time->value->item.date_time_value, &start_tick);
577 if (appt==NULL || !showtime_set(appt) || magic_time(start_tick))
580 tm = _XLocaltime(&start_tick, localtime_buf);
586 (void) sprintf(buf, "%2d:%02d ", hr, mn);
589 (void) sprintf(buf, "%02d%02d ", hr, mn);
593 month_event(XEvent *event)
595 static int lastcol, lastrow;
596 static XEvent lastevent;
597 int x, y, j, toffset;
598 int boxw, boxh, row, col, margin, dayname_height;
600 Calendar *c = calendar;
601 Editor *e = (Editor*)c->editor;
602 ToDo *t = (ToDo*)c->todo;
603 GEditor *ge = (GEditor*)c->geditor;
605 boxw = c->view->boxw;
606 boxh = c->view->boxh;
607 margin = c->view->outside_margin;
608 dayname_height = ((Month *) c->view->month_info)->dayname_height;
609 date = c->view->date;
610 x = event->xbutton.x;
611 y = event->xbutton.y;
612 toffset = c->view->topoffset;
617 col = (x-margin)/boxw;
621 row = (y-c->view->topoffset-dayname_height)/boxh;
623 /* boundary conditions */
624 if (x < margin || col > 6 || y < (dayname_height+toffset) || row > c->view->nwks-1) {
625 calendar_deselect(c);
626 lastcol=0; lastrow=0;
630 /* boundary check for click in invalid cell */
631 if (((col < fdom(date)) && (row==0)) ||
632 ((col > ldom(date)) && (row==c->view->nwks - 1))) {
633 calendar_deselect(c);
634 lastcol=0; lastrow=0;
638 switch(event->type) {
640 if (col !=lastcol || row !=lastrow) {
641 calendar_deselect(c);
642 j = xytoclock(col+1, row+1, date);
644 c->view->olddate = c->view->date;
646 calendar_select(c, daySelect, (caddr_t)NULL);
653 if (ds_is_double_click(&lastevent, event)) {
654 _DtTurnOnHourGlass(c->frame);
655 if (lastcol == col && lastrow == row)
656 show_editor(c, 0, 0, False);
657 _DtTurnOffHourGlass(c->frame);
660 calendar_deselect(c);
661 j = xytoclock(col+1, row+1, date);
663 c->view->olddate = c->view->date;
665 calendar_select(c, daySelect, (caddr_t)NULL);
668 if (editor_showing(e)) {
669 set_editor_defaults(e, 0, 0, False);
673 if (todo_showing(t)) {
674 set_todo_defaults(t);
677 if (geditor_showing(ge)) {
678 set_geditor_defaults(ge, 0, 0);
691 count_month_pages(Calendar *c, Tick start_date, int lines_per_box)
696 int day, ndays, num_appts, max = 0;
699 CSA_entry_handle *list;
700 CSA_attribute *range_attrs;
702 _Xltimeparams localtime_buf;
704 tm = *_XLocaltime(&start_date, localtime_buf);
708 day = (int)mktime(&tm);
710 day = (int)timelocal(&tm);
712 ndays = ((tm.tm_mon==1) && leapyr(tm.tm_year+1900))? 29 :
713 monthdays[tm.tm_mon];
715 /* print days of the week at the top */
716 rows = numwks (start_date);
718 /* need minimum 5 rows to paint miniature months */
719 if (rows == 4) rows++;
721 /* print the times and text of appts */
722 for (i = 1; i <= ndays; i++)
724 /* setup a time limit for appts searched */
725 start = (time_t) lowerbound (day);
726 stop = (time_t) next_ndays(day, 1) - 1;
727 setup_range(&range_attrs, &ops, &j, start, stop,
728 CSA_TYPE_EVENT, 0, B_FALSE,
729 c->general->version);
730 csa_list_entries(c->cal_handle, j, range_attrs, ops,
731 &a_total, &list, NULL);
732 free_range(&range_attrs, &ops, j);
734 num_appts = count_month_appts(list, a_total, c);
743 pages = max / lines_per_box;
744 if ((max % lines_per_box) > 0)
752 print_month ( Calendar *c,
759 int rows, i, j, lines_per_box;
760 time_t lo_hour, hi_hour;
762 int ndays, num_appts;
763 Boolean more, done = False, all_done = True;
765 OrderingType ot = get_int_prop(p, CP_DATEORDERING);
766 CSA_entry_handle *list;
767 CSA_attribute *range_attrs;
770 static Tick tick = 0;
771 static int total_pages;
776 tick = prevmonth_exactday(tick);
778 /* print days of the week at the top */
779 rows = numwks (tick);
781 /* need minimum 5 rows to paint miniature months */
782 if (rows == 4) rows++;
784 x_init_printer(xp, LANDSCAPE);
785 x_init_month(xp, rows);
786 lines_per_box = x_get_month_lines_per_page(xp);
789 total_pages = (lines_per_box > 0) ?
790 count_month_pages(c, tick, lines_per_box) : 1;
792 day = first_dom(tick);
793 ndays = monthlength(tick);
795 /* print month & year on top */
796 format_date(tick, ot, buf, 0, 0, 0);
798 x_print_header(xp, buf, num_page, total_pages);
799 x_month_daynames(xp, rows);
801 /* print the times and text of appts */
802 for (i = 1; i <= ndays; i++)
804 /* setup a time limit for appts searched */
805 lo_hour = (time_t)lowerbound (day);
806 hi_hour = (time_t) next_ndays(day, 1) - 1;
807 setup_range(&range_attrs, &ops, &j, lo_hour, hi_hour,
808 CSA_TYPE_EVENT, 0, B_FALSE, c->general->version);
809 csa_list_entries(c->cal_handle, j, range_attrs,
810 ops, &a_total, &list, NULL);
811 free_range(&range_attrs, &ops, j);
812 num_appts = count_month_appts(list, a_total, c);
813 if ((lines_per_box > 0) &&
814 (num_appts > (lines_per_box * num_page)))
819 x_month_timeslots(xp, day, more);
821 /* print out times and appts */
822 if (lines_per_box > 0)
823 done = x_print_month_appts(xp, list, a_total, num_page,
824 hi_hour, lines_per_box);
834 /* paint miniature previous & next month */
835 x_print_little_months(xp, tick);
836 x_finish_printer(xp);
838 tick = nextmonth(tick);
844 print_month_range(Calendar *c, Tick start_tick, Tick end_tick)
846 Props *p = (Props *)c->properties;
847 Tick end, first_date = start_tick;
849 Boolean done = False, first = True;
851 void *xp = (void *)NULL;
853 /* counting up the month pages is a little trickier than in the day
854 and week cases. Months will have variable numbers of seconds in
855 them, simple dividing the difference by the number of seconds
856 per month doesn't work. We'll brute force this by grinding thru,
857 adding seconds until we pass the end tick time. */
859 end_tick = last_dom(end_tick);
860 end = last_dom(start_tick);
861 for (n = 1; end < end_tick; n++)
862 end = last_dom(nextmonth(end));
864 if ((xp = x_open_file(c)) == (void *)NULL)
871 done = print_month(c, num_page, xp,
872 first_date, p, first);
885 count_month_appts(CSA_entry_handle *list, int a_total, Calendar *c)
887 int count = 0, i, meoval;
888 Props *pr = (Props*)c->properties;
889 Dtcm_appointment *appt;
890 CSA_return_code stat;
892 meoval = get_int_prop(pr, CP_PRINTPRIVACY);
894 appt = allocate_appt_struct(appt_read,
896 CSA_ENTRY_ATTR_CLASSIFICATION_I,
898 for (i = 0; i < a_total; i++) {
900 stat = query_appt_struct(c->cal_handle, list[i], appt);
901 if (stat != CSA_SUCCESS) {
902 free_appt_struct(&appt);
906 if ((privacy_set(appt) == CSA_CLASS_PUBLIC) && !(meoval & PRINT_PUBLIC))
908 else if ((privacy_set(appt) == CSA_CLASS_CONFIDENTIAL) && !(meoval & PRINT_SEMIPRIVATE))
910 else if ((privacy_set(appt) == CSA_CLASS_PRIVATE) && !(meoval & PRINT_PRIVATE))
916 free_appt_struct(&appt);
921 * Handler for "hot" buttons to navigate to day view
922 * Client data is index of activated button [0..30]
925 quick_button_cb(Widget widget, XtPointer client, XtPointer call)
927 Calendar *c = calendar;
928 int dom = (int) (intptr_t) client;
930 c->view->olddate = c->view->date;
931 c->view->date = next_ndays(first_dom(c->view->date), dom);
933 calendar_select(c, daySelect, NULL);
935 cleanup_after_monthview(c);
937 c->view->glance = dayGlance;
939 (void)init_dayview(c);
945 * Handle positioning and managing of hotbuttons
947 * IMPORTANT: This function assumes that it is being called during the
948 * Resize method of the canvas (XmDrawingArea), and for that reason
949 * it is effectively widget code and can legally call XtMoveWidget.
950 * Don't try this at home ! (and never from non-widget code)
952 * Also, this needs to be called *after* paint_month, as it relies on data
953 * calculated there and stores in the month data structure.
956 layout_children(Calendar *c)
958 Month *m = (Month *)c->view->month_info;
959 Widget *btns = m->hot_button;
962 /* Position required navigator buttons - note that if they're
963 mapped when this happens, many exposes will occur */
964 for (i=0; i < m->ndays; i++)
965 XtMoveWidget(btns[i], m->button_loc[i].x, m->button_loc[i].y);
967 /* Unmanage any unneeded navigator buttons (ie. 29, 30, 31) */
968 for (i=m->ndays; i<31; i++)
969 if (XtIsManaged(m->hot_button[i]))
970 XtUnmanageChild(m->hot_button[i]);
974 manage_children(Calendar *c)
977 Month *m = (Month *)c->view->month_info;
979 /* manage the header widget */
980 XtManageChild(m->month_label);
981 XtManageChildren(m->hot_button, m->ndays);
985 unmanage_children(Calendar *c)
988 Month *m = (Month *)c->view->month_info;
990 /* unmanage the header widget */
991 XtUnmanageChild(m->month_label);
992 XtUnmanageChildren(m->hot_button, 31);
996 * Clean up anything left around that won't be removed on
997 * switching to another view, such as the hot buttons for
998 * navigation to day view.
1001 cleanup_after_monthview(Calendar *c)
1004 invalidate_cache(c);
1006 XtUnmapWidget(c->canvas);
1007 unmanage_children(c);
1009 XmToggleButtonGadgetSetState(c->month_scope, False, False);
1012 * Deallocating everything causes all this view's memory to be
1013 * freed (at least all we have allocated in this application)
1014 * at the expense of rebuilding the view next time it is used.
1015 * Commenting it out improves usability and avoids any risk
1016 * of memory leakage from Xt and Motif.
1022 XtMapWidget(c->canvas);
1026 * check whether month view is allocated yet
1029 allocated(Calendar *c)
1031 return (c->view->month_info != NULL);
1035 * allocate storage & subwidgets used by month view
1037 allocator(Calendar *c)
1044 /* main storage for other month data */
1045 calendar->view->month_info = (caddr_t) ckalloc(sizeof(Month));
1046 m = (Month *)c->view->month_info;
1048 m->button_loc = (XPoint *) ckalloc(31 * sizeof(XPoint));
1050 /* label for month & navigation button to year */
1051 m->month_label = XmCreateLabel(c->canvas, "monthLabel", NULL, 0);
1053 /* navigation buttons to day view */
1054 m->hot_button = (Widget *) ckalloc(31 * sizeof(Widget));
1055 for (n=0; n<31; n++) {
1056 sprintf(buf, "%d", n+1);
1057 str = XmStringCreateLocalized(buf);
1058 sprintf(buf, "month2day%d", n);
1060 XmCreatePushButton(c->canvas, buf, NULL, 0);
1061 XtVaSetValues(m->hot_button[n], XmNlabelString, str, NULL);
1062 XtAddCallback(m->hot_button[n],XmNactivateCallback,
1063 quick_button_cb, (XtPointer) (intptr_t) n);
1070 * allocate storage & subwidgets used by month view
1073 deallocator(Calendar *c)
1075 Month *m = (Month *)c->view->month_info;
1078 /* free cache of points for buttons positions */
1079 free(m->button_loc);
1081 /* destroy widgets used for header */
1082 XtDestroyWidget(m->month_label);
1085 for (n=0; n<31; n++)
1086 XtDestroyWidget(m->hot_button[n]);
1088 /* array that held navigation buttons */
1089 free(m->hot_button);
1091 /* structure holding month information */
1093 c->view->month_info = NULL;