home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume19 / xmail / part05 < prev    next >
Encoding:
Text File  |  1993-04-27  |  57.5 KB  |  1,831 lines

  1. Newsgroups: comp.sources.x
  2. From: markham@cadence.com (Jeff Markham)
  3. Subject: v19i030:  xmail - X Window System interface to the mail program, Part05/10
  4. Message-ID: <1993Mar10.202902.10962@sparky.imd.sterling.com>
  5. X-Md4-Signature: 70ce6ebf5390ef82d9ad57359e837b6a
  6. Date: Wed, 10 Mar 1993 20:29:02 GMT
  7. Approved: chris@sparky.imd.sterling.com
  8.  
  9. Submitted-by: markham@cadence.com (Jeff Markham)
  10. Posting-number: Volume 19, Issue 30
  11. Archive-name: xmail/part05
  12. Environment: X11
  13. Supersedes: xmail: Volume 15, Issue 18-26
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then feed it
  17. # into a shell via "sh file" or similar.  To overwrite existing files,
  18. # type "sh file -c".
  19. # Contents:  COPYRIGHT Mailwatch.c windows.c
  20. # Wrapped by chris@sparky on Wed Mar 10 14:17:47 1993
  21. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  22. echo If this archive is complete, you will see the following message:
  23. echo '          "shar: End of archive 5 (of 10)."'
  24. if test -f 'COPYRIGHT' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'COPYRIGHT'\"
  26. else
  27.   echo shar: Extracting \"'COPYRIGHT'\" \(2029 characters\)
  28.   sed "s/^X//" >'COPYRIGHT' <<'END_OF_FILE'
  29. X/*
  30. X * xmail - X window system interface to the mail program
  31. X *
  32. X * Copyright 1989 The University of Texas at Austin
  33. X *
  34. X * Author:    Po Cheung
  35. X * Date:    March 10, 1989
  36. X *
  37. X * Permission to use, copy, modify, and distribute this software and
  38. X * its documentation for any purpose and without fee is hereby granted,
  39. X * provided that the above copyright notice appear in all copies and that
  40. X * both that copyright notice and this permission notice appear in
  41. X * supporting documentation.  The University of Texas at Austin makes no 
  42. X * representations about the suitability of this software for any purpose.  
  43. X * It is provided "as is" without express or implied warranty.
  44. X *
  45. X * Copyright 1990,1991 by National Semiconductor Corporation
  46. X *
  47. X * Permission to use, copy, modify, and distribute this software and its
  48. X * documentation for any purpose is hereby granted without fee, provided that
  49. X * the above copyright notice appear in all copies and that both that
  50. X * copyright notice and this permission notice appear in supporting
  51. X * documentation, and that the name of National Semiconductor Corporation not
  52. X * be used in advertising or publicity pertaining to distribution of the
  53. X * software without specific, written prior permission.
  54. X *
  55. X * NATIONAL SEMICONDUCTOR CORPORATION MAKES NO REPRESENTATIONS ABOUT THE
  56. X * SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE.  IT IS PROVIDED "AS IS"
  57. X * WITHOUT EXPRESS OR IMPLIED WARRANTY.  NATIONAL SEMICONDUCTOR CORPORATION
  58. X * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
  59. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO
  60. X * EVENT SHALL NATIONAL SEMICONDUCTOR CORPORATION BE LIABLE FOR ANY SPECIAL,
  61. X * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  62. X * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  63. X * OR OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  64. X * PERFORMANCE OF THIS SOFTWARE.
  65. X *
  66. X * Author:  Michael C. Wagnitz - National Semiconductor Corporation
  67. X *
  68. X */
  69. END_OF_FILE
  70.   if test 2029 -ne `wc -c <'COPYRIGHT'`; then
  71.     echo shar: \"'COPYRIGHT'\" unpacked with wrong size!
  72.   fi
  73.   # end of 'COPYRIGHT'
  74. fi
  75. if test -f 'Mailwatch.c' -a "${1}" != "-c" ; then 
  76.   echo shar: Will not clobber existing file \"'Mailwatch.c'\"
  77. else
  78.   echo shar: Extracting \"'Mailwatch.c'\" \(28664 characters\)
  79.   sed "s/^X//" >'Mailwatch.c' <<'END_OF_FILE'
  80. X/*
  81. X * @(#)Mailwatch.c - MODIFIED for use as an active icon in the xmail program.
  82. X *
  83. X * Author:  Dan Heller <island!argv@sun.com>
  84. X * This code was stolen from Mailbox.c --the widget which supports "xbiff"
  85. X * written by Jim Fulton which was apparently stolen from Clock.c, the widget
  86. X * which supports "xclock."  Note, you are witnessing the big bang theory of
  87. X * software development (everything is a subclass of universeWidgetClass).
  88. X *
  89. X * Major changes:
  90. X * XtRemoveTimeOut() is called before calling XtAddTimeOut().  The original
  91. X * xbiff would eventually timeout all the time rather than every 30 seconds
  92. X * because the old timer was never removed.
  93. X *
  94. X * User can specify any icon he chooses for either the up flag or the down
  95. X * flag.  Icons don't need to be the same size (defaults to flagup/flagdown).
  96. X *
  97. X * When new mail comes in, a user supplied callback function is invoked.
  98. X *
  99. X * The mailbox flag goes up when there is new mail _and_ the user hasn't
  100. X * read it yet.  As soon as the user updates the access time on the mailbox,
  101. X * the flag goes down.  This removes the incredibly annoying habit xbiff
  102. X * had where you read some mail but not delete it from the mailbox and the
  103. X * flag would remain up.
  104. X *
  105. X * Destroy() will now destroy the flagup and flagdown pixmaps.
  106. X *
  107. X** July 1991 - Michael C. Wagnitz - National Semiconductor Corporation
  108. X** The following modifications were made for use in xmail.
  109. X**
  110. X** Added support for colored icons via the XPixMap format library libXpm.a
  111. X**
  112. X** November 1990 - Michael C. Wagnitz - National Semiconductor Corporation
  113. X** The following modifications were made for use in xmail.
  114. X**
  115. X** Added options to display username or host name in icon window.
  116. X**
  117. X** November 1989 - Michael C. Wagnitz - National Semiconductor Corporation
  118. X**
  119. X** Removed button handler, custom cursor, and 'from()' reader functions.
  120. X** Added reset_mailbox() function, my own icons (56x56 bits), and also
  121. X** added timer initialization to Initialize() routine (we might not ever be
  122. X** Realized, if the user never iconifies my parent).  This also fixes a Sun4
  123. X** bug for trying to remove an initial interval_id with a garbage address.
  124. X** Also changed check_mailbox() to test access time vs. modified and zero size
  125. X** of file, rather than trying to track our last access or increase in size.
  126. X**
  127. X** Copyright 1990,1991 by National Semiconductor Corporation
  128. X**
  129. X** Permission to use, copy, modify, and distribute this software and its
  130. X** documentation for any purpose is hereby granted without fee, provided that
  131. X** the above copyright notice appear in all copies and that both that
  132. X** copyright notice and this permission notice appear in supporting
  133. X** documentation, and that the name of National Semiconductor Corporation not
  134. X** be used in advertising or publicity pertaining to distribution of the
  135. X** software without specific, written prior permission.
  136. X**
  137. X** NATIONAL SEMICONDUCTOR CORPORATION MAKES NO REPRESENTATIONS ABOUT THE
  138. X** SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE.  IT IS PROVIDED "AS IS"
  139. X** WITHOUT EXPRESS OR IMPLIED WARRANTY.  NATIONAL SEMICONDUCTOR CORPORATION
  140. X** DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
  141. X** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO
  142. X** EVENT SHALL NATIONAL SEMICONDUCTOR CORPORATION BE LIABLE FOR ANY SPECIAL,
  143. X** INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  144. X** LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  145. X** OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  146. X** PERFORMANCE OF THIS SOFTWARE.
  147. X**
  148. X** The following software modules were created and are Copyrighted by National
  149. X** Semiconductor Corporation:
  150. X**
  151. X** 1. reset_mailbox,
  152. X** 2. set_host,
  153. X** 3. set_user,
  154. X** 4. set_none,
  155. X** 5. GetHostName, and
  156. X** 6. XMyLocateXPixmapFile.
  157. X**
  158. X** Author:  Michael C. Wagnitz - National Semiconductor Corporation
  159. X*/
  160. X
  161. X
  162. X#include <X11/Xos.h>
  163. X#include <X11/IntrinsicP.h>        /* for toolkit stuff */
  164. X#include <X11/cursorfont.h>        /* for cursor constants */
  165. X#include <X11/StringDefs.h>        /* for useful atom names */
  166. X#include <X11/Xaw/XawInit.h>
  167. X#include "MailwatchP.h"            /* for implementation mailbox stuff */
  168. X#include <stdio.h>            /* for printing error messages */
  169. X#include <sys/stat.h>            /* for stat() */
  170. X#include <sys/param.h>            /* for MAXHOSTNAMELEN */
  171. X#include <pwd.h>            /* for getting username */
  172. X
  173. X#ifndef    XPM
  174. X#include <X11/Xmu/Converters.h>        /* for XmuCvtStringToBitmap */
  175. X#include "icon.mail"            /* for flag up (mail present) bits */
  176. X#include "icon.nomail"            /* for flag down (mail not here) */
  177. X#else
  178. X#include <X11/xpm.h>            /* for XPixMap colored icons */
  179. X#include <X11/Xmu/CvtCache.h>
  180. X#include "mail.xpm"            /* for flag up (mail present) bits */
  181. X#include "nomail.xpm"            /* for flag down (mail not here) */
  182. X
  183. X#define    mail_width    64
  184. X#define    mail_height    64
  185. X#define    nomail_width    64
  186. X#define    nomail_height    64
  187. X#endif
  188. X
  189. X#ifndef    MAXHOSTNAMELEN
  190. X#define    MAXHOSTNAMELEN    64
  191. X#endif
  192. X
  193. X#define between(x, i, y)   ((i) < (x) ? (x) : (i) > (y) ? (y) : (i))
  194. X
  195. X#define REMOVE_TIMEOUT(id) if (!id) ; else XtRemoveTimeOut(id)
  196. X
  197. Xextern XtActionProc    Quit();            /* termination procedure */
  198. X
  199. Xstatic struct stat    stbuf;
  200. Xstatic Boolean        SetValues();
  201. Xstatic Pixmap        make_pixmap();
  202. Xstatic GC        GetNormalGC(), GetInvertGC();
  203. Xstatic void        GetMailFile(), GetUserName(), GetHostName(),
  204. X            CloseDown(), check_mailbox(), redraw_mailbox(),
  205. X            ClassInitialize(), Initialize(), Destroy(),
  206. X            Realize(), Redisplay(), clock_tic(), set_title();
  207. Xextern void        reset_mailbox(), set_host(), set_user(), set_none();
  208. Xextern Widget        toplevel;
  209. X
  210. Xextern    int        RootWidth;
  211. Xextern    int        RootHeight;
  212. X
  213. X#define min(a,b) ((a) < (b) ? (a) : (b))
  214. X#define max(a,b) ((a) > (b) ? (a) : (b))
  215. X
  216. Xstatic char defaultTranslations[] =
  217. X    "<Key>h:        set-host()    \n\
  218. X     <Key>q:        Quit(q)        \n\
  219. X     <Key>u:        set-user()    \n\
  220. X     <Key>space:    set-none()";
  221. X
  222. Xstatic XtActionsRec actionsList[] = {
  223. X    { "set-host",    set_host    },
  224. X    { "set-user",    set_user    },
  225. X    { "set-none",    set_none    },
  226. X};
  227. X
  228. X/* Initialization of defaults */
  229. X#define offset(field) XtOffset(MailwatchWidget,mailbox.field)
  230. X#define goffset(field) XtOffset(Widget,core.field)
  231. X
  232. Xstatic XtResource resources[] = {
  233. X    {XtNupdate, XtCInterval, XtRInt, sizeof(int),
  234. X    offset(update), XtRImmediate, (caddr_t) 30 },
  235. X    {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
  236. X    offset(foreground_pixel), XtRString, XtDefaultForeground },
  237. X    {XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel),
  238. X    goffset(background_pixel), XtRString, XtDefaultBackground },
  239. X    {XtNreverseVideo, XtCBoolean, XtRBoolean, sizeof(Boolean),
  240. X    offset(reverseVideo), XtRImmediate, (caddr_t) False },
  241. X    {XtNbell, XtCBoolean, XtRBoolean, sizeof(Boolean),
  242. X    offset(bell), XtRImmediate, (caddr_t) True },
  243. X    {XtNfile, XtCFile, XtRString, sizeof(String),
  244. X    offset(filename), XtRString, NULL},
  245. X#ifndef    XPM
  246. X    {XtNmailFlag, XtCMailFlag, XtRBitmap, sizeof(Pixmap),
  247. X    offset(mail.bitmap), XtRString, NULL},
  248. X    {XtNnoMailFlag, XtCNoMailFlag, XtRBitmap, sizeof(Pixmap),
  249. X    offset(nomail.bitmap), XtRString, NULL},
  250. X#else
  251. X    {XtNmailFlag, XtCMailFlag, XtRString, sizeof(String),
  252. X    offset(mail.bitmap), XtRString, NULL},
  253. X    {XtNnoMailFlag, XtCNoMailFlag, XtRString, sizeof(String),
  254. X      offset(nomail.bitmap), XtRString, NULL},
  255. X#endif
  256. X    {XtNcallback, XtCCallback, XtRCallback, sizeof(caddr_t),
  257. X    offset(callback), XtRCallback, NULL},
  258. X    {"useName", XtCBoolean, XtRBoolean, sizeof(Boolean),
  259. X    offset(useName), XtRString, "FALSE" },
  260. X    {"useHost", XtCBoolean, XtRBoolean, sizeof(Boolean),
  261. X    offset(useHost), XtRString, "FALSE" },
  262. X    { XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
  263. X    offset(font), XtRString, XtDefaultFont},
  264. X};
  265. X
  266. X#undef offset
  267. X#undef goffset
  268. X
  269. XMailwatchClassRec mailwatchClassRec = {
  270. X    {    /* core fields */
  271. X    /* superclass        */ &widgetClassRec,
  272. X    /* class_name        */ "Mailwatch",
  273. X    /* widget_size        */ sizeof(MailwatchRec),
  274. X    /* class_initialize    */ ClassInitialize,
  275. X    /* class_part_initialize*/ NULL,
  276. X    /* class_inited     */ FALSE,
  277. X    /* initialize        */ Initialize,
  278. X    /* initialize_hook    */ NULL,
  279. X    /* realize        */ Realize,
  280. X    /* actions        */ actionsList,
  281. X    /* num_actions        */ XtNumber(actionsList),
  282. X    /* resources        */ resources,
  283. X    /* resource_count    */ XtNumber(resources),
  284. X    /* xrm_class        */ 0,
  285. X    /* compress_motion    */ TRUE,
  286. X    /* compress_exposure    */ TRUE,
  287. X    /* compress_enterleave    */ TRUE,
  288. X    /* visible_interest    */ FALSE,
  289. X    /* destroy        */ Destroy,
  290. X    /* resize        */ NULL,
  291. X    /* expose        */ Redisplay,
  292. X    /* set_values        */ SetValues,
  293. X    /* set_values_hook    */ NULL,
  294. X    /* set_values_almost    */ XtInheritSetValuesAlmost,
  295. X    /* get_values_hook    */ NULL,
  296. X    /* accept_focus        */ NULL,
  297. X    /* version        */ XtVersion,
  298. X    /* callback_private    */ NULL,
  299. X    /* tm_table        */ defaultTranslations,
  300. X    /* query_geometry    */ NULL,
  301. X    }
  302. X};
  303. X
  304. XWidgetClass mailwatchWidgetClass = (WidgetClass) & mailwatchClassRec;
  305. X
  306. X/*
  307. X * private procedures
  308. X */
  309. Xstatic Pixmap
  310. Xmake_pixmap (dpy, w, bitmap, depth, widthp, heightp)
  311. XDisplay        *dpy;
  312. XMailwatchWidget    w;
  313. XPixmap        bitmap;
  314. Xint        depth;
  315. Xint        *widthp, *heightp;
  316. X{
  317. X Window root;
  318. X int x, y;
  319. X unsigned int width, height, bw, dep;
  320. X unsigned long fore, back;
  321. X
  322. X if (bitmap == 0 ||
  323. X     ! XGetGeometry(dpy, bitmap, &root, &x, &y, &width, &height, &bw, &dep))
  324. X    return None;
  325. X
  326. X *widthp = (int) width;
  327. X *heightp = (int) height;
  328. X fore = w->mailbox.foreground_pixel;
  329. X back = w->core.background_pixel;
  330. X return XmuCreatePixmapFromBitmap(dpy, w->core.window, bitmap, 
  331. X                      width, height, depth, fore, back);
  332. X}
  333. X
  334. X
  335. Xstatic void
  336. XClassInitialize()
  337. X{
  338. X#ifndef XPM
  339. X static XtConvertArgRec screenConvertArg[] = {
  340. X    { XtWidgetBaseOffset, (caddr_t) XtOffset(Widget, core.screen), sizeof(Screen *) }
  341. X    };
  342. X#endif
  343. X
  344. X XawInitializeWidgetSet();
  345. X
  346. X#ifndef XPM
  347. X XtAddConverter (XtRString, XtRBitmap, XmuCvtStringToBitmap,
  348. X            screenConvertArg, XtNumber(screenConvertArg));
  349. X#endif
  350. X
  351. X return;
  352. X} /* ClassInitialize */
  353. X
  354. X
  355. X/* ARGSUSED */
  356. Xstatic void
  357. XInitialize(request, new)
  358. XWidget request, new;
  359. X{
  360. X    MailwatchWidget w = (MailwatchWidget) new;
  361. X
  362. X    GetUserName(w);
  363. X
  364. X    GetHostName(w);
  365. X
  366. X    if (!w->mailbox.filename)
  367. X    GetMailFile(w);
  368. X
  369. X    if (w->mailbox.reverseVideo) {
  370. X    Pixel tmp;
  371. X
  372. X    tmp = w->mailbox.foreground_pixel;
  373. X    w->mailbox.foreground_pixel = w->core.background_pixel;
  374. X    w->core.background_pixel = tmp;
  375. X    }
  376. X
  377. X    GetNormalGC(w);
  378. X
  379. X    GetInvertGC(w);
  380. X
  381. X    w->mailbox.flag_up = FALSE;        /* because it hasn't been shown yet */
  382. X    w->mailbox.mail.pixmap = None;
  383. X    w->mailbox.nomail.pixmap = None;
  384. X
  385. X    w->mailbox.last_access = (stat(w->mailbox.filename, &stbuf) == 0) ?
  386. X                             stbuf.st_atime : 0 ;    /* last accessed */
  387. X    return;
  388. X}
  389. X
  390. X
  391. X/* ARGSUSED */
  392. Xstatic void
  393. Xclock_tic(client_data, id)
  394. Xcaddr_t client_data;
  395. XXtIntervalId *id;
  396. X{
  397. X    MailwatchWidget w = (MailwatchWidget) client_data;
  398. X
  399. X    check_mailbox(w, FALSE);
  400. X}
  401. X
  402. X
  403. Xstatic void
  404. Xset_title(str)
  405. XString    str;
  406. X{
  407. X String        c, name, title;
  408. X Window        win  = XtWindow(toplevel);
  409. X Display    *dpy = XtDisplay(toplevel);
  410. X
  411. X
  412. X (void) XFetchName(dpy, win, &name);
  413. X if (! name)
  414. X    name = XtNewString("xmail");
  415. X else
  416. X    if ((c = (char *)strrchr(name, '_')) != NULL)
  417. X        *c = '\0';
  418. X
  419. X if (! *str)
  420. X    title = (String) XtMalloc((unsigned) strlen(name) + 1);
  421. X else
  422. X    title = (String) XtMalloc((unsigned) strlen(name) + strlen(str) + 2);
  423. X
  424. X if (! title)
  425. X    XtError("xmail: Insufficient memory to allocate title space");
  426. X
  427. X if (! *str)
  428. X    (void) sprintf(title, "%s", name);
  429. X else
  430. X    (void) sprintf(title, "%s_%s", name, str);
  431. X
  432. X XStoreName(dpy, win, title);
  433. X
  434. X XtFree((String) title);
  435. X XtFree((String) name);
  436. X} /* end - set_title */
  437. X
  438. X
  439. Xvoid
  440. Xset_host(m)
  441. XMailwatchWidget        m;
  442. X{
  443. X register Display    *dpy = XtDisplay(m);
  444. X register Window    win = XtWindow(m);
  445. X register int        x, y, h, w;
  446. X
  447. X
  448. X set_title(m->mailbox.mailhost);
  449. X
  450. X m->mailbox.useHost = True;
  451. X m->mailbox.useName = False;
  452. X h = m->mailbox.font->max_bounds.width - m->mailbox.font->max_bounds.lbearing;
  453. X w = strlen(m->mailbox.mailhost);
  454. X h = (h * w) - 2;
  455. X x = max(m->core.width - h, 2);            /* if (x < 2) x = 2; */
  456. X x /= 2;
  457. X y = m->core.height - m->mailbox.font->descent;
  458. X
  459. X XFillRectangle(dpy, win, m->mailbox.invert_GC,
  460. X                      0, y - m->mailbox.font->ascent, m->core.width,
  461. X                      m->mailbox.font->ascent + m->mailbox.font->descent);
  462. X
  463. X XDrawString(dpy, win, m->mailbox.normal_GC, x, y, m->mailbox.mailhost, w);
  464. X} /* end - set_host */
  465. X
  466. X
  467. Xvoid
  468. Xset_user(m)
  469. XMailwatchWidget        m;
  470. X{
  471. X register Display    *dpy = XtDisplay(m);
  472. X register Window    win = XtWindow(m);
  473. X register int        x, y, h, w;
  474. X
  475. X
  476. X set_title(m->mailbox.username);
  477. X
  478. X m->mailbox.useHost = False;
  479. X m->mailbox.useName = True;
  480. X h = m->mailbox.font->max_bounds.width - m->mailbox.font->max_bounds.lbearing;
  481. X w = strlen(m->mailbox.username);
  482. X h = (h * w) - 2;
  483. X x = max(m->core.width - h, 2);            /* if (x < 2) x = 2; */
  484. X x /= 2;
  485. X y = m->core.height - m->mailbox.font->descent;
  486. X
  487. X XFillRectangle(dpy, win, m->mailbox.invert_GC,
  488. X                      0, y - m->mailbox.font->ascent, m->core.width,
  489. X                      m->mailbox.font->ascent + m->mailbox.font->descent);
  490. X
  491. X XDrawString(dpy, win, m->mailbox.normal_GC, x, y, m->mailbox.username, w);
  492. X} /* end - set_user */
  493. X
  494. X
  495. Xvoid
  496. Xset_none(m)
  497. XMailwatchWidget        m;
  498. X{
  499. X set_title("");
  500. X m->mailbox.useHost = m->mailbox.useName = False;
  501. X redraw_mailbox(m);
  502. X} /* end - set_none */
  503. X
  504. X
  505. Xstatic GC
  506. XGetNormalGC(w)
  507. XMailwatchWidget w;
  508. X{
  509. X    XtGCMask valuemask;
  510. X    XGCValues xgcv;
  511. X
  512. X    valuemask = GCForeground | GCBackground | GCFunction | GCGraphicsExposures;
  513. X    xgcv.foreground = w->mailbox.foreground_pixel;
  514. X    xgcv.background = w->core.background_pixel;
  515. X    xgcv.function = GXcopy;
  516. X    xgcv.graphics_exposures = False;
  517. X    w->mailbox.normal_GC = XtGetGC((Widget) w, valuemask, &xgcv);
  518. X}
  519. X
  520. Xstatic GC
  521. XGetInvertGC(w)
  522. XMailwatchWidget w;
  523. X{
  524. X    XtGCMask valuemask;
  525. X    XGCValues xgcv;
  526. X
  527. X    valuemask = GCForeground | GCBackground | GCFunction | GCGraphicsExposures;
  528. X    xgcv.foreground = w->core.background_pixel;
  529. X    xgcv.background = w->mailbox.foreground_pixel;
  530. X    xgcv.function = GXcopy;
  531. X    xgcv.graphics_exposures = False;    /* this is Bool, not Boolean */
  532. X    w->mailbox.invert_GC = XtGetGC((Widget) w, valuemask, &xgcv);
  533. X}
  534. X
  535. X
  536. X#ifdef XPM
  537. X/*
  538. X * split_path_string - split a colon-separated list into its constituent
  539. X * parts; to release, free list[0] and list.  From libXmu LocBitmap.c
  540. X */
  541. Xstatic char **
  542. Xsplit_path_string (src)
  543. XString    src;
  544. X{
  545. X int nelems = 1;
  546. X String    dst;
  547. X String    *elemlist, *elem;
  548. X
  549. X /* count the number of elements */
  550. X for (dst = src; *dst; dst++) if (*dst == ':') nelems++;
  551. X
  552. X /* get memory for everything */
  553. X dst = (String) XtMalloc ((unsigned) (dst - src) + 1);
  554. X if (!dst) return NULL;
  555. X elemlist = (String *) XtMalloc ((unsigned) (nelems + 1), sizeof(String));
  556. X if (!elemlist) {
  557. X    XtFree ((String) dst);
  558. X    return NULL;
  559. X   }
  560. X
  561. X /* copy to new list and walk up nulling colons and setting list pointers */
  562. X (void) strcpy (dst, src);
  563. X for (elem = elemlist, src = dst; *src; src++) {
  564. X     if (*src == ':') {
  565. X        *elem++ = dst;
  566. X        *src = '\0';
  567. X        dst = src + 1;
  568. X       }
  569. X    }
  570. X *elem = dst;
  571. X
  572. X return elemlist;
  573. X}
  574. X
  575. XString            *bitmap_file_paths = NULL;
  576. X
  577. X#ifndef MAXPATHLEN
  578. X#define MAXPATHLEN    256
  579. X#endif
  580. X
  581. X#ifndef BITMAPDIR
  582. X#define BITMAPDIR    "/usr/include/X11/bitmaps"
  583. X#endif
  584. X
  585. X
  586. X/*
  587. X** @(#)XMyLocateXPixmapFile() - Cloned from libXmu LocBitmap.c for use in XPM
  588. X*/
  589. Xstatic Pixmap
  590. XXMyLocateXPixmapFile(w, name, widthp, heightp)
  591. XWidget    w;
  592. Xchar    *name;
  593. Xint    *widthp, *heightp;    /* RETURN */
  594. X{
  595. X int            i;
  596. X Bool            try_plain_name = True;
  597. X Display        *dpy = XtDisplay(w);
  598. X Pixmap            pixmap;                    /* RETURN */
  599. X XrmName        xrm_name[2];
  600. X XrmClass        xrm_class[2];
  601. X XrmRepresentation    rep_type;
  602. X XrmValue        value;
  603. X char            filename[MAXPATHLEN];
  604. X char            **file_paths = NULL;
  605. X XpmAttributes        pmAttr;
  606. X/*
  607. X** look for bitmap path (only once, because we're going to call this twice)
  608. X*/
  609. X if (bitmap_file_paths == NULL) {
  610. X    xrm_name[0] = XrmStringToName ("bitmapFilePath");
  611. X    xrm_name[1] = NULL;
  612. X    xrm_class[0] = XrmStringToClass ("BitmapFilePath");
  613. X    xrm_class[1] = NULL;
  614. X    /*
  615. X    ** XXX - warning, derefing Display * until XDisplayDatabase
  616. X    */
  617. X    if (!dpy->db)
  618. X       (void) XGetDefault (dpy, "", "");
  619. X
  620. X    if (XrmQGetResource (dpy->db, xrm_name, xrm_class, &rep_type, &value) &&
  621. X        rep_type == XrmStringToQuark(XtRString)) {
  622. X       bitmap_file_paths = split_path_string(value.addr);
  623. X      }
  624. X   }
  625. X file_paths = bitmap_file_paths;
  626. X/*
  627. X** Search order:
  628. X**    1.  name if it begins with / or ./
  629. X**    2.  "each prefix in file_paths"/name
  630. X**    3.  BITMAPDIR/name
  631. X**    4.  name if didn't begin with / or .
  632. X*/
  633. X for (i = 1; i <= 4; i++) {
  634. X     String fn = filename;
  635. X
  636. X     switch (i) {
  637. X       case 1:
  638. X            if (!(name[0] == '/' || (name[0] == '.') && name[1] == '/'))
  639. X              continue;
  640. X            fn = name;
  641. X            try_plain_name = False;
  642. X            break;
  643. X       case 2:
  644. X            if (file_paths && *file_paths) {
  645. X                (void) sprintf (filename, "%s/%s", *file_paths, name);
  646. X                file_paths++;
  647. X                i--;
  648. X                break;
  649. X            }
  650. X            continue;
  651. X       case 3:
  652. X            (void) sprintf (filename, "%s/%s", BITMAPDIR, name);
  653. X            break;
  654. X       case 4:
  655. X            if (!try_plain_name) continue;
  656. X            fn = name;
  657. X            break;
  658. X       }
  659. X
  660. X     pmAttr.valuemask = XpmReturnPixels;
  661. X     if (PixmapSuccess == XpmReadFileToPixmap(dpy, w->core.window, fn,
  662. X                         &pixmap, NULL, &pmAttr))
  663. X       {
  664. X        *widthp = pmAttr.width;
  665. X        *heightp = pmAttr.height;
  666. X        return pixmap;
  667. X       }
  668. X    }
  669. X return None;
  670. X}
  671. X#endif
  672. X
  673. X
  674. X
  675. Xstatic void
  676. XRealize(gw, valuemaskp, attr)
  677. XWidget gw;
  678. XXtValueMask *valuemaskp;
  679. XXSetWindowAttributes *attr;
  680. X{
  681. X#ifdef XPM
  682. X int            x, y;
  683. X Pixmap            bitmap, XmuLocateBitmapFile();
  684. X XpmAttributes        pmAttr;
  685. X#endif
  686. X MailwatchWidget    w = (MailwatchWidget) gw;
  687. X int            depth = w->core.depth;
  688. X register Display    *dpy = XtDisplay(w);
  689. X Arg            args[2];
  690. X
  691. X
  692. X XtCreateWindow(gw, InputOutput, (Visual *) CopyFromParent, *valuemaskp, attr);
  693. X/*
  694. X** build up the pixmaps that we'll put into the icon image
  695. X*/
  696. X if (w->mailbox.mail.bitmap == None) {    /* if user failed to specify an icon */
  697. X#ifndef    XPM            /* Non-XPM uses [no]mail.bitmap as a pixmap */
  698. X    w->mailbox.mail.bitmap = XCreateBitmapFromData(dpy, w->core.window,
  699. X                    mail_bits, mail_width, mail_height);
  700. X
  701. X    w->mailbox.mail.pixmap = make_pixmap(dpy, w, w->mailbox.mail.bitmap, depth,
  702. X                     &w->mailbox.mail.width,
  703. X                     &w->mailbox.mail.height);
  704. X   } else {            /* non-XPM used XmuConvertStringToPixmap */
  705. X    w->mailbox.mail.pixmap = make_pixmap(dpy, w, w->mailbox.mail.bitmap, depth,
  706. X                     &w->mailbox.mail.width,
  707. X                     &w->mailbox.mail.height);
  708. X#else
  709. X    pmAttr.valuemask = XpmReturnPixels;
  710. X    XpmCreatePixmapFromData(dpy, w->core.window, mail_xpm,
  711. X                &w->mailbox.mail.pixmap, NULL, &pmAttr);
  712. X    w->mailbox.mail.width = pmAttr.width;
  713. X    w->mailbox.mail.height = pmAttr.height;
  714. X   } else {
  715. X    /*
  716. X    ** Because for XPM we define mailbox.[no]mail.bitmap as a string,
  717. X    ** we must do the file conversion ourselves.  First, see if it is
  718. X    ** a plain old bitmap file.  Failing that, try for an XPM format
  719. X    ** file.  Failing that, default to our internally defined xpm icon.
  720. X    */
  721. X    if (bitmap = XmuLocateBitmapFile(w->core.screen, w->mailbox.mail.bitmap,
  722. X                                     NULL, 0, &w->mailbox.mail.width,
  723. X                                              &w->mailbox.mail.height, &x, &y))
  724. X       w->mailbox.mail.pixmap = make_pixmap(dpy, w, bitmap, depth,
  725. X                                            &w->mailbox.mail.width,
  726. X                        &w->mailbox.mail.height);
  727. X
  728. X    else if (! (w->mailbox.mail.pixmap = XMyLocateXPixmapFile((Widget) w,
  729. X                                                     w->mailbox.mail.bitmap,
  730. X                                                    &w->mailbox.mail.width,
  731. X                                                    &w->mailbox.mail.height))) {
  732. X        pmAttr.valuemask = XpmReturnPixels;
  733. X        XpmCreatePixmapFromData(dpy, w->core.window, mail_xpm,
  734. X                    &w->mailbox.mail.pixmap, NULL, &pmAttr);
  735. X        w->mailbox.mail.width = pmAttr.width;
  736. X        w->mailbox.mail.height = pmAttr.height;
  737. X    }
  738. X#endif
  739. X   }
  740. X
  741. X if (w->mailbox.nomail.bitmap == None) {
  742. X#ifndef    XPM
  743. X    w->mailbox.nomail.bitmap = XCreateBitmapFromData(dpy, w->core.window,
  744. X                                 no_mail_bits, no_mail_width, no_mail_height);
  745. X
  746. X    w->mailbox.nomail.pixmap = make_pixmap(dpy, w, w->mailbox.nomail.bitmap,
  747. X                     depth, &w->mailbox.nomail.width,
  748. X                     &w->mailbox.nomail.height);
  749. X   } else {
  750. X    w->mailbox.nomail.pixmap = make_pixmap(dpy, w, w->mailbox.nomail.bitmap,
  751. X                     depth, &w->mailbox.nomail.width,
  752. X                     &w->mailbox.nomail.height);
  753. X#else
  754. X    pmAttr.valuemask = XpmReturnPixels;
  755. X    XpmCreatePixmapFromData(dpy, w->core.window, nomail_xpm,
  756. X                &w->mailbox.nomail.pixmap, NULL, &pmAttr);
  757. X    w->mailbox.nomail.width = pmAttr.width;
  758. X    w->mailbox.nomail.height = pmAttr.height;
  759. X   } else {
  760. X    if (bitmap = XmuLocateBitmapFile(w->core.screen, w->mailbox.nomail.bitmap,
  761. X                                        NULL, 0, &w->mailbox.nomail.width,
  762. X                                        &w->mailbox.nomail.height, &x, &y))
  763. X       w->mailbox.nomail.pixmap = make_pixmap(dpy, w, bitmap, depth,
  764. X                          &w->mailbox.nomail.width,
  765. X                          &w->mailbox.nomail.height);
  766. X
  767. X    else if (! (w->mailbox.nomail.pixmap = XMyLocateXPixmapFile((Widget) w,
  768. X                                                   w->mailbox.nomail.bitmap,
  769. X                                                  &w->mailbox.nomail.width,
  770. X                                                  &w->mailbox.nomail.height))) {
  771. X        pmAttr.valuemask = XpmReturnPixels;
  772. X        XpmCreatePixmapFromData(dpy, w->core.window, nomail_xpm,
  773. X                    &w->mailbox.nomail.pixmap, NULL, &pmAttr);
  774. X        w->mailbox.nomail.width = pmAttr.width;
  775. X        w->mailbox.nomail.height = pmAttr.height;
  776. X    }
  777. X#endif
  778. X   }
  779. X/*
  780. X** the size of the icon should be the size of the larger icon image.
  781. X*/
  782. X w->core.width  = max(w->mailbox.mail.width, w->mailbox.nomail.width);
  783. X w->core.height = max(w->mailbox.mail.height, w->mailbox.nomail.height);
  784. X
  785. X XtSetArg(args[0], XtNwidth,  (XtArgVal) w->core.width);
  786. X XtSetArg(args[1], XtNheight, (XtArgVal) w->core.height);
  787. X XtSetValues(XtNameToWidget(toplevel, "icon"), args, 2);
  788. X
  789. X/* set status check timer */
  790. X w->mailbox.interval_id = XtAddTimeOut(w->mailbox.update * 1000,
  791. X                                            clock_tic, (caddr_t) w);
  792. X#ifdef XPM
  793. X if (bitmap_file_paths) {
  794. X    XtFree((String) bitmap_file_paths[0]);
  795. X    XtFree((String) bitmap_file_paths);
  796. X   }
  797. X#endif
  798. X}
  799. X
  800. Xstatic void
  801. XDestroy(gw)
  802. XWidget gw;
  803. X{
  804. X MailwatchWidget w = (MailwatchWidget) gw;
  805. X Display    *dpy = XtDisplay(gw);
  806. X
  807. X XtFree((String) w->mailbox.filename);
  808. X XtFree((String) w->mailbox.username);
  809. X XtFree((String) w->mailbox.mailhost);
  810. X REMOVE_TIMEOUT(w->mailbox.interval_id);
  811. X XtReleaseGC(w, w->mailbox.normal_GC);
  812. X#ifndef    XPM
  813. X XFreePixmap(dpy, w->mailbox.mail.bitmap);
  814. X XFreePixmap(dpy, w->mailbox.nomail.bitmap);
  815. X#endif
  816. X XFreePixmap(dpy, w->mailbox.mail.pixmap);
  817. X XFreePixmap(dpy, w->mailbox.nomail.pixmap);
  818. X}
  819. X
  820. Xstatic void
  821. XRedisplay(gw)
  822. XWidget gw;
  823. X{
  824. X    MailwatchWidget w = (MailwatchWidget) gw;
  825. X
  826. X    REMOVE_TIMEOUT(w->mailbox.interval_id);
  827. X    check_mailbox(w, TRUE);
  828. X}
  829. X
  830. X
  831. X/*
  832. X** Modified to NOT update the mail file timestamp via utimes(), and to
  833. X** ignore state change where mail adds a status record to the message.
  834. X** The first eliminates collisions with mail during delivery, and the
  835. X** second eliminates false triggers for new mail.  The number of times
  836. X** the terminal bell is rung is controlled by the same .mailrc resource
  837. X** (bell) used by Sunview's mailtool.
  838. X*/
  839. Xstatic void
  840. Xcheck_mailbox(w, force_redraw)
  841. XMailwatchWidget w;
  842. XBoolean force_redraw;
  843. X{
  844. X int        i, redraw = 0;
  845. X char        *p = NULL;
  846. X
  847. X
  848. X if (stat(w->mailbox.filename, &stbuf) < 0) {        /* no mail file */
  849. X    if (w->mailbox.flag_up == TRUE) {
  850. X       force_redraw = 0;
  851. X       UnsetNewmail(w, NULL, NULL);
  852. X      }
  853. X   } else {
  854. X    if (stbuf.st_atime > stbuf.st_mtime &&
  855. X        stbuf.st_atime >= w->mailbox.last_access) {    /* mail was seen */
  856. X       w->mailbox.last_access = stbuf.st_atime;
  857. X       if (w->mailbox.flag_up == TRUE) {
  858. X          force_redraw = 0;
  859. X          UnsetNewmail(w, NULL, NULL);
  860. X         }
  861. X      } else {
  862. X       if (stbuf.st_size != 0 && 
  863. X           stbuf.st_mtime > w->mailbox.last_access) {    /* got new mail */
  864. X          w->mailbox.last_access = stbuf.st_mtime;
  865. X          if (w->mailbox.flag_up == FALSE) {
  866. X             if (w->mailbox.bell) {
  867. X                i = 1;
  868. X                if (p = (char *)GetMailrc("bell"))
  869. X                   (void) sscanf(p, "%d", &i);
  870. X                i = between(1, i, 5);
  871. X                for (; i > 0; i--)
  872. X                    XBell(XtDisplay(w), MAILBOX_VOLUME);
  873. X               }
  874. X             w->mailbox.flag_up = TRUE;
  875. X             redraw = TRUE;
  876. X             XtCallCallbacks(w, XtNcallback, NULL);
  877. X            }
  878. X         }
  879. X      }
  880. X   }
  881. X
  882. X if (redraw || force_redraw)
  883. X    redraw_mailbox(w);
  884. X
  885. X /* reset timer */
  886. X w->mailbox.interval_id = XtAddTimeOut(w->mailbox.update * 1000,
  887. X    clock_tic, (caddr_t) w);
  888. X} /* check_mailbox */
  889. X
  890. X/*
  891. X** Retrieve the user's mailbox filename - use MAIL environment value, if set
  892. X*/
  893. Xstatic void
  894. XGetMailFile(w)
  895. XMailwatchWidget w;
  896. X{
  897. X if (! (w->mailbox.filename = (String) GetMailEnv("MAIL"))) {
  898. X    if (! (w->mailbox.filename = (String) XtMalloc((unsigned) strlen(MAILBOX_DIRECTORY)
  899. X       + 2 + strlen(w->mailbox.username) + 1))) {
  900. X       (void) fprintf(stderr, "Mailbox widget: can't allocate enough memory.\n");
  901. X       CloseDown(w, 1);
  902. X      }
  903. X    (void) sprintf(w->mailbox.filename, "%s/%s\0", MAILBOX_DIRECTORY, w->mailbox.username);
  904. X   }
  905. X} /* GetMailFile */
  906. X
  907. X
  908. X/*
  909. X** Retrieve the mailbox user's name
  910. X*/
  911. Xstatic void
  912. XGetUserName(w)
  913. XMailwatchWidget w;
  914. X{
  915. X char *username = (char *)getlogin();
  916. X
  917. X if (! username) {
  918. X    struct passwd *pw = getpwuid((uid_t) getuid());
  919. X
  920. X    if (! pw) {
  921. X       (void) fprintf(stderr, "Mailbox widget: can't find your username.\n");
  922. X       CloseDown(w, 1);
  923. X      }
  924. X    username = pw->pw_name;
  925. X   }
  926. X
  927. X if (! (w->mailbox.username = XtNewString(username))) {
  928. X    XtWarning("Mailbox widget: can't allocate space for username.\n");
  929. X    CloseDown(w, 1);
  930. X   }
  931. X} /* GetUserName */
  932. X
  933. X
  934. X/*
  935. X** Retrieve the process host name
  936. X*/
  937. Xstatic void
  938. XGetHostName(w)
  939. XMailwatchWidget w;
  940. X{
  941. X char    hostname[MAXHOSTNAMELEN];
  942. X
  943. X
  944. X (void) gethostname(hostname, MAXHOSTNAMELEN);
  945. X
  946. X if (! (w->mailbox.mailhost = XtNewString(hostname))) {
  947. X    XtWarning("Mailbox widget: can't allocate space for hostname.\n");
  948. X    CloseDown(w, 1);
  949. X   }
  950. X} /* GetHostName */
  951. X
  952. X
  953. Xstatic void
  954. XCloseDown(w, status)
  955. XMailwatchWidget w;
  956. Xint status;
  957. X{
  958. X    Display *dpy = XtDisplay(w);
  959. X
  960. X    XtDestroyWidget(w);
  961. X    XCloseDisplay(dpy);
  962. X    _exit(status);
  963. X}
  964. X
  965. X/* ARGSUSED */
  966. Xstatic Boolean
  967. XSetValues(gcurrent, grequest, gnew)
  968. XWidget gcurrent, grequest, gnew;
  969. X{
  970. X    MailwatchWidget current = (MailwatchWidget) gcurrent;
  971. X    MailwatchWidget new = (MailwatchWidget) gnew;
  972. X    Boolean redisplay = FALSE;
  973. X
  974. X    if (current->mailbox.update != new->mailbox.update) {
  975. X    REMOVE_TIMEOUT(current->mailbox.interval_id);
  976. X    new->mailbox.interval_id = XtAddTimeOut(new->mailbox.update * 1000,
  977. X        clock_tic,
  978. X        (caddr_t) gnew);
  979. X    }
  980. X    if (current->mailbox.foreground_pixel != new->mailbox.foreground_pixel ||
  981. X    current->core.background_pixel != new->core.background_pixel) {
  982. X    XtReleaseGC(current, current->mailbox.normal_GC);
  983. X    GetNormalGC(new);
  984. X    redisplay = TRUE;
  985. X    }
  986. X    return (redisplay);
  987. X}
  988. X
  989. X/*
  990. X * drawing code
  991. X */
  992. Xstatic void
  993. Xredraw_mailbox(m)
  994. XMailwatchWidget m;
  995. X{
  996. X    register Display    *dpy = XtDisplay(m);
  997. X    register Window    win = XtWindow(m);
  998. X    register int    x, y;
  999. X    Pixel        back = m->core.background_pixel;
  1000. X    GC            gc = m->mailbox.normal_GC;
  1001. X    struct _mbimage    *im;
  1002. X
  1003. X
  1004. X    if (m->mailbox.flag_up)            /* paint the "up" position */
  1005. X    im = &m->mailbox.mail;
  1006. X    else                    /* paint the "down" position */
  1007. X    im = &m->mailbox.nomail;
  1008. X
  1009. X    /* center the picture in the window */
  1010. X    x = ((int)m->core.width - im->width) / 2;
  1011. X    y = ((int)m->core.height - im->height) / 2;
  1012. X
  1013. X    XSetWindowBackground(dpy, win, back);
  1014. X    XClearWindow(dpy, win);
  1015. X    XCopyArea(dpy, im->pixmap, win, gc, 0, 0, im->width, im->height, x, y);
  1016. X
  1017. X    if (m->mailbox.useHost || m->mailbox.useName) {
  1018. X       if (m->mailbox.useHost) set_host(m);
  1019. X       else set_user(m);
  1020. X      }
  1021. X}
  1022. X
  1023. X
  1024. Xvoid
  1025. Xreset_mailbox(gw, down)
  1026. XWidget    gw;
  1027. Xint    down;
  1028. X{
  1029. X MailwatchWidget w = (MailwatchWidget) gw;
  1030. X char    *p;
  1031. X int    i;
  1032. X
  1033. X
  1034. X if (down)
  1035. X    w->mailbox.flag_up = FALSE;
  1036. X else {
  1037. X    if (w->mailbox.flag_up == FALSE) {
  1038. X       if (w->mailbox.bell) {
  1039. X          i = 1;
  1040. X          if (p = (char *)GetMailrc("bell"))
  1041. X             (void) sscanf(p, "%d", &i);
  1042. X          i = between(1, i, 5);
  1043. X          for (; i > 0; i--)
  1044. X              XBell(XtDisplay(w), MAILBOX_VOLUME);
  1045. X         }
  1046. X      }
  1047. X    w->mailbox.flag_up = TRUE;
  1048. X   }
  1049. X
  1050. X redraw_mailbox(w);
  1051. X} /* reset_mailbox */
  1052. END_OF_FILE
  1053.   if test 28664 -ne `wc -c <'Mailwatch.c'`; then
  1054.     echo shar: \"'Mailwatch.c'\" unpacked with wrong size!
  1055.   fi
  1056.   # end of 'Mailwatch.c'
  1057. fi
  1058. if test -f 'windows.c' -a "${1}" != "-c" ; then 
  1059.   echo shar: Will not clobber existing file \"'windows.c'\"
  1060. else
  1061.   echo shar: Extracting \"'windows.c'\" \(23700 characters\)
  1062.   sed "s/^X//" >'windows.c' <<'END_OF_FILE'
  1063. X/*
  1064. X * xmail - X window system interface to the mail program
  1065. X *
  1066. X * Copyright 1990,1991,1992 by National Semiconductor Corporation
  1067. X *
  1068. X * Permission to use, copy, modify, and distribute this software and its
  1069. X * documentation for any purpose is hereby granted without fee, provided that
  1070. X * the above copyright notice appear in all copies and that both that
  1071. X * copyright notice and this permission notice appear in supporting
  1072. X * documentation, and that the name of National Semiconductor Corporation not
  1073. X * be used in advertising or publicity pertaining to distribution of the
  1074. X * software without specific, written prior permission.
  1075. X *
  1076. X * NATIONAL SEMICONDUCTOR CORPORATION MAKES NO REPRESENTATIONS ABOUT THE
  1077. X * SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE.  IT IS PROVIDED "AS IS"
  1078. X * WITHOUT EXPRESS OR IMPLIED WARRANTY.  NATIONAL SEMICONDUCTOR CORPORATION
  1079. X * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
  1080. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO
  1081. X * EVENT SHALL NATIONAL SEMICONDUCTOR CORPORATION BE LIABLE FOR ANY SPECIAL,
  1082. X * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  1083. X * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  1084. X * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  1085. X * PERFORMANCE OF THIS SOFTWARE.
  1086. X *
  1087. X * The following software modules were created and are Copyrighted by National
  1088. X * Semiconductor Corporation:
  1089. X *
  1090. X * 1. AddHelpText:
  1091. X * 2. AddInfoHandler:
  1092. X * 3. AddMenuWindow:
  1093. X * 4. AddSetMenu:
  1094. X * 5. CreateFolderButton: and
  1095. X * 6. CreateInputWindow.
  1096. X *
  1097. X * Author:  Michael C. Wagnitz - National Semiconductor Corporation
  1098. X *
  1099. X */
  1100. X
  1101. X
  1102. X#include "global.h"
  1103. X#include "MailwatchP.h"
  1104. X#include "patchlevel.h"
  1105. X#include "national.bm"
  1106. X
  1107. X#ifdef XPM
  1108. X#define    mail_width    64
  1109. X#define    mail_height    64
  1110. X#else
  1111. X#include "icon.mail"
  1112. X#endif
  1113. X
  1114. X/*
  1115. X** @(#)AddHelpText() - add help text to string resources for help widget
  1116. X*/
  1117. Xvoid
  1118. XAddHelpText(parent, text)
  1119. XWidget parent;
  1120. XString    text;
  1121. X{
  1122. X Arg        args[2];
  1123. X String        name;
  1124. X helpText    *help_text;
  1125. X Widget        hw = XtNameToWidget(toplevel, "topBox.help.helpWindow");
  1126. X
  1127. X static String    p_Trans = "!Shift<Btn2Down>: ShowHelp()\n<Btn2Up>: MenuPopdown(help)";
  1128. X
  1129. X
  1130. X XtOverrideTranslations(parent, XtParseTranslationTable(p_Trans));
  1131. X
  1132. X if ((help_text = (helpText *) XtMalloc(sizeof(helpText))) == NULL)
  1133. X    XtError("No memory for help text");
  1134. X
  1135. X name = parent->core.name;
  1136. X help_text->name = XtNewString(name);
  1137. X
  1138. X XtSetArg(args[0], XtNstring, (XtArgVal) text);
  1139. X XtSetArg(args[1], XtNlength, (XtArgVal) strlen(text));
  1140. X
  1141. X help_text->data = (AsciiSrcObject) XtCreateWidget(name, asciiSrcObjectClass, hw, args, 2);
  1142. X
  1143. X help_text->next = HelpList;
  1144. X
  1145. X HelpList = help_text;
  1146. X} /* AddHelpText */
  1147. X
  1148. X
  1149. Xvoid
  1150. XAddInfoHandler(widget, message)
  1151. XWidget widget;
  1152. Xchar *message;
  1153. X{
  1154. X if (XMail.Show_Info)
  1155. X    XtAddEventHandler(widget,
  1156. X          (EventMask) (EnterWindowMask|LeaveWindowMask),
  1157. X          False,
  1158. X          info_handler,
  1159. X          (caddr_t) message);
  1160. X}
  1161. X
  1162. X
  1163. X/* 
  1164. X** @(#)AddMenuWindow() - create menu popup for the specified widget
  1165. X*/
  1166. Xvoid
  1167. XAddMenuWindow(parent, action, list, info_text)
  1168. XWidget        parent;
  1169. XString        action;
  1170. XmenuList_p    *list;
  1171. XString        *info_text;
  1172. X{
  1173. X Arg         args[6];
  1174. X Widget        menu, layout, previous, next;
  1175. X int        j, k, n, indx;
  1176. X char        tag[BUFSIZ], trans[BUFSIZ], *c;        
  1177. X
  1178. X static String p_Trans =
  1179. X    "<Btn3Down>:    SetPopup(%s) MenuPopup(%s)";
  1180. X
  1181. X static String b_Trans =
  1182. X    "<EnterWindow>:    highlight() set() \n\
  1183. X     <LeaveWindow>: unset()  unhighlight()\n\
  1184. X     <Btn3Up>:    notify() reset()";
  1185. X
  1186. X static String m_Trans =
  1187. X    "<Btn3Up>:    MenuPopdown(%s)";
  1188. X
  1189. X static String L_Trans[] = { NULL,
  1190. X    "! Shift      <Btn1Down>: %s(%s)",
  1191. X    "!       Ctrl <Btn1Down>: %s(%s)",
  1192. X    "! Shift Ctrl <Btn1Down>: %s(%s)",
  1193. X    NULL };
  1194. X
  1195. X static String Labels[] = { NULL,
  1196. X    " [Shift]",
  1197. X    "        [Ctrl]",
  1198. X    " [Shift][Ctrl]",
  1199. X    NULL };
  1200. X
  1201. X
  1202. X if (list[0]) {
  1203. X    (void) sprintf(tag, "%s_menu", parent->core.name);
  1204. X    (void) sprintf(trans, p_Trans, tag, tag);
  1205. X    XtOverrideTranslations(parent, XtParseTranslationTable(trans));
  1206. X
  1207. X    (void) sprintf(trans, m_Trans, tag);
  1208. X    XtSetArg(args[0], XtNtranslations, XtParseTranslationTable(trans));
  1209. X    menu = XtCreatePopupShell(tag, overrideShellWidgetClass, parent, args, 1);
  1210. X
  1211. X    XtSetArg(args[0], XtNdefaultDistance, (XtArgVal) 1);
  1212. X    layout = XtCreateManagedWidget("menu", formWidgetClass, menu, args, 1);
  1213. X/*
  1214. X** Find widest label for this menu
  1215. X*/
  1216. X    for (j = k = n = indx = 0; list[indx] != NULL; indx++)
  1217. X        if ((k = strlen(list[indx]->label)) > j) {
  1218. X           j = k;
  1219. X           n = indx;
  1220. X          }
  1221. X    k = XTextWidth(XMail.buttonFont, list[n]->label, j) + 12;
  1222. X
  1223. X    if (--indx > 0)    /* add length for accelerator keys menu notes */
  1224. X       k += XTextWidth(XMail.buttonFont, Labels[indx], strlen(Labels[indx]));
  1225. X/*
  1226. X** create the menu buttons
  1227. X*/
  1228. X    previous = NULL;
  1229. X    XtSetArg(args[0], XtNwidth, k);
  1230. X    XtSetArg(args[1], XtNfont, XMail.buttonFont);
  1231. X    XtSetArg(args[2], XtNjustify, XtJustifyLeft);
  1232. X    XtSetArg(args[3], XtNtranslations, XtParseTranslationTable(b_Trans));
  1233. X    for (indx = 0; list[indx] != NULL; indx++) {
  1234. X        (void) strcpy(tag, list[indx]->label);    /* set window name by label */
  1235. X        if ((c = strchr(tag, ' '))) *c = '\0';    /* first word only */
  1236. X        (void) sprintf(trans, "%-*.*s", j, j, list[indx]->label);
  1237. X        if (Labels[indx])            /* add accel. note if needed */
  1238. X           (void) strcat(trans, Labels[indx]);
  1239. X
  1240. X        XtSetArg(args[4], XtNlabel, trans);
  1241. X        XtSetArg(args[5], XtNfromVert, previous);
  1242. X        next = XtCreateManagedWidget(tag, commandWidgetClass, layout, args, 6);
  1243. X
  1244. X        if (info_text)
  1245. X           AddInfoHandler(next, info_text[indx]);
  1246. X
  1247. X        XtAddCallback(next, XtNcallback, list[indx]->func, list[indx]->data);
  1248. X        previous = next;
  1249. X
  1250. X    if (L_Trans[indx]) {
  1251. X       (void) sprintf(trans, L_Trans[indx], action, list[indx]->data);
  1252. X           XtOverrideTranslations(parent, XtParseTranslationTable(trans));
  1253. X          }
  1254. X       }
  1255. X/*
  1256. X** Dummy out any remaining combinations of accelerators to do nothing
  1257. X*/
  1258. X    for (; L_Trans[indx] != NULL; indx++) {
  1259. X    (void) sprintf(trans, L_Trans[indx], "DoNothing", "");
  1260. X        XtOverrideTranslations(parent, XtParseTranslationTable(trans));
  1261. X       }
  1262. X   }
  1263. X} /* AddMenuWindow */
  1264. X
  1265. X
  1266. X/*
  1267. X** @(#)AddButton() - add a button to the command window
  1268. X**                   include help and an auxilary commands popup menu
  1269. X*/
  1270. Xvoid
  1271. XAddButton(parent, name, action, command, list, info_text, help_text)
  1272. XWidget        parent;            /* widget which holds this button */
  1273. XString        name;            /* Label for button (and children) */
  1274. XString        action;            /* name of the XtActionProc to call */
  1275. XString        command;        /* passed as param(s) to ActionProc */
  1276. XmenuList_p    *list;            /* aux. menu buttons list w/ cbacks */
  1277. XString        *info_text;        /* pointer to button specific info */
  1278. XString        help_text;        /* pointer to button specific help */
  1279. X{
  1280. X Arg        args[5];
  1281. X Widget        button;
  1282. X char        trans[BUFSIZ];
  1283. X static String  b_Trans = "#override <Btn1Down>: %s(%s)";
  1284. X static String  h_Trans = "#override \
  1285. X    <Btn1Down>: %s(%s) \n\
  1286. X    <Btn2Down>: ShowHelp()";
  1287. X/*
  1288. X** Insert name of XtActionProc (and parameter(s)) in the translation list
  1289. X*/
  1290. X if (help_text)
  1291. X    (void) sprintf(trans, h_Trans, action, command);
  1292. X else
  1293. X    (void) sprintf(trans, b_Trans, action, command);
  1294. X
  1295. X XtSetArg(args[0], XtNwidth, XMail.buttonWidth);
  1296. X XtSetArg(args[1], XtNheight, XMail.buttonHeight);
  1297. X XtSetArg(args[2], XtNresize, False);
  1298. X XtSetArg(args[3], XtNfont, XMail.buttonFont);
  1299. X XtSetArg(args[4], XtNtranslations, XtParseTranslationTable(trans));
  1300. X button = XtCreateManagedWidget(name, commandWidgetClass, parent, args, 5);
  1301. X
  1302. X if (info_text)
  1303. X    AddInfoHandler(button, info_text[0]);
  1304. X
  1305. X if (help_text)
  1306. X    AddHelpText(button, help_text);
  1307. X
  1308. X if (list)
  1309. X    AddMenuWindow(button, action, list, info_text);
  1310. X} /* AddButton */
  1311. X
  1312. X
  1313. X/* 
  1314. X** @(#)AddSetMenu() - add hook to create menu for toggling mail options
  1315. X*/
  1316. Xvoid
  1317. XAddSetMenu(w)
  1318. XWidget        w;
  1319. X{
  1320. X Widget        parent = XtNameToWidget(w, "preserve");
  1321. X static String p_Trans = "<Btn3Down>: SetMenu() MenuPopup(set_menu)";
  1322. X
  1323. X XtOverrideTranslations(parent, XtParseTranslationTable(p_Trans));
  1324. X} /* AddSetMenu */
  1325. X
  1326. X
  1327. Xvoid
  1328. XCreateButtons(parent)
  1329. XWidget parent;
  1330. X{
  1331. X menuList_p    *list;
  1332. X menuList    b1, b2, b3, b4;
  1333. X
  1334. X
  1335. X list = (menuList **) XtMalloc((unsigned) 5 * sizeof(menuList *));
  1336. X
  1337. X b1.label = "next";        b1.func = (XtCallbackProc) DoWith;  b1.data = "n";
  1338. X b2.label = "previous";    b2.func = (XtCallbackProc) DoWith;  b2.data = "-";
  1339. X b3.label = "read";        b3.func = (XtCallbackProc) DoWith;  b3.data = "p";
  1340. X b4.label = "full header"; b4.func = (XtCallbackProc) DoWith;  b4.data = "P";
  1341. X list[0] = &b1; list[1] = &b2; list[2] = &b3; list[3] = &b4; list[4] = NULL;
  1342. X AddButton(parent, "next", "DoSelected", "n", list, Read_Info, Read_Help);
  1343. X
  1344. X b1.label = "save";    b1.func = (XtCallbackProc) Save;    b1.data = "s";
  1345. X b2.label = "Save to author"; b2.func = (XtCallbackProc) Save;    b2.data = "S";
  1346. X b3.label = "write";    b3.func = (XtCallbackProc) Save;    b3.data = "w";
  1347. X list[0] = &b1; list[1] = &b2; list[2] = &b3; list[3] = NULL;
  1348. X AddButton(parent, "save", "DoSave", "s", list, Save_Info, Save_Help);
  1349. X
  1350. X CreateFolderButton(parent);
  1351. X
  1352. X b1.label = "copy";    b1.func = (XtCallbackProc) Save;    b1.data = "c";
  1353. X b2.label = "Copy to author"; b2.func = (XtCallbackProc) Save;    b2.data = "C";
  1354. X list[0] = &b1; list[1] = &b2; list[2] = NULL;
  1355. X AddButton(parent, "copy", "DoSave", "c", list, Copy_Info, Copy_Help);
  1356. X
  1357. X AddButton(parent, "preserve", "DoSelected", "preserve", (menuList_p *)NULL, Hold_Info, Hold_Help);
  1358. X
  1359. X b1.label = "delete";    b1.func = (XtCallbackProc) DoWith;    b1.data = "d";
  1360. X b2.label = "undelete";    b2.func = (XtCallbackProc) DoWith;    b2.data = "u";
  1361. X list[0] = &b1; list[1] = &b2; list[2] = NULL;
  1362. X AddButton(parent, "delete", "DoSelected", "d", list, Delete_Info, Delete_Help);
  1363. X
  1364. X b1.label = "Newmail"; b1.func = (XtCallbackProc) DoIt; b1.data = "file %";
  1365. X b2.label = "inc (no commit)"; b2.func = (XtCallbackProc) DoIt; b2.data = "inc";
  1366. X b3.label = "Drop Folders"; b3.func = (XtCallbackProc) DropIt; b3.data = "drop";
  1367. X list[0] = &b1; list[1] = &b2; list[2] = &b3; list[3] = NULL;
  1368. X AddButton(parent, "Newmail", "DoCmd", "file %", list, NewMail_Info, NewMail_Help);
  1369. X
  1370. X b1.label = "quit";    b1.func = (XtCallbackProc) DoQuit;    b1.data = "q";
  1371. X b2.label = "exit";    b2.func = (XtCallbackProc) DoQuit;    b2.data = "x";
  1372. X list[0] = &b1; list[1] = &b2; list[2] = NULL;
  1373. X AddButton(parent, "quit", "Quit", "q", list, Quit_Info, Quit_Help);
  1374. X
  1375. X b1.label = "print"; b1.func = (XtCallbackProc) DoPrint; b1.data = "";
  1376. X list[0] = &b1; list[1] = NULL;
  1377. X AddButton(parent, "Print", "PrintMsg", "", list, Print_Info, Print_Help);
  1378. X
  1379. X b1.label="send a message";    b1.func = (XtCallbackProc) Reply; b1.data = "s";
  1380. X b2.label="forward message";   b2.func = (XtCallbackProc) Reply; b2.data = "S";
  1381. X list[0] = &b1; list[1] = &b2; list[2] = NULL;
  1382. X AddButton(parent, "Send", "DoReply", "s", list, Send_Info, Send_Help);
  1383. X
  1384. X b1.label="reply";             b1.func = (XtCallbackProc) Reply; b1.data = "r";
  1385. X b2.label="reply included";    b2.func = (XtCallbackProc) Reply; b2.data = "R";
  1386. X b3.label="replyall";          b3.func = (XtCallbackProc) Reply; b3.data = "a";
  1387. X b4.label="replyall included"; b4.func = (XtCallbackProc) Reply; b4.data = "A";
  1388. X list[0] = &b1; list[1] = &b2; list[2] = &b3;
  1389. X list[3] = &b4; list[4] = NULL;
  1390. X AddButton(parent, "reply", "DoReply", "r", list, Reply_Info, Reply_Help);
  1391. X
  1392. X XtFree((menuList *) list);
  1393. X
  1394. X CreateFileWindow(parent);
  1395. X
  1396. X AddSetMenu(parent);        /* add a menu for toggling mail options */
  1397. X
  1398. X} /* CreateButtons */
  1399. X
  1400. X
  1401. X/*
  1402. X** @(#)CreateCommandPanel() - add buttons, and set up the file menu.
  1403. X*/
  1404. Xvoid
  1405. XCreateCommandPanel(parent)
  1406. XWidget parent;
  1407. X{
  1408. X Widget        cw;
  1409. X Arg        args[8];
  1410. X
  1411. X static String w_Trans = "<Btn1Down>: DoNothing()\n<Btn2Down>: DoNothing()\n<Btn3Down>: DoNothing()";
  1412. X
  1413. X XtSetArg(args[0], XtNhSpace, XMail.commandHSpace);
  1414. X XtSetArg(args[1], XtNvSpace, XMail.commandVSpace);
  1415. X XtSetArg(args[2], XtNallowResize, (XtArgVal) False);
  1416. X XtSetArg(args[3], XtNmax, XMail.commandHeight);
  1417. X XtSetArg(args[4], XtNmin, XMail.commandHeight);
  1418. X XtSetArg(args[5], XtNfont, XMail.buttonFont);
  1419. X XtSetArg(args[6], XtNtranslations, XtParseTranslationTable(w_Trans));
  1420. X XtSetArg(args[7], XtNshowGrip, (XtArgVal) False);
  1421. X
  1422. X cw = XtCreateManagedWidget("commandPanel", boxWidgetClass, parent, args, 8);
  1423. X
  1424. X CreateButtons(cw);
  1425. X} /* CreateCommandPanel */
  1426. X
  1427. X
  1428. X/*
  1429. X** @(#)CreateFileWindow() - for user entry of file and folder names
  1430. X** Includes a special set of action routines for the keys to do
  1431. X** Delete/Backspace, Ctrl-U, Ctrl-W, and insert-selection().
  1432. X*/
  1433. Xvoid
  1434. XCreateFileWindow(parent)
  1435. XWidget parent;
  1436. X{
  1437. X Widget        w;
  1438. X Arg        args[9];
  1439. X
  1440. X static String    trans = "#override \n\
  1441. X  Ctrl <Key>a:        beginning-of-file() \n\
  1442. X  Ctrl <Key>b:        backward-character() \n\
  1443. X  Ctrl <Key>d:        CheckInsert() delete-next-character() \n\
  1444. X  Ctrl <Key>e:        end-of-file() \n\
  1445. X  Ctrl <Key>f:        forward-character() \n\
  1446. X  Ctrl <Key>h:        DeleteChar() \n\
  1447. X  Ctrl <Key>j:        DoNothing() \n\
  1448. X  Ctrl <Key>m:        DoNothing() \n\
  1449. X  Ctrl <Key>u:        DeleteLine() \n\
  1450. X  Ctrl <Key>w:        DeleteWord() \n\
  1451. X  Meta <Key>b:        backward-word() \n\
  1452. X  Meta <Key>d:        CheckInsert() delete-next-word() \n\
  1453. X  Meta <Key>f:        forward-word() \n\
  1454. X       <Key>Delete:    DeleteChar() \n\
  1455. X       <Key>BackSpace:    DeleteChar() \n\
  1456. X       <Key>Linefeed:    DoNothing() \n\
  1457. X       <Key>Return:    DoNothing() \n\
  1458. X       <Key>Right:    forward-character() \n\
  1459. X       <Key>Left:    backward-character() \n\
  1460. X       <Key>:        CheckInsert() insert-char()\n\
  1461. X       <Btn1Down>:    select-start() \n\
  1462. X       <Btn2Down>:    CheckInsert() insert-selection(PRIMARY, CUT_BUFFER0)";
  1463. X
  1464. X
  1465. X XtSetArg(args[0], XtNwidth, XMail.fileBoxWidth);
  1466. X XtSetArg(args[1], XtNheight, XMail.buttonHeight);
  1467. X XtSetArg(args[2], XtNborderWidth, 1);
  1468. X XtSetArg(args[3], XtNfont, XMail.buttonFont);
  1469. X XtSetArg(args[4], XtNeditType, XawtextEdit);
  1470. X XtSetArg(args[5], XtNstring, (XtArgVal) "");
  1471. X XtSetArg(args[6], XtNtranslations, XtParseTranslationTable(trans));
  1472. X
  1473. X w = XtCreateManagedWidget("fileWindow", asciiTextWidgetClass, parent, args, 7);
  1474. X
  1475. X writeTo(w, "File: ", REPLACE);        /* insert label and position cursor */
  1476. X
  1477. X AddInfoHandler(w, "Specify the name of a mail folder (or press <Shift><Button2> for help)");
  1478. X
  1479. X AddHelpText(w, File_Help);
  1480. X} /* CreateFileWindow */
  1481. X
  1482. X
  1483. X/*
  1484. X** @(#)CreateFolderButton() - attach special Btn3 hook to list folders
  1485. X*/
  1486. Xvoid
  1487. XCreateFolderButton(parent)
  1488. XWidget    parent;
  1489. X{
  1490. X Widget        button;
  1491. X Arg        args[5];
  1492. X
  1493. X static String    trans = "#override \n\
  1494. X            <Btn1Down>: Folder() \n\
  1495. X            <Btn2Down>: ShowHelp() \n\
  1496. X            <Btn3Down>: SetFolders()";
  1497. X
  1498. X XtSetArg(args[0], XtNwidth, XMail.buttonWidth);
  1499. X XtSetArg(args[1], XtNheight, XMail.buttonHeight);
  1500. X XtSetArg(args[2], XtNresize, False);
  1501. X XtSetArg(args[3], XtNfont, XMail.buttonFont);
  1502. X XtSetArg(args[4], XtNtranslations, XtParseTranslationTable(trans));
  1503. X button = XtCreateManagedWidget("Folder", commandWidgetClass, parent, args, 5);
  1504. X
  1505. X AddInfoHandler(button, Folder_Info[0]);
  1506. X
  1507. X AddHelpText(button, Folder_Help);
  1508. X
  1509. X XtRegisterGrabAction(SetFolders, True, ButtonPressMask | ButtonReleaseMask,
  1510. X                       GrabModeAsync, GrabModeAsync);
  1511. X
  1512. X XtRegisterGrabAction(SetDirectory, True, ButtonPressMask | ButtonReleaseMask,
  1513. X                       GrabModeAsync, GrabModeAsync);
  1514. X} /* CreateFolderButton */
  1515. X
  1516. X
  1517. X/* 
  1518. X** @(#)CreateHelpWindow() - create popup window for the help text
  1519. X*/
  1520. Xvoid
  1521. XCreateHelpWindow(parent)
  1522. XWidget parent;
  1523. X{
  1524. X Arg    args[5];
  1525. X Widget    w;
  1526. X static String    trans = "#override \n\
  1527. X  Ctrl <Key>J:        MenuPopdown(help) \n\
  1528. X  <Key>Linefeed:    MenuPopdown(help)";
  1529. X
  1530. X XtSetArg(args[0], XtNborderWidth, 3);
  1531. X w = XtCreatePopupShell("help", overrideShellWidgetClass, parent, args, 1);
  1532. X
  1533. X XtSetArg(args[0], XtNwidth, XMail.helpWidth);
  1534. X XtSetArg(args[1], XtNheight, XMail.helpHeight);
  1535. X XtSetArg(args[2], XtNfont, XMail.helpFont);
  1536. X XtSetArg(args[3], XtNtranslations, XtParseTranslationTable(trans));
  1537. X XtSetArg(args[4], XtNdisplayCaret, (XtArgVal) False);
  1538. X
  1539. X XtCreateManagedWidget("helpWindow", asciiTextWidgetClass, w, args, 5);
  1540. X} /* CreateHelpWindow */
  1541. X
  1542. X
  1543. X/* 
  1544. X** Index window is a AsciiTextWidget, with special key assignments
  1545. X*/
  1546. Xvoid
  1547. XCreateIndexWindow(parent)
  1548. XWidget parent;
  1549. X{
  1550. X Arg    args[7];
  1551. X Widget    w;
  1552. X
  1553. X
  1554. X XtSetArg(args[0], XtNheight, XMail.indexHeight);
  1555. X XtSetArg(args[1], XtNfont, XMail.textFont);
  1556. X XtSetArg(args[2], XtNdisplayCaret, (XtArgVal) False);
  1557. X XtSetArg(args[3], XtNeditType, XawtextEdit);
  1558. X XtSetArg(args[4], XtNscrollVertical, XawtextScrollAlways);
  1559. X XtSetArg(args[5], XtNwrap, XawtextWrapNever);
  1560. X XtSetArg(args[6], XtNstring, "");
  1561. X
  1562. X w = XtCreateManagedWidget("indexWindow", asciiTextWidgetClass,parent,args,7);
  1563. X
  1564. X AddHelpText(w, Index_Help);
  1565. X} /* CreateIndexWindow */
  1566. X
  1567. X
  1568. X/*
  1569. X** @(#)CreateStatusWindow() - place for messages from mail
  1570. X*/
  1571. Xvoid
  1572. XCreateStatusWindow(parent)
  1573. XWidget parent;
  1574. X{
  1575. X Arg        args[10];
  1576. X Widget        w;
  1577. X
  1578. X static String w_Trans = "<Btn1Down>: DoNothing()\n<Btn2Down>: ShowHelp()\n<Btn3Down>: DoNothing()";
  1579. X
  1580. X XtSetArg(args[0], XtNallowResize, False);
  1581. X XtSetArg(args[1], XtNmin, XMail.buttonHeight);
  1582. X XtSetArg(args[2], XtNmax, XMail.buttonHeight);
  1583. X XtSetArg(args[3], XtNshowGrip, False);
  1584. X
  1585. X XtSetArg(args[4], XtNwidth, XMail.shellWidth);
  1586. X XtSetArg(args[5], XtNfont, XMail.textFont);
  1587. X XtSetArg(args[6], XtNjustify, XtJustifyCenter);
  1588. X XtSetArg(args[7], XtNlabel, "Establishing connections");
  1589. X XtSetArg(args[8], XtNresize, False);
  1590. X XtSetArg(args[9], XtNtranslations, XtParseTranslationTable(w_Trans));
  1591. X
  1592. X w = XtCreateManagedWidget("statusWindow", labelWidgetClass, parent, args, 10);
  1593. X
  1594. X AddHelpText(w, Status_Help);
  1595. X} /* CreateStatusWindow */
  1596. X
  1597. X
  1598. X/*
  1599. X** @(#)CreateSubWindows() - create all the xmail subwindows.
  1600. X*/
  1601. Xvoid
  1602. XCreateSubWindows(parent)
  1603. XWidget parent;
  1604. X{
  1605. X int        n, x, y;
  1606. X Widget    icon, mb, topbox;
  1607. X Arg    args[4];
  1608. X
  1609. X
  1610. X XtSetArg(args[0], XtNinput,      True);
  1611. X XtSetArg(args[1], XtNwidth,      XMail.shellWidth);
  1612. X XtSetArg(args[2], XtNgripIndent, 0);
  1613. X XtSetArg(args[3], XtNskipAdjust, True);
  1614. X
  1615. X topbox = XtCreateManagedWidget("topBox", panedWidgetClass, parent, args, 4);
  1616. X
  1617. X CreateHelpWindow(topbox);
  1618. X CreateTitleBar(topbox);
  1619. X CreateIndexWindow(topbox);
  1620. X CreateStatusWindow(topbox);
  1621. X CreateCommandPanel(topbox);
  1622. X CreateTextWindow(topbox);
  1623. X/*
  1624. X** Create an icon window for the mailwatchWidget
  1625. X*/
  1626. X XtSetArg(args[0], XtNwidth, (XtArgVal) mail_width);
  1627. X XtSetArg(args[1], XtNheight, (XtArgVal) mail_height);
  1628. X n = 2;
  1629. X if (XMail.iconGeometry) {
  1630. X    ParseIconGeometry(XMail.iconGeometry, &x, &y);
  1631. X    XtSetArg(args[n], XtNx, (XtArgVal) x);        n++;
  1632. X    XtSetArg(args[n], XtNy, (XtArgVal) y);        n++;
  1633. X   }
  1634. X icon = XtCreateWidget("icon", applicationShellWidgetClass, toplevel, args, n);
  1635. X mb = XtCreateManagedWidget("mailbox", mailwatchWidgetClass, icon, args, 0);
  1636. X XtAddCallback(mb, XtNcallback, SetNewmail, NULL);
  1637. X} /* CreateSubWindows */ 
  1638. X
  1639. X
  1640. X/* 
  1641. X** @(#)CreateTextWindow() - AsciiTextWidget window, without special keys
  1642. X*/
  1643. Xvoid
  1644. XCreateTextWindow(parent)
  1645. XWidget parent;
  1646. X{
  1647. X Widget        form, tw;
  1648. X helpText    *help_text;
  1649. X Arg         args[12];
  1650. X
  1651. X
  1652. X XtSetArg(args[0], XtNmin, XMail.textHeight / 3);
  1653. X XtSetArg(args[1], XtNheight, XMail.textHeight);
  1654. X XtSetArg(args[2], XtNwidth, XMail.shellWidth);
  1655. X form = XtCreateManagedWidget("textWindow", formWidgetClass, parent, args, 3);
  1656. X
  1657. X XtSetArg(args[0], XtNleft, XtChainRight);
  1658. X XtSetArg(args[1], XtNright, XtChainRight);
  1659. X XtSetArg(args[2], XtNtop, XtChainTop);
  1660. X XtSetArg(args[3], XtNbottom, XtChainTop);
  1661. X XtSetArg(args[4], XtNvertDistance, 0);
  1662. X XtSetArg(args[5], XtNhorizDistance, XMail.shellWidth - 48);
  1663. X XtSetArg(args[6], XtNborderWidth, 0);
  1664. X XtSetArg(args[7], XtNheight, 48);
  1665. X XtSetArg(args[8], XtNwidth, 48);
  1666. X XtSetArg(args[9], XtNinternalWidth, 0);
  1667. X XtCreateWidget("face", labelWidgetClass, form, args, 10);
  1668. X
  1669. X XtSetArg(args[0], XtNleft, XtChainLeft);
  1670. X XtSetArg(args[1], XtNright, XtChainRight);
  1671. X XtSetArg(args[2], XtNtop, XtChainTop);
  1672. X XtSetArg(args[3], XtNbottom, XtChainBottom);
  1673. X /* see above... */
  1674. X XtSetArg(args[5], XtNhorizDistance, 0);
  1675. X /* see above... */
  1676. X XtSetArg(args[7], XtNheight, XMail.textHeight);
  1677. X XtSetArg(args[8], XtNfont, XMail.textFont);
  1678. X XtSetArg(args[9], XtNdisplayCaret, False);
  1679. X XtSetArg(args[10], XtNstring, "");
  1680. X XtSetArg(args[11], XtNscrollVertical, XawtextScrollAlways);
  1681. X tw = XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, 12);
  1682. X
  1683. X AddHelpText(tw, Text_Help);
  1684. X
  1685. X if ( (help_text = (helpText *) XtMalloc(sizeof(helpText))) == NULL)
  1686. X    XtError("No memory for help text");
  1687. X
  1688. X help_text->name = XtNewString("text2");
  1689. X
  1690. X XtSetArg(args[0], XtNstring, (XtArgVal) Text2_Help);
  1691. X XtSetArg(args[1], XtNlength, (XtArgVal) strlen(Text2_Help));
  1692. X
  1693. X help_text->data = (AsciiSrcObject) XtCreateWidget("text2", asciiSrcObjectClass,
  1694. X                        XtNameToWidget(toplevel, "topBox.help.helpWindow"),
  1695. X                        args, 2);
  1696. X
  1697. X help_text->next = HelpList;
  1698. X HelpList = help_text;
  1699. X} /* CreateTextWindow */
  1700. X
  1701. X
  1702. X/*
  1703. X** @(#)CreateTitleBar() - creates the title bar displayed at top of shell
  1704. X**              Include Nat. Semi. Corp. logo in top left corner.
  1705. X*/
  1706. Xvoid
  1707. XCreateTitleBar(parent)
  1708. XWidget parent;
  1709. X{
  1710. X Arg        args[8];
  1711. X Pixmap        logo;
  1712. X Widget        form, lg, tb;
  1713. X char        buf[20];
  1714. X
  1715. X static String w_Trans = "<Btn1Down>: DoNothing()\n<Btn2Down>: ShowHelp()\n<Btn3Down>: DoNothing()";
  1716. X
  1717. X static String l_Trans = "<Btn1Down>: Iconify()\n<Btn2Down>: Iconify()\n<Btn3Down>: Iconify()";
  1718. X
  1719. X XtSetArg(args[0], XtNdefaultDistance, 1);
  1720. X XtSetArg(args[1], XtNallowResize, (XtArgVal) False);
  1721. X XtSetArg(args[2], XtNmax, (XtArgVal) XMail.buttonHeight);
  1722. X XtSetArg(args[3], XtNmin, (XtArgVal) XMail.buttonHeight);
  1723. X XtSetArg(args[4], XtNshowGrip, (XtArgVal) False);
  1724. X
  1725. X form = XtCreateManagedWidget("titleBar", formWidgetClass, parent, args, 5);
  1726. X
  1727. X logo = XCreateBitmapFromData(XtDisplay(toplevel), XtScreen(toplevel)->root,
  1728. X                        national_bits, national_width, national_height);
  1729. X
  1730. X XtSetArg(args[0], XtNborderWidth, 0);
  1731. X XtSetArg(args[1], XtNheight, (XtArgVal) XMail.buttonHeight);
  1732. X XtSetArg(args[2], XtNwidth, national_width);
  1733. X XtSetArg(args[3], XtNinternalWidth, 0);
  1734. X XtSetArg(args[4], XtNbitmap, (XtArgVal) logo);
  1735. X XtSetArg(args[5], XtNshapeStyle, XmuShapeRectangle);
  1736. X XtSetArg(args[6], XtNtranslations, XtParseTranslationTable(l_Trans));
  1737. X lg = XtCreateManagedWidget("logo", commandWidgetClass, form, args, 7);
  1738. X
  1739. X (void) sprintf(buf, "%s%d", TITLE, PATCHLEVEL);
  1740. X
  1741. X XtSetArg(args[2], XtNwidth, XMail.shellWidth - national_width - 2);
  1742. X XtSetArg(args[3], XtNlabel, (XtArgVal) buf);
  1743. X XtSetArg(args[4], XtNfont, XMail.textFont);
  1744. X XtSetArg(args[5], XtNjustify, (XtArgVal) XtJustifyLeft);
  1745. X XtSetArg(args[6], XtNfromHoriz, lg);
  1746. X XtSetArg(args[7], XtNtranslations, XtParseTranslationTable(w_Trans));
  1747. X tb = XtCreateManagedWidget("title", labelWidgetClass, form, args, 8);
  1748. X
  1749. X AddHelpText(tb, Title_Help);
  1750. X} /* CreateTitleBar */
  1751. X
  1752. X
  1753. X/*
  1754. X** @(#)CreateInputWindow() - for specifying recipient, subject, and Cc list
  1755. X** Has its own set of translations for editing.
  1756. X** Special actions for Delete/Backspace, Ctrl-U, and Ctrl-W.
  1757. X*/
  1758. XWidget
  1759. XCreateInputWindow(parent, name)
  1760. XWidget    parent;
  1761. XString    name;
  1762. X{
  1763. X int    n;
  1764. X Widget    w;
  1765. X Arg    args[7];
  1766. X
  1767. X n  = XMail.shellWidth - 26;    /* - (20 + 2 * (internal_width+def_dist)) */
  1768. X n -= figureWidth(XMail.buttonFont)*9-10; /* less label width+fudge factor */
  1769. X
  1770. X XtSetArg(args[0], XtNinput, True);
  1771. X XtSetArg(args[1], XtNwidth, n);
  1772. X XtSetArg(args[2], XtNheight, XMail.buttonHeight + XMail.borderWidth);
  1773. X XtSetArg(args[3], XtNborderWidth, 1);
  1774. X XtSetArg(args[4], XtNfont, XMail.buttonFont);
  1775. X XtSetArg(args[5], XtNstring, "");
  1776. X XtSetArg(args[6], XtNeditType, XawtextEdit);
  1777. X
  1778. X w = XtCreateManagedWidget(name, asciiTextWidgetClass, parent, args, 7);
  1779. X
  1780. X return( w );
  1781. X} /* CreateInputWindow */
  1782. X
  1783. X/* 
  1784. X** @(#)ParseIconGeometry() - Parse the icon geometry
  1785. X*/
  1786. Xvoid
  1787. XParseIconGeometry(str, x, y)
  1788. XString        str;
  1789. XCardinal    *x, *y;
  1790. X{
  1791. X int        res;
  1792. X Cardinal    w, h;
  1793. X
  1794. X *x = 0;
  1795. X *y = 0;
  1796. X res = XParseGeometry(str, x, y, &w, &h);
  1797. X if ((res & (XNegative|XValue)) == (XNegative|XValue))
  1798. X    *x = RootWidth + *x - mail_width;
  1799. X if ((res & (YNegative|YValue)) == (YNegative|YValue))
  1800. X    *y = RootHeight + *y - mail_height;
  1801. X} /* ParseIconGeometry */
  1802. END_OF_FILE
  1803.   if test 23700 -ne `wc -c <'windows.c'`; then
  1804.     echo shar: \"'windows.c'\" unpacked with wrong size!
  1805.   fi
  1806.   # end of 'windows.c'
  1807. fi
  1808. echo shar: End of archive 5 \(of 10\).
  1809. cp /dev/null ark5isdone
  1810. MISSING=""
  1811. for I in 1 2 3 4 5 6 7 8 9 10 ; do
  1812.     if test ! -f ark${I}isdone ; then
  1813.     MISSING="${MISSING} ${I}"
  1814.     fi
  1815. done
  1816. if test "${MISSING}" = "" ; then
  1817.     echo You have unpacked all 10 archives.
  1818.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1819. else
  1820.     echo You still must unpack the following archives:
  1821.     echo "        " ${MISSING}
  1822. fi
  1823. exit 0
  1824. exit 0 # Just in case...
  1825. -- 
  1826.   // chris@IMD.Sterling.COM            | Send comp.sources.x submissions to:
  1827. \X/  Amiga - The only way to fly!      |
  1828.  "It's intuitively obvious to the most |    sources-x@imd.sterling.com
  1829.   casual observer..."                  |
  1830.