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
107 #include <X11/Xos_r.h>
109 static void paint_day_entries(Tick, int, int, int, int,
110 Paint_cache *, CSA_uint32, XRectangle *);
111 static Boolean allocated(Calendar *);
112 static void allocator(Calendar *);
113 static void deallocator(Calendar *);
114 extern void layout_children(Calendar *);
115 static void display_header(Calendar *);
116 static void quick_button_cb(Widget, XtPointer, XtPointer);
117 static Boolean print_month ( Calendar *, int,
118 void *, Tick, Props *, Boolean);
119 static int count_month_pages(Calendar *, Tick, int);
120 static void paint_daynames(Calendar *, XRectangle *);
121 static void paint_month(Calendar *, Tick, XRectangle *);
122 static void unmanage_children(Calendar *);
123 static void manage_children(Calendar *);
124 static int count_month_appts(CSA_entry_handle *, int, Calendar *);
133 CalTextExtents(pf, "1", 1, &nop, &nop, &width, &nop);
146 CSA_uint32 appt_total,
150 int i, loop, nlines = 0, maxchars;
151 Calendar *c=calendar;
152 Props *p = (Props*)c->properties;
153 DisplayType dt = get_int_prop(p, CP_DEFAULTDISP);
156 new_XContext *xc = c->xcontext;
157 Cal_Font *pf = c->fonts->viewfont;
158 XFontSetExtents fontextents;
161 Tick lower = lowerbound(day);
162 Tick upper = next_ndays(day, 1);
164 CalFontExtents(pf, &fontextents);
165 pfy = fontextents.max_ink_extent.height;
168 /* loop thru the list of appointments twice, first displaying
169 the no time appointments, and then the appointments with times
172 for (loop = 0; loop < 2; loop++) {
173 for (i = 0; i < appt_total; i++) {
174 start_tick = cache[i].start_time;
175 if (start_tick >= lower &&
176 start_tick < upper &&
177 (loop == cache[i].show_time)) {
178 if (nlines < maxlines) {
180 static int pad_width = 0;
183 text_to_lines(cache[i].summary, 1);
186 cm_strlen(lines->s) + 18);
187 pad = format_line(start_tick,
195 pad = format_line(start_tick,
201 destroy_lines(lines); lines=NULL;
205 compute_pad_width(pf);
208 maxchars = gr_nchars(
211 if (cm_strlen(buf) > maxchars)
212 buf[maxchars] = NULL;
213 (void)gr_text(xc, x + pad_width,
216 maxchars = gr_nchars(w, buf,
218 if (cm_strlen(buf) > maxchars)
219 buf[maxchars] = NULL;
220 (void)gr_text(xc, x, y, pf,
235 month_button(Widget widget, XtPointer data, XtPointer cbs)
237 Calendar *c = calendar;
239 if (c->view->glance == monthGlance)
242 XtUnmapWidget(c->canvas);
244 switch (c->view->glance) {
246 c->view->glance = monthGlance;
247 cleanup_after_dayview(c);
250 c->view->glance = monthGlance;
251 cleanup_after_weekview(c);
254 cleanup_after_yearview(c);
255 c->view->glance = monthGlance;
260 prepare_to_paint_monthview (c, NULL);
262 XtMapWidget(c->canvas);
266 * Do the actual month grid, headers and appointments
269 paint_month(Calendar *c, Tick key, XRectangle *rect)
271 Month *m = (Month *)c->view->month_info;
274 int firstdom, boxw, boxh, dayname_height, margin, default_height;
278 Dimension btn_ht=0, btn_w=0;
281 CSA_attribute *range_attrs;
282 CSA_entry_handle *list = NULL;
283 XFontSetExtents fontextents;
284 _Xltimeparams localtime_buf;
286 tm = *_XLocaltime(&key, localtime_buf);
292 day = timelocal(&tm);
294 m->ndays = ((tm.tm_mon==1) && leapyr(tm.tm_year+1900))? 29 :
295 monthdays[tm.tm_mon];
296 tm = *_XLocaltime(&day, localtime_buf);
297 firstdom = tm.tm_wday;
298 boxw = calendar->view->boxw;
299 boxh = calendar->view->boxh;
300 margin = calendar->view->outside_margin;
301 dayname_height = ((Month *) calendar->view->month_info)->dayname_height;
302 xc = calendar->xcontext;
305 if (c->paint_cache == NULL) {
306 start = (time_t) lowerbound(day);
307 stop = (time_t) last_dom(day);
308 setup_range(&range_attrs, &ops, &j, start, stop, CSA_TYPE_EVENT,
309 NULL, B_FALSE, c->general->version);
310 csa_list_entries(c->cal_handle, j, range_attrs, ops, &a_total, &list, NULL);
312 free_range(&range_attrs, &ops, j);
313 allocate_paint_cache(list, a_total, &c->paint_cache);
314 c->paint_cache_size = a_total;
318 CalFontExtents(c->fonts->viewfont, &fontextents);
319 default_height = fontextents.max_logical_extent.height;
322 for(i = 1; i <= m->ndays; i++) {
323 int box_origin_x=0, box_origin_y=0;
325 box_origin_x = (x * boxw) + margin;
326 box_origin_y = (y * boxh) + dayname_height + c->view->topoffset;
328 XtVaGetValues(m->hot_button[i-1], XmNheight, &btn_ht,
329 XmNwidth, &btn_w, NULL);
332 * Paint the list of calendar entries for this day
334 paint_day_entries(day,
336 box_origin_y + default_height + btn_ht,
337 boxw - 4, boxh - btn_ht - 4,
338 c->paint_cache, c->paint_cache_size, rect);
342 if (x > 6 & i != m->ndays) {
350 * Set the label header for the view to current month name
353 display_header(Calendar *c)
355 Month *m = (Month *) c->view->month_info;
360 Tick tmptick = c->view->date;
361 _Xltimeparams localtime_buf;
364 tm_ret = _XLocaltime(&tmptick, localtime_buf);
367 Attention Translator:
369 This string is used in the calendar month view. In the C locale
374 strftime conversion string: "%B, %Y" is used.
376 Use the appropriate strftime conversion for your locale.
378 sprintf( buf, "%s, %d", months[tm_ret->tm_mon+1],
379 tm_ret->tm_year + 1900 );
381 str = XmStringCreateLocalized(buf);
382 XtVaSetValues(m->month_label, XmNlabelString, str, NULL);
386 x = c->view->outside_margin; y = 15;
387 XtVaSetValues(m->month_label, XtNx, x, XtNy, y, NULL);
390 if (!XtIsManaged(m->month_label)) {
391 XtManageChild(m->month_label);
396 paint_daynames(Calendar *c, XRectangle *rect)
399 int boxw = c->view->boxw;
400 int margin = c->view->outside_margin;
402 ((Month *)c->view->month_info)->dayname_height;
403 Cal_Font *pf = c->fonts->viewfont;
404 new_XContext *xc = c->xcontext;
406 for(i = 0; i < 7; i++) {
407 gr_draw_box(xc, (boxw * i)+margin,
409 boxw, dayname_height, rect);
410 middle = gr_center(boxw, days[i], pf);
411 gr_text(xc, (boxw*i)+middle+margin,
412 c->view->topoffset+dayname_height-3,
418 paint_grid(Calendar *c, XRectangle *rect)
421 int boxh = c->view->boxh;
422 int boxw = c->view->boxw;
423 int nrows = c->view->nwks;
424 int margin = c->view->outside_margin;
425 int dayname_height = ((Month *)c->view->month_info)->dayname_height;
426 int rightmargin = margin + 7 * boxw;
427 int bottomargin = c->view->topoffset+ dayname_height+boxh*nrows;
428 new_XContext *xc = c->xcontext;
431 for (i = 1; i <= nrows; i++) {
432 gr_draw_line(xc, margin,
433 (i*boxh)+c->view->topoffset+dayname_height,
434 rightmargin, i*boxh+c->view->topoffset+dayname_height,
439 for (i = 0; i < 8; i++) {
440 gr_draw_line(xc, margin+(i*boxw),
441 c->view->topoffset+dayname_height,
442 margin+(i*boxw), bottomargin, gr_solid, rect);
444 /* embolden grid outline */
445 gr_draw_box(xc, margin-1,
446 c->view->topoffset-1, 7*boxw+2,
447 nrows*boxh+2+dayname_height, rect);
455 Month *m = (Month *)c->view->month_info;
458 boxw = calendar->view->boxw,
459 boxh = calendar->view->boxh,
460 margin = calendar->view->outside_margin,
461 dayname_height = m->dayname_height;
464 _Xltimeparams localtime_buf;
466 tm = *_XLocaltime(&date, localtime_buf);
472 day = timelocal(&tm);
474 m->ndays = ((tm.tm_mon==1) &&
475 leapyr(tm.tm_year+1900))? 29 : monthdays[tm.tm_mon];
476 tm = *_XLocaltime(&day, localtime_buf);
477 firstdom = tm.tm_wday;
481 for(i = 1; i <= m->ndays; i++) {
482 int box_origin_x = 0,
485 box_origin_x = (x * boxw) + margin;
486 box_origin_y = (y * boxh) + dayname_height + c->view->topoffset;
488 m->button_loc[i-1].x = box_origin_x + 3;
489 m->button_loc[i-1].y = box_origin_y + 3;
492 if (x > 6 & i != m->ndays) {
496 XtMoveWidget(m->hot_button[i-1],
497 m->button_loc[i-1].x, m->button_loc[i-1].y);
500 /* Unmanage any unneeded navigator buttons (ie. 29, 30, 31) */
501 for (i=m->ndays; i<31; i++)
502 if (XtIsManaged(m->hot_button[i]))
503 XtUnmanageChild(m->hot_button[i]);
507 repaint_damaged_month(
511 /* allocate Month memory & widgets if necessary */
513 XFontSetExtents boldfontextents;
516 XmToggleButtonGadgetSetState(c->month_scope, True, False);
517 CalFontExtents(c->fonts->boldfont, &boldfontextents);
518 ((Month *) c->view->month_info)->dayname_height =
519 boldfontextents.max_logical_extent.height + 6;
520 layout_month(c, c->view->date);
525 paint_daynames(c, rect);
527 paint_month(c, c->view->date, rect);
528 calendar_select(c, daySelect, (caddr_t)NULL);
532 prepare_to_paint_monthview(Calendar *c, XRectangle *rect)
537 XmToggleButtonGadgetSetState(c->month_scope, True, False);
538 XtVaGetValues(c->canvas, XmNwidth, &w, XmNheight, &h, NULL);
541 /* allocate Month memory & widgets if necessary */
543 XFontSetExtents boldfontextents;
546 CalFontExtents(c->fonts->boldfont, &boldfontextents);
547 ((Month *) c->view->month_info)->dayname_height =
548 boldfontextents.max_logical_extent.height + 6;
552 * need to unmanage buttons while drawing to avoid many exposures
553 * when they are moved
556 layout_month(c, c->view->date);
557 gr_clear_area(c->xcontext, 0, 0, c->view->winw, c->view->winh);
561 /* ADDED FOR PRINTING */
563 get_time_str (Dtcm_appointment *appt, char *buf)
565 Calendar *c = calendar;
566 Props *p = (Props*)c->properties;
567 DisplayType dt = get_int_prop(p, CP_DEFAULTDISP);
571 _Xltimeparams localtime_buf;
573 _csa_iso8601_to_tick(appt->time->value->item.date_time_value, &start_tick);
576 if (appt==NULL || !showtime_set(appt) || magic_time(start_tick))
579 tm = _XLocaltime(&start_tick, localtime_buf);
585 (void) sprintf(buf, "%2d:%02d ", hr, mn);
588 (void) sprintf(buf, "%02d%02d ", hr, mn);
592 month_event(XEvent *event)
594 static int lastcol, lastrow;
595 static XEvent lastevent;
596 int x, y, j, toffset;
597 int boxw, boxh, row, col, margin, dayname_height;
599 Calendar *c = calendar;
600 Editor *e = (Editor*)c->editor;
601 ToDo *t = (ToDo*)c->todo;
602 GEditor *ge = (GEditor*)c->geditor;
604 boxw = c->view->boxw;
605 boxh = c->view->boxh;
606 margin = c->view->outside_margin;
607 dayname_height = ((Month *) c->view->month_info)->dayname_height;
608 date = c->view->date;
609 x = event->xbutton.x;
610 y = event->xbutton.y;
611 toffset = c->view->topoffset;
616 col = (x-margin)/boxw;
620 row = (y-c->view->topoffset-dayname_height)/boxh;
622 /* boundary conditions */
623 if (x < margin || col > 6 || y < (dayname_height+toffset) || row > c->view->nwks-1) {
624 calendar_deselect(c);
625 lastcol=0; lastrow=0;
629 /* boundary check for click in invalid cell */
630 if (((col < fdom(date)) && (row==0)) ||
631 ((col > ldom(date)) && (row==c->view->nwks - 1))) {
632 calendar_deselect(c);
633 lastcol=0; lastrow=0;
637 switch(event->type) {
639 if (col !=lastcol || row !=lastrow) {
640 calendar_deselect(c);
641 j = xytoclock(col+1, row+1, date);
643 c->view->olddate = c->view->date;
645 calendar_select(c, daySelect, (caddr_t)NULL);
652 if (ds_is_double_click(&lastevent, event)) {
653 _DtTurnOnHourGlass(c->frame);
654 if (lastcol == col && lastrow == row)
655 show_editor(c, 0, 0, False);
656 _DtTurnOffHourGlass(c->frame);
659 calendar_deselect(c);
660 j = xytoclock(col+1, row+1, date);
662 c->view->olddate = c->view->date;
664 calendar_select(c, daySelect, (caddr_t)NULL);
667 if (editor_showing(e)) {
668 set_editor_defaults(e, 0, 0, False);
672 if (todo_showing(t)) {
673 set_todo_defaults(t);
676 if (geditor_showing(ge)) {
677 set_geditor_defaults(ge, 0, 0);
690 count_month_pages(Calendar *c, Tick start_date, int lines_per_box)
695 int day, ndays, num_appts, max = 0;
698 CSA_entry_handle *list;
699 CSA_attribute *range_attrs;
701 _Xltimeparams localtime_buf;
703 tm = *_XLocaltime(&start_date, localtime_buf);
707 day = (int)mktime(&tm);
709 day = (int)timelocal(&tm);
711 ndays = ((tm.tm_mon==1) && leapyr(tm.tm_year+1900))? 29 :
712 monthdays[tm.tm_mon];
714 /* print days of the week at the top */
715 rows = numwks (start_date);
717 /* need minimum 5 rows to paint miniature months */
718 if (rows == 4) rows++;
720 /* print the times and text of appts */
721 for (i = 1; i <= ndays; i++)
723 /* setup a time limit for appts searched */
724 start = (time_t) lowerbound (day);
725 stop = (time_t) next_ndays(day, 1) - 1;
726 setup_range(&range_attrs, &ops, &j, start, stop,
727 CSA_TYPE_EVENT, NULL, B_FALSE,
728 c->general->version);
729 csa_list_entries(c->cal_handle, j, range_attrs, ops,
730 &a_total, &list, NULL);
731 free_range(&range_attrs, &ops, j);
733 num_appts = count_month_appts(list, a_total, c);
742 pages = max / lines_per_box;
743 if ((max % lines_per_box) > 0)
751 print_month ( Calendar *c,
758 int rows, i, j, lines_per_box;
759 time_t lo_hour, hi_hour;
761 int ndays, num_appts;
762 Boolean more, done = False, all_done = True;
764 OrderingType ot = get_int_prop(p, CP_DATEORDERING);
765 CSA_entry_handle *list;
766 CSA_attribute *range_attrs;
769 static Tick tick = 0;
770 static int total_pages;
775 tick = prevmonth_exactday(tick);
777 /* print days of the week at the top */
778 rows = numwks (tick);
780 /* need minimum 5 rows to paint miniature months */
781 if (rows == 4) rows++;
783 x_init_printer(xp, LANDSCAPE);
784 x_init_month(xp, rows);
785 lines_per_box = x_get_month_lines_per_page(xp);
788 total_pages = (lines_per_box > 0) ?
789 count_month_pages(c, tick, lines_per_box) : 1;
791 day = first_dom(tick);
792 ndays = monthlength(tick);
794 /* print month & year on top */
795 format_date(tick, ot, buf, 0, 0, 0);
797 x_print_header(xp, buf, num_page, total_pages);
798 x_month_daynames(xp, rows);
800 /* print the times and text of appts */
801 for (i = 1; i <= ndays; i++)
803 /* setup a time limit for appts searched */
804 lo_hour = (time_t)lowerbound (day);
805 hi_hour = (time_t) next_ndays(day, 1) - 1;
806 setup_range(&range_attrs, &ops, &j, lo_hour, hi_hour,
807 CSA_TYPE_EVENT, NULL, B_FALSE, c->general->version);
808 csa_list_entries(c->cal_handle, j, range_attrs,
809 ops, &a_total, &list, NULL);
810 free_range(&range_attrs, &ops, j);
811 num_appts = count_month_appts(list, a_total, c);
812 if ((lines_per_box > 0) &&
813 (num_appts > (lines_per_box * num_page)))
818 x_month_timeslots(xp, day, more);
820 /* print out times and appts */
821 if (lines_per_box > 0)
822 done = x_print_month_appts(xp, list, a_total, num_page,
823 hi_hour, lines_per_box);
833 /* paint miniature previous & next month */
834 x_print_little_months(xp, tick);
835 x_finish_printer(xp);
837 tick = nextmonth(tick);
843 print_month_range(Calendar *c, Tick start_tick, Tick end_tick)
845 Props *p = (Props *)c->properties;
846 register Tick end, first_date = start_tick;
848 Boolean done = False, first = True;
850 void *xp = (void *)NULL;
852 /* counting up the month pages is a little trickier than in the day
853 and week cases. Months will have variable numbers of seconds in
854 them, simple dividing the difference by the number of seconds
855 per month doesn't work. We'll brute force this by grinding thru,
856 adding seconds until we pass the end tick time. */
858 end_tick = last_dom(end_tick);
859 end = last_dom(start_tick);
860 for (n = 1; end < end_tick; n++)
861 end = last_dom(nextmonth(end));
863 if ((xp = x_open_file(c)) == (void *)NULL)
870 done = print_month(c, num_page, xp,
871 first_date, p, first);
884 count_month_appts(CSA_entry_handle *list, int a_total, Calendar *c)
886 int count = 0, i, meoval;
887 Props *pr = (Props*)c->properties;
888 Dtcm_appointment *appt;
889 CSA_return_code stat;
891 meoval = get_int_prop(pr, CP_PRINTPRIVACY);
893 appt = allocate_appt_struct(appt_read,
895 CSA_ENTRY_ATTR_CLASSIFICATION_I,
897 for (i = 0; i < a_total; i++) {
899 stat = query_appt_struct(c->cal_handle, list[i], appt);
900 if (stat != CSA_SUCCESS) {
901 free_appt_struct(&appt);
905 if ((privacy_set(appt) == CSA_CLASS_PUBLIC) && !(meoval & PRINT_PUBLIC))
907 else if ((privacy_set(appt) == CSA_CLASS_CONFIDENTIAL) && !(meoval & PRINT_SEMIPRIVATE))
909 else if ((privacy_set(appt) == CSA_CLASS_PRIVATE) && !(meoval & PRINT_PRIVATE))
915 free_appt_struct(&appt);
920 * Handler for "hot" buttons to navigate to day view
921 * Client data is index of activated button [0..30]
924 quick_button_cb(Widget widget, XtPointer client, XtPointer call)
926 Calendar *c = calendar;
927 int dom = (int) client;
929 c->view->olddate = c->view->date;
930 c->view->date = next_ndays(first_dom(c->view->date), dom);
932 calendar_select(c, daySelect, NULL);
934 cleanup_after_monthview(c);
936 c->view->glance = dayGlance;
938 (void)init_dayview(c);
944 * Handle positioning and managing of hotbuttons
946 * IMPORTANT: This function assumes that it is being called during the
947 * Resize method of the canvas (XmDrawingArea), and for that reason
948 * it is effectively widget code and can legally call XtMoveWidget.
949 * Don't try this at home ! (and never from non-widget code)
951 * Also, this needs to be called *after* paint_month, as it relies on data
952 * calculated there and stores in the month data structure.
955 layout_children(Calendar *c)
957 Month *m = (Month *)c->view->month_info;
958 Widget *btns = m->hot_button;
961 /* Position required navigator buttons - note that if they're
962 mapped when this happens, many exposes will occur */
963 for (i=0; i < m->ndays; i++)
964 XtMoveWidget(btns[i], m->button_loc[i].x, m->button_loc[i].y);
966 /* Unmanage any unneeded navigator buttons (ie. 29, 30, 31) */
967 for (i=m->ndays; i<31; i++)
968 if (XtIsManaged(m->hot_button[i]))
969 XtUnmanageChild(m->hot_button[i]);
973 manage_children(Calendar *c)
976 Month *m = (Month *)c->view->month_info;
978 /* manage the header widget */
979 XtManageChild(m->month_label);
980 XtManageChildren(m->hot_button, m->ndays);
984 unmanage_children(Calendar *c)
987 Month *m = (Month *)c->view->month_info;
989 /* unmanage the header widget */
990 XtUnmanageChild(m->month_label);
991 XtUnmanageChildren(m->hot_button, 31);
995 * Clean up anything left around that won't be removed on
996 * switching to another view, such as the hot buttons for
997 * navigation to day view.
1000 cleanup_after_monthview(Calendar *c)
1003 invalidate_cache(c);
1005 XtUnmapWidget(c->canvas);
1006 unmanage_children(c);
1008 XmToggleButtonGadgetSetState(c->month_scope, False, False);
1011 * Deallocating everything causes all this view's memory to be
1012 * freed (at least all we have allocated in this application)
1013 * at the expense of rebuilding the view next time it is used.
1014 * Commenting it out improves usability and avoids any risk
1015 * of memory leakage from Xt and Motif.
1021 XtMapWidget(c->canvas);
1025 * check whether month view is allocated yet
1028 allocated(Calendar *c)
1030 return (c->view->month_info != NULL);
1034 * allocate storage & subwidgets used by month view
1036 allocator(Calendar *c)
1043 /* main storage for other month data */
1044 calendar->view->month_info = (caddr_t) ckalloc(sizeof(Month));
1045 m = (Month *)c->view->month_info;
1047 m->button_loc = (XPoint *) ckalloc(31 * sizeof(XPoint));
1049 /* label for month & navigation button to year */
1050 m->month_label = XmCreateLabel(c->canvas, "monthLabel", NULL, 0);
1052 /* navigation buttons to day view */
1053 m->hot_button = (Widget *) ckalloc(31 * sizeof(Widget));
1054 for (n=0; n<31; n++) {
1055 sprintf(buf, "%d", n+1);
1056 str = XmStringCreateLocalized(buf);
1057 sprintf(buf, "month2day%d", n);
1059 XmCreatePushButton(c->canvas, buf, NULL, 0);
1060 XtVaSetValues(m->hot_button[n], XmNlabelString, str, NULL);
1061 XtAddCallback(m->hot_button[n],XmNactivateCallback,
1062 quick_button_cb, (XtPointer)n);
1069 * allocate storage & subwidgets used by month view
1072 deallocator(Calendar *c)
1074 Month *m = (Month *)c->view->month_info;
1077 /* free cache of points for buttons positions */
1078 free(m->button_loc);
1080 /* destroy widgets used for header */
1081 XtDestroyWidget(m->month_label);
1084 for (n=0; n<31; n++)
1085 XtDestroyWidget(m->hot_button[n]);
1087 /* array that held navigation buttons */
1088 free(m->hot_button);
1090 /* structure holding month information */
1092 c->view->month_info = NULL;