1 /*
2 *
3 * Copyright (C) 1988 Massachusetts Institute of Technology
4 *
5 */
6
7 /*
8 * Permission to use, copy, modify, and distribute this software and its
9 * documentation for any purpose and without fee is hereby granted, provided
10 * that the above copyright notice appear in all copies and that both that
11 * copyright notice and this permission notice appear in supporting
12 * documentation, and that the name of M.I.T. not be used in advertising or
13 * publicity pertaining to distribution of the software without specific,
14 * written prior permission. M.I.T. makes no representations about the
15 * suitability of this software for any purpose. It is provided "as is"
16 * without express or implied warranty.
17 *
18 */
19
20 /***********************************************************************
21 * Copyright 1990-1994 by Richard Bingle and Purdue University. All rights
22 * reserved. Some individual files may be covered by other copyrights.
23 *
24 * Redistribution and use in source and binary forms are permitted
25 * provided that this entire copyright notice is duplicated in all such
26 * copies. Neither the name of the University, nor the name of the author
27 * may be used to endorse or promote products derived from this material
28 * without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
31 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
32 * MERCHANTIBILITY AND FITNESS FOR ANY PARTICULAR PURPOSE.
33 ************************************************************************/
34
35
36 /** Authors: Roman J. Budzianowski - Project Athena, MIT **/
37 /** Richard Bingle - Comp. Sci. Dept., Purdue University **/
38 /** Version 4.0 **/
39
40 #include "xcalendar.h"
41
42 Cardinal displayedMonth, displayedYear;
43 Widget toplevel;
44 Display *dsp;
45 int debug = 0;
46 List daylist;
47 List holilist;
48 void FormGeometryHandler();
49 LList *dayEntryList;
50 Cardinal day, month, year;
51 Boolean dayEntryState = False;
52 Arg markedDayColors[2];
53 Arg unmarkedDayColors[2];
54 void ShowEntries();
55 Window markedDaysKey;
56 Window allDaysKey;
57 LList *allDaysList;
58 Widget date;
59 Widget daynumbers;
60 Widget help_button;
61 Widget cdate;
62 char *smonth[13];
63 Cardinal defFirstDay = 1;
64
65 XtActionsRec appActions[] = {
66 {"ShowEntries", ShowEntries},
67 };
68
69 String defTranslations =
70 "<Btn1Down>:ShowEntries()";
71
72 #define SetResOffset(n,field) \
73 appResourceList[n].resource_offset = ((char *)&appResources.field - (char *)&appResources)
74 #define offset(field) XtOffset(struct _appRes *, field)
75
76 AppResourcesRec appResources; /* application specific resources */
77
78 XtResource appResourceList[] = {
79 {"reverseVideoMark", "ReverseVideo", XtRBoolean, sizeof(Boolean),
80 offset(reverseVideo), XtRString, "False"},
81 {"setMarkForeground", "SetForeground", XtRBoolean, sizeof(Boolean),
82 offset(setForeground), XtRString, "False"},
83 {"markForeground", "MarkForeground", XtRPixel, sizeof(Pixel),
84 offset(markForeground), XtRString, XtDefaultForeground},
85 {"setMarkBackground", "SetBackground", XtRBoolean, sizeof(Boolean),
86 offset(setBackground), XtRString, "False"},
87 {"markBackground", "MarkBackground", XtRPixel, sizeof(Pixel),
88 offset(markBackground), XtRString, XtDefaultBackground},
89 {"monthnames", "Monthnames", XtRString, sizeof(String),
90 offset(monthnames), XtRString, "January/February/March/April/May/June/July/August/September/October/November/December"},
91 {"monthnms", "Monthnms", XtRString, sizeof(String),
92 offset(monthnms), XtRString, "Jan/Feb/Mar/Apr/May/Jun/Jul/Aug/Sep/Oct/Nov/Dec"},
93 {"daynames", "Daynames", XtRString, sizeof(String),
94 offset(daynames), XtRString, "Sunday/Monday/Tuesday/Wednesday/Thursday/Friday/Saturday"},
95 {"daynms", "Daynms", XtRString, sizeof(String),
96 offset(daynms), XtRString, "Sun/Mon/Tue/Wed/Thu/Fri/Sat"},
97 {"date", "Date", XtRString, sizeof(String),
98 offset(date), XtRString, "%W, %M %d"},
99 {"january", "January", XtRString, sizeof(String),
100 offset(months[0]), XtRString, "January"},
101 {"february", "February", XtRString, sizeof(String),
102 offset(months[1]), XtRString, "February"},
103 {"march", "March", XtRString, sizeof(String),
104 offset(months[2]), XtRString, "March"},
105 {"april", "April", XtRString, sizeof(String),
106 offset(months[3]), XtRString, "April"},
107 {"may", "May", XtRString, sizeof(String),
108 offset(months[4]), XtRString, "May"},
109 {"june", "June", XtRString, sizeof(String),
110 offset(months[5]), XtRString, "June"},
111 {"july", "July", XtRString, sizeof(String),
112 offset(months[6]), XtRString, "July"},
113 {"august", "August", XtRString, sizeof(String),
114 offset(months[7]), XtRString, "August"},
115 {"september", "September", XtRString, sizeof(String),
116 offset(months[8]), XtRString, "September"},
117 {"october", "October", XtRString, sizeof(String),
118 offset(months[9]), XtRString, "October"},
119 {"november", "November", XtRString, sizeof(String),
120 offset(months[10]), XtRString, "November"},
121 {"december", "December", XtRString, sizeof(String),
122 offset(months[11]), XtRString, "December"},
123 {"firstDay", "FirstDay", XtRInt, sizeof(int),
124 offset(firstDay), XtRInt, (XtPointer) & defFirstDay},
125 {"markOnStartup", "MarkOnStarup", XtRBoolean, sizeof(Boolean),
126 offset(markOnStartup), XtRString, "False"},
127 {"helpFile", "HelpFile", XtRString, sizeof(String),
128 offset(helpFile), XtRString, "/usr/lib/X11/xcalendar/xcalendar.hlp"},
129 {"textBufferSize", "TextBufferSize", XtRInt, sizeof(int),
130 offset(textBufferSize), XtRString, "2048"},
131 {"calendarDir", "CalendarDir", XtRString, sizeof(String),
132 offset(calendarDir), XtRImmediate, NULL},
133 {"holidayFile", "HolidayFile", XtRString, sizeof(String),
134 offset(holidayFile), XtRImmediate, "/usr/lib/X11/xcalendar/xcalendar.hol"},
135 {"oldStyle", "OldStyle", XtRBoolean, sizeof(Boolean),
136 offset(oldStyle), XtRString, "True"},
137 {"markCurrent", "MarkCurrent", XtRBoolean, sizeof(Boolean),
138 offset(markCurrent), XtRString, "False"},
139 {"updateCurrent", "UpdateCurrent", XtRInt, sizeof(int),
140 offset(updateCurrent), XtRString, "60"},
141 {"currentForeground", "CurrentForeground", XtRPixel, sizeof(Pixel),
142 offset(currentForeground), XtRString, XtDefaultForeground},
143 {"markHoliday", "MarkHoliday", XtRBoolean, sizeof(Boolean),
144 offset(markHoliday), XtRString, "False"},
145 {"holidayForeground", "HolidayForeground", XtRPixel, sizeof(Pixel),
146 offset(holidayForeground), XtRString, XtDefaultForeground},
147 };
148
149 static int marked_day;
150
151 Arg markColors[2];
152 Cardinal nMark = 0;
153
154 static XtCallbackRec callbacks[] = {
155 {NULL, NULL},
156 {NULL, NULL},
157 };
158
159 /*
160 * quit() - Quit callback.
161 */
162
163 void
quit(w,closure,call_data)164 quit(w, closure, call_data)
165 Widget w;
166 XtPointer closure;
167 XtPointer call_data;
168 {
169 CloseEditors();
170 exit(0);
171 }
172
173 char *helpText =
174 "\n\
175 The full text of help is not available, because the help file\n\
176 couldn't be opened. Set the resource 'helpFile' to\n\
177 the full pathname of the xcalendar.hlp on your system.\n\
178 \n\
179 XCalendar is a simple interactive calendar program with a notebook\n\
180 capability. It is built on the X Toolkit and uses either the Athena\n\
181 or Motif Widgets.\n\
182 \n\
183 You can start the program as: xcalendar [month [year]]\n\
184 \n\
185 CREDITS:\n\
186 Version 4.0 \n\
187 Authors: Roman J. Budzianowski - MIT Project Athena\n\
188 Copyright 1988 Massachusetts Institute of Technology\n\
189 Richard Bingle - Comp. Sci. Dept., Purdue University\n\
190 Copyright 1990 Purdue University\n\
191 Contributions:\n\
192 Beth Chaney - Comp. Sci. Dept., Purdue University\n\
193 Mike Urban - JPL, NASA\n\
194 Joel Neisen - Minnesota Supercomputer Center\n\
195 Hiroshi Kuribayashi - Omron Corp.\n\
196 \n\
197 ";
198
199 String on[1] = {"on"};
200
201 /*
202 * help() - Help callback.
203 */
204
205 void
help(w,closure,call_data)206 help(w, closure, call_data)
207 Widget w;
208 XtPointer closure;
209 XtPointer call_data;
210 {
211 static DayEditor help = NULL;
212 char *iconName = "xcalendar: help";
213 Arg args[10];
214 int n;
215
216 if (!help) {
217 #ifdef ATHENA
218 help = CreateDayEditor("helpWindow", XawtextWrapNever, NULL);
219 #else
220 help = CreateMotifDayEditor("helpWindow", NULL, NULL);
221 #endif
222
223 help->button = w;
224 help->used = True;
225 help->saved = True;
226 help->filename = appResources.helpFile;
227
228 if (ReadFile(help) == False || EmptyBuffer(help)) {
229 XtFree(help->buffer);
230 (void) ChangeTextSource(help, helpText);
231 }
232 XtUnmanageChild(help->saveButton);
233 XtUnmanageChild(help->clearEntry);
234
235 XtUnmanageChild(help->prevday);
236 XtUnmanageChild(help->succday);
237
238 XtUnmanageChild(help->holiday);
239
240 n = 0;
241 #ifdef ATHENA
242 XtSetArg(args[n], XtNeditType, XawtextRead);
243 n++;
244 #else
245 XtSetArg(args[n], XmNeditable, False);
246 n++;
247 #endif
248 XtSetValues(help->editor, args, n);
249 }
250 n = 0;
251 XtSetArg(args[n], XtNiconName, iconName);
252 n++;
253 XtSetValues(help->shell, args, n);
254
255 #ifndef ATHENA
256 n = 0;
257 XtSetArg(args[n], XmNleftPosition, 1);
258 n++;
259 XtSetArg(args[n], XmNrightPosition, 2);
260 n++;
261 XtSetValues(help->doneButton, args, n);
262 #endif
263
264 StartEditor(help);
265 }
266
267 /*
268 * ChangeMonth() - changes view to month and year specified by the global
269 * variable month and year.
270 */
271
272 void
ChangeMonth()273 ChangeMonth()
274 {
275 Widget CreateCalendarFrame();
276 void prevmonth(), succmonth();
277 Cardinal numberOfDays, firstDay;
278 Arg args[10];
279 int n;
280 char title[80];
281 void NewDayNumbers();
282 #ifndef ATHENA
283 XmString xms;
284 #endif
285
286 /** in order to add the new buttons **/
287
288 sprintf(title, "%s %d", smonth[month], year);
289
290 firstDay = FirstDay(month, year);
291 numberOfDays = NumberOfDays(month, year);
292
293
294 /* date label */
295
296 n = 0;
297 #ifdef ATHENA
298 XtSetArg(args[n], XtNlabel, title);
299 n++;
300 XtSetValues(date, args, n);
301 #else
302 xms = XMS(title);
303 XtSetArg(args[n], XmNlabelString, xms);
304 n++;
305 XtSetValues(date, args, n);
306 XmStringFree(xms);
307 #endif
308
309 /* call NewDayNumbers */
310 NewDayNumbers(numberOfDays, firstDay);
311 }
312
313 /*
314 * prevmonth() - Sets month (and if needed, year) to the prior month.
315 */
316
317 void
prevmonth(w,closure,call_data)318 prevmonth(w, closure, call_data)
319 Widget w;
320 XtPointer closure;
321 XtPointer call_data;
322
323 {
324 if (displayedMonth == 1) {
325 displayedMonth = month = 12;
326 displayedYear = year = --displayedYear;
327 } else
328 displayedMonth = month = --displayedMonth;
329
330 ChangeMonth();
331 }
332
333 /*
334 * succmonth() - Sets month (and if needed, year) to the next month.
335 */
336
337 void
succmonth(w,closure,call_data)338 succmonth(w, closure, call_data)
339 Widget w;
340 XtPointer closure;
341 XtPointer call_data;
342
343 {
344 if (displayedMonth == 12) {
345 displayedMonth = month = 1;
346 displayedYear = year = ++displayedYear;
347 } else
348 displayedMonth = month = ++displayedMonth;
349 ChangeMonth();
350 }
351
352 /*
353 * main() - Main routine.
354 */
355
356 void
main(argc,argv)357 main(argc, argv)
358 int argc;
359 char **argv;
360 {
361 Arg args[10];
362 int n;
363 char title[80];
364 char iconName[80];
365 int i, resNo = 0;
366 Widget frame;
367
368 #ifdef XI18N
369 XtSetLanguageProc(NULL, NULL, NULL);
370 #endif
371 toplevel = XtInitialize(NULL, "XCalendar", NULL, 0, &argc, argv);
372
373 dsp = XtDisplay(toplevel);
374
375 /* get application specific resources */
376
377 if (XtScreen(toplevel)->root_visual->class == StaticGray)
378 appResourceList[0].default_addr = "True";
379
380 XtGetApplicationResources(toplevel, (XtPointer) & appResources,
381 appResourceList, XtNumber(appResourceList),
382 NULL, 0);
383
384 for (i = 0; i < 12; i++) {
385 smonth[i + 1] = appResources.months[i];
386 }
387
388 if (appResources.setBackground) {
389
390 XtSetArg(markColors[nMark], XtNbackground, appResources.markBackground);
391 nMark++;
392 }
393 if (appResources.setForeground) {
394
395 XtSetArg(markColors[nMark], XtNforeground, appResources.markForeground);
396 nMark++;
397 }
398
399 #ifndef ATHENA
400 XtAddEventHandler(toplevel, (EventMask)0, True,
401 _XEditResCheckMessages, NULL);
402 #endif
403
404 LoadHolidays();
405
406 day = current_day();
407 month = current_month();
408 year = current_year();
409
410 if (argc >= 2)
411 month = atoi(argv[1]);
412 if (!month)
413 month = current_month();
414
415 if (argc == 3)
416 year = atoi(argv[2]);
417 if (!year)
418 year = current_year();
419
420 displayedMonth = month;
421 displayedYear = year;
422
423 sprintf(iconName, "xcalendar: %s %d", smonth[displayedMonth],
424 displayedYear);
425
426 n = 0;
427 XtSetArg(args[n], XtNiconName, iconName);
428 n++;
429 XtSetValues(toplevel, args, n);
430
431 sprintf(title, "%s %d", smonth[month], year);
432
433 #ifdef ATHENA
434 frame = CreateCalendar(toplevel);
435 #else
436 frame = CreateMotifCalendar(toplevel);
437 #endif
438
439 /*
440 * Create the windows
441 */
442
443 XtRealizeWidget(toplevel);
444
445 allDaysKey = XtWindow(toplevel);
446 allDaysList = NULL;
447 markedDaysKey = XtWindow(frame);
448 MakeDayList();
449
450 /** mark the entries **/
451
452 if (appResources.markOnStartup == True) {
453 n = 1;
454 ShowEntries(toplevel, NULL, on, &n);
455 }
456 marked_day = -1;
457 if (appResources.updateCurrent <= 0)
458 appResources.updateCurrent = 60;
459 CurrentTic(toplevel, NULL);
460
461 /*
462 * Now process the events.
463 */
464 XtMainLoop();
465 }
466
467 /*
468 * ShowEntries() - Toggles the marking of days with something in them.
469 */
470
471 void
ShowEntries(w,event,params,numb)472 ShowEntries(w, event, params, numb)
473 Widget w;
474 XEvent *event;
475 String *params;
476 Cardinal *numb;
477 {
478 LList *listp;
479 Arg colors[2];
480 Arg *args = colors;
481 Cardinal n = 2;
482
483 initialized = False;
484
485 if (!(initialized || InitEditors()))
486 return;
487
488 if (numb && *numb) {
489 if (!strcmp(params[0], "on"))
490 dayEntryState = True;
491 else if (!strcmp(params[0], "off"))
492 dayEntryState = False;
493 } else {
494 if (dayEntryState)
495 dayEntryState = False;
496 else
497 dayEntryState = True;
498 }
499
500
501 listp = allDaysList;
502 if (allDaysList)
503 do {
504
505 XtSetArg(colors[0], XtNforeground, DayForeground(listp));
506
507 if (is_holiday((Widget) listp->element) &&
508 appResources.markHoliday) {
509 XtSetArg(colors[0], XtNforeground,
510 appResources.holidayForeground);
511 }
512 if (is_today((Widget) listp->element) && appResources.markCurrent) {
513 XtSetArg(colors[0], XtNforeground,
514 appResources.currentForeground);
515 }
516 XtSetValues((Widget) listp->element, colors, 1);
517
518 listp = listp->next;
519
520 } while (listp != allDaysList);
521
522
523 listp = dayEntryList;
524
525 if (dayEntryList)
526 do {
527 if (!dayEntryState) {
528 XtSetArg(colors[0], XtNbackground, DayBackground(listp));
529 XtSetArg(colors[1], XtNforeground, DayForeground(listp));
530 } else {
531 if (appResources.reverseVideo) {
532 XtSetArg(colors[0], XtNbackground, DayForeground(listp));
533 XtSetArg(colors[1], XtNforeground, DayBackground(listp));
534 } else {
535 args = markColors;
536 n = nMark;
537 }
538 }
539 XtSetValues((Widget) listp->element, args, n);
540
541 if (is_holiday((Widget) listp->element) &&
542 appResources.markHoliday) {
543 XtSetArg(colors[0], XtNforeground,
544 appResources.holidayForeground);
545 XtSetValues((Widget) listp->element, colors, 1);
546 }
547 if (is_today((Widget) listp->element) &&
548 appResources.markCurrent) {
549 XtSetArg(colors[0], XtNforeground,
550 appResources.currentForeground);
551 XtSetValues((Widget) listp->element, colors, 1);
552 }
553 listp = listp->next;
554
555 } while (listp != dayEntryList);
556 }
557
558 /*
559 * MarkDayEntry() - Adds or removes days (widgets) from the marked
560 * list.
561 */
562
563 void
MarkDayEntry(w,doFlag)564 MarkDayEntry(w, doFlag)
565 Widget w;
566 Boolean doFlag;
567 {
568 Arg colors[10];
569 int n;
570 LList *lp;
571 LList *lp2;
572
573 if (doFlag == True) {
574 if (lookup(w, markedDaysKey, dayEntryList) != NULL)
575 return; /* it's already on the list */
576
577 dayEntryList = (LList *) pput(w, markedDaysKey, dayEntryList);
578 dayEntryList->data = XtMalloc(sizeof(MarkColors));
579 lp2 = (LList *) lookup(w, allDaysKey, allDaysList);
580 DayBackground(dayEntryList) =
581 DayBackground(lp2);
582 DayForeground(dayEntryList) =
583 DayForeground(lp2);
584
585 if (dayEntryState == True) {
586 if (appResources.reverseVideo) {
587 n = 0;
588 XtSetArg(colors[n], XtNbackground, DayForeground(dayEntryList));
589 n++;
590 XtSetArg(colors[n], XtNforeground, DayBackground(dayEntryList));
591 n++;
592 XtSetValues(w, colors, n);
593 } else
594 XtSetValues(w, markColors, nMark);
595 }
596 if (is_holiday(w) && appResources.markHoliday) {
597 n = 0;
598 XtSetArg(colors[n], XtNforeground, appResources.holidayForeground);
599 n++;
600 XtSetValues(w, colors, n);
601 }
602 if (is_today(w) && appResources.markCurrent) {
603 n = 0;
604 XtSetArg(colors[n], XtNforeground, appResources.currentForeground);
605 n++;
606 XtSetValues(w, colors, n);
607 }
608 } else {
609 if ((lp = (LList *) lookup(w, markedDaysKey, dayEntryList)) == NULL) {
610 return; /* it's not on the list */
611 }
612 if (dayEntryState == True) {
613 dayEntryList = lp;
614 n = 0;
615 XtSetArg(colors[n], XtNbackground, DayBackground(dayEntryList));
616 n++;
617 XtSetArg(colors[n], XtNforeground, DayForeground(dayEntryList));
618 n;
619 if (is_holiday(w) && appResources.markHoliday)
620 XtSetArg(colors[n], XtNforeground,
621 appResources.holidayForeground);
622 if (is_today(w) && appResources.markCurrent)
623 XtSetArg(colors[n], XtNforeground,
624 appResources.currentForeground);
625 n++;
626 XtSetValues(w, colors, n);
627 }
628 XtFree(dayEntryList->data);
629 dayEntryList = (LList *) premove(w, markedDaysKey, dayEntryList);
630 }
631 }
632
633 /*
634 * CreateCalendarFrame() - Creates the calendar pane and calls
635 * other routines responsible for creating day labels and buttons.
636 */
637
638 Widget
CreateCalendarFrame(parent,args,nargs,numDays,firstDay)639 CreateCalendarFrame(parent, args, nargs, numDays, firstDay)
640 Widget parent;
641 Cardinal nargs;
642 ArgList args;
643 Cardinal numDays, firstDay;
644 {
645 Widget calendar, CreateDayLabels();
646 void CreateDayNumbers();
647 Widget widget;
648 Arg bargs[2];
649
650 /* callist = CreateList(2,sizeof(Widget)); */
651
652 #ifdef ATHENA
653 calendar = XtCreateManagedWidget("calendar", panedWidgetClass,
654 #else
655 calendar = XtCreateManagedWidget("calendar", xmPanedWindowWidgetClass,
656 #endif
657 parent, args, nargs);
658
659 widget = CreateDayLabels(calendar);
660
661 CreateDayNumbers(calendar, numDays, firstDay);
662 widget = daynumbers;
663
664 #ifndef ATHENA
665 HideSashes(calendar);
666 #endif
667
668 return calendar;
669
670 }
671
672 #ifdef ATHENA
673
674 /*
675 * CreateDayNumbers() - Creates the buttons for the days of the month.
676 */
677
678 void
CreateDayNumbers(parent,numDays,firstDay)679 CreateDayNumbers(parent, numDays, firstDay)
680 Widget parent;
681 Cardinal numDays, firstDay;
682 {
683 Widget prevButton = NULL;
684 Cardinal numButtons = 42;
685 Arg bargs[10];
686 int n;
687 int i;
688 char buttonText[4];
689 char buttonName[8];
690 void EditDayEntry();
691
692 #ifdef notdef
693 if (firstDay + numDays - 1 > 35)
694 numButtons = 42;
695 else
696 numButtons = 35;
697 #endif
698
699 daylist = CreateList(numButtons, sizeof(Widget));
700
701 n = 0;
702 daynumbers = XtCreateManagedWidget("daynumbers", formWidgetClass,
703 parent, bargs, n);
704
705 callbacks[0].callback = EditDayEntry;
706
707 XtSetArg(bargs[0], XtNcallback, callbacks);
708
709 for (i = 1; i <= numButtons; i++) {
710 n = 1;
711
712 if (i < firstDay || i > firstDay + numDays - 1) {
713 XtSetArg(bargs[n], XtNmappedWhenManaged, False);
714 n++;
715 callbacks[0].closure = NULL;
716 } else {
717 XtSetArg(bargs[n], XtNmappedWhenManaged, True);
718 n++;
719 callbacks[0].closure = (XtPointer) (i - firstDay + 1);
720 }
721
722 if ((i - 1) % 7 == 0) {
723 XtSetArg(bargs[n], XtNfromHoriz, NULL);
724 n++;
725 } else {
726 XtSetArg(bargs[n], XtNfromHoriz, prevButton);
727 n++;
728 }
729
730 if (i <= 7) {
731 XtSetArg(bargs[n], XtNfromVert, NULL);
732 n++;
733 } else {
734 XtSetArg(bargs[n], XtNfromVert, GetWidgetFromList(daylist, i - 7));
735 n++;
736 }
737
738 sprintf(buttonText, "%3.d", i - firstDay + 1);
739 XtSetArg(bargs[n], XtNlabel, buttonText);
740 n++;
741
742 /** sprintf(buttonName,"%d",(i-1)%7 + 1); **/
743 sprintf(buttonName, "%d", i);
744
745 prevButton = XtCreateManagedWidget(buttonName, commandWidgetClass,
746 daynumbers, bargs, n);
747
748 (void) PushWidgetOnList(daylist, prevButton);
749 }
750
751 }
752
753 /*
754 * NewDayNumbers() - Changes the buttons to reflect chosen month.
755 */
756
757 void
NewDayNumbers(numDays,firstDay)758 NewDayNumbers(numDays, firstDay)
759 Cardinal numDays, firstDay;
760 {
761 Cardinal numButtons = 42;
762 Arg bargs[10];
763 int n;
764 int i;
765 char buttonText[4];
766 char buttonName[8];
767 void EditDayEntry();
768 Widget tempWidget = NULL;
769
770 XtUnmapWidget(daynumbers);
771
772 callbacks[0].callback = EditDayEntry;
773
774 XtSetArg(bargs[0], XtNcallback, callbacks);
775
776 for (i = 1; i <= numButtons; i++) {
777 n = 1;
778
779 tempWidget = GetWidgetFromList(daylist, i);
780
781 if (i < firstDay || i > firstDay + numDays - 1) {
782 XtSetArg(bargs[n], XtNmappedWhenManaged, False);
783 n++;
784 callbacks[0].closure = NULL;
785 } else {
786 XtSetArg(bargs[n], XtNmappedWhenManaged, True);
787 n++;
788 callbacks[0].closure = (XtPointer) (i - firstDay + 1);
789 }
790
791 if ((i - 1) % 7 == 0) {
792 XtSetArg(bargs[n], XtNfromHoriz, NULL);
793 n++;
794 } else {
795 XtSetArg(bargs[n], XtNfromHoriz, GetWidgetFromList(daylist, i - 1));
796 n++;
797 }
798
799
800 MarkDayEntry(tempWidget, False);
801
802 if (i <= 7) {
803 XtSetArg(bargs[n], XtNfromVert, NULL);
804 n++;
805 } else {
806 XtSetArg(bargs[n], XtNfromVert, GetWidgetFromList(daylist, i - 7));
807 n++;
808 }
809
810
811 sprintf(buttonText, "%3.d", i - firstDay + 1);
812 XtSetArg(bargs[n], XtNlabel, buttonText);
813 n++;
814
815 sprintf(buttonName, "%d", i);
816
817 XtSetValues(tempWidget, bargs, n);
818 }
819
820 if (dayEntryState == True) {
821 n = 1;
822 ShowEntries(NULL, NULL, on, &n);
823 }
824 XtMapWidget(daynumbers);
825 }
826
827 /*
828 * CreateDayLabels() - Creates the day name labels (SUN,...).
829 */
830
831 Widget
CreateDayLabels(parent)832 CreateDayLabels(parent)
833 Widget parent;
834 {
835 Widget prevButton = NULL, daynames;
836 Arg bargs[10];
837 int n;
838 int i, day;
839 static char *names[8] =
840 {NULL, "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};
841
842 /* end of declarations */
843
844 n = 0;
845 daynames = XtCreateManagedWidget("daynames", formWidgetClass,
846 parent, bargs, n);
847
848 for (i = 1; i <= 7; i++) {
849 n = 0;
850 XtSetArg(bargs[n], XtNfromHoriz, prevButton);
851 n++;
852 day = (i + appResources.firstDay - 1) % 7;
853 day = day > 0 ? day : 7;
854 prevButton = XtCreateManagedWidget(names[day],
855 labelWidgetClass, daynames, bargs, n);
856 }
857
858 return daynames;
859
860 }
861
862 #else
863
864 /*
865 * CreateDayNumbers() - Creates the buttons for the days of the month.
866 */
867
868 void
CreateDayNumbers(parent,numDays,firstDay)869 CreateDayNumbers(parent, numDays, firstDay)
870 Widget parent;
871 Cardinal numDays, firstDay;
872 {
873 Widget prevButton = NULL;
874 Cardinal numButtons = 42;
875 Arg bargs[20];
876 int n;
877 int i;
878 char buttonText[10];
879 char buttonName[8];
880 void EditDayEntry();
881 XmString xms;
882
883 #ifdef notdef
884 if (firstDay + numDays - 1 > 35)
885 numButtons = 42;
886 else
887 numButtons = 35;
888 #endif
889
890 daylist = CreateList(numButtons, sizeof(Widget));
891
892 n = 0;
893 XtSetArg(bargs[n], XmNfractionBase, 42);
894 n++;
895 daynumbers = XtCreateManagedWidget("daynumbers", xmFormWidgetClass,
896 parent, bargs, n);
897
898 callbacks[0].callback = EditDayEntry;
899
900
901 for (i = 1; i <= numButtons; i++) {
902 n = 0;
903
904 if (i < firstDay || i > firstDay + numDays - 1) {
905 XtSetArg(bargs[n], XmNmappedWhenManaged, False);
906 n++;
907 callbacks[0].closure = NULL;
908 } else {
909 XtSetArg(bargs[n], XmNmappedWhenManaged, True);
910 n++;
911 callbacks[0].closure = (XtPointer) (i - firstDay + 1);
912 }
913 XtSetArg(bargs[n], XmNactivateCallback, callbacks);
914 n++;
915
916 XtSetArg(bargs[n], XmNleftAttachment, XmATTACH_POSITION);
917 n++;
918 XtSetArg(bargs[n], XmNleftPosition, ((i - 1) % 7) * 6);
919 n++;
920 XtSetArg(bargs[n], XmNrightAttachment, XmATTACH_POSITION);
921 n++;
922 XtSetArg(bargs[n], XmNrightPosition, (((i - 1) % 7) + 1) * 6);
923 n++;
924 XtSetArg(bargs[n], XmNtopAttachment, XmATTACH_POSITION);
925 n++;
926 XtSetArg(bargs[n], XmNtopPosition, ((int) ((i - 1) / 7)) * 7);
927 n++;
928 XtSetArg(bargs[n], XmNbottomAttachment, XmATTACH_POSITION);
929 n++;
930 XtSetArg(bargs[n], XmNbottomPosition, ((int) ((i - 1) / 7) + 1) * 7);
931 n++;
932
933 sprintf(buttonText, "%2.d", i - firstDay + 1);
934 xms = XMS(buttonText);
935 XtSetArg(bargs[n], XmNlabelString, xms);
936 n++;
937
938 /** sprintf(buttonName,"%d",(i-1)%7 + 1); **/
939 sprintf(buttonName, "%d", i);
940
941 prevButton = XtCreateManagedWidget(buttonName, xmPushButtonWidgetClass,
942 daynumbers, bargs, n);
943
944 (void) PushWidgetOnList(daylist, prevButton);
945 XmStringFree(xms);
946 }
947 }
948
949 /*
950 * NewDayNumbers() - Changes the buttons to reflect chosen month.
951 */
952
953 void
NewDayNumbers(numDays,firstDay)954 NewDayNumbers(numDays, firstDay)
955 Cardinal numDays, firstDay;
956 {
957 Cardinal numButtons = 42;
958 Arg bargs[10];
959 int i;
960 char buttonText[4];
961 char buttonName[8];
962 void EditDayEntry();
963 int n;
964 XmString xms;
965 Widget tempWidget = NULL;
966
967 XtUnmapWidget(daynumbers);
968
969 callbacks[0].callback = EditDayEntry;
970
971 for (i = 1; i <= numButtons; i++) {
972 n = 0;
973
974 tempWidget = GetWidgetFromList(daylist, i);
975
976 if (i < firstDay || i > firstDay + numDays - 1) {
977 XtSetArg(bargs[n], XmNmappedWhenManaged, False);
978 n++;
979 callbacks[0].closure = NULL;
980 } else {
981 XtSetArg(bargs[n], XmNmappedWhenManaged, True);
982 n++;
983 callbacks[0].closure = (XtPointer) (i - firstDay + 1);
984 }
985 XtSetArg(bargs[n], XmNactivateCallback, callbacks);
986 n++;
987
988 if ((i - 1) % 7 == 0) {
989 XtSetArg(bargs[n], XmNleftAttachment, XmATTACH_FORM);
990 n++;
991 } else {
992 XtSetArg(bargs[n], XmNleftAttachment, XmATTACH_WIDGET);
993 n++;
994 XtSetArg(bargs[n], XmNleftWidget,
995 GetWidgetFromList(daylist, i - 1));
996 n++;
997 }
998
999 MarkDayEntry(tempWidget, False);
1000
1001 if (i <= 7) {
1002 XtSetArg(bargs[n], XmNtopAttachment, XmATTACH_FORM);
1003 n++;
1004 } else {
1005 XtSetArg(bargs[n], XmNtopAttachment, XmATTACH_WIDGET);
1006 n++;
1007 XtSetArg(bargs[n], XmNtopWidget, GetWidgetFromList(daylist, i - 7));
1008 n++;
1009 }
1010
1011
1012 sprintf(buttonText, "%2.d", i - firstDay + 1);
1013 xms = XMS(buttonText);
1014 XtSetArg(bargs[n], XmNlabelString, xms);
1015 n++;
1016
1017 sprintf(buttonName, "%d", i);
1018
1019 XtSetValues(tempWidget, bargs, n);
1020 XmStringFree(xms);
1021 }
1022
1023 if (dayEntryState == True) {
1024 n = 1;
1025 ShowEntries(NULL, NULL, on, &n);
1026 }
1027 XtMapWidget(daynumbers);
1028 }
1029
1030 /*
1031 * CreateDayLabels() - Creates the day name labels (SUN,...).
1032 */
1033
1034 Widget
CreateDayLabels(parent)1035 CreateDayLabels(parent)
1036 Widget parent;
1037 {
1038 Widget prevButton = NULL, daynames;
1039 Arg bargs[10];
1040 int i, n, day;
1041 XtWidgetGeometry size;
1042 static char *names[8] =
1043 {NULL, "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};
1044
1045 /* end of declarations */
1046
1047 n = 0;
1048 XtSetArg(bargs[n], XmNfractionBase, 7);
1049 n++;
1050 daynames = XtCreateManagedWidget("daynames", xmFormWidgetClass,
1051 parent, bargs, n);
1052
1053 for (i = 1; i <= 7; i++) {
1054 n = 0;
1055 XtSetArg(bargs[n], XmNleftAttachment, XmATTACH_POSITION);
1056 n++;
1057 XtSetArg(bargs[n], XmNleftPosition, i - 1);
1058 n++;
1059 XtSetArg(bargs[n], XmNrightAttachment, XmATTACH_POSITION);
1060 n++;
1061 XtSetArg(bargs[n], XmNrightPosition, i);
1062 n++;
1063
1064 day = (i + appResources.firstDay - 1) % 7;
1065 day = day > 0 ? day : 7;
1066 prevButton = XtCreateManagedWidget(names[day],
1067 xmLabelWidgetClass, daynames, bargs, n);
1068 }
1069
1070 size.request_mode = CWHeight;
1071 XtQueryGeometry(daynames, NULL, &size);
1072
1073 n = 0;
1074 XtSetArg(bargs[n], XmNpaneMinimum, size.height);
1075 n++;
1076 XtSetArg(bargs[n], XmNpaneMaximum, size.height);
1077 n++;
1078 XtSetValues(daynames, bargs, n);
1079
1080 return daynames;
1081 }
1082
1083 #endif
1084
1085 static struct tm *today = NULL;
1086
1087 /*
1088 * gettime() - Updates the shared tm structure to the current time.
1089 */
1090
1091 struct tm *
gettime()1092 gettime()
1093 {
1094 time_t now;
1095
1096 (void) time(&now);
1097 today = localtime(&now);
1098 return today;
1099 }
1100
1101 /*
1102 * current_month() - Returns the number of the current month (1-12).
1103 */
1104
1105 int
current_month()1106 current_month()
1107 {
1108 if (today == NULL)
1109 (void) gettime();
1110 return (today->tm_mon + 1);
1111 }
1112
1113 /*
1114 * current_day() - Returns the day of the month of the current day.
1115 */
1116
1117 int
current_day()1118 current_day()
1119 {
1120 if (today == NULL)
1121 (void) gettime();
1122 return (today->tm_mday);
1123 }
1124
1125 /*
1126 * current_year() - Returns the current year (yyyy).
1127 */
1128
1129 int
current_year()1130 current_year()
1131 {
1132 if (today == NULL)
1133 (void) gettime();
1134 return (today->tm_year + 1900);
1135 }
1136
1137 char mon[] = {
1138 0,
1139 31, 29, 31, 30,
1140 31, 30, 31, 31,
1141 30, 31, 30, 31,
1142 };
1143
1144 static int calInit = 0;
1145
1146 /*
1147 * NumberOfDays() - Returns the number of days for month of year.
1148 */
1149
1150 int
NumberOfDays(m,y)1151 NumberOfDays(m, y)
1152 int m, y;
1153 {
1154 if (calInit != y)
1155 FirstDay(m, y);
1156 return mon[m];
1157 }
1158
1159 /* should be called first */
1160
1161 /*
1162 * FirstDay() - Returns the day of the week of the first day of the
1163 * given month and year.
1164 */
1165
1166 int
FirstDay(m,y)1167 FirstDay(m, y)
1168 int m, y;
1169 {
1170 register d, i;
1171
1172 calInit = y;
1173 d = jan1(y);
1174 mon[2] = 29;
1175 mon[9] = 30;
1176
1177 switch ((jan1(y + 1) + 7 - d) % 7) {
1178
1179 /*
1180 * non-leap year
1181 */
1182 case 1:
1183 mon[2] = 28;
1184 break;
1185
1186 /*
1187 * 1752
1188 */
1189 default:
1190 mon[9] = 19;
1191 break;
1192
1193 /*
1194 * leap year
1195 */
1196 case 2:
1197 ;
1198 }
1199
1200 for (i = 1; i < m; i++)
1201 d += mon[i];
1202 d %= 7;
1203
1204 d = d > 0 ? d : 7; /* returns 1-7, not 0-6 */
1205
1206 d = d + 1 - appResources.firstDay;
1207 return d > 0 ? d : 7 + d;
1208
1209 }
1210
1211 /*
1212 * jan1() - Returns day of the week of jan 1 of given year.
1213 */
1214
1215 int
jan1(yr)1216 jan1(yr)
1217 int yr;
1218 {
1219 register y, d;
1220
1221 /*
1222 * normal gregorian calendar one extra day per four years
1223 */
1224
1225 y = yr;
1226 d = 4 + y + (y + 3) / 4;
1227
1228 /*
1229 * julian calendar regular gregorian less three days per 400
1230 */
1231
1232 if (y > 1800) {
1233 d -= (y - 1701) / 100;
1234 d += (y - 1601) / 400;
1235 }
1236 /*
1237 * great calendar changeover instant
1238 */
1239
1240 if (y > 1752)
1241 d += 3;
1242
1243 return (d % 7);
1244 }
1245
1246 /*
1247 * CurrentTic() - Updates current day.
1248 */
1249
1250 void
CurrentTic(client_data,tid)1251 CurrentTic(client_data, tid)
1252 XtPointer client_data;
1253 XtIntervalId *tid;
1254 {
1255 int day;
1256 char sb[80];
1257 Arg args[10];
1258 int n;
1259 #ifndef ATHENA
1260 XmString xms;
1261 #endif
1262
1263 today = NULL;
1264 day = current_day();
1265 if (day != marked_day) {
1266 if ((day == 1) &&
1267 ((displayedMonth != current_month()) ||
1268 (displayedYear != current_year()))) {
1269 displayedMonth = month = current_month();
1270 displayedYear = year = current_year();
1271 ChangeMonth();
1272 }
1273 marked_day = day;
1274 if (appResources.markCurrent) {
1275 n = 1;
1276 ShowEntries(NULL, NULL, on, &n);
1277 }
1278 Fill_In_Date(sb);
1279 n = 0;
1280 #ifdef ATHENA
1281 XtSetArg(args[n], XtNlabel, sb);
1282 n++;
1283 XtSetValues(cdate, args, n);
1284 #else
1285 xms = XMS(sb);
1286 XtSetArg(args[n], XmNlabelString, xms);
1287 n++;
1288 XtSetValues(cdate, args, n);
1289 XmStringFree(xms);
1290 #endif
1291 }
1292 XtAppAddTimeOut(XtWidgetToApplicationContext((Widget) (client_data)),
1293 appResources.updateCurrent * 1000, CurrentTic,
1294 client_data);
1295 }
1296
1297 /*
1298 * is_today() - Returns true if the widget represents today.
1299 */
1300
1301 Boolean
is_today(w)1302 is_today(w)
1303 Widget w;
1304 {
1305 Widget foo = GetWidgetFromList(daylist,
1306 FirstDay(displayedMonth, displayedYear) - 1 + current_day());
1307
1308 if ((displayedMonth == current_month()) &&
1309 (displayedYear == current_year())) {
1310 if (w == foo) {
1311 return (True);
1312 } else {
1313 return (False);
1314 }
1315 } else {
1316 return (False);
1317 }
1318 }
1319
1320 /*
1321 * is_holiday() - Returns true if the widget is for a holiday.
1322 */
1323
1324 Boolean
is_holiday(w)1325 is_holiday(w)
1326 Widget w;
1327 {
1328 int i;
1329 struct holiday *holi;
1330
1331 for (i = 0; i < holilist->pos; i++) {
1332 holi = *((Holiday *) holilist->list + i);
1333 if (((GetWidgetFromList(daylist,
1334 FirstDay(displayedMonth, displayedYear) -
1335 1 + holi->day)) == w) &&
1336 (holi->month == displayedMonth) &&
1337 (holi->year == displayedYear))
1338 return (True);
1339 }
1340 return (False);
1341 }
1342
1343 /*
1344 * MakeDayList() - Keeps a list of all days.
1345 */
1346
1347 void
MakeDayList()1348 MakeDayList()
1349 {
1350 int i;
1351 Widget w;
1352 Arg args[10];
1353 int n;
1354
1355 for (i = 1; i <= 42; i++) {
1356 n = 0;
1357 w = GetWidgetFromList(daylist, i);
1358 allDaysList = (LList *) pput(w, allDaysKey, allDaysList);
1359 allDaysList->data = XtMalloc(sizeof(MarkColors));
1360 XtSetArg(args[n], XtNbackground, &DayBackground(allDaysList));
1361 n++;
1362 XtSetArg(args[n], XtNforeground, &(DayForeground(allDaysList)));
1363 n++;
1364 XtGetValues(w, args, n);
1365 }
1366 }
1367
1368 #ifdef ATHENA
1369
1370 /*
1371 * CreateCalendar() - Creates the main calendar pane and control areas.
1372 */
1373
1374 Widget
CreateCalendar(toplevel)1375 CreateCalendar(toplevel)
1376 Widget toplevel;
1377 {
1378 Widget calendar, controls;
1379 Widget prev_button, succ_button;
1380 Widget quit_button;
1381 Widget CreateCalendarFrame();
1382 Cardinal numberOfDays, firstDay;
1383 Widget frame;
1384
1385 Arg args[10];
1386 int n;
1387 char title[80];
1388
1389 Widget bcontrols;
1390
1391 firstDay = FirstDay(month, year);
1392 numberOfDays = NumberOfDays(month, year);
1393
1394 /*
1395 * Create the top level pane widget
1396 */
1397
1398 frame = XtCreateWidget("xcalendar", panedWidgetClass, toplevel, NULL, 0);
1399
1400 markedDaysKey = XtWindow(frame);
1401
1402 /** create control panel **/
1403
1404 n = 0;
1405 XtSetArg(args[n], XtNskipAdjust, True);
1406 n++;
1407 controls = XtCreateManagedWidget("controls", formWidgetClass, frame,
1408 args, n);
1409
1410 /* prev button */
1411
1412 n = 0;
1413 callbacks[0].callback = prevmonth;
1414 XtSetArg(args[n], XtNcallback, callbacks);
1415 n++;
1416 XtSetArg(args[n], XtNfromHoriz, NULL);
1417 n++;
1418 XtSetArg(args[n], XtNleft, XtChainLeft);
1419 n++;
1420 XtSetArg(args[n], XtNright, XtChainLeft);
1421 n++;
1422
1423 prev_button = XtCreateManagedWidget("prev", commandWidgetClass,
1424 controls, args, n);
1425
1426 /* month label */
1427
1428 sprintf(title, "%s %d", smonth[month], year);
1429
1430 n = 0;
1431 XtSetArg(args[n], XtNlabel, title);
1432 n++;
1433 XtSetArg(args[n], XtNfromHoriz, prev_button);
1434 n++;
1435 XtSetArg(args[n], XtNleft, XtChainLeft);
1436 n++;
1437 XtSetArg(args[n], XtNright, XtChainRight);
1438 n++;
1439
1440 date = XtCreateManagedWidget("date", labelWidgetClass, controls, args, n);
1441
1442 XtAppAddActions(XtWidgetToApplicationContext(date), appActions, 1);
1443
1444 XtAugmentTranslations(date, XtParseTranslationTable(defTranslations));
1445
1446 /* next button */
1447
1448 n = 0;
1449 callbacks[0].callback = succmonth;
1450 XtSetArg(args[n], XtNcallback, callbacks);
1451 n++;
1452 XtSetArg(args[n], XtNfromHoriz, date);
1453 n++;
1454 XtSetArg(args[n], XtNleft, XtChainRight);
1455 n++;
1456 XtSetArg(args[n], XtNright, XtChainRight);
1457 n++;
1458
1459 succ_button = XtCreateManagedWidget("succ",
1460 commandWidgetClass,
1461 controls, args, n);
1462
1463 /** end of control panel code **/
1464
1465 /** create calendar form **/
1466
1467 calendar = CreateCalendarFrame(frame, args, 0, numberOfDays, firstDay);
1468
1469 n = 0;
1470 XtSetArg(args[n], XtNskipAdjust, True);
1471 n++;
1472 bcontrols = XtCreateManagedWidget("bcontrols", formWidgetClass,
1473 frame, args, n);
1474
1475 n = 0;
1476 callbacks[0].callback = quit;
1477 XtSetArg(args[n], XtNcallback, callbacks);
1478 n++;
1479 XtSetArg(args[n], XtNfromHoriz, NULL);
1480 n++;
1481 XtSetArg(args[n], XtNleft, XtChainLeft);
1482 n++;
1483 XtSetArg(args[n], XtNright, XtChainLeft);
1484 n++;
1485
1486 quit_button = XtCreateManagedWidget("quitButton", commandWidgetClass,
1487 bcontrols, args, n);
1488
1489 Fill_In_Date(title);
1490
1491 n = 0;
1492 XtSetArg(args[n], XtNlabel, title);
1493 n++;
1494 XtSetArg(args[n], XtNfromHoriz, quit_button);
1495 n++;
1496 XtSetArg(args[n], XtNleft, XtChainLeft);
1497 n++;
1498 XtSetArg(args[n], XtNright, XtChainRight);
1499 n++;
1500
1501 cdate = XtCreateManagedWidget("cdate", labelWidgetClass, bcontrols,
1502 args, n);
1503
1504 XtAugmentTranslations(quit_button,
1505 XtParseTranslationTable(defTranslations));
1506
1507 n = 0;
1508 callbacks[0].callback = help;
1509 XtSetArg(args[n], XtNcallback, callbacks);
1510 n++;
1511 XtSetArg(args[n], XtNfromHoriz, cdate);
1512 n++;
1513 XtSetArg(args[n], XtNleft, XtChainRight);
1514 n++;
1515 XtSetArg(args[n], XtNright, XtChainRight);
1516 n++;
1517
1518 help_button = XtCreateManagedWidget("helpButton",
1519 commandWidgetClass,
1520 bcontrols, args, n);
1521
1522 /** end of top level form **/
1523
1524 XtInstallAllAccelerators(frame, frame);
1525
1526 XtManageChild(frame);
1527 return (frame);
1528 }
1529
1530 #else
1531
1532 /*
1533 * HideSashes() - Removes Motif sashes from traversal list and view.
1534 */
1535
1536 void
HideSashes(w)1537 HideSashes(w)
1538 Widget w;
1539 {
1540 Widget *children;
1541 int num;
1542 Arg args[10];
1543 int n;
1544
1545 n = 0;
1546 XtSetArg(args[n], XmNchildren, &children);
1547 n++;
1548 XtSetArg(args[n], XmNnumChildren, &num);
1549 n++;
1550 XtGetValues(w, args, n);
1551
1552 while (num-- > 0)
1553 if (XmIsSash(children[num])) {
1554 n = 0;
1555 XtSetArg(args[n], XmNmappedWhenManaged, False);
1556 n++;
1557 XtSetArg(args[n], XmNtraversalOn, False);
1558 n++;
1559 XtSetValues(children[num], args, n);
1560 }
1561 }
1562
1563 /*
1564 * CreateMotifCalendar() - Creates the main calendar pane and control areas.
1565 */
1566
1567 Widget
CreateMotifCalendar(toplevel)1568 CreateMotifCalendar(toplevel)
1569 Widget toplevel;
1570 {
1571 Widget calendar, controls;
1572 Widget prev_button, succ_button;
1573 Widget quit_button;
1574 Widget CreateCalendarFrame();
1575 Cardinal numberOfDays, firstDay;
1576 Widget frame;
1577 #ifndef ATHENA
1578 XmString xms;
1579 #endif
1580 Arg args[10];
1581 char title[80];
1582 Widget bcontrols;
1583 int n;
1584 XtWidgetGeometry size;
1585
1586 firstDay = FirstDay(month, year);
1587 numberOfDays = NumberOfDays(month, year);
1588
1589 /*
1590 * Create the top level form widget
1591 */
1592
1593 n = 0;
1594 frame = XtCreateWidget("xcalendar", xmPanedWindowWidgetClass, toplevel,
1595 args, n);
1596
1597 markedDaysKey = XtWindow(frame);
1598
1599 /** create control panel **/
1600
1601 n = 0;
1602 controls = XtCreateManagedWidget("controls", xmFormWidgetClass, frame,
1603 args, n);
1604
1605 /* prev button */
1606
1607 n = 0;
1608 callbacks[0].callback = prevmonth;
1609 XtSetArg(args[n], XmNactivateCallback, callbacks);
1610 n++;
1611
1612 prev_button = XtCreateManagedWidget("prev", xmPushButtonWidgetClass,
1613 controls, args, n);
1614
1615 /* next button */
1616
1617 n = 0;
1618 callbacks[0].callback = succmonth;
1619 XtSetArg(args[n], XmNactivateCallback, callbacks);
1620 n++;
1621 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM);
1622 n++;
1623
1624 succ_button = XtCreateManagedWidget("succ",
1625 xmPushButtonWidgetClass,
1626 controls, args, n);
1627
1628 /* month label */
1629
1630 sprintf(title, "%s %d", smonth[month], year);
1631
1632 n = 0;
1633 xms = XMS(title);
1634 XtSetArg(args[n], XmNlabelString, xms);
1635 n++;
1636 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET);
1637 n++;
1638 XtSetArg(args[n], XmNleftWidget, prev_button);
1639 n++;
1640 XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET);
1641 n++;
1642 XtSetArg(args[n], XmNrightWidget, succ_button);
1643 n++;
1644
1645 date = XtCreateManagedWidget("date", xmLabelWidgetClass, controls, args, n);
1646 XmStringFree(xms);
1647
1648 XtAppAddActions(XtWidgetToApplicationContext(date), appActions, 1);
1649
1650 XtAugmentTranslations(date, XtParseTranslationTable(defTranslations));
1651
1652 size.request_mode = CWHeight;
1653 XtQueryGeometry(controls, NULL, &size);
1654
1655 n = 0;
1656 XtSetArg(args[n], XmNpaneMinimum, size.height);
1657 n++;
1658 XtSetArg(args[n], XmNpaneMaximum, size.height);
1659 n++;
1660 XtSetValues(controls, args, n);
1661
1662 /** end of control panel code **/
1663
1664 /** create calendar form **/
1665
1666 n = 0;
1667 calendar = CreateCalendarFrame(frame, args, n, numberOfDays, firstDay);
1668
1669 n = 0;
1670 bcontrols = XtCreateManagedWidget("bcontrols", xmFormWidgetClass,
1671 frame, args, n);
1672
1673 n = 0;
1674 callbacks[0].callback = quit;
1675 XtSetArg(args[n], XmNactivateCallback, callbacks);
1676 n++;
1677
1678 quit_button = XtCreateManagedWidget("quitButton", xmPushButtonWidgetClass,
1679 bcontrols, args, n);
1680
1681 XtAugmentTranslations(quit_button,
1682 XtParseTranslationTable(defTranslations));
1683
1684 n = 0;
1685 callbacks[0].callback = help;
1686 XtSetArg(args[n], XmNactivateCallback, callbacks);
1687 n++;
1688 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM);
1689 n++;
1690
1691 help_button = XtCreateManagedWidget("helpButton",
1692 xmPushButtonWidgetClass,
1693 bcontrols, args, n);
1694
1695 Fill_In_Date(title);
1696 xms = XMS(title);
1697
1698 n = 0;
1699 XtSetArg(args[n], XmNlabelString, xms);
1700 n++;
1701 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET);
1702 n++;
1703 XtSetArg(args[n], XmNleftWidget, quit_button);
1704 n++;
1705 XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET);
1706 n++;
1707 XtSetArg(args[n], XmNrightWidget, help_button);
1708 n++;
1709 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM);
1710 n++;
1711 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM);
1712 n++;
1713
1714 cdate = XtCreateManagedWidget("cdate", xmLabelWidgetClass,
1715 bcontrols, args, n);
1716 XmStringFree(xms);
1717
1718 size.request_mode = CWHeight;
1719 XtQueryGeometry(bcontrols, NULL, &size);
1720
1721 n = 0;
1722 XtSetArg(args[n], XmNpaneMinimum, size.height);
1723 n++;
1724 XtSetArg(args[n], XmNpaneMaximum, size.height);
1725 n++;
1726 XtSetValues(bcontrols, args, n);
1727
1728 /** end of top level form **/
1729
1730 XtInstallAllAccelerators(frame, frame);
1731
1732 HideSashes(frame);
1733 XtManageChild(frame);
1734 return (frame);
1735 }
1736 #endif
1737
1738 /*
1739 * getmonthday() - Returns month or day string from the given list.
1740 */
1741
1742 char *
getmonthday(num,startptr)1743 getmonthday(num, startptr)
1744 int num; /* Month or day ordinal */
1745 char *startptr; /* String to pick it from */
1746 {
1747 static char returnval[128];
1748 char *start, *end;
1749 int i;
1750
1751 start = startptr;
1752 strcpy(returnval, "");
1753 for (i = 0; i < num; i++) {
1754 end = strchr(start, '/');
1755 if (end == (char *) NULL)
1756 return returnval;
1757 start = end + 1;
1758 }
1759 end = strchr(start, '/');
1760 if (end == (char *) NULL)
1761 strcpy(returnval, start);
1762 else {
1763 char *op;
1764
1765 op = returnval;
1766 while (start < end)
1767 *(op++) = *(start++);
1768 *op = '\0';
1769 }
1770 return returnval;
1771 }
1772
1773 /*
1774 * Fill_In_Date() - Formats current date for display.
1775 */
1776
1777 void
Fill_In_Date(sb)1778 Fill_In_Date(sb)
1779 char *sb;
1780 {
1781 int i, len, prev_len;
1782 char *startp, *p;
1783 struct tm tm;
1784 time_t time_value;
1785
1786
1787
1788 if (appResources.date == NULL) {
1789 strcpy(sb, "");
1790 return;
1791 }
1792 (void) time(&time_value);
1793 tm = *localtime(&time_value);
1794
1795 startp = sb;
1796 for (p = appResources.date; p && *p; p++) {
1797 if (*p != '%')
1798 *sb++ = *p;
1799 else
1800 switch (*++p) {
1801 case 'M':
1802 sb += strlen(strcpy(sb,
1803 getmonthday(tm.tm_mon,
1804 (char *) appResources.monthnames)));
1805 break;
1806 case 'm':
1807 sb += strlen(strcpy(sb,
1808 getmonthday(tm.tm_mon,
1809 (char *) appResources.monthnms)));
1810 break;
1811 case 'W':
1812 sb += strlen(strcpy(sb,
1813 getmonthday(tm.tm_wday,
1814 (char *) appResources.daynames)));
1815 break;
1816 case 'w':
1817 sb += strlen(strcpy(sb,
1818 getmonthday(tm.tm_wday,
1819 (char *) appResources.daynms)));
1820 break;
1821 case 'd':
1822 if (tm.tm_mday >= 10)
1823 *sb++ = (tm.tm_mday / 10 + '0');
1824 *sb++ = tm.tm_mday % 10 + '0';
1825 break;
1826 case 'Y':
1827 *sb++ = '1', *sb++ = '9';
1828 /* fall thru */
1829 case 'y':
1830 *sb++ = (tm.tm_year%100) / 10 + '0';
1831 *sb++ = (tm.tm_year%100) % 10 + '0';
1832 break;
1833 case '%':
1834 *sb++ = *p;
1835 otherwise:; /* nothing */
1836 }
1837 }
1838 *sb = '\0';
1839 sb = startp;
1840 }
1841
1842 /*
1843 * LoadHolidays() - Loads the holiday file.
1844 */
1845
1846 void
LoadHolidays()1847 LoadHolidays()
1848 {
1849 char *buf;
1850 int n;
1851 int len;
1852 char *next;
1853 char *tab;
1854 char *start;
1855 struct holiday *holi;
1856
1857 n = 2048;
1858 buf = XtMalloc(sizeof(char) * n);
1859
1860 holilist = CreateList(1, sizeof(Holiday));
1861
1862 len = read_file(appResources.holidayFile, buf, n);
1863 if (len == -1)
1864 return;
1865 else if (len > n) {
1866 buf = XtRealloc(buf, len + 1);
1867 n = len + 1;
1868 len = read_file(appResources.holidayFile, buf, n);
1869 if (len == -1)
1870 return;
1871 }
1872
1873 /* terminate `buf' with NULL */
1874 if (sizeof(buf) == len) {
1875 buf = XtRealloc(buf, len + 1);
1876 }
1877 buf[len] = NULL;
1878
1879 start = buf;
1880
1881 while (len > 0) {
1882 next = strchr(buf, '\n');
1883 tab = strchr(buf, '\t');
1884 if (tab == NULL) {
1885 XtFree(start);
1886 return;
1887 }
1888 if (next != NULL) {
1889 next[0] = '\0';
1890 }
1891 holi = (struct holiday *) XtMalloc(sizeof(struct holiday));
1892 holi->text = XtMalloc(sizeof(char) * strlen(tab));
1893 sscanf(buf, "%d/%d/%d", &holi->month, &holi->day, &holi->year);
1894 strcpy(holi->text, tab + 1);
1895 (void) PushOnList(holilist, &holi);
1896 if (next == NULL) {
1897 XtFree(start);
1898 return;
1899 }
1900 buf = next + 1;
1901 len = strlen(buf);
1902 }
1903 XtFree(start);
1904 }
1905
1906