Xmh patches for repl/forw style annotation (unofficial)
R.P.A.Collinson
pc at ukc.ac.uk
Sat Feb 2 12:03:55 AEST 1991
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 am unsure what news group(s) is/are appropriate so I am guessing -
please forgive me if you consider this is unwarranted intrusion into
your conversation.
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 on a Sparc 1+ running SunOs 4.1 and OpenWindows2.
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 code.
PS. If anyone has fixed the problem where xmh current message is not
that the same as that shown by mhpath cur - then please let me know.
------ patch away from here ------
*** /dev/null Wed Jan 2 22:32:51 1991
--- anno.c Sun Dec 23 21:14:56 1990
***************
*** 0 ****
--- 1,271 ----
+ /*
+ * anno.c
+ * - routines concerned with annotation
+ * File added by Peter Collinson, Hillside Systems
+ * pc at hillside.co.uk
+ */
+
+ /*
+ * Background
+ * mh6.7 uses various environment variables to permit message
+ * annotation.
+ *
+ * a) mhfolder
+ * contains the name of the folder to be annotated
+ * b) mhmessages
+ * space separated list of messages to annotate
+ * c) mhannotate
+ * text to use for annotation
+ * d) mhinplace
+ * 1 to annotate inplace
+ * 0 not to
+ *
+ * Theory
+ * Add a character string to a Scrn containing the message list
+ * for annotation.
+ * When send is called push the various objects into the
+ * environment
+ */
+ #include "xmh.h"
+ #include "tocintrnl.h"
+
+ static int MheLookup();
+ static Scrn AnnoSearch();
+ static char *MakeEnv();
+
+ /*
+ * Given a message - create an annotation list and
+ * return it
+ */
+ char *
+ AnnoMsgCreate(msg)
+ Msg msg;
+ {
+ MsgListRec ml;
+ char *AnnoCreate();
+
+ ml.nummsgs = 1;
+ ml.msglist = &msg;
+ return (AnnoCreate(&ml));
+ }
+
+ /*
+ * given an mlist - create an annotation list
+ * and return it - the first element in the list is the
+ * name of the folder
+ *
+ */
+ char *
+ AnnoCreate(mlist)
+ MsgList mlist;
+ {
+ char *anno;
+ char *folder;
+ int bytes;
+ register int d;
+ register int i;
+ char *src;
+ char numbuf[16];
+
+ if (mlist->nummsgs == 0)
+ return (NULL);
+
+ folder = mlist->msglist[0]->toc->foldername;
+ anno = (char *)XtMalloc(512);
+ bytes = 512;
+ for (d = 0, src = app_resources.mail_path; anno[d++] = *src++;);
+ anno[d-1] = '/';
+ for (src = folder; anno[d++] = *src++;);
+ d--;
+
+
+ for (i = 0; i < mlist->nummsgs; i++)
+ {
+ (void) sprintf(numbuf, "%d", mlist->msglist[i]->msgid);
+
+ if (d+16 > bytes)
+ { bytes += 512;
+ anno = (char *)XtRealloc(anno, bytes);
+ }
+ /* add a space */
+ anno[d++] = ' ';
+ for (src = numbuf; anno[d++] = *src++;);
+ d--;
+ }
+ anno[d] = '\0';
+ return (anno);
+ }
+
+ /*
+ * We will need to add and delete four things from
+ * the environment. This could be done after the fork()
+ * but this means that we have to change the environment
+ * to be sure of not affecting any other programs
+ *
+ * So the idea here is to copy the environment into our vector
+ * deleting the four things that we are interested in
+ * we then put OUR things in the first four string positions
+ */
+ static char **our_env; /* this points at our environment */
+ extern char **environ; /* what the world sees */
+
+ typedef struct addenv
+ { char *add;
+ int len;
+ } Addenv;
+
+ static Addenv adde[] =
+ {
+ { "mhfolder=", 9 },
+ { "mhmessages=", 11 },
+ { "mhannotate=", 11 },
+ { "mhinplace=", 10 },
+ { NULL, 0 }
+ };
+
+ #define MHE_FOLDER 0
+ #define MHE_MESSAGES 1
+ #define MHE_ANNOTATE 2
+ #define MHE_INPLACE 3
+
+ AnnoInitEnv()
+ {
+ register int count; /* number of things in the environment */
+ register char **pt;
+ register char **dst;
+ char inp[16];
+
+
+ if (our_env)
+ return;
+
+ for (count = 0, pt = environ; *pt++; count++);
+
+ our_env = (char **)XtMalloc((count+5)*sizeof (char **));
+ our_env[0] = our_env[1] = our_env[2] = NULL;
+
+ /* copy the environment into `our' environment */
+ /* start at position 4 */
+ dst = &our_env[4];
+
+ for (pt = environ; *pt; pt++)
+ {
+ if (MheLookup(*pt))
+ continue;
+ *dst++ = *pt;
+ }
+ *dst = NULL;
+ /*
+ * set up the inplace value
+ */
+ (void) sprintf(inp, "%s%d", adde[MHE_INPLACE].add, app_resources.annotate_in_place);
+ our_env[MHE_INPLACE] = XtNewString(inp);
+ }
+
+ /*
+ * Look in the list of things we are dealing with
+ * to find a match in the environment
+ */
+ static int
+ MheLookup(env)
+ char *env;
+ {
+ register Addenv *ae;
+
+ for (ae = adde; ae->add; ae++)
+ if (strncmp(env, ae->add, ae->len) == 0)
+ return(1);
+ return 0;
+ }
+
+ /*
+ * Reset the environment to the standard
+ */
+ AnnoEnvReset()
+ {
+ environ = &our_env[4];
+ }
+
+ /*
+ * Set the environment to new values
+ */
+ AnnoEnvSet(msg)
+ Msg msg;
+ {
+ Scrn scrn;
+ char *folder;
+ char *annotate;
+ char *s;
+ char *d;
+ register i;
+ Scrn AnnoSearch();
+ char buf[512];
+
+ if ((scrn = AnnoSearch(msg)) == NULL)
+ return;
+
+ switch (scrn->anno_type)
+ {
+ case ANrepl:
+ annotate = "Replied";
+ break;
+ case ANforw:
+ annotate = "Forwarded";
+ break;
+ default: /* shouldn't happen */
+ return;
+ }
+
+ for (i = 0; i < MHE_INPLACE; i++)
+ if (our_env[i])
+ { XtFree(our_env[i]);
+ our_env[i] = NULL;
+ }
+ /*
+ * Munge the annotation list
+ * we see it as
+ * folder-name number number
+ */
+ for (s = scrn->anno_list, d = buf; *s != ' '; *d++ = *s++);
+ *d = '\0';
+ s++;
+
+ our_env[MHE_FOLDER] = MakeEnv(&adde[MHE_FOLDER], buf);
+ our_env[MHE_MESSAGES] = MakeEnv(&adde[MHE_MESSAGES], s);
+ our_env[MHE_ANNOTATE] = MakeEnv(&adde[MHE_ANNOTATE], annotate);
+ environ = our_env;
+ }
+
+ static Scrn
+ AnnoSearch(msg)
+ Msg msg;
+ {
+ register i;
+ AnnoKind ak;
+
+ if (msg->num_scrns == 0)
+ return (NULL);
+
+ for (i = 0; i < msg->num_scrns; i++)
+ {
+ if ((ak = msg->scrn[i]->anno_type) == ANrepl)
+ return(msg->scrn[i]);
+ else
+ if (ak == ANforw)
+ return(msg->scrn[i]);
+ }
+ return (NULL);
+ }
+
+
+
+ static char *
+ MakeEnv(ad, value)
+ register Addenv *ad;
+ char *value;
+ {
+ char buf[512];
+
+ (void) sprintf(buf, "%s%s", ad->add, value);
+ return (XtNewString(buf));
+ }
*** Imakefile~ Wed Jan 2 22:36:59 1991
--- Imakefile Sun Dec 23 21:15:33 1990
***************
*** 8,17 ****
SRCS = bbox.c command.c compfuncs.c folder.c icon.c init.c \
main.c menu.c mlist.c msg.c pick.c popup.c screen.c \
! toc.c tocfuncs.c tocutil.c tsource.c util.c viewfuncs.c
OBJS = bbox.o command.o compfuncs.o folder.o icon.o init.o \
main.o menu.o mlist.o msg.o pick.o popup.o screen.o \
! toc.o tocfuncs.o tocutil.o tsource.o util.o viewfuncs.o
ComplexProgramTarget(xmh)
--- 8,17 ----
SRCS = bbox.c command.c compfuncs.c folder.c icon.c init.c \
main.c menu.c mlist.c msg.c pick.c popup.c screen.c \
! toc.c tocfuncs.c tocutil.c tsource.c util.c viewfuncs.c anno.c
OBJS = bbox.o command.o compfuncs.o folder.o icon.o init.o \
main.o menu.o mlist.o msg.o pick.o popup.o screen.o \
! toc.o tocfuncs.o tocutil.o tsource.o util.o viewfuncs.o anno.o
ComplexProgramTarget(xmh)
*** compfuncs.c~ Wed Jan 2 22:39:07 1991
--- compfuncs.c Sun Dec 23 21:15:33 1990
***************
*** 117,122 ****
--- 117,124 ----
{
Scrn scrn;
Msg msg;
+ char *AnnoCreate();
+
scrn = NewCompScrn();
msg = TocMakeNewMsg(DraftsFolder);
MsgLoadForward(scrn, msg, mlist);
***************
*** 123,126 ****
--- 125,133 ----
MsgSetTemporary(msg);
MsgSetScrnForComp(msg, scrn);
MapScrn(scrn);
+ if (app_resources.annotate_forw) {
+ scrn->anno_type = ANforw;
+ scrn->anno_list = AnnoCreate(mlist);
+ }
+
}
*** globals.h~ Wed Jan 2 22:40:33 1991
--- globals.h Sun Dec 23 21:15:31 1990
***************
*** 76,81 ****
--- 76,84 ----
int command_button_count; /* number of buttons in command box */
int app_defaults_version; /* for sanity check */
char *banner; /* defaults to xmh version string */
+ Boolean annotate_repl; /* true if we are to annotate reply sources */
+ Boolean annotate_forw; /* true if we are to annotate forw sources */
+ int annotate_in_place; /* 0 if don't annotate inplace, 1 otherwise */
} app_resources;
ext char *draftFile; /* Filename of draft. */
*** init.c~ Wed Jan 2 22:40:54 1991
--- init.c Sun Dec 23 21:15:31 1990
***************
*** 124,129 ****
--- 124,135 ----
offset(app_defaults_version), XtRImmediate, (XtPointer)0},
{"banner", "Banner", XtRString, sizeof(char *),
offset(banner), XtRString, "xmh MIT X Consortium R4"},
+ {"annotateRepl", "AnnotateRepl", XtRBoolean, sizeof(Boolean),
+ offset(annotate_repl), XtRImmediate, (XtPointer)False},
+ {"annotateForw", "AnnotateForw", XtRBoolean, sizeof(Boolean),
+ offset(annotate_forw), XtRImmediate, (XtPointer)False},
+ {"annotateInPlace", "AnnotateInPlace", XtRInt, sizeof(int),
+ offset(annotate_in_place), XtRImmediate, (XtPointer)1},
};
#undef offset
***************
*** 396,401 ****
--- 402,413 ----
InitPick();
IconInit();
BBoxInit();
+
+ /*
+ * Initialise annotations if required
+ */
+ if (app_resources.annotate_repl || app_resources.annotate_forw)
+ AnnoInitEnv();
XtAppAddActions( XtWidgetToApplicationContext(toplevel),
actions, XtNumber(actions));
*** msg.c~ Wed Jan 2 22:41:05 1991
--- msg.c Sun Dec 23 21:15:32 1990
***************
*** 731,736 ****
--- 731,737 ----
}
(void) myfclose(from);
(void) myfclose(to);
+ AnnoEnvSet(msg);
argv = MakeArgv(3);
argv[0] = "send";
argv[1] = "-push";
***************
*** 737,742 ****
--- 738,744 ----
argv[2] = str;
DoCommand(argv, (char *) NULL, (char *) NULL);
XtFree((char *) argv);
+ AnnoEnvReset();
}
*** screen.c~ Wed Jan 2 22:41:14 1991
--- screen.c Sun Dec 23 21:15:31 1990
***************
*** 391,396 ****
--- 391,398 ----
Scrn scrn;
scrn = CreateNewScrn(STcomp);
scrn->assocmsg = (Msg)NULL;
+ scrn->anno_type = ANno;
+ scrn->anno_list = NULL;
return scrn;
}
***************
*** 412,417 ****
--- 414,423 ----
TocSetScrn((Toc) NULL, scrn);
MsgSetScrnForce((Msg) NULL, scrn);
lastInput.win = -1;
+ if (scrn->anno_list) {
+ XtFree(scrn->anno_list);
+ scrn->anno_list = NULL;
+ }
}
}
*** tocfuncs.c~ Wed Jan 2 22:41:25 1991
--- tocfuncs.c Sun Dec 23 21:15:32 1990
***************
*** 651,656 ****
--- 651,657 ----
Scrn nscrn;
MsgList mlist;
Msg msg;
+ char *AnnoMsgCreate();
if (toc == NULL) return;
mlist = CurMsgListOrCurMsg(toc);
***************
*** 657,662 ****
--- 658,667 ----
if (mlist->nummsgs) {
nscrn = NewCompScrn();
ScreenSetAssocMsg(nscrn, mlist->msglist[0]);
+ if (app_resources.annotate_repl)
+ { nscrn->anno_type = ANrepl;
+ nscrn->anno_list = AnnoMsgCreate(mlist->msglist[0]);
+ }
msg = TocMakeNewMsg(DraftsFolder);
MsgSetTemporary(msg);
MsgLoadReply(msg, mlist->msglist[0]);
*** viewfuncs.c~ Wed Jan 2 22:41:38 1991
--- viewfuncs.c Sun Dec 23 21:15:32 1990
***************
*** 76,85 ****
--- 76,90 ----
Scrn scrn = (Scrn) client_data;
Msg msg;
Scrn nscrn;
+ char *AnnoMsgCreate();
if (scrn->msg == NULL) return;
nscrn = NewCompScrn();
ScreenSetAssocMsg(nscrn, scrn->msg);
+ if (app_resources.annotate_repl)
+ { nscrn->anno_type = ANrepl;
+ nscrn->anno_list = AnnoMsgCreate(scrn->msg);
+ }
msg = TocMakeNewMsg(DraftsFolder);
MsgSetTemporary(msg);
MsgLoadReply(msg, scrn->msg);
*** xmh.h~ Wed Jan 2 22:41:57 1991
--- xmh.h Sun Dec 23 21:15:31 1990
***************
*** 90,95 ****
--- 90,101 ----
STpick
} ScrnKind;
+ typedef enum {
+ ANno,
+ ANrepl,
+ ANforw
+ } AnnoKind;
+
typedef struct _StackRec {
char *data;
struct _StackRec *next;
***************
*** 119,124 ****
--- 125,132 ----
Msg assocmsg; /* Associated message for reply, etc. */
Window wait_window; /* InputOnly window with busy cursor */
Stack folder_stack; /* Stack of folder names */
+ AnnoKind anno_type; /* type of annotation */
+ char * anno_list; /* list of messages to annotate */
} ScrnRec, *Scrn;
*** xmh.man~ Wed Jan 2 22:42:07 1991
--- xmh.man Mon Dec 24 12:02:12 1990
***************
*** 921,926 ****
--- 921,946 ----
The following resources are defined:
.TP 8
+ .B AnnotateRepl
+ Permits annotation of messages that are being replied to.
+ This uses the standard
+ .I mh
+ mechanism in
+ .IR send .
+ Default is false.
+ .TP 8
+ .B AnnotateForw
+ Permits annotation of messages that are being forwarded.
+ This uses the standard
+ .I mh
+ mechanism in
+ .IR send .
+ Default is false.
+ .TP
+ .B AnnotateInPlace
+ When set to non-zero causes annotation to be done in place to preserve
+ links to the annotated message.
+ .TP 8
.B Banner
A short string that is the default label of the folder, Table of Contents,
and view. The default is "xmh MIT X Consortium R4".
***************
*** 1241,1243 ****
--- 1261,1265 ----
Terry Weissman, Digital Western Research Laboratory
.br
modified by Donna Converse, MIT X Consortium
+ .br
+ Annotation code by Peter Collinson, Hillside Systems
More information about the Alt.sources
mailing list