pc@hillside.co.uk (Peter Collinson) (12/19/90)
Submitted-by: Peter Collinson <pc@hillside.co.uk> Posting-number: Volume 10, Issue 96 Archive-name: xcal/part03 #! /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_cal.man # xcal_edit.c # xcal_help.c # xcal_memo.c # xcal_strip.c # This archive created: Sun Dec 9 12:51:36 1990 export PATH; PATH=/bin:$PATH echo shar: extracting "'xcal_cal.c'" '(4919 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#include <sys/dir.h> X#include <time.h> X#include <strings.h> X 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 4919 -ne "`wc -c < 'xcal_cal.c'`" then echo shar: error transmitting "'xcal_cal.c'" '(should have been 4919 characters)' fi fi # end of overwriting check echo shar: extracting "'xcal_cal.man'" '(1102 characters)' if test -f 'xcal_cal.man' then echo shar: will not over-write existing file "'xcal_cal.man'" else sed 's/^ X//' << \SHAR_EOF > 'xcal_cal.man' X.TH XCAL_CAL (1) X.SH NAME Xxcal_cal \- interface to calendar(1) for xcal X.SH SYNOPSIS X.B xcal_cal X[ X.B \-d Xdirectory X] [ X.B \-f Xfile X] [ X.B \-m X] X.SH DESCRIPTION X.I Xcal_cal Xreads through the files created by X.IR xcal (1) Xand creates a file suitable for use by X.IR calendar (1). XBy default, the files are found in a directory named X``Calendar'' in the user's home directory; Xan alternate directory may be specified with the X.B \-d Xflag. XOutput goes by default into a file named ``.xcal'' Xin the user's home directory; Xit may be overridden with the X.B \-f Xflag. XIn both cases, if the argument given begins with a slash (`/'), Xthen it will be taken as a full path name, not as a path relative to the Xuser's home directory. XIf the argument begins with the two character sequence `./' then Xit will be taken relative to the current directory. XThis last form is primarily intended for use while debugging. XThe X.B \-m Xflag directs that multi-line entries in X.I xcal Xfiles be collected in their Xentirety. XBy default, only the first line is copied. X.SH "SEE ALSO Xxcal(1) X.SH AUTHOR XEd Gould, Mt.Xinu. Thanks Ed. SHAR_EOF if test 1102 -ne "`wc -c < 'xcal_cal.man'`" then echo shar: error transmitting "'xcal_cal.man'" '(should have been 1102 characters)' fi fi # end of overwriting check echo shar: extracting "'xcal_edit.c'" '(22066 characters)' if test -f 'xcal_edit.c' then echo shar: will not over-write existing file "'xcal_edit.c'" else sed 's/^ X//' << \SHAR_EOF > 'xcal_edit.c' X#ifndef lint Xstatic char *sccsid = "@(#)xcal_edit.c 3.7 (Hillside Systems) 12/7/90"; Xstatic char *copyright = "@(#)Copyright 1989,1990 Peter Collinson, Hillside Systems"; X#endif /* lint */ X/*** X X* module name: X xcal_edit.c X* function: X Deal with editable days X This is derived from xcalendar's view of how to store things 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/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#include <sys/stat.h> X#ifdef SYSV X# include <dirent.h> X#else X# include <sys/dir.h> X#endif X Xtypedef struct editline X{ struct editline *ed_next; /* Pointer to next */ X struct meWrap *ed_meWrap; /* Pointer to head of the chain */ X Cardinal ed_day; /* What day we are */ X Widget ed_popup; /* widget of editor popup */ X Widget ed_quit; /* widget of quit button */ X Widget ed_save; /* widget of save button */ X Widget ed_text; /* the text area */ X Cardinal ed_size; /* size of the buffer */ X char *ed_data; /* pointer to malloc'ed data buffer */ X} EditLine; X Xtypedef struct meWrap X{ struct meWrap *mw_next; X struct stat mw_stat; /* stat of the enclosing directory */ X String mw_dir; /* name of the directory */ X Boolean mw_useTopDir; /* have found some data in the top dir */ X MonthEntry mw_me; /* what the external world sees */ X Instance *mw_list; /* list of toplevel widget for the */ X /* current set of displayed strips */ X EditLine *mw_ed; /* data being edited */ X} MeWrap; X X#define mw_year mw_me.me_year X#define mw_month mw_me.me_month X#define mw_have mw_me.me_have X Xstatic MeWrap *WrapBase; /* base of the list */ Xstatic MeWrap *WrapEnd; /* the last one in the list */ X Xchar *MapStem; /* pointer to the string which is */ X /* where the map data is stored */ X XBoolean FoundCalendarDir; /* whether the Calendar directory exists */ X Xstatic XtCallbackRec callbacks[] = { X {NULL,NULL}, X {NULL,NULL} X}; X#define ClearCallbacks() bzero((caddr_t)callbacks, sizeof (callbacks)) X X/* X * Routine specs X */ XMeWrap *NewMeWrap(); XMeWrap *MeWrapSearch(); Xvoid SetAllButtons(); Xvoid StartDayEditor(); Xvoid DeleteCalendarFile(); Xvoid Fatal(); Xvoid CheckExit(); Xvoid CleanEditPanel(); X X/* X * Fire up the month entry environment X * called once X */ Xvoid XInitMonthEntries() X{ char buf[BUFSIZ]; X char *home; X char *getenv(); X X if (MapStem == NULL) X { home = getenv("HOME"); X if (home == NULL) X { /* should do things with password files */ X /* but for now we will simply die */ X Fatal("Xcal needs HOME defined in the environment"); X } X (void) sprintf(buf, "%s/%s", home, appResources.directory); X MapStem = XtNewString(buf); X } X if (access(MapStem, F_OK) < 0) X FoundCalendarDir = False; X else X { FoundCalendarDir = True; X /* X * If we can see the directory, then lurch into it X */ X if (chdir(MapStem) < 0) X Fatal("Cannot change into %s", MapStem); X } X} X X/* X * Get the entry for a specific month X * X * xcalendar files are all X * xc<d><Mon><Year> X * or X * xc<dd><Mon><Year> X * X * where d or dd is the day (%02d would have been better) X * <Mon> is a capitalised first three letters of the X * English month name. If you need compatibility X * don't redefine the short names in the resources X * for this program. X * <Year> is the full numeric year. X * X * We will follow this BUT we will also make this program X * create subdirectories for new years X * xy<Year> X * to speed up file access X */ XMonthEntry * XGetMonthEntry(yr, mo) X Cardinal yr; X Cardinal mo; X{ X struct stat ns; X MeWrap *mw; X char *dir; X DIR *dirp; X#ifdef SYSV X struct dirent *dp; X#else X struct direct *dp; X#endif X int da; X Boolean inSubDir; X char yearbuf[5]; X char monthbuf[4]; X X if ((mw = MeWrapSearch(yr, mo)) == NULL) X mw = NewMeWrap(yr, mo); X X if (!FoundCalendarDir) X return(&mw->mw_me); X X /* X * need this for string match X */ X (void) sprintf(yearbuf, "%d", yr); X (void) sprintf(monthbuf, "%s", appResources.smon[mo]); X X /* we are in the directory */ X /* so let's lookee here for the any files of interest */ X X dir = "."; X inSubDir = False; X if (mw->mw_dir) X { dir = mw->mw_dir; X inSubDir = True; X } X X if (stat(dir, &ns) < 0) X Fatal("Cannot stat: %s/%s\n", MapStem, dir); X X if (mw->mw_stat.st_mtime == ns.st_mtime) X return(&mw->mw_me); X X mw->mw_stat = ns; X X if ((dirp = opendir(dir)) == NULL) X Fatal("Cannot open directory: %s", MapStem); X X for (da = 1; da < 32; da++) X if (mw->mw_have[da]) X { XtFree(mw->mw_have[da]); X mw->mw_have[da] = NULL; X } X X while ((dp = readdir(dirp)) != NULL) X { X#ifdef SYSV X int d_namlen = strlen(dp->d_name) +1; X switch(d_namlen) X#else X switch(dp->d_namlen) X#endif X { X case 6: /* xy<Year> ?? */ X if (dp->d_name[0] == 'x' && X dp->d_name[1] == 'y' && X dp->d_name[2] == yearbuf[0] && X dp->d_name[3] == yearbuf[1] && X dp->d_name[4] == yearbuf[2] && X dp->d_name[5] == yearbuf[3] && X appResources.calCompat == False) X { /* X * well - we're wasting our time at the X * top level - rejig things to work in the X * subdirectory X */ X inSubDir = True; X mw->mw_useTopDir = False; X mw->mw_dir = XtNewString(dp->d_name); X closedir(dirp); X if (stat(mw->mw_dir, &mw->mw_stat) < 0) X Fatal("Cannot stat directory %s/%s", MapStem, mw->mw_dir); X if ((dirp = opendir(mw->mw_dir)) == NULL) X Fatal("Cannot open directory %s/%s", MapStem, mw->mw_dir); X X } X break; X case 10: /* xc<d><Mon><Year> ?? */ X if (dp->d_name[0] == 'x' && X dp->d_name[1] == 'c' && X isdigit(dp->d_name[2]) && X dp->d_name[3] == monthbuf[0] && X dp->d_name[4] == monthbuf[1] && X dp->d_name[5] == monthbuf[2] && X dp->d_name[6] == yearbuf[0] && X dp->d_name[7] == yearbuf[1] && X dp->d_name[8] == yearbuf[2] && X dp->d_name[9] == yearbuf[3]) X { da = dp->d_name[2] - '0'; X mw->mw_have[da] = ReadCalendarFile(mw->mw_dir, dp->d_name); X if (inSubDir == False) X mw->mw_useTopDir = True; X } X break; X case 11: /* xc<dd><Mon><Year> ?? */ X if (dp->d_name[0] == 'x' && X dp->d_name[1] == 'c' && X isdigit(dp->d_name[2]) && X isdigit(dp->d_name[3]) && X dp->d_name[4] == monthbuf[0] && X dp->d_name[5] == monthbuf[1] && X dp->d_name[6] == monthbuf[2] && X dp->d_name[7] == yearbuf[0] && X dp->d_name[8] == yearbuf[1] && X dp->d_name[9] == yearbuf[2] && X dp->d_name[10] == yearbuf[3]) X { da = (dp->d_name[2]-'0')*10 + (dp->d_name[3]-'0'); X mw->mw_have[da] = ReadCalendarFile(mw->mw_dir, dp->d_name); X if (inSubDir == False) X mw->mw_useTopDir = True; X } X break; X } X } X closedir(dirp); X return(&mw->mw_me); X} X X/* X * create a new MapWrap area X */ Xstatic MeWrap * XNewMeWrap(yr, mo) X Cardinal yr; X Cardinal mo; X{ X register MeWrap *mw; X X mw = (MeWrap *)XtMalloc(sizeof (MeWrap)); X bzero(mw, sizeof (MeWrap)); X if (WrapEnd) X WrapEnd->mw_next = mw; X WrapEnd = mw; X if (WrapBase == NULL) X WrapBase = mw; X mw->mw_year = yr; X mw->mw_month = mo; X mw->mw_useTopDir = False; X return(mw); X} X X/* X * Search the MapWrap list for a year X */ Xstatic MeWrap * XMeWrapSearch(yr, mo) X Cardinal yr; X Cardinal mo; X{ X register MeWrap *mw; X X if (WrapBase) X for (mw = WrapBase; mw; mw = mw->mw_next) X if (yr == mw->mw_year && mo == mw->mw_month) X return(mw); X return(NULL); X} X X/* X * Register an instance of a month X * Return a pointer to an instance structure so it can be filled X * in by the caller X */ XInstance * XRegisterMonth(yr, mo, w) X Cardinal yr; X Cardinal mo; X Widget w; X{ X register MeWrap *mw; X register Instance *ins; X void DeRegisterMonth(); X X if ((mw = MeWrapSearch(yr, mo)) == NULL) X mw = NewMeWrap(yr, mo); X X ins = (Instance *)XtMalloc(sizeof(Instance)); X ins->i_next = mw->mw_list; X mw->mw_list = ins; X ins->i_w = w; X X callbacks[0].callback = DeRegisterMonth; X#ifdef LONG_IS_32_BITS X callbacks[0].closure = (caddr_t)DatePack(0, mo, yr); X#else X callbacks[0].closure = (caddr_t)DatePack(mo, yr); X#endif X X XtAddCallbacks(w, XtNdestroyCallback, callbacks); X return(ins); X} X X/* X * Return the head of an instance list - given a date X */ XInstance * XFindInstanceList(da) X Date *da; X{ X register MeWrap *mw; X X if ((mw = MeWrapSearch(da->year, da->month)) == NULL) X return(NULL); X return (mw->mw_list); X} X X/* X * Delete an instance X */ X/* ARGSUSED */ Xstatic void XDeRegisterMonth(w, closure, call_data) X Widget w; X caddr_t closure; X caddr_t call_data; X{ X Cardinal yr, mo; X register Instance *ins, *inlast; X register MeWrap *mw; X X yr = YrUnpack((Cardinal)closure); X mo = MoUnpack((Cardinal)closure); X X if ((mw = MeWrapSearch(yr, mo)) == NULL) X return; X for (ins = mw->mw_list, inlast = NULL; X ins; X inlast = ins, ins = ins->i_next) X { if (ins->i_w == w) X { if (inlast) X inlast->i_next = ins->i_next; X else mw->mw_list = ins->i_next; X XtFree(ins); X return; X } X inlast = ins; X } X} X X X/* X * Read a calendar file into memory into a string X * if the file is zero length then unlink and return NULL X */ XString XReadCalendarFile(dir, file) X String dir; X String file; X{ X char fname[256]; X int fd; X String destb; X struct stat fsb; X X if (dir) X { (void) sprintf(fname, "%s/%s", dir, file); X file = fname; X } X if ((fd = open(file, 0)) < 0) X Fatal("Cannot open: %s for reading", file); X if (fstat(fd, &fsb) < 0) X Fatal("Cannot fstat %s", file); X X if (fsb.st_size == 0) X { (void) unlink(file); X close(fd); X return (NULL); X } X destb = (String) XtMalloc(fsb.st_size+1); X X if (read(fd, (String)destb, fsb.st_size) != fsb.st_size) X Fatal("Read error on %s", file); X X close(fd); X X destb[fsb.st_size] = '\0'; X X return(destb); X} X X/* X * Write a calendar file creating any directories X * which are needed X * Return True is OK X */ Xstatic Boolean XWriteCalendarFile(mw, day, contents) X register MeWrap *mw; X Cardinal day; X char *contents; X{ X int fd; X Cardinal len; X char fname[256]; X char cname[16]; X X len = strlen(contents); X if (len == 0) X { DeleteCalendarFile(mw, day); X return(True); X } X /* X * First let's see if we have X * to create the toplevel directory X */ X if (!FoundCalendarDir) X { if (mkdir(MapStem, 0700) == -1) X { XBell(XtDisplay(toplevel), 0); X fprintf(stderr, "xcal: Could not create: %s directory.\n", MapStem); X perror("xcal: mkdir"); X fflush(stderr); X return(False); X } X if (chdir(MapStem) < 0) X { XBell(XtDisplay(toplevel), 0); X fprintf(stderr, "xcal: Could not chdir into %s.\n", MapStem); X perror("xcal: chdir"); X fflush(stderr); X return(False); X } X FoundCalendarDir = True; X } X /* X * So that looks OK X * We can now create the output file. X * However, we would like to put any new data into subdirectories X * named for the year unless we are compatible with xcalendar X */ X fname[0] = '\0'; X if (appResources.calCompat == False && mw->mw_useTopDir == False) X { /* we have no data in the top directory */ X /* so let's create the directory name */ X (void) sprintf(fname, "xy%d", mw->mw_year); X X if (access(fname, F_OK) < 0) X { if (mkdir(fname, 0700) < 0) X { XBell(XtDisplay(toplevel), 0); X fprintf(stderr, "xcal: Could not create: %s/%s directory.\n", MapStem, fname); X perror("xcal: mkdir "); X fflush(stderr); X return(False); X } X } X strcat(fname, "/"); X } X /* X * Whew - it looks as if we can now write the file X */ X (void) sprintf(cname, "xc%d%s%d", day, X appResources.smon[mw->mw_month], X mw->mw_year); X X strcat(fname, cname); 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, contents, 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 /* X * tickle the alarm system if we have altered `today' X */ X if (today.day == day && today.month == mw->mw_month && X today.year == mw->mw_year) X AlarmFilePoll(NULL); X return(True); X} X Xstatic void XDeleteCalendarFile(mw, day) X register MeWrap *mw; X Cardinal day; X{ X char fname[256]; X char cname[16]; X X fname[0] = '\0'; X X if (mw->mw_useTopDir == False) X { /* we have no data in the top directory */ X /* so let's create the directory name */ X (void) sprintf(fname, "xy%d", mw->mw_year); X X if (access(fname, F_OK) < 0) X return; X strcat(fname, "/"); X } X X (void) sprintf(cname, "xc%d%s%d", day, X appResources.smon[mw->mw_month], X mw->mw_year); X X strcat(fname, cname); X X unlink(fname); X X /* X * tickle the alarm system if we have altered `today' X */ X if (today.day == day && today.month == mw->mw_month && X today.year == mw->mw_year) X AlarmFilePoll(NULL); X} X X/* X * Start up an editor window from the callback X * Pass the calling widget so we can change its contents X * after the edit X */ X/* ARGSUSED */ Xvoid XStartEditing(w, da) X Widget w; X Date *da; X{ X register MeWrap *mw; X register EditLine *ed; X X if ((mw = MeWrapSearch(da->year, da->month)) == NULL) X mw = NewMeWrap(da->year, da->month); /* shouldn`t happen */ X /* X * see if we are already editing this day X */ X for (ed = mw->mw_ed; ed; ed = ed->ed_next) X { if (ed->ed_day == da->day) X { /* we are! */ X /* Complain via a popup */ X NoEditIsPossible(w, da); X return; X } X } X /* X * Things are looking OK X * Create a new editing record X */ X ed = (EditLine *)XtMalloc(sizeof(EditLine)); X bzero(ed, sizeof (EditLine)); X ed->ed_day = da->day; X ed->ed_meWrap = mw; /* help for unlinking */ X /* X * Do we have a string now X */ X if (mw->mw_have[da->day]) X { ed->ed_size = appResources.textbufsz + strlen(mw->mw_have[da->day]) + 1; X ed->ed_data = XtMalloc(ed->ed_size); X strcpy(ed->ed_data, mw->mw_have[da->day]); X } X else X { ed->ed_data = XtMalloc(ed->ed_size = appResources.textbufsz); X *ed->ed_data = '\0'; X } X /* X * put the record into the list X */ X ed->ed_next = mw->mw_ed; X mw->mw_ed = ed; X /* X * We fiddle with the source widget too X * Desensitise visible source widgets X * If the user starts up another strip for this month X * then the NoEditIsPossible() code above copes X */ X SetAllButtons(mw->mw_list, da->day, False); X /* X * Now we should start up the edit window for this X * month X */ X StartDayEditor(mw, da); X} X X X/* X * Set all the relevant buttons in a widget list to off or on X */ Xstatic void XSetAllButtons(ins, day, val) X Instance *ins; X Cardinal day; X Boolean val; X{ X for (;ins; ins = ins->i_next) X XtSetSensitive(ins->i_day_info[day], val); X} X X/* X * Start up a day editor X * Modelled on xcalendar.c X */ Xvoid XStartDayEditor(mw, da) X register MeWrap *mw; X register Date *da; X{ X register EditLine *ed = mw->mw_ed; /* top of the list is ours */ X Widget lw, et; X Widget frame; X Arg args[10]; X Cardinal nargs; X char buf[64]; X extern Widget toplevel; X void FinishEditing(); X void SaveEdits(); X void ClearEntry(); X void TextChanged(); X void EditHelp(); X X ed->ed_popup = XtCreatePopupShell("edit", topLevelShellWidgetClass, toplevel, NULL, 0); X X /* X * Create the title line - which is a form containing X * buttons and a date label X */ X et = XtCreateManagedWidget("panel", panedWidgetClass, ed->ed_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 * Take label "quit" from resources X */ X callbacks[0].callback = FinishEditing; X callbacks[0].closure = (caddr_t)ed; 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 ed->ed_quit = XtCreateManagedWidget("quit", commandWidgetClass, frame, args, nargs); X X /* X * Take label "save" from resources X */ X callbacks[0].callback = SaveEdits; X callbacks[0].closure = (caddr_t)ed; X nargs = 0; X XtSetArg(args[nargs], XtNcallback, callbacks); nargs++; X XtSetArg(args[nargs], XtNfromHoriz, ed->ed_quit); nargs++; X XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++; X XtSetArg(args[nargs], XtNright, XtChainLeft); nargs++; X XtSetArg(args[nargs], XtNsensitive, False); nargs++; X lw = ed->ed_save = XtCreateManagedWidget("save", commandWidgetClass, frame, args, nargs); X X if (appResources.giveHelp) X { X /* X * Take label "help" from resources X */ X callbacks[0].callback = EditHelp; 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 PlaceStr(buf, da->day, appResources.mon[da->month], da->year); 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 = XtCreateManagedWidget("date", 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 = TextChanged; X callbacks[0].closure = (caddr_t)ed; X nargs = 0; X XtSetArg(args[nargs], XtNshowGrip, False); nargs++; X XtSetArg(args[nargs], XtNstring, ed->ed_data); nargs++; X XtSetArg(args[nargs], XtNeditType, XawtextEdit); nargs++; X XtSetArg(args[nargs], XtNlength, ed->ed_size); nargs++; X XtSetArg(args[nargs], XtNuseStringInPlace, True); nargs++; X XtSetArg(args[nargs], XtNcallback, callbacks); nargs++; X ed->ed_text = XtCreateManagedWidget("text", asciiTextWidgetClass, et, args, nargs); X X XtPopup(ed->ed_popup, XtGrabNone); X X} X X/* X * Callback for text widget X * This gets called before the string is updated X */ X/* ARGSUSED */ Xstatic void XTextChanged(w, closure, call_data) X Widget w; X caddr_t closure; X caddr_t call_data; X{ X register EditLine *ed = (EditLine *)closure; X X XtSetSensitive(ed->ed_save, True); X} X X X/* X * Callback routines X */ X/* ARGSUSED */ Xvoid XSaveEdits(w, closure, call_data) X Widget w; X caddr_t closure; X caddr_t call_data; X{ X register EditLine *ed = (EditLine *)closure; X register Instance *ins; X register MeWrap *mw; X register Cardinal day; X extern Widget toplevel; X Arg args[3]; X X mw = ed->ed_meWrap; X day = ed->ed_day; X X if (WriteCalendarFile(mw, day, ed->ed_data) == False) X return; X /* X * Otherwise change the displayed string X */ X if (mw->mw_have[day]) X XtFree(mw->mw_have[day]); X mw->mw_have[day] = XtMalloc(strlen(ed->ed_data)+1); X strcpy(mw->mw_have[day], ed->ed_data); X X XtSetArg(args[0], XtNlabel, mw->mw_have[day]); X if (*mw->mw_have[day]) X { XtSetArg(args[1], XtNforeground, appResources.marked.fg); X XtSetArg(args[2], XtNbackground, appResources.marked.bg); X } X for (ins = mw->mw_list; ins; ins = ins->i_next) X { if (*mw->mw_have[day] == '\0') X { XtSetArg(args[1], XtNforeground, ins->i_col.fg); X XtSetArg(args[2], XtNbackground, ins->i_col.bg); X } X XtSetValues(ins->i_day_info[day], args, 3); X } X XtSetSensitive(ed->ed_save, False); X X /* X * worry about updating the memo system X */ X if (today.day == day && today.month == mw->mw_month && X today.year == mw->mw_year) X UpdateMemo(); X X} X Xstatic void XFinishEditing(w, closure, call_data) X Widget w; X caddr_t closure; X caddr_t call_data; X{ X register EditLine *ed = (EditLine *)closure; X register MeWrap *mw; X Cardinal day; X X mw = ed->ed_meWrap; X day = ed->ed_day; X X if (mw->mw_have[day] == NULL) X { if (*ed->ed_data) X { CheckExit(ed); X return; X } X } X else X if (strcmp(mw->mw_have[day], ed->ed_data)) X { CheckExit(ed); X return; X } X CleanEditPanel(w, ed, call_data); X} X Xstatic void XCleanEditPanel(w, closure, call_data) X Widget w; X caddr_t closure; X caddr_t call_data; X{ X register EditLine *ed = (EditLine *)closure; X register EditLine *edl, *eds; X register MeWrap *mw; X Cardinal day; X Widget popup; X X mw = ed->ed_meWrap; X day = ed->ed_day; X popup = ed->ed_popup; X X XtFree(ed->ed_data); X X for (edl = NULL, eds = mw->mw_ed; X eds; X edl = eds, eds = eds->ed_next) X { if (eds == ed) X { if (edl) X edl->ed_next = ed->ed_next; X else mw->mw_ed = ed->ed_next; X break; X } X } X XtFree(ed); X XtPopdown(popup); X XtDestroyWidget(popup); X X SetAllButtons(mw->mw_list, day, True); X} X X/* X * We are trying to leave with saving the data X * let us see if the user really wants to X */ Xstatic void XCheckExit(ed) X register EditLine *ed; X{ X void CheckDia(); X X DialogPopup(ed->ed_quit, CheckDia, ed); X} X X/* X * Here we do the work X */ Xstatic void XCheckDia(pop, ed) X Widget pop; X EditLine *ed; X{ X Widget dia; X void YesCheck(); X void NoCheck(); 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 SaveEdits(w, closure, call_data); X CleanEditPanel(w, closure, call_data); 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 CleanEditPanel(w, closure, call_data); X XtDestroyWidget(XtParent(XtParent(w))); X} X X X/* X * Slighty formatted XtError X */ X/* VARARGS1 */ Xvoid XFatal(fmt, a, b) X char *fmt; X char *a; X char *b; X{ X char buf[BUFSIZ]; X X (void) sprintf(buf, fmt, a, b); X XtError(buf); X /* NOTREACHED */ X} SHAR_EOF if test 22066 -ne "`wc -c < 'xcal_edit.c'`" then echo shar: error transmitting "'xcal_edit.c'" '(should have been 22066 characters)' fi fi # end of overwriting check echo shar: extracting "'xcal_help.c'" '(6540 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.5 (Hillside Systems) 12/7/90"; 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} SHAR_EOF if test 6540 -ne "`wc -c < 'xcal_help.c'`" then echo shar: error transmitting "'xcal_help.c'" '(should have been 6540 characters)' fi fi # end of overwriting check echo shar: extracting "'xcal_memo.c'" '(11975 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.3 (Hillside Systems) 12/7/90"; 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/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#include <unistd.h> /* works on my Sun */ X /* I need the access code */ 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 Widget m_display; /* widget of display title area */ X Widget m_text; /* the text area */ X Widget m_today; /* today's data */ X Cardinal m_size; /* size of the buffer */ X char *m_data; /* pointer to malloc'ed data buffer */ X} MemoEdit; X Xstatic MemoEdit memo; XString GetMemoFile(); X Xextern Boolean FoundCalendarDir; /* whether the Calendar directory exists */ X Xstatic String memoContents; X X X/* X * Internal routines X */ Xvoid MemoPopup(); Xvoid CleanMemo(); Xvoid MemoCheckExit(); Xvoid MCheckDia(); XBoolean WriteMemoFile(); Xint NewlineCount(); 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 X /* X * Make button not sensitive X */ X XtSetSensitive(memo.m_button = w, False); X MouseShow(w, False); X /* X * Get existing memo contents X * if any 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 Cardinal len; X String str; X MonthEntry *me; X char buf[32]; X void FinishMemoEditing(); X void SaveMemoEdits(); X void MemoTextChanged(); X void MemoHelp(); 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.day, appResources.mon[today.month], today.year); 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 height = height*NewlineCount(str); X XtSetArg(args[0], XtNheight, height); X XtSetValues(memo.m_today, args, 1); X } X 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 /* 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 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 XtSetSensitive(memo->m_save, True); X} X X/* X * Callback routines X */ X/* ARGSUSED */ Xvoid 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 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 (!FoundCalendarDir) X { if (mkdir(MapStem, 0700) == -1) X { XBell(XtDisplay(toplevel), 0); X fprintf(stderr, "xcal: Could not create: %s directory.\n", MapStem); X perror("xcal: mkdir"); X fflush(stderr); X return(False); X } X if (chdir(MapStem) < 0) X { XBell(XtDisplay(toplevel), 0); X fprintf(stderr, "xcal: Could not chdir into %s.\n", MapStem); X perror("xcal: chdir"); X fflush(stderr); X return(False); X } X FoundCalendarDir = True; X } X X fname = appResources.memoFile; 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 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 (memoContents == NULL || strcmp(memoContents, memo.m_data)) X { MemoCheckExit(); X return; X } X CleanMemo(); X} X Xstatic void XCleanMemo() X{ X XtSetSensitive(memo.m_button, True); 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 void YesCheck(); X void NoCheck(); 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 11975 -ne "`wc -c < 'xcal_memo.c'`" then echo shar: error transmitting "'xcal_memo.c'" '(should have been 11975 characters)' fi fi # end of overwriting check echo shar: extracting "'xcal_strip.c'" '(14269 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.6 (Hillside Systems) 12/7/90"; 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#ifdef LONG_IS_32_BITS Xvoid YmBack(); X#endif Xvoid StripQuit(); X Xvoid MakeNewMonth(); X XCardinal DateSum(); XCardinal NumberOfDays(); XCardinal FirstDay(); XCardinal JanuaryOne(); 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/* 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 MonthEntry *me; X Instance *ins; X register int i; X register Cardinal nargs; X Cardinal thisDay; 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 void StripHelp(); X X (void) sprintf(iconName, "%s %d", appResources.smon[td->month], td->year); X X XtSetArg(args[0], XtNiconName, iconName); X shell = XtCreatePopupShell(XtNewString(iconName), topLevelShellWidgetClass, toplevel, args, 1); X X ins = RegisterMonth(td->year, td->month, shell); X X mon = XtCreateManagedWidget(appResources.mon[td->month], panedWidgetClass, shell, NULL, 0); X X thisDay = FirstDay(td->month, td->year); X numberOfDays = NumberOfDays(td->month, td->year); X /* X * Get the map for this year X */ X me = GetMonthEntry(td->year, td->month); 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 /* 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 /* 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#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 = 1; i <= numberOfDays; i++) X { X dayStr = appResources.day[thisDay]; X (void) sprintf(nbuf, "%2d %s", i, dayStr); X thisDay = (thisDay+1)%7; X X#ifdef LONG_IS_32_BITS X callbacks[0].closure = (caddr_t)DatePack(i, td->month, td->year); X#else X callbacks[0].closure = (caddr_t)DatePack(td->month, td->year); X callbacks[1].closure = (caddr_t)i; X#endif 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 && today.day == 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 * 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, 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 callb.day = DyUnpack((Cardinal)closure); X#else X callb.day = (Cardinal)closure; X#endif 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 14269 -ne "`wc -c < 'xcal_strip.c'`" then echo shar: error transmitting "'xcal_strip.c'" '(should have been 14269 characters)' fi fi # end of overwriting check # End of shell archive exit 0 -- dan ---------------------------------------------------- O'Reilly && Associates argv@sun.com / argv@ora.com Opinions expressed reflect those of the author only.