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 /*******************************************************************************
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>
59 #include <sys/param.h> /* MAXPATHLEN defined here */
61 #include <sys/utsname.h> /* SYS_NMLN */
69 #include <sys/resource.h>
71 #include <netinet/in.h>
73 #include <X11/IntrinsicP.h>
75 #include <Xm/DrawingA.h>
78 #include <Xm/RowColumn.h>
79 #include <Xm/ToggleBG.h>
80 #include <Dt/HourGlass.h>
84 #include "datefield.h"
85 #include "x_graphics.h"
89 #include "group_editor.h"
90 #include "monthglance.h"
91 #include "weekglance.h"
95 #include "dayglance.h"
96 #include "yearglance.h"
102 #define XOS_USE_XT_LOCKING
103 #define X_INCLUDE_TIME_H
104 #include <X11/Xos_r.h>
106 static void paint_day_entries(Tick, int, int, int, int,
107 Paint_cache *, CSA_uint32, XRectangle *);
108 static Boolean allocated(Calendar *);
109 static void allocator(Calendar *);
110 static void deallocator(Calendar *);
111 extern void layout_children(Calendar *);
112 static void display_header(Calendar *);
113 static void quick_button_cb(Widget, XtPointer, XtPointer);
114 static Boolean print_month ( Calendar *, int,
115 void *, Tick, Props *, Boolean);
116 static int count_month_pages(Calendar *, Tick, int);
117 static void paint_daynames(Calendar *, XRectangle *);
118 static void paint_month(Calendar *, Tick, XRectangle *);
119 static void unmanage_children(Calendar *);
120 static void manage_children(Calendar *);
121 static int count_month_appts(CSA_entry_handle *, int, Calendar *);
130 CalTextExtents(pf, "1", 1, &nop, &nop, &width, &nop);
143 CSA_uint32 appt_total,
147 int i, loop, nlines = 0, maxchars;
148 Calendar *c=calendar;
149 Props *p = (Props*)c->properties;
150 DisplayType dt = get_int_prop(p, CP_DEFAULTDISP);
153 new_XContext *xc = c->xcontext;
154 Cal_Font *pf = c->fonts->viewfont;
155 XFontSetExtents fontextents;
158 Tick lower = lowerbound(day);
159 Tick upper = next_ndays(day, 1);
161 CalFontExtents(pf, &fontextents);
162 pfy = fontextents.max_ink_extent.height;
165 /* loop thru the list of appointments twice, first displaying
166 the no time appointments, and then the appointments with times
169 for (loop = 0; loop < 2; loop++) {
170 for (i = 0; i < appt_total; i++) {
171 start_tick = cache[i].start_time;
172 if (start_tick >= lower &&
173 start_tick < upper &&
174 (loop == cache[i].show_time)) {
175 if (nlines < maxlines) {
177 static int pad_width = 0;
180 text_to_lines(cache[i].summary, 1);
183 cm_strlen(lines->s) + 18);
184 pad = format_line(start_tick,
192 pad = format_line(start_tick,
198 destroy_lines(lines); lines=NULL;
202 compute_pad_width(pf);
205 maxchars = gr_nchars(
208 if (cm_strlen(buf) > maxchars)
209 buf[maxchars] = NULL;
210 (void)gr_text(xc, x + pad_width,
213 maxchars = gr_nchars(w, buf,
215 if (cm_strlen(buf) > maxchars)
216 buf[maxchars] = NULL;
217 (void)gr_text(xc, x, y, pf,
232 month_button(Widget widget, XtPointer data, XtPointer cbs)
234 Calendar *c = calendar;
236 if (c->view->glance == monthGlance)
239 XtUnmapWidget(c->canvas);
241 switch (c->view->glance) {
243 c->view->glance = monthGlance;
244 cleanup_after_dayview(c);
247 c->view->glance = monthGlance;
248 cleanup_after_weekview(c);
251 cleanup_after_yearview(c);
252 c->view->glance = monthGlance;
257 prepare_to_paint_monthview (c, NULL);
259 XtMapWidget(c->canvas);
263 * Do the actual month grid, headers and appointments
266 paint_month(Calendar *c, Tick key, XRectangle *rect)
268 Month *m = (Month *)c->view->month_info;
271 int firstdom, boxw, boxh, dayname_height, margin, default_height;
275 Dimension btn_ht=0, btn_w=0;
278 CSA_attribute *range_attrs;
279 CSA_entry_handle *list = NULL;
280 XFontSetExtents fontextents;
281 _Xltimeparams localtime_buf;
283 tm = *_XLocaltime(&key, localtime_buf);
289 day = timelocal(&tm);
291 m->ndays = ((tm.tm_mon==1) && leapyr(tm.tm_year+1900))? 29 :
292 monthdays[tm.tm_mon];
293 tm = *_XLocaltime(&day, localtime_buf);
294 firstdom = tm.tm_wday;
295 boxw = calendar->view->boxw;
296 boxh = calendar->view->boxh;
297 margin = calendar->view->outside_margin;
298 dayname_height = ((Month *) calendar->view->month_info)->dayname_height;
299 xc = calendar->xcontext;
302 if (c->paint_cache == NULL) {
303 start = (time_t) lowerbound(day);
304 stop = (time_t) last_dom(day);
305 setup_range(&range_attrs, &ops, &j, start, stop, CSA_TYPE_EVENT,
306 NULL, B_FALSE, c->general->version);
307 csa_list_entries(c->cal_handle, j, range_attrs, ops, &a_total, &list, NULL);
309 free_range(&range_attrs, &ops, j);
310 allocate_paint_cache(list, a_total, &c->paint_cache);
311 c->paint_cache_size = a_total;
315 CalFontExtents(c->fonts->viewfont, &fontextents);
316 default_height = fontextents.max_logical_extent.height;
319 for(i = 1; i <= m->ndays; i++) {
320 int box_origin_x=0, box_origin_y=0;
322 box_origin_x = (x * boxw) + margin;
323 box_origin_y = (y * boxh) + dayname_height + c->view->topoffset;
325 XtVaGetValues(m->hot_button[i-1], XmNheight, &btn_ht,
326 XmNwidth, &btn_w, NULL);
329 * Paint the list of calendar entries for this day
331 paint_day_entries(day,
333 box_origin_y + default_height + btn_ht,
334 boxw - 4, boxh - btn_ht - 4,
335 c->paint_cache, c->paint_cache_size, rect);
339 if (x > 6 & i != m->ndays) {
347 * Set the label header for the view to current month name
350 display_header(Calendar *c)
352 Month *m = (Month *) c->view->month_info;
357 Tick tmptick = c->view->date;
358 _Xltimeparams localtime_buf;
361 tm_ret = _XLocaltime(&tmptick, localtime_buf);
364 Attention Translator:
366 This string is used in the calendar month view. In the C locale
371 strftime conversion string: "%B, %Y" is used.
373 Use the appropriate strftime conversion for your locale.
375 sprintf( buf, "%s, %d", months[tm_ret->tm_mon+1],
376 tm_ret->tm_year + 1900 );
378 str = XmStringCreateLocalized(buf);
379 XtVaSetValues(m->month_label, XmNlabelString, str, NULL);
383 x = c->view->outside_margin; y = 15;
384 XtVaSetValues(m->month_label, XtNx, x, XtNy, y, NULL);
387 if (!XtIsManaged(m->month_label)) {
388 XtManageChild(m->month_label);
393 paint_daynames(Calendar *c, XRectangle *rect)
396 int boxw = c->view->boxw;
397 int margin = c->view->outside_margin;
399 ((Month *)c->view->month_info)->dayname_height;
400 Cal_Font *pf = c->fonts->viewfont;
401 new_XContext *xc = c->xcontext;
403 for(i = 0; i < 7; i++) {
404 gr_draw_box(xc, (boxw * i)+margin,
406 boxw, dayname_height, rect);
407 middle = gr_center(boxw, days[i], pf);
408 gr_text(xc, (boxw*i)+middle+margin,
409 c->view->topoffset+dayname_height-3,
415 paint_grid(Calendar *c, XRectangle *rect)
418 int boxh = c->view->boxh;
419 int boxw = c->view->boxw;
420 int nrows = c->view->nwks;
421 int margin = c->view->outside_margin;
422 int dayname_height = ((Month *)c->view->month_info)->dayname_height;
423 int rightmargin = margin + 7 * boxw;
424 int bottomargin = c->view->topoffset+ dayname_height+boxh*nrows;
425 new_XContext *xc = c->xcontext;
428 for (i = 1; i <= nrows; i++) {
429 gr_draw_line(xc, margin,
430 (i*boxh)+c->view->topoffset+dayname_height,
431 rightmargin, i*boxh+c->view->topoffset+dayname_height,
436 for (i = 0; i < 8; i++) {
437 gr_draw_line(xc, margin+(i*boxw),
438 c->view->topoffset+dayname_height,
439 margin+(i*boxw), bottomargin, gr_solid, rect);
441 /* embolden grid outline */
442 gr_draw_box(xc, margin-1,
443 c->view->topoffset-1, 7*boxw+2,
444 nrows*boxh+2+dayname_height, rect);
452 Month *m = (Month *)c->view->month_info;
455 boxw = calendar->view->boxw,
456 boxh = calendar->view->boxh,
457 margin = calendar->view->outside_margin,
458 dayname_height = m->dayname_height;
461 _Xltimeparams localtime_buf;
463 tm = *_XLocaltime(&date, localtime_buf);
469 day = timelocal(&tm);
471 m->ndays = ((tm.tm_mon==1) &&
472 leapyr(tm.tm_year+1900))? 29 : monthdays[tm.tm_mon];
473 tm = *_XLocaltime(&day, localtime_buf);
474 firstdom = tm.tm_wday;
478 for(i = 1; i <= m->ndays; i++) {
479 int box_origin_x = 0,
482 box_origin_x = (x * boxw) + margin;
483 box_origin_y = (y * boxh) + dayname_height + c->view->topoffset;
485 m->button_loc[i-1].x = box_origin_x + 3;
486 m->button_loc[i-1].y = box_origin_y + 3;
489 if (x > 6 & i != m->ndays) {
493 XtMoveWidget(m->hot_button[i-1],
494 m->button_loc[i-1].x, m->button_loc[i-1].y);
497 /* Unmanage any unneeded navigator buttons (ie. 29, 30, 31) */
498 for (i=m->ndays; i<31; i++)
499 if (XtIsManaged(m->hot_button[i]))
500 XtUnmanageChild(m->hot_button[i]);
504 repaint_damaged_month(
508 /* allocate Month memory & widgets if necessary */
510 XFontSetExtents boldfontextents;
513 XmToggleButtonGadgetSetState(c->month_scope, True, False);
514 CalFontExtents(c->fonts->boldfont, &boldfontextents);
515 ((Month *) c->view->month_info)->dayname_height =
516 boldfontextents.max_logical_extent.height + 6;
517 layout_month(c, c->view->date);
522 paint_daynames(c, rect);
524 paint_month(c, c->view->date, rect);
525 calendar_select(c, daySelect, (caddr_t)NULL);
529 prepare_to_paint_monthview(Calendar *c, XRectangle *rect)
534 XmToggleButtonGadgetSetState(c->month_scope, True, False);
535 XtVaGetValues(c->canvas, XmNwidth, &w, XmNheight, &h, NULL);
538 /* allocate Month memory & widgets if necessary */
540 XFontSetExtents boldfontextents;
543 CalFontExtents(c->fonts->boldfont, &boldfontextents);
544 ((Month *) c->view->month_info)->dayname_height =
545 boldfontextents.max_logical_extent.height + 6;
549 * need to unmanage buttons while drawing to avoid many exposures
550 * when they are moved
553 layout_month(c, c->view->date);
554 gr_clear_area(c->xcontext, 0, 0, c->view->winw, c->view->winh);
558 /* ADDED FOR PRINTING */
560 get_time_str (Dtcm_appointment *appt, char *buf)
562 Calendar *c = calendar;
563 Props *p = (Props*)c->properties;
564 DisplayType dt = get_int_prop(p, CP_DEFAULTDISP);
568 _Xltimeparams localtime_buf;
570 _csa_iso8601_to_tick(appt->time->value->item.date_time_value, &start_tick);
573 if (appt==NULL || !showtime_set(appt) || magic_time(start_tick))
576 tm = _XLocaltime(&start_tick, localtime_buf);
582 (void) sprintf(buf, "%2d:%02d ", hr, mn);
585 (void) sprintf(buf, "%02d%02d ", hr, mn);
589 month_event(XEvent *event)
591 static int lastcol, lastrow;
592 static XEvent lastevent;
593 int x, y, j, toffset;
594 int boxw, boxh, row, col, margin, dayname_height;
596 Calendar *c = calendar;
597 Editor *e = (Editor*)c->editor;
598 ToDo *t = (ToDo*)c->todo;
599 GEditor *ge = (GEditor*)c->geditor;
601 boxw = c->view->boxw;
602 boxh = c->view->boxh;
603 margin = c->view->outside_margin;
604 dayname_height = ((Month *) c->view->month_info)->dayname_height;
605 date = c->view->date;
606 x = event->xbutton.x;
607 y = event->xbutton.y;
608 toffset = c->view->topoffset;
613 col = (x-margin)/boxw;
617 row = (y-c->view->topoffset-dayname_height)/boxh;
619 /* boundary conditions */
620 if (x < margin || col > 6 || y < (dayname_height+toffset) || row > c->view->nwks-1) {
621 calendar_deselect(c);
622 lastcol=0; lastrow=0;
626 /* boundary check for click in invalid cell */
627 if (((col < fdom(date)) && (row==0)) ||
628 ((col > ldom(date)) && (row==c->view->nwks - 1))) {
629 calendar_deselect(c);
630 lastcol=0; lastrow=0;
634 switch(event->type) {
636 if (col !=lastcol || row !=lastrow) {
637 calendar_deselect(c);
638 j = xytoclock(col+1, row+1, date);
640 c->view->olddate = c->view->date;
642 calendar_select(c, daySelect, (caddr_t)NULL);
649 if (ds_is_double_click(&lastevent, event)) {
650 _DtTurnOnHourGlass(c->frame);
651 if (lastcol == col && lastrow == row)
652 show_editor(c, 0, 0, False);
653 _DtTurnOffHourGlass(c->frame);
656 calendar_deselect(c);
657 j = xytoclock(col+1, row+1, date);
659 c->view->olddate = c->view->date;
661 calendar_select(c, daySelect, (caddr_t)NULL);
664 if (editor_showing(e)) {
665 set_editor_defaults(e, 0, 0, False);
669 if (todo_showing(t)) {
670 set_todo_defaults(t);
673 if (geditor_showing(ge)) {
674 set_geditor_defaults(ge, 0, 0);
687 count_month_pages(Calendar *c, Tick start_date, int lines_per_box)
692 int day, ndays, num_appts, max = 0;
695 CSA_entry_handle *list;
696 CSA_attribute *range_attrs;
698 _Xltimeparams localtime_buf;
700 tm = *_XLocaltime(&start_date, localtime_buf);
704 day = (int)mktime(&tm);
706 day = (int)timelocal(&tm);
708 ndays = ((tm.tm_mon==1) && leapyr(tm.tm_year+1900))? 29 :
709 monthdays[tm.tm_mon];
711 /* print days of the week at the top */
712 rows = numwks (start_date);
714 /* need minimum 5 rows to paint miniature months */
715 if (rows == 4) rows++;
717 /* print the times and text of appts */
718 for (i = 1; i <= ndays; i++)
720 /* setup a time limit for appts searched */
721 start = (time_t) lowerbound (day);
722 stop = (time_t) next_ndays(day, 1) - 1;
723 setup_range(&range_attrs, &ops, &j, start, stop,
724 CSA_TYPE_EVENT, NULL, B_FALSE,
725 c->general->version);
726 csa_list_entries(c->cal_handle, j, range_attrs, ops,
727 &a_total, &list, NULL);
728 free_range(&range_attrs, &ops, j);
730 num_appts = count_month_appts(list, a_total, c);
739 pages = max / lines_per_box;
740 if ((max % lines_per_box) > 0)
748 print_month ( Calendar *c,
755 int rows, i, j, lines_per_box;
756 time_t lo_hour, hi_hour;
758 int ndays, num_appts;
759 Boolean more, done = False, all_done = True;
761 OrderingType ot = get_int_prop(p, CP_DATEORDERING);
762 CSA_entry_handle *list;
763 CSA_attribute *range_attrs;
766 static Tick tick = 0;
767 static int total_pages;
772 tick = prevmonth_exactday(tick);
774 /* print days of the week at the top */
775 rows = numwks (tick);
777 /* need minimum 5 rows to paint miniature months */
778 if (rows == 4) rows++;
780 x_init_printer(xp, LANDSCAPE);
781 x_init_month(xp, rows);
782 lines_per_box = x_get_month_lines_per_page(xp);
785 total_pages = (lines_per_box > 0) ?
786 count_month_pages(c, tick, lines_per_box) : 1;
788 day = first_dom(tick);
789 ndays = monthlength(tick);
791 /* print month & year on top */
792 format_date(tick, ot, buf, 0, 0, 0);
794 x_print_header(xp, buf, num_page, total_pages);
795 x_month_daynames(xp, rows);
797 /* print the times and text of appts */
798 for (i = 1; i <= ndays; i++)
800 /* setup a time limit for appts searched */
801 lo_hour = (time_t)lowerbound (day);
802 hi_hour = (time_t) next_ndays(day, 1) - 1;
803 setup_range(&range_attrs, &ops, &j, lo_hour, hi_hour,
804 CSA_TYPE_EVENT, NULL, B_FALSE, c->general->version);
805 csa_list_entries(c->cal_handle, j, range_attrs,
806 ops, &a_total, &list, NULL);
807 free_range(&range_attrs, &ops, j);
808 num_appts = count_month_appts(list, a_total, c);
809 if ((lines_per_box > 0) &&
810 (num_appts > (lines_per_box * num_page)))
815 x_month_timeslots(xp, day, more);
817 /* print out times and appts */
818 if (lines_per_box > 0)
819 done = x_print_month_appts(xp, list, a_total, num_page,
820 hi_hour, lines_per_box);
830 /* paint miniature previous & next month */
831 x_print_little_months(xp, tick);
832 x_finish_printer(xp);
834 tick = nextmonth(tick);
840 print_month_range(Calendar *c, Tick start_tick, Tick end_tick)
842 Props *p = (Props *)c->properties;
843 register Tick end, first_date = start_tick;
845 Boolean done = False, first = True;
847 void *xp = (void *)NULL;
849 /* counting up the month pages is a little trickier than in the day
850 and week cases. Months will have variable numbers of seconds in
851 them, simple dividing the difference by the number of seconds
852 per month doesn't work. We'll brute force this by grinding thru,
853 adding seconds until we pass the end tick time. */
855 end_tick = last_dom(end_tick);
856 end = last_dom(start_tick);
857 for (n = 1; end < end_tick; n++)
858 end = last_dom(nextmonth(end));
860 if ((xp = x_open_file(c)) == (void *)NULL)
867 done = print_month(c, num_page, xp,
868 first_date, p, first);
881 count_month_appts(CSA_entry_handle *list, int a_total, Calendar *c)
883 int count = 0, i, meoval;
884 Props *pr = (Props*)c->properties;
885 Dtcm_appointment *appt;
886 CSA_return_code stat;
888 meoval = get_int_prop(pr, CP_PRINTPRIVACY);
890 appt = allocate_appt_struct(appt_read,
892 CSA_ENTRY_ATTR_CLASSIFICATION_I,
894 for (i = 0; i < a_total; i++) {
896 stat = query_appt_struct(c->cal_handle, list[i], appt);
897 if (stat != CSA_SUCCESS) {
898 free_appt_struct(&appt);
902 if ((privacy_set(appt) == CSA_CLASS_PUBLIC) && !(meoval & PRINT_PUBLIC))
904 else if ((privacy_set(appt) == CSA_CLASS_CONFIDENTIAL) && !(meoval & PRINT_SEMIPRIVATE))
906 else if ((privacy_set(appt) == CSA_CLASS_PRIVATE) && !(meoval & PRINT_PRIVATE))
912 free_appt_struct(&appt);
917 * Handler for "hot" buttons to navigate to day view
918 * Client data is index of activated button [0..30]
921 quick_button_cb(Widget widget, XtPointer client, XtPointer call)
923 Calendar *c = calendar;
924 int dom = (int) client;
926 c->view->olddate = c->view->date;
927 c->view->date = next_ndays(first_dom(c->view->date), dom);
929 calendar_select(c, daySelect, NULL);
931 cleanup_after_monthview(c);
933 c->view->glance = dayGlance;
935 (void)init_dayview(c);
941 * Handle positioning and managing of hotbuttons
943 * IMPORTANT: This function assumes that it is being called during the
944 * Resize method of the canvas (XmDrawingArea), and for that reason
945 * it is effectively widget code and can legally call XtMoveWidget.
946 * Don't try this at home ! (and never from non-widget code)
948 * Also, this needs to be called *after* paint_month, as it relies on data
949 * calculated there and stores in the month data structure.
952 layout_children(Calendar *c)
954 Month *m = (Month *)c->view->month_info;
955 Widget *btns = m->hot_button;
958 /* Position required navigator buttons - note that if they're
959 mapped when this happens, many exposes will occur */
960 for (i=0; i < m->ndays; i++)
961 XtMoveWidget(btns[i], m->button_loc[i].x, m->button_loc[i].y);
963 /* Unmanage any unneeded navigator buttons (ie. 29, 30, 31) */
964 for (i=m->ndays; i<31; i++)
965 if (XtIsManaged(m->hot_button[i]))
966 XtUnmanageChild(m->hot_button[i]);
970 manage_children(Calendar *c)
973 Month *m = (Month *)c->view->month_info;
975 /* manage the header widget */
976 XtManageChild(m->month_label);
977 XtManageChildren(m->hot_button, m->ndays);
981 unmanage_children(Calendar *c)
984 Month *m = (Month *)c->view->month_info;
986 /* unmanage the header widget */
987 XtUnmanageChild(m->month_label);
988 XtUnmanageChildren(m->hot_button, 31);
992 * Clean up anything left around that won't be removed on
993 * switching to another view, such as the hot buttons for
994 * navigation to day view.
997 cleanup_after_monthview(Calendar *c)
1000 invalidate_cache(c);
1002 XtUnmapWidget(c->canvas);
1003 unmanage_children(c);
1005 XmToggleButtonGadgetSetState(c->month_scope, False, False);
1008 * Deallocating everything causes all this view's memory to be
1009 * freed (at least all we have allocated in this application)
1010 * at the expense of rebuilding the view next time it is used.
1011 * Commenting it out improves usability and avoids any risk
1012 * of memory leakage from Xt and Motif.
1018 XtMapWidget(c->canvas);
1022 * check whether month view is allocated yet
1025 allocated(Calendar *c)
1027 return (c->view->month_info != NULL);
1031 * allocate storage & subwidgets used by month view
1033 allocator(Calendar *c)
1040 /* main storage for other month data */
1041 calendar->view->month_info = (caddr_t) ckalloc(sizeof(Month));
1042 m = (Month *)c->view->month_info;
1044 m->button_loc = (XPoint *) ckalloc(31 * sizeof(XPoint));
1046 /* label for month & navigation button to year */
1047 m->month_label = XmCreateLabel(c->canvas, "monthLabel", NULL, 0);
1049 /* navigation buttons to day view */
1050 m->hot_button = (Widget *) ckalloc(31 * sizeof(Widget));
1051 for (n=0; n<31; n++) {
1052 sprintf(buf, "%d", n+1);
1053 str = XmStringCreateLocalized(buf);
1054 sprintf(buf, "month2day%d", n);
1056 XmCreatePushButton(c->canvas, buf, NULL, 0);
1057 XtVaSetValues(m->hot_button[n], XmNlabelString, str, NULL);
1058 XtAddCallback(m->hot_button[n],XmNactivateCallback,
1059 quick_button_cb, (XtPointer)n);
1066 * allocate storage & subwidgets used by month view
1069 deallocator(Calendar *c)
1071 Month *m = (Month *)c->view->month_info;
1074 /* free cache of points for buttons positions */
1075 free(m->button_loc);
1077 /* destroy widgets used for header */
1078 XtDestroyWidget(m->month_label);
1081 for (n=0; n<31; n++)
1082 XtDestroyWidget(m->hot_button[n]);
1084 /* array that held navigation buttons */
1085 free(m->hot_button);
1087 /* structure holding month information */
1089 c->view->month_info = NULL;