[comp.sources.misc] v13i072: Faces v1.4.5: a visual list monitor for mail etc..

rburridge@Sun.COM (Rich Burridge) (07/03/90)

Posting-number: Volume 13, Issue 72
Submitted-by: rburridge@Sun.COM (Rich Burridge)
Archive-name: faces-1.4.5/part03

------CUT HERE------faces.part3------CUT HERE------
#! /bin/sh
# this is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh to create the files:
#	xview.c
#	x11.c
#	extern.h
#	faces.h
#	patchlevel.h
# This archive created: Fri Jun 29 10:45:10 EST 1990
#
#
export PATH; PATH=/bin:$PATH
#
if [ -f xview.c ]
then
echo shar: will not over-write existing file xview.c
else
echo shar: extracting 'xview.c',    12752 characters
cat > xview.c <<'Funky_Stuff'

/*  @(#)xview.c 1.6 90/06/26
 *
 *  XView dependent graphics routines used by faces,
 *  the visual mail and print job monitor.
 * 
 *  Copyright (c) Rich Burridge - Sun Microsystems Australia.
 *                                All rights reserved.
 *
 *  Permission is given to distribute these sources, as long as the
 *  copyright messages are not removed, and no monies are exchanged. 
 * 
 *  No responsibility is taken for any errors or inaccuracies inherent
 *  either to the comments or the code of this program, but if reported
 *  to me, then an attempt will be made to fix them.
 */

#include <stdio.h>
#include "faces.h"
#include "extern.h"
#include <xview/xview.h>
#include <xview/canvas.h>
#include <xview/icon.h>
#include <X11/Xlib.h>

#define  DEF_FONT  "fixed"
#define  F_ICON    0                  /* Icon index to frame array. */
#define  F_WINDOW  1                  /* Window index to frame array. */
#define  FONT      "times-roman-10"

#define  NOTIFY_INTERPOSE_EVENT_FUNC  (void) notify_interpose_event_func
#define  NOTIFY_SET_ITIMER_FUNC       (void) notify_set_itimer_func
#define  XV_DESTROY                   (void) xv_destroy
#define  XV_SET                       (void) xv_set

#define  ITIMER_NULL             ((struct itimerval *) 0)

int repaint_proc() ;

Canvas canvas ;
Canvas_paint_window pw ;
Frame frame ;
Icon faces_icon ;

Display *dpy ;
Drawable xid[2] ;               /* Xlib pointers to the screen and the icon. */
Pixmap pr[3] = { NULL, NULL, NULL } ;     /* Current memory pixmaps. */
Pixmap old_pr[2] = { NULL, NULL } ;       /* Previous memory pixmaps. */

/* Array of the different icon images. */
Pixmap images[MAXICONS] = {
  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
} ;

GC gc ;                       /* Main drawing graphics context. */
GC tilegc ;                   /* Graphics context for tiling background. */
Window root ;
XFontStruct *sfont ;
XGCValues gc_val ;            /* Used to setup graphics context values. */
int screen ;                  /* Default graphics display screen. */
int toclear ;                 /* Set if faces icon needs clearing. */
unsigned int depth ;
unsigned long backgnd ;       /* Default background color. */
unsigned long foregnd ;       /* Default foreground color. */
unsigned long gc_mask ;       /* Mask for setting graphic context values. */


adjust_image(dtype, itype, row, column)  /* Put new face in memory pixrect. */
enum disp_type dtype ;
enum icon_type itype ;
int row, column ;
{
  if (mtype == MONNEW)
    XCopyArea(dpy, pr[(int) dtype], pr[(int) dtype], gc, 0, 0,
              (maxcols-1)*imagewidth, imageheight, imagewidth, 0) ;

  XCopyArea(dpy, images[(int) itype], pr[(int) dtype], gc, 0, 0,
            imagewidth, imageheight, column*imagewidth, row*imageheight) ;
}


/*ARGSUSED*/
beep_flash(beeps, flashes)    /* Perform visual feedback. */
int beeps, flashes ;
{
  int i ;

  for (i = 0; i < beeps; i++) window_bell(frame) ;
}


/*ARGSUSED*/
void
canvas_proc(canvas, event, arg)
Canvas canvas ;
Event *event ;
caddr_t arg ;
{
  int nextc ;

  nextc = event_id(event) ;
  if (event_is_down(event) && nextc == MS_LEFT)
    {
      wdtype = (wdtype == DISP_NAME) ? DISP_OTHER : DISP_NAME ;
      XCopyArea(dpy, pr[(int) wdtype], xid[F_WINDOW], gc, 0, 0,
                width, height, 0, 0) ;
    }
  else if (mtype == MONNEW && event_is_ascii(event) && nextc == DEL)
    {
      repl_image(DISP_NAME,  CUROFF, width, height) ;
      repl_image(DISP_OTHER, CUROFF, width, height) ;
      toclear = 1 ;
      do_check() ;
    }
}


Notify_value
check_mail()
{
  do_check() ;
}


create_pixrects(width, height)   /* Create pixrects for the face images. */
int width, height ;
{
  old_pr[(int) DISP_NAME]  = pr[(int) DISP_NAME] ;
  old_pr[(int) DISP_OTHER] = pr[(int) DISP_OTHER] ;

  make_area(DISP_NAME, width, height) ;
  repl_image(DISP_NAME, CUROFF, width, height) ;

  if (toclear && mtype == MONNEW)
    {
      repl_image(DISP_OTHER, OLDOFF, width, height) ;
      toclear = 0 ;
    }

  make_area(DISP_OTHER, width, height) ;
  repl_image(DISP_OTHER, CUROFF, width, height) ;

  if (mtype == MONNEW && old_pr[(int) DISP_NAME] != NULL)
    XCopyArea(dpy, old_pr[(int) DISP_NAME], pr[(int) DISP_NAME], gc, 0, 0,
              (unsigned int) width, (unsigned int) height, 0, 0) ;
  if (mtype == MONNEW && old_pr[(int) DISP_OTHER] != NULL)
    XCopyArea(dpy, old_pr[(int) DISP_OTHER], pr[(int) DISP_OTHER], gc, 0, 0,
              (unsigned int) width, (unsigned int) height, 0, 0) ;
}


destroy_image(itype)
enum icon_type itype ;
{
  if (images[(int) itype] != NULL)
    {
      XFreePixmap(dpy, images[(int) itype]) ;
      images[(int) itype] = NULL ;
    }
}


static Notify_value
frame_interpose(frame, event, arg, type)
Frame frame ;
Event *event ;
Notify_arg arg ;
Notify_event_type type ;
{
  Notify_value rc ;

  rc = notify_next_event_func(frame, event, arg, type) ;
  if (event_action(event) == ACTION_CLOSE)
    {
      XCopyArea(dpy, pr[(int) DISP_ICON], xid[F_ICON], gc, 0, 0, 
                imagewidth, imageheight, 0, 0) ; 
    }
  return(rc) ;
}


init_font()
{
  if (!(sfont = XLoadQueryFont(dpy, FONT)))
    if (!(sfont = XLoadQueryFont(dpy, DEF_FONT)))
      {
        perror("couldn't get the default font.") ;
        exit(1) ;
      }
}


init_ws_type(argc, argv)
int argc ;
char *argv[] ;
{
  int i, j ;
  unsigned short buf[256] ;

  xv_init(XV_INIT_ARGS, argc, argv, 0) ;
  frame = xv_create(XV_NULL, FRAME, 0) ;   /* Needed to get Xlib handles now.*/

  faces_icon = xv_create(XV_NULL,   ICON,
                         XV_WIDTH,  imagewidth,
                         XV_HEIGHT, imageheight,
                         0) ;
  xid[F_ICON] = (Drawable) xv_get(faces_icon, XV_XID) ;

  dpy  = (Display *) xv_get(frame, XV_DISPLAY) ;
  screen  = DefaultScreen(dpy) ;
  root = RootWindow(dpy, screen) ;
  foregnd = BlackPixel(dpy, screen) ;
  backgnd = WhitePixel(dpy, screen) ;
  depth = DefaultDepth(dpy, screen) ;

  init_font() ;

  gc_mask = GCFont | GCForeground | GCBackground | GCGraphicsExposures ;
  gc_val.font = sfont->fid ;
  gc_val.foreground = foregnd ;
  gc_val.background = backgnd ;
  gc_val.graphics_exposures = False ;
  gc = XCreateGC(dpy, root, gc_mask, &gc_val) ;

  tilegc = XCreateGC(dpy, root, gc_mask, &gc_val) ;
  if (depth == 1) XSetFillStyle(dpy, tilegc, FillOpaqueStippled) ;
  else            XSetFillStyle(dpy, tilegc, FillTiled) ;

  for (i = 0; i < 16; i++)    /* Load default gray background. */
    {
      for (j = 0; j < 4; j++) buf[i * 16      + j] = 0x7777 ;
      for (j = 0; j < 4; j++) buf[i * 16 +  4 + j] = 0xDDDD ;
      for (j = 0; j < 4; j++) buf[i * 16 +  8 + j] = 0xBBBB ;
      for (j = 0; j < 4; j++) buf[i * 16 + 12 + j] = 0xEEEE ;
    }

  if (strlen(bgicon)) GET_SUN_ICON(bgicon, buf) ;
  load_icon(BACKGROUND, buf) ;

  STRCPY(fname[0], "sun.icon") ;
  STRCPY(fname[1], "48x48x1") ;
  STRCPY(fname[2], "face.xbm") ;
  maxtypes = 3 ;
  gtype = XVIEW ;
  pr[(int) DISP_NAME] = pr[(int) DISP_OTHER] = NULL ;
  old_pr[(int) DISP_NAME] = old_pr[(int) DISP_OTHER] = NULL ;
  toclear = 0 ;
  return 0 ;
}


/* Create a server image from given image data. */

/*ARGSUSED*/
load_icon(itype, sbuf, not_flipped)
enum icon_type itype ;
unsigned short sbuf[256] ;
int not_flipped ;
{
  char cbuf[512] ;
  int i ;

  for (i = 0; i < 256; i++)
    {
      cbuf[i*2+0] = revtable[(sbuf[i] >> 8) & 0xFF] ;
      cbuf[i*2+1] = revtable[sbuf[i] & 0xFF] ;
    }
  images[(int) itype] = XCreatePixmapFromBitmapData(dpy, root,
                                           cbuf, iconwidth, iconheight,
                                           foregnd, backgnd, depth) ;
}


make_area(dtype, width, height)
enum disp_type dtype ;
int width, height ;
{
  pr[(int) dtype] = XCreatePixmap(dpy, root, (unsigned int) width,
                                  (unsigned int) height, depth) ;
  XSetFunction(dpy, gc, GXandInverted) ;
  XFillRectangle(dpy, pr[(int) dtype], gc, 0, 0, width, height) ;
  XSetFunction(dpy, gc, GXcopy) ;
}


/*ARGSUSED*/
make_frame(argc, argv)
int argc ;
char *argv[] ;
{
  XV_SET(frame,
         FRAME_ICON,                  faces_icon,
         FRAME_LABEL,                 "faces",
         FRAME_NO_CONFIRM,            TRUE,
         FRAME_SHOW_FOOTER,           FALSE,
         XV_WIDTH,                    maxcols * imagewidth,
         XV_HEIGHT,                   imageheight * 10,
         0) ;
  NOTIFY_INTERPOSE_EVENT_FUNC(frame, frame_interpose, 0) ;

  canvas = xv_create(frame,               CANVAS,
                     CANVAS_REPAINT_PROC, repaint_proc,
                     CANVAS_RETAINED,     FALSE,
                     CANVAS_PAINTWINDOW_ATTRS,
                     WIN_CONSUME_EVENTS,
                       MS_LEFT, WIN_ASCII_EVENTS,
                       WIN_LEFT_KEYS, WIN_TOP_KEYS, WIN_RIGHT_KEYS,
                       0,
                     WIN_IGNORE_EVENTS,
                       LOC_MOVE, LOC_DRAG,
                       0,
                     WIN_EVENT_PROC, canvas_proc,
                       0,
                     0) ;

  pw = canvas_paint_window(canvas) ;
  xid[F_WINDOW] = (Drawable) xv_get(pw, XV_XID) ;

  width = maxcols * imagewidth ;
  height = imageheight ;
}


make_icon()
{
  if (mtype == MONPRINTER) adjust_image(DISP_ICON, NOPRINT, 0, 0) ;
  else                     adjust_image(DISP_ICON, NOMAIL,  0, 0) ;
}


/*ARGSUSED*/
repaint_proc(canvas, window, repaint_area)
Canvas canvas ;
Xv_Window window ;
Rectlist *repaint_area ;
{
  XCopyArea(dpy, pr[(int) wdtype], xid[F_WINDOW], gc, 0, 0,
            (unsigned int) width, (unsigned int) height, 0, 0) ;
}


repl_image(dtype, dest, width, height)
enum disp_type dtype ;
enum image_type dest ;
int width, height ;
{
  Pixmap dpm ;

  if (dest == CUROFF) dpm = pr[(int) dtype] ;
  else dpm = old_pr[(int) dtype] ;
  if (depth == 1) XSetStipple(dpy, tilegc, images[(int) BACKGROUND]) ;
  else XSetTile(dpy, tilegc, images[(int) BACKGROUND]) ;
  XFillRectangle(dpy, dpm, tilegc, 0, 0, width, height) ;
}


show_display()    /* Show the latest set of mail icon faces. */
{
  Rect *temprect ;

  if (invert)     /* Invert the memory pixrects before displaying. */
    {
      XSetFunction(dpy, gc, GXcopyInverted) ;
      XCopyArea(dpy, pr[(int) DISP_NAME], pr[(int) DISP_NAME], gc, 0, 0,
                (unsigned int) width, (unsigned int) height, 0, 0) ;
      XCopyArea(dpy, pr[(int) DISP_OTHER], pr[(int) DISP_OTHER], gc, 0, 0,
                (unsigned int)  width, (unsigned int) height, 0, 0) ;
    }

  XCopyArea(dpy, pr[(int) DISP_ICON], xid[F_ICON], gc, 0, 0,
            (unsigned int) width, (unsigned int) height, 0, 0) ;
 
  temprect = (Rect *) xv_get(frame, FRAME_OPEN_RECT) ;
  temprect->r_height = height ;
  temprect->r_width = width ;
  XV_SET(frame, FRAME_OPEN_RECT, temprect, 0) ;

  XCopyArea(dpy, pr[(int) wdtype], xid[F_WINDOW], gc, 0, 0,
            (unsigned int) width, (unsigned int) height, 0, 0) ;

  if (newmail) beep_flash(beeps, flashes) ;
  if (old_pr[(int) DISP_NAME])  XFreePixmap(dpy, old_pr[(int) DISP_NAME]) ;
  if (old_pr[(int) DISP_OTHER]) XFreePixmap(dpy, old_pr[(int) DISP_OTHER]) ;
  old_pr[(int) DISP_NAME] = NULL ;
  old_pr[(int) DISP_OTHER] = NULL ;
  XSync(dpy, 0) ;
}


start_tool()
{
  struct itimerval tval ;

  tval.it_interval.tv_usec = 0 ;
  tval.it_interval.tv_sec = period ;
  tval.it_value.tv_usec = 0 ;
  tval.it_value.tv_sec = period ;
  NOTIFY_SET_ITIMER_FUNC(frame, check_mail,
                         ITIMER_REAL, &tval, ITIMER_NULL) ;
  xv_main_loop(frame) ;
}


text(dtype, jtype, str)
enum disp_type dtype ;
enum just_type jtype ;
char *str ;
{
  int len ;
  int c, r ;         /* Column and row position for this face. */
  int x, y ;         /* Position of start of this text string. */

  c = column ;
  r = row ;
  switch (dtype)
    {
      case DISP_ALL    : text(DISP_ICON,  jtype, str) ;
      case DISP_BOTH   : text(DISP_NAME,  jtype, str) ;
                         text(DISP_OTHER, jtype, str) ;
                         return ;
      case DISP_ICON   : c = r = 0 ;
    }

  if ((len = strlen(str)) > 10)      /* Character length of text. */
    {
      len = 10 ;
      str[10] = '\0' ;               /* Maximum of 10 characters. */
    }
  switch (jtype)
    {
      case LEFT  : x =  c      * imagewidth + 2 ;
                   y = (r + 1) * imageheight - 5 ;
                   break ;
      case RIGHT : x = (c + 1) * imagewidth - (len * 6) - 2 ;
                   y = (r + 1) * imageheight - 5 ;
    }
  XSetFunction(dpy, gc, GXandInverted) ;
  XFillRectangle(dpy, pr[(int) dtype], gc, x, y-9, (unsigned int) len*6+2, 13) ;
  XSetFunction(dpy, gc, GXxor) ;
  XDrawImageString(dpy, pr[(int) dtype], gc, x, y, str, strlen(str)) ;
  XSetFunction(dpy, gc, GXcopy) ;
}
Funky_Stuff
len=`wc -c < xview.c`
if [ $len !=    12752 ] ; then
echo error: xview.c was $len bytes long, should have been    12752
fi
fi # end of overwriting check
if [ -f x11.c ]
then
echo shar: will not over-write existing file x11.c
else
echo shar: extracting 'x11.c',    16665 characters
cat > x11.c <<'Funky_Stuff'

/*  @(#)x11.c 1.12 90/06/26
 *
 *  X11 dependent graphics routines used by faces,
 *  the visual mail and print job monitor.
 * 
 *  Copyright (c) Rich Burridge - Sun Microsystems Australia.
 *                                All rights reserved.
 *
 *  Permission is given to distribute these sources, as long as the
 *  copyright messages are not removed, and no monies are exchanged. 
 * 
 *  No responsibility is taken for any errors or inaccuracies inherent
 *  either to the comments or the code of this program, but if reported
 *  to me, then an attempt will be made to fix them.
 *
 */
 
#include <stdio.h>
#include <sys/time.h>
#include "faces.h"
#include "extern.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
 
#define  DEF_FONT            "fixed"
#define  F_ICON              0         /* Icon index to frame array. */
#define  F_WINDOW            1         /* Window index to frame array. */
#define  FACES_BORDER_WIDTH  2
#define  FONT                "times-roman-10"
#define  FRAME_MASK          (ButtonPressMask  | ExposureMask | \
                              ButtonMotionMask | KeyPressMask)

Atom protocol_atom, kill_atom ;
Display *dpy ;
GC gc ;
GC tilegc ;
Pixmap faces_icon ;

/* Array of the different icon images. */
Pixmap images[MAXICONS] = {
  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
} ;

Pixmap pr[3] = { NULL, NULL, NULL } ;    /* Current memory Pixmaps. */
Pixmap old_pr[2] = { NULL, NULL } ;      /* Previous memory Pixmaps. */
Window frame[2] ;
Window root ;
XFontStruct *sfont ;
XGCValues gc_val ;
XSizeHints size ;
XWMHints wm_hints ;
 
#ifdef NO_43SELECT
int fullmask ;               /* Full mask of file descriptors to check on. */
int readmask ;               /* Readmask used in select call. */
#else
fd_set fullmask ;            /* Full mask of file descriptors to check on. */
fd_set readmask ;            /* Readmask used in select call. */
#endif /*NO_43SELECT*/

unsigned long gc_mask ;
int screen ;
int toclear ;                /* Set if faces icon needs clearing. */
int xfd ;                    /* File descriptor for X11 server connection. */
unsigned int depth ;
long backgnd, foregnd ;
 

adjust_image(dtype, itype, row, column)  /* Put new face in memory pixrect. */
enum disp_type dtype ;
enum icon_type itype ;
int row, column ;
{
  if (mtype == MONNEW)
    XCopyArea(dpy, pr[(int) dtype], pr[(int) dtype], gc, 0, 0,
              (maxcols-1)*imagewidth, imageheight, imagewidth, 0) ;
  XCopyArea(dpy, images[(int) itype], pr[(int) dtype], gc, 0, 0,
            imagewidth, imageheight, column*imagewidth, row*imageheight) ;
}

 
beep_flash(beeps, flashes)    /* Perform visual feedback. */
int beeps, flashes ;
{
  static struct timeval btime = { 0, 250000 } ;   /* Beep timer. */

  while (beeps > 0)
    {
      XBell(dpy, 56) ;
      SELECT(0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &btime) ;
      beeps-- ;
    }
  while (flashes > 0)
    {
      XSetFunction(dpy, gc, GXcopyInverted) ;
      XCopyArea(dpy, frame[F_WINDOW], frame[F_WINDOW], gc, 0, 0,
                (unsigned int) width, (unsigned int) height, 0, 0) ;
      XCopyArea(dpy, frame[F_WINDOW], frame[F_WINDOW], gc, 0, 0,
                (unsigned int) width, (unsigned int) height, 0, 0) ;

      XCopyArea(dpy, frame[F_ICON], frame[F_ICON], gc, 0, 0,
                (unsigned int) width, (unsigned int) height, 0, 0) ;
      XCopyArea(dpy, frame[F_ICON], frame[F_ICON], gc, 0, 0,
                (unsigned int) width, (unsigned int) height, 0, 0) ;
      flashes-- ;
    }
  XSetFunction(dpy, gc, GXcopy) ;
}


create_pixrects(width, height)   /* Create pixrects for the face images. */
int width, height ;
{
  old_pr[(int) DISP_NAME]  = pr[(int) DISP_NAME] ;
  old_pr[(int) DISP_OTHER] = pr[(int) DISP_OTHER] ;

  make_area(DISP_NAME, width, height) ;
  repl_image(DISP_NAME, CUROFF, width, height) ;

  if (toclear && mtype == MONNEW)
    {
      repl_image(DISP_OTHER, OLDOFF, width, height) ;
      toclear = 0 ;
    }
    
  make_area(DISP_OTHER, width, height) ;
  repl_image(DISP_OTHER, CUROFF, width, height) ;
 
  if (mtype == MONNEW && old_pr[(int) DISP_NAME] != NULL)
    XCopyArea(dpy, old_pr[(int) DISP_NAME], pr[(int) DISP_NAME], gc, 0, 0,
              (unsigned int) width, (unsigned int) height, 0, 0) ;
  if (mtype == MONNEW && old_pr[(int) DISP_OTHER] != NULL)
    XCopyArea(dpy, old_pr[(int) DISP_OTHER], pr[(int) DISP_OTHER], gc, 0, 0,
              (unsigned int) width, (unsigned int) height, 0, 0) ;
}


destroy_image(itype)
enum icon_type itype ;
{
  if (images[(int) itype] != NULL)
    {
      XFreePixmap(dpy, images[(int) itype]) ;
      images[(int) itype] = NULL ;
    }
}


init_font()
{
  if ((sfont = XLoadQueryFont(dpy, FONT)) == NULL)
    if ((sfont = XLoadQueryFont(dpy, DEF_FONT)) == NULL)
      {
        perror("couldn't get the default font.") ;
        exit(1) ;
      }
}


/*ARGSUSED*/
init_ws_type(argc, argv)
int argc ;
char *argv[] ;
{
  int i, j ;
  unsigned short buf[256] ;

  if ((dpy = XOpenDisplay(display)) == NULL)
    {
      FPRINTF(stderr,"%s: Couldn't open display %s\n", progname,
              (getenv ("DISPLAY") ? getenv("DISPLAY") : display)) ;
      exit(1) ;
    }
  xfd = ConnectionNumber(dpy) ;

#ifdef NO_43SELECT
  fullmask = 1 << xfd ;
#else
  FD_ZERO(&fullmask) ;
  FD_SET(xfd, &fullmask) ;
#endif /*NO_43SELECT*/

  screen = DefaultScreen(dpy) ;
  root = RootWindow(dpy, screen) ;
  if (geometry[0] != '\0')
    STRCPY(geometry, XGetDefault(dpy, progname, "Geometry")) ;

  foregnd = BlackPixel(dpy, screen) ;
  backgnd = WhitePixel(dpy, screen) ;
  depth = DefaultDepth(dpy, screen) ;

  init_font() ;

  gc_mask = GCFont | GCForeground | GCBackground | GCGraphicsExposures ;
  gc_val.font = sfont->fid ;
  gc_val.foreground = foregnd ;
  gc_val.background = backgnd ;
  gc_val.graphics_exposures = False ;
  gc = XCreateGC(dpy, root, gc_mask, &gc_val) ;
    
  tilegc = XCreateGC(dpy, root, gc_mask, &gc_val) ;
  if (depth == 1) XSetFillStyle(dpy, tilegc, FillOpaqueStippled) ;
  else            XSetFillStyle(dpy, tilegc, FillTiled) ;

  for (i = 0; i < 16; i++)    /* Load default gray background. */
    {
      for (j = 0; j < 4; j++) buf[i * 16      + j] = 0x7777 ;
      for (j = 0; j < 4; j++) buf[i * 16 +  4 + j] = 0xDDDD ;
      for (j = 0; j < 4; j++) buf[i * 16 +  8 + j] = 0xBBBB ;
      for (j = 0; j < 4; j++) buf[i * 16 + 12 + j] = 0xEEEE ;
    }
 
  if (strlen(bgicon)) GET_SUN_ICON(bgicon, buf) ;
  load_icon(BACKGROUND, buf) ;

  STRCPY(fname[0], "face.xbm") ;
  STRCPY(fname[1], "sun.icon") ;
  STRCPY(fname[2], "48x48x1") ;
  maxtypes = 3 ;
  gtype = X11 ;
  pr[(int) DISP_NAME] = pr[(int) DISP_OTHER] = NULL ;
  old_pr[(int) DISP_NAME] = old_pr[(int) DISP_OTHER] = NULL ;
  toclear = 0 ;
  return(0) ;
}


/*ARGSUSED*/
static Bool
is_exposed(dpy, ev, window)   /* Return True if window is being exposed */
Display *dpy ;
XEvent *ev ;
char *window ;
{
  if (ev->type == Expose && *((Window *) window) == ev->xkey.window)
    return True ;
  return False ;
}


/*ARGSUSED*/
load_icon(itype, sbuf, not_flipped)
enum icon_type itype ;
unsigned short sbuf[256] ;
int not_flipped ;
{
  char cbuf[512] ;
  int i ;

  for (i = 0; i < 256; i++)
    {
      cbuf[i*2+0] = revtable[(sbuf[i] >> 8) & 0xFF] ;
      cbuf[i*2+1] = revtable[sbuf[i] & 0xFF] ;
    }
  images[(int) itype] = XCreatePixmapFromBitmapData(dpy, root,
                                           cbuf, iconwidth, iconheight,
                                           foregnd, backgnd, depth) ;
}


make_area(dtype, width, height)
enum disp_type dtype ;
int width, height ;
{
  pr[(int) dtype] = XCreatePixmap(dpy, root,
                      (unsigned int) width, (unsigned int) height, depth) ;
  XSetFunction(dpy, gc, GXandInverted) ;
  XFillRectangle(dpy, pr[(int) dtype], gc, 0, 0, width, height) ;
  XSetFunction(dpy, gc, GXcopy) ;
}


/*ARGSUSED*/
make_frame(argc, argv)
int argc ;
char *argv[] ;
{
  unsigned int h, w ;                /* Window dimensions. */
  int flags ;
  int x, y ;                         /* Window position. */
  XSetWindowAttributes winattrs ;

  w = width = maxcols * imagewidth ;
  h = height = imageheight ;

  size.flags = PMinSize | PMaxSize | PPosition | PSize ;
  size.x = 0 ;
  size.y = 0 ;
  size.min_width = imagewidth ;
  size.min_height = imageheight ;
  size.max_width = size.width = width ;
  if (mtype == MONNEW) size.max_height = imageheight ;
  else                 size.max_height = 900 ;
  size.height = height ;

  if (strlen(geometry))
    {
      flags = XParseGeometry(geometry, &x, &y, &w, &h) ;
      if (XValue & flags)
        {
          if (XNegative & flags)
            x = DisplayWidth(dpy, screen) + x - size.width ;
            size.flags |= USPosition ;
            size.x = x ;
        }
      if (YValue & flags)
        {
          if (YNegative & flags)
            y = DisplayHeight(dpy, screen) + y - size.height ;
            size.flags |= USPosition ;
            size.y = y ;
        }
    }

#ifdef WANTED
  frame[F_WINDOW] = XCreateSimpleWindow(dpy, root,
                                        size.x, size.y, size.width, size.height,
                                        FACES_BORDER_WIDTH, foregnd, backgnd) ;

  frame[F_ICON] = XCreateSimpleWindow(dpy, root,
                                      ix, iy, imagewidth, imageheight,
                                      FACES_BORDER_WIDTH, foregnd, backgnd) ;
#endif /*WANTED*/

  winattrs.background_pixel = backgnd ;
  winattrs.border_pixel = foregnd ;
  winattrs.event_mask = FRAME_MASK ;

  frame[F_WINDOW] = XCreateWindow(dpy, root, size.x, size.y,
                        size.width, size.height, FACES_BORDER_WIDTH,
                        CopyFromParent, InputOutput, CopyFromParent,
                        CWBackPixel | CWBorderPixel | CWEventMask, &winattrs) ;

  frame[F_ICON] = XCreateWindow(dpy, root,
                        ix, iy, imagewidth, imageheight, FACES_BORDER_WIDTH,
                        CopyFromParent, InputOutput, CopyFromParent, 
                        CWBackPixel | CWBorderPixel | CWEventMask, &winattrs) ;

  protocol_atom = XInternAtom(dpy, "WM_PROTOCOLS", False) ;
  kill_atom = XInternAtom(dpy, "WM_DELETE_WINDOW", False) ;
  XSetWMProtocols(dpy, frame[F_WINDOW], &kill_atom, 1) ;

  XSetStandardProperties(dpy, frame[F_WINDOW], "faces", "faces", None,
                         argv, argc, &size) ;
 
  wm_hints.icon_x = ix ;
  wm_hints.icon_y = iy ;
  wm_hints.input = True ;
  wm_hints.icon_window = frame[F_ICON] ;
  wm_hints.flags = IconPositionHint | InputHint | IconWindowHint ;
  if (iconic)
    {    
      wm_hints.initial_state = IconicState ;
      wm_hints.flags |= StateHint ;
    }    
  XSetWMHints(dpy, frame[F_WINDOW], &wm_hints) ;
/**  XSetWMHints(dpy, frame[F_ICON],   &wm_hints) ; **/

/* Equivalent of make_icon. */

  if (mtype == MONPRINTER) adjust_image(DISP_ICON, NOPRINT, 0, 0) ;
  else                     adjust_image(DISP_ICON, NOMAIL,  0, 0) ;
}
 

make_icon()         /* Null routine. */
{}


repl_image(dtype, dest, width, height)
enum disp_type dtype ;
enum image_type dest ;
int width, height ;
{
  Pixmap dpm ;

  if (dest == CUROFF) dpm = pr[(int) dtype] ;
  else dpm = old_pr[(int) dtype] ;
  if (depth == 1) XSetStipple(dpy, tilegc, images[(int) BACKGROUND]) ;
  else XSetTile(dpy, tilegc, images[(int) BACKGROUND]) ;
  XFillRectangle(dpy, dpm, tilegc, 0, 0, width, height) ;
}


show_display()    /* Show the latest set of mail icon faces. */
{
  XEvent ev ;
  static int first_time = 1 ;

  if (invert)     /* Invert the memory pixrects before displaying. */
    {
      XSetFunction(dpy, gc, GXcopyInverted) ;
      XCopyArea(dpy, pr[(int) DISP_NAME], pr[(int) DISP_NAME], gc, 0, 0,
                (unsigned int) width, (unsigned int) height, 0, 0) ;
      XCopyArea(dpy, pr[(int) DISP_OTHER], pr[(int) DISP_OTHER], gc, 0, 0,
                (unsigned int)  width, (unsigned int) height, 0, 0) ;
    }
  if (first_time)
    {
      XSelectInput(dpy, frame[F_WINDOW], FRAME_MASK) ;
      XMapWindow(dpy, frame[F_WINDOW]) ;
      XSync(dpy, 0) ;
      XPeekIfEvent(dpy, &ev, is_exposed, (char *) &frame[F_WINDOW]) ;
      first_time = 0 ;
    }

  XCopyArea(dpy, pr[(int) DISP_ICON], frame[F_ICON], gc, 0, 0,
            (unsigned int) width, (unsigned int) height, 0, 0) ;

  XResizeWindow(dpy, frame[F_WINDOW],
                (unsigned int) width, (unsigned int) height) ;
  XCopyArea(dpy, pr[(int) wdtype], frame[F_WINDOW], gc, 0, 0,
            (unsigned int) width, (unsigned int) height, 0, 0) ;
 
  if (newmail) beep_flash(beeps, flashes) ;
  if (old_pr[(int) DISP_NAME])  XFreePixmap(dpy, old_pr[(int) DISP_NAME]) ;
  if (old_pr[(int) DISP_OTHER]) XFreePixmap(dpy, old_pr[(int) DISP_OTHER]) ;
  old_pr[(int) DISP_NAME] = NULL ;
  old_pr[(int) DISP_OTHER] = NULL ;
  XSync(dpy, 0) ;
}
 

start_tool()
{
  struct timeval tval ;          /* To set checking period. */
  XEvent event ;                 /* For events received. */
  XClientMessageEvent *ev ;
  XKeyPressedEvent *key_event ;
  char chs[2] ;
 
  tval.tv_usec = 0 ;
  tval.tv_sec = period ;

  for (;;)
    {
      readmask = fullmask ;
#ifdef NO_43SELECT
      SELECT(32, &readmask, 0, 0, &tval) ;
      if (readmask && (1 << xfd))
#else
      SELECT(FD_SETSIZE, &readmask, (fd_set *) 0, (fd_set *) 0, &tval) ;
      if (FD_ISSET(xfd, &readmask))
#endif /*NO_43SELECT*/
        do
          {
            XNextEvent(dpy, &event) ;

/* ClientMessage: (catch ICCCM kill from WM). */

            if (event.type == ClientMessage)
              {
                ev = (XClientMessageEvent *) &event ;
                if (ev->message_type == protocol_atom &&
                  ev->data.l[0] == kill_atom)
                exit(0) ;
              }

/* Expose. */

            else if (event.type == Expose && event.xexpose.count == 0)
              {
                while (XCheckTypedEvent(dpy, Expose, &event)) /* do nothing. */ ;
                XCopyArea(dpy, pr[(int) wdtype],
                          frame[F_WINDOW], gc, 0, 0,
                          (unsigned int) width, (unsigned int) height, 0, 0) ;
                XCopyArea(dpy, pr[(int) DISP_ICON],
                          frame[F_ICON], gc, 0, 0,
                          (unsigned int) width, (unsigned int) height, 0, 0) ;
              }

/* ButtonPress. */

            else if (event.type == ButtonPress        &&
                     event.xbutton.button == Button1)
              {
                wdtype = (wdtype == DISP_NAME) ? DISP_OTHER : DISP_NAME ;
                XCopyArea(dpy, pr[(int) wdtype],
                          frame[F_WINDOW], gc, 0, 0,
                          (unsigned int) width, (unsigned int) height, 0, 0) ;
              }

/* KeyPress. */

            else if (mtype == MONNEW && event.type == KeyPress)
              {
                key_event = (XKeyPressedEvent *) &event ;
                (void) XLookupString(key_event, chs, 1, (KeySym *) NULL,
                                     (XComposeStatus *) NULL) ;
                if (chs[0] == DEL)
                  {
                    repl_image(DISP_NAME,  CUROFF, width, height) ;
                    repl_image(DISP_OTHER, CUROFF, width, height) ;
                    toclear = 1 ;
                    do_check() ;
                  }
              }
          }
        while (XPending(dpy)) ;
      else do_check() ;     /* Check the mail/printer/user queue again. */
    }
}
 

text(dtype, jtype, str)
enum disp_type dtype ;
enum just_type jtype ;
char *str ;
{
  int len ;
  int c, r ;         /* Column and row position for this face. */
  int x, y ;         /* Position of start of this text string. */
 
  c = column ;
  r = row ;
  switch (dtype)
    {
      case DISP_ALL    : text(DISP_ICON,  jtype, str) ;
      case DISP_BOTH   : text(DISP_NAME,  jtype, str) ;
                         text(DISP_OTHER, jtype, str) ;
                         return ;
      case DISP_ICON   : c = r = 0 ;
    }
 
  if ((len = strlen(str)) > 10)     /* Character length of text. */
    {
      len = 10 ;
      str[10] = '\0' ;              /* Maximum of 10 characters. */
    }
  switch (jtype)
    {
      case LEFT  : x =  c      * imagewidth + 2 ;
                   y = (r + 1) * imageheight - 5 ;
                   break ;
      case RIGHT : x = (c + 1) * imagewidth - (len * 6) - 2 ;
                   y = (r + 1) * imageheight - 5 ;
    }
  XSetFunction(dpy, gc, GXandInverted) ;
  XFillRectangle(dpy, pr[(int) dtype], gc, x, y-9, (unsigned int) len*6+2, 13) ;
  XSetFunction(dpy, gc, GXxor) ;
  XDrawImageString(dpy, pr[(int) dtype], gc, x, y, str, strlen(str)) ;
  XSetFunction(dpy, gc, GXcopy) ;
}
Funky_Stuff
len=`wc -c < x11.c`
if [ $len !=    16665 ] ; then
echo error: x11.c was $len bytes long, should have been    16665
fi
fi # end of overwriting check
if [ -f extern.h ]
then
echo shar: will not over-write existing file extern.h
else
echo shar: extracting 'extern.h',     5702 characters
cat > extern.h <<'Funky_Stuff'

/*  @(#)extern.h 1.13 90/06/26
 *
 *  Contains the external variable definitions used by faces.
 *
 *  Copyright (c) Rich Burridge.
 *                Sun Microsystems, Australia - All rights reserved.
 *
 *  Permission is given to distribute these sources, as long as the
 *  copyright messages are not removed, and no monies are exchanged. 
 *
 *  No responsibility is taken for any errors or inaccuracies inherent
 *  either to the comments or the code of this program, but if
 *  reported to me then an attempt will be made to fix them.
 */

extern char *getname(), *strlower() ;
extern int do_check() ;
struct recinfo *rec_exists() ;

extern struct comminfo *communities ;  /* Community alias/username chain. */
extern struct comminfo *clast ;        /* End of chain of community records. */
extern struct machinfo *machines ;     /* Known machine/communities. */
extern struct machinfo *mlast ;        /* End of chain of machine records. */
extern struct psinfo *psrecs ;   /* List of news.ps animation files. */
extern struct psinfo *plast ;    /* End of chain of NeWS animation files. */
extern struct recinfo *recs ;    /* Mail messages being monitored. */
extern struct recinfo *last ;    /* End of the chain of mail records. */
extern struct stat buf ;         /* Buffer for stat call for file existence. */
extern long lastsize ;           /* Last known size of the mail folder. */

extern enum disp_type wdtype ;   /* Current window display option. */
extern enum gr_type gtype ;  /* Indicates what graphics system is being used. */
extern enum mon_type mtype ; /* What type of monitoring we should do. */

extern char bgicon[] ;     /* Alternate background pattern. */
extern char community[] ;  /* Community name ("real" host name). */
extern char defdir[] ;     /* The default face directory. */
extern char display[] ;    /* X11 display information. */
extern char face_buf[] ;   /* Buffer for "X-Face" face images. */
extern char face_host[] ;  /* Pointer to host name from the "From" line. */
extern char face_ts[] ;    /* Pointer to time stamp from the "From" line. */
extern char face_user[] ;  /* Pointer to user name from the "From" line. */
extern char facedir[] ;    /* Alternate face image directory. */
extern char fname[MAXTYPES][MAXLINE] ;  /* Array of various face name types. */
extern char geometry[] ;   /* X11 geometry information. */
extern char hostname[] ;   /* Machine name to monitor. */
extern char iconname[] ;   /* Name of the icon file for this person. */
extern char line[] ;       /* Next line from users mail spool file. */
extern char machfile[] ;   /* Name of the machine/community file. */
extern char nextline[] ;   /* Input/conversion buffer for various routines. */
extern char peopfile[] ;   /* Name of the people/username file. */
extern char printer[] ;    /* Printer name to monitor. */
extern char progname[] ;   /* Name of this program. */
extern char realname[] ;   /* Real username for this user. */
extern char revtable[] ;   /* Table for reversing the bits in a byte. */
extern char spoolfile[] ;  /* Full pathname of users current mail. */
extern char update_alias[] ;   /* Name of mail alias for database updates. */
extern char userprog[] ;   /* User supplied program to run. */

extern int beeps ;         /* Number of beeps for arrival of new mail. */
extern int column ;        /* Column number for next icon. */
extern int doing_xface ;   /* Set if we've started to process an X-Face: */
extern int dontshowno ;    /* Set if no. of messages shouldn't  be shown. */
extern int dontshowtime ;  /* Set if timestamp shouldn't be shown. */
extern int dontshowuser ;  /* Set if username shouldn't be shown. */
extern int facetype ;      /* Type of face file found. */
extern int firsttime ;     /* Zeroised after first mail/printer check. */
extern int flashes ;       /* Number of flashes for arrival of new mail. */
extern int found ;         /* Set if iconname found under username directory. */
extern int fromc_found ;   /* Set if "From:" line found during processing. */
extern int froms_found ;   /* Set if "From " line found during processing. */
extern int height ;        /* Height in pixels of faces display. */
extern int iconheight ;    /* Height of an individual icon. */
extern int iconwidth ;     /* Width of an individual icon. */
extern int iconic ;        /* Start as an icon if set. */
extern int imageheight ;   /* Height of an individual face image. */
extern int imagewidth ;    /* Width of an individual face image. */
extern int invert ;        /* Set if to use reverse video. */
extern int ix ;            /* Initial X position of the icon. */
extern int iy ;            /* Initial Y position of the icon. */
extern int maxcols ;       /* Maximum number of columns to display. */
extern int maxtypes ;      /* Max. no. of icon types for graphics target. */
extern int mhflag ;        /* Set if this user uses MH to read mail. */
extern int newmail ;       /* Set if there is new mail this time around. */
extern int noicons ;       /* Number of faces this time around. */
extern int old_style ;     /* Set when "old" style face ikon is found. */
extern int period ;        /* Period in seconds for checking new mail. */
extern int posspec ;       /* Set if -Wp or -g option is present (for X11) */
extern int row ;           /* Row number for next icon. */
extern int update ;        /* If set, send mail to update faces database. */
extern int width ;         /* Width in pixels of faces display. */
extern int wx ;            /* Initial X position of the window. */
extern int wy ;            /* Initial Y position of the window. */
extern int x_face ;        /* Set if we've extracted an "on-the-fly" face. */
Funky_Stuff
len=`wc -c < extern.h`
if [ $len !=     5702 ] ; then
echo error: extern.h was $len bytes long, should have been     5702
fi
fi # end of overwriting check
if [ -f faces.h ]
then
echo shar: will not over-write existing file faces.h
else
echo shar: extracting 'faces.h',     6241 characters
cat > faces.h <<'Funky_Stuff'

/*  @(#)faces.h 1.14 90/06/26
 *
 *  Contains all the global definitions used by faces.
 *
 *  Copyright (c) Rich Burridge - Sun Microsystems Australia.
 *                                All rights reserved.
 *
 *  Permission is given to distribute these sources, as long as the
 *  copyright messages are not removed, and no monies are exchanged. 
 *
 *  No responsibility is taken for any errors or inaccuracies inherent
 *  either to the comments or the code of this program, but if
 *  reported to me then an attempt will be made to fix them.
 */

#define  FCLOSE        (void) fclose      /* To make lint happy. */
#define  FFLUSH        (void) fflush
#define  FGETS         (void) fgets
#define  FPRINTF       (void) fprintf
#define  FPUTS         (void) fputs
#define  FSEEK         (void) fseek
#define  GETHOSTNAME   (void) gethostname
#define  GET_SUN_ICON  (void) get_sun_icon
#define  IOCTL         (void) ioctl
#define  PCLOSE        (void) pclose
#define  PUTC          (void) putc
#define  SELECT        (void) select
#define  SSCANF        (void) sscanf
#define  SPRINTF       (void) sprintf
#define  STRCAT        (void) strcat
#define  STRCPY        (void) strcpy
#define  STRNCAT       (void) strncat
#define  STRNCPY       (void) strncpy
#define  UTIME         (void) utime
#define  WRITE         (void) write

/* Window display types. */
enum disp_type { DISP_NAME,      /* Window type 1. */
                 DISP_OTHER,     /* Window type 2. */
                 DISP_ICON,      /* Icon display. */
                 DISP_BOTH,      /* Both window types. */
                 DISP_ALL,       /* Both window types and the icon. */
} ;

/* Different types of possible face images. */
enum icon_type { BACKGROUND, NOFACE, NOMAIL, NOPAPER,
                 NOPRINT, NOUSERS, ORDINARY, XFACE } ;

enum image_type { ONSCREEN, OLDOFF, CUROFF } ;   /* Image types. */

enum just_type { LEFT, RIGHT } ;                 /* Text justification. */

/* Different types of file monitoring performed by this program. */
enum mon_type { MONALL, MONNEW, MONPRINTER, MONPROG, MONUSERS } ;

/* Different graphics systems. Appropriate one set in gtype. */
enum gr_type { NEWS, SVIEW, X11, XVIEW } ;

/* Determine order for face type lookup. */
#define  NEWSTYPE        0
#define  SUNTYPE         1
#define  BLITTYPE        2
#define  X11TYPE         3

/* NeWS return event values. */
#define  DIED            100  /* Faces has been zapped. */
#define  PAINTED         101  /* Canvas/Icon needs repainting. */
#define  LEFTDOWN        102  /* Left mouse button has been pressed. */

#define  BLITHEIGHT      48       /* Maximum number of lines in a blit icon. */
#define  DEL             '\177'   /* Clear faces display. */
#define  EQUAL(str,val)  !strncmp(str,val,strlen(val))
#define  ICONHEIGHT      64   /* Default height of individual face icons. */
#define  ICONWIDTH       64   /* Default width of individual face icons. */
#define  INC             argc-- ; argv++ ;

#ifndef  LINT_CAST
#ifdef   lint
#define  LINT_CAST(arg)  (arg ? 0 : 0)
#else
#define  LINT_CAST(arg)  (arg)
#endif /*lint*/
#endif /*LINT_CAST*/

#define  MAXICONS        8    /* Maximum number of different icon types. */
#define  MAXITYPES       3    /* Maximum number of image types. */

#ifndef  MAXLINE
#define  MAXLINE         200  /* Maximum length for character strings. */
#endif   MAXLINE

#define  MAXTYPES        4    /* Maximum number of different face types. */
#define  NO_PER_ROW      10   /* Default number of faces per row. */

#ifdef  NOINDEX
#define  index        strchr
#define  rindex       strrchr
#endif /*NOINDEX*/

char *getenv(), *malloc(), *sprintf() ;
void endpwent() ;
FILE *popen() ;

/*  Various programs that are used by faces.
 *  You might need to change these on some machines.
 */

/* Monitoring the printer:        %s replaced by printer name. */
#define  PRINTDEF   "lpq -P %s"

/* Updating the faces database:   %s replaced with mail update alias name. */
#define  UPDATEDEF  "/usr/lib/sendmail -oeq -oi %s"

/* Monitoring users on a machine: %s replaced with hostname. */
#define  USERSDEF   "rusers -l %s"

/* Default definitions used by faces. They can be globally changed here. */

#define  MACHINETAB    "machine.tab"   /* Machine aliases table. */
#define  PEOPLETAB     "people.tab"    /* Username aliases table. */
#define  UPDATE_ALIAS  "facemaker"     /* Faces database update alias. */

struct machinfo                 /* Machine/community record. */
  {
    char *machine ;             /* Machine name. */
    char *community ;           /* Community it belongs to. */
    struct machinfo *next ;     /* Pointer to next record. */
  } ;

struct comminfo                 /* Community alias/username records. */
  {
    char *community ;           /* Community name. */
    struct peopinfo *people ;   /* Chain of alias/usernames. */
    struct comminfo *next ;     /* Pointer to next record. */
  } ;

struct peopinfo                 /* Username/alias record. */
  {
    char *alias ;               /* Alias for this user. */
    char *username ;            /* Real username. */
    struct peopinfo *next ;     /* Pointer to next record. */
  } ;

struct psinfo                   /* News.ps animation records. */
  {
    char *name ;                /* Full pathname of news.ps file. */
    int row ;                   /* Row number where animation will occur. */
    int column ;                /* Column number where animation will occur. */
    struct psinfo *next ;       /* Pointer to next record. */
  } ;

struct recinfo                  /* Mail/print information record. */
  {
    char *community ;           /* Community name for this person. */
    unsigned char *faceimage ;  /* X-Face image or NULL. */
    char *iconname ;            /* Name of iconfile for this person. */
    char *username ;            /* User name for this person. */
    int total ;                 /* Total number of messages/print jobs. */
    int size ;                  /* Total size in bytes of print job. */
    int update ;                /* If set, the database has been updated. */
    char ts[6] ;                /* Latest timestamp for this user. */
    struct recinfo *next ;      /* Pointer to next record. */
  } ;
Funky_Stuff
len=`wc -c < faces.h`
if [ $len !=     6241 ] ; then
echo error: faces.h was $len bytes long, should have been     6241
fi
fi # end of overwriting check
if [ -f patchlevel.h ]
then
echo shar: will not over-write existing file patchlevel.h
else
echo shar: extracting 'patchlevel.h',      561 characters
cat > patchlevel.h <<'Funky_Stuff'
 
/*  @(#)patchlevel.h 1.20 90/06/29
 *
 *  This is the current patch level for this version of faces.
 *
 *  Copyright (c) Rich Burridge.
 *		Sun Microsystems, Australia - All rights reserved.
 *
 *  Permission is given to distribute these sources, as long as the
 *  copyright messages are not removed, and no monies are exchanged. 
 *
 *  No responsibility is taken for any errors or inaccuracies inherent
 *  either to the comments or the code of this program, but if
 *  reported to me then an attempt will be made to fix them.
 */

#define  PATCHLEVEL  5
Funky_Stuff
len=`wc -c < patchlevel.h`
if [ $len !=      561 ] ; then
echo error: patchlevel.h was $len bytes long, should have been      561
fi
fi # end of overwriting check