home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / x / volume13 / xmail / part03 / handler.c next >
C/C++ Source or Header  |  1991-06-15  |  12KB  |  352 lines

  1. /*
  2.  * xmail - X window system interface to the mail program
  3.  *
  4.  * Copyright 1989 The University of Texas at Austin
  5.  *
  6.  * Author:    Po Cheung
  7.  * Date:    March 10, 1989
  8.  *
  9.  * Permission to use, copy, modify, and distribute this software and
  10.  * its documentation for any purpose and without fee is hereby granted,
  11.  * provided that the above copyright notice appear in all copies and that
  12.  * both that copyright notice and this permission notice appear in
  13.  * supporting documentation.  The University of Texas at Austin makes no 
  14.  * representations about the suitability of this software for any purpose.  
  15.  * It is provided "as is" without express or implied warranty.
  16.  *
  17.  * Copyright 1990 by National Semiconductor Corporation
  18.  *
  19.  * Permission to use, copy, modify, and distribute this software and its
  20.  * documentation for any purpose is hereby granted without fee, provided that
  21.  * the above copyright notice appear in all copies and that both that
  22.  * copyright notice and this permission notice appear in supporting
  23.  * documentation, and that the name of National Semiconductor Corporation not
  24.  * be used in advertising or publicity pertaining to distribution of the
  25.  * software without specific, written prior permission.
  26.  *
  27.  * NATIONAL SEMICONDUCTOR CORPORATION MAKES NO REPRESENTATIONS ABOUT THE
  28.  * SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE.  IT IS PROVIDED "AS IS"
  29.  * WITHOUT EXPRESS OR IMPLIED WARRANTY.  NATIONAL SEMICONDUCTOR CORPORATION
  30.  * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
  31.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO
  32.  * EVENT SHALL NATIONAL SEMICONDUCTOR CORPORATION BE LIABLE FOR ANY SPECIAL,
  33.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  34.  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  35.  * OR OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  36.  * PERFORMANCE OF THIS SOFTWARE.
  37.  *
  38.  * The following software modules were created and are Copyrighted by National
  39.  * Semiconductor Corporation:
  40.  *
  41.  * 1. In_System_Folder:
  42.  * 2. icon_handler:
  43.  * 3. index_handler:
  44.  * 4. info_handler: and
  45.  * 5. file_handler.
  46.  *
  47.  * Author:  Michael C. Wagnitz - National Semiconductor Corporation
  48.  *
  49.  */
  50.  
  51.  
  52. #include <ctype.h>
  53. #include "global.h"
  54. #include "xmailregex.h"
  55. #include "MailwatchP.h"
  56. #include <X11/Xaw/LabelP.h>
  57.  
  58. Boolean    In_Bogus_Mail_File = False;    /* TRUE when we go iconic */
  59.  
  60. /*
  61. ** Examine the current value of the titleBar title and return TRUE/FALSE
  62. ** to the question "Does it match the system mail folder name?"
  63. */
  64. int
  65. In_System_Folder()
  66. {
  67.  int         result;
  68.  char         *cp, buf[BUFSIZ];
  69.  Arg         args[1];
  70.  MailwatchWidget mb = (MailwatchWidget) XtNameToWidget(toplevel, "icon.mailbox");
  71.  LabelWidget     tb = (LabelWidget) XtNameToWidget(toplevel, "topBox.titleBar.title");
  72.  
  73.  XtSetArg(args[0], XtNlabel, (XtArgVal) NULL);
  74.  XtGetValues(tb, args, ONE);
  75.  strcpy(buf, (char *)args[0].value);
  76.  
  77.  if ((cp = strrchr(buf, '"')) == NULL) result = FALSE;
  78.  else {                    /* if a current folder name exists */
  79.     *cp = NULL;                /* chop off the rest of the label */
  80.     if ((cp = strchr(buf, '"')) == NULL) result = FALSE;
  81.     else result = (strcmp(mb->mailbox.filename, ++cp) == 0) ? TRUE : FALSE;
  82.    }
  83.  return(result);
  84. } /* In_System_Folder */
  85.  
  86.  
  87. /*
  88. ** Process map and unmap events for the icon widget to manage iconify and
  89. ** deiconify events and switch to/from a bogus mail folder.  This allows users
  90. ** to access mail from another process without colliding with an open folder.
  91. ** Once the bogus mail folder is accessed, we unlink it, to avoid having to
  92. ** explicitly remove it later.
  93. */
  94. XtEventHandler
  95. icon_handler(w, client_data, event)
  96. Widget    w;
  97. caddr_t    client_data;
  98. XEvent    *event;
  99. {
  100.  FILE    *fp;
  101.  char    *cp, cmd[BUFSIZ];
  102.  static Boolean    Was_System_Folder = False;    /* TRUE if we had been in */
  103.  
  104.  
  105.  if (mailpid) {
  106.     switch (event->type) {
  107.            case MapNotify :
  108.                 if (! In_Bogus_Mail_File) {
  109.                    Was_System_Folder = In_System_Folder();
  110.                    (void) sprintf(cmd, "%s+", tmpName);
  111.                    if (fp = fopen(cmd, "w")) {    /* create a bogus mail file */
  112.                       (void) fprintf(fp, "\n");
  113.                       fclose(fp);
  114.                       (void) sprintf(cmd, "file %s+", tmpName);
  115.                       cp = QueryMail(cmd);    /* focus our attention there */
  116.                       XtFree(cp);
  117.                       (void) sprintf(cmd, "%s+", tmpName);
  118.                       (void) unlink(cmd);    /* toss it now that we're in */
  119.                       In_Bogus_Mail_File = True;
  120.                      }
  121.                   }
  122.                 break;
  123.            case UnmapNotify :
  124.                 if (In_Bogus_Mail_File) {
  125.                    if (strcmp(Command, "Start") != 0) {    /* if not starting up */
  126.                       if (Was_System_Folder) {        /* go to system file */
  127.                          (void) strcpy(Command, "file %\n");
  128.                         } else {            /* go to prev. file */
  129.                          (void) strcpy(Command, "file #\n");
  130.                         }
  131.                      } else {
  132.                       if (XMail.MFileName) {    /* start in specified folder */
  133.                          (void) sprintf(Command, "file %s\n", XMail.MFileName);
  134.                         } else {        /* or else use system folder */
  135.                          (void) strcpy(Command, "file %\n");
  136.                         }
  137.                      }
  138.                    writeMail(Command);        /* let parser do the updating */
  139.                    In_Bogus_Mail_File = False;
  140.                    Was_System_Folder = False;
  141.                   } else if (In_System_Folder())
  142.                             UnsetNewmail(NULL, NULL, NULL);
  143.                 break;
  144.            default:
  145.                 break;
  146.           } /* end - switch on event type */
  147.    } /* end - if mail is active */
  148. } /* icon_handler */
  149.  
  150.  
  151. /*
  152. ** @(#)index_handler() - find value of specified or next appropriate message
  153. */
  154. int
  155. index_handler(msg_num, undeleting)
  156. int    msg_num;
  157. int    undeleting;
  158. {
  159.  Arg            args[1];
  160.  Cardinal        j, k;
  161.  String            c, s, IBuf;
  162.  Widget            iw;
  163.  XawTextPosition    pos;
  164.  
  165.  
  166.  Bell("");                    /* reset bell worthyness flag */
  167.  Bell(Default_Status_Info);
  168.  
  169.  k = msg_num;                    /* Try to use specified msg. */
  170.  if (k == 0) {                    /* But, if not specified... */
  171.     c = QueryMail("=");
  172.     if (*c)
  173.        sscanf(c, "%d", &k);            /* get msg num from mail. */
  174.     XtFree(c);
  175.    }
  176.  
  177.  IBuf = NULL;
  178.  XtSetArg(args[0], XtNstring, &IBuf);
  179.  iw = XtNameToWidget(toplevel, "topBox.indexWindow");
  180.  XtGetValues(iw, args, ONE);
  181.  
  182.  if (k <= 50) {                    /* do short index from front */
  183.     s = IBuf;
  184.     for (j = k - 1; j > 0 && (c = strchr(s, '\n')) != NULL; j--) s = c + 1;
  185.    } else {                    /* if index is fairly large */
  186.     for (s = &IBuf[strlen(IBuf) - 2]; s > IBuf && *s != '\n'; s--);
  187.     for (c = s + 1; *c && !isdigit(*c); c++);    /* get number of last entry */
  188.     j = 0;
  189.     if (*c)
  190.        sscanf(c, "%d", &j);            /* look backwards from there */
  191.     for (; j > k; j--) {
  192.         if (s > IBuf) s--;
  193.         for (; s > IBuf && *s != '\n'; s--);
  194.        }
  195.     if (*s == '\n') s++;
  196.    } 
  197.  
  198.  j = k;
  199.  for (;;) {                    /* allow for deleted msgs */
  200.      for (c = s; *c && !isdigit(*c); c++);
  201.      if (! *c || k == 0 ||
  202.     (sscanf(c, "%d", &j) && j <= k))    /* total may be less than us */
  203.         break;
  204.  
  205.      if (s - 2 >= IBuf)
  206.         for (s -= 2; s > IBuf && *s != '\n'; s--);
  207.      if (*s == '\n') s++;
  208.     }
  209.  
  210.  if (! undeleting && *(s + 1) == 'D') {        /* If this is a deleted msg */
  211.     j = 0;                    /* then num is inappropriate */
  212.     for (;*s && *(s + 1) == 'D';) {        /* try looking above deletes */
  213.         if (! (c = strchr(s,'\n'))) break;    /* don't go past end of buf */
  214.         s = c + 1;
  215.        }
  216.     for (;s > IBuf && *(s + 1) == 'D';) {
  217.         for (s -= 2; s > IBuf && *s != '\n'; s--);
  218.         if (*s == '\n') s++;
  219.        }
  220.     if (*(s + 1) != 'D') {            /* If we found a readable msg */
  221.        for (c = s; *c && !isdigit(*c); c++);
  222.        if (*c)
  223.           sscanf(c, "%d", &j);
  224.       }
  225.    }
  226.  
  227.  if (j) {                    /* if we have a valid msg num */
  228.     pos = s - IBuf;                /* resolve our position */
  229.     XawTextSetInsertionPoint(iw, pos);        /* point at selected line */
  230.     markIndex("> ");                /* flag it as current */
  231.    } else XawAsciiSourceFreeString(iw);        /* release GetValues memory */
  232.  
  233.  return(j);                    /* return msg actually found */
  234. } /* index_handler */
  235.  
  236.  
  237. /*
  238. ** @(#)info_handler - use enter/leave_notify events to alter status window info
  239. */
  240. /*ARGSUSED*/
  241. void
  242. info_handler(w, client_data, event)
  243. Widget    w;                /* unused */
  244. caddr_t    client_data;
  245. XEvent    *event;
  246. {
  247.  if      (event->type == LeaveNotify)    Bell(Default_Status_Info);
  248.  else if (event->type == EnterNotify)    Bell(client_data);
  249. } /* end - info_handler */
  250.  
  251.  
  252. /*
  253. ** @(#)file_handler() - Handle output of Start and file commands.
  254. **                      If *Show_Last: resource is TRUE show last
  255. **                      message in list, if none are marked as new.
  256. */
  257. file_handler()
  258. {
  259.  Widget            iw = XtNameToWidget(toplevel, "topBox.indexWindow");
  260.  XawTextPosition    pos;
  261.  char            *c, *s, *p, msgnum_str[10];
  262.  int            more_than_one, msg_num = 0;
  263.  
  264.  
  265.  c = QueryMail("=");                /* Get current mail msg num. */
  266.  while (! isdigit(*c)) {
  267.     XtFree(c);
  268.     if (! mailpid) return;
  269.     c = QueryMail("=");
  270.    }
  271.  sprintf(msgnum_str, c);
  272.  XtFree(c);
  273.  
  274.  c = QueryMail("file");                /* Forces current msg to one */
  275.  if (! mailpid) return (0);
  276.  
  277.  if (! In_Bogus_Mail_File)
  278.     (void) UpdateTitleBar(c);
  279.  XtFree(c);
  280.  
  281.  if (strcmp(Command, "Start") == 0) {        /* unless we're at Start, in */
  282.     c = QueryMail("=");                /* which case we get it now  */
  283.     sprintf(msgnum_str, c);            /* (due to -N mailargv use). */
  284.     XtFree(c);
  285.    }
  286.  if (! mailpid) return (0);
  287.  
  288.  s = QueryMail("h");
  289.  if (strncmp(s, "No applicable messages", 22) == 0) {
  290.     Bell(s);
  291.     writeTo(iw, " ");
  292.     writeTo(XtNameToWidget(toplevel, "topBox.textWindow.text"), " ");
  293.    } else {
  294. /*
  295. ** find mail's idea of this folder's current message number
  296. */
  297.     for (c = s; *c; c++)
  298.         if (*c == '>' && (c == s || *(c - 1) == '\n'))
  299.            break;
  300. /*
  301. ** If the current message is marked new or unread, ensure as many of the new
  302. ** message headers as possible are displayed in the index window (especially
  303. ** the current one), else if the Show_Last resource is not false, select the
  304. ** last message in the header.
  305. */
  306.    p = c;                    /* save position of current */
  307.    more_than_one = FALSE;            /* set a flag for new/unread */
  308.    if (*(c+1) == 'N' || *(c+1) == 'U') more_than_one = TRUE;
  309.    else if (XMail.Show_Last) {            /* find the last message */
  310.            if (*p == '>') *p = ' ';        /* erase the original marker */
  311.            if (c == s) {            /* if would've started @ One */
  312.               for (p = &s[strlen(s)-2];
  313.                    p > s && *p != '\n'; p--);
  314.               if (*p == '\n') p++;        /* go to last line of buffer */
  315.              } else {
  316.               for (;*++c && *(c+1) != 'N' && *(c+1) != 'U';) {
  317.                   if (! (c = strchr(p,'\n')))
  318.                      break;            /* don't go past end of buf */
  319.                   p = c + 1;
  320.                  }
  321.              }
  322.            for (c = p; *c && !isdigit(*c); c++);
  323.            if (*c)
  324.               sscanf(c, "%d", &msg_num);
  325.            sprintf(msgnum_str, "%d", msg_num);
  326.           }
  327. /*
  328. ** mark the current message's index line
  329. */
  330.    *p = '>'; *(p+1) = ' ';
  331. /*
  332. ** Return the current message number.
  333. */
  334.     msg_num = atoi(msgnum_str);
  335. /*
  336. ** Write the header info to the index window buffer, replacing existing info.
  337. */
  338.     writeTo(iw, s);
  339. /*
  340. ** Ensure if we are seeing new or unread messages that as many as possible are
  341. ** displayed in the index window, to reduce the amount of scrolling required
  342. ** when reading(/deleting) them.
  343. */
  344.     pos = p - s;
  345.     if (more_than_one)
  346.        XawTextSetInsertionPoint(iw, TextGetLastPos(iw));
  347.     XawTextSetInsertionPoint(iw, pos);
  348.    }
  349.  XtFree(s);
  350.  return(msg_num);
  351. } /* file_handler */
  352.