Path: rde!uunet!Germany.EU.net!thoth.mch.sni.de!horus.mch.sni.de!D012S594.mch.sni.de!not-for-mail
From: gerald@D012S594.mch.sni.de (Gerald Rinske)
Newsgroups: alt.sources
Subject: xelm - An intelligent Xbiff, part 01/01
Date: 10 Nov 1993 17:19:09 +0100
Organization: Siemens Nixdorf AG
Lines: 1046
Distribution: world
Message-ID: <2br49t$2kg@D012S594.mch.sni.de>
NNTP-Posting-Host: d012s594.mch.sni.de

:
# This is a shell archive, meaning:
# 1. Remove everything above the : line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	Makefile
#	README
#	Xelm.ad
#	elm_in_use
#	flagdown
#	flagup
#	xelm.c
#	xelm.h
# This archive created: Wed Nov 10 17:11:42 1993
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'Makefile'
then
	echo shar: "will not over-write existing file 'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
BINDIR=/usr/local/bin
APPDEFDIR=/usr/lib/X11/app-defaults

SRC=xelm.c
OBJ=xelm.o
HDR=xelm.h
BITMAPFILES=flagup flagdown elm_in_use

LIBS=-lXm -lXt -lX11 -lnsl -lsocket
CFLAGS= -DSYSV -DSVR4 -O -W0
LDFLAGS= -s

all:	xelm

xelm:	$(OBJ)
	cc $(LDFLAGS) -o $@ $(OBJ) $(LIBS)

xelm.o:	xelm.c $(HDR) $(BITMAPFILES)
	cc $(CFLAGS) -c $<

clean:
	rm -f *.o cscope.* core

realclean:
	rm -f *.o xelm cscope.* core

install:
	cp xelm $(BINDIR)
	chmod 755 $(BINDIR)/xelm
	cp Xelm.ad $(APPDEFDIR)/Xelm
	chmod 644 $(APPDEFDIR)/Xelm

cscope:
	ls $(SRC) $(HDR) $(BITMAPFILES) >cscope.files
	cscope -b
SHAR_EOF
fi
if test -f 'README'
then
	echo shar: "will not over-write existing file 'README'"
else
cat << \SHAR_EOF > 'README'
Xelm V1.0
=========

This is the first release of Xelm. Xelm is a Xbiff program
for Internet-Mail.

Xelm notifies a user when mail has arrived. To do so, it
checks the user's mailbox every n (default 30) seconds.

Xelm shows different pictures for
	No Mail
	Mail
	Mailbox in use 

Xelm can alternatively only show text-messages.

Xelm shows the mailbox-status in a Motif-PushButton. The user can
configure the button to start any program (intended for a mail-reader like
elm). Xelm will go to sleep while the mail-reader is active,
and check the mailbox immediately after it ended.
The button cannot be activated by the keyboard, rather the mouse has to
be used. This is to prevent starting up the mail-reader, when Xelm
gets the input focus from another process. (I have tried to prevent Xelm
from getting the input-focus at all, but should another process die, it can
still get it. Maybe I missed something there?)

I have tested it on MX300i (SINIX 5.41) machines.


Requirements:
-------------

To make Xelm, you'll need the Motif-Development System.

To run Xelm, you'll need Motif-Runtime.


Making Xelm:
------------

Just edit the Makefile to reflect the OS you're on. I have provided
definitions for SINIX 5.41 (which is compatible to SYSV R4).

type "make"


Installing Xelm:
----------------
Edit the Makefile. (Change BINDIR, APPDEFDIR, etc)

type "make install"

All important information for Xelm is stored in $APPDEFDIR/Xelm 
so that the normal user doesn't need to configure anything.


Readmailcommand:
----------------

Xelm has a resource to define which command to start when the button is
activated. As a default, elm is started inside a xterm.

Bugs:
----

Xelm dumps core if it doesn't find its applicationdefault file.

Copyright:
---------

Copyright (C) 1993 Siemens Nixdorf Informationssysteme AG
                   SNI BU BA NM 124
All rights reserved

Permission to use, modify and distribute this software and its
documentation for any purpose is hereby granted to all SNI Offices,
provided that the above copyright notice and this permission notice appear
in all copies, derived products and supporting documentation.
This permission includes the distribution of source or binaries to
customers/resellers etc. In any case, no fees may be taken for this software,
except such as represent the cost of media and/or copying.

Non SNI Offices may distribute this software further only when written 
permission is granted by SNI. Modification, re-use or sale of this software 
by any other than SNI is prohibited.

This is not an official SNI product. SNI, and especially SNI BA NM 124, do not
make any claim about the suitability of this software for any purpose. It
is provided "as is" without express or implied warranty.

Parts of this software were derived from another non-product program of SNI.
The original versions of these parts were written by Mathias Koerber
and were copyrighted in the same way.


Bug-Reports & Suggestions
-------------------------

	Gerald.Rinske@mch.sni.de

----
S I E M E N S | Gerald Rinske                       SNI AG   -  BU BA NM 124
_____________ | Carl-Wery-Strasse 22                81730 Muenchen (Germany)
	      | Phone: ++49/89/636 - 41154          FAX: ++49/89/636 - 43687
N I X D O R F | Internet: Gerald.Rinske@mch.sni.de  NERV: rinske.muc@sni.de
SHAR_EOF
fi
if test -f 'Xelm.ad'
then
	echo shar: "will not over-write existing file 'Xelm.ad'"
else
cat << \SHAR_EOF > 'Xelm.ad'
! $Id: Xelm.ad,v 0.3 1993/11/10 G.Rinske SNI BA NM 124
!
! Application Defaults
! for xelm
!
Xelm*geometry:		60x60+0+0
Xelm*fontList:		variable
Xelm*background:	yellow
Xelm*foreground:	black
Xelm*interval:		10
Xelm*tracelevel:	0
Xelm*emptytext:		You have no mail.
Xelm*fulltext:		You have Mail!
Xelm*inusetext:		Can't open Mailbox!
Xelm*showtext:		False
Xelm*nodaemon:		False
Xelm*readmailcommand:	/usr/bin/X11/xterm -e /usr/local/bin/elm
Mwm*Xelm*ClientDecoration:	none
Mwm*Xelm*ClientFunction:	none
SHAR_EOF
fi
if test -f 'elm_in_use'
then
	echo shar: "will not over-write existing file 'elm_in_use'"
else
cat << \SHAR_EOF > 'elm_in_use'
#define inuse_width 48
#define inuse_height 48
static char inuse_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00,
   0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x03, 0x00,
   0x00, 0xc0, 0xff, 0xff, 0x07, 0x00, 0x00, 0xf0, 0xe3, 0xe1, 0x1f, 0x00,
   0x00, 0xf8, 0x70, 0x80, 0x3f, 0x00, 0x00, 0x3c, 0x18, 0x00, 0x7b, 0x00,
   0x00, 0x1f, 0x0c, 0x00, 0xf3, 0x00, 0x00, 0x0f, 0x06, 0x00, 0xe6, 0x01,
   0x80, 0x1f, 0x03, 0x00, 0xc6, 0x03, 0x80, 0xbf, 0x01, 0x00, 0x86, 0x07,
   0xc0, 0xf9, 0x1f, 0x00, 0x87, 0x07, 0xe0, 0xf1, 0x7f, 0x80, 0x07, 0x0f,
   0xe0, 0xf0, 0xe1, 0xc0, 0x05, 0x0f, 0xe0, 0xf8, 0x83, 0xe1, 0x04, 0x0e,
   0x70, 0xd8, 0x87, 0x71, 0x04, 0x1e, 0x70, 0x8c, 0x0f, 0x3b, 0x06, 0x1c,
   0x70, 0x0c, 0x1f, 0x1f, 0x07, 0x1c, 0x70, 0x06, 0x3e, 0x8e, 0x07, 0x1c,
   0x70, 0x06, 0x7c, 0xc6, 0x05, 0x1c, 0x78, 0x06, 0xf8, 0xc6, 0x05, 0x3c,
   0x78, 0x06, 0xf0, 0xc7, 0x04, 0x3c, 0x78, 0x06, 0xe0, 0x07, 0x04, 0x3c,
   0x78, 0x06, 0xc0, 0x07, 0x04, 0x3c, 0x70, 0x06, 0x80, 0x0f, 0x04, 0x1c,
   0x70, 0x06, 0x00, 0x1f, 0x04, 0x1c, 0x70, 0x06, 0x00, 0x3e, 0x06, 0x1c,
   0x70, 0x06, 0x00, 0x7e, 0x03, 0x1c, 0xe0, 0x06, 0x00, 0xfe, 0x01, 0x0e,
   0xe0, 0x06, 0x00, 0xf6, 0x01, 0x0e, 0xe0, 0x07, 0x00, 0xe6, 0x03, 0x0f,
   0xc0, 0x07, 0x00, 0xf6, 0x07, 0x07, 0x80, 0x07, 0x00, 0xbe, 0x8f, 0x03,
   0x80, 0xff, 0xff, 0x2f, 0xdf, 0x03, 0x00, 0xff, 0xff, 0x27, 0xfe, 0x01,
   0x00, 0x1e, 0x88, 0x20, 0xfc, 0x00, 0x00, 0x3c, 0x88, 0x20, 0x78, 0x00,
   0x00, 0xf8, 0x88, 0x20, 0x7e, 0x00, 0x00, 0xf0, 0x8b, 0xa0, 0x1f, 0x00,
   0x00, 0xc0, 0xff, 0xff, 0x07, 0x00, 0x00, 0x80, 0xff, 0xff, 0x03, 0x00,
   0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x88, 0x23, 0x00, 0x00,
   0xf7, 0xbf, 0x8e, 0xfc, 0xdf, 0xf8, 0x9d, 0xeb, 0x9b, 0x76, 0xd2, 0x7a,
   0x46, 0x30, 0xe2, 0x0f, 0xe1, 0x47, 0x55, 0x84, 0x48, 0x11, 0x84, 0x99};

SHAR_EOF
fi
if test -f 'flagdown'
then
	echo shar: "will not over-write existing file 'flagdown'"
else
cat << \SHAR_EOF > 'flagdown'
#define flagdown_width 48
#define flagdown_height 48
static char flagdown_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00,
   0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xe1, 0x00, 0x00,
   0x00, 0x00, 0x70, 0x80, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x03, 0x00,
   0x00, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x04,
   0x00, 0x00, 0x03, 0x00, 0x06, 0x06, 0x00, 0x80, 0x01, 0x00, 0x06, 0x07,
   0x00, 0xc0, 0x1f, 0x00, 0x87, 0x07, 0x00, 0xe0, 0x7f, 0x80, 0xc7, 0x07,
   0x00, 0x70, 0xe0, 0xc0, 0xe5, 0x07, 0x00, 0x38, 0x80, 0xe1, 0x74, 0x07,
   0x00, 0x18, 0x80, 0x71, 0x3c, 0x07, 0x00, 0x0c, 0x00, 0x3b, 0x1e, 0x03,
   0x00, 0x0c, 0x00, 0x1f, 0x0f, 0x00, 0x00, 0x86, 0x1f, 0x8e, 0x07, 0x00,
   0x00, 0x06, 0x06, 0xc6, 0x05, 0x00, 0x00, 0x06, 0x00, 0xc6, 0x05, 0x00,
   0x00, 0x06, 0x00, 0xc6, 0x04, 0x00, 0x00, 0x06, 0x00, 0x06, 0x04, 0x00,
   0x7f, 0x06, 0x00, 0x06, 0xe4, 0xff, 0x00, 0x06, 0x00, 0x06, 0x04, 0x00,
   0x00, 0x06, 0x00, 0x06, 0x04, 0x00, 0x00, 0x06, 0x00, 0x06, 0x06, 0x00,
   0x00, 0x06, 0x00, 0x06, 0x03, 0x00, 0x00, 0x06, 0x00, 0x86, 0x01, 0x00,
   0x00, 0x06, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x06, 0x00, 0x66, 0x00, 0x00,
   0x00, 0x06, 0x00, 0x36, 0x00, 0x00, 0x00, 0x06, 0x00, 0x3e, 0x00, 0x00,
   0x00, 0xfe, 0xff, 0x2f, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x27, 0x00, 0x00,
   0x00, 0x00, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x20, 0x00, 0x00,
   0x00, 0x00, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x20, 0x00, 0x00,
   0x00, 0x00, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x20, 0x00, 0x00,
   0x00, 0x00, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x20, 0x00, 0x00,
   0xf7, 0xbf, 0x8e, 0xfc, 0xdf, 0xf8, 0x9d, 0xeb, 0x9b, 0x76, 0xd2, 0x7a,
   0x46, 0x30, 0xe2, 0x0f, 0xe1, 0x47, 0x55, 0x84, 0x48, 0x11, 0x84, 0x19};
SHAR_EOF
fi
if test -f 'flagup'
then
	echo shar: "will not over-write existing file 'flagup'"
else
cat << \SHAR_EOF > 'flagup'
#define flagup_width 48
#define flagup_height 48
static char flagup_bits[] = {
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x80, 0xff,
   0xff, 0xff, 0xff, 0x1f, 0x80, 0xff, 0xff, 0xff, 0xff, 0x10, 0x95, 0xff,
   0xff, 0xff, 0x3f, 0x84, 0x8a, 0xff, 0xff, 0xff, 0x1f, 0x1f, 0x95, 0xff,
   0xff, 0xff, 0xcf, 0x9f, 0x8a, 0xff, 0xff, 0xff, 0xe7, 0x1f, 0x80, 0xff,
   0xff, 0xff, 0xf3, 0x1f, 0x80, 0xff, 0xff, 0xff, 0xf9, 0x1f, 0xfb, 0xff,
   0xff, 0xff, 0xfc, 0x1f, 0xfb, 0xff, 0xff, 0x7f, 0xfe, 0x1f, 0xf9, 0xff,
   0xff, 0x3f, 0xe0, 0x1f, 0xf8, 0xff, 0xff, 0x1f, 0x80, 0x1f, 0xf8, 0xff,
   0xff, 0x8f, 0x1f, 0x1f, 0xfa, 0xff, 0xff, 0xc7, 0x7f, 0x1e, 0xfb, 0xff,
   0xff, 0xe7, 0x7f, 0x0e, 0xfb, 0xff, 0xff, 0xf3, 0xff, 0x04, 0xfb, 0xff,
   0xff, 0xf3, 0xff, 0x00, 0xfb, 0xff, 0xff, 0x79, 0xe0, 0x11, 0xfb, 0xff,
   0xff, 0xf9, 0xf9, 0x19, 0xfb, 0xff, 0xff, 0xf9, 0xff, 0x19, 0xfb, 0xff,
   0xff, 0xf9, 0xff, 0x19, 0xfb, 0xff, 0xff, 0xf9, 0xff, 0x99, 0xfb, 0xff,
   0x80, 0xa9, 0xad, 0xf9, 0x1b, 0x00, 0xff, 0x89, 0xaa, 0xf9, 0xfb, 0xff,
   0xff, 0xa9, 0xa8, 0xf9, 0xfb, 0xff, 0xff, 0xa9, 0xaa, 0xf9, 0xf9, 0xff,
   0xff, 0xa9, 0x2a, 0xf9, 0xfc, 0xff, 0xff, 0xf9, 0xff, 0x79, 0xfe, 0xff,
   0xab, 0xf9, 0xff, 0x39, 0xab, 0xaa, 0x55, 0xf9, 0xff, 0x99, 0x55, 0xd5,
   0xab, 0xf9, 0xff, 0xc9, 0xaa, 0xaa, 0x55, 0xf9, 0xff, 0x41, 0x55, 0xd5,
   0xab, 0x01, 0x00, 0x90, 0xaa, 0xaa, 0x55, 0x03, 0x00, 0x58, 0x55, 0xd5,
   0xab, 0xfe, 0x77, 0x9f, 0xaa, 0xaa, 0x55, 0x55, 0x75, 0x5f, 0x55, 0xd5,
   0xab, 0xaa, 0x72, 0x9f, 0xaa, 0xaa, 0x55, 0x55, 0x75, 0x5f, 0x55, 0xd5,
   0xab, 0xaa, 0x72, 0x9f, 0xaa, 0xaa, 0x55, 0x55, 0x75, 0x5f, 0x55, 0xd5,
   0xab, 0xaa, 0x72, 0xaf, 0xaa, 0xaa, 0x55, 0x55, 0x75, 0x57, 0x55, 0xd5,
   0xab, 0xaa, 0x6a, 0xab, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
   0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xea, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
SHAR_EOF
fi
if test -f 'xelm.c'
then
	echo shar: "will not over-write existing file 'xelm.c'"
else
cat << \SHAR_EOF > 'xelm.c'
char ident[] = "@(#)xelm V1.0 93/11/10 SNI BA NM 124";

/*
 * System includes 
 */
#include	<stdio.h>
#include	<signal.h>
#include	<malloc.h>
#include	<errno.h>
#include	<sys/types.h>
#include	<sys/stat.h>
#include        <unistd.h>
#include	<Xm/Xm.h>
#include	<X11/Shell.h>
#include	<Xm/PushB.h>
#include	"xelm.h"

/*
 * include the default bitmaps
 */

#include	"flagup"
#include	"flagdown"
#include	"elm_in_use"

/*
 * Global Variables
 */
XtAppContext	kontext;
Widget		applShell;
Widget		buttonW;
Display		*display;
ApplResTyp	applResources;
XtIntervalId	timer;
int		currentstate = XIB_EMPTY;
char		mail_p[80];

/*
 * here we stow all the pixmaps
 * and the texts
 */
Pixmap  	buttonpixmap[XIB_MAXMODE+1];
XmString	buttontext[XIB_MAXMODE+1];

/*
 * external references
 */

extern	char	*sys_errlist[];
static int fstat();


/*
 * command-line options
 */

static XrmOptionDescRec options[] = {
	{ "-readmailcommand", ".readmailcommand", XrmoptionSepArg, NULL },
	{ "-interval",        ".interval",	  XrmoptionSepArg, NULL },
	{ "-tracelevel",      ".tracelevel",      XrmoptionSepArg, NULL },
	{ "-emptytext",       ".emptytext",       XrmoptionSepArg, NULL },
	{ "-fulltext",        ".fulltext",        XrmoptionSepArg, NULL },
	{ "-inusetext",       ".inusetext",       XrmoptionSepArg, NULL },
	{ "-emptypixmap",     ".emptypixmap",     XrmoptionSepArg, NULL },
	{ "-fullpixmap",      ".fullpixmap",      XrmoptionSepArg, NULL },
	{ "-inusepixmap",     ".inusepixmap",     XrmoptionSepArg, NULL },
	{ "-showtext",        ".showtext",        XrmoptionSepArg, NULL },
	{ "-nodaemon",        ".nodaemon",        XrmoptionSepArg, NULL },
	};

/*
 * Application Resources
 */
static XtResource resources[] = {
	{ XibNcommand, XibCCommand,
	  XmRString, sizeof(String),
	  XtOffset(ApplResTyp*, command),
	  XmRString, ""
	},
	{ XibNappDefaultsVersion, XibCAppDefaultsVersion,
	  XmRInt, sizeof(int),
	  XtOffset(ApplResTyp*, version),
	  XmRString, "0"
	},
	{ XibNinterval, XibCInterval,
	  XmRInt, sizeof(int),
	  XtOffset(ApplResTyp*, interval),
	  XmRString, XIB_DEF_INTERVAL
	},
	{ XibNtracelevel, XibCTracelevel,
	  XmRInt, sizeof(int),
	  XtOffset(ApplResTyp*,tracelevel),
	  XmRString, XIB_DEF_TRACELEVEL
	},
	{ XibNinusetext, XibCInusetext,
	  XmRString, sizeof(String),
	  XtOffset(ApplResTyp*,inusetext),
	  XmRString, "Can't open Mailbox"
	},
	{ XibNemptytext, XibCEmptytext,
	  XmRString, sizeof(String),
	  XtOffset(ApplResTyp*,emptytext),
	  XmRString, "No Mail"
	},
	{ XibNfulltext, XibCFulltext,
	  XmRString, sizeof(String),
	  XtOffset(ApplResTyp*,fulltext),
	  XmRString, "You have Mail"
	},
	{ XibNemptypixmap, XibCEmptypixmap,
	  XmRString, sizeof(String),
	  XtOffset(ApplResTyp*,emptypixmapfile),
	  XmRString, ""
	},
	{ XibNfullpixmap, XibCFullpixmap,
	  XmRString, sizeof(String),
	  XtOffset(ApplResTyp*,fullpixmapfile),
	  XmRString, ""
	},
	{ XibNinusepixmap, XibCInusepixmap,
	  XmRString, sizeof(String),
	  XtOffset(ApplResTyp*,inusepixmapfile),
	  XmRString, ""
	},
	{ XibNshowtext, XibCShowtext,
	  XmRBool, sizeof(Bool),
	  XtOffset(ApplResTyp*,showtext),
	  XmRBool, False
	},
	{ XibNnodaemon, XibCNodaemon,
	  XmRBool, sizeof(Bool),
	  XtOffset(ApplResTyp*,nodaemon),
	  XmRBool, False
	},
	};
	


main(argc, argv)
int	argc;
char	*argv[];
{
	Cardinal	argcTmp;
	String		*argvTmp;
	int		i;
	Arg		args[10];
	Cardinal	n;


	XtToolkitInitialize();
	kontext = XtCreateApplicationContext();


	argcTmp = argc;
	argvTmp = (String *) XtMalloc ((Cardinal)(argc*sizeof(String)));
	for (i=0; i < argc; i++)
		{
		argvTmp[i] = XtNewString(argv[i]);
		}

	strcpy (mail_p, getenv("MAIL"));
	if (strlen (mail_p) == 0)
	{
		strcpy (mail_p, "/usr/spool/mail/");
		strcat (mail_p, getenv("USER"));
	}

	if (access (mail_p, R_OK | W_OK) != 0)
	{
		fprintf (stderr, "Can't open folder %s for reading!\n", mail_p);
		exit (2);
	}

	display = XtOpenDisplay(kontext, (String)NULL,(String)NULL,
			APPL_KLASSE, options, XtNumber(options),
			&argc, argv);


	if (display == NULL)
		{
		XtAppError(kontext,"Display could not be opened");
		}

	if (argc != 1)
		{
		paramerror(argc-1,argv+1);
		}

	/*
	 * Create Application Shell
	 *
	 * Keep it auto-rezizable
	 */
	n = 0;
	XtSetArg (args[n], XmNargc, argcTmp); n++;
	XtSetArg (args[n], XmNinput, False); n++;
	XtSetArg (args[n], XmNargv, argvTmp); n++;
	XtSetArg (args[n], XmNscreen, DefaultScreenOfDisplay(display)); n++;
	XtSetArg (args[n], XmNallowShellResize, True); n++;
	applShell = XtAppCreateShell((String)NULL, APPL_KLASSE,
			applicationShellWidgetClass, display, args, n);

	/*
	 * make the button
	 * it can either display PIXMAPS or STRINGS,
	 * which is configurable via the showtext resource
	 * 
	 */
	n = 0;
	XtSetArg (args[n], XmNtraversalOn, False); n++;
	buttonW = XtCreateManagedWidget ("button", xmPushButtonWidgetClass,
			applShell, args, n);

	/*
	 * then read the application resources
	 * and process them
	 */

	readApplicationResources(applShell);

	n = 0;
	if (applResources.showtext == True)
	{
		XtSetArg (args[n], XmNlabelType, XmSTRING); n++;
		XtSetArg (args[n], XmNlabelString, buttontext[XIB_EMPTY]); n++;
	}
	else
	{
		XtSetArg (args[n], XmNlabelType, XmPIXMAP); n++;
		XtSetArg (args[n], XmNlabelPixmap, buttonpixmap[XIB_EMPTY]); n++;
		XtSetArg (args[n], XmNlabelInsensitivePixmap, buttonpixmap[XIB_INUSE]); n++;
	}
	XtSetArg (args[n], XmNrecomputeSize, True); n++;
	XtSetValues(buttonW, args, n);

	/*
	 * If a command is specified, it can be started by pressing the
	 * button.
	 */
	if (strcmp(applResources.command,"") != 0)
		XtAddCallback(buttonW, XmNactivateCallback, 
		startreaderCB, (caddr_t)NULL);

	XtSetMappedWhenManaged(applShell, False);

	XtRealizeWidget(applShell);

	/*
	 * check the mailbox
	 * the routine will initialize a timer to call for the next check
	 */

	checkmailboxCB(applShell,(caddr_t)NULL, (caddr_t)NULL);

	XtMapWidget(applShell);

	XtAppMainLoop(kontext);

}

/*
 *	Function:	readApplicationResources
 *
 *	reads the Application resources and process them
 *
 */
void	readApplicationResources(applShell)
Widget	applShell;
{
	char	*buf;

	XtGetApplicationResources (applShell, &applResources,
				resources, XtNumber(resources),
				(Arg *)NULL, 0);

	/*
	 * If there is no set DISPLAY Shell variable in the environment,
	 * set ours, for the sake of our children
	 */

	if (strcmp(getenv("DISPLAY"),"") == 0)
		{
		if (applResources.tracelevel > 0)
			{
			fprintf(stderr,"setting DISPLAY=%s\n",
				DisplayString(display));
			}
		buf = (char *)malloc(strlen(DisplayString(display))+
					strlen("DISPLAY=")+2);
		sprintf(buf,"DISPLAY=%s",DisplayString(display));
		putenv(buf);
		}
		
	if (strcmp(mail_p,"") == 0)
	{
		fprintf(stderr,"No Mailbox specified..exiting\n");
		exit(1);
	}

	/*
	 * Convert the resource-text into Compund-Strings
	 */
	buttontext[XIB_EMPTY]	= XmStringCreate(applResources.emptytext,
					XmSTRING_DEFAULT_CHARSET);
	buttontext[XIB_FULL]	= XmStringCreate(applResources.fulltext,
					XmSTRING_DEFAULT_CHARSET);
	buttontext[XIB_INUSE]	= XmStringCreate(applResources.inusetext,
					XmSTRING_DEFAULT_CHARSET);

	/*
	 * and free the memory used by the application resources
	 */
	XtFree(applResources.emptytext);
	XtFree(applResources.fulltext);
	XtFree(applResources.inusetext);

	/*
	 * load bitmaps is we need them
	 */
	if (applResources.showtext == False)
		{
		loadBitmap(buttonW,&buttonpixmap[XIB_EMPTY],
			   applResources.emptypixmapfile,
			   flagdown_bits,flagdown_width,flagdown_height);
		loadBitmap(buttonW,&buttonpixmap[XIB_FULL],
			   applResources.fullpixmapfile,
			   flagup_bits,flagup_width,flagup_height);
		loadBitmap(buttonW,&buttonpixmap[XIB_INUSE],
			   applResources.inusepixmapfile,
			   inuse_bits,inuse_width,inuse_height);
		}
	/*
	 * shall we become a daemon ?
	 */

	if (applResources.nodaemon == True)
		return;

	if (applResources.tracelevel > 0)
		{
		fprintf(stderr,"becoming a daemon\n");
		}

	if (fork())
		exit(0);

#ifdef SVR4
	setsid();
#else
	setpgrp();
#endif

	signal(SIGHUP, SIG_IGN);

	if (fork())
		exit(0);


	}


/*
 *	Startreader Callback
 *
 *	Called when the button is pressed.
 *
 *	The process forks. The child will start the given command via
 *		/bin/sh -c
 *
 *	The parent will set the button to insensitive,
 *	try to get rid of the input focus,
 *	prepare a handler for when the child (command) dies
 *	and suspend polling the mailbox
 *
 *	
 */
void startreaderCB(w,client_data, call_data)
Widget	w;
caddr_t	client_data;
caddr_t	call_data;
{
	/*
	 * if not activated by Mouse-Button1
	 * do not execute
	 */

	if (applResources.tracelevel > 0)
		{
		fprintf(stderr,"xbutton = %d\n", ((XmAnyCallbackStruct *)call_data)->event->xbutton.button);
		}

	if (((XmAnyCallbackStruct *)call_data)->event->xbutton.button != Button1)
		return;


	if (strcmp(applResources.command,"") == 0)
		{
		if (applResources.tracelevel > 0)
			{
			fprintf(stderr,"no command to execute");
			}
		ringbell(0);
		return;
		}
	
	if (fork() != 0)
		{
		/*
		 * make the button insensitive,
		 * prepare a handler for the death of the child
		 * remove the timer
		 */
		XtSetSensitive(buttonW, False);
		XSync(display,False);

		signal (SIGCHLD, childSH);

		if (timer)
			XtRemoveTimeOut(timer);
		return;
		}
	else
		{
		/* child */
		execlp("/bin/sh","sh","-c",applResources.command,(char *)0);
		fprintf(stderr,"exec 'sh %s' failed: %d (%s)\n",
			applResources.command,
			errno, sys_errlist[errno]);
		ringbell(0);
		exit(0);
		}
}

/*
 *	prepare Bitmaps
 *
 *	If Bitmaps are named as files, we'll try to load them
 *	otherwise the compiled-in bitmaps are set up.
 *
 *	Parameters
 *		w:	window
 *		pm:	pointer to pixmap to load
 *		pmfile:	name of file to load from
 *		data:	pointer to default pixmap
 *		width:	width of default pixmap
 *		height:	height of default pixmap
 */

void	loadBitmap(w,pm,pmfile,data,width,height)
Widget	w;
Pixmap	*pm;
char	*pmfile;
char	*data;
unsigned int	width, height;
{
	Pixel   foreground, 
		background;
	Arg     arglist[5];
	int     n;
	Screen	*TheScreen	= XtScreen(w);

	n = 0;
	XtSetArg(arglist[n], XmNbackground, &background); n++;
	XtSetArg(arglist[n], XmNforeground, &foreground); n++;
	XtGetValues(w, arglist, n);


	if (strcmp(pmfile,"") != 0)
		{
		if (((*pm) = XmGetPixmap(TheScreen, pmfile, 
			foreground, background)) != XmUNSPECIFIED_PIXMAP)
			{
			return;
			}
		fprintf(stderr,"couldn't load %s, using default pixmap\n",
			pmfile);
		}
	(*pm) = XCreatePixmapFromBitmapData(display,
		DefaultRootWindow(display), 
		data, width, height, 
		foreground, background,
		DefaultDepthOfScreen(TheScreen));
}


/*
 * CHECKMAILBOX
 *
 */

void	checkmailboxCB(w, client_data, call_data)
Widget	w;
caddr_t	client_data;
caddr_t	call_data;
{
	int		cc;
	Cardinal	n;
	Arg		args[10];
	int		ring = 0;
	static int	old_box_size = 0;

	cc = check_mail(mail_p);

	if (applResources.tracelevel > 0)
	{
		fprintf(stderr,"\n--> checkmailboxCB()\n");
		fprintf(stderr,"check_mail returns %d\n",cc);
		fprintf(stderr,"old_box_size is %d\n",old_box_size);
		fprintf(stderr,"currentstate =%d\n",currentstate);
	}
	
	if (((cc >  0) && (cc <= old_box_size)) || 
	    ((cc == 0) && (currentstate == XIB_EMPTY)))
	{
		timer = XtAppAddTimeOut(kontext, (applResources.interval*1000), 
				checkmailboxCB, (caddr_t)NULL);
		if (applResources.tracelevel > 0)
		{
			fprintf(stderr,"no state change\n");
			fprintf(stderr,"new timeout added for %d seconds\n",
					applResources.interval);
		}
		old_box_size = cc;
		return;
	}

	n = 0;

	if (cc>0) currentstate = XIB_FULL;
	     else currentstate = XIB_EMPTY;

	if (applResources.showtext == False)
		XtSetArg (args[n], XmNlabelPixmap, buttonpixmap[currentstate]); 
	else
		XtSetArg (args[n], XmNlabelString, buttontext[currentstate]);
	n++;
	XtSetValues(buttonW, args, n);

	if (applResources.tracelevel > 0)
	{
		String	buf;

		XmStringGetLtoR(buttontext[currentstate], XmSTRING_DEFAULT_CHARSET, &buf);
		fprintf(stderr,"          cc=%d\n",cc);
		fprintf(stderr,"old_box_size=%d\n",old_box_size);
		fprintf(stderr,"currentstate=%d\n",currentstate);
		fprintf(stderr,"buttontext[currentstate]=%s\n",buf);
		XtFree(buf);
	}


	if (cc > old_box_size)
		ring = 1;

	timer = XtAppAddTimeOut(kontext, (applResources.interval*1000), 
			checkmailboxCB, (caddr_t)NULL);
	if (applResources.tracelevel > 0)
		fprintf(stderr,"new timeout added for %d seconds\n",
				applResources.interval);
	if (ring)
		ringbell(currentstate);
	old_box_size = cc;
}


/*
 * signal handler for dying child
 *
 * when the child has returned, we can  make the button sensitive again
 * and start another check on the mailbox...
 */

void childSH(sig)
int	sig;
{
	if (applResources.tracelevel > 0)
		{
		fprintf(stderr,"received signal: %d\n", sig);
		}

	/* ignore further dying children */
	signal(SIGCHLD, SIG_IGN);

	checkmailboxCB(applShell,(caddr_t)NULL, (caddr_t)NULL);
	XtSetSensitive(buttonW, True);
	}


/*
 * ringbell
 *
 * execute different bell signals
 */

void	ringbell(mode)
int	mode;
{
	if (applResources.tracelevel > 0)
		fprintf(stderr,"ringing bell mode=%d\n", mode);

	switch(mode) {
		case XIB_FULL:	/*
				 * The Postman always rings twice
				 */
				XBell(display,100);
				XSync(display,False);
				sleep(1);
				XBell(display,100);
				XSync(display,False);
				break;
		default:	XBell(display,100);
				XSync(display,False);
				break;
		}
}

/*
 * print out all unknown parameters
 */

void paramerror(argcerr,argverr)
int	argcerr;
char	*argverr[];
{
	int	nchar;
	String	warning;
	int	i;

	nchar = 0;
	for (i=0; i<argcerr;i++)
		nchar += strlen(argverr[i]) +1;
	warning = XtMalloc((nchar+30) * sizeof(char));

	strcpy(warning, "Wrong parameters:");
	for (i=0;i<argcerr;i++)
	{
		strcat(warning, " ");
		strcat(warning, argverr[i]);
	}

	XtAppWarning(kontext, warning);

	XtFree(warning);
}


/*
 * check the User's Mailbox
 */

int check_mail(mail_p)
char * mail_p;
{
	struct stat finf;
	int mail_new = 0;
	if (applResources.tracelevel > 0)
		fprintf (stderr, "Mailbox is %s\n", mail_p);

	if (stat(mail_p, &finf) == 0)
		mail_new = finf.st_size;
	return (mail_new);
}
SHAR_EOF
fi
if test -f 'xelm.h'
then
	echo shar: "will not over-write existing file 'xelm.h'"
else
cat << \SHAR_EOF > 'xelm.h'
#define	APPL_KLASSE			"Xelm"
#define XIB_BELLSTEP			10

#define	XIB_DEF_INTERVAL		"60"
#define XIB_DEF_TRACELEVEL		"0"
#define MAX_TRACE_LEVEL			1

#define XIB_EMPTY			0
#define XIB_FULL			1
#define XIB_INUSE			2

#define XIB_MAXMODE			XIB_INUSE

#define	XibNcommand			"readmailcommand"
#define	XibCCommand			"Readmailcommand"
#define XibCAppDefaultsVersion          "AppDefaultsVersion"
#define XibNappDefaultsVersion          "appDefaultsVersion"

#define XibNshowtext                    "showtext"
#define XibCShowtext                    "Showtext"
#define XibNinterval			"interval"
#define XibCInterval			"Interval"
#define	XibNtracelevel			"tracelevel"
#define XibCTracelevel			"Tracelevel"
#define XibNnodaemon			"nodaemon"
#define XibCNodaemon			"Nodaemon"

	/*
	 * Pixmap resources
	 */
#define	XibNemptypixmap			"emptypixmap"
#define XibCEmptypixmap			"Emptypixmap"
#define XibNfullpixmap			"fullpixmap"
#define XibCFullpixmap			"Fullpixmap"
#define XibNinusepixmap                 "inusepixmap"
#define XibCInusepixmap                 "Inusepixmap"

	/*
	 * text Resources
	 */
#define XibNemptytext                   "emptytext"
#define XibCEmptytext                   "Emptytext"
#define XibNfulltext                    "fulltext"
#define XibCFulltext                    "Fulltext"
#define XibNinusetext                   "inusetext"
#define XibCInusetext                   "Inusetext"

typedef struct {
	String	command;
	int	version;
	int	interval;
	int	tracelevel;
	String  emptytext;
	String  fulltext;
	String  inusetext;
	String	emptypixmapfile;
	String	fullpixmapfile;
	String  inusepixmapfile;
	int     showtext;
	int     nodaemon;
} ApplResTyp;

int	check_mail();
void	loadBitmap();
void	startreaderCB();
void	checkmailboxCB();
void	readApplicationResources();
void	childSH();
void	ringbell();
void	paramerror();
SHAR_EOF
fi
exit 0
#	End of shell archive

   
