Xmh patches for repl/forw style annotation (unofficial) + bug fix
R.P.A.Collinson
pc at ukc.ac.uk
Fri Feb 15 11:59:05 AEST 1991
(**Contains bug fix to previous posting that must be applied**)
These diffs allow you to see when you have replied or forwarded mail
by making a note at the top of the source message(s). Regular mh does
this and I have long wanted xmh to do this too. The diffs have been
sent into MIT - who told me that they will use them but will not
distribute them at this time.
I regret that this is a second release of this. The first release broke
xmh for people who DIDN'T want to annotate their mail. There are two
files here: if you have installed the previous patches (<2485 at ukc>)
then you need to apply `bug_patch'. If not, throw bug_patch away and
patch with the Diffs file.
Apologies for this reposting - but it does seem sensible to keep all
this together in one file.
The diffs permit the `standard' xmh release with X11R4 to annotate
messages that have been replied to or forwarded. I have tested this ONLY
with mh6.7. Annotation is controlled by resources - see the manual page.
Annotation will not SHOW if a currently displayed message is annotated.
Most of the work is done in a new file `anno.c', this also contains
the theory of behaviour. Most of the other changes just insert code
to call the appropriate routines.
#! /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:
# bug_patch
# Diffs
# This archive created: Thu Feb 14 22:45:00 1991
export PATH; PATH=/bin:$PATH
echo shar: extracting "'bug_patch'" '(1492 characters)'
if test -f 'bug_patch'
then
echo shar: will not over-write existing file "'bug_patch'"
else
sed 's/^ X//' << \SHAR_EOF > 'bug_patch'
XTo: pc
XSubject: bug in your annotation patches for xmh
XDate: Thu, 14 Feb 91 16:00:45 +0100
XFrom: Sjoerd Mullender <sjoerd at cwi.nl>
X
X
XI found a bug in your annotation patches for xmh. The problem is: when
Xa user does not annotate his/her mail, AnnoInitEnv isn't called, but
XAnnoEnvSet and AnnoEnvReset are called. Since our_env isn't
Xinitialised, you get a core dump. I include a context diff of the
Xpatched msg.c.
X
X*** msg.c.bug Mon Feb 4 11:08:04 1991
X--- msg.c Thu Feb 14 15:56:35 1991
X***************
X*** 731,737 ****
X }
X (void) myfclose(from);
X (void) myfclose(to);
X! AnnoEnvSet(msg);
X argv = MakeArgv(3);
X argv[0] = "send";
X argv[1] = "-push";
X--- 731,738 ----
X }
X (void) myfclose(from);
X (void) myfclose(to);
X! if (app_resources.annotate_repl || app_resources.annotate_forw)
X! AnnoEnvSet(msg);
X argv = MakeArgv(3);
X argv[0] = "send";
X argv[1] = "-push";
X***************
X*** 738,744 ****
X argv[2] = str;
X DoCommand(argv, (char *) NULL, (char *) NULL);
X XtFree((char *) argv);
X! AnnoEnvReset();
X }
X
X
X--- 739,746 ----
X argv[2] = str;
X DoCommand(argv, (char *) NULL, (char *) NULL);
X XtFree((char *) argv);
X! if (app_resources.annotate_repl || app_resources.annotate_forw)
X! AnnoEnvReset();
X }
X
X
X
XSjoerd Mullender
XCWI, dept. CST, Kruislaan 413, 1098 SJ Amsterdam, Netherlands
Xemail: sjoerd at cwi.nl fax: +31 20 592 4199
Xphone: +31 20 592 4132 telex: 12571 mactr nl
SHAR_EOF
if test 1492 -ne "`wc -c < 'bug_patch'`"
then
echo shar: error transmitting "'bug_patch'" '(should have been 1492 characters)'
fi
chmod +x 'bug_patch'
fi # end of overwriting check
echo shar: extracting "'Diffs'" '(13986 characters)'
if test -f 'Diffs'
then
echo shar: will not over-write existing file "'Diffs'"
else
sed 's/^ X//' << \SHAR_EOF > 'Diffs'
XThese diffs permit the `standard' xmh release with X11R4 to annotate
Xmessages that have been replied to or forwarded. I have tested this ONLY
Xwith mh6.7. Annotation is controlled by resources - see the manual page.
X
XAnnotation will not SHOW if a currently displayed message is annotated.
X
XMost of the work is done in a new file `anno.c', this also contains
Xthe theory of behaviour. Most of the other changes just insert code
Xto call the appropriate code.
X
X(Note this is a second release of this. The first release broke for
Xpeople who DIDN'T want to annotate their mail)
X
X*** /dev/null Thu Feb 14 21:34:02 1991
X--- anno.c Sun Dec 23 21:14:56 1990
X***************
X*** 0 ****
X--- 1,271 ----
X+ /*
X+ * anno.c
X+ * - routines concerned with annotation
X+ * File added by Peter Collinson, Hillside Systems
X+ * pc at hillside.co.uk
X+ */
X+
X+ /*
X+ * Background
X+ * mh6.7 uses various environment variables to permit message
X+ * annotation.
X+ *
X+ * a) mhfolder
X+ * contains the name of the folder to be annotated
X+ * b) mhmessages
X+ * space separated list of messages to annotate
X+ * c) mhannotate
X+ * text to use for annotation
X+ * d) mhinplace
X+ * 1 to annotate inplace
X+ * 0 not to
X+ *
X+ * Theory
X+ * Add a character string to a Scrn containing the message list
X+ * for annotation.
X+ * When send is called push the various objects into the
X+ * environment
X+ */
X+ #include "xmh.h"
X+ #include "tocintrnl.h"
X+
X+ static int MheLookup();
X+ static Scrn AnnoSearch();
X+ static char *MakeEnv();
X+
X+ /*
X+ * Given a message - create an annotation list and
X+ * return it
X+ */
X+ char *
X+ AnnoMsgCreate(msg)
X+ Msg msg;
X+ {
X+ MsgListRec ml;
X+ char *AnnoCreate();
X+
X+ ml.nummsgs = 1;
X+ ml.msglist = &msg;
X+ return (AnnoCreate(&ml));
X+ }
X+
X+ /*
X+ * given an mlist - create an annotation list
X+ * and return it - the first element in the list is the
X+ * name of the folder
X+ *
X+ */
X+ char *
X+ AnnoCreate(mlist)
X+ MsgList mlist;
X+ {
X+ char *anno;
X+ char *folder;
X+ int bytes;
X+ register int d;
X+ register int i;
X+ char *src;
X+ char numbuf[16];
X+
X+ if (mlist->nummsgs == 0)
X+ return (NULL);
X+
X+ folder = mlist->msglist[0]->toc->foldername;
X+ anno = (char *)XtMalloc(512);
X+ bytes = 512;
X+ for (d = 0, src = app_resources.mail_path; anno[d++] = *src++;);
X+ anno[d-1] = '/';
X+ for (src = folder; anno[d++] = *src++;);
X+ d--;
X+
X+
X+ for (i = 0; i < mlist->nummsgs; i++)
X+ {
X+ (void) sprintf(numbuf, "%d", mlist->msglist[i]->msgid);
X+
X+ if (d+16 > bytes)
X+ { bytes += 512;
X+ anno = (char *)XtRealloc(anno, bytes);
X+ }
X+ /* add a space */
X+ anno[d++] = ' ';
X+ for (src = numbuf; anno[d++] = *src++;);
X+ d--;
X+ }
X+ anno[d] = '\0';
X+ return (anno);
X+ }
X+
X+ /*
X+ * We will need to add and delete four things from
X+ * the environment. This could be done after the fork()
X+ * but this means that we have to change the environment
X+ * to be sure of not affecting any other programs
X+ *
X+ * So the idea here is to copy the environment into our vector
X+ * deleting the four things that we are interested in
X+ * we then put OUR things in the first four string positions
X+ */
X+ static char **our_env; /* this points at our environment */
X+ extern char **environ; /* what the world sees */
X+
X+ typedef struct addenv
X+ { char *add;
X+ int len;
X+ } Addenv;
X+
X+ static Addenv adde[] =
X+ {
X+ { "mhfolder=", 9 },
X+ { "mhmessages=", 11 },
X+ { "mhannotate=", 11 },
X+ { "mhinplace=", 10 },
X+ { NULL, 0 }
X+ };
X+
X+ #define MHE_FOLDER 0
X+ #define MHE_MESSAGES 1
X+ #define MHE_ANNOTATE 2
X+ #define MHE_INPLACE 3
X+
X+ AnnoInitEnv()
X+ {
X+ register int count; /* number of things in the environment */
X+ register char **pt;
X+ register char **dst;
X+ char inp[16];
X+
X+
X+ if (our_env)
X+ return;
X+
X+ for (count = 0, pt = environ; *pt++; count++);
X+
X+ our_env = (char **)XtMalloc((count+5)*sizeof (char **));
X+ our_env[0] = our_env[1] = our_env[2] = NULL;
X+
X+ /* copy the environment into `our' environment */
X+ /* start at position 4 */
X+ dst = &our_env[4];
X+
X+ for (pt = environ; *pt; pt++)
X+ {
X+ if (MheLookup(*pt))
X+ continue;
X+ *dst++ = *pt;
X+ }
X+ *dst = NULL;
X+ /*
X+ * set up the inplace value
X+ */
X+ (void) sprintf(inp, "%s%d", adde[MHE_INPLACE].add, app_resources.annotate_in_place);
X+ our_env[MHE_INPLACE] = XtNewString(inp);
X+ }
X+
X+ /*
X+ * Look in the list of things we are dealing with
X+ * to find a match in the environment
X+ */
X+ static int
X+ MheLookup(env)
X+ char *env;
X+ {
X+ register Addenv *ae;
X+
X+ for (ae = adde; ae->add; ae++)
X+ if (strncmp(env, ae->add, ae->len) == 0)
X+ return(1);
X+ return 0;
X+ }
X+
X+ /*
X+ * Reset the environment to the standard
X+ */
X+ AnnoEnvReset()
X+ {
X+ environ = &our_env[4];
X+ }
X+
X+ /*
X+ * Set the environment to new values
X+ */
X+ AnnoEnvSet(msg)
X+ Msg msg;
X+ {
X+ Scrn scrn;
X+ char *folder;
X+ char *annotate;
X+ char *s;
X+ char *d;
X+ register i;
X+ Scrn AnnoSearch();
X+ char buf[512];
X+
X+ if ((scrn = AnnoSearch(msg)) == NULL)
X+ return;
X+
X+ switch (scrn->anno_type)
X+ {
X+ case ANrepl:
X+ annotate = "Replied";
X+ break;
X+ case ANforw:
X+ annotate = "Forwarded";
X+ break;
X+ default: /* shouldn't happen */
X+ return;
X+ }
X+
X+ for (i = 0; i < MHE_INPLACE; i++)
X+ if (our_env[i])
X+ { XtFree(our_env[i]);
X+ our_env[i] = NULL;
X+ }
X+ /*
X+ * Munge the annotation list
X+ * we see it as
X+ * folder-name number number
X+ */
X+ for (s = scrn->anno_list, d = buf; *s != ' '; *d++ = *s++);
X+ *d = '\0';
X+ s++;
X+
X+ our_env[MHE_FOLDER] = MakeEnv(&adde[MHE_FOLDER], buf);
X+ our_env[MHE_MESSAGES] = MakeEnv(&adde[MHE_MESSAGES], s);
X+ our_env[MHE_ANNOTATE] = MakeEnv(&adde[MHE_ANNOTATE], annotate);
X+ environ = our_env;
X+ }
X+
X+ static Scrn
X+ AnnoSearch(msg)
X+ Msg msg;
X+ {
X+ register i;
X+ AnnoKind ak;
X+
X+ if (msg->num_scrns == 0)
X+ return (NULL);
X+
X+ for (i = 0; i < msg->num_scrns; i++)
X+ {
X+ if ((ak = msg->scrn[i]->anno_type) == ANrepl)
X+ return(msg->scrn[i]);
X+ else
X+ if (ak == ANforw)
X+ return(msg->scrn[i]);
X+ }
X+ return (NULL);
X+ }
X+
X+
X+
X+ static char *
X+ MakeEnv(ad, value)
X+ register Addenv *ad;
X+ char *value;
X+ {
X+ char buf[512];
X+
X+ (void) sprintf(buf, "%s%s", ad->add, value);
X+ return (XtNewString(buf));
X+ }
X*** Imakefile~ Thu Feb 14 22:33:41 1991
X--- Imakefile Sun Dec 23 21:15:33 1990
X***************
X*** 8,17 ****
X
X SRCS = bbox.c command.c compfuncs.c folder.c icon.c init.c \
X main.c menu.c mlist.c msg.c pick.c popup.c screen.c \
X! toc.c tocfuncs.c tocutil.c tsource.c util.c viewfuncs.c
X OBJS = bbox.o command.o compfuncs.o folder.o icon.o init.o \
X main.o menu.o mlist.o msg.o pick.o popup.o screen.o \
X! toc.o tocfuncs.o tocutil.o tsource.o util.o viewfuncs.o
X
X
X ComplexProgramTarget(xmh)
X--- 8,17 ----
X
X SRCS = bbox.c command.c compfuncs.c folder.c icon.c init.c \
X main.c menu.c mlist.c msg.c pick.c popup.c screen.c \
X! toc.c tocfuncs.c tocutil.c tsource.c util.c viewfuncs.c anno.c
X OBJS = bbox.o command.o compfuncs.o folder.o icon.o init.o \
X main.o menu.o mlist.o msg.o pick.o popup.o screen.o \
X! toc.o tocfuncs.o tocutil.o tsource.o util.o viewfuncs.o anno.o
X
X
X ComplexProgramTarget(xmh)
X*** compfuncs.c~ Thu Feb 14 22:33:42 1991
X--- compfuncs.c Sun Dec 23 21:15:33 1990
X***************
X*** 117,122 ****
X--- 117,124 ----
X {
X Scrn scrn;
X Msg msg;
X+ char *AnnoCreate();
X+
X scrn = NewCompScrn();
X msg = TocMakeNewMsg(DraftsFolder);
X MsgLoadForward(scrn, msg, mlist);
X***************
X*** 123,126 ****
X--- 125,133 ----
X MsgSetTemporary(msg);
X MsgSetScrnForComp(msg, scrn);
X MapScrn(scrn);
X+ if (app_resources.annotate_forw) {
X+ scrn->anno_type = ANforw;
X+ scrn->anno_list = AnnoCreate(mlist);
X+ }
X+
X }
X*** globals.h~ Thu Feb 14 22:33:42 1991
X--- globals.h Sun Dec 23 21:15:31 1990
X***************
X*** 76,81 ****
X--- 76,84 ----
X int command_button_count; /* number of buttons in command box */
X int app_defaults_version; /* for sanity check */
X char *banner; /* defaults to xmh version string */
X+ Boolean annotate_repl; /* true if we are to annotate reply sources */
X+ Boolean annotate_forw; /* true if we are to annotate forw sources */
X+ int annotate_in_place; /* 0 if don't annotate inplace, 1 otherwise */
X } app_resources;
X
X ext char *draftFile; /* Filename of draft. */
X*** init.c~ Thu Feb 14 22:33:43 1991
X--- init.c Sun Dec 23 21:15:31 1990
X***************
X*** 124,129 ****
X--- 124,135 ----
X offset(app_defaults_version), XtRImmediate, (XtPointer)0},
X {"banner", "Banner", XtRString, sizeof(char *),
X offset(banner), XtRString, "xmh MIT X Consortium R4"},
X+ {"annotateRepl", "AnnotateRepl", XtRBoolean, sizeof(Boolean),
X+ offset(annotate_repl), XtRImmediate, (XtPointer)False},
X+ {"annotateForw", "AnnotateForw", XtRBoolean, sizeof(Boolean),
X+ offset(annotate_forw), XtRImmediate, (XtPointer)False},
X+ {"annotateInPlace", "AnnotateInPlace", XtRInt, sizeof(int),
X+ offset(annotate_in_place), XtRImmediate, (XtPointer)1},
X };
X
X #undef offset
X***************
X*** 396,401 ****
X--- 402,413 ----
X InitPick();
X IconInit();
X BBoxInit();
X+
X+ /*
X+ * Initialise annotations if required
X+ */
X+ if (app_resources.annotate_repl || app_resources.annotate_forw)
X+ AnnoInitEnv();
X
X XtAppAddActions( XtWidgetToApplicationContext(toplevel),
X actions, XtNumber(actions));
X*** msg.c~ Thu Feb 14 22:33:43 1991
X--- msg.c Thu Feb 14 22:24:25 1991
X***************
X*** 731,736 ****
X--- 731,738 ----
X }
X (void) myfclose(from);
X (void) myfclose(to);
X+ if (app_resources.annotate_repl || app_resources.annotate_forw)
X+ AnnoEnvSet(msg);
X argv = MakeArgv(3);
X argv[0] = "send";
X argv[1] = "-push";
X***************
X*** 737,742 ****
X--- 739,746 ----
X argv[2] = str;
X DoCommand(argv, (char *) NULL, (char *) NULL);
X XtFree((char *) argv);
X+ if (app_resources.annotate_repl || app_resources.annotate_forw)
X+ AnnoEnvReset();
X }
X
X
X*** screen.c~ Thu Feb 14 22:33:44 1991
X--- screen.c Sun Dec 23 21:15:31 1990
X***************
X*** 391,396 ****
X--- 391,398 ----
X Scrn scrn;
X scrn = CreateNewScrn(STcomp);
X scrn->assocmsg = (Msg)NULL;
X+ scrn->anno_type = ANno;
X+ scrn->anno_list = NULL;
X return scrn;
X }
X
X***************
X*** 412,417 ****
X--- 414,423 ----
X TocSetScrn((Toc) NULL, scrn);
X MsgSetScrnForce((Msg) NULL, scrn);
X lastInput.win = -1;
X+ if (scrn->anno_list) {
X+ XtFree(scrn->anno_list);
X+ scrn->anno_list = NULL;
X+ }
X }
X }
X
X*** tocfuncs.c~ Thu Feb 14 22:33:44 1991
X--- tocfuncs.c Sun Dec 23 21:15:32 1990
X***************
X*** 651,656 ****
X--- 651,657 ----
X Scrn nscrn;
X MsgList mlist;
X Msg msg;
X+ char *AnnoMsgCreate();
X
X if (toc == NULL) return;
X mlist = CurMsgListOrCurMsg(toc);
X***************
X*** 657,662 ****
X--- 658,667 ----
X if (mlist->nummsgs) {
X nscrn = NewCompScrn();
X ScreenSetAssocMsg(nscrn, mlist->msglist[0]);
X+ if (app_resources.annotate_repl)
X+ { nscrn->anno_type = ANrepl;
X+ nscrn->anno_list = AnnoMsgCreate(mlist->msglist[0]);
X+ }
X msg = TocMakeNewMsg(DraftsFolder);
X MsgSetTemporary(msg);
X MsgLoadReply(msg, mlist->msglist[0]);
X*** viewfuncs.c~ Thu Feb 14 22:33:45 1991
X--- viewfuncs.c Sun Dec 23 21:15:32 1990
X***************
X*** 76,85 ****
X Scrn scrn = (Scrn) client_data;
X Msg msg;
X Scrn nscrn;
X!
X if (scrn->msg == NULL) return;
X nscrn = NewCompScrn();
X ScreenSetAssocMsg(nscrn, scrn->msg);
X msg = TocMakeNewMsg(DraftsFolder);
X MsgSetTemporary(msg);
X MsgLoadReply(msg, scrn->msg);
X--- 76,90 ----
X Scrn scrn = (Scrn) client_data;
X Msg msg;
X Scrn nscrn;
X! char *AnnoMsgCreate();
X!
X if (scrn->msg == NULL) return;
X nscrn = NewCompScrn();
X ScreenSetAssocMsg(nscrn, scrn->msg);
X+ if (app_resources.annotate_repl)
X+ { nscrn->anno_type = ANrepl;
X+ nscrn->anno_list = AnnoMsgCreate(scrn->msg);
X+ }
X msg = TocMakeNewMsg(DraftsFolder);
X MsgSetTemporary(msg);
X MsgLoadReply(msg, scrn->msg);
X*** xmh.h~ Thu Feb 14 22:33:45 1991
X--- xmh.h Sun Dec 23 21:15:31 1990
X***************
X*** 90,95 ****
X--- 90,101 ----
X STpick
X } ScrnKind;
X
X+ typedef enum {
X+ ANno,
X+ ANrepl,
X+ ANforw
X+ } AnnoKind;
X+
X typedef struct _StackRec {
X char *data;
X struct _StackRec *next;
X***************
X*** 119,124 ****
X--- 125,132 ----
X Msg assocmsg; /* Associated message for reply, etc. */
X Window wait_window; /* InputOnly window with busy cursor */
X Stack folder_stack; /* Stack of folder names */
X+ AnnoKind anno_type; /* type of annotation */
X+ char * anno_list; /* list of messages to annotate */
X } ScrnRec, *Scrn;
X
X
X*** xmh.man~ Thu Feb 14 22:33:46 1991
X--- xmh.man Mon Dec 24 12:02:12 1990
X***************
X*** 921,926 ****
X--- 921,946 ----
X
X The following resources are defined:
X .TP 8
X+ .B AnnotateRepl
X+ Permits annotation of messages that are being replied to.
X+ This uses the standard
X+ .I mh
X+ mechanism in
X+ .IR send .
X+ Default is false.
X+ .TP 8
X+ .B AnnotateForw
X+ Permits annotation of messages that are being forwarded.
X+ This uses the standard
X+ .I mh
X+ mechanism in
X+ .IR send .
X+ Default is false.
X+ .TP
X+ .B AnnotateInPlace
X+ When set to non-zero causes annotation to be done in place to preserve
X+ links to the annotated message.
X+ .TP 8
X .B Banner
X A short string that is the default label of the folder, Table of Contents,
X and view. The default is "xmh MIT X Consortium R4".
X***************
X*** 1241,1243 ****
X--- 1261,1265 ----
X Terry Weissman, Digital Western Research Laboratory
X .br
X modified by Donna Converse, MIT X Consortium
X+ .br
X+ Annotation code by Peter Collinson, Hillside Systems
SHAR_EOF
if test 13986 -ne "`wc -c < 'Diffs'`"
then
echo shar: error transmitting "'Diffs'" '(should have been 13986 characters)'
fi
chmod +x 'Diffs'
fi # end of overwriting check
# End of shell archive
exit 0
More information about the Alt.sources
mailing list