Official patch #5 for faces v1.3; please apply it.

Rich Burridge richb at sunchat.oz
Sun Jan 29 12:09:39 AEST 1989


The majority of the code in this patch comes from David Cohrs, for
which I'm very grateful. With this patch, faces now works on vaxen
(running 4.3+NFS & X11R2), as well as Sun3s (3.x, 4.0), Sun4s (4.0)
and Sun386i (4.0).

It fixes the following problems:

Thanks to Dave Cohrs (sun!hplabs!rutgers!romano.cs.wisc.edu!dave) for
the following fixes:

1/ Makefile has been adjusted so that all the small changes needed,
   in order to compile faces on different systems are in one section.
   The README file has been updated accordingly. Faces needs to be
   compiled statically on a Sun4 running SunOS 4.0 and X11R2. The
   faces Makefile has been adjusted for this.

2/ A new option "-MH" has been added which tells faces that MH mail is
   being used. This is required because when the spoolfile shrinks, this
   should be the same as if it were removed and then grew (that it, faces
   should assume all messages in the shrunk spoolfile are new). The manual
   page has been altered to reflect this change.

3/ The command line option parsing has been changed to allow "next
   arguments" to begin with a '-'. This is because the X11 geometry
   specification: "-g -0-0" is legal.

4/ Faces now does gethostname() followed by gethostbyname() to get the
   official hostname. This allows Internet machines to specify full
   domain names for the hostname.

5/ make_iconname() has been improved so that it now knows about domain names.
   For example, if mail comes from "foo at a.b.c", it will try:
     facedir/a.b.c/foo/file
     facedir/b.c/foo/file
     facedir/c/foo/file
   And then the misc. and unknown things, it will also try the various
   substrings of "a.b.c" with the unknown user, if necessary.

6/ Removed the code that changed the username to "unknown", when the
   iconname changed to unknown. This is for all monitoring options
   except '-a'. Thanks also to C.P. Lai for pointing out this problem.

7/ Support has been added for X1[01] style bitmaps. Faces now looks for
   a file called "face.xbm" in the face directory tree, as well as the
   other possible options. Currently it's a little too forgiving on the
   file format, but it does read all correct X11 bitmap files. It allows
   the X11 bitmaps to be of any size, but only uses the upper left 64x64
   corner.

8/ The X11 graphics code has been considerably improved.

   - Support for multi-bitplane X11 displays.

   - The faces window is placed automatically if the -g option is given.

   - The initial size of the window and icon were huge. They are now the
     correct size.

   - The -WP option now correctly works.

   - The program now sets its' window and icon names to "faces".

   - Event handling wasn't happening at the right time. An appropriate
     XPending() call has been added and a loop.

   - Running faces -a and using twm, the initial XResizeWindow() is
     ignored, because the XMapWindow() gets intercepted by twm, and
     the map doesn't take place right away. the X11 code has been
     changed to wait for the first Expose event before resizing the
     window.

Thanks to C.P. Lai (sunaus!sun!daisy.sun.com!cplai) for the following
fix:

9/ Icons were not been correctly displayed on the Sun386i due to byte
   order differences. A definition has been added to the Makefile
   which must be uncommented when compiling faces on the 386i.


10/ Support has been added to use the left mouse button to clear the open
    window display with the default mail monitoring option. This is
    compatible with vismon and easily allows you to see when new mail has
    arrived. Thanks to David Cohrs for the code for the X11 version and for
    pointing out this vismon option. The manual page has been updated.

Feed this file to Larry Walls' patch program, thewn recompile.

    Rich.

------CUT HERE------CUT HERE------
*** original/Makefile	Wed Jan 18 16:30:19 1989
--- Makefile	Sun Jan 29 12:44:02 1989
***************
*** 1,7 ****
  #
  #  Makefile for faces, an icon face server, plus associated software.
  #
! #  @(#)Makefile 1.3 89/01/18
  #
  #  Copyright (c) Rich Burridge.
  #                Sun Microsystems, Australia - All rights reserved.
--- 1,7 ----
  #
  #  Makefile for faces, an icon face server, plus associated software.
  #
! #  @(#)Makefile 1.4 89/01/29
  #
  #  Copyright (c) Rich Burridge.
  #                Sun Microsystems, Australia - All rights reserved.
***************
*** 61,66 ****
--- 61,93 ----
  #
  DONTSHOWUSER     = -DDONTSHOWUSER=0
  #-------------------------------------------------------------------
+ #
+ #  There are various small changes needed when compiling faces on
+ #  different systems. These have been isolated here, and should
+ #  be uncommented if needed.
+ #
+ #  If you are running SunOS v3.x, then pr_ttext doesn't exist, and
+ #  you must uncomment this definition.
+ #
+ #TTEXT          = -DNO_PR_TTEXT
+ #
+ #  If you not running under a BSD4.3 derived system, the parameters
+ #  to the select call are different, and this definition should be
+ #  uncommented. You need to uncomment this for SunOS v3.x.
+ #
+ #SELTYPE        = -DNO_4.3SELECT
+ #
+ #  If you are running X11R2 on a Sun4, then the faces executable
+ #  needs to be statically linked to work correctly, so the following
+ #  line should be uncommented.
+ #
+ #LDX11FLAGS     = -Bstatic
+ #
+ #  If you are using a Sun386i, then the following definition should
+ #  be uncommented.
+ #
+ #ROADRUNNER     = -DSUN386i
+ #-------------------------------------------------------------------
  
  VARIABLES       = $(FMONTYPE) $(BACKGROUND) $(FACEPARAM) \
                    $(INVERT) $(PERIOD) $(DONTSHOWNO) $(SPOOLFILE) \
***************
*** 73,83 ****
  MANDIR          = /usr/man/man$(MANSECT)
  MANSECT         = l
  
! #
! #  If you are compiling faces under v3.x of SunOS, then uncomment this line.
! #OSTYPE          = -DSUNOS3.x
! 
! CFLAGS          = -g $(NEWSFILE) $(OSTYPE) $(VARIABLES)
  HDRS            = extern.h faces.h patchlevel.h
  IMAGES          = noface.icon nomail.icon noprint.icon \
  		  nopaper.icon nousers.icon
--- 100,107 ----
  MANDIR          = /usr/man/man$(MANSECT)
  MANSECT         = l
  
! CFLAGS          = -g $(NEWSFILE) $(TTEXT) $(SELTYPE) \
! 		     $(ROADRUNNER) $(VARIABLES)
  HDRS            = extern.h faces.h patchlevel.h
  IMAGES          = noface.icon nomail.icon noprint.icon \
  		  nopaper.icon nousers.icon
***************
*** 124,130 ****
  		cc -o sv_faces $(CFLAGS) $(SVOBJS) $(SVLIBS)
  
  x11_faces:      $(X11OBJS)
! 		cc -o x11_faces $(CFLAGS) $(X11OBJS) $(X11LIBS)
  
  install:        $(BINARIES)
  		install -s -m 751 faces $(BINDIR)
--- 148,154 ----
  		cc -o sv_faces $(CFLAGS) $(SVOBJS) $(SVLIBS)
  
  x11_faces:      $(X11OBJS)
! 		cc $(LDX11FLAGS) -o x11_faces $(CFLAGS) $(X11OBJS) $(X11LIBS)
  
  install:        $(BINARIES)
  		install -s -m 751 faces $(BINDIR)
*** original/README	Wed Jan 18 16:30:19 1989
--- README	Sun Jan 29 12:44:00 1989
***************
*** 23,32 ****
  sub-directories username ikons/icons, machine and people tables, and you're
  set.
  
! If you are compiling faces under v3.x of the SunOS, then there is a line in
! the Makefile starting with OSTYPE, that needs to be uncommented.
  
- 
  Faces has four different modes of operation:
  
  The default will monitor for new mail. Only the last ten messages are
--- 23,34 ----
  sub-directories username ikons/icons, machine and people tables, and you're
  set.
  
! The Makefile compilation details are setup to default to compiling faces
! on a Sun3 running SunOS v4.0. Note that there are a few small compilation
! definitions that might need uncommenting if you are trying to compile and
! run it on any other system.
! 
  
  Faces has four different modes of operation:
  
  The default will monitor for new mail. Only the last ten messages are
***************
*** 85,92 ****
  sending me a copy of the Pike/Presotto paper "Face the Nation", which I used
  to get vismon compatibility, to Jonathan Bowen for suggesting the rusers
  monitoring addition, and to everybody else who suggested enhancements, and
! fixed bugs in the previous version. And finally thanks to Neil Crellin and
! Mark Andrews for a fix to the (0,0) redraw bug with the NeWS version.
  
      Rich.
  
--- 87,96 ----
  sending me a copy of the Pike/Presotto paper "Face the Nation", which I used
  to get vismon compatibility, to Jonathan Bowen for suggesting the rusers
  monitoring addition, and to everybody else who suggested enhancements, and
! fixed bugs in the previous version. Special thanks to Neil Crellin and Mark
! Andrews for a fix to the (0,0) redraw bug with the NeWS version, to Dave
! Cohrs for several fixes and enhancements, the addition of X11 bitmap support,
! and generally sorting out most of the problems with the X11 version.
  
      Rich.
  
*** original/extern.h	Wed Jan 18 16:30:19 1989
--- extern.h	Sun Jan 29 12:43:58 1989
***************
*** 1,5 ****
  
! /*  @(#)extern.h 1.4 89/01/18
   *
   *  Contains the external variable definitions used by faces.
   *
--- 1,5 ----
  
! /*  @(#)extern.h 1.5 89/01/29
   *
   *  Contains the external variable definitions used by faces.
   *
***************
*** 44,49 ****
--- 44,50 ----
  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 revtable[] ;   /* Table for reversing the bits in a byte. */
  extern char spoolfile[] ;  /* Full pathname of users current mail. */
  
  extern int beeps ;         /* Number of beeps for arrival of new mail. */
***************
*** 59,67 ****
--- 60,70 ----
  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 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 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 width ;         /* Width in pixels of faces display. */
  extern int wx ;            /* Initial X position of the window. */
*** original/faces.1	Wed Jan 18 16:30:19 1989
--- faces.1	Sun Jan 29 12:44:00 1989
***************
*** 1,4 ****
! .\" @(#)faces.1 1.4 89/01/18
  .TH FACES 1L "2 December 1988"
  .SH NAME
  faces \- visual mail, user and print face server.
--- 1,4 ----
! .\" @(#)faces.1 1.5 89/01/29
  .TH FACES 1L "2 December 1988"
  .SH NAME
  faces \- visual mail, user and print face server.
***************
*** 5,10 ****
--- 5,13 ----
  .SH SYNOPSIS
  .B "faces
  [
+ .B \-MH
+ ]
+ [
  .B \-P
  .I printer
  ]
***************
*** 73,79 ****
  .LP
  The default will monitor for new mail. Only the last ten messages are
  displayed. In its iconic form, it is also possible to display the timestamp
! of each message, and the open window format can give the username.
  .LP
  The second choice is to monitor the whole of a mail file. The icon and open
  window display the appropriate faces, and dynamically change size as a new
--- 76,84 ----
  .LP
  The default will monitor for new mail. Only the last ten messages are
  displayed. In its iconic form, it is also possible to display the timestamp
! of each message, and the open window format can give the username. The left
! mouse button can be used with the open window, to clear the display so that
! only new mail is shown.
  .LP
  The second choice is to monitor the whole of a mail file. The icon and open
  window display the appropriate faces, and dynamically change size as a new
***************
*** 124,129 ****
--- 129,136 ----
  .br
  	/usr/local/faces/machine/uid/48x48x1
  .br
+ 	/usr/local/faces/machine/uid/face.xbm
+ .br
  	/usr/local/faces/misc./uid/face.ps
  .br
  	/usr/local/faces/misc./uid/sun.icon
***************
*** 130,135 ****
--- 137,144 ----
  .br
  	/usr/local/faces/misc./uid/48x48x1
  .br
+ 	/usr/local/faces/misc./uid/face.xbm
+ .br
  	/usr/local/faces/machine/unknown/face.ps
  .br
  	/usr/local/faces/machine/unknown/sun.icon
***************
*** 136,147 ****
--- 145,174 ----
  .br
  	/usr/local/faces/machine/unknown/48x48x1
  .br
+ 	/usr/local/faces/machine/unknown/face.xbm
+ .br
  	/usr/local/faces/misc./unknown/face.ps
  .br
  	/usr/local/faces/misc./unknown/sun.icon
  .br
  	/usr/local/faces/misc./unknown/48x48x1
+ .br
+ 	/usr/local/faces/misc./unknown/face.xbm
  .LP
+ Domain names are now fully supported. For example, if mail arrives from
+ .br
+ 	foo at a.b.c
+ .br
+ then
+ .I faces
+ will use the following directories for the machine name:
+ .br
+ 	a.b.c
+ .br
+ 	b.c
+ .br
+ 	c
+ .LP
  The directory
  .I misc.
  hold faces for generic users such as
***************
*** 171,183 ****
  for the community
  .I sunaus
  .LP
- Domain name structure would be handled in the same way. For example:
- .LP
- 	sunaus.sun.oz=sunaus
- .LP
- would map the full domain name in the community
- .I sunaus.
- .LP
  If the faces directory hierarchy is not found, then a blank face image
  will be used.
  .LP
--- 198,203 ----
***************
*** 207,212 ****
--- 227,238 ----
  .br
  .SH OPTIONS
  .TP
+ .B \-MH
+ Used when the user is using MH to read mail. MH can shrink the mail
+ spoolfile and the default mail monitoring facility within
+ .I faces
+ adjusts accordingly.
+ .TP
  .BI \-P " printer"
  Printer name to monitor. If this and a mail spool file are given with the -s
  option,
***************
*** 303,311 ****
  .B /usr/local/faces/machine.tab
  machine/community equivalences
  .SH BUGS
- The X11 version will not run on a color screen. Currently there are also
- several other minor problems with this implementation.
- .br
  The machine and people table lookup is hopelessly inefficient and
  will need to be improved as the faces database gets larger.
  .SH AUTHOR
--- 329,334 ----
*** original/faces.h	Wed Jan 18 16:30:19 1989
--- faces.h	Sun Jan 29 12:43:58 1989
***************
*** 1,5 ****
  
! /*  @(#)faces.h 1.6 89/01/18
   *
   *  Contains all the global definitions used by faces.
   *
--- 1,5 ----
  
! /*  @(#)faces.h 1.7 89/01/29
   *
   *  Contains all the global definitions used by faces.
   *
***************
*** 22,27 ****
--- 22,28 ----
  #include <sys/time.h>
  #include <pwd.h>
  #include <strings.h>
+ #include <netdb.h>
  
  #define  FCLOSE        (void) fclose      /* To make lint happy. */
  #define  FFLUSH        (void) fflush
***************
*** 64,73 ****
--- 65,76 ----
  #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  EQUAL(str,val)  !strncmp(str,val,strlen(val))
***************
*** 75,81 ****
  #define  ICONWIDTH       64   /* Width of individual face icons. */
  #define  INC             argc-- ; argv++ ;
  #define  MAXLINE         200  /* Maximum length for character strings. */
! #define  MAXTYPES        3    /* Maximum number of different face types. */
  #define  NO_PER_ROW      10   /* Number of faces per row. */
  
  char *getenv(), *malloc(), *sprintf() ;
--- 78,84 ----
  #define  ICONWIDTH       64   /* Width of individual face icons. */
  #define  INC             argc-- ; argv++ ;
  #define  MAXLINE         200  /* Maximum length for character strings. */
! #define  MAXTYPES        4    /* Maximum number of different face types. */
  #define  NO_PER_ROW      10   /* Number of faces per row. */
  
  char *getenv(), *malloc(), *sprintf() ;
*** original/faces.ps	Wed Jan 18 16:30:19 1989
--- faces.ps	Sun Jan 29 12:44:01 1989
***************
*** 1,7 ****
  
  %  These are NeWS dependent graphics routines used by faces.
  %
! %  @(#)faces.ps 1.4 89/01/18
  %
  %  Copyright (c) Rich Burridge - Sun Microsystems Australia.
  %                                All rights reserved.
--- 1,7 ----
  
  %  These are NeWS dependent graphics routines used by faces.
  %
! %  @(#)faces.ps 1.5 89/01/29
  %
  %  Copyright (c) Rich Burridge - Sun Microsystems Australia.
  %                                All rights reserved.
***************
*** 53,58 ****
--- 53,59 ----
  
    /DIED 100 def
    /PAINTED 101 def
+   /LEFTDOWN 102 def
    /ClientHeight FrameHeight 10 sub def
    /ClientWidth FrameWidth 10 sub def
    /IconHeight FrameHeight def
***************
*** 124,129 ****
--- 125,136 ----
            grestore
          } def
      } Frame send
+   /DownEventInterest { /DownTransition Frame /ClientCanvas get
+                        eventmgrinterest } def
+   /EventMgr
+     [
+       LeftMouseButton { LEFTDOWN typedprint } DownEventInterest
+     ] forkeventmgr def
    IsIcon 1 eq { /flipiconic Frame send } if
  } def
  
*** original/get.c	Wed Jan 18 16:30:18 1989
--- get.c	Sun Jan 29 12:43:53 1989
***************
*** 1,6 ****
  /*LINTLIBRARY*/
  #ifndef lint
! static char sccsid[] = "@(#)get.c 1.5 89/01/18" ;
  #endif
  	
  /*  Extraction routines used by faces.
--- 1,6 ----
  /*LINTLIBRARY*/
  #ifndef lint
! static char sccsid[] = "@(#)get.c 1.6 89/01/29" ;
  #endif
  	
  /*  Extraction routines used by faces.
***************
*** 34,40 ****
--- 34,44 ----
      {
        FGETS(nextline, MAXLINE, fin) ;
        ptr = nextline ;
+ #ifdef SUN386i
+       for (j = 2; j >= 0; j--)
+ #else
        for (j = 0; j < 3; j++)
+ #endif SUN386i
          {
            while (*ptr == ' ' || *ptr == '\t') ptr++ ;
            SSCANF(ptr,"0x%X",&temp) ;
***************
*** 103,108 ****
--- 107,137 ----
  }
  
  
+ unsigned short
+ get_hex(fp)
+ FILE *fp ;
+ {
+   int c ;
+   unsigned short rval = 0 ;
+ 
+   while ((c = getc(fp)) != EOF)
+     {
+       if (c != '0') continue ;
+       c = getc(fp) ;
+       if (c != 'x') continue ;
+       while ((c = getc(fp)) != EOF)
+         {
+                if (c >= '0' && c <= '9') rval = (rval << 4) + (c - '0') ;
+           else if (c >= 'a' && c <= 'f') rval = (rval << 4) + (c - 'a' + 10) ;
+           else if (c >= 'A' && c <= 'F') rval = (rval << 4) + (c - 'A' + 10) ;
+           else break ;
+         }
+       break ;
+     }
+   return rval ;
+ }
+ 
+ 
  get_icon(dirname, buf)            /* Read in ikon or .icon file. */
  char *dirname ;
  unsigned short buf[256] ;
***************
*** 111,118 ****
  /*  Attempts to open the correct face file.
   *  If the face file is face.ps, then another record is added to the list
   *  of NeWS .ps files to animate at a later time.
!  *  If this is 48x48x1 or sun.icon, and the open is successful, then the
!  *  face image is read into buf.
   *  -1 is returned on failure.
   */
  
--- 140,147 ----
  /*  Attempts to open the correct face file.
   *  If the face file is face.ps, then another record is added to the list
   *  of NeWS .ps files to animate at a later time.
!  *  If this is face.xbm, 48x48x1 or sun.icon, and the open is successful,
!  *  then the face image is read into buf.
   *  -1 is returned on failure.
   */
  
***************
*** 125,130 ****
--- 154,161 ----
      if (get_sun_icon(dirname, buf) == 0) return SUNTYPE ;
    if (EQUAL(ptr+1,"48x48x1"))
      if (get_blit_ikon(dirname, buf) == 0) return BLITTYPE ;
+   if (EQUAL(ptr+1,"face.xbm"))
+     if (get_x11_icon(dirname, buf) == 0) return X11TYPE ;
    return -1 ;
  }
  
***************
*** 154,159 ****
--- 185,193 ----
        if (argv[0][0] == '-')
          switch (argv[0][1])
            {
+             case 'M' : if (argv[0][2] == 'H') mhflag++ ;
+                        else goto error ;
+                        break ;
              case 'P' : mtype = MONPRINTER ;  /* Monitor printer queue. */
                         INC ;
                         getparam(printer, argv, "-P needs printer name") ;
***************
*** 173,178 ****
--- 207,213 ----
                         break ;
              case 'g' : INC ;                 /* X11 geometry information. */
                         getparam(geometry, argv, "-g needs geometry information") ;
+                        posspec = 1 ;
                         break ;
              case 'h' : mtype = MONUSERS ;    /* Monitor users on a machine. */
                         INC ;
***************
*** 223,228 ****
--- 258,264 ----
                                        getparam(next, argv,
                                                 "-Wp needs y coordinate") ;
                                        wy = atoi(next) ;
+                                       posspec = 1 ;
                                        break ;
                             case 'P' : INC ;      /* -WP xnum ynum */
                                        getparam(next, argv,
***************
*** 243,249 ****
                                        break ;
                           }
                         break ;
!             default  : FPRINTF(stderr, "Usage: %s [-P printer] ", progname) ;
                         FPRINTF(stderr, "[-Wi] [-Wp x y] [-WP x y] ") ;
                         FPRINTF(stderr, "[-b background] [-d display] [-f facedir] ") ;
                         FPRINTF(stderr, "[-g geometry] [-i] [-n] ") ;
--- 279,286 ----
                                        break ;
                           }
                         break ;
!             error    :
!             default  : FPRINTF(stderr, "Usage: %s [-MH] [-P printer] ", progname) ;
                         FPRINTF(stderr, "[-Wi] [-Wp x y] [-WP x y] ") ;
                         FPRINTF(stderr, "[-b background] [-d display] [-f facedir] ") ;
                         FPRINTF(stderr, "[-g geometry] [-i] [-n] ") ;
***************
*** 255,260 ****
--- 292,360 ----
  }
  
  
+ get_x11_icon(name, buf)     /* Load X11 icon file. */
+ char *name ;
+ unsigned short buf[256] ;
+ {
+   FILE *fin ;
+   int hgt, i, j, wid ;
+   char c, *cptr, vbuf[512] ;
+   unsigned int tmp ;
+ 
+   if ((fin = fopen(name, "r")) == NULL) return -1 ;
+   if (fgets(nextline, MAXLINE, fin) == NULL) goto err_end ;
+   if (sscanf(nextline, "#define %s %d", vbuf, &wid) != 2) goto err_end ;
+   if ((cptr = rindex(vbuf, '_')) == NULL || strcmp(cptr, "_width"))
+     goto err_end ;
+   wid = (wid + 7) / 8 ;
+ 
+   if (fgets(nextline, MAXLINE, fin) == NULL) goto err_end ;
+   if (sscanf(nextline, "#define %s %d", vbuf, &hgt) != 2) goto err_end ;
+   if ((cptr = rindex(vbuf, '_')) == NULL || strcmp(cptr, "_height"))
+     goto err_end ;
+   if (hgt > ICONHEIGHT) hgt = ICONHEIGHT ;
+ 
+   while(nextline[0] == '#')
+     if (fgets(nextline, MAXLINE, fin) == NULL) goto err_end ;
+   if (sscanf(nextline, "static %s %*[^{]%c", vbuf, &c) != 2) goto err_end ;
+   if (strcmp(vbuf, "char") == 0)
+     {
+       for (i = 0; i < sizeof(vbuf); vbuf[i++] = 0) ;
+       for (i = 0; i < hgt; i++)
+         for (j = 0; j < wid; j++)
+           {
+             tmp = get_hex(fin) & 0xFF ;
+             if (j < (ICONWIDTH / 8))
+               vbuf[i*8+j] = (unsigned char) tmp ;
+           }
+       for (i = 0; i < 256; i++)
+         buf[i] = (revtable[vbuf[(i*2)+1]] & 0xFF) +
+                  ((revtable[vbuf[i*2]] & 0xFF) << 8) ;
+       FCLOSE(fin) ;
+       return(0) ;
+     }
+   else if (strcmp(vbuf, "short") == 0)
+     {
+       wid = (wid + 1) / 2 ;
+       for (i = 0; i < 256; buf[i++] = 0) ;
+       for (i = 0; i < hgt; i++)
+         for (j = 0; j < wid; j++)
+           {
+             tmp = get_hex(fin) ;
+             if (j < (ICONWIDTH/16))
+               buf[i*4+j] = (revtable[tmp >> 8] & 0xFF) +
+                            ((revtable[tmp & 0xFF] & 0xFF) << 8) ;
+           }
+       FCLOSE(fin) ;
+       return(0) ;
+     }
+ err_end:
+ 
+   FCLOSE(fin) ;
+   return -1 ;
+ }
+ 
+ 
  char *
  getname()       /* Get users name from passwd entry. */
  {
***************
*** 274,280 ****
  getparam(s, argv, errmes)
  char *s, *argv[], *errmes ;
  {
!   if (*argv != NULL && argv[0][0] != '-') STRCPY(s, *argv) ;
    else
      {
        FPRINTF(stderr,"%s: %s as next argument.\n", progname, errmes) ;
--- 374,380 ----
  getparam(s, argv, errmes)
  char *s, *argv[], *errmes ;
  {
!   if (*argv != NULL) STRCPY(s, *argv) ;
    else
      {
        FPRINTF(stderr,"%s: %s as next argument.\n", progname, errmes) ;
***************
*** 302,308 ****
--- 402,413 ----
          {
            while (*ptr == ' ' || *ptr == '\t') ptr++ ;
            SSCANF(ptr,"0x%X",&temp) ;
+ #ifdef SUN386i
+           buf[i*8+j] = (short) ((revtable[temp & 0xFF] << 8) +
+                                 ((revtable[(temp >> 8) & 0xFF]) & 0xFF)) ;
+ #else
            buf[i*8+j] = (short) temp ;
+ #endif SUN386i
            ptr = index(ptr, ',') ;
            ptr++ ;
          }
*** original/main.c	Wed Jan 18 16:30:18 1989
--- main.c	Sun Jan 29 12:43:54 1989
***************
*** 1,5 ****
  #ifndef lint
! static char sccsid[] = "@(#)main.c 1.5 89/01/18" ;
  #endif
  
  /*  Icon face server for monitoring mail and print jobs.
--- 1,5 ----
  #ifndef lint
! static char sccsid[] = "@(#)main.c 1.6 89/01/29" ;
  #endif
  
  /*  Icon face server for monitoring mail and print jobs.
***************
*** 66,80 ****
--- 66,121 ----
  int invert ;        /* Set if to use reverse video. */
  int ix ;            /* Initial X position of the icon. */
  int iy ;            /* Initial Y position of the icon. */
+ int mhflag ;        /* Set if this user uses MH to read mail. */
  int newmail ;       /* Set if there is new mail this time around. */
  int noicons ;       /* Number of faces this time around. */
  int period ;        /* Period in seconds for new mail check. */
+ int posspec ;       /* Set if -Wp or -g option is present (for X11) */
  int row ;           /* Row number for next icon. */
  int width ;         /* Width in pixels of faces display. */
  int wx ;            /* Initial X position of the window. */
  int wy ;            /* Initial Y position of the window. */
  
+ /*  256-byte table for quickly reversing the bits in an unsigned 8-bit char,
+  *  used to convert between MSBFirst and LSBFirst image formats.
+  */
  
+ char revtable[256] = {
+         0, -128,   64,  -64,   32,  -96,   96,  -32,
+        16, -112,   80,  -48,   48,  -80,  112,  -16,
+         8, -120,   72,  -56,   40,  -88,  104,  -24,
+        24, -104,   88,  -40,   56,  -72,  120,   -8,
+         4, -124,   68,  -60,   36,  -92,  100,  -28,
+        20, -108,   84,  -44,   52,  -76,  116,  -12,
+        12, -116,   76,  -52,   44,  -84,  108,  -20,
+        28, -100,   92,  -36,   60,  -68,  124,   -4,
+         2, -126,   66,  -62,   34,  -94,   98,  -30,
+        18, -110,   82,  -46,   50,  -78,  114,  -14,
+        10, -118,   74,  -54,   42,  -86,  106,  -22,
+        26, -102,   90,  -38,   58,  -70,  122,   -6,
+         6, -122,   70,  -58,   38,  -90,  102,  -26,
+        22, -106,   86,  -42,   54,  -74,  118,  -10,
+        14, -114,   78,  -50,   46,  -82,  110,  -18,
+        30,  -98,   94,  -34,   62,  -66,  126,   -2,
+         1, -127,   65,  -63,   33,  -95,   97,  -31,
+        17, -111,   81,  -47,   49,  -79,  113,  -15,
+         9, -119,   73,  -55,   41,  -87,  105,  -23,
+        25, -103,   89,  -39,   57,  -71,  121,   -7,
+         5, -123,   69,  -59,   37,  -91,  101,  -27,
+        21, -107,   85,  -43,   53,  -75,  117,  -11,
+        13, -115,   77,  -51,   45,  -83,  109,  -19,
+        29,  -99,   93,  -35,   61,  -67,  125,   -3,
+         3, -125,   67,  -61,   35,  -93,   99,  -29,
+        19, -109,   83,  -45,   51,  -77,  115,  -13,
+        11, -117,   75,  -53,   43,  -85,  107,  -21,
+        27, -101,   91,  -37,   59,  -69,  123,   -5,
+         7, -121,   71,  -57,   39,  -89,  103,  -25,
+        23, -105,   87,  -41,   55,  -73,  119,   -9,
+        15, -113,   79,  -49,   47,  -81,  111,  -17,
+        31,  -97,   95,  -33,   63,  -65,  127,   -1,
+ };
+ 
+ 
  main(argc,argv)
  int argc ;
  char *argv[] ;
***************
*** 127,138 ****
    lastsize = 0 ;              /* Initial size of spoolfile. */
    firsttime = 1 ;             /* No checks made yet. */
    iconic = 0 ;                /* Initially an open window. */
    STRCPY(fname[BLITTYPE], "48x48x1") ;
    STRCPY(fname[SUNTYPE], "sun.icon") ;
    STRCPY(fname[NEWSTYPE], "face.ps") ;
    STRCPY(display, "") ;       /* X11 display type. */
    STRCPY(geometry, "") ;      /* X11 geometry information. */
-   wx = wy = ix = iy = 0 ;
  
  #ifdef FBMONTYPE
    mtype = FBMONTYPE ;         /* Type of monitoring to do. */
--- 168,182 ----
    lastsize = 0 ;              /* Initial size of spoolfile. */
    firsttime = 1 ;             /* No checks made yet. */
    iconic = 0 ;                /* Initially an open window. */
+   mhflag = 0 ;                /* Assume no MH mail by default. */
+   posspec = 0 ;               /* Assume no -Wp or -g by default. */
+   wx = wy = ix = iy = 0 ;
    STRCPY(fname[BLITTYPE], "48x48x1") ;
    STRCPY(fname[SUNTYPE], "sun.icon") ;
    STRCPY(fname[NEWSTYPE], "face.ps") ;
+   STRCPY(fname[X11TYPE], "face.xbm") ;
    STRCPY(display, "") ;       /* X11 display type. */
    STRCPY(geometry, "") ;      /* X11 geometry information. */
  
  #ifdef FBMONTYPE
    mtype = FBMONTYPE ;         /* Type of monitoring to do. */
***************
*** 197,206 ****
  h_to_c(host, community)        /* Turn hostname into community name. */
  char *host, *community ;
  {
    struct machinfo *temp ;      /* Pointer to next machine record. */
   
    temp = machines ;            /* Point to list of machine/communitys. */
!   if (host[0] == '\0') GETHOSTNAME(community, MAXLINE) ;
    else STRCPY(community, host) ;   /* Copied in case machine name not found. */
    while (temp != NULL)
      {
--- 241,256 ----
  h_to_c(host, community)        /* Turn hostname into community name. */
  char *host, *community ;
  {
+   struct hostent *hp ;
    struct machinfo *temp ;      /* Pointer to next machine record. */
   
    temp = machines ;            /* Point to list of machine/communitys. */
!   if (host[0] == '\0')
!     {
!       GETHOSTNAME(community, MAXLINE) ;
!       hp = gethostbyname(community) ;
!       if (hp != NULL) STRCPY(community, hp->h_name) ;
!     }
    else STRCPY(community, host) ;   /* Copied in case machine name not found. */
    while (temp != NULL)
      {
***************
*** 229,245 ****
   *  If none of these are found, the "blank face" is returned.
   */
  
    int i ;
  
    for (i = 0; i < MAXTYPES; i++)
!     {
!       SPRINTF(iconname, "%s/%s/%s/%s", facedir, community, user, fname[i]) ;
!       if (stat(iconname, &buf) != -1)
!         {
!           if (EQUAL(fname[i],"face.ps") && gtype != NEWS) continue ;
!           else return ;
!         }
!     }
   
    for (i = 0; i < MAXTYPES; i++)
      {
--- 279,298 ----
   *  If none of these are found, the "blank face" is returned.
   */
  
+   char *cptr ;
    int i ;
  
    for (i = 0; i < MAXTYPES; i++)
!     for (cptr = community; cptr != NULL; cptr = index(cptr, '.'))
!       {
!         if (*cptr == '.') cptr++ ;
!         SPRINTF(iconname, "%s/%s/%s/%s", facedir, cptr, user, fname[i]) ;
!         if (stat(iconname, &buf) != -1)
!           {
!             if (EQUAL(fname[i],"face.ps") && gtype != NEWS) continue ;
!             else return ;
!           }
!       }
   
    for (i = 0; i < MAXTYPES; i++)
      {
***************
*** 256,273 ****
      }
   
    for (i = 0; i < MAXTYPES; i++)
!     {
!       SPRINTF(iconname, "%s/%s/unknown/%s", facedir, community, fname[i]) ;
!       if (stat(iconname, &buf) != -1)
!         {
!           if (EQUAL(fname[i], "face.ps") && gtype != NEWS) continue ;
!           else
!             {
!               STRCPY(user, "unknown") ;
!               return ;
!             }
!         }
!     }
  
    for (i = 0; i < MAXTYPES; i++)
      {
--- 309,328 ----
      }
   
    for (i = 0; i < MAXTYPES; i++)
!     for (cptr = community; cptr != NULL; cptr = index(cptr, '.'))
!       {
!         if (*cptr == '.') cptr++ ;
!         SPRINTF(iconname, "%s/%s/unknown/%s", facedir, cptr, fname[i]) ;
!         if (stat(iconname, &buf) != -1)
!           {
!             if (EQUAL(fname[i], "face.ps") && gtype != NEWS) continue ;
!             else
!               {
!                 if (mtype == MONALL) STRCPY(user, "unknown") ;
!                 return ;
!               }
!           }
!       }
  
    for (i = 0; i < MAXTYPES; i++)
      {
***************
*** 278,284 ****
            else
              {
                STRCPY(community, "misc.") ;
!               STRCPY(user, "unknown") ;
                return ;
              }
          }
--- 333,339 ----
            else
              {
                STRCPY(community, "misc.") ;
!               if (mtype == MONALL) STRCPY(user, "unknown") ;
                return ;
              }
          }
*** original/mon.c	Wed Jan  4 19:46:59 1989
--- mon.c	Sun Jan 29 12:43:55 1989
***************
*** 1,6 ****
  /*LINTLIBRARY*/
  #ifndef lint
! static char sccsid[] = "@(#)mon.c 1.5 89/01/04" ;
  #endif
  
  /*  Monitoring routines used by the faces program.
--- 1,6 ----
  /*LINTLIBRARY*/
  #ifndef lint
! static char sccsid[] = "@(#)mon.c 1.6 89/01/29" ;
  #endif
  
  /*  Monitoring routines used by the faces program.
***************
*** 88,98 ****
    if (buf.st_size > lastsize) newmail = 1 ;   /* New mail found. */
    if (mtype == MONNEW)
      if (buf.st_size <= lastsize)   /* Is the size of mail folder bigger? */
!       {
!         lastsize = buf.st_size ;   /* No: save new size and exit. */
!         show_display() ;
!         return ;
!       }
  
    if ((fp = fopen(spoolfile,"r")) == NULL)     /* Open spoolfile. */
      {
--- 88,104 ----
    if (buf.st_size > lastsize) newmail = 1 ;   /* New mail found. */
    if (mtype == MONNEW)
      if (buf.st_size <= lastsize)   /* Is the size of mail folder bigger? */
!       if (mhflag && (buf.st_size < lastsize) && (buf.st_size != 0))
!         {
!           lastsize = 0 ;    /* User uses MH. Any shrinkage means new mail. */
!           newmail = 1 ;
!         }
!       else
!         {
!           lastsize = buf.st_size ;   /* No: save new size and exit. */
!           show_display() ;
!           return ;
!         }
  
    if ((fp = fopen(spoolfile,"r")) == NULL)     /* Open spoolfile. */
      {
*** original/news.c	Wed Jan 18 16:30:19 1989
--- news.c	Sun Jan 29 12:43:56 1989
***************
*** 1,6 ****
  /*LINTLIBRARY*/
  #ifndef lint
! static char sccsid[] = "@(#)news.c 1.5 89/01/18" ;
  #endif
  
  /*  NeWS dependent graphics routines used by faces,
--- 1,6 ----
  /*LINTLIBRARY*/
  #ifndef lint
! static char sccsid[] = "@(#)news.c 1.6 89/01/29" ;
  #endif
  
  /*  NeWS dependent graphics routines used by faces,
***************
*** 42,54 ****
  #include "nousers.icon"
  } ;
  
! #ifdef SUNOS3.x
  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 SUNOS3.x
  
  int kbdfd ;                  /* File descriptor for the keyboard. */
  int psfd ;                   /* NeWS connection file descriptor. */
--- 42,54 ----
  #include "nousers.icon"
  } ;
  
! #ifdef NO_4.3SELECT
  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_4.3SELECT
  
  int kbdfd ;                  /* File descriptor for the keyboard. */
  int psfd ;                   /* NeWS connection file descriptor. */
***************
*** 146,154 ****
  }
  
  
  create_pixrects(width, height)        /* Create pixrects for the face images. */
  {
!   int h, i, j, w ;
  
    if (mtype == MONNEW && !firsttime) return ;
    FPRINTF(PostScript,"%d %d PR DoPixrects\n", width, height) ;
--- 146,170 ----
  }
  
  
+ clear_animates()      /* Remove chain of animate records. */
+ {
+   struct psinfo *next, *this ;   /* For removing current chain of records. */
+ 
+   this = psrecs ;     /* Point to beginning of NeWS records. */
+   while (this != NULL)
+     {
+       next = this->next ;
+       if (this->name != NULL) free(this->name) ;
+       free((char *) this) ;   /* Remove this record. */
+       this = next ;
+     }
+   psrecs = plast = NULL ;
+ }
+ 
+ 
  create_pixrects(width, height)        /* Create pixrects for the face images. */
  {
!   int h, w ;
  
    if (mtype == MONNEW && !firsttime) return ;
    FPRINTF(PostScript,"%d %d PR DoPixrects\n", width, height) ;
***************
*** 160,165 ****
--- 176,189 ----
        w = ICONWIDTH ;
      }
    FPRINTF(PostScript,"%d %d MPR DoPixrects\n", w, h) ;
+   do_background() ;          /* Setup background pattern. */
+ }
+ 
+ 
+ do_background()     /* Set up background pattern. */
+ {
+   int i, j ;
+ 
    if (strlen(bgicon))
      {
        for (i = 0; i < (height / 64); i++)
***************
*** 196,201 ****
--- 220,233 ----
  }
  
  
+ handle_mouse()     /* Clear canvas to background and recheck for new mail. */
+ {
+   do_background() ;    /* Setup background pattern. */
+   clear_animates() ;   /* Remove chain of animate records. */
+   do_check() ;
+ }
+ 
+ 
  init_ws_type()
  {
    if (ps_open_PostScript() < 0) return -1 ;
***************
*** 246,257 ****
  
    psfd = fileno(PostScriptInput) ;
  
! #ifdef SUNOS3.x
    fullmask = 1 << psfd ;
  #else
    FD_ZERO(&fullmask) ;
    FD_SET(psfd, &fullmask) ;
! #endif SUNOS3.x
  
    if (strlen(bgicon))
      if (get_sun_icon(bgicon, ibuf) == 0) load_icon("Background") ;
--- 278,289 ----
  
    psfd = fileno(PostScriptInput) ;
  
! #ifdef NO_4.3SELECT
    fullmask = 1 << psfd ;
  #else
    FD_ZERO(&fullmask) ;
    FD_SET(psfd, &fullmask) ;
! #endif NO_4.3SELECT
  
    if (strlen(bgicon))
      if (get_sun_icon(bgicon, ibuf) == 0) load_icon("Background") ;
***************
*** 314,320 ****
  start_tool()
  {
    int type ;                     /* Value from NeWS server. */
-   struct psinfo *next, *this ;   /* For removing current chain of records. */
    struct timeval tval ;
  
    tval.tv_usec = 0 ;
--- 346,351 ----
***************
*** 323,357 ****
    for (;;)
      {
        readmask = fullmask ;
! #ifdef SUNOS3.x
        SELECT(32, &readmask, 0, 0, &tval) ;
        if (readmask && (1 << psfd))
  #else
        SELECT(FD_SETSIZE, &readmask, (fd_set *) 0, (fd_set *) 0, &tval) ;
        if (FD_ISSET(psfd, &readmask))
! #endif SUNOS3.x
          {
            if (pscanf(PostScriptInput, "%d", &type) == EOF) exit(1) ;
            switch (type)
              {
                case DIED     : exit(0) ;
                case PAINTED  : if (psrecs != NULL) do_news_ps(psrecs) ;
              }
          }
        else
          {
!           this = psrecs ;     /* Point to beginning of NeWS records. */
!           if (mtype != MONNEW)
!             {
!               while (this != NULL)
!                 {
!                   next = this->next ;
!                   if (this->name != NULL) free(this->name) ;
!                   free((char *) this) ;   /* Remove this record. */
!                   this = next ;
!                 }
!               psrecs = plast = NULL ;
!             }
            do_check() ;        /* Check the mail/printer again. */
          }
      }
--- 354,384 ----
    for (;;)
      {
        readmask = fullmask ;
! #ifdef NO_4.3SELECT
        SELECT(32, &readmask, 0, 0, &tval) ;
        if (readmask && (1 << psfd))
  #else
        SELECT(FD_SETSIZE, &readmask, (fd_set *) 0, (fd_set *) 0, &tval) ;
        if (FD_ISSET(psfd, &readmask))
! #endif NO_4.3SELECT
          {
            if (pscanf(PostScriptInput, "%d", &type) == EOF) exit(1) ;
            switch (type)
              {
                case DIED     : exit(0) ;
+               case LEFTDOWN : if (mtype == MONNEW)
+                                 {
+                                   do_background() ;
+                                   clear_animates() ;
+                                   do_check() ;
+                                 }
+                               break ;
                case PAINTED  : if (psrecs != NULL) do_news_ps(psrecs) ;
              }
          }
        else
          {
!           if (mtype != MONNEW) clear_animates() ;
            do_check() ;        /* Check the mail/printer again. */
          }
      }
*** original/patchlevel.h	Wed Jan 18 16:30:19 1989
--- patchlevel.h	Sun Jan 29 12:43:59 1989
***************
*** 1,5 ****
   
! /*  @(#)patchlevel.h 1.5 89/01/18
   *
   *  This is the current patch level for this version of faces.
   *
--- 1,5 ----
   
! /*  @(#)patchlevel.h 1.6 89/01/29
   *
   *  This is the current patch level for this version of faces.
   *
***************
*** 14,17 ****
   *  reported to me then an attempt will be made to fix them.
   */
  
! #define  PATCHLEVEL  4
--- 14,17 ----
   *  reported to me then an attempt will be made to fix them.
   */
  
! #define  PATCHLEVEL  5
*** original/sunview.c	Wed Jan  4 19:46:59 1989
--- sunview.c	Sun Jan 29 12:43:57 1989
***************
*** 1,6 ****
  /*LINTLIBRARY*/
  #ifndef lint
! static char sccsid[] = "@(#)sunview.c 1.3 89/01/04" ;
  #endif
  
  /*  SunView dependent graphics routines used by faces,
--- 1,6 ----
  /*LINTLIBRARY*/
  #ifndef lint
! static char sccsid[] = "@(#)sunview.c 1.4 89/01/29" ;
  #endif
  
  /*  SunView dependent graphics routines used by faces,
***************
*** 29,39 ****
  #define  PR_REPLROP              (void) pr_replrop
  #define  PR_ROP                  (void) pr_rop
  
! #ifdef SUNOS3.x
  #define  PR_TTEXT                (void) pf_ttext
  #else
  #define  PR_TTEXT                (void) pr_ttext
! #endif SUNOS3.x
  
  #define  PW_ROP                  (void) pw_rop
  #define  WIN_BELL                (void) win_bell
--- 29,39 ----
  #define  PR_REPLROP              (void) pr_replrop
  #define  PR_ROP                  (void) pr_rop
  
! #ifdef NO_PR_TTEXT
  #define  PR_TTEXT                (void) pf_ttext
  #else
  #define  PR_TTEXT                (void) pr_ttext
! #endif NO_PR_TTEXT
  
  #define  PW_ROP                  (void) pw_rop
  #define  WIN_BELL                (void) win_bell
***************
*** 173,178 ****
--- 173,199 ----
  }
  
  
+ /*ARGSUSED*/
+ void
+ canvas_proc(canvas, event, arg)
+ Canvas canvas ;
+ Event *event ;
+ caddr_t arg ;
+ {
+   if (mtype == MONNEW && event_id(event) == MS_LEFT && event_is_down(event))
+     {
+       if (pr) PR_REPLROP(pr, 0, 0, width, height, PIX_SRC, background, 0, 0) ;
+ /*
+       if (mpr)
+         PR_REPLROP(mpr, 0, 0, width, height, PIX_SRC, background, 0, 0) ;
+       show_display() ;
+ */
+       do_check() ;
+     }
+   else window_default_event_proc(canvas, event, arg) ;
+ }
+ 
+ 
  create_pixrects(width, height)   /* Create pixrects for the face images. */
  int width, height ;
  {
***************
*** 239,244 ****
--- 260,266 ----
    ffd = (int) window_get(frame, WIN_FD) ;
  
    canvas = window_create(frame, CANVAS,
+                          WIN_EVENT_PROC, canvas_proc,
                           CANVAS_REPAINT_PROC, repaint_proc,
                           CANVAS_RETAINED, TRUE,
                           0) ;
*** original/x11.c	Wed Jan 18 16:30:19 1989
--- x11.c	Sun Jan 29 12:44:03 1989
***************
*** 1,6 ****
  /*LINTLIBRARY*/
  #ifndef lint
! static char sccsid[] = "@(#)x11.c 1.2 89/01/18" ;
  #endif
  
  /*  X11 dependent graphics routines used by faces,
--- 1,6 ----
  /*LINTLIBRARY*/
  #ifndef lint
! static char sccsid[] = "@(#)x11.c 1.3 89/01/29" ;
  #endif
  
  /*  X11 dependent graphics routines used by faces,
***************
*** 25,31 ****
   
  #define  DEF_FONT    "fixed"
  #define  FONT        "6x10b"
! #define  FRAME_MASK  (ButtonPressMask | ButtonReleaseMask | ExposureMask | ButtonMotionMask)
  
  Pixmap load_icon() ;
  
--- 25,31 ----
   
  #define  DEF_FONT    "fixed"
  #define  FONT        "6x10b"
! #define  FRAME_MASK  (ButtonPressMask | ExposureMask | ButtonMotionMask)
  
  Pixmap load_icon() ;
  
***************
*** 43,102 ****
  XSizeHints size ;
  XWMHints wm_hints ;
   
! #ifdef SUNOS3.x
  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 SUNOS3.x
  
  unsigned long gc_mask ;
  int screen ;
  int xfd ;                    /* File descriptor for X11 server connection. */
  unsigned long mask ;
  long backgnd, foregnd ;
   
- /*  256-byte table for quickly reversing the bits in an unsigned 8-bit char,
-  *  used to convert between MSBFirst and LSBFirst image formats.
-  */
  
- static char revtable[256] = {
-             0, -128,   64,  -64,   32,  -96,   96,  -32,
-            16, -112,   80,  -48,   48,  -80,  112,  -16,
-             8, -120,   72,  -56,   40,  -88,  104,  -24,
-            24, -104,   88,  -40,   56,  -72,  120,   -8,
-             4, -124,   68,  -60,   36,  -92,  100,  -28,
-            20, -108,   84,  -44,   52,  -76,  116,  -12,
-            12, -116,   76,  -52,   44,  -84,  108,  -20,
-            28, -100,   92,  -36,   60,  -68,  124,   -4,
-             2, -126,   66,  -62,   34,  -94,   98,  -30,
-            18, -110,   82,  -46,   50,  -78,  114,  -14,
-            10, -118,   74,  -54,   42,  -86,  106,  -22,
-            26, -102,   90,  -38,   58,  -70,  122,   -6,
-             6, -122,   70,  -58,   38,  -90,  102,  -26,
-            22, -106,   86,  -42,   54,  -74,  118,  -10,
-            14, -114,   78,  -50,   46,  -82,  110,  -18,
-            30,  -98,   94,  -34,   62,  -66,  126,   -2,
-             1, -127,   65,  -63,   33,  -95,   97,  -31,
-            17, -111,   81,  -47,   49,  -79,  113,  -15,
-             9, -119,   73,  -55,   41,  -87,  105,  -23,
-            25, -103,   89,  -39,   57,  -71,  121,   -7,
-             5, -123,   69,  -59,   37,  -91,  101,  -27,
-            21, -107,   85,  -43,   53,  -75,  117,  -11,
-            13, -115,   77,  -51,   45,  -83,  109,  -19,
-            29,  -99,   93,  -35,   61,  -67,  125,   -3,
-             3, -125,   67,  -61,   35,  -93,   99,  -29,
-            19, -109,   83,  -45,   51,  -77,  115,  -13,
-            11, -117,   75,  -53,   43,  -85,  107,  -21,
-            27, -101,   91,  -37,   59,  -69,  123,   -5,
-             7, -121,   71,  -57,   39,  -89,  103,  -25,
-            23, -105,   87,  -41,   55,  -73,  119,   -9,
-            15, -113,   79,  -49,   47,  -81,  111,  -17,
-            31,  -97,   95,  -33,   63,  -65,  127,   -1,
- };
- 
- 
  static unsigned short noface_image[] = {
  #include "noface.icon"
  } ;
--- 43,64 ----
  XSizeHints size ;
  XWMHints wm_hints ;
   
! #ifdef NO_4.3SELECT
  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_4.3SELECT
  
  unsigned long gc_mask ;
  int screen ;
  int xfd ;                    /* File descriptor for X11 server connection. */
+ unsigned int depth ;
  unsigned long mask ;
  long backgnd, foregnd ;
   
  
  static unsigned short noface_image[] = {
  #include "noface.icon"
  } ;
***************
*** 211,217 ****
  
    old_pr = pr ;
    pr = XCreatePixmap(dpy, frame,
!                      (unsigned int) width, (unsigned int) height, 1) ;
   
    for (i = 0; i < (height / ICONHEIGHT); i++)
      for (j = 0; j < (width / ICONWIDTH); j++)
--- 173,179 ----
  
    old_pr = pr ;
    pr = XCreatePixmap(dpy, frame,
!                      (unsigned int) width, (unsigned int) height, depth) ;
   
    for (i = 0; i < (height / ICONHEIGHT); i++)
      for (j = 0; j < (width / ICONWIDTH); j++)
***************
*** 220,230 ****
   
    old_mpr = mpr ;
    if (mtype == MONPRINTER)
!     mpr = XCreatePixmap(dpy, frame, ICONWIDTH, ICONHEIGHT, 1) ;
    else
      {
        mpr = XCreatePixmap(dpy, frame,
!                           (unsigned int) width, (unsigned int) height, 1) ;
        for (i = 0; i < (height / ICONHEIGHT); i++)
          for (j = 0; j < (width / ICONWIDTH); j++)
            XCopyArea(dpy, background, mpr, gc, 0, 0, ICONWIDTH, ICONHEIGHT,
--- 182,192 ----
   
    old_mpr = mpr ;
    if (mtype == MONPRINTER)
!     mpr = XCreatePixmap(dpy, frame, ICONWIDTH, ICONHEIGHT, depth) ;
    else
      {
        mpr = XCreatePixmap(dpy, frame,
!                           (unsigned int) width, (unsigned int) height, depth) ;
        for (i = 0; i < (height / ICONHEIGHT); i++)
          for (j = 0; j < (width / ICONWIDTH); j++)
            XCopyArea(dpy, background, mpr, gc, 0, 0, ICONWIDTH, ICONHEIGHT,
***************
*** 247,252 ****
--- 209,227 ----
  }
  
  
+ /*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 ;
+ }
+ 
+ 
  Pixmap
  load_icon(sbuf)
  unsigned short sbuf[256] ;
***************
*** 259,266 ****
        cbuf[i*2+0] = revtable[(sbuf[i] >> 8) & 0xFF] ;
        cbuf[i*2+1] = revtable[sbuf[i] & 0xFF] ;
      }
!   return(XCreateBitmapFromData(dpy, RootWindow(dpy, screen), cbuf,
!                                      ICONWIDTH, ICONHEIGHT)) ;
  }
  
  
--- 234,242 ----
        cbuf[i*2+0] = revtable[(sbuf[i] >> 8) & 0xFF] ;
        cbuf[i*2+1] = revtable[sbuf[i] & 0xFF] ;
      }
!   return(XCreatePixmapFromBitmapData(dpy, RootWindow(dpy, screen), cbuf,
!                                      ICONWIDTH, ICONHEIGHT,
!                                      foregnd, backgnd, depth)) ;
  }
  
  
***************
*** 273,283 ****
    unsigned int h, w ;        /* Window dimensions. */
    int flags, i, j ;
    int x, y ;                 /* Window position. */
  
    x = wx ;
    y = wy ;
    w = NO_PER_ROW * ICONWIDTH ;
!   h = ICONHEIGHT * 10 ;
  
    if ((dpy = XOpenDisplay(display)) == NULL)
      {
--- 249,260 ----
    unsigned int h, w ;        /* Window dimensions. */
    int flags, i, j ;
    int x, y ;                 /* Window position. */
+   XSetWindowAttributes winattrs ;
  
    x = wx ;
    y = wy ;
    w = NO_PER_ROW * ICONWIDTH ;
!   h = ICONHEIGHT ;
  
    if ((dpy = XOpenDisplay(display)) == NULL)
      {
***************
*** 287,302 ****
      }
    xfd = ConnectionNumber(dpy) ;
  
! #ifdef SUNOS3.x
    fullmask = 1 << xfd ;
  #else
    FD_ZERO(&fullmask) ;
    FD_SET(xfd, &fullmask) ;
! #endif SUNOS3.x
  
    screen = DefaultScreen(dpy) ;
    foregnd = BlackPixel(dpy, screen) ;
    backgnd = WhitePixel(dpy, screen) ;
  
    if (mtype == MONPRINTER) faces_icon = noprint_icon ;
    else faces_icon = nomail_icon ;
--- 264,280 ----
      }
    xfd = ConnectionNumber(dpy) ;
  
! #ifdef NO_4.3SELECT
    fullmask = 1 << xfd ;
  #else
    FD_ZERO(&fullmask) ;
    FD_SET(xfd, &fullmask) ;
! #endif NO_4.3SELECT
  
    screen = DefaultScreen(dpy) ;
    foregnd = BlackPixel(dpy, screen) ;
    backgnd = WhitePixel(dpy, screen) ;
+   depth = DefaultDepth(dpy, screen) ;
  
    if (mtype == MONPRINTER) faces_icon = noprint_icon ;
    else faces_icon = nomail_icon ;
***************
*** 310,319 ****
        exit(1) ;
      }
  
!   gc_mask = GCFont | GCForeground | GCBackground ;
    gc_val.font = sfont->fid ;
    gc_val.foreground = foregnd ;
    gc_val.background = backgnd ;
    gc = XCreateGC(dpy, RootWindow(dpy, screen), gc_mask, &gc_val) ;
    XSetFunction(dpy, gc, GXcopy) ;
  
--- 288,298 ----
        exit(1) ;
      }
  
!   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, RootWindow(dpy, screen), gc_mask, &gc_val) ;
    XSetFunction(dpy, gc, GXcopy) ;
  
***************
*** 336,348 ****
          y += DisplayHeight(dpy, screen) - h ;
      }
  
!   frame = XCreateSimpleWindow(dpy, RootWindow(dpy, screen), x, y,
!                 w, h, 2, foregnd, backgnd) ;
!   XSelectInput(dpy, frame, FRAME_MASK) ;
  
!   frame_icon =  XCreateSimpleWindow(dpy, RootWindow(dpy, screen), 0, 0,
!                 w, h, 2, foregnd, backgnd) ;
!   XSelectInput(dpy, frame_icon, FRAME_MASK) ;
  
    wm_hints.icon_x = ix ;
    wm_hints.icon_y = iy ;
--- 315,331 ----
          y += DisplayHeight(dpy, screen) - h ;
      }
  
!   winattrs.background_pixel = backgnd ;
!   winattrs.border_pixel = foregnd ;
!   winattrs.event_mask = FRAME_MASK ;
  
!   frame = XCreateWindow(dpy, RootWindow(dpy, screen), x, y, w, h, 2,
!                         CopyFromParent, InputOutput, CopyFromParent,
!                         CWBackPixel | CWBorderPixel | CWEventMask, &winattrs) ;
!  
!   frame_icon = XCreateWindow(dpy, RootWindow(dpy, screen), ix, iy, w, h, 2,
!                              CopyFromParent, InputOutput, CopyFromParent,
!                              CWBackPixel | CWBorderPixel | CWEventMask, &winattrs) ;
  
    wm_hints.icon_x = ix ;
    wm_hints.icon_y = iy ;
***************
*** 355,367 ****
      }
    XSetWMHints(dpy, frame, &wm_hints) ;
  
!   size.flags = (PPosition | PSize | PMinSize | PMaxSize) ;
    size.x = x ;
    size.y = y ;
!   size.width = size.min_width = size.max_width = w ;
!   size.height = size.min_height = size.max_height = h ;
!   XSetStandardProperties(dpy, frame, (char *) NULL, (char *) NULL, None,
!                 argv, argc, &size) ;
   
    noface_icon = load_icon(noface_image) ;
    nomail_icon = load_icon(nomail_image) ;
--- 338,353 ----
      }
    XSetWMHints(dpy, frame, &wm_hints) ;
  
!   size.flags = ((posspec ? USPosition : PPosition) |
!                 PSize | PMinSize | PMaxSize) ;
    size.x = x ;
    size.y = y ;
!   size.min_width = ICONWIDTH ;
!   size.min_height = ICONHEIGHT ;
!   size.width = size.max_width = w ;
!   size.height = size.max_height = h ;
!   XSetStandardProperties(dpy, frame, "faces", "faces", None,
!                          argv, argc, &size) ;
   
    noface_icon = load_icon(noface_image) ;
    nomail_icon = load_icon(nomail_image) ;
***************
*** 380,385 ****
--- 366,374 ----
  
  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) ;
***************
*** 388,395 ****
        XCopyArea(dpy, mpr, mpr, gc, 0, 0,
                  (unsigned int)  width, (unsigned int) height, 0, 0) ;
      }
!   XSetFunction(dpy, gc, GXcopy) ; 
!   XMapWindow(dpy, frame) ;
  
    if (mtype != MONPRINTER)
      XResizeWindow(dpy, frame_icon,
--- 377,389 ----
        XCopyArea(dpy, mpr, mpr, gc, 0, 0,
                  (unsigned int)  width, (unsigned int) height, 0, 0) ;
      }
!   if (first_time)
!     {
!       XMapWindow(dpy, frame) ;
!       XSync(dpy, 0) ;
!       XPeekIfEvent(dpy, &ev, is_exposed, (char*) &frame) ;
!       first_time = 0 ;
!     }
  
    if (mtype != MONPRINTER)
      XResizeWindow(dpy, frame_icon,
***************
*** 405,410 ****
--- 399,405 ----
    if (newmail) beep_flash(beeps, flashes) ;
    if (old_pr) XFreePixmap(dpy, old_pr) ;
    if (old_mpr) XFreePixmap(dpy, old_mpr) ;
+   old_pr = old_mpr = NULL ;
    XSync(dpy, 0) ;
  }
   
***************
*** 420,443 ****
    for (;;)
      {
        readmask = fullmask ;
! #ifdef SUNOS3.x
        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 SUNOS3.x
!         {
!           XNextEvent(dpy, &event) ;
!           if (event.type == Expose && event.xexpose.count == 0)
!             {
!               while (XCheckTypedEvent(dpy, Expose, &event)) /* do nothing. */ ;
!               XCopyArea(dpy, pr, frame, gc, 0, 0,
!                         (unsigned int) width, (unsigned int) height, 0, 0) ;
!               XCopyArea(dpy, mpr, frame_icon, gc, 0, 0,
!                         (unsigned int) width, (unsigned int) height, 0, 0) ;
              }
!         }
        else do_check() ;     /* Check the mail/printer/user queue again. */
      }
  }
--- 415,447 ----
    for (;;)
      {
        readmask = fullmask ;
! #ifdef NO_4.3SELECT
        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_4.3SELECT
!         while (XPending(dpy))
!           {
!             XNextEvent(dpy, &event) ;
!             if (event.type == Expose && event.xexpose.count == 0)
!               {
!                 while (XCheckTypedEvent(dpy, Expose, &event)) /* do nothing. */ ;
!                 XCopyArea(dpy, pr, frame, gc, 0, 0,
!                           (unsigned int) width, (unsigned int) height, 0, 0) ;
!                 XCopyArea(dpy, mpr, frame_icon, gc, 0, 0,
!                           (unsigned int) width, (unsigned int) height, 0, 0) ;
!               }
!             else if (mtype == MONNEW && event.type == ButtonPress &&
!                    event.xbutton.button == Button1)
!               {
!                 if (pr) XFreePixmap(dpy, pr) ;
!                 if (mpr) XFreePixmap(dpy, mpr) ;
!                 pr = mpr = NULL ;
!                 do_check() ;
              }
!           }
        else do_check() ;     /* Check the mail/printer/user queue again. */
      }
  }



More information about the Comp.sources.bugs mailing list