[alt.sources] Xkal - X appointment calendar, Part02/04

ferguson@cs.rochester.edu (George Ferguson) (11/15/90)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 4)."
# Contents:  xkal.man Xkal.ad.h day.c day.h db.h month.h util.h
#   widgets.h
# Wrapped by ferguson@swan.cs.rochester.edu on Mon Nov 12 14:07:06 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'xkal.man' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xkal.man'\"
else
echo shar: Extracting \"'xkal.man'\" \(13685 characters\)
sed "s/^X//" >'xkal.man' <<'END_OF_FILE'
X.\"
X.\"	Xkal : Graphical appointment calendar
X.\"
X.\"	George Ferguson, ferguson@cs.rochester.edu,  27 Oct 1990.
X.\"
X.\"	$Id: xkal.man,v 1.6 90/11/12 13:15:11 ferguson Exp $
X.\"
X.TH XKAL 1 "26/10/90"
X.ds ]W U of Rochester
X.SH NAME
Xxkal \- graphical appointment calendar
X
X.SH SYNOPSIS
X.B xkal
X[X\ Toolkit\ options]
X[-appoints\ filename]
X[-date\ date]
X[-listOnly]
X[-silent]
X[-numMonths\ 1|3|12]
X[-bothShown]
X[-nobothShown]
X[-opaqueDates]
X[-noopaqueDates]
X[-dowLabels]
X[-nodowLabels]
X[-help]
X
X.SH DESCRIPTION
X.PP
XXkal is a graphical appointment calendar that allows you to maintain
Xseveral types of appointments and weekly reminders, displays them in
Xseveral different formats, and allows you to add and edit them. Silent and
Xnon-graphic modes are provided to allow xkal to be used to check for
Xappointments without interaction.
X.PP
XThe general behaviour of xkal is to display one or more months. Clicking
XButton1 on a particular day displays that day's appointment information,
Xeither next to the month or in a popup window (see the
X.B bothShown
Xresource, below). The appointments can be editing within this window, and
Xchanges are automatically saved when the tool is exited. Changes can be
Xaborted or the appointments can be saved immediately using other actions.
XMost available actions are provided by a set of menuButtons above the month
Xdisplay. Clicking on these buttons displays a menu from which the desired
Xaction can be selected. (See below under Translation Actions for a list of
Xthe actions and ways to customize xkal's behaviour.)
X.PP
XXkal also manages weekly reminders. These can be edited by selecting
X"Edit Schedule" from the
X.B Other
Xmenu (by default). Note that if an appointment is specified for a
Xparticular day and time, it will override any weekly entry for that slot.
X
X.SH OPTIONS
X.PP
XThe following non-widget resources can be set on the command line as well
Xas in a resource file. As usual, they can be abbreviated to their shortest
Xunique prefix. Furthermore, xkal accepts all the standard X Toolkit
Xoptions.
X.IP "\fB-appoints\fP filename"
XUses the given filename as the name of the appointment file. The format of
Xthis file is described below under FILE FORMATS. A leading tilde (`~') is
Xexpanded to the value of $HOME. The default is `~/.appoints'.
X.IP "\fB-date\fP date"
XChanges xkal's notion of the current date (usually obtained from the
Xsystem). The date string should be as described below under DATE FORMATS,
Xwith whitespace escaped if given on the command line.
X.IP "\fB-listOnly\fP"
XIf given, then xkal simply lists the appointments and weekly reminders
Xto stdout, and exits without interaction. The exit status is the number of
Xappointements for the day, not including weekly reminders.
X.IP "\fB-silent\fP"
XLike above, but simply sets the exit status and doesn't print anything.
XUseful for checking whether there are any appointments.
X.IP "\fB-numMonths\fP 1|3|12"
XDetermines whether xkal will start displaying one, three, or twelve months.
XThis can be changed while xkal is running using the
X.B xkal-numMonths()
Xaction described below under Translation Actions. The default is to show one
Xmonth.
X.IP "\fB-bothShown\fP"
XIf given, then the day's appointments are displayed in the main tool
Xwindow, otherwise a popup window is created for them. When a day window is
Xpopped up, it becomes the selected window and subsequent appointment updates
Xare done in it. It can be selected and deselected using the buttons. If no
Xpopup window is selected when a day is clicked on, then a new popup window
Xwill be created. The
X.B Dismiss
Xbutton destroys the popup window.
X.IP "\fB-nobothShown\fP"
XThe opposite of
X.BR -bothShown .
X.IP "\fB-opaqueDates\fP"
XIf given, then the numbers in the dayButtons are drawn opaquely, which
Xsome people find easier to read when the day is stippled.
X.IP "\fB-noopaqueDates\fP"
XThe opposite of
X.BR -opaqueDates .
X.IP "\fB-dowLabels\fP"
XIf given, labels are provided at the top of each column in each month
Xindicating the day of the week.
X.IP "\fB-nodowLabels\fP"
XThe opposite of
X.BR -nodowLabels .
X.IP "\fB-help\fP"
XPrints the usage message, summarizing these options.
X
X.SH "CUSTOMIZING XKAL"
X.PP
XXkal has a default set of resources built in. If you wish to customize the
Xtool, take a copy of the default application defaults file (see
XFILES below) and modify it. Then, before invoking xkal, set the environment
Xvariable
X.B XAPPLRESDIR
Xto the directory containing your private copy. Alternatively, you can place
Xentries in your .Xdefaults file or provide them with the -xrm toolkit
Xoption.
X
X.SH "Widget hierarchy"
X.PP
XXkal uses standard Athena widgets which can be customized as usual.
XThe widget hierarchy is as follows:
X
X.ta 8,16,24,32,40,48,56,64
X.na
X.nf
X	TopLevelShell Xkal
X	    Form bothForm
X		MenuButton fileButton,viewButton,otherButton
X		Form allMonthsForm
X		Form dayForm [if bothShown is True]
X.fi
X.ad
X
XThe widget
X.B allMonthsForm
Xcontains the months, depending on the value of the
X.B numMonths
Xresource these will be Forms named
X.BR monthForm1 ,
X.B monthForm3
Xor
X.BR monthForm12 .
XThis separation of specification allows each type of display to be customized
Xseparately. Each monthForm will contain a Label
X.BR MonthLabel X
X(where X is 1, 3, or 12) and Toggles for the days named
X.BR dayButton X.
XIn order to correctly allocate resources, the size of these buttons must be
Xset in the non-widget resources
X.BR dateWidth X
Xand
X.BR dateHeight X,
Xrather than using the width and height resources of the
X.BR dayButton X.
XThe printing of the date in the
X.B dayButton
Xis controlled by the non-widget resources
X.BR dateFont X
Xand
X.BR datePosition X;
Xthis last should be a geometry string of the form `+x+y' taken as an offset
Xfrom the top left corner of the button.
X.PP
XIf
X.B bothShown
Xis not True, then the popup window looks like
X
X.na
X.nf
X	TransientShell popupShell
X	    Form popupForm
X		Command dismissButton,selectButton,unselectButton
X		Form dayForm
X.fi
X.ad
X
XIn either case, the
X.B dayForm
Xcontains a Label
X.B dayLabel
X(to display the date), and 22 instances of: a Label
X.B timeLabel
Xto display the time of the appointment, and an AsciiText
X.B textText
Xfor displaying and editing the appointment itself.
XThe relative positions of these are hard-coded and so cannot be
Xchanged using resources. The buttons' behaviours are hard-coded as
Xdescribed above for the
X.B -bothShown
Xoption.
X.PP
XXkal provides three menuButtons on the main window, called
X.BR fileButton ,
X.BR viewButton ,
Xand
X.BR otherButton .
XThey are all children of
X.BR bothForm .
XSince
X.B allMonthsForm
Xand
X.B dayForm
X(if
X.B bothShown
Xis True) are also children of
X.BR bothForm ,
Xthe buttons can be placed arbitrarily in the tool. The corresponding
XezMenu widgets
X.BR fileMenu ,
X.BR viewMenu ,
Xand
X.BR otherMenu
Xcan be customized to provide other actions if desired.
X.PP
XWhen the
X.B xkal-edit-schedule()
Xaction is invoked, a window is popped up to allow the weekly reminders
Xto be edited. This widget hierarchy is:
X
X.nf
X.na
X	TopLevelShell shchedulePopupShell
X	    Form popupForm
X		Command dismissSchedButton,applySchedButton
X		Form dayForm
X.ad
X.fi
X
Xwhere the
X.B dayForm
Xis as above (but smaller, by default). The functionality of these buttons
Xis hard-coded.
X
X.SH "Translation Actions"
X.PP
XThe following action procedures are registered for xkal and can be bound
Xto widget events using the
X.B translations
Xresource (see the Xt manual, Appendix C). Certain actions are hard-coded
Xto widget events (for example, setting the dayForm when a dayButton is
Xclicked on) since they are so essential to correct behaviour.
X.IP \fBxkal-quit()\fP
XUpdate the appointments file, destroy the tool, and exit with status 0.
XBy default this is performed by selecting
X.B Quit
Xfrom the fileMenu, or typing `q' in a dayButton.
X.IP \fBxkal-exit()\fP
XDestroy the tool and exit without saving any changes to the
Xappointments file. By default this is bound to selecting
X.B Exit
Xfrom the fileMenu, and to `x' in the dayButtons.
X.IP \fBxkal-save()\fP
XUpdates the appointments file, saving any changes. By default, this is
Xinvoked by the
X.B Save
Xentry of the fileMenu, or by typing `s'.
X.IP \fBxkal-next()\fP
XIf
X.B numMonths
Xis 1 or 3, this action will move the month display ahead to the next month.
XIf
X.B numMonths
Xis 12, it will move to the next year. By default this is provided by the
X.B Next
Xentry of the viewMenu, or by typing `n' in the dayButtons.
X.IP \fBxkal-prev()\fP
XLike above, but moves back one month or year. By default this is provided
Xby the
X.B Prev
Xentry of the viewMenu, and by typing `p'.
X.IP \fBxkal-today()\fP
XSelects the current date. Note that this can be altered by the
X.B -date
Xflag. By default thsi is available form the viewMenu or by typing `t'.
X.IP \fBxkal-numMonths(\fPnum\fB)\fP
XSet the month display to 1, 3, or 12, depending on the value of `num'.
XThis is provided by default by the three appropriately entries of the
XviewMenu, and by typing `1', `2', and `3' respectively. (I admit that those
Xkeys are somewhat unmnemonic.)
X.IP \fBxkal-edit-schedule()\fP
XPops up a (large) window displaying the schedule entries for an entire week.
XThe entries can be edited as normal, and when the
X.B Apply
Xbutton is clicked on they will become the current schedule and will be
Xsaved the next time the appointments are written. The
X.B Dismiss
Xbutton destroys this window without checking for applied changes.
X
X.SH "Patterns and Colors"
X.PP
XXkal indicates the number for appointments for a day in the month form
Xdifferently depending on the type of display. On a color display, the
Xnon-widget resources
X.BR color X
Xare used (where X ranges from 1 to 22) to indicate that there are X
Xappointments for that day. These entries can be symbolic color names or
XRGB specs, as described in X(1). On monochrome displays, the bitmaps given by
Xthe non-widget resources
X.BR shade X
Xare used to tile the dayButtons. These bitmaps are either absolute pathnames
Xor found in the directory given by the global resource
X.B bitmapFilePath
X(/usr/staff/include/X11/images by default). Finally, the non-widget
Xresource
X.B noDayShade
Xgives the bitmap to use to tile boxes in the monthForms which have no date.
X
X.SH "FILE FORMAT"
X.PP
XThe appointment file consists of two types of reminders:
X.BR appointments ,
Xwhich occur on a single day, and
X.BR "weekly reminders" ,
Xwhich occur each week. Leading whitespace and lines beginning with `#' are
Xignored.
X.PP
XAn appointment entry is formatted as
X
X.ce 1
X	dd mon yyyy hh:mm text
X
XAny amount of white space can separate the fields but they must all be
Xpresent. The day goes in the `dd' field and can be one or two digits,
Xthe `mon' field should be a standard UNIX abbreviation of the month
X(Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec), and the year
Xshould be four digits long in the `yyyy' field.
XThe time of the appointment in 24-hour format should be in `hh:mm' (the colon
Xmust be present), and the text of the reminder is taken up to a newline.
XAppointment entries are normally manipulated from within xkal.
X.PP
XA weekly reminder is formatted as
X
X.ce 1
X	dow hh:mm text
X
XThe same rules apply as above but `dow' is the standard UNIX three-character
Xabbreviation of the day of the week for the reminder (Mon, Tue, Wed, Thu, Fri,
XSat, Sun). Schedule entries can only be created using the "Edit Schedule"
Xitem of the
X.B Other
Xmenu (i.e. the action
X.BR xkal-edit-schedule() ).
X.PP
XAs mentioned, an appointment overrides a weekly reminder for the same day
Xand time, so although both may be in the file, only the appointment will
Xbe displayed. Similarly, editing a weekly reminder changes it into an
Xappointment for that day, although other weeks will still have the
Xreminder.
X
X.SH "DATE FORMAT"
X.PP
XWhen using the
X.B date
Xresource to change xkal's notion of the current date, the value of the
Xresource can be either an absolute or a relative date, as follows.
X.IP
XA relative date begins with either `+' or `-' followed by any
Xamount of `number'`specifer' pairs where `specifier' is one of
X`d', `m', or `y' indicating days, months, and years respectively.
XXkal's current date is set to the current system date offset by the relative
Xdate. For example:
X
X.ce 1
X	% xkal -listOnly -date +1d
X
Xwould list tomorrow's reminders, and
X
X.ce 1
X	% xkal -date +1d1y
X
Xwould start interaction at the day one year from tomorrow. If a number without
Xa specifier terminates a date, the specifier is taken to be `d' (so `+1' is the
Xsame as `+1d').
X.IP
XAn absolute date is specified by giving any of the day, month, or year desired.
XThe month should be a standard three-character UNIX abbreviation. A number less
Xthan 32 is taken to be a day, one greater than 31 specifies a year. Note that
Xyears less than 1900 have no meaning in UNIX and years less than 1970 will
Xconfuse the system time routines. Thus
X
X.ce 1
X	% xkal -date 25Dec\ \ and\ \ % xkal -date Dec25
X
Xspecify Christmas of the current year,
X
X.ce 1
X	% xkal -date 'Dec 1925'
X
Xspecifies today's day in December of 1925, and
X
X.ce 1
X	% xkal -date 25Dec1925
X
Xspecifies Christmas Day, 1925. Note that spaces are allowed within a date
Xbut must be escaped from the shell if given on the command line.
X
X.SH ENVIRONMENT
X.PP
XXAPPLRESDIR	- Directory containing xkal resource file
X
X.SH FILES
X.PP
X.nf
X.na
X~/.appoints				- default appointment file
X/u/ferguson/lib/app-defaults/Xkal	- default xkal resource file
X.ad
X.fi
X
X.SH DIAGNOSTICS
X.PP
XThe conversion message "cannot convert NULL to widget" is unfortunately
Xunavoidable.
X.PP
XXkal complains about incorrectly formatted appoinment entries, specifying
Xthe exact location of the error. These messages go to stderr.
X
X.SH "SEE ALSO"
X.PP
XX(1),
Xkal(1),
Xcal(1),
Xcalend(1),
Xcalendar(1).
X.sp
X.SH AUTHOR
X.PP
XGeorge Ferguson, University of Rochester
X.br
X(ferguson@cs.rochester.edu)
END_OF_FILE
if test 13685 -ne `wc -c <'xkal.man'`; then
    echo shar: \"'xkal.man'\" unpacked with wrong size!
fi
# end of 'xkal.man'
fi
if test -f 'Xkal.ad.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Xkal.ad.h'\"
else
echo shar: Extracting \"'Xkal.ad.h'\" \(7008 characters\)
sed "s/^X//" >'Xkal.ad.h' <<'END_OF_FILE'
X"Xkal.revision:                  $Revision: 1.8 $",
X"Xkal.title:			Xkal 1.0 (beta)",
X"Xkal.appoints:			~/.appoints",
X"Xkal.bothShown:			True",
X"Xkal.numMonths:			1",
X"Xkal.opaqueDates:		False",
X"Xkal.dowLabels:			False",
X"Xkal*allowShellResize: True",
X"Xkal*Form.defaultDistance:	0",
X"Xkal*bothForm.defaultDistance:	2",
X"Xkal*fileButton.label:		File",
X"Xkal*fileButton.menuName:	fileMenu",
X"Xkal*fileMenu.menu:\
X	(item \"File\") \
X	(line) \
X	(item \"[S] Save\" (action \"xkal-save()\")) \
X	(item \"[Q] Quit\" (action \"xkal-quit()\")) \
X	(item \"[X] Exit\" (action \"xkal-exit()\"))",
X"Xkal*viewButton.label:		View",
X"Xkal*viewButton.fromHoriz:	fileButton",
X"Xkal*viewButton.menuName:	viewMenu",
X"Xkal*viewMenu.menu:\
X	(item \"View\") \
X	(line) \
X	(item \"[N] Next\" (action \"xkal-next()\")) \
X	(item \"[P] Prev\" (action \"xkal-prev()\")) \
X	(item \"[T] Today\" (action \"xkal-today()\")) \
X	(item \"[1] 1 Month\" (action \"xkal-numMonths(1)\")) \
X	(item \"[2] 3 Months\" (action \"xkal-numMonths(3)\")) \
X	(item \"[3] 12 Months\" (action \"xkal-numMonths(12)\"))",
X"Xkal*otherButton.label:		Other",
X"Xkal*otherButton.fromHoriz:	viewButton",
X"Xkal*otherButton.menuName:	otherMenu",
X"Xkal*otherMenu.menu:\
X	(item \"Other\") \
X	(line) \
X	(item \"[E] Edit schedule\" (action \"xkal-edit-schedule()\"))",
X"Xkal*allMonthsForm.fromVert:		fileButton",
X"Xkal*allMonthsForm*resizable:		True",
X"Xkal*allMonthsForm*internalWidth:	1",
X"Xkal*allMonthsForm*internalHeight:	1",
X"Xkal*allMonthsForm*translations:#override\\n\
X	<Key>Q:		xkal-quit() \\n\
X	<Key>X:		xkal-exit() \\n\
X	<Key>N:		xkal-next() \\n\
X	<Key>P:		xkal-prev() \\n\
X	<Key>T:		xkal-today() \\n\
X	<Key>S:		xkal-save() \\n\
X	<Key>E:		xkal-edit-schedule() \\n\
X	<Key>1:		xkal-numMonths(1) \\n\
X	<Key>2:		xkal-numMonths(3) \\n\
X	<Key>3:		xkal-numMonths(12) \\n",
X"Xkal*monthForm1.fromHoriz:	NULL",
X"Xkal*monthForm1.fromVert:	NULL",
X"Xkal*monthForm3_1.fromHoriz:	NULL",
X"Xkal*monthForm3_1.fromVert:	NULL",
X"Xkal*monthForm3_2.fromVert:	monthForm3_1",
X"Xkal*monthForm3_3.fromVert:	monthForm3_2",
X"Xkal*monthForm12_1.fromHoriz:	NULL",
X"Xkal*monthForm12_1.fromVert:	NULL",
X"Xkal*monthForm12_2.fromHoriz:	monthForm12_1",
X"Xkal*monthForm12_3.fromHoriz:	monthForm12_2",
X"Xkal*monthForm12_4.fromHoriz:	monthForm12_3",
X"Xkal*monthForm12_5.fromVert:	monthForm12_1",
X"Xkal*monthForm12_6.fromHoriz:	monthForm12_5",
X"Xkal*monthForm12_6.fromVert:	monthForm12_2",
X"Xkal*monthForm12_7.fromHoriz:	monthForm12_6",
X"Xkal*monthForm12_7.fromVert:	monthForm12_3",
X"Xkal*monthForm12_8.fromHoriz:	monthForm12_7",
X"Xkal*monthForm12_8.fromVert:	monthForm12_4",
X"Xkal*monthForm12_9.fromVert:	monthForm12_5",
X"Xkal*monthForm12_10.fromHoriz:	monthForm12_9",
X"Xkal*monthForm12_10.fromVert:	monthForm12_6",
X"Xkal*monthForm12_11.fromHoriz:	monthForm12_10",
X"Xkal*monthForm12_11.fromVert:	monthForm12_7",
X"Xkal*monthForm12_12.fromHoriz:	monthForm12_11",
X"Xkal*monthForm12_12.fromVert:	monthForm12_8",
X"Xkal*monthLabel1.font:		*fixed*bold*",
X"Xkal*monthLabel1.borderWidth:	0",
X"Xkal*monthLabel1.justify:	center",
X"Xkal*monthLabel1.width:		376",
X"Xkal*monthLabel1.resize:	False",
X"Xkal*monthLabel3.font:		6x9",
X"Xkal*monthLabel3.borderWidth:	0",
X"Xkal*monthLabel3.justify:	center",
X"Xkal*monthLabel3.width:		201",
X"Xkal*monthLabel3.resize:	False",
X"Xkal*monthLabel12.font:		5x8",
X"Xkal*monthLabel12.borderWidth:	0",
X"Xkal*monthLabel12.justify:	center",
X"Xkal*monthLabel12.width:	131",
X"Xkal*monthLabel12.resize:	False",
X"Xkal*dowLabel1.font:		*fixed*bold*",
X"Xkal*dowLabel1.borderWidth:	1",
X"Xkal*dowLabel1.width:		52",
X"Xkal*dowLabel1.resize:		False",
X"Xkal*dowLabel3.font:		6x9",
X"Xkal*dowLabel3.borderWidth:	1",
X"Xkal*dowLabel3.width:		27",
X"Xkal*dowLabel3.resize:		False",
X"Xkal*dowLabel12.font:		5x8",
X"Xkal*dowLabel12.borderWidth:	1",
X"Xkal*dowLabel12.width:		17",
X"Xkal*dowLabel12.resize:		False",
X"Xkal.dateFont1:			*fixed*bold*",
X"Xkal.datePosition1:		+10+10",
X"Xkal.dateWidth1:		50",
X"Xkal.dateHeight1:		50",
X"Xkal.dateFont3:			6x9",
X"Xkal.datePosition3:		+0+6",
X"Xkal.dateWidth3:		25",
X"Xkal.dateHeight3:		25",
X"Xkal.dateFont12:		5x8",
X"Xkal.datePosition12:		+0+6",
X"Xkal.dateWidth12:		15",
X"Xkal.dateHeight12:		15",
X"Xkal*popupForm.defaultDistance:	2",
X"Xkal*dayForm.defaultDistance:	4",
X"Xkal*TopLevelShell.title:	Xkal Day Window",
X"Xkal*popupForm*dayForm.fromVert:	dismissButton",
X"Xkal*popupForm*dayForm.borderWidth:	0",
X"Xkal*bothForm*dayForm.fromHoriz:	allMonthsForm",
X"Xkal*bothForm*dayForm.fromVert:		fileButton",
X"Xkal*dismissButton.label:		Dismiss",
X"Xkal*selectButton.label:		Select",
X"Xkal*selectButton.fromHoriz:		dismissButton",
X"Xkal*unselectButton.label:		Unselect",
X"Xkal*unselectButton.fromHoriz:		selectButton",
X"Xkal*dayLabel.justify:		center",
X"Xkal*dayLabel.width:		230",
X"Xkal*dayLabel.borderWidth:	0",
X"Xkal*dayLabel.label:		Xkal 1.0(alpha)",
X"Xkal*timeLabel.font:		fixed",
X"Xkal*timeLabel.borderWidth:	0",
X"Xkal*timeLabel.vertDistance:	2",
X"Xkal*textText*font:			fixed",
X"Xkal*textText.width:			200",
X"Xkal*textText.height:			20",
X"Xkal*textText.vertDistance:		2",
X"Xkal*textText.borderWidth:		0",
X"Xkal*textText.topMargin:		0",
X"Xkal*textText*editType:			edit",
X"Xkal*textText*resize:			True",
X"Xkal*textText*displayCaret:		False",
X"Xkal*textText.scrollHorizontal:		whenNeeded",
X"Xkal*textText*Scrollbar.thickness:	5",
X"Xkal*textText.translations:#override\\n\
X	<Enter>:	display-caret(True) \\n\
X	<Leave>:	display-caret(False) \\n\
X	<Key>Return:	no-op() \\n",
X"Xkal*schedulePopupShell.title:		Xkal Schedule Window",
X"Xkal*dismissSchedButton.label:		Dismiss",
X"Xkal*applySchedButton.label:		Apply",
X"Xkal*applySchedButton.fromHoriz:	dismissSchedButton",
X"Xkal*schedulePopupShell*dayForm.fromVert: dismissSchedButton",
X"Xkal*schedulePopupShell*dayForm*font:	5x8",
X"Xkal*schedulePopupShell*Text*width:	100",
X"Xkal*schedulePopupShell*Text*height:	12",
X"Xkal*schedulePopupShell*Text*Scrollbar.height:	3",
X"Xkal.noDayShade:	cross_weave",
X"Xkal.shade1:		gray3",
X"Xkal.shade2:		gray3",
X"Xkal.shade3:		light_gray",
X"Xkal.shade4:		light_gray",
X"Xkal.shade5:		gray",
X"Xkal.shade6:		gray",
X"Xkal.shade7:		flipped_gray",
X"Xkal.shade8:		flipped_gray",
X"Xkal.shade9:		flipped_gray",
X"Xkal.shade10:		flipped_gray",
X"Xkal.shade11:		flipped_gray",
X"Xkal.shade12:		flipped_gray",
X"Xkal.shade13:		flipped_gray",
X"Xkal.shade14:		flipped_gray",
X"Xkal.shade15:		flipped_gray",
X"Xkal.shade16:		flipped_gray",
X"Xkal.shade17:		flipped_gray",
X"Xkal.shade18:		flipped_gray",
X"Xkal.shade19:		flipped_gray",
X"Xkal.shade20:		flipped_gray",
X"Xkal.shade21:		flipped_gray",
X"Xkal.shade22:		flipped_gray",
X"Xkal.color1:		green",
X"Xkal.color2:		green",
X"Xkal.color3:		blue",
X"Xkal.color4:		blue",
X"Xkal.color5:		yellow",
X"Xkal.color6:		yellow",
X"Xkal.color7:		red",
X"Xkal.color8:		red",
X"Xkal.color9:		red",
X"Xkal.color10:		red",
X"Xkal.color11:		red",
X"Xkal.color12:		red",
X"Xkal.color13:		red",
X"Xkal.color14:		red",
X"Xkal.color15:		red",
X"Xkal.color16:		red",
X"Xkal.color17:		red",
X"Xkal.color18:		red",
X"Xkal.color19:		red",
X"Xkal.color20:		red",
X"Xkal.color21:		red",
X"Xkal.color22:		red",
END_OF_FILE
if test 7008 -ne `wc -c <'Xkal.ad.h'`; then
    echo shar: \"'Xkal.ad.h'\" unpacked with wrong size!
fi
# end of 'Xkal.ad.h'
fi
if test -f 'day.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'day.c'\"
else
echo shar: Extracting \"'day.c'\" \(5326 characters\)
sed "s/^X//" >'day.c' <<'END_OF_FILE'
X/*
X *	day.c : The day windows
X *
X *	$Id: day.c,v 1.1 90/11/07 11:22:38 ferguson Exp $
X */
X#include <X11/Intrinsic.h>
X#include <X11/Shell.h>
X#include <X11/StringDefs.h>
X#include <X11/Xaw/Form.h>
X#include <X11/Xaw/Command.h>
X#include <X11/Xaw/Label.h>
X#include <X11/Xaw/AsciiText.h>
X#include <X11/Xaw/Cardinals.h>
X#include "widgets.h"
X#include "month.h"
X#include "day.h"
X#include "db.h"
X#include "date-strings.h"
X
Xextern int appointsChanged;
X
X/*
X * Functions defined in this file
X */
XDayFormData *createDayFormData(),*createPopupDayFormData();
Xvoid setDayFormData();
Xvoid checkpointAppoints();
X
Xstatic void textEventProc(),dismissProc(),selectProc(),unselectProc();
X
X/*
X * Data defined in this file
X */
XDayFormData *currentDayFormData;
X
Xstatic int dayAppointsChanged;		/* fast, local check */
X
X/*	-	-	-	-	-	-	-	-	*/
X
XDayFormData *
XcreateDayFormData(parent)
XWidget parent;
X{
X    DayFormData *d;
X    DayTextData *t;
X    Arg args[3];
X    int i;
X    char *time="XX:XX";
X
X    d = XtNew(DayFormData);
X    d->form = XtCreateManagedWidget("dayForm",formWidgetClass,parent,
X								NULL,ZERO);
X    d->date = XtCreateManagedWidget("dayLabel",labelWidgetClass,d->form,
X								NULL,ZERO);
X    XtSetArg(args[0],XtNfromVert,d->date);
X    for (i = 0; i < 22; i++) {
X	t = d->items[i] = XtNew(DayTextData);
X	XtSetArg(args[1],XtNfromHoriz,NULL);
X	if (i < 20)
X	    sprintf(time,"%2d:%02d",8+i/2,i%2*30);
X	else
X	    sprintf(time,"NOTES");
X	XtSetArg(args[2],XtNlabel,time);
X	t->time = XtCreateManagedWidget("timeLabel",labelWidgetClass,
X							d->form,args,THREE);
X	XtSetArg(args[1],XtNfromHoriz,t->time);
X	t->text = XtCreateManagedWidget("textText",asciiTextWidgetClass,
X							d->form,args,TWO);
X	XtAddEventHandler(t->text,KeyPressMask,False,textEventProc,NULL);
X	XtSetArg(args[0],XtNfromVert,t->time);
X    }
X    return(d);
X}
X
XDayFormData *
XcreatePopupDayFormData()
X{
X    Widget shell,form,select,dismiss,unselect;
X    DayFormData *d;
X
X    shell = XtCreatePopupShell("popupShell",topLevelShellWidgetClass,
X							toplevel,NULL,ZERO);
X    form = XtCreateManagedWidget("popupForm",formWidgetClass,shell,
X								NULL,ZERO);
X    dismiss = XtCreateManagedWidget("dismissButton",commandWidgetClass,form,
X								NULL,ZERO);
X    select = XtCreateManagedWidget("selectButton",commandWidgetClass,form,
X								NULL,ZERO);
X    unselect = XtCreateManagedWidget("unselectButton",commandWidgetClass,form,
X								NULL,ZERO);
X    d = createDayFormData(form);
X    d->shell = shell;
X    XtAddCallback(select,"callback",selectProc,d);
X    XtAddCallback(dismiss,"callback",dismissProc,d);
X    XtAddCallback(unselect,"callback",unselectProc,d);
X    XtPopup(shell,XtGrabNone);
X    return(d);
X}
X
Xstatic void
XtextEventProc(w,client_data,event,continue_flag)
XWidget w;
XXtPointer client_data;
XXEvent *event;
XBoolean *continue_flag;
X{
X    dayAppointsChanged = True;
X}
X
Xstatic void
XdismissProc(w,client_data,call_data)
XWidget w;
Xcaddr_t client_data,call_data;
X{
X    DayFormData *d = (DayFormData *)client_data;
X
X    checkpointAppoints(d);
X    if (currentDayFormData == d)
X	currentDayFormData = NULL;
X    XtPopdown(d->shell);
X    XtDestroyWidget(d->shell);
X}
X
Xstatic void
XselectProc(w,client_data,call_data)
XWidget w;
Xcaddr_t client_data,call_data;
X{
X    DayFormData *d = (DayFormData *)client_data;
X
X    checkpointAppoints(d);
X    if (currentDayFormData == d)
X	return;
X    if (currentDayFormData != NULL)
X	XtSetSensitive(currentDayFormData->form,False);
X    XtSetSensitive(d->form,True);
X    currentDayFormData = d;
X}
X
Xstatic void
XunselectProc(w,client_data,call_data)
XWidget w;
Xcaddr_t client_data,call_data;
X{
X    DayFormData *d = (DayFormData *)client_data;
X
X    checkpointAppoints(d);
X    XtSetSensitive(d->form,False);
X    currentDayFormData = NULL;
X}
X
Xvoid
XsetDayFormData(d,day,month,year)
XDayFormData *d;
Xint day,month,year;
X{
X    char text[32];
X    Arg args[1];
X    char *s;
X    int i;
X
X    sprintf(text,"%s %d %s %d",shortDayStr[computeDOW(day,month,year)],day,
X						shortMonStr[month],year+1900);
X    XtSetArg(args[0],XtNlabel,text);
X    XtSetValues(d->date,args,ONE);
X    for (i=0; i < 22; i++) {
X	if ((s=lookupAppoint(i,day,month,year)) != NULL) {
X	    XtSetArg(args[0],XtNstring,s);
X	    XtSetValues(d->items[i]->text,args[0],ONE);
X	} else if ((s=lookupSchedule(i,day,month,year)) != NULL) {
X	    XtSetArg(args[0],XtNstring,s);
X	    XtSetValues(d->items[i]->text,args[0],ONE);
X	} else {
X	    XtSetArg(args[0],XtNstring,"");
X	    XtSetValues(d->items[i]->text,args[0],ONE);
X	}
X    }
X    d->day = day;
X    d->month = month;
X    d->year = year;
X}
X
Xvoid
XcheckpointAppoints(d)
XDayFormData *d;
X{
X    Arg args[1];
X    int i;
X    char *new,*sch,*app;
X
X    if (!dayAppointsChanged)
X	return;
X    XtSetArg(args[0],XtNstring,&new);
X    for (i=0; i < 22; i++) {
X	XtGetValues(d->items[i]->text,args,ONE);
X	sch = lookupSchedule(i,d->day,d->month,d->year);
X	app = lookupAppoint(i,d->day,d->month,d->year);
X	if (*new != '\0') {
X	    if ((app != NULL && strcmp(new,app) != 0) ||
X		(sch != NULL && strcmp(new,sch) != 0) ||
X		(app == NULL && sch == NULL)) {
X		addAppoint(i,d->day,d->month,d->year,new);
X		appointsChanged = True;
X	    }
X	} else if (app != NULL) {
X	    deleteAppoint(i,d->day,d->month,d->year);
X	    appointsChanged = True;
X	}
X    }
X    dayAppointsChanged = False;
X    if (currentDayFormData != NULL)
X	shadeButton(currentDayFormData->buttonData,(GC)NULL,0,0);
X}
END_OF_FILE
if test 5326 -ne `wc -c <'day.c'`; then
    echo shar: \"'day.c'\" unpacked with wrong size!
fi
# end of 'day.c'
fi
if test -f 'day.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'day.h'\"
else
echo shar: Extracting \"'day.h'\" \(714 characters\)
sed "s/^X//" >'day.h' <<'END_OF_FILE'
X/*
X *	day.h : Data types and external defs for day stuff
X *
X *	$Id: day.h,v 1.1 90/11/07 11:22:41 ferguson Exp $
X *
X *	Requires month.h (which is probably needed anyway).
X */
Xtypedef struct _DayTextData {
X	Widget symbol;		/* Label */
X	Widget time;		/* Label */
X	Widget text;		/* Text */
X} DayTextData;
Xtypedef struct _DayFormData {
X	int day,month,year;
X	DayTextData *items[22];
X	Widget date;		/* Label */
X	Widget form;		/* Form */
X	Widget shell;		/* Shell for popups */
X	DayButtonData *buttonData;	/* button pressed if any */
X} DayFormData;
X
Xextern DayFormData *createDayFormData(),*createPopupDayFormData();
Xextern void setDayFormData();
Xextern void checkpointAppoints();
X
Xextern DayFormData *currentDayFormData;
END_OF_FILE
if test 714 -ne `wc -c <'day.h'`; then
    echo shar: \"'day.h'\" unpacked with wrong size!
fi
# end of 'day.h'
fi
if test -f 'db.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'db.h'\"
else
echo shar: Extracting \"'db.h'\" \(449 characters\)
sed "s/^X//" >'db.h' <<'END_OF_FILE'
X/*
X *	db.h : External defs for database users.
X *
X *      George Ferguson (ferguson@cs.rochester.edu), 27 Oct 1990.
X *
X *	$Id: db.h,v 1.2 90/11/07 11:22:52 ferguson Exp $
X */
X
Xextern void initDb(), addAppoint(), deleteAppoint();
Xextern void addScheduleDow(), addAppoint();
Xextern void deleteScheduleDow(), deleteSchedule();
Xextern char *lookup(),*lookupAppoint(),*lookupScheduleDow(),*lookupSchedule();
Xextern void readAppoints(), writeAppoints();
X
END_OF_FILE
if test 449 -ne `wc -c <'db.h'`; then
    echo shar: \"'db.h'\" unpacked with wrong size!
fi
# end of 'db.h'
fi
if test -f 'month.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'month.h'\"
else
echo shar: Extracting \"'month.h'\" \(554 characters\)
sed "s/^X//" >'month.h' <<'END_OF_FILE'
X/*
X *	month.h : Data types and external defs for month stuff
X *
X *	George Ferguson (ferguson@cs.rochester.edu), 27 Oct 1990.
X *
X *	$Id: month.h,v 1.1 90/11/07 11:23:04 ferguson Exp $
X */
X
Xtypedef struct _DayButtonData {
X	int day,month,year;
X	Pixmap pixmap;
X	Widget button;		/* Command */
X} DayButtonData;
Xtypedef struct _MonthFormData {
X	int month,year;
X	DayButtonData *days[42];
X	Widget label;		/* Label */
X	Widget form;		/* Form */
X} MonthFormData;
X
Xextern MonthFormData *createMonthFormData();
Xextern void setMonthFormData();
Xextern void selectDay();
END_OF_FILE
if test 554 -ne `wc -c <'month.h'`; then
    echo shar: \"'month.h'\" unpacked with wrong size!
fi
# end of 'month.h'
fi
if test -f 'util.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util.h'\"
else
echo shar: Extracting \"'util.h'\" \(322 characters\)
sed "s/^X//" >'util.h' <<'END_OF_FILE'
X/*
X *	util.h : External defs for callers of misc routines.
X *
X *      George Ferguson (ferguson@cs.rochester.edu), 27 Oct 1990.
X *
X *      $Id: util.h,v 1.1 90/10/28 13:05:16 ferguson Exp $
X *
X */
X
Xextern int computeDOW(), firstDOW(), lastDay(), nextDay(), prevDay();
Xextern void getCurrentDate();
Xextern int parseDate();
END_OF_FILE
if test 322 -ne `wc -c <'util.h'`; then
    echo shar: \"'util.h'\" unpacked with wrong size!
fi
# end of 'util.h'
fi
if test -f 'widgets.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'widgets.h'\"
else
echo shar: Extracting \"'widgets.h'\" \(351 characters\)
sed "s/^X//" >'widgets.h' <<'END_OF_FILE'
X/*
X *	widgets.h : Linkage, more linkage.
X *
X *	George Ferguson (ferguson@cs.rochester.edu), 27 Oct 1990.
X *
X *	$Id: widgets.h,v 1.2 90/11/07 11:23:26 ferguson Exp $
X *
X */
X
Xextern XtAppContext app_con;
Xextern Widget toplevel;
X
Xextern Display *display;
Xextern Screen *screen;
Xextern Window root;
Xextern GC dateGC1,dateGC3,dateGC12,emptyGC,shadeGC[23];
END_OF_FILE
if test 351 -ne `wc -c <'widgets.h'`; then
    echo shar: \"'widgets.h'\" unpacked with wrong size!
fi
# end of 'widgets.h'
fi
echo shar: End of archive 2 \(of 4\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 4 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
George Ferguson			ARPA: ferguson@cs.rochester.edu
University of Rochester		UUCP: {decvax,rutgers}!rochester!ferguson
Rochester  NY  14627		VOX:  (716) 275-2527