[comp.sources.x] v11i071: dbiff -- double-enhanced xbiff, Part01/02

pfuetz@agd.fhg.de (02/15/91)

Submitted-by: pfuetz@agd.fhg.de
Posting-number: Volume 11, Issue 71
Archive-name: dbiff/part01

I got hold of xbiff-audio for SUN SPARCstations.
Then I got hold of xbiff2 (comp.sources.x, Volume 8, Issue 7). Because I'd
liked both of them for their individual enhancements, I combined them.

Read the README* files for mor information.

Matthias Pfuetzner
===== cut for part 1 ========
#!/bin/sh
# To unshare, sh or unshar this file
echo CHANGES 1>&2
sed -e 's/^X//' > CHANGES <<'E!O!F! CHANGES'
XThe following changes have been made to this directory since R3:
X
X     o  -shape option added
X     o  WM_DELETE_WINDOW support added
X     o  bugs fixed
X
XThe following changes have been made by Mike Wagner 
X(wagner@cadillac.siemens.com):
X     o  added -sound option on SparcStation
X     o  overloaded -volume option to also work for sound played
X     o  added -soundBindings option to customize sounds for
X        different senders and recipients.
X     o  Reimplemented the newmsgs function (and the semantics of
X        the check_command). Both now return the number of unread
X	messages.
X     o  Added the review() action
XThe following changes have been made by Matthias Pfuetzner
X(pfuetzner@agd.fhg.de):
X     o  added -hide and -show option of Filip Sawicki LAKE (fs@uwasa.fi)
X	(as posted in comp.sources.x Volume8, Issue 7) to hide (unmap)
X	the empty mailbox window.
E!O!F! CHANGES
echo Imakefile 1>&2
sed -e 's/^X//' > Imakefile <<'E!O!F! Imakefile'
X       DEFINES  = -DSUNOS4_1
X       INCLUDES = $(TOP_INCLUDES) -I/usr/demo/SOUND
X        DEPLIBS = XawClientDepLibs
XLOCAL_LIBRARIES = XawClientLibs
X  SYS_LIBRARIES = -L/usr/demo/SOUND -laudio -lm
X#ifdef SparcArchitecture
X           SRCS = xbiff.c play.c SSMailbox.c libst.c libsst.c regexp.c regsub.c strtoken.c strsep.c
X           OBJS = xbiff.o play.o SSMailbox.o libst.o libsst.o regexp.o regsub.o strtoken.o strsep.o
X#else
X           SRCS = xbiff.c SSMailbox.c 
X           OBJS = xbiff.o SSMailbox.o
X#endif
X	DEFINES = -DSHAPE
X
XComplexProgramTarget(xbiff)
E!O!F! Imakefile
echo Makefile 1>&2
sed -e 's/^X//' > Makefile <<'E!O!F! Makefile'
X# Makefile generated by imake - do not edit!
X# $XConsortium: imake.c,v 1.51 89/12/12 12:37:30 jim Exp $
X#
X# The cpp used on this machine replaces all newlines and multiple tabs and
X# spaces in a macro expansion with a single space.  Imake tries to compensate
X# for this, but is not always successful.
X#
X
X###########################################################################
X# Makefile generated from "Imake.tmpl" and <Imakefile>
X# $XConsortium: Imake.tmpl,v 1.77 89/12/18 17:01:37 jim Exp $
X#
X# Platform-specific parameters may be set in the appropriate .cf
X# configuration files.  Site-wide parameters may be set in the file
X# site.def.  Full rebuilds are recommended if any parameters are changed.
X#
X# If your C preprocessor doesn't define any unique symbols, you'll need
X# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
X# "make Makefile", "make Makefiles", or "make World").
X#
X# If you absolutely can't get imake to work, you'll need to set the
X# variables at the top of each Makefile as well as the dependencies at the
X# bottom (makedepend will do this automatically).
X#
X
X###########################################################################
X# platform-specific configuration parameters - edit sun.cf to change
X
XSYSLIBS=-lXt -lX11
XMWM_DEFINES=-DSHAPE -DOPAQUE
X
X# platform:  $XConsortium: sun.cf,v 1.38 89/12/23 16:10:10 jim Exp $
X# operating system:  SunOS 4.1
X
X###########################################################################
X# site-specific configuration parameters - edit site.def to change
X
X# site:  $XConsortium: site.def,v 1.21 89/12/06 11:46:50 jim Exp $
X
X            SHELL = /bin/sh
X
X              TOP = .
X      CURRENT_DIR = .
X
X               AR = ar cq
X  BOOTSTRAPCFLAGS =
X               CC = cc
X
X         COMPRESS = compress
X              CPP = /lib/cpp $(STD_CPP_DEFINES)
X    PREPROCESSCMD = cc -E $(STD_CPP_DEFINES)
X          INSTALL = install
X               LD = ld
X             LINT = lint
X      LINTLIBFLAG = -C
X         LINTOPTS = -axz
X               LN = ln -s
X             MAKE = make
X               MV = mv
X               CP = cp
X           RANLIB = ranlib
X  RANLIBINSTFLAGS =
X               RM = rm -f
X     STD_INCLUDES =
X  STD_CPP_DEFINES =
X      STD_DEFINES =
X EXTRA_LOAD_FLAGS =
X  EXTRA_LIBRARIES =
X             TAGS = ctags
X
X    SHAREDCODEDEF = -DSHAREDCODE
X         SHLIBDEF = -DSUNSHLIB
X
X    PROTO_DEFINES =
X
X     INSTPGMFLAGS =
X
X     INSTBINFLAGS = -m 0755
X     INSTUIDFLAGS = -m 4755
X     INSTLIBFLAGS = -m 0664
X     INSTINCFLAGS = -m 0444
X     INSTMANFLAGS = -m 0444
X     INSTDATFLAGS = -m 0444
X    INSTKMEMFLAGS = -m 4755
X
X          DESTDIR =
X
X     TOP_INCLUDES = -I$(INCROOT)
X
X      CDEBUGFLAGS = -O
X        CCOPTIONS = -DSUNOS4_1 -D_NO_PROTO -DSTRINGS_ALIGNED -DNO_REGEX -DNO_ISDIR -DUSE_RE_COMP -DUSE_GETWD
X      COMPATFLAGS =
X
X      ALLINCLUDES = $(STD_INCLUDES) $(TOP_INCLUDES) $(INCLUDES) $(EXTRA_INCLUDES)
X       ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(PROTO_DEFINES) $(DEFINES) $(COMPATFLAGS)
X           CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
X        LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
X           LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
X        LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS)
X   LDCOMBINEFLAGS = -X -r
X
X        MACROFILE = sun.cf
X           RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
X
X    IMAKE_DEFINES =
X
X         IRULESRC = $(CONFIGDIR)
X        IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)
X
X     ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
X			$(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
X			$(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
X
X###########################################################################
X# X Window System Build Parameters
X# $XConsortium: Project.tmpl,v 1.63 89/12/18 16:46:44 jim Exp $
X
X###########################################################################
X# X Window System make variables; this need to be coordinated with rules
X# $XConsortium: Project.tmpl,v 1.63 89/12/18 16:46:44 jim Exp $
X
X          PATHSEP = /
X        USRLIBDIR = $(DESTDIR)/usr/lib
X           BINDIR = $(DESTDIR)/usr/bin/X11
X          INCROOT = $(DESTDIR)/usr/include
X     BUILDINCROOT = $(TOP)
X      BUILDINCDIR = $(BUILDINCROOT)/X11
X      BUILDINCTOP = ..
X           INCDIR = $(INCROOT)/X11
X           ADMDIR = $(DESTDIR)/usr/adm
X           LIBDIR = $(USRLIBDIR)/X11
X        CONFIGDIR = $(LIBDIR)/config
X       LINTLIBDIR = $(USRLIBDIR)/lint
X
X          FONTDIR = $(LIBDIR)/fonts
X         XINITDIR = $(LIBDIR)/xinit
X           XDMDIR = $(LIBDIR)/xdm
X           AWMDIR = $(LIBDIR)/awm
X           TWMDIR = $(LIBDIR)/twm
X           GWMDIR = $(LIBDIR)/gwm
X          MANPATH = $(DESTDIR)/usr/man
X    MANSOURCEPATH = $(MANPATH)/man
X           MANDIR = $(MANSOURCEPATH)n
X        LIBMANDIR = $(MANSOURCEPATH)3
X      XAPPLOADDIR = $(LIBDIR)/app-defaults
X
X        SOXLIBREV = 4.2
X          SOXTREV = 4.0
X         SOXAWREV = 4.0
X        SOOLDXREV = 4.0
X         SOXMUREV = 4.0
X        SOXEXTREV = 4.0
X
X       FONTCFLAGS = -t
X
X     INSTAPPFLAGS = $(INSTDATFLAGS)
X
X            IMAKE = imake
X           DEPEND = makedepend
X              RGB = rgb
X            FONTC = bdftosnf
X        MKFONTDIR = mkfontdir
X        MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier.sh
X
X        CONFIGSRC = $(TOP)/config
X        CLIENTSRC = $(TOP)/clients
X          DEMOSRC = $(TOP)/demos
X           LIBSRC = $(TOP)/lib
X          FONTSRC = $(TOP)/fonts
X       INCLUDESRC = $(TOP)/X11
X        SERVERSRC = $(TOP)/server
X          UTILSRC = $(TOP)/util
X        SCRIPTSRC = $(UTILSRC)/scripts
X       EXAMPLESRC = $(TOP)/examples
X       CONTRIBSRC = $(TOP)/../contrib
X           DOCSRC = $(TOP)/doc
X           RGBSRC = $(TOP)/rgb
X        DEPENDSRC = $(UTILSRC)/makedepend
X         IMAKESRC = $(CONFIGSRC)
X         XAUTHSRC = $(LIBSRC)/Xau
X          XLIBSRC = $(LIBSRC)/X
X           XMUSRC = $(LIBSRC)/Xmu
X       TOOLKITSRC = $(LIBSRC)/Xt
X       AWIDGETSRC = $(LIBSRC)/Xaw
X       OLDXLIBSRC = $(LIBSRC)/oldX
X      XDMCPLIBSRC = $(LIBSRC)/Xdmcp
X      BDFTOSNFSRC = $(FONTSRC)/bdftosnf
X     MKFONTDIRSRC = $(FONTSRC)/mkfontdir
X     EXTENSIONSRC = $(TOP)/extensions
X
X  DEPEXTENSIONLIB = $(USRLIBDIR)/libXext.a
X     EXTENSIONLIB =  -lXext
X
X          DEPXLIB = $(DEPEXTENSIONLIB)
X             XLIB = $(EXTENSIONLIB) -lX11
X
X      DEPXAUTHLIB = $(USRLIBDIR)/libXau.a
X         XAUTHLIB =  -lXau
X
X        DEPXMULIB =
X           XMULIB = -lXmu
X
X       DEPOLDXLIB =
X          OLDXLIB = -loldX
X
X      DEPXTOOLLIB =
X         XTOOLLIB = -lXt
X
X        DEPXAWLIB =
X           XAWLIB = -lXaw
X
X LINTEXTENSIONLIB = $(USRLIBDIR)/llib-lXext.ln
X         LINTXLIB = $(USRLIBDIR)/llib-lX11.ln
X          LINTXMU = $(USRLIBDIR)/llib-lXmu.ln
X        LINTXTOOL = $(USRLIBDIR)/llib-lXt.ln
X          LINTXAW = $(USRLIBDIR)/llib-lXaw.ln
X
X          DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
X
X         DEPLIBS1 = $(DEPLIBS)
X         DEPLIBS2 = $(DEPLIBS)
X         DEPLIBS3 = $(DEPLIBS)
X
X      USRINCDIR = $(DESTDIR)/usr/include
X        TESTSRC = $(TOP)/tests
X    MTOOLKITSRC = $(LIBSRC)/Xt
X     MWIDGETSRC = $(LIBSRC)/Xm
X   MRESOURCESRC = $(LIBSRC)/Mrm
X         UILSRC = $(CLIENTSRC)/uil
X
X            UIL = uil
X
X          DEPLIBS =
X
X         DEPLIBS1 = $(DEPLIBS)
X         DEPLIBS2 = $(DEPLIBS)
X         DEPLIBS3 = $(DEPLIBS)
X
X          SOXMREV = 1.1
X         SOMRMREV = 1.1
X
X       DEPXMLIB =
X          XMLIB = -lXm
X
XDEPMRESOURCELIB =
X   MRESOURCELIB = -lMrm
X
X      DEPUILLIB = $(USRLIBDIR)/libUil.a
X         UILLIB =  -lUil
X  LINTMRESOURCE = $(USRLIBDIR)/llib-lMrm.ln
XLINTXMWIDGETLIB = $(USRLIBDIR)/llib-lXm.ln
X     LINTUILLIB = $(USRLIBDIR)/llib-lUil.ln
X
X###########################################################################
X# Imake rules for building libraries, programs, scripts, and data files
X# rules:  $XConsortium: Imake.rules,v 1.67 89/12/18 17:14:15 jim Exp $
X
X###########################################################################
X# start of Imakefile
X
X       DEFINES  = -DSUNOS4_1
X       INCLUDES = $(TOP_INCLUDES) -I/usr/demo/SOUND
X        DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
XLOCAL_LIBRARIES = $(XAWLIB) $(XMULIB) $(XTOOLLIB) $(XLIB)
X  SYS_LIBRARIES = -L/usr/demo/SOUND -laudio -lm
X
X           SRCS = xbiff.c play.c SSMailbox.c libst.c libsst.c regexp.c regsub.c strtoken.c strsep.c
X           OBJS = xbiff.o play.o SSMailbox.o libst.o libsst.o regexp.o regsub.o strtoken.o strsep.o
X
X	DEFINES = -DSHAPE
X
X PROGRAM = xbiff
X
Xall:: xbiff
X
Xxbiff: $(OBJS) $(DEPLIBS)
X	$(RM) $@
X	$(CC) -o $@ $(OBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOAD_FLAGS)
X
Xinstall:: xbiff
X	$(INSTALL) -c $(INSTPGMFLAGS)   xbiff $(BINDIR)
X
Xinstall.man:: xbiff.man
X	$(INSTALL) -c $(INSTMANFLAGS) xbiff.man $(MANDIR)/xbiff.n
X
Xdepend::
X	$(DEPEND) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)
X
Xlint:
X	$(LINT) $(LINTFLAGS) $(SRCS) $(LINTLIBS)
Xlint1:
X	$(LINT) $(LINTFLAGS) $(FILE) $(LINTLIBS)
X
Xclean::
X	$(RM) $(PROGRAM)
X
X###########################################################################
X# common rules for all Makefiles - do not edit
X
Xemptyrule::
X
Xclean::
X	$(RM_CMD) \#*
X
XMakefile::
X	-@if [ -f Makefile ]; then \
X	echo "	$(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \
X	$(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
X	else exit 0; fi
X	$(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
X
Xtags::
X	$(TAGS) -w *.[ch]
X	$(TAGS) -xw *.[ch] > TAGS
X
X###########################################################################
X# empty rules for directories that do not have SUBDIRS - do not edit
X
Xinstall::
X	@echo "install in $(CURRENT_DIR) done"
X
Xinstall.man::
X	@echo "install.man in $(CURRENT_DIR) done"
X
XMakefiles::
X
Xincludes::
X
X###########################################################################
X# dependencies generated by makedepend
X
E!O!F! Makefile
echo README 1>&2
sed -e 's/^X//' > README <<'E!O!F! README'
XThis is an enhanced version of the X11 R4 xbiff. The major
Xenhancement is the support for playing sounds on the Sun
XSPARCstation. A minor enhancement is how it checks for new mail.
XThe old version just checked to see if the size had changed. This
Xversion actually scans the mail file and determines which
Xmessages have not been read (by looking for "Status:" lines in
Xthe headers.) 
X
XSound support is provided in two flavors. First you can specify a
Xlist of bindings of sounds to patterns. The patterns are matched
Xagainst lines in the message headers and if a match is made, the
Xcorresponding sound is played (given that the message is new).
XSecond, a default sound can be given which is played for each
Xmessage that doesn't match a sound binding pattern. In the
Xsimplest case, the default sound can be used to replace the beep
Xsound played by the old version of xbiff. 
X
XThe format of sound bindings is given in the man page. Simply
Xput, it is a string made up of comma separated substrings. Each
Xsubstring specifies a binding. A binding is a pattern and sound
Xpair, separated by a vertical bar ('|'). Here's an example
Xresource specification illustrating the binding format.
X
X! xbiff
X!
Xxbiff.Geometry: 48x48+1032+6
Xxbiff*showTitle: off
Xxbiff*shapeWindow: on
Xxbiff*fullPixmap:/home/kong/wagner/X/bitmaps/mailbox_full.xbm
Xxbiff*fullPixmapMask:/home/kong/wagner/X/bitmaps/mailbox_full_msk.xbm
Xxbiff*emptyPixmap:/home/kong/wagner/X/bitmaps/mailbox_empty.xbm
Xxbiff*emptyPixmapMask:/home/kong/wagner/X/bitmaps/mailbox_empty_msk.xbm
Xxbiff*sound:/home/kong/wagner/sound/new/OhmyGod.au
Xxbiff*soundBindings:\
XFrom:.*wagner|/home/kong/wagner/sound/Musical/Flourish6.au,\
XFrom:.*jcc|/home/kong/wagner/sound/Beeps/jazz_piano_beep.au,\
XFrom:.*root|/home/kong/wagner/sound/Misc/EvilLaugh.au,\
XFrom:.*Mailer-Daemon|/home/kong/wagner/sound/Misc/Moron.au,\
XSubject:.*Homebrew.*|/home/kong/wagner/sound/SFX/Slurp.au
Xxbiff*volume:50
X
XNote that the "xbiff*soundBindings" resource uses escaped
Xnewlines for readability. Also, xbiff uses Henry Spencer's
Xregular expression package for the patterns. See the included man
Xpage for a description of the regular expression syntax
Xsupported.
X
X--
XMike Wagner
Xwagner@cadillac.siemens.com
XApr. 11, 1990
X
X===============================================================================
XI added the hide-show option of Filip Sawicki LAKE (fs@uwasa.fi) to this.
XHere is his README:
X-----
X  Here is my next small contribution. This time I modified Mailbox
XWidget and xbiff to hide (unmap) window on empty mailbox -- I really
Xhate useless stuff hanging on my screen.
X
X  New resource for Mailbox
X        "hideEmpty" (Boolean), default value: false
Xcontrols hiding of the empty Mailbox. With the value of false, new
XMailbox is exactly the old one: new parts of code are skipped.
X
X  New command line options for xbiff:
X        -hide - hide empty Mailbox
X        -show - always show Mailbox (works just like an old xbiff)
X
X  These modifications were made long time ago for X11R3, and now I
Xported them to X11R4. Everything works well, but, at least under TWM,
Xit's a good idea to set mailbox position with -geometry (check why).
XMapped window immediately gets lowered -- I had to do that to avoid
Xxbiff showing itself on top of xlock (and burning screen).
X
X  One possible drawback of this version is that the modified Mailbox
Xcannot be used within a bigger program with hideEmpty option set on:
Xinstead of hiding it's own window, Mailbox simply unmaps its top-level
Xancestor.
X-----
XMatthias Pfuetzner
Xpfuetz@agd.fhg.de
E!O!F! README
echo README.NEW 1>&2
sed -e 's/^X//' > README.NEW <<'E!O!F! README.NEW'
XThis is a slightly enhanced  version of xbiff-audio  (from Mike Wagner
X[wagner@cadillac.siemens.com]).  I simply added   the -hide and  -show
Xoptions   of  Filip    Sawicki    LAKE  <fs@uwasa.fi>   as  posted  in
Xcomp.sources.x, Volume 8, Issue 7.
X
XRead README for more details.
X
XMatthias Pfuetzner
Xpfuetzner@agd.fhg.de
XJan. 25, 1991
E!O!F! README.NEW
echo SSMailbox.c 1>&2
sed -e 's/^X//' > SSMailbox.c <<'E!O!F! SSMailbox.c'
X/*
X * $XConsortium: SSMailbox.c,v 1.35 89/10/09 16:51:44 jim Exp $
X *
X * Copyright 1988 Massachusetts Institute of Technology
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted, provided
X * that the above copyright notice appear in all copies and that both that
X * copyright notice and this permission notice appear in supporting
X * documentation, and that the name of M.I.T. not be used in advertising or
X * publicity pertaining to distribution of the software without specific,
X * written prior permission.  M.I.T. makes no representations about the
X * suitability of this software for any purpose.  It is provided "as is"
X * without express or implied warranty.
X *
X * Author:  Jim Fulton, MIT X Consortium
X *
X * I recommend that you use the new mailfull and mailempty bitmaps instead of
X * the ugly mailboxes:
X *
X *         XBiff*fullPixmap:  mailfull
X *         XBiff*emptyPixmap:  mailempty
X */
X
X#include <stdio.h>			/* for printing error messages */
X#include <pwd.h>			/* for getting username */
X
X#include <X11/cursorfont.h>		/* for cursor constants */
X#include <X11/StringDefs.h>		/* for useful atom names */
X#include <X11/IntrinsicP.h>		/* for toolkit stuff */
X#include <sys/stat.h>			/* for stat() ** needs types.h ***/
X
X#include <X11/bitmaps/mailfull>		/* for flag up (mail present) bits */
X#include <X11/bitmaps/mailempty>	/* for flag down (mail not here) */
X
X#include <X11/Xaw/XawInit.h>
X#include "SSMailboxP.h"			/* for implementation mailbox stuff */
X
X#include <X11/Xmu/Converters.h>		/* for XmuCvtStringToBitmap */
X
X#ifdef SHAPE
X#include <X11/extensions/shape.h>
X#endif
X
X#include "strtok.h"
X
X/*
X * The default user interface is to have the mailbox turn itself off whenever
X * the user presses a button in it.  Expert users might want to make this 
X * happen on EnterWindow.  It might be nice to provide support for some sort of
X * exit callback so that you can do things like press q to quit.
X */
X
Xstatic char defaultTranslations[] = 
X  "<Btn1Down>:  unset()\n\
X   <Btn3Down>:  review()";
X
Xstatic void Check(), Set(), Unset(), Review();
X
Xstatic XtActionsRec actionsList[] = { 
X    { "check",	Check },
X    { "unset",	Unset },
X    { "set",	Set },
X    { "review", Review },
X};
X
X
X/* Initialization of defaults */
X
X#define offset(field) XtOffset(SSMailboxWidget,ssmailbox.field)
X#define goffset(field) XtOffset(Widget,core.field)
X
Xstatic Dimension defDim = 48;
Xstatic Pixmap nopix = None;
X
Xstatic XtResource resources[] = {
X    { XtNwidth, XtCWidth, XtRDimension, sizeof (Dimension), 
X	goffset (width), XtRDimension, (caddr_t)&defDim },
X    { XtNheight, XtCHeight, XtRDimension, sizeof (Dimension),
X	goffset (height), XtRDimension, (caddr_t)&defDim },
X    { XtNupdate, XtCInterval, XtRInt, sizeof (int),
X	offset (update), XtRString, "30" },
X    { XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel),
X	offset (foreground_pixel), XtRString, "black" },
X    { XtNbackground, XtCBackground, XtRPixel, sizeof (Pixel),
X	goffset (background_pixel), XtRString, "white" },
X    { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
X	offset (reverseVideo), XtRString, "FALSE" },
X    { XtNfile, XtCFile, XtRString, sizeof (String),
X	offset (filename), XtRString, NULL },
X    { XtNcheckCommand, XtCCheckCommand, XtRString, sizeof(char*),
X	offset (check_command), XtRString, NULL},
X    { XtNvolume, XtCVolume, XtRInt, sizeof(int),
X	offset (volume), XtRString, "50"},
X    { XtNonceOnly, XtCBoolean, XtRBoolean, sizeof(Boolean),
X	offset (once_only), XtRImmediate, (caddr_t)False },
X    { XtNfullPixmap, XtCPixmap, XtRBitmap, sizeof(Pixmap),
X	offset (full.bitmap), XtRString, "flagup" },
X    { XtNfullPixmapMask, XtCPixmapMask, XtRBitmap, sizeof(Pixmap),
X	offset (full.mask), XtRBitmap, (caddr_t) &nopix },
X    { XtNemptyPixmap, XtCPixmap, XtRBitmap, sizeof(Pixmap),
X	offset (empty.bitmap), XtRString, "flagdown" },
X    { XtNemptyPixmapMask, XtCPixmapMask, XtRBitmap, sizeof(Pixmap),
X	offset (empty.mask), XtRBitmap, (caddr_t) &nopix },
X    { XtNflip, XtCFlip, XtRBoolean, sizeof(Boolean),
X	offset (flipit), XtRString, "true" },
X    { XtNhideEmpty, XtCBoolean, XtRBoolean, sizeof(Boolean),
X        offset(hide_empty), XtRImmediate, (caddr_t)False },
X#ifdef SHAPE
X    { XtNshapeWindow, XtCShapeWindow, XtRBoolean, sizeof(Boolean),
X        offset (shapeit), XtRString, "false" },
X#endif
X    { XtNsound, XtCSound, XtRString, sizeof (String),
X	offset (sound), XtRString, NULL },
X    { XtNsoundBindings, XtCSoundBindings, XtRString, sizeof (String),
X	offset (sound_bindings), XtRString, NULL },
X};
X
X#undef offset
X#undef goffset
X
Xstatic void GetMailFile(), CloseDown();
Xstatic void check_ssmailbox(), redraw_ssmailbox(), beep();
Xstatic void ClassInitialize(), Initialize(), Realize(), Destroy(), Redisplay();
Xstatic Boolean SetValues();
X
XSSMailboxClassRec ssmailboxClassRec = {
X    { /* core fields */
X    /* superclass		*/	&widgetClassRec,
X    /* class_name		*/	"SSMailbox",
X    /* widget_size		*/	sizeof(SSMailboxRec),
X    /* class_initialize		*/	ClassInitialize,
X    /* class_part_initialize	*/	NULL,
X    /* class_inited		*/	FALSE,
X    /* initialize		*/	Initialize,
X    /* initialize_hook		*/	NULL,
X    /* realize			*/	Realize,
X    /* actions			*/	actionsList,
X    /* num_actions		*/	XtNumber(actionsList),
X    /* resources		*/	resources,
X    /* resource_count		*/	XtNumber(resources),
X    /* xrm_class		*/	NULL,
X    /* compress_motion		*/	TRUE,
X    /* compress_exposure	*/	TRUE,
X    /* compress_enterleave	*/	TRUE,
X    /* visible_interest		*/	FALSE,
X    /* destroy			*/	Destroy,
X    /* resize			*/	NULL,
X    /* expose			*/	Redisplay,
X    /* set_values		*/	SetValues,
X    /* set_values_hook		*/	NULL,
X    /* set_values_almost	*/	XtInheritSetValuesAlmost,
X    /* get_values_hook		*/	NULL,
X    /* accept_focus		*/	NULL,
X    /* version			*/	XtVersion,
X    /* callback_private		*/	NULL,
X    /* tm_table			*/	defaultTranslations,
X    /* query_geometry		*/	XtInheritQueryGeometry,
X    /* display_accelerator	*/	XtInheritDisplayAccelerator,
X    /* extension		*/	NULL
X    }
X};
X
Xstruct SoundStruct 
X{
X    char *sound;
X    struct SoundStruct *next;
X};
X
Xstruct MsgStruct 
X{
X    struct SoundStruct *sounds;
X    struct MsgStruct *next;
X};
X
XWidgetClass ssmailboxWidgetClass = (WidgetClass) &ssmailboxClassRec;
X
X/*
X * widget initialization
X */
X
Xstatic void ClassInitialize ()
X{
X    static XtConvertArgRec screenConvertArg[] = {
X    { XtWidgetBaseOffset, (caddr_t) XtOffset(Widget, core.screen), sizeof(Screen *) }
X    };
X
X    XawInitializeWidgetSet();
X    XtAddConverter (XtRString, XtRBitmap, XmuCvtStringToBitmap,
X		    screenConvertArg, XtNumber(screenConvertArg));
X    return;
X}
X
Xstatic GC get_ssmailbox_gc (w)
X    SSMailboxWidget w;
X{
X    XtGCMask valuemask;
X    XGCValues xgcv;
X
X    valuemask = GCForeground | GCBackground | GCFunction | GCGraphicsExposures;
X    xgcv.foreground = w->ssmailbox.foreground_pixel;
X    xgcv.background = w->core.background_pixel;
X    xgcv.function = GXcopy;
X    xgcv.graphics_exposures = False;	/* this is Bool, not Boolean */
X    return (XtGetGC ((Widget) w, valuemask, &xgcv));
X}
X
X
X/* ARGSUSED */
Xstatic void Initialize (request, new)
X    Widget request, new;
X{
X    SSMailboxWidget w = (SSMailboxWidget) new;
X#ifdef SHAPE
X    int shape_event_base, shape_error_base;
X#endif
X
X    if (!w->ssmailbox.filename) GetMailFile (w);
X
X    if (w->core.width <= 0) w->core.width = 1;
X    if (w->core.height <= 0) w->core.height = 1;
X
X    if (w->ssmailbox.reverseVideo) {
X	Pixel tmp;
X
X	tmp = w->ssmailbox.foreground_pixel;
X	w->ssmailbox.foreground_pixel = w->core.background_pixel;
X	w->core.background_pixel = tmp;
X    }
X
X#ifdef SHAPE
X    if (w->ssmailbox.shapeit && !XShapeQueryExtension (XtDisplay (w),
X						     &shape_event_base,
X						     &shape_error_base))
X      w->ssmailbox.shapeit = False;
X    w->ssmailbox.shape_cache.mask = None;
X#endif
X
X    w->ssmailbox.gc = get_ssmailbox_gc (w);
X    w->ssmailbox.interval_id = (XtIntervalId) 0;
X    w->ssmailbox.full.pixmap = None;
X    w->ssmailbox.empty.pixmap = None;
X    w->ssmailbox.last_numnew = 0;
X    w->ssmailbox.bindings = 0;
X
X    return;
X}
X
X
X/*
X * action procedures
X */
X
X/*
X * pretend there is new mail; put widget in flagup state
X */
X
X/* ARGSUSED */
Xstatic void Set (gw, event, params, nparams)
X    Widget gw;
X    XEvent *event;
X    String *params;
X    Cardinal *nparams;
X{
X    SSMailboxWidget w = (SSMailboxWidget) gw;
X
X    w->ssmailbox.last_numnew = -1;
X
X    check_ssmailbox (w, TRUE, FALSE);	/* redraw, no reset */
X
X    return;
X}
X
X
X/*
X * ack the existing mail; put widget in flagdown state
X */
X
X/* ARGSUSED */
Xstatic void Unset (gw, event, params, nparams)
X    Widget gw;
X    XEvent *event;
X    String *params;
X    Cardinal *nparams;
X{
X    SSMailboxWidget w = (SSMailboxWidget) gw;
X
X    check_ssmailbox (w, TRUE, TRUE);	/* redraw, reset */
X
X    return;
X}
X
X/*
X * pretend all mail is new; review sounds
X */
X
X/* ARGSUSED */
Xstatic void Review (gw, event, params, nparams)
X    Widget gw;
X    XEvent *event;
X    String *params;
X    Cardinal *nparams;
X{
X    SSMailboxWidget w = (SSMailboxWidget) gw;
X
X    w->ssmailbox.last_numnew = 0;
X    check_ssmailbox (w, TRUE, FALSE);	/* redraw, reset */
X
X    return;
X}
X
X
X/*
X * look to see if there is new mail; if so, Set, else Unset
X */
X
X/* ARGSUSED */
Xstatic void Check (gw, event, params, nparams)
X    Widget gw;
X    XEvent *event;
X    String *params;
X    Cardinal *nparams;
X{
X    SSMailboxWidget w = (SSMailboxWidget) gw;
X
X    check_ssmailbox (w, TRUE, FALSE);	/* redraw, no reset */
X
X    return;
X}
X
X
X/* ARGSUSED */
Xstatic void clock_tic (client_data, id)
X    caddr_t client_data;
X    XtIntervalId *id;
X{
X    SSMailboxWidget w = (SSMailboxWidget) client_data;
X
X    check_ssmailbox (w, FALSE, FALSE);	/* no redraw, no reset */
X
X    /*
X     * and reset the timer
X     */
X
X    w->ssmailbox.interval_id = XtAddTimeOut (w->ssmailbox.update * 1000,
X					   clock_tic, (caddr_t) w);
X
X    return;
X}
X
Xstatic Pixmap make_pixmap (dpy, w, bitmap, depth, flip, widthp, heightp)
X    Display *dpy;
X    SSMailboxWidget w;
X    Pixmap bitmap;
X    Boolean flip;
X    int depth;
X    int *widthp, *heightp;
X{
X    Window root;
X    int x, y;
X    unsigned int width, height, bw, dep;
X    unsigned long fore, back;
X
X    if (!XGetGeometry (dpy, bitmap, &root, &x, &y, &width, &height, &bw, &dep))
X      return None;
X
X    *widthp = (int) width;
X    *heightp = (int) height;
X    if (flip) {
X	fore = w->core.background_pixel;
X	back = w->ssmailbox.foreground_pixel;
X    } else {
X	fore = w->ssmailbox.foreground_pixel;
X	back = w->core.background_pixel;
X    }
X    return XmuCreatePixmapFromBitmap (dpy, w->core.window, bitmap, 
X				      width, height, depth, fore, back);
X}
X
Xstatic void Realize (gw, valuemaskp, attr)
X    Widget gw;
X    XtValueMask *valuemaskp;
X    XSetWindowAttributes *attr;
X{
X    SSMailboxWidget w = (SSMailboxWidget) gw;
X    register Display *dpy = XtDisplay (w);
X    int depth = w->core.depth;
X
X    *valuemaskp |= (CWBitGravity | CWCursor);
X    attr->bit_gravity = ForgetGravity;
X    attr->cursor = XCreateFontCursor (dpy, XC_top_left_arrow);
X
X    XtCreateWindow (gw, InputOutput, (Visual *) CopyFromParent,
X		    *valuemaskp, attr);
X
X    /*
X     * build up the pixmaps that we'll put into the image
X     */
X    if (w->ssmailbox.full.bitmap == None) {
X	w->ssmailbox.full.bitmap = 
X	  XCreateBitmapFromData (dpy, w->core.window, mailfull_bits,
X				 mailfull_width, mailfull_height);
X    }
X    if (w->ssmailbox.empty.bitmap == None) {
X	w->ssmailbox.empty.bitmap =
X	  XCreateBitmapFromData (dpy, w->core.window, mailempty_bits,
X				 mailempty_width, mailempty_height);
X    }
X
X    w->ssmailbox.empty.pixmap = make_pixmap (dpy, w, w->ssmailbox.empty.bitmap,
X					   depth, False,
X					   &w->ssmailbox.empty.width,
X					   &w->ssmailbox.empty.height);
X    w->ssmailbox.full.pixmap = make_pixmap (dpy, w, w->ssmailbox.full.bitmap,
X					  depth, w->ssmailbox.flipit,
X					  &w->ssmailbox.full.width,
X					  &w->ssmailbox.full.height);
X			 
X#ifdef SHAPE
X    if (w->ssmailbox.empty.mask == None && w->ssmailbox.full.mask == None)
X      w->ssmailbox.shapeit = False;
X#endif
X
X    w->ssmailbox.interval_id = XtAddTimeOut (w->ssmailbox.update * 1000,
X					   clock_tic, (caddr_t) w);
X
X#ifdef SHAPE
X    w->ssmailbox.shape_cache.mask = None;
X#endif
X
X    if (w->ssmailbox.sound_bindings) 
X    {
X	Bindings *binding;
X	char *pair, *name, *sound;
X	
X	while (pair=strtoken(&w->ssmailbox.sound_bindings,",",1)) 
X	{
X            name=strtoken(&pair, "|", 1);
X	    if (name) sound=strtoken(&pair, "|", 1);
X	    if (!name || !sound)
X	    {
X		fprintf(stderr, "malformed sound bindings.\n");
X		continue;
X	    }
X	    binding = (Bindings *)malloc(sizeof(Bindings));
X	    binding->sound = sound;
X	    if (binding->pattern = regcomp(name)) 
X	    {
X		binding->next = w->ssmailbox.bindings;
X		w->ssmailbox.bindings = binding;
X	    }
X	}
X    }
X
X    return;
X}
X
X
Xstatic void Destroy (gw)
X    Widget gw;
X{
X    SSMailboxWidget w = (SSMailboxWidget) gw;
X    Display *dpy = XtDisplay (gw);
X
X    XtFree (w->ssmailbox.filename);
X    if (w->ssmailbox.interval_id) XtRemoveTimeOut (w->ssmailbox.interval_id);
X    XtDestroyGC (w->ssmailbox.gc);
X#define freepix(p) if (p) XFreePixmap (dpy, p)
X    freepix (w->ssmailbox.full.bitmap);		/* until cvter does ref cnt */
X    freepix (w->ssmailbox.full.mask);		/* until cvter does ref cnt */
X    freepix (w->ssmailbox.full.pixmap);
X    freepix (w->ssmailbox.empty.bitmap);		/* until cvter does ref cnt */
X    freepix (w->ssmailbox.empty.mask);		/* until cvter does ref cnt */
X    freepix (w->ssmailbox.empty.pixmap);
X#ifdef SHAPE
X    freepix (w->ssmailbox.shape_cache.mask);
X#endif
X#undef freepix
X    return;
X}
X
X
Xstatic void Redisplay (gw)
X    Widget gw;
X{
X    SSMailboxWidget w = (SSMailboxWidget) gw;
X
X    check_ssmailbox (w, TRUE, FALSE);
X}
X
X
Xstatic void check_ssmailbox (w, force_redraw, reset)
X    SSMailboxWidget w;
X    Boolean force_redraw, reset;
X{
X    long numnew = 0;
X    int beepit = 0;
X    struct MsgStruct *sounds = 0;
X
X    if (w->ssmailbox.check_command != NULL) {
X	numnew = system(w->ssmailbox.check_command);
X    }
X    else {
X	numnew = newmsgs(w, &sounds);
X    }
X
X    /*
X     * Now check for changes.  If reset is set then we want to pretent that
X     * there is no mail.  If the mailbox is empty then we want to turn off
X     * the flag.  Otherwise if the mailbox has changed size then we want to
X     * put the flag up.
X     *
X     * The cases are:
X     *    o  forced reset by user                        DOWN
X     *    o  no mailbox or empty (zero-sized) mailbox    DOWN
X     *    o  same size as last time                      no change
X     *    o  bigger than last time                       UP
X     *    o  smaller than last time but non-zero         UP
X     *
X     * The last two cases can be expressed as different from last
X     * time and non-zero.
X     */
X
X    if (reset) {			/* forced reset */
X	w->ssmailbox.flag_up = FALSE;
X	force_redraw = TRUE;
X    } else if (numnew == 0) {
X	w->ssmailbox.flag_up = FALSE;
X	if (w->ssmailbox.last_numnew > 0) force_redraw = TRUE;  /* if change */
X    } else if (numnew <= w->ssmailbox.last_numnew) {	/* less mail than
X							   before */
X	/* do nothing; don't play sounds and don't change icon since
X	   user may have lowered the flag manually. */
X    } else if (numnew > w->ssmailbox.last_numnew) {  /* different size */
X	if (!w->ssmailbox.once_only || !w->ssmailbox.flag_up)
X	    beepit = 1; 
X	w->ssmailbox.flag_up = TRUE;
X	force_redraw = TRUE;
X    } 
X
X    if (force_redraw) redraw_ssmailbox (w);
X    if (beepit) beep(w, sounds, numnew - w->ssmailbox.last_numnew);
X    w->ssmailbox.last_numnew = numnew;
X    while (sounds) 
X    {
X	struct MsgStruct *x;
X	x = sounds->next;
X	while (sounds->sounds) 
X	{
X	    struct SoundStruct *s;
X	    s = sounds->sounds->next;
X	    free(sounds->sounds);
X	    sounds->sounds = s;
X	}
X	free(sounds);
X	sounds = x;
X    }
X    
X    return;
X}
X
X/*
X * get user name for building mailbox
X */
X
Xstatic void GetMailFile (w)
X    SSMailboxWidget w;
X{
X    char *getlogin();
X    char *username;
X
X    username = getlogin ();
X    if (!username) {
X	struct passwd *pw = getpwuid (getuid ());
X
X	if (!pw) {
X	    fprintf (stderr, "%s:  unable to find a username for you.\n",
X		     "Mailbox widget");
X	    CloseDown (w, 1);
X	}
X	username = pw->pw_name;
X    }
X    w->ssmailbox.filename = (String) XtMalloc (strlen (MAILBOX_DIRECTORY) + 1 +
X				   	     strlen (username) + 1);
X    strcpy (w->ssmailbox.filename, MAILBOX_DIRECTORY);
X    strcat (w->ssmailbox.filename, "/");
X    strcat (w->ssmailbox.filename, username);
X    return;
X}
X
Xstatic void CloseDown (w, status)
X    SSMailboxWidget w;
X    int status;
X{
X    Display *dpy = XtDisplay (w);
X
X    XtDestroyWidget (w);
X    XCloseDisplay (dpy);
X    exit (status);
X}
X
X
X/* ARGSUSED */
Xstatic Boolean SetValues (gcurrent, grequest, gnew)
X    Widget gcurrent, grequest, gnew;
X{
X    SSMailboxWidget current = (SSMailboxWidget) gcurrent;
X    SSMailboxWidget new = (SSMailboxWidget) gnew;
X    Boolean redisplay = FALSE;
X
X    if (current->ssmailbox.update != new->ssmailbox.update) {
X	if (current->ssmailbox.interval_id) 
X	  XtRemoveTimeOut (current->ssmailbox.interval_id);
X	new->ssmailbox.interval_id = XtAddTimeOut (new->ssmailbox.update * 1000,
X						 clock_tic,
X						 (caddr_t) gnew);
X    }
X
X    if (current->ssmailbox.foreground_pixel != new->ssmailbox.foreground_pixel ||
X	current->core.background_pixel != new->core.background_pixel) {
X	XtDestroyGC (current->ssmailbox.gc);
X	new->ssmailbox.gc = get_ssmailbox_gc (new);
X	redisplay = TRUE;
X    }
X
X    if (current->ssmailbox.hide_empty != new->ssmailbox.hide_empty &&
X      ! new->ssmailbox.flag_up)
X      redisplay = TRUE;       /* either will hide or show */
X
X    return (redisplay);
X}
X
X
X/*
X * drawing code
X */
X
Xstatic void redraw_ssmailbox (w)
X    SSMailboxWidget w;
X{
X    register Display *dpy = XtDisplay (w);
X    register Window win = XtWindow (w);
X    register int x, y;
X    GC gc = w->ssmailbox.gc;
X    Pixel back = w->core.background_pixel;
X    struct _mbimage *im;
X    Widget par;
X
X    /* center the picture in the window */
X
X    if (w->ssmailbox.flag_up) {		/* paint the "up" position */
X	im = &w->ssmailbox.full;
X	if (w->ssmailbox.flipit) back = w->ssmailbox.foreground_pixel;
X    } else {				/* paint the "down" position */
X	im = &w->ssmailbox.empty;
X    }
X    x = (((int)w->core.width) - im->width) / 2;
X    y = (((int)w->core.height) - im->height) / 2;
X
X    XSetWindowBackground (dpy, win, back);
X    XClearWindow (dpy, win);
X    XCopyArea (dpy, im->pixmap, win, gc, 0, 0, im->width, im->height, x, y);
X
X#ifdef SHAPE
X    /*
X     * XXX - temporary hack; walk up widget tree to find top most parent (which
X     * will be a shell) and mash it to have our shape.  This will be replaced
X     * by a special shell widget.
X     */
X    if (w->ssmailbox.shapeit) {
X	Widget parent;
X
X	for (parent = (Widget) w; XtParent(parent);
X	     parent = XtParent(parent)) {
X	    x += parent->core.x + parent->core.border_width;
X	    y += parent->core.y + parent->core.border_width;
X	}
X
X	if (im->mask != w->ssmailbox.shape_cache.mask ||
X	    x != w->ssmailbox.shape_cache.x || y != w->ssmailbox.shape_cache.y) {
X	    XShapeCombineMask (XtDisplay(parent), XtWindow(parent),
X			       ShapeBounding, x, y, im->mask, ShapeSet);
X	    w->ssmailbox.shape_cache.mask = im->mask;
X	    w->ssmailbox.shape_cache.x = x;
X	    w->ssmailbox.shape_cache.y = y;
X	}
X    }
X#endif
X
X    if (w->ssmailbox.hide_empty) {
X      for (par=(Widget)w; XtParent(par); par = XtParent(par)) ;
X      /* should look for windows, instead */
X      if (w->ssmailbox.flag_up) {
X          XtMapWidget(par);
X          XLowerWindow(XtDisplay(par), XtWindow(par));
X          /* to avoid hanging on top of xlock */
X      }
X      else
X          XtUnmapWidget(par);
X    }
X
X    return;
X}
X
Xstatic void beep (w, sounds, num)
X    SSMailboxWidget w;
X    struct MsgStruct *sounds;
X    int num;
X{
X    struct SoundStruct *ss;
X    
X#ifdef sparc
X    if (sounds)
X	while (sounds && num) 
X	{
X	    ss = sounds->sounds;
X	    while(ss) 
X	    {
X		play_sound(ss->sound, w->ssmailbox.volume);
X		ss = ss->next;
X	    }
X	    sounds = sounds->next;
X	    --num;
X	}
X    else if (w->ssmailbox.sound) 
X	play_sound(w->ssmailbox.sound, w->ssmailbox.volume);
X    else
X#endif
X	XBell (XtDisplay (w), w->ssmailbox.volume);
X    return;
X}
X#define LSIZE 256
X
Xvoid add_sound();
X
Xstatic int newmsgs(w, sounds)
X    SSMailboxWidget w;
X    struct MsgStruct **sounds;
X{
X    char *mbox;
X    FILE *fp;
X    int mcnt, status, numnew, in_header;
X    static char line[LSIZE];
X    Bindings *binding;
X    struct MsgStruct *ms = 0;
X
X    mbox = w->ssmailbox.filename;
X    
X    /* if we can't open the mailbox return 0.
X     */
X    if (!(fp= fopen(mbox, "r")))
X	return 0;
X    
X    /* read in the sender and subject of each letter
X     */
X    mcnt = -1; status = numnew = 0; in_header=1;
X    
X    while ( fgets(line, LSIZE, fp) ) {
X	if (!strncmp(line, "From ", 5)) {
X	    if (!status && mcnt != -1) {
X		numnew++;
X		add_sound(w, sounds, ms, status);
X	    }
X	    ms = 0;
X	    mcnt++;
X	    status = 0;
X	    in_header = 1;
X	} else if (in_header && *line == '\n')
X	    in_header = 0;
X	else if (in_header && (!strncmp(line, "From: ", 6) ||
X			       !strncmp(line, "Cc: ", 4) ||
X			       !strncmp(line, "Subject: ", 4) ||
X			       !strncmp(line, "To: ", 4))) 
X	{
X	    for (binding=w->ssmailbox.bindings; binding; binding = binding->next) 
X		if (regexec(binding->pattern, line)) 
X		{
X		    struct SoundStruct *s;
X		    if (!ms) 
X		    {
X			ms = (struct MsgStruct *)malloc(sizeof(struct
X							       MsgStruct));
X			ms->sounds = 0;
X			ms->next = 0;
X		    }
X		    s = (struct SoundStruct *)malloc(sizeof(struct
X							    SoundStruct));
X		    s->sound = binding->sound;
X		    s->next = ms->sounds;
X		    ms->sounds = s;
X		}
X	}
X	else if (!status && in_header && !strncmp(line, "Status: ", 8))
X	    status = 1;
X    }
X    if (!status && mcnt != -1) {
X	numnew++;
X	add_sound(w, sounds, ms, status);
X    }
X    fclose(fp);
X    return numnew;
X}
X
Xstatic void add_sound(w, sounds, ms, status)
X    SSMailboxWidget w;
X    struct MsgStruct **sounds, *ms;
X    int status;
X{
X    if (!status) 
X    {
X	if (!ms)
X	{
X	    ms = (struct MsgStruct *)malloc(sizeof(struct
X						   MsgStruct));
X	    ms->sounds = (struct SoundStruct *)malloc(sizeof(struct
X							     SoundStruct));
X	    ms->sounds->sound = w->ssmailbox.sound;
X	    ms->sounds->next = 0;
X	}
X	ms->next = *sounds;
X	*sounds = ms;
X    }
X    else if (ms)
X    {
X	while (ms->sounds) 
X	{
X	    struct SoundStruct *x;
X	    x = ms->sounds->next;
X	    free((char *)ms->sounds);
X	    ms->sounds = x;
X	}
X	free((char *)ms);
X    }
X}
X
Xvoid regerror(s)
X    char *s;
X{
X    fprintf(stderr, "regexp(3): %s\n", s);
X}
E!O!F! SSMailbox.c
echo SSMailbox.h 1>&2
sed -e 's/^X//' > SSMailbox.h <<'E!O!F! SSMailbox.h'
X/*
X * $XConsortium: Mailbox.h,v 1.19 89/07/21 01:55:46 kit Exp $
X *
X * Copyright 1988 Massachusetts Institute of Technology
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted, provided
X * that the above copyright notice appear in all copies and that both that
X * copyright notice and this permission notice appear in supporting
X * documentation, and that the name of M.I.T. not be used in advertising or
X * publicity pertaining to distribution of the software without specific,
X * written prior permission.  M.I.T. makes no representations about the
X * suitability of this software for any purpose.  It is provided "as is"
X * without express or implied warranty.
X *
X * Author:  Jim Fulton, MIT X Consortium
X * Audio Mods:    Mike Wagner, Siemens Corporate Research
X */
X
X#ifndef _SSMailbox_h
X#define _SSMailbox_h
X
X/*
X * Mailbox widget; looks a lot like the clock widget, don't it...
X */
X
X/* resource names used by mailbox widget that aren't defined in StringDefs.h */
X
X#define XtNupdate "update"
X
X/* command to exec */
X#define XtNcheckCommand "checkCommand"
X#define XtNonceOnly "onceOnly"
X
X/* Int: volume for bell */
X#define XtNvolume "volume"
X#define XtNfullPixmap "fullPixmap"
X#define XtNfullPixmapMask "fullPixmapMask"
X#define XtNemptyPixmap "emptyPixmap"
X#define XtNemptyPixmapMask "emptyPixmapMask"
X#define XtNflip "flip"
X#define XtNshapeWindow "shapeWindow"
X#define XtNhideEmpty "hideEmpty"
X#define XtNsound "sound"
X#define XtNsoundBindings "soundBindings"
X
X#define XtCCheckCommand "CheckCommand"
X#define XtCVolume "Volume"
X#define XtCPixmapMask "PixmapMask"
X#define XtCFlip "Flip"
X#define XtCShapeWindow "ShapeWindow"
X#define XtCSound "Sound"
X#define XtCSoundBindings "SoundBindings"
X
X
X/* structures */
X
Xtypedef struct _SSMailboxRec *SSMailboxWidget;  /* see SSMailboxP.h */
Xtypedef struct _SSMailboxClassRec *SSMailboxWidgetClass;  /* see SSMailboxP.h */
X
X
Xextern WidgetClass ssmailboxWidgetClass;
X
X#endif /* _SSmailbox_h */
X/* DON'T ADD STUFF AFTER THIS #endif */
E!O!F! SSMailbox.h
echo SSMailboxP.h 1>&2
sed -e 's/^X//' > SSMailboxP.h <<'E!O!F! SSMailboxP.h'
X/*
X * $XConsortium: SSMailboxP.h,v 1.16 89/05/11 01:05:56 kit Exp $
X *
X * Copyright 1988 Massachusetts Institute of Technology
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted, provided
X * that the above copyright notice appear in all copies and that both that
X * copyright notice and this permission notice appear in supporting
X * documentation, and that the name of M.I.T. not be used in advertising or
X * publicity pertaining to distribution of the software without specific,
X * written prior permission.  M.I.T. makes no representations about the
X * suitability of this software for any purpose.  It is provided "as is"
X * without express or implied warranty.
X *
X * Author:  Jim Fulton, MIT X Consortium
X */
X
X#ifndef _SSMailboxP_h
X#define _SSMailboxP_h
X
X#include "SSMailbox.h"
X#include "regexp.h"
X
X
X#ifdef SYSV
X#define MAILBOX_DIRECTORY "/usr/mail"
X#else
X#define MAILBOX_DIRECTORY "/usr/spool/mail"
X#endif
X
Xtypedef struct bindings_struct
X{
X    regexp *pattern;
X    String sound;
X    struct bindings_struct *next;
X} Bindings;
X
Xtypedef struct {			/* new fields for mailbox widget */
X    /* resources */
X    int update;				/* seconds between updates */
X    Pixel foreground_pixel;		/* color index of normal state fg */
X    String filename;			/* filename to watch */
X    String check_command;		/* command to exec for mail check */
X    Boolean reverseVideo;		/* do reverse video? */
X    Boolean flipit;			/* do flip of full pixmap */
X    int volume;				/* bell volume */
X    Boolean once_only;			/* ring bell only once on new mail */
X    /* local state */
X    GC gc;				/* normal GC to use */
X    long last_numnew;			/* last number of new msgs */
X    XtIntervalId interval_id;		/* time between checks */
X    Boolean flag_up;			/* is the flag up? */
X    Boolean hide_empty;                 /* hide empty mailbox ? */
X    struct _mbimage {
X	Pixmap bitmap, mask;		/* depth 1, describing shape */
X	Pixmap pixmap;			/* full depth pixmap */
X	int width, height;		/* geometry of pixmaps */
X    } full, empty;
X#ifdef SHAPE
X    Boolean shapeit;			/* do shape extension */
X    struct {
X	Pixmap mask;
X	int x, y;
X    } shape_cache;			/* last set of info */
X#endif
X    String sound;                        /* name of the sound to play */
X    String sound_bindings;		 /* bindings of sounds to sender names */
X    Bindings *bindings;
X} SSMailboxPart;
X
Xtypedef struct _SSMailboxRec {		/* full instance record */
X    CorePart core;
X    SSMailboxPart ssmailbox;
X} SSMailboxRec;
X
X
Xtypedef struct {			/* new fields for mailbox class */
X    int dummy;				/* stupid C compiler */
X} SSMailboxClassPart;
X
Xtypedef struct _SSMailboxClassRec {	/* full class record declaration */
X    CoreClassPart core_class;
X    SSMailboxClassPart ssmailbox_class;
X} SSMailboxClassRec;
X
Xextern SSMailboxClassRec ssmailboxClassRec;	 /* class pointer */
X
X#endif /* _SSMailboxP_h */
E!O!F! SSMailboxP.h
echo strsep.c 1>&2
sed -e 's/^X//' > strsep.c <<'E!O!F! strsep.c'
X/*
X * Copyright (c) 1989 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley.  The name of the
X * University may not be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#include <string.h>
X#ifdef __ANSI__
X#include <sys/stdc.h>
X#else
X#define const
X#define NULL 0
X#include "strtok.h"
X#endif
X
X#if defined(LIBC_SCCS) && !defined(lint)
Xstatic const char sccsid[] = "%W% (Berkeley) %G%";
X#endif /* LIBC_SCCS and not lint */
X
X/*
X * Get next token from string s (NULL on 2nd, 3rd, etc. calls),
X * where tokens are possibly empty strings separated by any character
X * from delim.  Writes NULs into s to end tokens.  delim need not
X * remain constant from call to call.
X */
Xchar *
Xstrsep(s, delim)
X	char *s;
X	const char *delim;
X{
X	static char *last;
X
X	if (s != NULL)
X		last = s;
X	return (strtoken(&last, delim, 0));
X}
X
E!O!F! strsep.c
echo strtok.c 1>&2
sed -e 's/^X//' > strtok.c <<'E!O!F! strtok.c'
X/*
X * Copyright (c) 1989 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley.  The name of the
X * University may not be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#include <string.h>
X#ifdef __ANSI__
X#include <sys/stdc.h>
X#else
X#include "strtok.h"
X#define const
X#define NULL 0
X#endif
X
X#if defined(LIBC_SCCS) && !defined(lint)
Xstatic const char sccsid[] = "%W% (Berkeley) %G%";
X#endif /* LIBC_SCCS and not lint */
X
X/*
X * Get next token from string s (NULL on 2nd, 3rd, etc. calls),
X * where tokens are nonempty strings separated by runs of
X * chars from delim.  Writes NULs into s to end tokens.  delim need not
X * remain constant from call to call.
X */
Xchar *
Xstrtok(s, delim)
X	char *s;
X	const char *delim;
X{
X	static char *last;
X
X	if (s != NULL)
X		last = s;
X	return (strtoken(&last, delim, 1));
X}
X
E!O!F! strtok.c
echo strtok.h 1>&2
sed -e 's/^X//' > strtok.h <<'E!O!F! strtok.h'
Xextern char *strtok(/* char *s, const char *delim */);
Xextern char *strtoken(/* char **stringp, const char *delim, int skip */);
Xextern char *strsep(/* char *s, const char *delim */);
X
E!O!F! strtok.h
echo strtoken.c 1>&2
sed -e 's/^X//' > strtoken.c <<'E!O!F! strtoken.c'
X/*
X * Copyright (c) 1989 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley.  The name of the
X * University may not be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#include <string.h>
X#ifdef __ANSI__
X#include <sys/stdc.h>
X#else
X#include "strtok.h"
X#define const
X#define NULL 0
X#endif
X
X#if defined(LIBC_SCCS) && !defined(lint)
Xstatic const char sccsid[] = "%W% (Berkeley) %G%";
X#endif /* LIBC_SCCS and not lint */
X
X/*
X * Get next token from string *stringp, where tokens are (possibly empty)
X * strings separated by characters from delim.  Tokens are separated
X * by exactly one delimiter iff the skip parameter is false; otherwise
X * they are separated by runs of characters from delim, because we
X * skip over any initial `delim' characters.
X *
X * Writes NULs into the string at *stringp to end tokens.
X * delim will usually, but need not, remain constant from call to call.
X * On return, *stringp points past the last NUL written (if there might
X * be further tokens), or is NULL (if there are definitely no more tokens).
X *
X * If *stringp is NULL, strtoken returns NULL.
X */
Xchar *
Xstrtoken(stringp, delim, skip)
X	register char **stringp;
X	register const char *delim;
X	int skip;
X{
X	register char *s;
X	register const char *spanp;
X	register int c, sc;
X	char *tok;
X
X	if ((s = *stringp) == NULL)
X		return (NULL);
X
X	if (skip) {
X		/*
X		 * Skip (span) leading delimiters (s += strspn(s, delim)).
X		 */
X	cont:
X		c = *s;
X		for (spanp = delim; (sc = *spanp++) != 0;) {
X			if (c == sc) {
X				s++;
X				goto cont;
X			}
X		}
X		if (c == 0) {		/* no token found */
X			*stringp = NULL;
X			return (NULL);
X		}
X	}
X
X	/*
X	 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
X	 * Note that delim must have one NUL; we stop if we see that, too.
X	 */
X	for (tok = s;;) {
X		c = *s++;
X		spanp = delim;
X		do {
X			if ((sc = *spanp++) == c) {
X				if (c == 0)
X					s = NULL;
X				else
X					s[-1] = 0;
X				*stringp = s;
X				return (tok);
X			}
X		} while (sc != 0);
X	}
X	/* NOTREACHED */
X}
E!O!F! strtoken.c
echo xbiff.c 1>&2
sed -e 's/^X//' > xbiff.c <<'E!O!F! xbiff.c'
X/*
X * $XConsortium: xbiff.c,v 1.15 89/12/12 13:55:33 rws Exp $
X *
X * Copyright 1988 Massachusetts Institute of Technology
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted, provided
X * that the above copyright notice appear in all copies and that both that
X * copyright notice and this permission notice appear in supporting
X * documentation, and that the name of M.I.T. not be used in advertising or
X * publicity pertaining to distribution of the software without specific,
X * written prior permission.  M.I.T. makes no representations about the
X * suitability of this software for any purpose.  It is provided "as is"
X * without express or implied warranty.
X *
X * Author:  Jim Fulton, MIT X Consortium
X */
X
X#include <stdio.h>
X#include <X11/Xatom.h>
X#include <X11/Intrinsic.h>
X#include <X11/StringDefs.h>
X#include "SSMailbox.h"
X#include <X11/Xaw/Cardinals.h>
X
Xextern void exit();
Xstatic void quit();
X
Xchar *ProgramName;
X
Xstatic XrmOptionDescRec options[] = {
X{ "-update", "*ssmailbox.update", XrmoptionSepArg, (caddr_t) NULL },
X{ "-file",   "*ssmailbox.file", XrmoptionSepArg, (caddr_t) NULL },
X{ "-volume", "*ssmailbox.volume", XrmoptionSepArg, (caddr_t) NULL },
X{ "-shape",  "*ssmailbox.shapeWindow", XrmoptionNoArg, (caddr_t) "on" },
X{ "-hide",   "*ssmailbox.hideEmpty",  XrmoptionNoArg, (caddr_t) "true" },
X{ "-show",   "*ssmailbox.hideEmpty",  XrmoptionNoArg, (caddr_t) "false" },
X{ "-sound",  "*ssmailbox.sound", XrmoptionSepArg, (caddr_t) NULL },
X{ "-soundBindings",  "*ssmailbox.sound_bindings", XrmoptionSepArg, (caddr_t) NULL },
X};
X
Xstatic XtActionsRec xbiff_actions[] = {
X    { "quit", quit },
X};
Xstatic Atom wm_delete_window;
X
Xstatic void Usage ()
X{
X    static char *help_message[] = {
X"where options include:",
X"    -display host:dpy              X server to contact",
X"    -geometry geom                 size of mailbox",
X"    -file file                     file to watch",
X"    -update seconds                how often to check for mail",
X"    -volume percentage             how loud to ring the bell or play a sound",
X"    -bg color                      background color",
X"    -fg color                      foreground color",
X"    -rv                            reverse video",
X"    -shape                         shape the window",
X"    -hide                          hide (unmap) empty mailbox",
X"    -show                          always show empty mailbox",
X"    -sound                         sound to play for new mail",
X"    -soundBindings                 bindings of sounds to message header patterns,",
XNULL};
X    char **cpp;
X
X    fprintf (stderr, "usage:  %s [-options ...]\n", ProgramName);
X    for (cpp = help_message; *cpp; cpp++) {
X	fprintf (stderr, "%s\n", *cpp);
X    }
X    fprintf (stderr, "\n");
X    exit (1);
X}
X
X
Xvoid main (argc, argv)
X    int argc;
X    char **argv;
X{
X    Widget toplevel, w;
X
X    ProgramName = argv[0];
X
X    toplevel = XtInitialize ("main", "XBiff", options, XtNumber (options),
X			     &argc, argv);
X    if (argc != 1) Usage ();
X
X    /*
X     * This is a hack so that f.delete will do something useful in this
X     * single-window application.
X     */
X    XtAppAddActions (XtWidgetToApplicationContext(toplevel),
X                     xbiff_actions, XtNumber(xbiff_actions));
X    XtOverrideTranslations(toplevel,
X		   XtParseTranslationTable ("<Message>WM_PROTOCOLS: quit()"));
X
X    w = XtCreateManagedWidget ("ssmailbox", ssmailboxWidgetClass, toplevel,
X			       NULL, 0);
X    XtRealizeWidget (toplevel);
X    wm_delete_window = XInternAtom (XtDisplay(toplevel), "WM_DELETE_WINDOW",
X                                    False);
X    (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel),
X                            &wm_delete_window, 1);
X    XtMainLoop ();
X}
X
Xstatic void quit (w, event, params, num_params)
X    Widget w;
X    XEvent *event;
X    String *params;
X    Cardinal *num_params;
X{
X    if (event->type == ClientMessage &&
X        event->xclient.data.l[0] != wm_delete_window) {
X        XBell (XtDisplay(w), 0);
X        return;
X    }
X    XCloseDisplay (XtDisplay(w));
X    exit (0);
X}
E!O!F! xbiff.c
echo xbiff.man 1>&2
sed -e 's/^X//' > xbiff.man <<'E!O!F! xbiff.man'
X.TH XBIFF 1 "Release 4" "X Version 11"
X.SH NAME
Xxbiff - mailbox flag for X
X.SH SYNOPSIS
X.B xbiff
X[-\fItoolkitoption\fP ...] [-option ...]
X.SH DESCRIPTION
XThe
X.I xbiff
Xprogram displays a little image of a mailbox.  When there is no
Xnew mail, the flag on the mailbox is down.  When mail arrives,
Xthe flag goes up and the mailbox beeps (or optionally plays a
Xsound on the Sun SPARCstation). New mail is defined as messages
Xwithout a "Status:" line in the message header.
XBy default, pressing the left mouse button in the image forces
X\fIxbiff\fP to remember the current size of the mail file as
Xbeing the ``empty'' size and to lower the flag. Pressing the
Xright button causes \fIxbiff\fP to review all new mail (and play
Xany sounds which are appropriate). 
X.PP
XThis program is nothing more than a wrapper around an enhanced
XAthena \fIMailbox\fP widget.
X.SH OPTIONS
X.I Xbiff
Xaccepts all of the standard X Toolkit command line options along with the
Xadditional options listed below:
X.TP 8
X.B \-help
XThis option indicates that a brief summary of the allowed options should be
Xprinted on the standard error.
X.TP 8
X.B \-update \fIseconds\fP
XThis option specifies the frequency in seconds at which \fIxbiff\fP
Xshould update its display.  If the mailbox is obscured and then exposed,
Xit will be updated immediately.  The default is 60 seconds.
X.TP 8
X.B \-file \fIfilename\fP
XThis option specifies the name of the file which should be monitored.  By
Xdefault, it watches /usr/spool/mail/\fIusername\fP, where \fIusername\fP
Xis your login name.
X.TP 8
X.B \-shape
XThis option indicates that the mailbox window should be shaped if masks for
Xthe empty or full images are given.
X.TP 8
X.B \-hide
XThis option indicates that the mailbox window should disappear when the
Xmonitored file is empty.
X.TP 8
X.B \-show
XThis option indicates that the mailbox window should behave as the
Xnormal xbiff client (flug down when empty mailbox).
X.TP 8
X.B \-sound \fIfilename\fP
XThis option specifies a sound to be played when new mail arrives
Xand the message header doesn't match one of the given bindings.
X(Note: sounds only work on the Sun SPARCstation.)
X.TP 8
X.B \-soundBindings \fIbinding-list\fP
XThis option specifies sounds to be played for new messages
Xwhose headers match a given patterns. See the following
Xdescription of the soundBindings resource for the format of the binding-list.
X(Note: sounds only work on the Sun SPARCstation.)
X.TP 8
X.B \-volume \fIpercentage\fP
XThis option specifies how loud the bell should be rung or a sound
Xshould be played when new mail comes in.
X.PP
XThe following standard X Toolkit command line arguments are commonly used with 
X.I xbiff:
X.TP 8
X.B \-display \fIdisplay\fP
XThis option specifies the X server to contact.
X.TP 8
X.B \-geometry \fIgeometry\fP
XThis option specifies the prefered size and position of the mailbox window.
XThe mailbox is 48 pixels wide and 48 pixels high and will be centered in
Xthe window.
X.TP 8
X.B \-bg \fIcolor\fP
XThis option specifies the color to use for the background of the window.  
XThe default is ``white.''
X.TP 8
X.B \-bd \fIcolor\fP
XThis option specifies the color to use for the border of the window.
XThe default is ``black.''
X.TP 8
X.B \-bw \fInumber\fP
XThis option specifies the width in pixels of the border surrounding the window.
X.TP 8
X.B \-fg \fIcolor\fP
XThis option specifies the color to use for the foreground of the window.
XThe default is ``black.''
X.TP 8
X.B \-rv
XThis option indicates that reverse video should be simulated by swapping
Xthe foreground and background colors.
X.TP 8
X.B \-xrm \fIresourcestring\fP
XThis option specifies a resource string to be used.  This is especially
Xuseful for setting resources that do not have separate command line options.
X.SH X DEFAULTS
XThis program uses the 
X.I Mailbox
Xwidget in the X Toolkit.  It understands all of the core resource names and
Xclasses as well as:
X.PP
X.TP 8
X.B checkCommand (\fPclass\fB CheckCommand)
XSpecifies a shell command to be executed to check for new mail rather than
Xscanning \fBfile\fP for new messages.  The specified string value is used as the
Xargument to a \fIsystem\fP(3) call and may therefore contain i/o redirection.
XThe exit status of the command should indicate the number of
Xunread messages pending.
X.TP 8
X.B file (\fPclass\fB File)
XSpecifies the name of the file to monitor.  The default is to watch
X/usr/spool/mail/\fIusername\fP, where \fIusername\fP is your login name.
X.TP 8
X.B onceOnly (\fPclass\fB Boolean)
XSpecifies that the bell is only rung the first time new mail is found
Xand is not rung again until at least one interval has passed with
Xno mail waiting.  The window will continue to indicate the presence
Xof new mail until it has been retrieved.
X.TP 8
X.B width (\fPclass\fB Width)
XSpecifies the width of the mailbox.
X.TP 8
X.B height (\fPclass\fB Height)
XSpecifies the height of the mailbox.
X.TP 8
X.B update (\fPclass\fB Interval)
XSpecifies the frequency in seconds at which the mail should be checked.
X.TP 8
X.B hideEmpty (\fPclass\fB Boolean)
XSpecifies whether the mailbox widget sould be visible when the mailbox
Xis empty ("false") or unvisible ("true").
X.TP 8
X.B sound (\fPclass\fB Sound)
XSpecifies the sound to be played for each new message which
Xdoesn't match one of the current sound bindings (see the
XsoundBindings resource). The value should be the name of the file
Xfor the sound.
X.TP 8
X.B soundBindings (\fPclass\fB SoundBindings)
XSpecifies bindings of specific sound files to patterns which are
Xmatched to lines in the headers of new messages. Currently only
Xthe "From:", "Cc:", "To:", and "Subject:" lines are matched. The value of this
Xresource is a string which is a comma separated list of bindings.
XEach binding is a pattern-sound pair, separated by a vertical bar
X("|"). An example binding string is:
X.br
X.ti +3
X"To:.*SunUsers|/usr/sounds/Flourish6.au,From:.*root|/usr/sounds/evil.au."
X.br
XNote that a "." is used before a wildcard "*". This is required
Xsince the regular expression package used defines "*" to mean
Xzero or more occurences of the previous regular expression.
X.TP 8
X.B volume (\fPclass\fB Volume)
XSpecifies how load the bell should be rung or a sound should be played.
XThe default is 50 percent.
X.TP 8
X.B foreground (\fPclass\fB Foreground)
XSpecifies the color for the foreground.
XThe default is ``black'' since the core default for background is ``white.''
X.TP 8
X.B reverseVideo (\fPclass\fB ReverseVideo)
XSpecifies that the foreground and background should be reversed.
X.TP 8
X.B flip (\fPclass\fB Flip)
XSpecifies whether or not the image that is shown when mail has arrived 
Xshould be inverted.  The default is ``true.''
X.TP 8
X.B fullPixmap (\fPclass\fB Pixmap)
XSpecifies a bitmap to be shown when new mail has arrived.
X.TP 8
X.B emptyPixmap (\fPclass\fB Pixmap)
XSpecifies a bitmap to be shown when no new mail is present.
X.TP 8
X.B shapeWindow (\fPclass\fB ShapeWindow)
XSpecifies whether or not the mailbox window should be shaped to the
Xgiven fullPixmapMask and emptyPixmapMask.
X.TP 8
X.B fullPixmapMask (\fPclass\fB PixmapMask)
XSpecifies a mask for the bitmap to be shown when new mail has arrived.
X.TP 8
X.B emptyPixmapMask (\fPclass\fB PixmapMask)
XSpecifies a mask for the bitmap to be shown when no new mail is present.
X.SH ACTIONS
XThe \fIMailbox\fP widget provides the following actions for use in event
Xtranslations:
X.TP 8
X.B check()
XThis action causes the widget to check for new mail and display the flag
Xappropriately.
X.TP 8
X.B unset()
XThis action causes the widget to lower the flag until new mail comes in.
X.TP 8
X.B set()
XThis action causes the widget to raise the flag until the user resets it.
X.TP 8
X.B review()
XThis action causes the widget to review all unread messages. This
Xincludes playing sounds for these messages.
X.PP
XThe default translation is 
X.sp
X.nf
X        <Btn1Down>:  unset()
X        <Btn3Down>:  review()
X.fi
X.sp
X.SH ENVIRONMENT
X.PP
X.TP 8
X.B DISPLAY
Xto get the default host and display number.
X.TP 8
X.B XENVIRONMENT
Xto get the name of a resource file that overrides the global resources
Xstored in the RESOURCE_MANAGER property.
X.SH "SEE ALSO"
XX(1),
Xxrdb(1),
Xstat(2)
X.SH BUGS
XThe mailbox bitmaps are ugly.
X.SH COPYRIGHT
XCopyright 1988, Massachusetts Institute of Technology.
X.br
XSee \fIX(1)\fP for a full statement of rights and permissions.
X.SH AUTHOR
XJim Fulton, MIT X Consortium
X.br
XAdditional hacks by Ralph Swick, DEC/MIT Project Athena
X.br
XSound hacks by Mike Wagner, Siemens Corporate Research,
XPrinceton, NJ.
X.br
XRegular expression package from Henry Spencer.
X.br
XSPARCstation sound playing by Jef Poskanzer.
X.br
E!O!F! xbiff.man
======= end of part 1 =======
            @work:            | Matthias Pfuetzner  |         @home:
  ZGDV, Wilhelminenstrasse 7  | 6100 Darmstadt, FRG |  Lichtenbergstrasse 73
    +49 6151 155-164 or -101  \    <- Tel.nr. ->    /     +49 6151 75717
   pfuetzner@agd.fhg.de    pfuetzner@zgdvda.UUCP    XBR1YD3U@DDATHD21.BITNET


--
Dan Heller
------------------------------------------------
O'Reilly && Associates 		      Zyrcom Inc
Senior Writer			       President
argv@ora.com			argv@zipcode.com