v13i004: xcal, Part04/04

Peter Collinson pc at hillside.co.uk
Mon May 13 06:26:38 AEST 1991


Submitted-by: Peter Collinson <pc at hillside.co.uk>
Posting-number: Volume 13, Issue 4
Archive-name: xcal/part04

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	xcal_cal.c
#	xcal.h
#	xcal_help.c
#	xcal_memo.c
#	xcal_strip.c
# This archive created: Wed May  8 09:14:09 1991
export PATH; PATH=/bin:$PATH
echo shar: extracting "'xcal_cal.c'" '(5025 characters)'
if test -f 'xcal_cal.c'
then
	echo shar: will not over-write existing file "'xcal_cal.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'xcal_cal.c'
	X#ifndef lint
	Xstatic char *sccsid = "@(#)xcal_cal.c	1.1 (Hillside Systems) 7/14/90";
	X#endif  /* lint */
	X/***
	X
	X* program name:
	X	xcal_cal.c
	X* function:
	X	read files generated by xcal and produce a file compatible
	X	with the standard "calendar" utility
	X* switches:
	X	-d dir	use "dir" instead of "Calendar"
	X	-f file use "file" instead of .xcal
	X	-m	copy all of multi-line entries
	X* history:
	X	Written July, 1990
	X	Ed Gould
	X	mt Xinu, Inc.
	X* (C) Copyright: 1990 mt Xinu, Inc.
	X	
	X	Permission to use, copy, modify, and distribute this software
	X	and its documentation for any purpose is hereby granted to
	X	anyone, provided that the above copyright notice appear in
	X	all copies and that both that copyright notice and this
	X	permission notice appear in supporting documentation, and
	X	that the names of Ed Gould and mt Xinu, Inc. not be used
	X	in advertising or publicity pertaining to distribution of
	X	the software without specific, written prior permission.
	X	mt Xinu, Inc. makes no representations about the suitability
	X	of this software for any purpose.  It is provided "as is"
	X	without express or implied warranty.
	X
	X	Ed Gould and mt Xinu, Inc. DISCLAIM ALL WARRANTIES WITH
	X	REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
	X	OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL Ed Gould
	X	or mt Xinu, Inc. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
	X	CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
	X	FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
	X	CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
	X	OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
	X	SOFTWARE.
	X
	X***/
	X#include <stdio.h>
	X#include <ctype.h>
	X#include <sys/param.h>
	X#include <sys/types.h>
	X#ifdef SYSV
	X#include <dirent.h>
	X#include <string.h>
	X#else
	X#include <strings.h>
	X#endif
	X#include <sys/dir.h>
	X#include <time.h>
	X
	X
	X#ifdef SYSV
	X#define	index	strchr
	X#endif
	Xchar	*directory	= "Calendar";
	Xchar	*file		= ".xcal";
	Xchar	*home;
	Xchar	usedir[MAXPATHLEN];
	Xchar	usefile[MAXPATHLEN];
	Xchar	line[BUFSIZ];
	X
	Xchar	*months[]	= {"jan", "feb", "mar", "apr", "may", "jun",
	X			   "jul", "aug", "sep", "oct", "nov", "dec"};
	X
	Xint	debug;
	Xint	mflag;
	X
	XFILE	*out;
	X
	Xvoid
	Xmain(argc, argv)
	X	char **argv;
	X{
	X	register int c;
	X	time_t now;
	X	register struct tm *lt;
	X	char *getenv();
	X
	X	while((c = getopt(argc, argv, "d:f:m#")) != EOF) {
	X		extern char *optarg;
	X
	X		switch (c) {
	X
	X		case 'd':
	X			directory = optarg;
	X			break;
	X
	X		case 'f':
	X			file = optarg;
	X			break;
	X
	X		case 'm':
	X			mflag++;
	X			break;
	X
	X		case '#':
	X			debug++;
	X			break;
	X
	X		case '?':
	X		default:
	X			fprintf(stderr, "usage: %s [-d dir] [-f file]\n",
	X								argv[0]);
	X			exit(1);
	X		}
	X	}
	X	home = getenv("HOME");
	X	/*
	X	 * For both directory and output file, 
	X	 *
	X	 *   /...	is absolute path
	X	 *   ./...	is relative to current directory
	X	 *
	X	 * otherwise, relative to $HOME, if available
	X	 */
	X	if(file[0] == '/' || (file[0] == '.' && file[1] == '/') ||
	X	   home == NULL)
	X		strcpy(usefile, file);
	X	else
	X		sprintf(usefile, "%s/%s", home, file);
	X	if(debug)
	X		fprintf(stderr, "output to %s\n", usefile);
	X	if((out = fopen(usefile, "w")) == NULL) {
	X		perror(usefile);
	X		exit(1);
	X	}
	X	now = time((time_t *)NULL);
	X	lt = localtime(&now);
	X	calfiles(directory, lt->tm_year + 1900, lt->tm_mon, lt->tm_mday);
	X	if(lt->tm_mday >= 25 ) {
	X		/*
	X		 * close to end of month: include next month, too
	X		 */
	X		if(lt->tm_mon == 11)
	X			calfiles(directory, lt->tm_year + 1900 + 1, 0, 1);
	X		else
	X			calfiles(directory, lt->tm_year + 1900,
	X							lt->tm_mon + 1, 1);
	X	}
	X}
	X
	Xcalfiles(dir, year, thismonth, today)
	X	register char *dir;
	X{
	X	register DIR *dp;
	X	register char *to;
	X	register char *from;
	X	register struct direct *d;
	X	char day[3];
	X	char month[4];
	X
	X	if(dir[0] == '/' || (dir[0] == '.' && dir[1] == '/') ||
	X	   home == NULL)
	X		sprintf(usedir, "%s/xy%4d", dir, year);
	X	else
	X		sprintf(usedir, "%s/%s/xy%4d", home, dir, year);
	X	if(debug)
	X		fprintf(stderr, "looking in directory %s\n", usedir);
	X	if((dp = opendir(usedir)) == NULL) {
	X		perror(usedir);
	X		exit(1);
	X	}
	X	while((d = readdir(dp)) != NULL) {
	X		register FILE *in;
	X
	X		if(d->d_name[0] != 'x' || d->d_name[1] != 'c' ||
	X		   !isascii(d->d_name[2]) || !isdigit(d->d_name[2]))
	X			continue;
	X		sprintf(usefile, "%s/%s", usedir, d->d_name);
	X		if(debug)
	X			fprintf(stderr, "looking in file %s\n", usefile);
	X		if((in = fopen(usefile, "r")) == NULL) {
	X			if(debug)
	X				perror(usefile);
	X			continue;
	X		}
	X		from = &d->d_name[2];
	X		to = day;
	X		while(isascii(*from) && isdigit(*from))
	X			*to++ = *from++;
	X		*to = '\0';
	X		to = month;
	X		while(isascii(*from) && !isdigit(*from)) {
	X			if(isupper(*from))
	X				*from = tolower(*from);
	X			*to++ = *from++;
	X		}
	X		*to = '\0';
	X		if(strcmp(month, months[thismonth]) != 0 ||
	X		   atoi(day) < today) {
	X			if(debug)
	X				fprintf(stderr, "\tskipped - date\n");
	X			fclose(in);
	X			continue;
	X		}
	X		while(fgets(line, sizeof(line), in) != NULL) {
	X			if((to = index(line, '\n')) != NULL)
	X				*to = '\0';
	X			if(debug)
	X				fprintf(stderr, "==>\t%s %s\t%s\n", month,
	X								day, line);
	X			fprintf(out, "%s %s\t%s\n", month, day, line);
	X			if(mflag == 0)
	X				break;
	X		}
	X		fclose(in);
	X	}
	X}
SHAR_EOF
if test 5025 -ne "`wc -c < 'xcal_cal.c'`"
then
	echo shar: error transmitting "'xcal_cal.c'" '(should have been 5025 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'xcal.h'" '(6035 characters)'
if test -f 'xcal.h'
then
	echo shar: will not over-write existing file "'xcal.h'"
else
sed 's/^	X//' << \SHAR_EOF > 'xcal.h'
	X/*
	X *	xcal.h	3.14	1/16/91
	X *
	X *	Header file for the xcal program
	X */
	X
	X/*
	X *	On 32 bit machines we can pack the date into one word
	X *	if not we have to use two callbacks
	X *	so undef if not true
	X *	and fiddle with the definitions below
	X */
	X/* #define	LONG_IS_32_BITS */
	X
	X/* pack year and month into Cardinals */
	X#ifdef LONG_IS_32_BITS
	X#define	DatePack(w, d, m, y)	((((w)&0x7)<<21) | (((d)&0x1f)<<16) | (((m)&0xf)<<12) | ((y)&0xfff))
	X#define YrUnpack(v)	((v)&0xfff)
	X#define MoUnpack(v)	(((v)>>12)&0xf)
	X#define DyUnpack(v)	(((v)>>16)&0x1f)
	X#define WdUnpack(v)	(((v)>>21)&0x7)
	X#else /*  LONG_IS_32_BITS */
	X#define	DatePack(m, y)	((((m)&0xf)<<12) | ((y)&0xfff))
	X#define DayPack(w, d)	((((w)&0x7)<<5) | ((d)&0x1f))
	X#define YrUnpack(v)	((v)&0xfff)
	X#define MoUnpack(v)	(((v)>>12)&0xf)
	X#define DyUnpack(v)	((v)&0x1f)
	X#define WdUnpack(v)	(((v)>>5)&0xf)
	X#endif /* LONG_IS_32_BITS */
	X
	X/*
	X *	Foreground/Background colours
	X */
	Xtypedef struct
	X{	Pixel	bg;
	X	Pixel	fg;
	X} Colour;
	X
	X/*
	X *	resources used by xcal.c
	X */
	Xstruct resources
	X{	Boolean	debug;		/* Debug switch - currently used to fast fwd */
	X				/* the date */
	X	Boolean	alarmScan;	/* Debug switch for alarm system */
	X	Boolean	reverseVideo;	/* Display in Reverse video */
	X	Boolean	useWmTitle;	/* When displaying strips do not include a */
	X				/* month - year value */
	X	Boolean	markToday;	/* Mark today with today's colours */
	X	Boolean	calCompat;	/* True if handle files like xcalendar */
	X	Boolean giveHelp;	/* True if help is needed (default) */
	X	Boolean initialCalendar;/* Pop up Calendar on startup if True */
	X	Boolean initialEdit;	/* Pop up today's Edit on startup if True */
	X	Boolean	initialMemo;	/* Pop up memo box on start */
	X	Boolean	dateYearIs2;	/* Display year as two digits in date strip  */
	X	Boolean	editYearIs2;	/* Display year as two digits in edit strip  */
	X	Boolean	memoYearIs2;	/* Display year as two digits in memo strip  */
	X	String	mon[12];	/* Long month names */
	X	String	smon[12];	/* Short month names */
	X	String	day[7];		/* Day names - full */
	X	String	sday[7];	/* Short day names */
	X	String	weekly;		/* Title of weekly edit strip */
	X	String	opfmt;		/* format for main box */
	X	String	order;		/* Orders are dmy/ymd/mdy/ydm */
	X	int	val_order;	/* The selected order */
	X	Colour	marked;		/* Marked entry colour */
	X	Colour	today;		/* What to mark today with */
	X	XFontStruct *fontToday; /* We can also do Today in a different font */
	X	String	directory;	/* Directory under home where Calendar files */
	X				/* can be found */
	X	int	textbufsz;	/* Text buffer size for editing */
	X	Dimension minstripwidth; /* Minimum strip width */
	X	Boolean	alarms;		/* false - no alarms, true - alarms */
	X	XtIntervalId interval_id;/* store XtAddTimeOut value */
	X	int	update;		/* interval between peeks (60 secs) */
	X	int	volume;		/* how loud to beep the alarm 0-100 */
	X	int	nbeeps;		/* how many beeps for an alarm ? */
	X	int	autoquit;	/* Automatically delete message boxes */
	X	String	countdown;	/* Comma separated countdown string for alarms */
	X	String	cmd;		/* command to execute for every alarm */
	X	String	alarmleft;	/* string containing a message - %d mins left */
	X	String	alarmnow;	/* string containing a message - Now! */
	X	Boolean	useMemo;	/* true use top-level memo button, false - don't */
	X	Boolean memoLeft;	/* True if on left of date, false otherwise */
	X	String	memoFile;	/* name of the file where the memo data is stored */
	X	int	maxDisplayLines;/* maximum number of lines that we want to */
	X				/* allow the top half of a memo window to */
	X				/* stretch to */
	X};
	X
	Xextern	struct resources	appResources;
	X
	X/*
	X *	Order coding inserted into val_order
	X */
	X#define	O_DMY		0	/* default */
	X#define O_YMD		1	/* Year/Month/Day */
	X#define O_MDY		2	/* Month/Day/Year */
	X#define O_YDM		3	/* Year/Day/Month */
	X#define	O_WEEKLEFT	4	/* Place day of the week on the left */
	X#define O_WEEKRIGHT	8	/* Place day of the week on the right */
	X#define	O_WEEKMASK	O_WEEKLEFT|O_WEEKRIGHT
	X
	X/*
	X *	Date structure
	X */
	Xtypedef struct
	X{	Cardinal	day;
	X	Cardinal	month;
	X	Cardinal	year;
	X	Cardinal	wday;
	X} Date;
	X
	X/*
	X *	A month entry
	X */
	Xtypedef struct me
	X{
	X	Cardinal	me_year;	/* map year */
	X	Cardinal	me_month;	/* which month */
	X	String		me_have[32];	/* if a file present for the day */
	X					/* then will have a non-zero entry */
	X	int		me_type;	/* type of displayed strip */
	X} MonthEntry;
	X
	X#define ME_MONTHLY	1		/* `Normal' monthly strip */
	X#define ME_WEEKLY	2		/* Weekly strip */
	X
	X/*
	X *	An instance of the strip
	X */
	Xtypedef	struct	instance
	X{	struct	instance *i_next;	/* next object */
	X	Widget	i_w;			/* the widget top level */
	X	Widget	i_day_label[32];	/* the handle to the label on each day */
	X					/* so we can change dates at night */
	X	Widget	i_day_info[32];		/* The info field for this date - so */
	X					/* we can sensitise/desensitise on editing */
	X	Colour	i_col;			/* what the fg/bg colours used to be */
	X	XFontStruct	*i_font;	/* what the font was */
	X} Instance;
	X
	XInstance *RegisterMonth();
	XInstance *FindInstanceList();
	X
	X/*
	X *	Alarm structure
	X *	one of these exists for each event in the timeout queue
	X *	the list is sorted in event order
	X */
	Xtypedef struct _alarm
	X{	struct _alarm *next;	/* pointer to next alarm */
	X	String	alarm;		/* alarm string */
	X	String	what;		/* what is message */
	X	int	alarm_mm;	/* hour*60 + min */
	X	int	alarm_state;	/* what time left to `real' timeout */
	X	Boolean isAction;	/* more than alarm */
	X} Alarm;
	X
	X/*
	X *	We occasionally need these
	X */
	Xextern	Widget	toplevel;
	Xextern	Date	today;
	X
	X/*
	X *	Global routines
	X */
	Xvoid	InitAlarms();
	Xvoid	MouseShow();
	Xvoid	Leave();
	Xvoid	Fatal();
	Xvoid	SetDate();
	Xvoid	AskLeave();
	Xvoid	DialogPopup();
	Xvoid	SetDate();
	Xvoid	TextCal();
	Xvoid	DoCalendar();
	Xvoid	DoMemo();
	Xvoid	DoWeekly();
	Xvoid	MemoPoll();
	Xvoid	NewMonthStrip();
	Xvoid	InitMonthEntries();
	Xvoid	ChangeHighlight();
	Xvoid	NoEditIsPossible();
	Xvoid	NoDayEditIsPossible();
	Xvoid	StartEditing();
	XMonthEntry *GetMonthEntry();
	XMonthEntry *GetWeeklyEntry();
	Xvoid	AlarmFilePoll();
	XString	ReadCalendarFile();
	Xvoid	UpdateMemo();
	Xvoid	PlaceStr();
	XString	MakeWeeklyName();
	XString	GetWeeklyFile();
	XBoolean	NeedTop();
	X
	Xtime_t	time();
SHAR_EOF
if test 6035 -ne "`wc -c < 'xcal.h'`"
then
	echo shar: error transmitting "'xcal.h'" '(should have been 6035 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'xcal_help.c'" '(7541 characters)'
if test -f 'xcal_help.c'
then
	echo shar: will not over-write existing file "'xcal_help.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'xcal_help.c'
	X#ifndef lint
	Xstatic char *sccsid = "@(#)xcal_help.c	3.6 (Hillside Systems) 1/16/91";
	Xstatic char *copyright = "@(#)Copyright 1989,1990 Peter Collinson, Hillside Systems";
	X#endif  /* lint */
	X/***
	X
	X* module name:
	X	xcal_help.c
	X* function:
	X	Generate help screens in separate popup windows
	X* history:
	X	Written December 1989
	X	Peter Collinson
	X	Hillside Systems
	X* (C) Copyright: 1989 Hillside Systems/Peter Collinson
	X	
	X	For full permissions and copyright notice - see xcal.c
	X***/
	X#include <stdio.h>
	X#include <ctype.h>
	X#include <X11/Intrinsic.h>
	X#include <X11/StringDefs.h>
	X#include <X11/Shell.h>
	X#include <X11/Xaw/AsciiText.h>
	X#include <X11/Xaw/Text.h>
	X#include <X11/Xaw/Command.h>
	X#include <X11/Xaw/Form.h>
	X#include <X11/Xaw/Paned.h>
	X#include "xcal.h"
	X
	Xstatic XtCallbackRec callbacks[] = {
	X   {NULL,NULL},
	X   {NULL,NULL}
	X};
	X
	Xvoid	addversion();
	X
	Xvoid
	XDisplayHelpWindow(str)
	X	String	str;
	X{
	X	Widget		shell, form, title;
	X	Arg		args[10];
	X	Cardinal	nargs;
	X	void		DestroyHelp();
	X	
	X	shell = XtCreatePopupShell("help", topLevelShellWidgetClass, toplevel, NULL, 0);
	X
	X	form =  XtCreateManagedWidget("helpPanel", panedWidgetClass, shell, NULL, 0);
	X
	X	nargs = 0;
	X	XtSetArg(args[nargs], XtNshowGrip, False); nargs++;
	X	XtSetArg(args[nargs], XtNdefaultDistance, 2); nargs++;
	X	title = XtCreateManagedWidget("helpForm", formWidgetClass, form, args, nargs);
	X	/*
	X	 *	Exit button
	X	 *	Take "Quit" from resources
	X	 */
	X	callbacks[0].callback = DestroyHelp;
	X	callbacks[0].closure = (caddr_t)shell;
	X	nargs = 0;
	X	XtSetArg(args[nargs], XtNcallback, callbacks); nargs++;
	X	XtSetArg(args[nargs], XtNfromHoriz, NULL); nargs++;
	X	XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
	X	XtSetArg(args[nargs], XtNright, XtChainLeft); nargs++;
	X	(void) XtCreateManagedWidget("helpQuit", commandWidgetClass, title, args, nargs);
	X	/*
	X	 *	Now the text
	X	 *	which is the remainder of the panel
	X	 */
	X	nargs = 0;
	X	XtSetArg(args[nargs], XtNshowGrip, False); nargs++;
	X	XtSetArg(args[nargs], XtNstring, str); nargs++;
	X	XtSetArg(args[nargs], XtNdisplayCaret, False); nargs++;
	X	(void) XtCreateManagedWidget("helpText", asciiTextWidgetClass, form, args, nargs);
	X
	X	XtPopup(shell, XtGrabNone);
	X}
	X
	X/* ARGSUSED */
	Xvoid
	XDestroyHelp(w, closure, call_data)
	X	Widget	w;
	X	caddr_t	closure;
	X	caddr_t call_data;
	X{
	X	XtDestroyWidget((Widget)closure);
	X
	X}
	X
	X/*
	X *	Help scripts
	X */
	Xstatic char stripHelp[] = "\
	XThe date strip consists of a number of lines of text. \n\n\
	XLine 1:	The Month and the Year of the strip.\n\
	X	The information may be duplicated in the window\n\
	X	manager title line. In this case the line may be omitted\n\
	X	by setting the resource `useWmTitle' to False.\n\n\
	XLine 2:	The main control buttons for the strip actioned by the\n\
	X	left mouse button.\n\
	X	<	Generates last month's strip in a separate window\n\
	X	Quit	Close this script\n\
	X	>	Generates next month's strip in a separate window\n\n\
	XLine 3: The Help button.\n\
	X	Help can be suppressed by setting `giveHelp' to False.\n\n\
	XThen -  A line for each day in the month.\n\
	X	Each line is two areas:\n\
	X	The left hand side shows the day in the month and the name of\n\
	X	the day of the week.`Today' may be highlighted specially in\n\
	X	this region.\n\
	X	The right hand side is an active button. When pressed it starts\n\
	X	up an editor for the day. This will create a file for the day\n\
	X	in the user's Calendar directory. The label on the button will\n\
	X	be the first few characters of the file, if there are any.\n\
	X\n\
	XXCal was written by Peter Collinson\n\
	X+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
	X
	X/* ARGSUSED */
	Xvoid
	XStripHelp(w, closure, call_data)
	X	Widget w;
	X	caddr_t	closure;
	X	caddr_t call_data;
	X{
	X	static int vadded;
	X
	X	if (vadded == 0)
	X	{	vadded = 1;
	X		addversion(stripHelp);
	X	}
	X	DisplayHelpWindow(stripHelp);
	X}
	X	
	Xstatic char editHelp[] = "\
	XThis editing window will create or delete a day file for the day shown\n\
	Xin the title. The file is stored in a directory specified by the resource\n\
	X`directory', this is usually `Calendar' in your home directory.\n\n\
	XCalendar will usually contain directories, one for each year,\n\
	Xand the day file will be stored in one of these directories. However,\n\
	Xthis makes xcal incompatible with xcalendar - so if the resource\n\
	XxcalendarCompat is True then the use of subdirectories is suppressed.\n\
	XThe large area in the edit window is a normal text input area. Text is\n\
	Xsimply be typed into it, the text is saved by hitting the save button\n\
	Xwhich is set to sensitive when the text is changed.  Saving an empty\n\
	Xbuffer will delete the file.  The Quit button will exit. Some more\n\
	Xquestions will be asked if leaving will result in losing information.\n\
	X\n\
	XXCal was written by Peter Collinson\n\
	X+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
	X
	X/* ARGSUSED */
	Xvoid
	XEditHelp(w, closure, call_data)
	X	Widget w;
	X	caddr_t	closure;
	X	caddr_t call_data;
	X{
	X	static int vadded;
	X
	X	if (vadded == 0)
	X	{	vadded = 1;
	X		addversion(editHelp);
	X	}
	X
	X	DisplayHelpWindow(editHelp);
	X}
	X	
	X/*
	X *	Add the external version string
	X */
	Xstatic void
	Xaddversion(str)
	X	register char *str;
	X{
	X	extern char version[];
	X	register int vlen;
	X	register char *ptr;
	X
	X	if (ptr = index(str, '+'))
	X	{	vlen = strlen(version);
	X		bcopy(version, ptr, vlen);
	X		ptr[vlen] = '\n';
	X		ptr[vlen+1] = '\0';
	X	}
	X}
	X
	Xstatic char memoHelp[] = "\
	XThe memo window is intended to do two things. First, it allows a\n\
	Xsingle button click to display today's actions from your diary.\n\
	XSecond, it provides an editable window whose contents can be saved in\n\
	Xa file.  The idea is that this file will contain reminders and other\n\
	Xnotes.  The file is usually called `memo' and is stored in a directory\n\
	Xspecified by the resource `directory', usually `Calendar' in your home\n\
	Xdirectory.\n\
	X\n\
	XThe window is split into two areas. The top half shows the current\n\
	Xdiary entry and cannot be altered. The bottom half contains the memo\n\
	Xfile text area. Text is simply be typed into it and is stored saved by\n\
	Xhitting the save button. This will go black when the text is changed.\n\
	XSaving an empty buffer will delete the file.\n\
	X\n\
	XThe Quit button will exit. Some more questions will be asked if\n\
	Xleaving will result in losing information.\n\
	X\n\
	XXCal was written by Peter Collinson\n\
	X+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
	X
	X/* ARGSUSED */
	Xvoid
	XMemoHelp(w, closure, call_data)
	X	Widget w;
	X	caddr_t	closure;
	X	caddr_t call_data;
	X{
	X	static int vadded;
	X
	X	if (vadded == 0)
	X	{	vadded = 1;
	X		addversion(memoHelp);
	X	}
	X
	X	DisplayHelpWindow(memoHelp);
	X}
	X
	Xstatic char weeklyHelp[] = "\
	XThe weekly strip consists of a number of lines of text. \n\n\
	XLine 1: The title\n\
	XLine 2: The Quit button that removes the strip from the screen\n\
	XLine 3: The Help Button.\n\
	X	Help can be suppressed by setting `giveHelp' to False.\n\n\
	XThen -  A line for each day in the week.\n\
	X	Each line is two areas:\n\
	X	The left hand side shows the day in the week\n\
	X	The right hand side is an active button. When pressed it starts\n\
	X	up an editor for the day. This will create a file for the day\n\
	X	in the user's Calendar directory. The label on the button will\n\
	X	be the first few characters of the file, if there are any.\n\
	X\n\
	XXCal was written by Peter Collinson\n\
	X+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
	X	
	X/* ARGSUSED */
	Xvoid
	XWeeklyHelp(w, closure, call_data)
	X	Widget w;
	X	caddr_t	closure;
	X	caddr_t call_data;
	X{
	X	static int vadded;
	X
	X	if (vadded == 0)
	X	{	vadded = 1;
	X		addversion(weeklyHelp);
	X	}
	X
	X	DisplayHelpWindow(weeklyHelp);
	X}
	X
SHAR_EOF
if test 7541 -ne "`wc -c < 'xcal_help.c'`"
then
	echo shar: error transmitting "'xcal_help.c'" '(should have been 7541 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'xcal_memo.c'" '(14910 characters)'
if test -f 'xcal_memo.c'
then
	echo shar: will not over-write existing file "'xcal_memo.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'xcal_memo.c'
	X#ifndef lint
	Xstatic char *sccsid = "@(#)xcal_memo.c	1.11 (Hillside Systems) 1/16/91";
	Xstatic char *copyright = "@(#)Copyright 1989,1990 Peter Collinson, Hillside Systems";
	X#endif  /* lint */
	X/***
	X
	X* module name:
	X	xcal_memo.c
	X* function:
	X	Deal with popup memo file
	X	A single popup file is stored in a file called
	X	memo on the Calendar directory
	X* history:
	X	Written December 1990
	X	Peter Collinson
	X	Hillside Systems
	X* (C) Copyright: 1989,1990 Hillside Systems/Peter Collinson
	X	
	X	For full permissions and copyright notice - see xcal.c
	X***/
	X#include <stdio.h>
	X#include <ctype.h>
	X#include <X11/Xos.h>
	X#include <X11/Intrinsic.h>
	X#include <X11/StringDefs.h>
	X#include <X11/Shell.h>
	X#include <X11/Xaw/AsciiText.h>
	X#include <X11/Xaw/Text.h>
	X#include <X11/Xaw/Command.h>
	X#include <X11/Xaw/Label.h>
	X#include <X11/Xaw/Paned.h>
	X#include <X11/Xaw/Form.h>
	X#include <X11/Xaw/Dialog.h>
	X#include "xcal.h"
	X
	Xstatic XtCallbackRec callbacks[] = {
	X   {NULL,NULL},
	X   {NULL,NULL}
	X};
	X#define ClearCallbacks() bzero((caddr_t)callbacks, sizeof (callbacks))
	X
	X/*
	X *	Structure for storing relavant data about the
	X *	memo Edit
	X */
	Xtypedef struct	memoEdit
	X{
	X	Widget	m_button;	/* widget of the control button */
	X	Widget	m_popup;	/* widget of editor popup */
	X	Widget	m_quit;		/* widget of quit button */
	X	Widget	m_save;		/* widget of save button */
	X	Boolean m_savesens;	/* state of the save button */
	X	Widget	m_display;	/* widget of display title area */
	X	Widget	m_text;		/* the text area */
	X	Widget	m_today;	/* today's data */
	X	Widget	m_weekly;	/* widget of text image of weekly events */
	X	Cardinal m_size;	/* size of the buffer */
	X	char	*m_data;	/* pointer to malloc'ed data buffer */
	X} MemoEdit;
	X
	Xstatic	MemoEdit memo;
	X
	Xextern	Boolean FoundCalendarDir;               /* whether the Calendar directory exists */
	X
	Xstatic	String	memoContents;
	X
	Xextern void MemoHelp();				/* look in xcal_help.c */
	X
	X/*
	X *	Internal routines
	X */
	Xvoid	MemoPopup();
	Xstatic void CleanMemo();
	Xstatic void MemoCheckExit();
	Xstatic void MCheckDia();
	Xstatic Boolean WriteMemoFile();
	Xstatic int NewlineCount();
	Xstatic String GetMemoFile();
	Xstatic void SaveMemoEdits();
	Xstatic void MemoTextChanged();
	Xstatic void FinishMemoEditing();
	Xstatic void YesCheck();
	Xstatic void NoCheck();
	X
	X/*
	X *	Callback routine to display the memo file
	X */
	X
	Xvoid
	XDoMemo(w, closure, call_data)
	X	Widget w;
	X	caddr_t	closure;
	X	caddr_t call_data;
	X{
	X	static Arg args[1];
	X	
	X	/*
	X	 *	Make the button become a finish button
	X	 */
	X	memo.m_button = w;
	X	callbacks[0].callback = FinishMemoEditing;
	X	callbacks[0].closure = (caddr_t)&memo;
	X	XtSetArg(args[0], XtNcallback, callbacks);
	X	XtSetValues(w, args, 1);
	X	
	X	MouseShow(w, False);
	X	/*
	X	 *	Get existing memo contents
	X	 *	if the user is polling then re-read the file
	X	 */
	X	if (appResources.update && memoContents != NULL)
	X	{	XtFree(memoContents);
	X		memoContents = NULL;
	X	}
	X	if (memoContents == NULL)
	X		memoContents = GetMemoFile();
	X
	X	/*
	X	 *	Set up the popup widget for editing
	X	 */
	X	MemoPopup();
	X}
	X
	X
	X/*
	X *	Get old contents from a memo file if any
	X */
	Xstatic String
	XGetMemoFile()
	X{
	X
	X	if (FoundCalendarDir && access(appResources.memoFile, F_OK) == 0)
	X		return ReadCalendarFile(NULL, appResources.memoFile);
	X	return NULL;
	X}
	X
	X
	X/*
	X *	Do the biz to popup an edit style window
	X */
	Xvoid
	XMemoPopup()
	X{
	X	Widget		et, lw;
	X	Widget		frame;
	X	Arg		args[10];
	X	Cardinal	nargs;
	X	String		str;
	X	MonthEntry	*me;
	X	Dimension	charHeight;
	X	char		buf[32];
	X
	X	/*
	X	 *	set up edit buffer
	X	 */
	X	if (memoContents)
	X		memo.m_size = appResources.textbufsz + strlen(memoContents) + 1;
	X	else	
	X		memo.m_size = appResources.textbufsz;
	X	memo.m_data = XtMalloc(memo.m_size);
	X	if (memoContents)
	X		strcpy(memo.m_data, memoContents);
	X	else
	X		*memo.m_data = '\0';
	X	memo.m_popup = XtCreatePopupShell("memo", topLevelShellWidgetClass, toplevel, NULL, 0);
	X
	X	/*
	X	 *	The first title line
	X	 */
	X	et = XtCreateManagedWidget("memoPanel", panedWidgetClass, memo.m_popup, NULL, 0);
	X
	X	nargs = 0;
	X	XtSetArg(args[nargs], XtNshowGrip, False); nargs++;
	X	XtSetArg(args[nargs], XtNskipAdjust, True); nargs++;
	X	XtSetArg(args[nargs], XtNdefaultDistance, 1); nargs++;
	X	frame = XtCreateManagedWidget("title", formWidgetClass, et, args, nargs);
	X	/*
	X	 *	containing some buttons for controlling the world
	X	 */
	X	/*
	X	 *	Take label "quit" from resources
	X	 */
	X	callbacks[0].callback = FinishMemoEditing;
	X	callbacks[0].closure = (caddr_t)&memo;
	X	nargs = 0;
	X	XtSetArg(args[nargs], XtNcallback, callbacks); nargs++;
	X	XtSetArg(args[nargs], XtNfromHoriz, NULL); nargs++;
	X	XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
	X	XtSetArg(args[nargs], XtNright, XtChainLeft); nargs++;
	X	lw = memo.m_quit = XtCreateManagedWidget("quit", commandWidgetClass, frame, args, nargs);
	X	/*
	X	 *	If we are dealing with  help then do it now
	X	 */
	X	if (appResources.giveHelp)
	X	{	/*
	X		 *	Take label "help" from resources
	X		 */
	X		callbacks[0].callback = MemoHelp;
	X		callbacks[0].closure = (caddr_t)0;
	X		nargs = 0;
	X		XtSetArg(args[nargs], XtNcallback, callbacks); nargs++;
	X		XtSetArg(args[nargs], XtNfromHoriz, lw); nargs++;
	X		XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
	X		XtSetArg(args[nargs], XtNright, XtChainLeft); nargs++;
	X		lw = XtCreateManagedWidget("help", commandWidgetClass, frame, args, nargs);
	X	}
	X	/*
	X	 *	The remaining bit here is a date label
	X	 */
	X	PlaceStr(buf, &today, appResources.memoYearIs2);
	X	nargs = 0;
	X	XtSetArg(args[nargs], XtNlabel, buf); nargs++;
	X	XtSetArg(args[nargs], XtNborderWidth, 0); nargs++;
	X	XtSetArg(args[nargs], XtNfromHoriz, lw); nargs++;
	X	XtSetArg(args[nargs], XtNfromVert, NULL); nargs++;
	X	XtSetArg(args[nargs], XtNvertDistance, 2); nargs++;
	X	XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
	X	XtSetArg(args[nargs], XtNright, XtChainRight); nargs++;
	X	lw = memo.m_display = XtCreateManagedWidget("date", labelWidgetClass, frame, args, nargs);
	X	/*
	X	 *	Details for today
	X	 */
	X	me = GetMonthEntry(today.year, today.month);
	X	nargs = 0;
	X	str = me->me_have[today.day];
	X	if (str == NULL)
	X		str = "";
	X	XtSetArg(args[nargs], XtNstring, str); nargs++;
	X	XtSetArg(args[nargs], XtNdisplayCaret, False); nargs++;
	X	XtSetArg(args[nargs], XtNeditType, XawtextRead); nargs++;
	X	memo.m_today = XtCreateManagedWidget("display", asciiTextWidgetClass, et, args, nargs);
	X	{	Dimension height;
	X
	X		XtSetArg(args[0], XtNheight, &height);
	X		XtGetValues(memo.m_today, args, 1);
	X		charHeight = height;
	X		height = height*NewlineCount(str);
	X		XtSetArg(args[0], XtNheight, height);
	X		XtSetValues(memo.m_today, args, 1);
	X	}
	X
	X	/*
	X	 *	Weekly details - the data for today + an edit button
	X	 *	The header to this is a form
	X	 */
	X	nargs = 0;
	X	XtSetArg(args[nargs], XtNshowGrip, False); nargs++;
	X	XtSetArg(args[nargs], XtNskipAdjust, True); nargs++;
	X	XtSetArg(args[nargs], XtNdefaultDistance, 1); nargs++;
	X	frame = XtCreateManagedWidget("weeklyMemo", formWidgetClass, et, args, nargs);
	X
	X	/*
	X	 *	Take label "edit" from resources
	X	 */
	X	callbacks[0].callback = DoWeekly;
	X	callbacks[0].closure = (caddr_t)&memo;
	X	nargs = 0;
	X	XtSetArg(args[nargs], XtNcallback, callbacks); nargs++;
	X	XtSetArg(args[nargs], XtNfromHoriz, NULL); nargs++;
	X	XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
	X	XtSetArg(args[nargs], XtNright, XtChainLeft); nargs++;
	X	lw = XtCreateManagedWidget("weeklyEdit", commandWidgetClass, frame, args, nargs);
	X
	X	/*
	X	 *	Say this is a weekly commitment
	X	 */
	X	nargs = 0;
	X
	X	XtSetArg(args[nargs], XtNshowGrip, True); nargs++;
	X	XtSetArg(args[nargs], XtNborderWidth, 0); nargs++;
	X	XtSetArg(args[nargs], XtNfromHoriz, lw); nargs++;
	X	XtSetArg(args[nargs], XtNfromVert, NULL); nargs++;
	X	XtSetArg(args[nargs], XtNvertDistance, 2); nargs++;
	X	XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
	X	XtSetArg(args[nargs], XtNright, XtChainRight); nargs++;
	X	lw = XtCreateManagedWidget("weeklyTitle", labelWidgetClass, frame, args, nargs);
	X
	X	/*
	X	 *	Details for today
	X	 */
	X	nargs = 0;
	X	str = GetWeeklyFile(today.wday);
	X	if (str == NULL)
	X		str = "";
	X	XtSetArg(args[nargs], XtNstring, str); nargs++;
	X	XtSetArg(args[nargs], XtNdisplayCaret, False); nargs++;
	X	XtSetArg(args[nargs], XtNeditType, XawtextRead); nargs++;
	X	if (charHeight)
	X		XtSetArg(args[nargs], XtNheight, NewlineCount(str)*charHeight); nargs++;
	X	memo.m_weekly = XtCreateManagedWidget("display", asciiTextWidgetClass, et, args, nargs);
	X	/*
	X	 *	Another form with some buttons
	X	 */
	X	nargs = 0;
	X	XtSetArg(args[nargs], XtNshowGrip, False); nargs++;
	X	XtSetArg(args[nargs], XtNskipAdjust, True); nargs++;
	X	XtSetArg(args[nargs], XtNdefaultDistance, 1); nargs++;
	X	frame = XtCreateManagedWidget("memoMiddle", formWidgetClass, et, args, nargs);
	X	/*
	X	 *	Take label "save" from resources
	X	 */
	X	callbacks[0].callback = SaveMemoEdits;
	X	callbacks[0].closure = (caddr_t)&memo;
	X	nargs = 0;
	X	XtSetArg(args[nargs], XtNcallback, callbacks); nargs++;
	X	XtSetArg(args[nargs], XtNfromHoriz, NULL); nargs++;
	X	XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
	X	XtSetArg(args[nargs], XtNright, XtChainLeft); nargs++;
	X	XtSetArg(args[nargs], XtNsensitive, False); nargs++;
	X	lw = memo.m_save = XtCreateManagedWidget("save", commandWidgetClass, frame, args, nargs);
	X	memo.m_savesens = False;
	X	/*
	X	 *	Say this is a memo edit
	X	 */
	X	nargs = 0;
	X	XtSetArg(args[nargs], XtNshowGrip, True); nargs++;
	X	XtSetArg(args[nargs], XtNborderWidth, 0); nargs++;
	X	XtSetArg(args[nargs], XtNfromHoriz, lw); nargs++;
	X	XtSetArg(args[nargs], XtNfromVert, NULL); nargs++;
	X	XtSetArg(args[nargs], XtNvertDistance, 2); nargs++;
	X	XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
	X	XtSetArg(args[nargs], XtNright, XtChainRight); nargs++;
	X	lw = XtCreateManagedWidget("memoTitle", labelWidgetClass, frame, args, nargs);
	X
	X 	/*
	X	 *	The text widget is in the pane below
	X	 *	The Scroll Attributes are controlled from the application
	X	 *	defaults file
	X	 */
	X	callbacks[0].callback = MemoTextChanged;
	X	callbacks[0].closure = (caddr_t)&memo;
	X	nargs = 0;
	X	XtSetArg(args[nargs], XtNstring, memo.m_data); nargs++;
	X	XtSetArg(args[nargs], XtNeditType, XawtextEdit); nargs++;
	X	XtSetArg(args[nargs], XtNlength, memo.m_size); nargs++;
	X	XtSetArg(args[nargs], XtNuseStringInPlace, True); nargs++;
	X	XtSetArg(args[nargs], XtNcallback, callbacks); nargs++;
	X	memo.m_text = XtCreateManagedWidget("memoText", asciiTextWidgetClass, et, args, nargs);
	X
	X	
	X	XtPopup(memo.m_popup, XtGrabNone);
	X	
	X}
	X
	X/*
	X *	Count newlines in a string
	X */
	Xstatic int
	XNewlineCount(str)
	X	String	str;
	X{
	X	register int sum = 0;
	X
	X	while (*str)
	X		if (*str++ == '\n')
	X			sum++;
	X	/* Add one line - assume last line does NOT have an nl */
	X	sum++;
	X	/* ignore a final newline */
	X	if (str[-1] == '\n')
	X		sum--;
	X	if (sum <= 0) sum = 1;
	X	return(sum > appResources.maxDisplayLines ? appResources.maxDisplayLines : sum);
	X}
	X
	X/*
	X *	Entry point from outside when today's text changed
	X */
	Xvoid
	XUpdateMemo()
	X{
	X	Arg		args[1];
	X	String		str;
	X	Cardinal	nargs;
	X	MonthEntry	*me;
	X	char		buf[32];
	X	
	X	/*
	X	 * if the button widget is zero then we are displaying nothing
	X	 */
	X	if (memo.m_button == 0)
	X		return;
	X
	X	me = GetMonthEntry(today.year, today.month);
	X	nargs = 0;
	X	str = me->me_have[today.day];
	X	if (str == NULL)
	X		str = "";
	X	XtSetArg(args[0], XtNstring, str); nargs++;
	X	XtSetValues(memo.m_today, args, 1);
	X
	X	(void) sprintf(buf, "%d %s %d", today.day, appResources.mon[today.month], today.year);
	X	XtSetArg(args[0], XtNlabel, buf);
	X	XtSetValues(memo.m_display, args, 1);
	X
	X	str = GetWeeklyFile(today.wday);
	X	if (str == NULL)
	X		str = "";
	X	XtSetArg(args[0], XtNstring, str);
	X	XtSetValues(memo.m_weekly, args, 1);
	X
	X}
	X
	X/*
	X *	Poll call from the alarm timeout
	X */
	Xvoid
	XMemoPoll()
	X{
	X	int	size;
	X	Arg	args[10];
	X	int	nargs;
	X	
	X	if (memo.m_button == 0)
	X		return;
	X	if (memo.m_savesens == True)
	X		return;
	X
	X	if (memoContents)
	X		XtFree(memoContents);
	X	memoContents = GetMemoFile();
	X	if (memoContents)
	X	{	if (strcmp(memoContents, memo.m_data) == 0)
	X			return;
	X		size = strlen(memoContents) + 1;
	X		if (size > memo.m_size)
	X		{	size += appResources.textbufsz;
	X			XtFree(memo.m_data);
	X			memo.m_data = XtMalloc(memo.m_size = size);
	X		}
	X		strcpy(memo.m_data, memoContents);
	X	}
	X	else
	X		*memo.m_data = '\0';
	X		
	X	nargs = 0;
	X	XtSetArg(args[nargs], XtNstring, memo.m_data); nargs++;
	X	XtSetArg(args[nargs], XtNlength, memo.m_size); nargs++;
	X	XtSetArg(args[nargs], XtNuseStringInPlace, True); nargs++;
	X	XtSetValues(memo.m_text, args, nargs);
	X}
	X		
	X/*
	X *	Call backs for various buttons
	X */
	X/* ARGSUSED */
	Xstatic void
	XMemoTextChanged(w, closure, call_data)
	X	Widget	w;
	X	caddr_t	closure;
	X	caddr_t call_data;
	X{
	X	register MemoEdit *memo = (MemoEdit *)closure;
	X
	X	memo->m_savesens = True;
	X	XtSetSensitive(memo->m_save, True);
	X}
	X
	X/*
	X *	Callback routines
	X */
	X/* ARGSUSED */
	Xstatic void
	XSaveMemoEdits(w, closure, call_data)
	X	Widget	w;
	X	caddr_t	closure;
	X	caddr_t call_data;
	X{
	X	MemoEdit	*memo = (MemoEdit *)closure;
	X
	X	if (WriteMemoFile(memo) == False)
	X		return;
	X	if (memoContents)
	X	{	XtFree(memoContents);
	X		memoContents = XtNewString(memo->m_data);
	X	}
	X	memo->m_savesens = False;
	X	XtSetSensitive(memo->m_save, False);
	X}
	X
	X/*
	X *	Write the memo file out
	X */
	Xstatic Boolean
	XWriteMemoFile(memo)
	X	MemoEdit	*memo;
	X{
	X	Cardinal	len = strlen(memo->m_data);
	X	String		fname;
	X	int		fd;
	X	extern		String MapStem;
	X	
	X	if (len == 0)
	X	{	unlink(appResources.memoFile);
	X		return(True);
	X	}
	X	/*
	X	 *	First let's see if we have 
	X	 *	to create the toplevel directory
	X	 */
	X	if (!NeedTop())
	X		return (False);
	X
	X	fname = appResources.memoFile;
	X
	X	if ((fd = open(fname, O_WRONLY|O_TRUNC|O_CREAT, 0666)) < 0)
	X	{	XBell(XtDisplay(toplevel), 0);
	X		fprintf(stderr, "xcal: Could not open %s/%s for writing.\n", MapStem, fname);
	X		perror("xcal: open");
	X		fflush(stderr);
	X		return(False);
	X	}
	X
	X	if (write(fd, memo->m_data, len) != len)
	X	{	XBell(XtDisplay(toplevel), 0);
	X		fprintf(stderr, "xcal: Write error %s/%s file.\n", MapStem, fname);
	X		perror("xcal: write");
	X		fflush(stderr);
	X		close(fd);
	X		return(False);
	X	}
	X	close(fd);
	X	return (True);
	X}
	X
	Xstatic void
	XFinishMemoEditing(w, closure, call_data)
	X	Widget	w;
	X	caddr_t	closure;
	X	caddr_t call_data;
	X{
	X
	X	if (memo.m_savesens == True)
	X	{	MemoCheckExit();
	X		return;
	X	}
	X	CleanMemo();
	X}
	X
	Xstatic void
	XCleanMemo()
	X{
	X	static Arg args[1];
	X	
	X	callbacks[0].callback = DoMemo;
	X	callbacks[0].closure = NULL;
	X	XtSetArg(args[0], XtNcallback, callbacks);
	X	XtSetValues(memo.m_button, args, 1);
	X
	X	MouseShow(memo.m_button, True);
	X	XtPopdown(memo.m_popup);
	X	XtDestroyWidget(memo.m_popup);
	X	XtFree(memo.m_data);
	X	bzero((char *)&memo, sizeof(MemoEdit));
	X
	X}
	X
	Xstatic void
	XMemoCheckExit()
	X{
	X	DialogPopup(memo.m_quit, MCheckDia, &memo);
	X}
	X
	Xstatic void
	XMCheckDia(pop, ed)
	X	Widget	pop;
	X	MemoEdit *ed;
	X{
	X	Widget	dia;
	X
	X	/* Take "Save file?" from resources */
	X	dia =  XtCreateManagedWidget("check", dialogWidgetClass, pop, NULL, 0);
	X	XawDialogAddButton(dia, "yes", YesCheck, ed);
	X	XawDialogAddButton(dia, "no", NoCheck, ed);
	X}
	X
	X/* ARGSUSED */
	Xstatic void
	XYesCheck(w, closure, call_data)
	X	Widget w;
	X	caddr_t	closure;
	X	caddr_t call_data;
	X{
	X	SaveMemoEdits(w, closure, call_data);
	X	CleanMemo();
	X	XtDestroyWidget(XtParent(XtParent(w)));
	X
	X}
	X
	X/* ARGSUSED */
	Xstatic void
	XNoCheck(w, closure, call_data)
	X	Widget w;
	X	caddr_t	closure;
	X	caddr_t call_data;
	X{
	X	CleanMemo();
	X	XtDestroyWidget(XtParent(XtParent(w)));
	X}
SHAR_EOF
if test 14910 -ne "`wc -c < 'xcal_memo.c'`"
then
	echo shar: error transmitting "'xcal_memo.c'" '(should have been 14910 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'xcal_strip.c'" '(17420 characters)'
if test -f 'xcal_strip.c'
then
	echo shar: will not over-write existing file "'xcal_strip.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'xcal_strip.c'
	X#ifndef lint
	Xstatic char *sccsid = "@(#)xcal_strip.c	3.10 (Hillside Systems) 1/16/91";
	Xstatic char *copyright = "@(#)Copyright 1989,1990 Peter Collinson, Hillside Systems";
	X#endif  /* lint */
	X/***
	X
	X* module name:
	X	xcal_strip.c
	X* function:
	X	Deal with the popup strip calendars obtained either by
	X	selection and the middle button, or by the < and > buttons
	X	on each strip.
	X* history:
	X	Written November 1989
	X	Peter Collinson
	X	Hillside Systems
	X* (C) Copyright: 1989 Hillside Systems/Peter Collinson
	X	
	X	For full permissions and copyright notice - see xcal.c
	X***/
	X#include <stdio.h>
	X#include <ctype.h>
	X#include <X11/Intrinsic.h>
	X#include <X11/StringDefs.h>
	X#include <X11/Shell.h>
	X#include <X11/Xaw/Paned.h>
	X#include <X11/Xaw/Command.h>
	X#include <X11/Xaw/Label.h>
	X#include <X11/Xaw/Dialog.h>
	X#include <X11/Xaw/AsciiText.h>
	X#include "xcal.h"
	X
	Xstatic XtCallbackRec callbacks[] = {
	X   {NULL,NULL},
	X   {NULL,NULL},
	X   {NULL,NULL},
	X   {NULL,NULL}
	X};
	X#define ClearCallbacks() bzero((caddr_t)callbacks, sizeof (callbacks))
	X
	XDate	callb;		/* contains date when calendar day button pressed */
	X
	X/*
	X *	Forward routines local to this file
	X */
	Xvoid MakeMonth();
	Xvoid	DayBack();
	X#ifndef LONG_IS_32_BITS
	Xvoid	YmBack();
	X#endif
	Xvoid	StripQuit();
	Xvoid	StripHelp();
	Xvoid	WeeklyHelp();
	Xvoid	MakeNewMonth();
	X
	XCardinal DateSum();
	XCardinal NumberOfDays();
	XCardinal FirstDay();
	XCardinal JanuaryOne();
	X
	X/*
	X *	Local routines
	X */
	Xstatic void	CreateActionBar();
	Xstatic void	CreateWeeklyActionBar();
	X
	X/*
	X*	Start a strip calendar happening
	X *	a callback of left button 
	X */
	X/* ARGSUSED */
	Xvoid
	XDoCalendar(w, closure, call_data)
	X	Widget w;
	X	caddr_t	closure;
	X	caddr_t call_data;
	X{
	X	NewMonthStrip(&today);		/* today is global */
	X}
	X
	X/* ARGSUSED */
	Xvoid
	XDoWeekly(w, closure, call_data)
	X	Widget w;
	X	caddr_t	closure;
	X	caddr_t call_data;
	X{
	X	Date	thisday;
	X
	X	thisday.day = 0;
	X	thisday.month = 0;
	X	thisday.year = 0;
	X	thisday.wday = 0;
	X	NewMonthStrip(&thisday);	/* today is global */
	X}
	X
	X
	X/*
	X *	Start a strip calendar happening
	X *	a callback of the > or < buttons in another strip
	X */
	X/* ARGSUSED */
	Xstatic void
	XMakeNewMonth(w, closure, call_data)
	X	Widget w;
	X	caddr_t	closure;
	X	caddr_t call_data;
	X{
	X	Date	thisday;
	X
	X	thisday.year = YrUnpack((Cardinal)closure);
	X	thisday.month = MoUnpack((Cardinal)closure);
	X	thisday.day = today.day;
	X	NewMonthStrip(&thisday);
	X}
	X
	X/* 
	X *	Do all the X stuff to popup a Strip calendar
	X *	A calendar strip is:
	X *
	X *	Popup ("<month year>")		// Name is the month and the year
	X *	    Paned ("<month>")		// Name is the month
	X *		Label ("header")	// optional contains Month Year
	X *		Form ("action")		// < Quit >
	X *		    Command ("back")	// contains < 
	X *		    Label ("quit")	// contains Quit
	X *		    Command ("next")	// contains >
	X *	(Then many of..)
	X *		Form ("<dd DDD>")	// where dd is the day number, DDD is the
	X *					// day of the week
	X *		    Label ("label")	// contains the string above
	X *		    Command ("info")	// contains the text from the file
	X *		
	X */
	Xvoid
	XNewMonthStrip(td)
	X	Date	*td;
	X{
	X	Widget		shell, mon, dw, lw, lwi, form;
	X	Arg		args[15];
	X	char		nbuf[256];
	X	char		iconName[80];
	X	int		type;
	X	MonthEntry	*me;
	X	Instance	*ins;
	X	register int	i;
	X	register Cardinal nargs;
	X	Cardinal	thisDay;
	X	Cardinal	startLoop;
	X	String		dayStr;
	X	Cardinal	numberOfDays;
	X	Boolean		defaultsAreSet = False;
	X	Boolean		markThisMonth = False;
	X	Cardinal	adjustLabelY;
	X	Cardinal	adjustInfoY;
	X	Dimension	labelH, infoH;
	X	Dimension	width;
	X	Dimension	totalWidth;
	X
	X	type = (td->day == 0) ? ME_WEEKLY : ME_MONTHLY;
	X	
	X	/*
	X	 *	There are lots of differences between
	X	 *	Months and weekly strips here.
	X	 *	Later tests are done using a switch structure
	X	 */
	X	switch (type)
	X	{
	X	case ME_MONTHLY:
	X		(void) sprintf(iconName, "%s %d", appResources.smon[td->month], td->year);
	X		XtSetArg(args[0], XtNiconName, iconName);
	X		shell = XtCreatePopupShell(XtNewString(iconName), topLevelShellWidgetClass, toplevel, args, 1);
	X		ins = RegisterMonth(td->year, td->month, shell);	
	X		mon = XtCreateManagedWidget(appResources.mon[td->month], panedWidgetClass, shell, NULL, 0);
	X		thisDay = FirstDay(td->month, td->year);
	X		numberOfDays = NumberOfDays(td->month, td->year);
	X		startLoop = 1;
	X		/*
	X		 *	Get the map for this year
	X		 */
	X		me = GetMonthEntry(td->year, td->month);
	X		me->me_type = type;
	X		/*
	X		 *	Title bar is month and date
	X		 */
	X		(void) sprintf(nbuf, "%s %d", appResources.mon[td->month], td->year);
	X		/*
	X		 *	see if we will need to worry about marking today's entry
	X		 */
	X		if (appResources.markToday && td->year == today.year && td->month == today.month)
	X			markThisMonth = True;
	X		break;
	X	case ME_WEEKLY:
	X		(void) strcpy(iconName, appResources.weekly);
	X		XtSetArg(args[0], XtNiconName, iconName);
	X		shell = XtCreatePopupShell(XtNewString(iconName), topLevelShellWidgetClass, toplevel, args, 1);
	X		ins = RegisterMonth(0, 0, shell);	
	X		mon = XtCreateManagedWidget(iconName, panedWidgetClass, shell, NULL, 0);
	X		thisDay = 0;
	X		numberOfDays = 6;	/* test is <= */
	X		startLoop = 0;
	X		/*
	X		 *	Get the map for this year
	X		 */
	X		me = GetWeeklyEntry();
	X		me->me_type = type;
	X		/*
	X		 *	Title bar is from the resources
	X		 */
	X		strcpy(nbuf, iconName);
	X		/*
	X		 *	see if we will need to worry about marking today's entry
	X		 */
	X		if (appResources.markToday)
	X			markThisMonth = True;
	X		break;
	X	}
	X	/*
	X	 *	Find size of title bar
	X	 *	by creating the widget and then throwing it away
	X	 */
	X	XtSetArg(args[0], XtNlabel, "mmmmmmmmm NNNN");
	X	lw = XtCreateManagedWidget("sizer", labelWidgetClass, shell, args, 1);
	X	XtSetArg(args[0], XtNwidth, &totalWidth);
	X	XtGetValues(lw, args, 1);
	X	XtDestroyWidget(lw);
	X	/*
	X	 *	Width is affected by a resource value
	X	 */
	X	if (appResources.minstripwidth && appResources.minstripwidth > totalWidth)
	X		totalWidth = appResources.minstripwidth;
	X	/*
	X	 *	Now set the title bar should we need it
	X	 */
	X	if (appResources.useWmTitle)
	X	{	XtSetArg(args[0], XtNlabel, XtNewString(nbuf));
	X		(void) XtCreateManagedWidget("header", labelWidgetClass, mon, args, 1);
	X	}
	X		
	X	/*
	X	 *	Action bar
	X	 */
	X	nargs = 0;
	X	XtSetArg(args[nargs], XtNshowGrip, False); nargs++;
	X	XtSetArg(args[nargs], XtNdefaultDistance, 2); nargs++;
	X	dw = XtCreateManagedWidget("action", formWidgetClass, mon, args, nargs);
	X
	X	switch (type)
	X	{
	X	case ME_MONTHLY:
	X		CreateActionBar(shell, dw, mon, td);
	X		break;
	X	case ME_WEEKLY:
	X		CreateWeeklyActionBar(shell, dw);
	X		break;
	X	}
	X
	X#ifdef	LONG_IS_32_BITS
	X	callbacks[0].callback = DayBack;
	X#else
	X	callbacks[0].callback = YmBack;
	X	callbacks[1].callback = DayBack;
	X#endif
	X	for (i = startLoop; i <= numberOfDays; i++)
	X	{
	X		dayStr = appResources.sday[thisDay];
	X		switch(type)
	X		{
	X		case ME_MONTHLY:
	X			(void) sprintf(nbuf, "%2d %s", i, dayStr);
	X			break;
	X		case ME_WEEKLY:
	X			(void) strcpy(nbuf, dayStr);
	X			break;
	X		}
	X#ifdef LONG_IS_32_BITS
	X		callbacks[0].closure = (caddr_t)DatePack(thisDay, i, td->month, td->year);
	X#else
	X		callbacks[0].closure = (caddr_t)DatePack(td->month, td->year);
	X		callbacks[1].closure = (caddr_t)DayPack(thisDay, i);
	X#endif		
	X
	X		thisDay = (thisDay+1)%7;
	X		
	X		/*
	X		 *	Each line in the strip is
	X		 *	form containing
	X		 *	label - command
	X		 */
	X		nargs = 0;
	X		XtSetArg(args[nargs], XtNshowGrip, False); nargs++;
	X		XtSetArg(args[nargs], XtNdefaultDistance, 0); nargs++;
	X		form = XtCreateManagedWidget(dayStr, formWidgetClass, mon, args, nargs);
	X		
	X		nargs = 0;
	X		XtSetArg(args[nargs], XtNlabel, XtNewString(nbuf)); nargs++;
	X						/* a little naughty here */
	X						/* this string memory is lost */
	X						/* on quit */
	X		XtSetArg(args[nargs], XtNborderWidth, 0); nargs++;
	X		XtSetArg(args[nargs], XtNjustify, XtJustifyLeft); nargs++;
	X		XtSetArg(args[nargs], XtNfromHoriz, NULL); nargs++;
	X		XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
	X		XtSetArg(args[nargs], XtNright, XtChainLeft); nargs++;
	X
	X		ins->i_day_label[i] = lw = XtCreateManagedWidget("label", labelWidgetClass, form, args, nargs);
	X
	X		/*
	X		 *	To get a handle on the old values which are lost by
	X		 *	highlighting we get them after we have created the
	X		 *	widget. Then we highlight today.
	X		 */
	X		if (markThisMonth &&
	X		    ((type == ME_MONTHLY && today.day == i) ||
	X		     (type == ME_WEEKLY && today.wday == i)))
	X		{
	X			nargs = 0;
	X			XtSetArg(args[nargs], XtNforeground, &ins->i_col.fg); nargs++;
	X			XtSetArg(args[nargs], XtNbackground, &ins->i_col.bg); nargs++;
	X			XtSetArg(args[nargs], XtNfont, &ins->i_font); nargs++;
	X			XtGetValues(lw, args, nargs);
	X
	X			nargs = 0;
	X			XtSetArg(args[nargs], XtNforeground, appResources.today.fg); nargs++;
	X			XtSetArg(args[nargs], XtNbackground, appResources.today.bg); nargs++;
	X			XtSetArg(args[nargs], XtNfont, appResources.fontToday); nargs++;
	X			XtSetValues(lw, args, nargs);
	X		}
	X		/*
	X		 *	Done the first time through
	X		 *	Gets the width of the line we have just made
	X		 */
	X		if (defaultsAreSet == False)
	X		{	/* compute text width */
	X			nargs = 0;
	X			XtSetArg(args[nargs], XtNwidth, &width); nargs++;
	X			XtSetArg(args[nargs], XtNheight, &labelH); nargs++;
	X			XtGetValues(lw, args, nargs);
	X			defaultsAreSet = True;
	X		}
	X		/*
	X		 *	Start processing the RHS of the line
	X		 *	This contains text from the file
	X		 *	should any exist
	X		 */
	X		nargs = 0;
	X		XtSetArg(args[nargs], XtNborderWidth, 0); nargs++;
	X		XtSetArg(args[nargs], XtNcallback, callbacks); nargs++;
	X		XtSetArg(args[nargs], XtNfromHoriz, lw); nargs++;
	X		XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
	X		XtSetArg(args[nargs], XtNright, XtChainRight); nargs++;
	X		XtSetArg(args[nargs], XtNjustify, XtJustifyLeft); nargs++;
	X		XtSetArg(args[nargs], XtNwidth, totalWidth - width); nargs++;
	X
	X		if (me->me_have[i])
	X		{	XtSetArg(args[nargs], XtNforeground, appResources.marked.fg); nargs++;
	X			XtSetArg(args[nargs], XtNbackground, appResources.marked.bg); nargs++;
	X			XtSetArg(args[nargs], XtNlabel, me->me_have[i]); nargs++;
	X		}
	X		else
	X		{	XtSetArg(args[nargs], XtNlabel, "    "); nargs++;	}
	X		ins->i_day_info[i] = lwi = XtCreateManagedWidget("info", commandWidgetClass, form, args, nargs);
	X
	X		/* deal with height */
	X		XtSetArg(args[0], XtNheight, &infoH);
	X		XtGetValues(lwi, args, 1);
	X		if (labelH < infoH)
	X		{	adjustLabelY = ((infoH-labelH)/2);
	X			/* fix up widget */
	X			nargs = 0;
	X			XtSetArg(args[nargs], XtNvertDistance, adjustLabelY); nargs++;
	X                        XtSetArg(args[nargs], XtNfromVert, NULL); nargs++;
	X			XtSetValues(lw, args, nargs);
	X		}
	X		else
	X		if (labelH > infoH)
	X		{	adjustInfoY = ((labelH - infoH)/2);
	X			/* fix up widget 1 */
	X			nargs = 0;
	X			XtSetArg(args[nargs], XtNvertDistance, adjustInfoY); nargs++;
	X                        XtSetArg(args[nargs], XtNfromVert, NULL); nargs++;
	X			XtSetValues(lwi, args, nargs);
	X		}
	X
	X		/*
	X		 *	cope with 1752
	X		 */
	X		if (td->year == 1752 && td->month == 8 && i == 2)
	X		{	i = 13;
	X			numberOfDays += 11;	/* giving back the 11 days */
	X		}
	X	}
	X	ClearCallbacks();
	X
	X	XtPopup(shell, XtGrabNone);
	X}
	X
	X/*
	X *	Create action bar for normal monthly strip
	X */
	Xstatic void
	XCreateActionBar(shell, dw, mon, td)
	X	Widget	shell;
	X	Widget	dw;
	X	Widget	mon;
	X	Date	*td;
	X{
	X	Widget		lw;
	X	register Cardinal nargs;
	X	Arg		args[8];
	X
	X	/*
	X	 *	back one month
	X	 *	label "<" from resources
	X	 */
	X	callbacks[0].callback = MakeNewMonth;
	X	callbacks[0].closure = (caddr_t)DateSum(td, -1);
	X	nargs = 0;
	X	XtSetArg(args[nargs], XtNcallback, callbacks); nargs++;
	X	XtSetArg(args[nargs], XtNfromHoriz, NULL); nargs++;
	X	XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
	X	XtSetArg(args[nargs], XtNright, XtChainLeft); nargs++;
	X	lw = XtCreateManagedWidget("back", commandWidgetClass, dw, args, nargs);
	X	ClearCallbacks();
	X
	X	/*
	X	 *	Quit button
	X	 *	label "quit" from resources
	X	 */
	X	callbacks[0].callback = StripQuit;
	X	callbacks[0].closure = (caddr_t)shell;
	X	nargs = 0;
	X	XtSetArg(args[nargs], XtNcallback, callbacks); nargs++;
	X	XtSetArg(args[nargs], XtNfromHoriz, lw); nargs++;
	X	XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
	X	XtSetArg(args[nargs], XtNright, XtChainRight); nargs++;
	X	lw = XtCreateManagedWidget("quit", commandWidgetClass, dw, args, nargs);
	X	ClearCallbacks();
	X
	X	/*
	X	 *	On one month
	X	 *	label ">" from reources
	X	 */
	X	callbacks[0].callback = MakeNewMonth;
	X	callbacks[0].closure = (caddr_t)DateSum(td, 1);
	X	nargs = 0;
	X	XtSetArg(args[nargs], XtNcallback, callbacks); nargs++;
	X	XtSetArg(args[nargs], XtNfromHoriz, lw); nargs++;
	X	XtSetArg(args[nargs], XtNleft, XtChainRight); nargs++;
	X	XtSetArg(args[nargs], XtNright, XtChainRight); nargs++;
	X	lw = XtCreateManagedWidget("next", commandWidgetClass, dw, args, nargs);
	X	ClearCallbacks();
	X
	X	/*
	X	 *	Help button
	X	 *	label help from resources
	X	 */
	X	if (appResources.giveHelp)
	X	{	
	X		callbacks[0].callback = StripHelp;
	X		callbacks[0].closure = (caddr_t)0;
	X		nargs = 0;
	X		XtSetArg(args[nargs], XtNcallback, callbacks); nargs++;
	X		XtSetArg(args[nargs], XtNshowGrip, False); nargs++;
	X		lw = XtCreateManagedWidget("help", commandWidgetClass, mon, args, nargs);
	X		ClearCallbacks();
	X	}
	X}
	X
	X/*
	X *	Create action bar for normal monthly strip
	X */
	Xstatic void
	XCreateWeeklyActionBar(shell, dw)
	X	Widget	shell;
	X	Widget	dw;
	X{
	X	Widget		lw;
	X	register Cardinal nargs;
	X	Arg		args[8];
	X
	X	/*
	X	 *	Quit button
	X	 *	label "quit" from resources
	X	 */
	X	callbacks[0].callback = StripQuit;
	X	callbacks[0].closure = (caddr_t)shell;
	X	nargs = 0;
	X	XtSetArg(args[nargs], XtNcallback, callbacks); nargs++;
	X	XtSetArg(args[nargs], XtNfromHoriz, NULL); nargs++;
	X	XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
	X	XtSetArg(args[nargs], XtNright, appResources.giveHelp ? XtChainLeft: XtChainRight); nargs++;
	X	lw = XtCreateManagedWidget("quit", commandWidgetClass, dw, args, nargs);
	X	ClearCallbacks();
	X
	X	/*
	X	 *	Help button
	X	 *	label help from resources
	X	 */
	X	if (appResources.giveHelp)
	X	{	
	X		callbacks[0].callback = WeeklyHelp;
	X		callbacks[0].closure = (caddr_t)0;
	X		nargs = 0;
	X		XtSetArg(args[nargs], XtNcallback, callbacks); nargs++;
	X		XtSetArg(args[nargs], XtNfromHoriz, lw); nargs++;
	X		XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++;
	X		XtSetArg(args[nargs], XtNright, XtChainRight); nargs++;
	X		lw = XtCreateManagedWidget("help", commandWidgetClass, dw, args, nargs);
	X		ClearCallbacks();
	X	}
	X}
	X
	X/*
	X *	Called when the date changes to ensure that
	X *	the correct day has the appropriate highlights
	X */
	Xvoid
	XChangeHighlight(old, new)
	X	Date	*old;
	X	Date	*new;
	X{
	X	register Instance *ins;
	X	Arg		args[5];
	X	Cardinal	nargs;
	X
	X	for (ins = FindInstanceList(old); ins; ins = ins->i_next)
	X	{	nargs = 0;	
	X		XtSetArg(args[nargs], XtNforeground, ins->i_col.fg); nargs++;
	X		XtSetArg(args[nargs], XtNbackground, ins->i_col.bg); nargs++;
	X		XtSetArg(args[nargs], XtNfont, ins->i_font); nargs++;
	X		XtSetValues(ins->i_day_label[old->day], args, nargs);
	X	}
	X
	X	for (ins = FindInstanceList(new); ins; ins = ins->i_next)
	X	{	nargs = 0;
	X		XtSetArg(args[nargs], XtNforeground, &ins->i_col.fg); nargs++;
	X		XtSetArg(args[nargs], XtNbackground, &ins->i_col.bg); nargs++;
	X		XtSetArg(args[nargs], XtNfont, &ins->i_font); nargs++;
	X		XtGetValues(ins->i_day_label[new->day], args, nargs);
	X
	X		nargs = 0;	
	X		XtSetArg(args[nargs], XtNforeground, appResources.today.fg); nargs++;
	X		XtSetArg(args[nargs], XtNbackground, appResources.today.bg); nargs++;
	X		XtSetArg(args[nargs], XtNfont, appResources.fontToday); nargs++;
	X		XtSetValues(ins->i_day_label[new->day], args, nargs);
	X	}
	X}
	X
	X/*
	X *	Call back from a quit button to lose a month strip
	X */
	X/* ARGSUSED */
	Xstatic void
	XStripQuit(w, closure, call_data)
	X	Widget w;
	X	caddr_t	closure;
	X	caddr_t call_data;
	X{
	X	XtPopdown((Widget)closure);
	X	XtDestroyWidget((Widget)closure);
	X}
	X	
	X
	X/*
	X *	Month arithmetic and packing
	X */
	Xstatic Cardinal
	XDateSum(td, inx)
	X	Date	*td;
	X	int	inx;
	X{
	X	int	m, y;
	X
	X	m = td->month;
	X	y = td->year;
	X	m += inx;
	X	if (m < 0)
	X	{	m = 11;
	X		y--;
	X	}
	X	else
	X	if (m > 11)
	X	{	m = 0;
	X		y++;
	X	}
	X#ifdef LONG_IS_32_BITS
	X	return(DatePack(0, 0, m, y));
	X#else
	X	return(DatePack(m, y));
	X#endif
	X}
	X
	X/*
	X *	Call back from day selection button press
	X *	This is done in two stages if cannot fold dates into a closure
	X */
	X/* ARGSUSED */
	Xstatic void
	XDayBack(w, closure, call_data)
	X	Widget w;
	X	caddr_t	closure;
	X	caddr_t call_data;
	X{
	X#ifdef LONG_IS_32_BITS
	X	callb.month = MoUnpack((Cardinal)closure);
	X	callb.year = YrUnpack((Cardinal)closure);
	X#endif
	X	callb.day = DyUnpack((Cardinal)closure);
	X	callb.wday = WdUnpack((Cardinal)closure);
	X	StartEditing(w, &callb);
	X}
	X
	X#ifndef LONG_IS_32_BITS
	X/* ARGSUSED */
	Xstatic void
	XYmBack(w, closure, call_data)
	X	Widget w;
	X	caddr_t	closure;
	X	caddr_t call_data;
	X{
	X	callb.month = MoUnpack((Cardinal)closure);
	X	callb.year = YrUnpack((Cardinal)closure);
	X}
	X#endif
	X
	X/*
	X *	Stolen from xcalendar.c
	X */
	X/* taken from cal.c */
	X
	Xchar	mon[] = {
	X   31, 29, 31, 30,
	X   31, 30, 31, 31,
	X   30, 31, 30, 31,
	X};
	X
	Xstatic Cardinal calInit = 0;
	X
	Xstatic Cardinal
	XNumberOfDays(m, y)
	X	Cardinal m, y;
	X{
	X	if(calInit != y)
	X		(void) FirstDay(m, y); /* set side effect */
	X	return mon[m];
	X}
	X
	X/* should be called first */
	Xstatic Cardinal
	XFirstDay(m, y)
	X     Cardinal m, y;
	X{
	X	register d, i;
	X
	X	calInit = y;
	X	d = JanuaryOne(y);
	X	mon[1] = 29;
	X	mon[8] = 30;
	X   
	X	switch((JanuaryOne(y+1)+7-d)%7)
	X	{
	X      
	X	/*
	X	 *	non-leap year
	X	 */
	X	case 1:
	X		mon[1] = 28;
	X		break;
	X      
	X	/*
	X	 *	1752
	X	 */
	X	default:
	X		mon[8] = 19;
	X		break;
	X
	X	/*
	X	 *	leap year
	X	 */
	X	case 2:
	X		;
	X	}
	X   
	X	for(i=0; i<m; i++)
	X		d += mon[i];
	X
	X	return(d%7);
	X}
	X
	X/*
	X *	return day of the week
	X *	of jan 1 of given year
	X */
	Xstatic Cardinal
	XJanuaryOne(yr)
	X	Cardinal yr;
	X{
	X	register Cardinal y, d;
	X
	X/*
	X *	normal gregorian calendar
	X *	one extra day per four years
	X */
	X
	X	y = yr;
	X	d = 4+y+(y+3)/4;
	X
	X/*
	X *	julian calendar
	X *	regular gregorian
	X *	less three days per 400
	X */
	X
	X	if(y > 1800) {
	X		d -= (y-1701)/100;
	X		d += (y-1601)/400;
	X	}
	X
	X/*
	X *	great calendar changeover instant
	X */
	X
	X	if(y > 1752)
	X		d += 3;
	X
	X	return(d%7);
	X}
SHAR_EOF
if test 17420 -ne "`wc -c < 'xcal_strip.c'`"
then
	echo shar: error transmitting "'xcal_strip.c'" '(should have been 17420 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0

--
Dan Heller
O'Reilly && Associates       Z-Code Software    Comp-sources-x:
Senior Writer                President          comp-sources.x at uunet.uu.net
argv at ora.com                 argv at zipcode.com



More information about the Comp.sources.x mailing list