[comp.sources.x] v10i001: xpbiff -- xbiff with popups, Part01/01

shutoh@uunet.UU.NET (Kazuhiko Shutoh) (10/19/90)

Submitted-by: kddlab!isl.yamaha.co.jp!shutoh@uunet.UU.NET (Kazuhiko Shutoh)
Posting-number: Volume 10, Issue 1
Archive-name: xpbiff/part01

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  Imakefile README arrive.bitmap no.bitmap patchlevel.h
#   xpbiff.c xpbiff.man
# Wrapped by shutoh@uni on Thu Oct 18 09:27:04 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Imakefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Imakefile'\"
else
echo shar: Extracting \"'Imakefile'\" \(855 characters\)
sed "s/^X//" >'Imakefile' <<'END_OF_FILE'
X# SCCS ID : @(#)Imakefile	1.5   10/18/90
X#
X#   Imakefile - Imakefile for xpbiff
X# 
X#   Author: Kazuhiko Shutoh, 1990.
X#
X#   Permission to use, copy, modify and distribute without charge this
X#   software, documentation, images, etc. is granted, provided that this 
X#   comment and the author's name is retained.  The author assumes no 
X#   responsibility for lost sleep as a consequence of use of this software.
X#
X#   Send any comments, bug reports, etc. to: shutoh@isl.yamaha.co.jp or, 
X#   for oversea: shutoh%isl.yamaha.co.jp%kddlab@uunet.uu.net  
X#
X
X
X#	For Slow WorkStation
X#	DEFINES = -DSLOW_MACHINE
X
X#	No cuserid() in library.
X#	DEFINES = -DNO_CUSERID
X
X       INCLUDES = -I$(TOP)/X11
XLOCAL_LIBRARIES = $(XAWLIB) $(XMULIB) $(XTOOLLIB) $(XLIB)
X  SYS_LIBRARIES = -lm
X           SRCS = xpbiff.c
X           OBJS = xpbiff.o
X
XComplexProgramTarget(xpbiff)
X
END_OF_FILE
if test 855 -ne `wc -c <'Imakefile'`; then
    echo shar: \"'Imakefile'\" unpacked with wrong size!
fi
# end of 'Imakefile'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(2165 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X
X
X
X				xpbiff 
X
X
X* Command line options
X
XUsage : xpbiff [Toolkit-Options][-nfg noarrive_bitmap_foreground color]
X                [-nbg noarrive_bitmap_background_color]
X		[-afg arrive_bitmap_foreground_color]
X                [-abg arrive_bitmap_background_color]
X		[-polling_time  time(msec)]
X                [-noraise][-nopopup][-noanimate][-nobell]
X		[-nopopdown][-patchlevel]
X
X-nfg color_name :
X-nbg color_name :
X
X	Picture foreground / background color when still not arrive mail.
X	The default value is black and cyan.
X
X-afg color_name :
X-abg color_name :
X
X	Picture foreground / background color when arrive mail.
X	The default value is yellow and red.
X
X-polling_time  time(msec) :
X
X	Polling /usr/spool/mail interval time.
X	Default time is 15000[msec] = 15 [seconds]
X
X-noraise :
X	Do not raise up xpbiff when arrive mail.
X
X-nopopup :
X	Do not popup sender and subject information.
X
X-noanimate :
X	Do not animate.
X
X-nobell :
X	Do not bell.
X
X-nopopdown :
X	Do not show popdown button on sender information.
X
X-mono:
X	Color coordinates for monochrome server.
X
X-patchlevel :
X	Show current patchlevel and source code version.
X
X
X* Compile
X
X	If you can't uses imake, Please manually compile:
X
X	% cc -o xpbiff xpbiff.c -lXaw -lXmu -lXt -lX11 -lm
X	or
X	% cc -o xpbiff xpbiff.c -lXaw -lXmu -lXt -lX11 -lXext -lm
X
X	If your server is toooo slow animation, Please try
X
X	#	DEFINES = -DSLOW_MACHINE
X
X	in Imakefile, then recompile with Imake.
X	Rotational mail animation become more shortly.
X
X						enjoy!!!
X
X* Comments & suggestion
X
X	Send any comments, bug reports, etc. to: shutoh@isl.yamaha.co.jp or, 
X	for oversea: shutoh%isl.yamaha.co.jp%kddlab@uunet.uu.net  
X
X* Special Thanks to:
X
X	Test :
X
X		Shingo Kawasaki(YAMAHA/ISL)
X
X	Bug report & fix suggestion :
X
X		Hidetsugu Nakashio <naka@soum.co.jp>
X		hkato@krc.sony.co.jp (Hiroshi KATO)
X		hotta@asimov.soft.flab.fujitsu.co.jp 
X		ikawa@onion.osaka.jip.co.jp (Ikawa Hiroki)
X		makimura@agusa.nuee.nagoya-u.ac.jp (Ken Makimura)
X		murase@ctf5.drl.mei.co.jp 
X		nishida@phantom.src.ricoh.co.jp (Akihiro Nishida)
X				
X					Thanks a lot!!!!!!!
X
X--
X						Kazuhiko Shutoh
X						InSoft System Lab.
X						YAMAHA Corp.
X						shutoh@isl.yamama.co.jp
X
X
END_OF_FILE
if test 2165 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'arrive.bitmap' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'arrive.bitmap'\"
else
echo shar: Extracting \"'arrive.bitmap'\" \(1880 characters\)
sed "s/^X//" >'arrive.bitmap' <<'END_OF_FILE'
X#define arrive_width 48
X#define arrive_height 48
Xstatic char arrive_bits[] = {
X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X   0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x1f,
X   0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f,
X   0xfc, 0xea, 0xff, 0xff, 0xff, 0x3f, 0x7c, 0xe0, 0xff, 0xff, 0xff, 0x3f,
X   0x3c, 0xcf, 0xff, 0xff, 0xff, 0x3f, 0x7c, 0xef, 0xff, 0xff, 0xff, 0x3f,
X   0x3c, 0xcf, 0xff, 0xff, 0xff, 0x3f, 0x7c, 0xef, 0xff, 0xff, 0xff, 0x3f,
X   0x3c, 0xcf, 0xff, 0xff, 0xff, 0x3f, 0x7c, 0xe0, 0xff, 0xff, 0xff, 0x3f,
X   0x7c, 0xf5, 0xff, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f,
X   0xfc, 0x7f, 0x61, 0xa9, 0xf0, 0x3f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f,
X   0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xc2, 0x11, 0xfa, 0x3f,
X   0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f,
X   0xfc, 0x7f, 0x41, 0x64, 0xfd, 0x3f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f,
X   0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfc, 0x7f, 0x26, 0xfc, 0xff, 0x3f,
X   0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0xff, 0x15, 0x3f,
X   0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0xff, 0x2a, 0x3f,
X   0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x1f,
X   0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X   0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
X   0xc0, 0x00, 0x00, 0x02, 0x00, 0x1c, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x1c,
X   0x20, 0x91, 0x65, 0x26, 0x72, 0x08, 0x20, 0x51, 0x14, 0x22, 0x8a, 0x08,
X   0xf0, 0x33, 0x0c, 0x22, 0x8a, 0x00, 0x10, 0x32, 0x0c, 0x42, 0x79, 0x08,
X   0x08, 0x14, 0x04, 0x82, 0x08, 0x1c, 0x08, 0x14, 0x04, 0x87, 0xf0, 0x08,
X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
END_OF_FILE
if test 1880 -ne `wc -c <'arrive.bitmap'`; then
    echo shar: \"'arrive.bitmap'\" unpacked with wrong size!
fi
# end of 'arrive.bitmap'
fi
if test -f 'no.bitmap' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'no.bitmap'\"
else
echo shar: Extracting \"'no.bitmap'\" \(1868 characters\)
sed "s/^X//" >'no.bitmap' <<'END_OF_FILE'
X#define no_width 48
X#define no_height 48
Xstatic char no_bits[] = {
X   0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf7, 0x41, 0x44, 0x2f, 0x7a,
X   0xff, 0x07, 0xe0, 0x45, 0x69, 0x0b, 0xff, 0x07, 0x50, 0x44, 0xa9, 0x0a,
X   0xff, 0x03, 0xe0, 0x7c, 0xa9, 0x3a, 0xff, 0x0b, 0x40, 0x45, 0x29, 0x0a,
X   0xff, 0x31, 0xf0, 0x44, 0x29, 0x0a, 0xff, 0xc0, 0x40, 0x44, 0x2f, 0x7a,
X   0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x02, 0x00, 0x00, 0x00, 0xff,
X   0x0f, 0x04, 0x00, 0x00, 0x80, 0xff, 0x00, 0x08, 0x00, 0x00, 0xc0, 0xff,
X   0x22, 0x08, 0x00, 0x00, 0xe0, 0xff, 0x22, 0x00, 0x00, 0x00, 0xf0, 0xff,
X   0x42, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x42, 0x00, 0x00, 0x00, 0xfc, 0xff,
X   0x02, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
X   0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
X   0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
X   0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
X   0x00, 0x00, 0x00, 0x00, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00,
X   0x00, 0x00, 0x80, 0x0f, 0xa4, 0xdf, 0x00, 0x00, 0x40, 0x10, 0xa4, 0x50,
X   0x00, 0x00, 0x40, 0x10, 0xa4, 0x50, 0x00, 0x00, 0x40, 0x17, 0xa4, 0x50,
X   0x00, 0x00, 0x40, 0x10, 0xa4, 0xdf, 0x00, 0x00, 0x40, 0x10, 0x24, 0x00,
X   0x00, 0x00, 0x40, 0x10, 0xa4, 0xdf, 0x00, 0x00, 0x40, 0x10, 0xa4, 0x50,
X   0x00, 0x00, 0xc0, 0x1f, 0xa4, 0x50, 0x00, 0x14, 0x00, 0x02, 0xa4, 0x50,
X   0x50, 0x20, 0x00, 0x02, 0xa4, 0xdf, 0xc8, 0x0a, 0x00, 0x02, 0x24, 0x00,
X   0xac, 0x20, 0x00, 0x02, 0xe4, 0xff, 0x10, 0x0c, 0x00, 0x02, 0x04, 0x00,
X   0xa8, 0x08, 0x00, 0x02, 0x04, 0x00, 0x20, 0x28, 0x00, 0x02, 0x04, 0x00,
X   0x24, 0x1d, 0x00, 0x02, 0x04, 0x00, 0xa8, 0x08, 0x00, 0xc2, 0x0f, 0x00,
X   0x70, 0x7f, 0x00, 0x3e, 0xf0, 0xff, 0xff, 0x81, 0xff, 0x01, 0x00, 0x00,
X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
END_OF_FILE
if test 1868 -ne `wc -c <'no.bitmap'`; then
    echo shar: \"'no.bitmap'\" unpacked with wrong size!
fi
# end of 'no.bitmap'
fi
if test -f 'patchlevel.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'patchlevel.h'\"
else
echo shar: Extracting \"'patchlevel.h'\" \(24 characters\)
sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
X
X#define PATCHLEVEL 0
X
X
END_OF_FILE
if test 24 -ne `wc -c <'patchlevel.h'`; then
    echo shar: \"'patchlevel.h'\" unpacked with wrong size!
fi
# end of 'patchlevel.h'
fi
if test -f 'xpbiff.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xpbiff.c'\"
else
echo shar: Extracting \"'xpbiff.c'\" \(13301 characters\)
sed "s/^X//" >'xpbiff.c' <<'END_OF_FILE'
X
Xstatic char     sccsid[] = "@(#)xpbiff.c	1.15   10/18/90";
X
X/*
X * xpbiff - popup biff for X
X * 
X * Author: Kazuhiko Shutoh, 1990.
X * 
X * Permission to use, copy, modify and distribute without charge this software,
X * documentation, images, etc. is granted, provided that this comment and the
X * author's name is retained.  The author assumes no responsibility for lost
X * sleep as a consequence of use of this software.
X * 
X * Send any comments, bug reports, etc. to: shutoh@isl.yamaha.co.jp or, for
X * oversea: shutoh%isl.yamaha.co.jp%kddlab@uunet.uu.net
X * 
X */
X
X#include <X11/Intrinsic.h>
X#include <X11/StringDefs.h>
X#include <X11/Shell.h>
X#include <X11/Xaw/Box.h>
X#include <X11/Xaw/Label.h>
X#include <X11/Xaw/Command.h>
X#include <X11/Xaw/AsciiText.h>
X#include <X11/Xaw/Cardinals.h>
X#include <X11/Xos.h>
X#include <fcntl.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <stdio.h>
X#include <math.h>
X
X#include "patchlevel.h"
X#include "arrive.bitmap"
X#include "no.bitmap"
X
X#define	PI	3.141592654
X#define	ARRIVE	1
X#define	NO	0
X#ifdef	SLOW_MACHINE
X#define	ROTATION	180	/* For Slow Server */
X#else
X#define	ROTATION	720
X#endif
X
X#define SPOOLPATH	"/usr/spool/mail/"
X
XXtCallbackProc  redraw_callback();
XXtCallbackProc  BreakPopup();
XXtTimerCallbackProc Polling();
Xchar           *GetMailHeader();
Xvoid            PopupMailHeader();
Xvoid            AnimateBiff();
X
X
XWidget          toplevel, biff, header, info_base, info, popdown_button;
X
X/*
X * widget tree:
X * 
X * toplevel --- biff ... header --- info_base ---+--- popdown_button 
X *                                               +--- info
X * 
X */
X
XGC              gcBiff, gcAnimate, gcAnimateBack;
XPixmap          arrivePixmap, noPixmap, workPixmap;
Xint             width, height;
Xunsigned char   current_status;
X
XString          colors[4] = {"dummy_colorname", "dummy_colorname", "dummy_colorname", "dummy_colorname"};
Xchar            spool_path[100];
Xunsigned long   polling_time = 15000;	/* Default 15 second */
X
Xunsigned char   raise = True;
Xunsigned char   animate = True;
Xunsigned char   popup = True;
Xunsigned char   bell = True;
Xunsigned char   popdown = True;
X
Xmain(argc, argv)
X	int             argc;
X	char          **argv;
X{
X
X	Arg             args[10];
X	XtTranslations  newTranslations;
X	static XtActionsRec redrawActions[] = {
X		{"expose", (XtCallbackProc) redraw_callback},
X	};
X
X	static char    *overrideTranslations =
X	"<Expose>:	expose() \n\
X	 <ResReq>:	expose()";
X
X	XColor          backColor, foreColor, dummyColor;
X
X	int             i;
X	int             count;
X
X	XtTimerCallbackProc Polling();
X
X	strcpy(spool_path, SPOOLPATH);
X#ifndef NO_CUSERID
X	strcat(spool_path, cuserid(NULL));
X#else
X	strcat(spool_path, getenv("USER"));
X#endif
X	strcpy(colors[0], "black");
X	strcpy(colors[1], "cyan");
X	strcpy(colors[2], "yellow");
X	strcpy(colors[3], "red");
X
X	toplevel = XtInitialize("xpbiff", "XPbiff", NULL, 0, &argc, argv);
X
X	for (count = 1; count < argc; count++) {
X		if ((strcmp("-nfg", argv[count]) == 0) && (count + 1 <= argc))
X			strcpy(colors[0], argv[++count]);
X		else if ((strcmp("-nbg", argv[count]) == 0) && (count + 1 <= argc))
X			strcpy(colors[1], argv[++count]);
X		else if ((strcmp("-afg", argv[count]) == 0) && (count + 1 <= argc))
X			strcpy(colors[2], argv[++count]);
X		else if ((strcmp("-abg", argv[count]) == 0) && (count + 1 <= argc))
X			strcpy(colors[3], argv[++count]);
X		else if ((strcmp("-polling_time", argv[count]) == 0) && (count + 1 <= argc))
X			polling_time = (unsigned long) atol(argv[++count]);
X		else if ((strcmp("-noraise", argv[count]) == 0) && (count + 1 <= argc))
X			raise = False;
X		else if ((strcmp("-nopopup", argv[count]) == 0) && (count + 1 <= argc))
X			popup = False;
X		else if ((strcmp("-noanimate", argv[count]) == 0) && (count + 1 <= argc))
X			animate = False;
X		else if ((strcmp("-nobell", argv[count]) == 0) && (count + 1 <= argc))
X			bell = False;
X		else if ((strcmp("-nopopdown", argv[count]) == 0) && (count + 1 <= argc))
X			popdown = False;
X		else if ((strcmp("-mono", argv[count]) == 0) && (count + 1 <= argc)) {
X			strcpy(colors[0], "black");
X			strcpy(colors[1], "white");
X			strcpy(colors[2], "white");
X			strcpy(colors[3], "black");
X		} else if ((strcmp("-patchlevel", argv[count]) == 0) && (count + 1 <= argc)) {
X			printf("xpbiff -  written by Kazuhiko Shutoh\nSCCS ID : %s\nPatchlevel : %d\n", sccsid, PATCHLEVEL);
X			exit(0);
X		} else {
X			fprintf(stderr, "Usage : xpbiff [Toolkit-Options][-nfg noarrive_bitmap_foreground color]\n");
X			fprintf(stderr, "		[-nbg noarrive_bitmap_background_color][-afg arrive_bitmap_foreground_color]\n");
X			fprintf(stderr, "		[-abg arrive_bitmap_background_color][-polling_time  time(msec)]\n");
X			fprintf(stderr, "		[-noraise][-nopopup][-noanimate][-nopopdown][-nobell][-mono][-patchlevel]\n");
X			exit(0);
X		}
X	}
X
X	i = 0;
X	XtSetArg(args[i], XtNwidth, arrive_width);
X	i++;
X	XtSetArg(args[i], XtNheight, arrive_height);
X	i++;
X	biff = XtCreateManagedWidget("biff", boxWidgetClass, toplevel, args, i);
X
X	XtAddActions(redrawActions, XtNumber(redrawActions));
X	newTranslations = XtParseTranslationTable(overrideTranslations);
X	XtOverrideTranslations(biff, newTranslations);
X
X	XtRealizeWidget(toplevel);
X
X	/* Get graphic context	 */
X
X	XAllocNamedColor(XtDisplay(toplevel), DefaultColormapOfScreen(XtScreen(toplevel)), colors[0], &foreColor, &dummyColor);
X	XAllocNamedColor(XtDisplay(toplevel), DefaultColormapOfScreen(XtScreen(toplevel)), colors[1], &backColor, &dummyColor);
X	noPixmap = XCreatePixmapFromBitmapData(XtDisplay(toplevel), XtWindow(biff),
X			      no_bits, no_width, no_height, foreColor.pixel,
X		 backColor.pixel, DefaultDepthOfScreen(XtScreen(toplevel)));
X
X	gcBiff = XCreateGC(XtDisplay(toplevel), XtWindow(biff),
X			   (unsigned long) 0, NULL);
X	XSetGraphicsExposures(XtDisplay(toplevel), gcBiff, False);
X	XAllocNamedColor(XtDisplay(toplevel), DefaultColormapOfScreen(XtScreen(toplevel)), colors[2], &foreColor, &dummyColor);
X	XAllocNamedColor(XtDisplay(toplevel), DefaultColormapOfScreen(XtScreen(toplevel)), colors[3], &backColor, &dummyColor);
X	arrivePixmap = XCreatePixmapFromBitmapData(XtDisplay(toplevel), XtWindow(biff),
X		  arrive_bits, arrive_width, arrive_height, foreColor.pixel,
X		 backColor.pixel, DefaultDepthOfScreen(XtScreen(toplevel)));
X
X	workPixmap = XCreatePixmap(XtDisplay(toplevel), XtWindow(biff), arrive_width, arrive_height, DefaultDepthOfScreen(XtScreen(toplevel)));
X
X	gcAnimate = XCreateGC(XtDisplay(toplevel), XtWindow(biff),
X			      (unsigned long) 0, NULL);
X	XSetGraphicsExposures(XtDisplay(toplevel), gcAnimate, False);
X	XSetForeground(XtDisplay(toplevel), gcAnimate, foreColor.pixel);
X
X	gcAnimateBack = XCreateGC(XtDisplay(toplevel), XtWindow(biff),
X				  (unsigned long) 0, NULL);
X	XSetGraphicsExposures(XtDisplay(toplevel), gcAnimateBack, False);
X	XSetForeground(XtDisplay(toplevel), gcAnimateBack, backColor.pixel);
X
X
X
X	/* Interval timer start	 */
X	XtAddTimeOut(polling_time, Polling, NULL);
X
X	XtMainLoop();
X}
X
X
XXtCallbackProc
Xredraw_callback(w, event, params, nparams)
X	Widget          w;
X	XEvent         *event;
X	String         *params;
X	Cardinal       *nparams;
X{
X
X	Arg             args[10];
X
X	XtSetArg(args[0], XtNwidth, 0);
X	XtSetArg(args[1], XtNheight, 0);
X	XtGetValues(w, args, 2);
X
X	width = args[0].value;
X	height = args[1].value;
X
X	if (current_status == ARRIVE) {
X		XCopyArea(XtDisplay(toplevel), arrivePixmap, XtWindow(biff), gcBiff, 0, 0, arrive_width, arrive_height, 0, 0);
X	} else {
X		XCopyArea(XtDisplay(toplevel), noPixmap, XtWindow(biff), gcBiff, 0, 0, arrive_width, arrive_height, 0, 0);
X	}
X}
X
X
XXtTimerCallbackProc
XPolling(client_data, id)
X	caddr_t         client_data;
X	XtIntervalId    id;
X{
X
X	static long     mail_size = 0;
X	struct stat     file_stat;
X	char           *mail_header;
X
X
X	if ((stat(spool_path, &file_stat) == 0) && (file_stat.st_size != 0)) {
X		/* There are Mail */
X
X		if (current_status == NO) {
X			/* NEW mail !! */
X			current_status = ARRIVE;
X			mail_size = file_stat.st_size;
X			if (popup == True)
X				mail_header = GetMailHeader();
X			if (raise == True)
X				XRaiseWindow(XtDisplay(toplevel), XtWindow(toplevel));
X			if (animate == True)
X				AnimateBiff();
X			XCopyArea(XtDisplay(toplevel), arrivePixmap, XtWindow(biff),
X			   gcBiff, 0, 0, arrive_width, arrive_height, 0, 0);
X			if (popup == True)
X				PopupMailHeader(mail_header);
X			XSync(XtDisplay(toplevel), 0);
X			if (bell == True)
X				XBell(XtDisplay(toplevel), 0);
X		} else if (file_stat.st_size > mail_size) {
X			mail_size = file_stat.st_size;
X			if (popup == True)
X				mail_header = GetMailHeader();
X			/* more come! only ringing bell. */
X			if (popup == True)
X				BreakPopup(toplevel, (XtPointer) NULL, (XtPointer) NULL);
X			if (raise == True)
X				XRaiseWindow(XtDisplay(toplevel), XtWindow(toplevel));
X			if (animate == True)
X				AnimateBiff();
X			XCopyArea(XtDisplay(toplevel), arrivePixmap, XtWindow(biff),
X			   gcBiff, 0, 0, arrive_width, arrive_height, 0, 0);
X			if (popup == True)
X				PopupMailHeader(mail_header);
X			XSync(XtDisplay(toplevel), 0);
X			if (bell == True)
X				XBell(XtDisplay(toplevel), 0);
X		} else {
X			mail_size = file_stat.st_size;
X			if (raise == True)
X				XLowerWindow(XtDisplay(toplevel), XtWindow(toplevel));
X			if (popup == True)
X				BreakPopup(toplevel, (XtPointer) NULL, (XtPointer) NULL);
X		}
X	} else
X		/* No mail */
X	if (current_status == ARRIVE) {
X		current_status = NO;
X		XCopyArea(XtDisplay(toplevel), noPixmap, XtWindow(biff), gcBiff, 0, 0,
X			  arrive_width, arrive_height, 0, 0);
X		if (raise == True)
X			XLowerWindow(XtDisplay(toplevel), XtWindow(toplevel));
X		if (popup == True)
X			BreakPopup(toplevel, (XtPointer) NULL, (XtPointer) NULL);
X	}
X	/* No arrive */
X
X	XtAddTimeOut(polling_time, Polling, NULL);
X
X}
X
X
Xvoid
XAnimateBiff()
X{
X
X	XPoint          points[4];
X	double          r, angle, t1, t2, t3, t4;
X
X	for (r = 0, angle = 90; angle < (ROTATION + 90); angle++, r += (double) (arrive_width) / (double) (ROTATION * 2)) {
X
X		t1 = (angle + 40) * PI / 180.0;
X		t2 = (angle + 140) * PI / 180.0;
X		t3 = (angle + 220) * PI / 180.0;
X		t4 = (angle + 320) * PI / 180.0;
X
X		points[0].x = (short) (sin(t1) * r + (double) arrive_width / 2);
X		points[0].y = (short) (cos(t1) * r + (double) arrive_height / 2 - 5);
X		points[1].x = (short) (sin(t2) * r + (double) arrive_width / 2);
X		points[1].y = (short) (cos(t2) * r + (double) arrive_height / 2 - 5);
X		points[2].x = (short) (sin(t3) * r + (double) arrive_width / 2);
X		points[2].y = (short) (cos(t3) * r + (double) arrive_height / 2 - 5);
X		points[3].x = (short) (sin(t4) * r + (double) arrive_width / 2);
X		points[3].y = (short) (cos(t4) * r + (double) arrive_height / 2 - 5);
X
X		XFillRectangle(XtDisplay(toplevel), workPixmap, gcAnimateBack, 0, 0, arrive_width, arrive_height);
X		XFillPolygon(XtDisplay(toplevel), workPixmap, gcAnimate, points, 4, Convex, CoordModeOrigin);
X		XCopyArea(XtDisplay(toplevel), workPixmap, XtWindow(biff), gcAnimate, 0, 0, arrive_width, arrive_height, 0, 0);
X	}
X
X}
X
X
Xvoid
XPopupMailHeader(head)
X	char           *head;
X{
X
X	Arg             args[5];
X	int             arg_count;
X	Position        biff_x, biff_y, root_x, root_y;
X
X	/* Calcurate Relative position -> Root absolute position */
X
X	arg_count = 0;
X	XtSetArg(args[arg_count], XtNwidth, &biff_x);
X	arg_count++;
X	XtSetArg(args[arg_count], XtNheight, &biff_y);
X	arg_count++;
X	XtGetValues(biff, args, arg_count);
X
X	XtTranslateCoords(biff, biff_x, biff_y, &root_x, &root_y);
X
X	/* Create Popup Shell */
X
X	arg_count = 0;
X	XtSetArg(args[arg_count], XtNx, root_x);
X	arg_count++;
X	XtSetArg(args[arg_count], XtNy, root_y);
X	arg_count++;
X
X	header = XtCreatePopupShell("header", transientShellWidgetClass, biff,
X				    args, arg_count);
X
X	info_base = XtCreateManagedWidget("info_base", boxWidgetClass, header, args,
X					  arg_count);
X
X	if (popdown == True) {
X		arg_count = 0;
X		XtSetArg(args[arg_count], XtNlabel, "PopDown");
X		arg_count++;
X		popdown_button = XtCreateManagedWidget("popdown_button", commandWidgetClass, info_base, args,
X						       arg_count);
X		XtAddCallback(popdown_button, XtNcallback, BreakPopup, (XtPointer) NULL);
X	}
X	arg_count = 0;
X	XtSetArg(args[arg_count], XtNlabel, head);
X	arg_count++;
X
X	info = XtCreateManagedWidget("info", labelWidgetClass, info_base, args,
X				     arg_count);
X
X
X	free(head);
X
X	XtPopup(header, XtGrabExclusive);
X}
X
X
Xchar           *
XGetMailHeader()
X{
X
X	struct stat     status;
X	int             fd;
X	char           *mail_header, *mail_buffer, *head;
X
X	/* get mail headers */
X
X	fd = open(spool_path, O_RDONLY);
X	fstat(fd, &status);
X	mail_buffer = (char *) malloc((unsigned int) (status.st_size + 1));
X	head = mail_header = (char *) malloc((unsigned int) (status.st_size + 1));
X	read(fd, mail_buffer, status.st_size);
X	close(fd);
X
X	while (*mail_buffer != NULL) {
X		if ((strncmp(mail_buffer, "From:", 5) == 0) && (*(mail_buffer - 1) == '\n')) {
X			while (*mail_buffer != '\n')
X				*mail_header++ = *mail_buffer++;
X			*mail_header++ = '\n';
X		} else if ((strncmp(mail_buffer, "Subject:", 8) == 0) && (*(mail_buffer - 1) == '\n')) {
X			while (*mail_buffer != '\n')
X				*mail_header++ = *mail_buffer++;
X			*mail_header++ = '\n';
X		} else
X			mail_buffer++;
X
X	}
X	*mail_header = NULL;
X
X	free(mail_buffer);
X	return (head);
X
X}
X
X
X
XXtCallbackProc
XBreakPopup(w, client_data, call_data)
X	Widget          w;
X	XtPointer       client_data;
X	XtPointer       call_data;
X{
X
X	XtPopdown(header);
X	XtDestroyWidget(header);
X
X}
END_OF_FILE
if test 13301 -ne `wc -c <'xpbiff.c'`; then
    echo shar: \"'xpbiff.c'\" unpacked with wrong size!
fi
# end of 'xpbiff.c'
fi
if test -f 'xpbiff.man' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xpbiff.man'\"
else
echo shar: Extracting \"'xpbiff.man'\" \(1657 characters\)
sed "s/^X//" >'xpbiff.man' <<'END_OF_FILE'
X.TH XPBIFF 1 "18 October 1990" "X Version 11"
X.SH NAME
Xxpbiff - Popup biff for X
X.SH SYNOPSIS
X.B xpbiff
X[-\fItoolkitoption\fP ...] [-option ...]
X.SH DESCRIPTION
XThe
X.I xpbiff
Xprogram displays a little image of a mailbox.  When mail arrives, the animate "Flying mail", and popup sender & subject information.
X.SH OPTIONS
X.I Xpbiff
Xaccepts all of the standard X Toolkit command line options along with the
Xadditional options listed below:
X.TP 8
X.B \-nfg \fIcolor_name\fP
X.B \-nbg \fIcolor_name\fP
XPicture foreground / background color when still not arrive mail.
XThe default value is black and cyan.
X.TP 8
X.B \-polling_time \fItime\fP
XPolling /usr/spool/mail interval time.
XDefault time is 15000[msec] = 15 [seconds]
X.TP 8
X.B \-noraise
XDo not raise up xpbiff when arrive mail.
X.TP 8
X.B \-nopopup
XDo not popup sender and subject information.
X.TP 8
X.B \-noanimate
XDo not animate.
X.TP 8
X.B \-nobell
XDo not bell.
X.TP 8
X.B \-nopopdown
XDo not show popdown button on sender information.
X.TP 8
X.B \-mono
XColor coordinates for monochrome server.
X.TP 8
X.B \-patchlevel
XShow current patchlevel and source code version.
X.SH "SEE ALSO"
XX(1),
Xstat(2)
X.SH BUGS
XThe mailbox bitmaps are ugly too.
X.SH COPYRIGHT NOTICE
XPermission to use, copy, modify and distribute without charge this
Xsoftware, documentation, images, etc. is granted, provided that this 
Xcomment and the author's name is retained.  The author assumes no 
Xresponsibility for lost sleep as a consequence of use of this software.
XSend any comments, bug reports, etc. to: shutoh@isl.yamaha.co.jp or, 
Xfor oversea: shutoh%isl.yamaha.co.jp%kddlab@uunet.uu.net  
X.SH AUTHOR
XKazuhiko Shutoh (shutoh@isl.yamaha.co.jp)
END_OF_FILE
if test 1657 -ne `wc -c <'xpbiff.man'`; then
    echo shar: \"'xpbiff.man'\" unpacked with wrong size!
fi
chmod +x 'xpbiff.man'
# end of 'xpbiff.man'
fi
echo shar: End of shell archive.
exit 0


dan
----------------------------------------------------
O'Reilly && Associates   argv@sun.com / argv@ora.com
Opinions expressed reflect those of the author only.