Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / dtcm / dtcm / dayglance.c
1 /*******************************************************************************
2 **
3 **  dayglance.c
4 **
5 **  $XConsortium: dayglance.c /main/10 1996/11/21 19:42:19 drk $
6 **
7 **  RESTRICTED CONFIDENTIAL INFORMATION:
8 **
9 **  The information in this document is subject to special
10 **  restrictions in a confidential disclosure agreement between
11 **  HP, IBM, Sun, USL, SCO and Univel.  Do not distribute this
12 **  document outside HP, IBM, Sun, USL, SCO, or Univel without
13 **  Sun's specific written approval.  This document and all copies
14 **  and derivative works thereof must be returned or destroyed at
15 **  Sun's request.
16 **
17 **  Copyright 1993 Sun Microsystems, Inc.  All rights reserved.
18 **
19 *******************************************************************************/
20
21 /*                                                                      *
22  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
23  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
24  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
25  * (c) Copyright 1993, 1994 Novell, Inc.                                *
26  */
27
28 #ifndef lint
29 static char sccsid[] = "@(#)dayglance.c 1.76 95/04/24 Copyr 1991 Sun Microsystems, Inc.";
30 #endif
31
32 #include <EUSCompat.h>
33 #include <stdio.h>
34 #include <Xm/Xm.h>
35 #include <Xm/Form.h>
36 #include <Xm/Text.h>
37 #include <Xm/ToggleBG.h>
38 #include <Dt/HourGlass.h>
39 #include "util.h"
40 #include "stdlib.h"
41 #include "calendar.h"
42 #include "timeops.h"
43 #include "datefield.h"
44 #include "props.h"
45 #include "help.h"
46 #include "x_graphics.h"
47 #include "format.h"
48 #include "weekglance.h"
49 #include "monthglance.h"
50 #include "yearglance.h"
51 #include "MonthPanel.h"
52 #include "getdate.h"
53 #include "select.h"
54 #include "dayglance.h"
55 #include "editor.h"
56 #include "todo.h"
57 #include "print.h"
58 #include "group_editor.h"
59
60 #define XOS_USE_XT_LOCKING
61 #define X_INCLUDE_TIME_H
62 #include <X11/Xos_r.h>
63
64 extern int debug;
65
66
67 /* private function prototypes */
68 static Boolean _print_day(Calendar*, int, void *,
69                           Tick, Props*, Boolean);
70 static void day_btn_cb(Widget, XtPointer, XtPointer);
71 static void create_month_panels(Calendar *);
72 static void display_monthpanels(Calendar *);
73 static void update_quarter(Calendar *);
74 static Boolean in_moboxes(Calendar *, int, int);
75
76 #define INSIDE_MARGIN 6
77
78 extern void
79 paint_day_header(Calendar *c, Tick date, void *rect)
80 {
81         Props *p = (Props*)c->properties;
82         OrderingType ot = get_int_prop(p, CP_DATEORDERING);
83         int pfy, x;
84         char buf[100];
85         Boolean inrange = False;
86         Colormap cmap;
87         Pixel foreground_pixel;
88         XFontSetExtents fontextents;
89         struct tm *tm;
90         _Xltimeparams localtime_buf;
91
92         tm = _XLocaltime(&date, localtime_buf);
93
94         CalFontExtents(c->fonts->labelfont, &fontextents);
95         pfy = fontextents.max_logical_extent.height;
96         XtVaGetValues(c->canvas, XmNcolormap, &cmap, NULL);
97         XtVaGetValues(c->canvas, XmNforeground, &foreground_pixel, NULL);
98         buf [0] = '\0';
99         /* NL_COMMENT
100            Attention Translator:
101
102            This string is used in the calendar day view.  In the C locale
103            it has the form:
104
105                 Monday, January 16, 1995
106
107            strftime conversion string: "%A, %B %e, %Y" is used.  
108
109            Use the appropriate strftime conversion for your locale.
110         */
111         strftime(buf, 100, catgets(c->DT_catd, 1, 992, "%A, %B %e, %Y"), tm);
112         inrange = today_inrange(c, date);
113         x = gr_center(c->view->winw-(int)MOBOX_AREA_WIDTH, buf,
114                         c->fonts->labelfont) + (int)MOBOX_AREA_WIDTH;
115         if (c->xcontext->screen_depth >= 8 && inrange) 
116                 gr_text_rgb(c->xcontext, x, c->view->topoffset - (pfy/2),
117                         c->fonts->labelfont, buf, foreground_pixel, 
118                         cmap, rect);
119         else
120                 gr_text(c->xcontext, x, c->view->topoffset - (pfy/2),
121                         c->fonts->labelfont, buf, rect);
122 }
123         
124 extern int
125 morning(int hr)
126 {
127         return(hr<12);
128 }
129
130 static void
131 paint_dayview_appts(Calendar *c, Paint_cache *cache, int a_total, void *rect)
132 {
133         int w = c->view->boxw;
134         int h = c->view->boxh;
135         int begin_time, end_time;
136         int x, x2, y, y2, num_hrs, i, last_hr, hr, x_off;
137         Cal_Font *pf = c->fonts->boldfont;
138         Cal_Font *pf2 = c->fonts->viewfont;
139         XFontSetExtents fontextents;
140         XFontSetExtents fontextents2;
141         Props *p = (Props*)c->properties;
142         Boolean am = True;
143         char buf[5], *appt_str;
144         int pfy, curr_line, maxlines;
145         Lines *lines = NULL, *headlines = NULL;
146         DisplayType disp_t;
147         Colormap cmap;
148         Pixel fg;
149         Tick start_tick, end_tick;
150         int     nop, hrbox_margin;
151
152         CalFontExtents(pf, &fontextents);
153         CalFontExtents(pf2, &fontextents2);
154
155
156         XtVaGetValues(c->canvas, XmNcolormap, &cmap, XmNforeground, &fg, NULL);
157
158         /* draw horizontal lines */
159         begin_time = get_int_prop(p, CP_DAYBEGIN);
160         end_time = get_int_prop(p, CP_DAYEND);
161         disp_t = get_int_prop(p, CP_DEFAULTDISP);
162         num_hrs = end_time - begin_time + 1;
163
164         if (disp_t == HOUR12)
165                 CalTextExtents(pf, "12pm", 4, &nop, &nop, &hrbox_margin, &nop);
166         else
167                 CalTextExtents(pf, "24 ", 3, &nop, &nop, &hrbox_margin, &nop);
168
169         x = MOBOX_AREA_WIDTH+2;
170         x2 = x + w;
171         y = c->view->topoffset;
172         for (i = 0; i <= num_hrs; i++) {
173                 gr_draw_line(c->xcontext, x, y, x2, y, gr_solid, rect);
174                 y += h;
175         }
176         /* draw vertical line */
177         y = c->view->topoffset;
178         y2 = y + num_hrs * h;
179         x += hrbox_margin;
180         gr_draw_line(c->xcontext, x, y, x, y2, gr_solid, rect);
181
182         x = MOBOX_AREA_WIDTH+3;
183         y += h/2+4;
184
185         /* draw in hours */
186         for (i = begin_time - 1; i < end_time; i++) {
187                 hr = i;
188                 if (i < begin_time)
189                         (void) sprintf(buf, "");
190                 else if (disp_t == HOUR12) {
191                         am = adjust_hour(&hr);
192                         (void) sprintf(buf, "%d%s", hr, am ? "a" : "p");
193                 }
194                 else
195                         (void) sprintf(buf, "%02d", hr);
196                 x_off = gr_center(hrbox_margin, buf, pf); 
197
198 /* REVISIT: unclear why we're still distinguishing between gr_text[_rgb]
199                 if (c->xcontext->screen_depth >= 8) 
200                         gr_text_rgb(c->xcontext, x+x_off, y, pf,
201                                 buf, fg, cmap, rect);
202                 else
203 */
204                         gr_text(c->xcontext, x+x_off, y, pf, buf, rect);
205
206                 y += h;
207         }
208
209         /* draw in appointments */
210
211         x = MOBOX_AREA_WIDTH + hrbox_margin + 6;
212         pfy = fontextents2.max_logical_extent.height;
213
214         maxlines = (h - 6) / pfy;
215         curr_line = last_hr = 0;
216
217         /* loop thru, getting out the "no time" appointments */
218
219         for (i = 0; i < a_total; i++) {
220                 if (i != a_total)
221                         last_hr = hr;
222                 hr = begin_time;
223                 if (cache[i].show_time == 0) {
224                         if (last_hr != hr) curr_line = 0;
225                         y = c->view->topoffset + 2 + pfy;
226                         if (curr_line < maxlines) {
227                                 y += (curr_line * pfy) + h * (hr - begin_time);
228                                 headlines = lines = text_to_lines(cache[i].summary, 4);
229
230                                 start_tick = cache[i].start_time;
231                                 end_tick = cache[i].end_time;
232                                 if (lines != NULL && lines->s != NULL) { 
233                                         appt_str = ckalloc(cm_strlen(lines->s)+18);
234                                         format_line(start_tick, lines->s, 
235                                                 appt_str, end_tick, 
236                                                 cache[i].show_time, disp_t);
237                                         lines = lines->next;
238                                 }
239                                 else {
240                                         appt_str = ckalloc(15);
241                                         format_line(start_tick, (char*)NULL, 
242                                                 appt_str, end_tick, 
243                                                 cache[i].show_time, disp_t);
244                                 }
245                                 appt_str[cm_strlen(appt_str)]=NULL;
246
247 /* REVISIT: unclear why we're still distinguishing between gr_text[_rgb]
248                                 if (c->xcontext->screen_depth >= 8) 
249                                         gr_text_rgb(c->xcontext, x, y,
250                                            pf2, appt_str, fg, cmap, rect);
251                                 else
252 */
253                                         gr_text(c->xcontext, x, y,
254                                            pf2, appt_str, rect);
255
256                                 free(appt_str); appt_str = NULL;
257                                 curr_line++;
258                                 if (curr_line < maxlines && lines != NULL) {
259                                         appt_str = ckalloc(324);
260                                         cm_strcpy(appt_str, "    ");
261                                         while (lines != NULL) { 
262                                                 if (lines->s != NULL) 
263                                                         cm_strcat(appt_str, lines->s);
264                                                 lines = lines->next;
265                                                 if (lines != NULL && lines->s != NULL)
266                                                         cm_strcat(appt_str, " - ");
267                                         }
268                                         y += pfy;
269
270 /* REVISIT: unclear why we're still distinguishing between gr_text[_rgb]
271
272                                         if (c->xcontext->screen_depth >= 8) 
273                                                 gr_text_rgb(c->xcontext, x, y,
274                                                    pf2, appt_str, fg,
275                                                    cmap, rect);
276                                         else
277 */
278                                                 gr_text(c->xcontext, x, y,
279                                                    pf2, appt_str, rect);
280
281                                         curr_line++;
282                                         free(appt_str); appt_str = NULL;
283                                 }
284                                 destroy_lines(headlines); lines=NULL;
285                         }
286                 }
287         }
288
289         for (i = 0; i < a_total; i++) {
290                 if (i != a_total)
291                         last_hr = hr;
292
293                 start_tick = cache[i].start_time;
294                 end_tick = cache[i].end_time;
295                 hr = hour(start_tick);
296                 if (hr >= begin_time && hr < end_time && (cache[i].show_time && !magic_time(start_tick))) {
297                         if (last_hr != hr) curr_line = 0;
298                         y = c->view->topoffset + 2 + pfy;
299                         if (curr_line < maxlines) {
300                                 y += (curr_line * pfy) + h * (hr - begin_time + 1);
301                                 headlines = lines = text_to_lines(cache[i].summary, 4);
302                                 if (lines != NULL && lines->s != NULL) { 
303                                         appt_str = ckalloc(cm_strlen(lines->s)+18);
304                                         format_line(start_tick, lines->s, 
305                                                 appt_str, end_tick, 
306                                                 cache[i].show_time, disp_t);
307                                         lines = lines->next;
308                                 }
309                                 else {
310                                         appt_str = ckalloc(15);
311                                         format_line(start_tick, (char*)NULL, 
312                                                 appt_str, end_tick, 
313                                                 cache[i].show_time, disp_t);
314                                 }
315                                 appt_str[cm_strlen(appt_str)]=NULL;
316
317 /* REVISIT: unclear why we're still distinguishing between gr_text[_rgb]
318                                 if (c->xcontext->screen_depth >= 8) 
319                                         gr_text_rgb(c->xcontext, x, y,
320                                            pf2, appt_str, fg, cmap, rect);
321                                 else
322 */
323                                         gr_text(c->xcontext, x, y,
324                                            pf2, appt_str, rect);
325
326                                 free(appt_str); appt_str = NULL;
327                                 curr_line++;
328                                 if (curr_line < maxlines && lines != NULL) {
329                                         appt_str = ckalloc(324);
330                                         cm_strcpy(appt_str, "    ");
331                                         while (lines != NULL) { 
332                                                 if (lines->s != NULL) 
333                                                         cm_strcat(appt_str, lines->s);
334                                                 lines = lines->next;
335                                                 if (lines != NULL && lines->s != NULL)
336                                                         cm_strcat(appt_str, " - ");
337                                         }
338                                         y += pfy;
339
340 /* REVISIT: unclear why we're still distinguishing between gr_text[_rgb]
341
342                                         if (c->xcontext->screen_depth >= 8) 
343                                                 gr_text_rgb(c->xcontext, x, y,
344                                                    pf2, appt_str, fg,
345                                                    cmap, rect);
346                                         else 
347 */
348                                                 gr_text(c->xcontext, x, y,
349                                                    pf2, appt_str, rect);
350
351                                         curr_line++;
352                                         free(appt_str); appt_str = NULL;
353                                 }
354                                 destroy_lines(headlines); lines=NULL;
355                         }
356                 }
357         }
358 }
359
360 extern void
361 init_mo(Calendar *c)
362 {
363         Day *day_info = (Day *)c->view->day_info;
364         day_info->month1 = previousmonth(c->view->date);
365         day_info->month2 = c->view->date;
366         day_info->month3 = nextmonth(c->view->date);
367 }
368
369 extern void 
370 init_dayview(Calendar *c)
371 {
372         int  tot_rows, wks_1, wks_2, wks_3;
373         Dimension w, h;
374         Day *day_info = (Day *) c->view->day_info;
375
376         /*
377          * Create month panels if they're not already there
378          */
379         if (day_info->month_panels == (Widget *) NULL) {
380                 day_info->month_panels = (Widget *)ckalloc(3 * sizeof(Widget));
381
382                 create_month_panels(c);
383         }
384
385
386         XtVaGetValues(c->canvas, XmNwidth, &w, XmNheight, &h, NULL);
387         (void)cache_dims(c, w, h);
388
389         day_info->day_selected = -1;
390         day_info->mobox_width = (int)MOBOX_AREA_WIDTH - 
391                         2*c->view->outside_margin;
392         /* col width of day number in month boxes */
393         day_info->col_w = 
394                 (day_info->mobox_width-INSIDE_MARGIN*2)/7;
395         /* width of all of the month boxes */
396         day_info->mobox_width = 7 * day_info->col_w + 
397                         2 * INSIDE_MARGIN;
398
399         wks_1 = numwks(day_info->month1);
400         wks_2 = numwks(day_info->month2);
401         wks_3 = numwks(day_info->month3); 
402         /* total rows in three months */ 
403         tot_rows = wks_1 + wks_2 + wks_3 + 3; 
404
405         /* row height of day number in month boxes */
406         day_info->row_h = (c->view->winh - 3*c->view->topoffset-c->view->outside_margin) 
407                         / tot_rows;
408
409         /* height of 1st month */
410         day_info->mobox_height1 = day_info->row_h * 
411                         (wks_1+1)+1;
412         /* height of 2nd month */
413         day_info->mobox_height2 = day_info->row_h * 
414                         (wks_2+1)+1;
415         /* height of 2rd month */
416         day_info->mobox_height3 = day_info->row_h * 
417                         (wks_3+1)+1;
418
419         day_info->month1_y = c->view->topoffset;
420         day_info->month2_y = 2*c->view->topoffset + 
421                         day_info->mobox_height1; 
422         day_info->month3_y = 3*c->view->topoffset + 
423                         day_info->mobox_height1 +
424                         day_info->mobox_height2;
425         ((Selection*)(c->view->current_selection))->row = 0;
426 }
427
428 extern void
429 monthbox_xytodate(Calendar *c, int x, int y)
430 {
431         char str[5];
432         Day *day_info = (Day *)c->view->day_info;
433         XFontSetExtents fontextents;
434         int pfy;
435         int col_w = day_info->col_w;
436         int row_h = day_info->row_h;
437         int row, col, x_off;
438         int day_selected, tmpx;
439
440         CalFontExtents(c->fonts->labelfont, &fontextents);
441         pfy = fontextents.max_ink_extent.height;
442
443         col = (x-c->view->outside_margin-INSIDE_MARGIN) / col_w;
444         if (col < 0) return;
445         tmpx = c->view->outside_margin + INSIDE_MARGIN + col * col_w;
446
447         if (y < (day_info->month1_y + 
448                         day_info->mobox_height1)) {
449                 row = (y-day_info->month1_y-row_h) / row_h;
450                 day_selected = (7 * (row+1)) - fdom(day_info->month1)
451                                  - (6 - col);
452                 if (day_selected <= 0 || day_selected >
453                          monthlength(day_info->month1)) 
454                                 return;
455                 day_info->day_selected = day_selected;
456                 day_info->day_selected_y = 
457                         day_info->month1_y + (row+1)*row_h; 
458                 c->view->olddate = c->view->date;
459                 c->view->date = next_ndays(first_dom(day_info->month1),
460                          day_info->day_selected);
461         }
462         else if (y < (day_info->month2_y +
463                         day_info->mobox_height2)) {
464                 row = (y-day_info->month2_y-row_h) / row_h;
465                 day_selected = (7 * (row+1)) - fdom(day_info->month2)
466                                  - (6 - col);
467                 if (day_selected <= 0 || day_selected >
468                          monthlength(day_info->month2)) 
469                                 return;
470                 day_info->day_selected = day_selected;
471                 day_info->day_selected_y = 
472                         day_info->month2_y + (row+1)*row_h; 
473                 c->view->olddate = c->view->date;
474                 c->view->date = next_ndays(first_dom(day_info->month2),
475                          day_info->day_selected);
476         }
477         else if (y < (day_info->month3_y +
478                         day_info->mobox_height3)) {
479                 row = (y-day_info->month3_y-row_h) / row_h;
480                 day_selected = (7 * (row+1)) - fdom(day_info->month3) 
481                                 - (6 - col);
482                 if (day_selected <= 0 || day_selected > 
483                                 monthlength(day_info->month3)) 
484                                 return;
485                 day_info->day_selected = day_selected;
486                 day_info->day_selected_y = 
487                         day_info->month3_y + (row+1)*row_h; 
488                 c->view->olddate = c->view->date;
489                 c->view->date = next_ndays(first_dom(day_info->month3),
490                          day_info->day_selected);
491         }
492         day_info->day_selected_x = tmpx;
493         sprintf(str, "%d", day_info->day_selected);
494         x_off = gr_center(col_w, str, c->fonts->labelfont);
495         day_info->day_selected_x2 =
496                 day_info->day_selected_x+x_off;
497         day_info->day_selected_y2 =
498                 day_info->day_selected_y + pfy;
499
500 }
501
502 extern void
503 monthbox_datetoxy(Calendar *c)
504 {
505         char str[5];
506         int week, x_off, dayw, daym, mo;
507         Day *day_info = (Day *) c->view->day_info;
508         XFontSetExtents fontextents;
509         int pfy;
510         int col_w = day_info->col_w;
511         int row_h = day_info->row_h;
512         struct tm tm;
513         _Xltimeparams localtime_buf;
514
515         CalFontExtents(c->fonts->labelfont, &fontextents);
516         pfy = fontextents.max_logical_extent.height;
517
518         tm = *_XLocaltime(&c->view->date, localtime_buf);
519         mo = tm.tm_mon+1;
520         dayw = tm.tm_wday;
521         daym = tm.tm_mday;
522         week = (12+tm.tm_mday-tm.tm_wday)/7;
523         day_info->day_selected_x = c->view->outside_margin + 
524                         INSIDE_MARGIN + col_w*dayw;
525
526         if (mo == month(day_info->month1)) 
527                 day_info->day_selected_y = 
528                         day_info->month1_y + 
529                         row_h*week;
530         else if (mo == month(day_info->month2))  
531                 day_info->day_selected_y = 
532                         day_info->month2_y + 
533                         row_h*week;
534         else if (mo == month(day_info->month3)) 
535                 day_info->day_selected_y = 
536                         day_info->month3_y + 
537                         row_h*week;
538         sprintf(str, "%d", daym);
539         x_off = gr_center(col_w, str, c->fonts->labelfont);
540         day_info->day_selected_x2 = 
541                         day_info->day_selected_x+x_off;
542         day_info->day_selected_y2 = 
543                         day_info->day_selected_y + pfy;
544         day_info->day_selected = daym;
545 }
546
547 static Boolean
548 in_moboxes(Calendar *c, int x, int y)
549 {
550         int margin = c->view->outside_margin;
551         int topoff = c->view->topoffset;
552         Boolean in_mobox = False;
553         Day *day_info = (Day *)c->view->day_info;
554         int row_h = day_info->row_h;
555
556         if (x < (MOBOX_AREA_WIDTH-margin-2*INSIDE_MARGIN) && 
557                 x > margin && y > topoff && 
558                 ( (y < (day_info->month3_y+
559                         day_info->mobox_height3) &&
560                         y > (day_info->month3_y+row_h)) || 
561                   (y < (day_info->month2_y+
562                         day_info->mobox_height2) &&
563                         y > (day_info->month2_y+row_h)) ||
564                   (y < (day_info->month1_y+
565                         day_info->mobox_height1) &&
566                         y > day_info->month1_y+row_h) ) )
567                 in_mobox = True;
568
569         return in_mobox;
570 }
571
572 extern void
573 paint_dayview(Calendar *c, Boolean repaint, XRectangle *rect, Boolean update_months)
574 {
575         Props           *p = (Props*)c->properties;
576         int             num_hrs;
577         int             beg = get_int_prop(p, CP_DAYBEGIN);
578         int             end = get_int_prop(p, CP_DAYEND);
579         time_t          start, stop;
580         CSA_attribute           *range_attrs;
581         CSA_entry_handle        *list;
582         CSA_enum        *ops;
583         int             i, j;
584         CSA_uint32      a_total;
585         int             panel0_year, panel0_month;
586         int             panel1_year, panel1_month;
587         int             panel2_year, panel2_month;
588         int             year_num, month_num;
589         Boolean         day_not_on_panel = False;
590         Day             *d = (Day *)c->view->day_info;
591         int             top_panel = 0;
592         int             bottom_panel = 2;
593
594         num_hrs = end - beg + 1;
595         if (c->paint_cache == NULL) {
596                 start = (time_t) lower_bound(0, c->view->date);
597                 stop = (time_t) next_nhours(start, end+1) - 1;
598                 setup_range(&range_attrs, &ops, &j, start, stop, CSA_TYPE_EVENT, NULL,
599                         B_FALSE, c->general->version);
600                 csa_list_entries(c->cal_handle, j, range_attrs, ops, &a_total, &list, NULL);
601         
602                 free_range(&range_attrs, &ops, j);
603                 allocate_paint_cache(list, a_total, &c->paint_cache);
604                 c->paint_cache_size = a_total;
605                 csa_free(list);
606         }
607
608         year_num = year(c->view->date);
609         month_num = month(c->view->date);
610         XtVaGetValues(d->month_panels[1],
611                 XmNyear, &panel1_year,
612                 XmNmonth, &panel1_month,
613                 NULL);
614
615         if ((panel1_year == year(get_bot())) && (panel1_month == 1))
616                 top_panel = 1;
617         else if ((panel1_year == year(get_eot())) && (panel1_month == 12))
618                 bottom_panel = 1;
619
620         XtVaGetValues(d->month_panels[top_panel],
621                 XmNyear, &panel0_year,
622                 XmNmonth, &panel0_month,
623                 NULL);
624
625         if ((year_num < panel0_year) || 
626             ((year_num == panel0_year) && (month_num < panel0_month)))
627                 day_not_on_panel = True;
628         
629         XtVaGetValues(d->month_panels[bottom_panel],
630                 XmNyear, &panel2_year,
631                 XmNmonth, &panel2_month,
632                 NULL);
633
634         if ((year_num > panel2_year) || 
635             ((year_num == panel2_year) && (month_num > panel2_month)))
636                 day_not_on_panel = True;
637
638         /* set up month panels */
639         if (update_months || day_not_on_panel)
640                 update_quarter(c);
641
642         /* no need to do this on a damage event */
643
644         if (!rect)
645                 display_monthpanels(c);
646
647         /* repaint appointment area */
648         if (repaint) {
649                 int     line_length;
650
651                 gr_clear_area(c->xcontext, 0, 0, 
652                         c->view->winw, c->view->winh);
653                 line_length = c->view->topoffset + 
654                               ((end - beg + 1) * c->view->boxh);
655                 /* draw line separating mo. boxes and appts. */
656                 gr_draw_line(c->xcontext, (int)MOBOX_AREA_WIDTH+1,
657                          0, (int)MOBOX_AREA_WIDTH+1,
658                          line_length, gr_solid, rect);
659                 gr_draw_line(c->xcontext, (int)MOBOX_AREA_WIDTH+2, 
660                          0, (int)MOBOX_AREA_WIDTH+2,
661                          line_length, gr_solid, rect);
662                 gr_draw_line(c->xcontext, (int)MOBOX_AREA_WIDTH+2, 
663                          c->view->topoffset-1, c->view->winw,
664                          c->view->topoffset-1,  gr_solid, rect);
665                 gr_draw_line(c->xcontext, (int)MOBOX_AREA_WIDTH+2, 
666                          c->view->topoffset, c->view->winw,
667                          c->view->topoffset, gr_solid, rect);
668                 paint_dayview_appts(c, c->paint_cache, c->paint_cache_size, rect);
669         }
670         /* just repaint schedule area */
671         else {
672                 gr_clear_area(c->xcontext, 
673                                 (int)MOBOX_AREA_WIDTH+4, 0, 
674                                 c->view->winw - (int)MOBOX_AREA_WIDTH+4,
675                                 c->view->winh);
676                 gr_draw_line(c->xcontext, (int)MOBOX_AREA_WIDTH+2, 
677                          c->view->topoffset, c->view->winw,
678                          c->view->topoffset,  gr_solid, rect);
679                 gr_draw_line(c->xcontext, (int)MOBOX_AREA_WIDTH+2, 
680                          c->view->topoffset+1, c->view->winw,
681                          c->view->topoffset+1, gr_solid, rect);
682                 paint_dayview_appts(c, c->paint_cache, c->paint_cache_size, rect);
683         }
684
685         paint_day_header(c, c->view->date, rect);
686 }
687
688 extern void
689 paint_day(Calendar *c)
690 {
691         Day *day_info = (Day *) c->view->day_info;
692
693         c->view->glance = dayGlance;
694         XmToggleButtonGadgetSetState(c->day_scope, True, False);
695         gr_clear_area(c->xcontext, 0, 0, c->view->winw, c->view->winh);
696         if (day_info->month_panels == (Widget *) NULL)
697                 (void)init_dayview(c);
698         paint_dayview(c, True, NULL, True); 
699         calendar_select(c, hourSelect, (caddr_t)NULL);
700 }
701         
702 /*
703  * handler for button to switch to day view.
704  */
705 extern void
706 day_button (Widget widget, XtPointer data, XtPointer cbs)
707 {
708         Calendar *c = calendar;
709
710         if (c->view->glance == dayGlance)
711                 return;
712
713         XtUnmapWidget(c->canvas);
714         invalidate_cache(c);
715
716         switch (c->view->glance) {
717                 case weekGlance:
718                         c->view->glance = dayGlance;
719                         cleanup_after_weekview(c);
720                         break;
721                 case yearGlance:
722                         c->view->glance = dayGlance;
723                         cleanup_after_yearview(c);
724                         break;
725                 case monthGlance:
726                         c->view->glance = dayGlance;
727                         cleanup_after_monthview(c);
728                         break;
729                 default:
730                         break;  
731         }
732
733         init_mo(c);
734         (void)init_dayview(c);
735
736         XtMapWidget(c->canvas);
737 }
738
739 extern void
740 print_day_range(Calendar *c, Tick start_tick, Tick end_tick)
741 {
742         int             n;
743         register Tick   first_date = start_tick;
744         Boolean         done = False, first = True;
745         int             num_page = 1;
746         Props           *pr = (Props*)c->properties;
747         void *xp = (void *)NULL;
748
749         n = (end_tick - start_tick)/daysec + 1;
750
751         if (n <= 0) n = 1;
752
753         if ((xp = x_open_file(c)) == (void *)NULL)
754           return;
755
756         for (; n > 0; n--) {
757           while (!done) {
758             done = _print_day(c, num_page, xp,
759                               first_date, pr, first);
760             num_page++;
761             first = False;
762           }
763           done = False;
764           num_page = 1;
765         }
766
767         x_print_file(xp, c);
768 }
769
770 static int
771 count_day_pages(Calendar *c, int lines_per_page, Tick tick)
772 {
773         int     n, i, j, timeslots, num_appts, pages, max = 0; 
774         Props *p = (Props *)c->properties;
775         int       daybegin = get_int_prop(p, CP_DAYBEGIN);
776         int       dayend   = get_int_prop(p, CP_DAYEND);
777         char    *location;
778         time_t  start, end;
779         CSA_return_code stat;
780         CSA_entry_handle *list;
781         CSA_attribute *range_attrs;
782         CSA_enum *ops;
783         CSA_uint32 a_total;
784
785         for (i=daybegin; i < dayend; i++) {
786                 start = (time_t) lower_bound(i, tick);
787                 end = (time_t) next_nhours(start+1, 1) - 1;
788                 setup_range(&range_attrs, &ops, &j, start, end,
789                             CSA_TYPE_EVENT, NULL, B_FALSE, c->general->version);
790                 csa_list_entries(c->cal_handle, j, range_attrs, ops, &a_total, &list, NULL);
791                 free_range(&range_attrs, &ops, j);
792
793                 num_appts = count_multi_appts(list, a_total, c);
794
795                 if (num_appts > max)
796                         max = num_appts;
797
798                 csa_free(list);
799         }
800  
801         pages = max / lines_per_page;
802         if ((max % lines_per_page) > 0)
803                 pages++;
804  
805         return(pages);
806 }
807
808 static Boolean
809 _print_day(Calendar *c,
810     int num_page,
811     void *xp,
812     Tick first_date,
813     Props *p,
814     Boolean first)
815 {
816     char buf[100];
817     int n, i, j, timeslots, num_appts, pages;
818     int max = 0;
819     int daybegin = get_int_prop(p, CP_DAYBEGIN);
820     int dayend   = get_int_prop(p, CP_DAYEND);
821     OrderingType ord_t = get_int_prop(p, CP_DATEORDERING);
822     Boolean more, done = False, all_done = True;
823     char *location;
824     CSA_return_code stat;
825     CSA_entry_handle *list;
826     CSA_attribute *range_attrs;
827     CSA_enum *ops;
828     CSA_uint32 a_total;
829     time_t start, stop;
830     int lines_per_page;
831     static Tick tick = 0;
832     static int total_pages = 0;
833
834     /*
835      * Need to find the max number of timeslots which will be shown
836      * in one column, for later calculation of box height.
837      */  
838     if ((!morning(daybegin)) || dayend <= 12) 
839         timeslots = dayend - daybegin;
840     else
841         timeslots = ((12-daybegin) > (dayend-12)) ?
842                      (12-daybegin) : (dayend-12);
843
844     x_init_printer(xp, PORTRAIT);
845     x_init_day(xp, timeslots);
846     lines_per_page = x_get_day_lines_per_page(xp);
847
848     if (first)
849       tick = first_date;
850
851     if (num_page > 1)
852       tick = prevday(tick);
853     else
854       total_pages = (lines_per_page > 0) ?
855         count_day_pages(c, lines_per_page, tick) : 1;
856
857     format_date(tick, ord_t, buf, 1, 0, 0);
858
859     x_print_header(xp, buf, num_page, total_pages);
860     x_day_header(xp);
861
862     for (i=daybegin; i < dayend; i++) {
863       start = (time_t) lower_bound(i, tick);
864       stop = (time_t) next_nhours(start+1, 1) - 1;
865       setup_range(&range_attrs, &ops, &j, start, stop,
866                   CSA_TYPE_EVENT, NULL, B_FALSE, c->general->version);
867
868       csa_list_entries(c->cal_handle, j, range_attrs,
869                        ops, &a_total, &list, NULL);
870       free_range(&range_attrs, &ops, j);
871  
872       num_appts = count_multi_appts(list, a_total, c);
873
874       if ((lines_per_page > 0) && (num_appts > (lines_per_page * num_page)))
875         more = True;
876       else
877         more = False;
878
879       x_day_timeslots (xp, i, more);
880
881       if (lines_per_page > 0)
882         done = x_print_multi_appts (xp, list, a_total,
883                                     num_page, dayGlance);
884       else done = True;
885
886       if (!done)
887         all_done = False;
888       csa_free(list);
889     }
890  
891     x_finish_printer(xp);
892     tick = nextday(tick); 
893
894     return(all_done);
895 }
896
897 static int
898 day_xytoclock(Calendar *c, int x, int y, Tick t)
899 {
900         int daybegin, hr, val;
901         char buf[10];
902         struct tm tm;
903         Props *p;
904         _Xltimeparams localtime_buf;
905
906         p       = (Props *)c->properties;
907         daybegin = get_int_prop(p, CP_DAYBEGIN);
908         tm      = *_XLocaltime(&t, localtime_buf);
909
910         hr = (x == 1) ? (12 + y) : (y + daybegin - 1);
911
912         /* 
913          * If y == 0 then the user is clicking on the no-time area.  There
914          * is no hour associated with no-time events.
915          */
916         if (y == 0) hr = 0;
917
918         (void)sprintf(buf, "%d/%d/%d", tm.tm_mon+1, tm.tm_mday, tm.tm_year+1900);
919         val     =cm_getdate(buf, NULL);
920         val     = val+(hr*(int)hrsec);
921         adjust_dst(t, val);
922         return(val);
923 }
924
925 extern void
926 day_event(XEvent *event)
927 {
928         static int lastcol, lastrow;
929         static XEvent lastevent;
930         pr_pos xy;
931         int x, y, i, j;
932         int boxw, boxh, margin, id;
933         Calendar *c = calendar;
934         Tick date = c->view->date;
935         Boolean in_mbox = False; /* in month boxes ? */
936         Editor *e = (Editor*)c->editor;
937         ToDo *t = (ToDo*)c->todo;
938         GEditor *ge = (GEditor*)c->geditor;
939         Day *day_info = (Day *)c->view->day_info;
940  
941         boxw    = c->view->boxw;
942         boxh    = c->view->boxh;
943         margin  = c->view->outside_margin;
944         x       = event->xbutton.x;
945         y       = event->xbutton.y;
946  
947         /* boundary conditions */
948         if ((!(in_mbox = in_moboxes(c, x, y)) && x < MOBOX_AREA_WIDTH+2)
949 ||
950                 (x > MOBOX_AREA_WIDTH+2 && y < c->view->topoffset)) {
951                 lastcol=0; lastrow=0;
952                 return;
953         }
954         if (in_mbox) {
955                 xy.x = (x - margin)/ day_info->col_w;
956                 xy.y = (x - c->view->topoffset)/ day_info->row_h;
957         }
958         else {
959                 xy.x    = boxw;
960                 xy.y    = (y - c->view->topoffset)/boxh;
961         }
962         switch(event->type) {
963         case MotionNotify:
964                 if (!in_mbox) {
965                         if (xy.x !=lastcol || xy.y !=lastrow) {
966                                 calendar_deselect(c);
967                                 j = day_xytoclock(c, xy.x, xy.y, date);
968                                 if (j >= 0) {
969                                         c->view->olddate = c->view->date;                                        c->view->date = j;
970                                         calendar_select(c, hourSelect, (caddr_t)&xy);
971                                 }
972                                 lastcol=xy.x;
973                                 lastrow=xy.y;
974                         }
975                 }
976                 break;
977         case ButtonPress:
978                 if (ds_is_double_click(&lastevent, event)) {
979                         _DtTurnOnHourGlass(c->frame);
980                         j = day_xytoclock(c, xy.x, xy.y, date);
981                         if (lastcol == xy.x && lastrow == xy.y)
982                                 show_editor(c, j, next_nhours(j, 1), xy.y == 0 ? True : False);
983                         if (in_mbox) {
984                                 monthbox_deselect(c);
985                                 monthbox_xytodate(c, x, y);
986                                 monthbox_select(c);
987                         } else
988                                 show_editor(c, j, next_nhours(j, 1), xy.y == 0 ? True : False);
989                         _DtTurnOffHourGlass(c->frame);
990                 } else {
991                         if (in_mbox) {
992                                 monthbox_deselect(c);
993                                 monthbox_xytodate(c, x, y);
994                                 paint_dayview(c, False, NULL, True);
995                                 calendar_select(c, hourSelect, (caddr_t)NULL);
996                                 monthbox_select(c);
997                                 j = day_xytoclock(c, xy.x, xy.y, date);
998                                 if (editor_showing(e)) {
999                                         set_editor_defaults(e, j,
1000                                                             next_nhours(j, 1), False);
1001                                         add_all_appt(e);
1002                                 }
1003                                 if (todo_showing(t)) {
1004                                         set_todo_defaults(t);
1005                                         add_all_todo(t);
1006                                 }
1007                                 if (geditor_showing(ge)) {
1008                                         set_geditor_defaults(ge, j,
1009                                                              next_nhours(j, 1));
1010                                         add_all_gappt(ge);
1011                                 }
1012                         } else {
1013                                 calendar_deselect(c);
1014                                 j = day_xytoclock(c, xy.x, xy.y, date);
1015                                 if (j >= 0) {
1016                                         c->view->olddate = c->view->date;
1017                                         c->view->date = j;
1018                                         calendar_select(c, hourSelect,
1019                                                         (caddr_t)&xy);
1020                                         if (editor_showing(e)) {
1021                                                 set_editor_defaults(e, j,
1022                                                         next_nhours(j, 1), xy.y == 0 ? True : False);
1023                                                 add_all_appt(e);
1024                                         }
1025                                         if (todo_showing(t)) {
1026                                                 set_todo_defaults(t);
1027                                                 add_all_todo(t);
1028                                         }
1029                                         if (geditor_showing(ge)) {
1030                                                 set_geditor_defaults(ge, j,
1031                                                         next_nhours(j, 1));
1032                                                 add_all_gappt(ge);
1033                                         }
1034                                 }
1035                         }
1036                 }
1037                 lastcol=xy.x;
1038                 lastrow=xy.y;
1039                 break;
1040         default:
1041                 break;
1042         };            /* switch */
1043         lastevent = *event;
1044 }
1045
1046 static void
1047 display_monthpanels(Calendar *c)
1048 {
1049         Day     *d = (Day *)c->view->day_info;
1050         char    buf[BUFSIZ];
1051         int     lastyear = year(get_eot());
1052         int     firstyear = year(get_bot());
1053         int     panel_year;
1054         int     panel_month;
1055
1056         XtManageChild(d->panel_form);
1057
1058         XtVaGetValues(d->month_panels[1],
1059                 XmNyear, &panel_year,
1060                 XmNmonth, &panel_month,
1061                 NULL);
1062
1063         if ((panel_year == firstyear) && (panel_month == 1)) {
1064                 XtUnmapWidget(d->month_panels[0]);
1065                 XtMapWidget(d->month_panels[2]);
1066                 sprintf(buf, "%s", catgets(c->DT_catd, 1, 623, "Calendar does not display dates prior to January 1, 1970"));
1067                 set_message(c->message_text, buf);
1068         }
1069         else if ((panel_year == lastyear) && (panel_month == 12)) {
1070                 XtMapWidget(d->month_panels[0]);
1071                 XtUnmapWidget(d->month_panels[2]);
1072                 sprintf(buf, "%s", catgets(c->DT_catd, 1, 624, "Calendar does not display dates after December 31, 2037"));
1073                 set_message(c->message_text, buf);
1074         }
1075         else {
1076                 XtMapWidget(d->month_panels[0]);
1077                 XtMapWidget(d->month_panels[2]);
1078                 set_message(c->message_text, "");
1079         }
1080
1081         /* switch canvas to attach using its XmNleftPosition value */
1082 /* THIS IS THE RIGHT THIS TO DO, BUT ONLY AFTER REMOVING THE
1083    CODE THAT DRAWS THE OLD MO_BOXES.  FOR NOW, WE JUST MANAGE THE
1084    MONTHPANELS ON TOP OF THAT PART OF THE CANVAS - dac
1085         XtVaSetValues(c->canvas,
1086                 XmNleftAttachment, XmATTACH_POSITION,
1087                 XmNleftPosition, 40,
1088                 NULL);
1089 */
1090
1091 }
1092
1093 extern void
1094 cleanup_after_dayview(Calendar *c)
1095 {
1096         Day *d = (Day *)c->view->day_info;
1097
1098         invalidate_cache(c);
1099
1100         XtUnmanageChild(d->panel_form);
1101
1102         XmToggleButtonGadgetSetState(c->day_scope, False, False);
1103
1104         /* make canvas attach to form, and ignore its XmNleftPosition */
1105 /* DITTO ABOVE: THIS ISN'T NEEDED TILL WE ACTUALLY DO RESIZE THE
1106    CANVAS TO ADJOIN THE MONTHPANELS WHILE DAY VIEW IS UP
1107         XtVaSetValues(c->canvas, XmNleftAttachment, XmATTACH_FORM, NULL);
1108 */
1109
1110         gr_clear_area(calendar->xcontext, 0, 0, calendar->view->winw,
1111                        calendar->view->winh);
1112
1113         set_message(c->message_text, "");
1114 }
1115
1116 static void
1117 create_month_panels(Calendar *c)
1118 {
1119         Day *d = (Day *)c->view->day_info;
1120         Arg al[20];
1121         int ac;
1122
1123         ac=0;
1124         XtSetArg(al[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); ac++;
1125         XtSetArg(al[ac], XmNtopWidget, c->canvas); ac++;
1126         XtSetArg(al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
1127         XtSetArg(al[ac], XmNrightPosition, 40); ac++;
1128         XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1129         XtSetArg(al[ac], XmNleftOffset, 2); ac++;
1130         XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_POSITION); ac++;
1131         XtSetArg(al[ac], XmNbottomPosition, 95); ac++;
1132         XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1133         d->panel_form = XmCreateForm(c->form, "quarter", al, ac);
1134
1135
1136         ac=0;
1137         XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
1138         XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
1139         XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_POSITION); ac++;
1140         XtSetArg(al[ac], XmNbottomPosition, 33); ac++;
1141         XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1142         XtSetArg(al[ac], XmNmonth, month(previousmonth(c->view->date))); ac++;
1143         XtSetArg(al[ac], XmNyear, year(previousmonth(c->view->date))); ac++;
1144         d->month_panels[0] = XmCreateMonthPanel(d->panel_form, "lastMonth", al, ac);
1145         XtAddCallback(d->month_panels[0], XmNactivateCallback,
1146                         day_btn_cb, (XtPointer) c);
1147         XtAddCallback(d->month_panels[0], XmNhelpCallback, 
1148                         (XtCallbackProc)help_view_cb, NULL);
1149
1150         ac=0;
1151         XtSetArg(al[ac], XmNtopAttachment, XmATTACH_POSITION); ac++;
1152         XtSetArg(al[ac], XmNtopPosition, 33); ac++;
1153         XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
1154         XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_POSITION); ac++;
1155         XtSetArg(al[ac], XmNbottomPosition, 66); ac++;
1156         XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1157         XtSetArg(al[ac], XmNmonth, month(c->view->date)); ac++;
1158         XtSetArg(al[ac], XmNyear, year(c->view->date)); ac++;
1159         d->month_panels[1] = XmCreateMonthPanel(d->panel_form, "thisMonth", al, ac);
1160         XtAddCallback(d->month_panels[1], XmNactivateCallback,
1161                         day_btn_cb, (XtPointer) c);
1162         XtAddCallback(d->month_panels[1], XmNhelpCallback, 
1163                         (XtCallbackProc)help_view_cb, NULL);
1164
1165         ac=0;
1166         XtSetArg(al[ac], XmNtopAttachment, XmATTACH_POSITION); ac++;
1167         XtSetArg(al[ac], XmNtopPosition, 66); ac++;
1168         XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
1169         XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
1170         XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1171         XtSetArg(al[ac], XmNmonth, month(nextmonth(c->view->date))); ac++;
1172         XtSetArg(al[ac], XmNyear, year(nextmonth(c->view->date))); ac++;
1173         d->month_panels[2] = XmCreateMonthPanel(d->panel_form, "nextMonth", al, ac);
1174         XtAddCallback(d->month_panels[2], XmNactivateCallback,
1175                         day_btn_cb, (XtPointer) c);
1176         XtAddCallback(d->month_panels[2], XmNhelpCallback, 
1177                         (XtCallbackProc)help_view_cb, NULL);
1178
1179         ManageChildren(d->panel_form);
1180
1181 }
1182
1183 /*
1184  * This redisplays the 3 month panels 2 show the correct 3-month
1185  * window, centred around the month containing the "current" date.
1186  */
1187 static void
1188 update_quarter(Calendar *c)
1189 {
1190         Day *d = (Day *)c->view->day_info;
1191         int year_num, month_num;
1192
1193         /* previous month */
1194         year_num = year(previousmonth(c->view->date));
1195         month_num = month(previousmonth(c->view->date));
1196         XtVaSetValues(d->month_panels[0],
1197                 XmNyear, year_num,
1198                 XmNmonth, month_num,
1199                 NULL);
1200         
1201         /* current month */
1202         year_num = year(c->view->date);
1203         month_num = month(c->view->date);
1204         XtVaSetValues(d->month_panels[1],
1205                 XmNyear, year_num,
1206                 XmNmonth, month_num,
1207                 NULL);
1208         
1209         /* next month */
1210         year_num = year(nextmonth(c->view->date));
1211         month_num = month(nextmonth(c->view->date));
1212         XtVaSetValues(d->month_panels[2],
1213                 XmNyear, year_num,
1214                 XmNmonth, month_num,
1215                 NULL);
1216         
1217 }
1218
1219 static void
1220 day_btn_cb(Widget w, XtPointer client, XtPointer call)
1221 {
1222         XmMonthPanelCallbackStruct *cbs = (XmMonthPanelCallbackStruct *) call;
1223         Calendar *c = (Calendar *)client;
1224         int monthno, year;
1225         int date = c->view->date;
1226  
1227         invalidate_cache(c);
1228
1229         XtVaGetValues(w, XmNmonth, &monthno, XmNyear, &year, NULL);
1230  
1231         if (cbs->type == MONTH_SELECTION) {
1232
1233                 XtUnmapWidget(c->canvas);
1234
1235                 /*
1236                  * Date update:
1237                  *      if month chosen is not current month
1238                  *      set date to 1st of new month, otherwise
1239                  *      don't change date.
1240                  */
1241                 if (month(c->view->date) != monthno) {
1242                         calendar_deselect (c);
1243                         c->view->olddate = c->view->date;
1244                         c->view->date = monthdayyear(monthno, 1, year);
1245                         c->view->nwks = numwks(c->view->date);
1246                         calendar_select (c, monthSelect, NULL);
1247                 }
1248  
1249                 /* switch to month view */
1250                 c->view->glance = monthGlance;
1251                 cleanup_after_dayview(c);
1252                 prepare_to_paint_monthview(c, NULL);
1253
1254                 XtMapWidget(c->canvas);
1255         }
1256         else {  /* type == DAY_SELECTION */
1257                 c->view->olddate = c->view->date;
1258                 c->view->date = monthdayyear(monthno, cbs->day, year);
1259                 gr_clear_area(c->xcontext, 0, 0, c->view->winw, c->view->winh);
1260                 paint_dayview(c, True, NULL, False); 
1261                 calendar_select(c, hourSelect, (caddr_t)NULL);
1262         }
1263 }