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