[comp.sources.unix] v17i062: MGR, Bellcore window manager, Part61/61

rsalz@uunet.uu.net (Rich Salz) (01/31/89)

Submitted-by: Stephen A. Uhler <sau@bellcore.com>
Posting-number: Volume 17, Issue 62
Archive-name: mgr/part61




#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 61 (of 61)."
# Contents:  src/put_window.c
# Wrapped by rsalz@papaya.bbn.com on Thu Nov 17 21:06:09 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/put_window.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/put_window.c'\"
else
echo shar: Extracting \"'src/put_window.c'\" \(44878 characters\)
sed "s/^X//" >'src/put_window.c' <<'END_OF_FILE'
X/*                        Copyright (c) 1987 Bellcore
X *                            All Rights Reserved
X *       Permission is granted to copy or use this program, EXCEPT that it
X *       may not be sold for profit, the copyright notice must be reproduced
X *       on copies, and credit should be given to Bellcore where it is due.
X *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X */
X/*	$Header: put_window.c,v 4.4 88/08/16 07:25:54 sau Exp $
X	$Source: /tmp/mgrsrc/src/RCS/put_window.c,v $
X*/
Xstatic char	RCSid_[] = "$Source: /tmp/mgrsrc/src/RCS/put_window.c,v $$Revision: 4.4 $";
X
X/* Very simple terminal emulator (this is an old comment) */
X
X#include <sys/time.h>		/* experimental */
X#include "bitmap.h"
X#include "font.h"
X#include "defs.h"
X#include "menu.h"
X#include "event.h"
X#include <stdio.h>
X#include "window.h"
X#include "clip.h"
X
X/* macros for putting a character on a window */
X
X#define DO_CHAR(font,c) \
X	((font)->glyph[c])
X	
X#ifdef COLOR
X#define PUT_CHAR(dest,x,y,font,op,c)   \
X   bit_blit(dest,x,y-fsizehigh,fsizewide,fsizehigh, \
X   BIT_SRC | (W(background)&~NOCOLOR),BIT_NULL,0,0), \
X   bit_blit(dest,x,y-fsizehigh,fsizewide,fsizehigh, \
X   (op & NOCOLOR)^BIT_DST | (op ^ W(background))&~NOCOLOR, \
X   DO_CHAR(font,c),0,0)
X
X/* fix the border color */
X
X#define BORDER(win) \
X   ((win==active) ? border(win,SUM_BDR-1,1) : border(win,BLK_BDR,WH_BDR))
X
X#else NOCOLOR
X
X#define PUT_CHAR(dest,x,y,font,op,c)	\
X	bit_blit(dest,x,y-fsizehigh,fsizewide,fsizehigh, \
X	op,DO_CHAR(font,c),0,0)
X#define BORDER(win)
X
X#endif
X#define Abs(x)               ((x)>0?(x):-(x))
X
X/* flseep is experimental */
X
X#define fsleep() \
X   { \
X   struct timeval time; \
X   time.tv_sec = 0; \
X   time.tv_usec = 330000; \
X   select(0,0,0,0,&time); \
X   }
X
Xrect clip;				/* clipping rectangle */
X
X/* send a string to a window, interpret ESC's
X * return # of chars actually processed
X */
X
Xint
Xput_window(win,buff,buff_count)
Xregister WINDOW *win;					/* window to update */
Xregister char *buff;					/* ptr to update text */
Xint buff_count;						/* # of characters */
X   {
X   register BITMAP *window;			/* bitmap to update */
X   register BITMAP *text = (BITMAP *) 0;	/* current text region */
X   register int indx;				/* index into buff */
X   register int cnt;				/* # of esc. numbers */
X   register char c;				/* current char */
X   register int done=0;				/* set to 1 to exit */
X   int bell=0;					/* 1 if screen flashed once */
X   int sub_window = 0;				/* sub window created */
X   int fsizehigh, fsizewide;			/* variables to save deref. */
X   struct font *Get_font();	
X   char *malloc(), *binary();
X   struct menu_state *do_menu();
X   char *trans();
X
X   /* set up environment */
X
X   if (W(flags)&W_ACTIVE) {
X      window = W(window);
X      }
X   else {
X      window = bit_create(W(save),SUM_BDR,SUM_BDR,
X                          BIT_WIDE(W(window)),BIT_HIGH(W(window)));
X      sub_window++;
X      }
X
X   if (window==(BITMAP *) 0) {		/* never! */
X      perror("Bit_create failed for window");
X      return(0);
X      }
X
X   /* avoid repeated dereferencing of pointers */
X
X   fsizehigh = FSIZE(high);
X   fsizewide = FSIZE(wide);
X
X   if (Do_clip()) {
X      Set_clipall();
X      Set_cliplow(W(x)+W(text).x,W(y)+W(text).y-fsizehigh);
X      }
X
X   if (W(text.wide))
X      text = bit_create(window,W(text.x),W(text.y),W(text.wide),W(text.high)); 
X   if (text == (BITMAP *) 0)
X      text = window;
X
X   if (W(flags)&W_ACTIVE && mousein(mousex,mousey,win,0)) {
X      MOUSE_OFF(mousex,mousey);
X      }
X
X   if (win==active)
X      cursor_off();
X
X   /* do each character */
X
X   for(indx=0;c= *buff++, indx<buff_count && !done; indx++)
X   switch (W(flags)&W_STATE) {
X
X      /* download and process text strings */
X
X   case W_TEXT:				/* down load a text string */
X      cnt = W(esc_cnt);
X         W(snarf[W(esc)[TEXT_COUNT]++]) = c;
X      if (W(esc)[TEXT_COUNT] >= W(esc)[cnt]) {
X         W(snarf)[W(esc)[TEXT_COUNT]] = '\0';
X         W(flags) &= ~W_TEXT;
X         if (W(snarf) && W(code)!=T_BITMAP && W(code)!=T_GRUNCH)
X            (void) trans(W(snarf));
X         down_load(win,window,text);
X         done++;
X         }
X      break;
X
X   /**********************************************************************
X    *	Handle escape codes 
X    */
X
X   case W_ESCAPE:			/* process an escape code */
X      W(flags) &= ~(W_ESCAPE);
X      cnt = W(esc_cnt);
X      switch(c&=0177) {
X         case ESC : 			/* turn on escape mode */
X                    W(flags) |= W_ESCAPE;
X                    W(esc_cnt) = 0;
X                    W(esc[0]) = 0;
X                    break;
X
X         case '0': case '1': case '2': case '3': case '4':
X         case '5': case '6': case '7': case '8': case '9':
X               W(esc)[W(esc_cnt)] = W(esc)[W(esc_cnt)]*10 + c-'0'; 
X               W(flags) |= W_ESCAPE;
X               if (W(flags)&W_MINUS && W(esc)[W(esc_cnt)] > 0) {
X                  W(esc)[W(esc_cnt)] = -(W(esc)[W(esc_cnt)]);
X                  W(flags) &= ~(W_MINUS);
X                  }
X               break;
X
X         case E_SEP1:			/* primary field separator */
X         case E_SEP2:			/* secondary field separator */
X               if (W(esc_cnt)+1 < MAXESC)
X                   W(esc_cnt)++;
X               W(esc)[W(esc_cnt)] = 0;
X               W(flags) &= ~(W_MINUS);
X               W(flags) |= W_ESCAPE;
X               break;
X
X         case E_MINUS:  		/* set the MINUS flag */
X               W(flags) |= (W_ESCAPE|W_MINUS);
X               break;
X
X         case E_NULL:			/* do nothing */
X               done++;
X               break;
X
X         case E_ADDLINE:  		/* add a new line */
X               if (*W(esc)) {
X                  register int count = *W(esc);
X                  scroll(win,text,W(y)-fsizehigh,T_HIGH,- count*(fsizehigh),
X                      W(background));
X                  }
X               else {
X                  scroll(win,text,W(y)-fsizehigh,T_HIGH,-(fsizehigh),
X                      W(background));
X                  bit_blit(text,0,HIGH-fsizehigh,T_WIDE,
X                      fsizehigh,W(background),NULL_DATA,0,0);
X                  }
X               done++;
X               break;
X
X         case E_ADDCHAR:  		/* insert a character */
X               {
X               register int wide = fsizewide*(*W(esc)?*W(esc):1);
X               if (wide+W(x)>T_WIDE)
X                  wide = T_WIDE-W(x);
X               bit_blit(text,W(x)+wide,W(y)-fsizehigh,
X                        T_WIDE-W(x)-wide, fsizehigh,BIT_SRC,
X                        text,W(x),W(y)-fsizehigh);
X               bit_blit(text,W(x),W(y)-fsizehigh,wide,
X                    fsizehigh,W(background),0,0,0);
X               }
X               break;
X
X         case E_DELETELINE:  		/* delete a line */
X               if (*W(esc)) {
X                  register int count = *W(esc);
X                  scroll(win,text,W(y)-fsizehigh,T_HIGH,count*fsizehigh,
X                      W(background));
X                  }
X               else {
X                  scroll(win,text,W(y)-fsizehigh,T_HIGH,fsizehigh,
X                      W(background));
X                  }
X               done++;
X               break;
X
X         case E_DELETECHAR:  		/* delete a character */
X               {
X               register int wide = fsizewide*(*W(esc)?*W(esc):1);
X               if (wide+W(x)>T_WIDE)
X                  wide = T_WIDE-W(x);
X               bit_blit(text,W(x),W(y)-fsizehigh,
X                        T_WIDE-W(x)-wide, fsizehigh,BIT_SRC,
X                        text,W(x)+wide,W(y)-fsizehigh);
X               bit_blit(text,T_WIDE-wide,W(y)-fsizehigh,wide,
X                    fsizehigh,W(background),0,0,0);
X               }
X               break;
X
X         case E_UPLINE:  		/* up 1 line */
X#ifdef FRACCHAR
X               if (cnt>0) {	/* move up fractions of a character line */
X                  int div = W(esc)[1] == 0 ? 1 : W(esc)[1];
X                  int n = W(esc)[0] * fsizehigh / div;
X                  if (W(y)>n) {
X                     W(y) -= n;
X                     if (Do_clip())
X                        Set_cliplow(10000,W(y)+W(text).y-fsizehigh);
X                     }
X                  break;
X                  }
X#endif
X               if (W(y)>fsizehigh) W(y) -= fsizehigh;
X               if (Do_clip())
X                  Set_cliplow(10000,W(y)+W(text).y-fsizehigh);
X               break;
X
X         case E_RIGHT:  		/* right 1 line */
X#ifdef FRACCHAR				
X               if (cnt>0) {	/* move right/left a fraction of a character */
X                  int div = W(esc)[1] == 0 ? 1 : W(esc)[1];
X                  int n = W(esc)[0] * fsizewide / div;
X                  W(x) += n;
X                  if (W(x) < 0)
X                     W(x) = 0;
X                  break;
X                  }
X#endif
X               W(x) += fsizewide;
X               break;
X
X         case E_DOWN:			/* down 1 line */
X#ifdef FRACCHAR
X               if (cnt>0) {	/* move down a fraction of a character */
X                  int div = W(esc)[1] == 0 ? 1 : W(esc)[1];
X                  int n = W(esc)[0] * fsizehigh / div;
X						if (W(y)+n > T_HIGH) {
X							scroll(win,text,0,T_HIGH,n,W(background));
X							done++;
X							}
X                  else {
X							W(y) += n;
X							if (Do_clip())
X								Set_cliphigh(0,W(y)+W(text).y);
X                     }
X                  break;
X                  }
X#endif
X               if (W(y)+fsizehigh > T_HIGH) {
X                  scroll(win,text,0,T_HIGH,fsizehigh,W(background));
X                  done++;
X                  }
X               else {
X                  W(y) += fsizehigh;
X                  if (Do_clip())
X                     Set_cliphigh(0,W(y)+W(text).y);
X                  }
X               break;
X
X         case E_FCOLOR:       /* set forground color */
X               W(style) = (W(style)&NOCOLOR) | GETCOLOR(*W(esc));
X               BORDER(win);
X               break;
X
X         case E_BCOLOR:       /* set background color */
X               W(background) = (W(background)&NOCOLOR) | GETCOLOR(*W(esc));
X               BORDER(win);
X               break;
X
X         case E_STANDOUT:		/* inverse video (characters) */
X	       standout( win );
X               break;
X
X         case E_STANDEND:		/* normal video (characters) */
X	       standend( win );
X               break;
X
X         case E_CLEAREOL:  		/* clear to end of line */
X               bit_blit(text,W(x),W(y)-fsizehigh,T_WIDE-W(x),
X                    fsizehigh,W(background),0,0,0);
X               if (Do_clip())
X                  Set_cliphigh(BIT_WIDE(W(window)),0);
X               break;
X
X         case E_CLEAREOS:  		/* clear to end of window */
X               bit_blit(text,W(x),W(y)-fsizehigh,T_WIDE-W(x),
X                    fsizehigh,W(background),0,0,0);
X               bit_blit(text,0,W(y),T_WIDE,T_HIGH-W(y),W(background),0,0,0);
X               if (Do_clip())
X                  Set_cliphigh(BIT_WIDE(W(window)),BIT_HIGH(window));
X               break;
X
X         case E_SETCURSOR:			/* set the character cursor */
X					W(curs_type) = *W(esc);
X					break;
X         case E_BLEEP:			/* highlight a section of the screen */
X               if (cnt>2) {
X                  register int *p = W(esc);
X                  if (p[0]<0 || p[1]<0 )
X                     break;
X                  p[2] = BETWEEN(1,p[2],BIT_WIDE(screen)-1);
X                  p[3] = BETWEEN(1,p[3],BIT_WIDE(screen)-1);
X                  bit_blit(screen,p[0],p[1],p[2],p[3],BIT_NOT(BIT_DST),NULL_DATA,0,0);
X                  fsleep();
X                  bit_blit(screen,p[0],p[1],p[2],p[3],BIT_NOT(BIT_DST),NULL_DATA,0,0);
X                  done++;
X                  }
X               break;
X
X         case E_FONT:  			/* pick a new font */
X#ifdef CUT
X               W(flags) &= ~W_SNARFABLE;
X#endif
X               if (cnt > 0) {
X                  W(esc)[TEXT_COUNT] = 0;
X                  if (W(esc)[cnt]>0 && (W(snarf)=malloc(W(esc)[cnt]+1)) != (char *)0)
X                     W(flags) |= W_TEXT;
X                  W(code) = T_FONT;
X                  break;
X                  }
X
X                  {
X                  int font_count = W(esc)[cnt];
X                  int baseline = FSIZE(baseline);
X
X                  W(font)=Get_font(font_count);
X		  fsizehigh = FSIZE(high);
X		  fsizewide = FSIZE(wide);
X                  W(y) += FSIZE(baseline)-baseline;
X                  if (W(y) < fsizehigh) {
X                     scroll(win,text,W(y)-fsizehigh,T_HIGH,
X                            W(y)-fsizehigh,W(background));
X                     W(y)=fsizehigh;
X                     done++;
X                     }
X                  }
X               break;
X
X         case E_MOUSE:  		/* testing  -- move the mouse */
X               MOUSE_OFF(mousex,mousey);
X               if (W(esc_cnt) < 1) {
X                  mousex = W(x0) + W(x);
X                  mousey = W(y0) + W(y);
X                  }
X               else {
X                  mousex = W(esc)[cnt-1];
X                  mousey = W(esc)[cnt];
X                  mousex = BETWEEN(0,mousex,BIT_WIDE(screen)-1);
X                  mousey = BETWEEN(0,mousey,BIT_HIGH(screen)-1);
X                  }
X               if (!(W(flags)&W_ACTIVE && mousein(mousex,mousey,win,0)))
X                  MOUSE_ON(mousex,mousey);
X               break;
X
X         case E_SIZE:  			/* reshape window: cols, rows */
X               if (!W(flags)&W_ACTIVE) break;
X               if (cnt >= 1) {
X                  int cols = W(esc)[cnt-1];
X                  int lines = W(esc)[cnt];
X                  int x = W(x0), y = W(y0);
X
X                  MOUSE_OFF(mousex,mousey);
X
X                  if (cnt>=3) {
X                     x = W(esc)[0];
X                     y = W(esc)[1];
X                     }
X
X                  if (win!=active)
X                     cursor_off();
X                  ACTIVE_OFF();
X                  expose(win);
X                  shape(x, y,
X                        cols?cols*fsizewide+2*SUM_BDR:
X                             2*SUM_BDR + WIDE,
X                        lines?lines*fsizehigh+2*SUM_BDR:
X                             2*SUM_BDR + HIGH);
X                  ACTIVE_ON();
X                  if (!(W(flags)&W_ACTIVE && mousein(mousex,mousey,win,0)))
X                     MOUSE_ON(mousex,mousey);
X                  done++;
X                  }
X               break;
X
X         case E_PUTSNARF:  		/* put the snarf buffer */
X               if (snarf)
X                  Write(W(to_fd),snarf,strlen(snarf));
X#ifdef DEBUG
X               dprintf(y)(stderr,"%s: sending yank buffer [%s]\n",W(tty),
X                         snarf?snarf:"EMPTY");
X#endif
X               break;
X
X         case E_GIMME:  		/* snarf text into input queue */
X               W(esc)[TEXT_COUNT] = 0;
X               if (W(esc)[cnt]>0 && W(esc)[cnt]<MAXSHELL &&
X                          (W(snarf)=malloc(W(esc)[cnt]+1)) != (char *)0)
X                  W(flags) |= W_TEXT;
X               W(code) = T_GIMME;
X               break;
X
X         case E_GMAP:  		/* read a bitmap from a file */
X#ifdef DEBUG
X              dprintf(*)(stderr,"%s: fetching bitmap %d\r\n",
X                               W(tty),*W(esc)-1);
X#endif
X               W(esc)[TEXT_COUNT] = 0;
X               if (W(esc)[cnt]>0 && W(esc)[cnt]<MAX_PATH &&
X                          (W(snarf)=malloc(W(esc)[cnt]+1)) != (char *)0)
X                  W(flags) |= W_TEXT;
X               W(code) = T_GMAP;
X               break;
X
X         case E_SMAP:  		/* save a bitmap on a file */
X               W(esc)[TEXT_COUNT] = 0;
X               if (W(esc)[cnt]>0 && W(esc)[cnt]<MAX_PATH &&
X                          (W(snarf)=malloc(W(esc)[cnt]+1)) != (char *)0) {
X                  W(flags) |= W_TEXT;
X#ifdef DEBUG
X                  dprintf(*)(stderr,"%s: saving bitmap %d\r\n",
X                               W(tty),*W(esc)-1);
X#endif
X                  }
X               W(code) = T_SMAP;
X               break;
X
X         case E_SNARF:  		/* snarf text into the snarf buffer */
X               W(esc)[TEXT_COUNT] = 0;
X               if (W(esc)[cnt]>=0 &&	/*** was just > */
X                          (W(snarf)=malloc(W(esc)[cnt]+1)) != (char *)0)
X                  W(flags) |= W_TEXT;
X               W(code) = T_YANK;
X               break;
X
X         case E_STRING:  		/* write text into the offscreen bitmap */
X               W(esc)[TEXT_COUNT] = 0;
X               if (W(esc)[cnt]>0 && /* W(bitmaps)[*W(esc)-1] && */
X                          (W(snarf)=malloc(W(esc)[cnt]+1)) != (char *)0)
X                  W(flags) |= W_TEXT;
X               W(code) = T_STRING;
X               break;
X
X         case E_GRUNCH:  		/* graphics scrunch mode  (experimental) */
X               W(esc)[TEXT_COUNT] = 0;
X               if (W(esc)[cnt]>=0 &&	/*** was just > */
X                          (W(snarf)=malloc(W(esc)[cnt]+1)) != (char *)0)
X                  W(flags) |= W_TEXT;
X               W(code) = T_GRUNCH;
X               break;
X
X#ifdef XMENU
X         case E_XMENU:  			/* extended menu stuff */
X										/* ^[3X	remove menu 3 from window */
X										/* ^[3,4X	select item 4 of menu 3 */
X										/* ^[1,2,3X	display menu 3 at 1,2 */
X										/* ^[1,2,3,4Xhighlight menu 3 item 4 at 1,2 */
X               {
X               register int *p = W(esc);
X               register struct menu_state *menu;
X               switch(cnt) {
X                  case 0:			/* remove menu from display */
X                     if (p[0]>=0 && p[0]<MAXMENU && (menu=W(menus[p[0]])))
X                        menu_remove(menu);
X                  case 1:			/* select active item */
X                     if (p[0]>=0 && p[0]<MAXMENU && (menu=W(menus[p[0]])))
X                        menu->current = p[1];
X                     break;
X                  case 2:			/* display menu  on window */
X                     if (p[2]>=0 && p[2]<MAXMENU && (menu=W(menus[p[2]])))
X                        menu_setup(menu,window,Scalex(p[0]),Scaley(p[1]),-1);
X                     break;
X                  case 3:			/* highlight menu item on window */
X                     if (p[2]>=0 && p[2]<MAXMENU && 
X                                   (menu=W(menus[p[2]])) && menu->menu) {
X                        bit_blit(window, Scalex(p[0])+MENU_BORDER,
X                                 Scaley(p[1])+(p[3]-1)*menu->bar_sizey+
X                                 MENU_BORDER,
X                               menu->bar_sizex, menu->bar_sizey,
X                               BIT_NOT(BIT_DST), NULL_DATA, 0, 0);
X                        }
X                     break;
X                     }
X               }
X               break;
X#endif
X         case E_MENU:  			/* get a menu */
X               {			/* should be split into several cases */
X               register int b = (W(esc)[0]<0);		/* which button */
X               register int n = Abs(W(esc)[0]);		/* menu number */
X
X               /* setup menu pointer */
X
X               if (cnt > 2) {
X                  int parent = n;		/* parent menu # */
X                  int child = W(esc[2]);	/* child menu number */
X                  int item = W(esc[1]);		/* item # of parent */
X                  int flags = W(esc[3]);	/* menu flags */
X
X                  if (parent<0 || parent >= MAXMENU || child >= MAXMENU ||
X                      W(menus[parent])==(struct menu_state*)0)
X                     break;
X
X#ifdef DEBUG
X                  dprintf(M)(stderr,"Linking menu %d to parent %d at item %d\n",
X                             child,parent,item);
X#endif
X
X                  if (item<0)					/* page link */
X                     W(menus[parent])->next = child;
X                  else if (item < W(menus[parent])->count)	/* slide lnk */
X                     menu_setnext(W(menus[parent]),item) = child; 
X
X                  /* menu flags */
X
X                  if (flags > 0)
X                     W(menus[parent])->flags = flags;
X
X                  break;
X                  }
X
X               /* download a menu */
X
X               if (cnt > 0) {
X                  W(esc)[TEXT_COUNT] = 0;
X                  if (W(menus)[n]) {
X                     menu_destroy(W(menus)[n]);
X                     W(menus)[n] = (struct menu_state *) 0;
X                     if (W(menu[0])== n)
X                        W(menu[0]) = -1;
X                     if (W(menu[1])== n)
X                        W(menu[1]) = -1;
X                     }
X                  if (W(esc)[cnt]>0 && (W(snarf)=malloc(W(esc)[cnt]+1))
X                                     != (char *)0) {
X                     W(flags) |= W_TEXT;
X                     W(code) = T_MENU;
X                     }
X#ifdef DEBUG
X                  dprintf(M)(stderr,"downloading menu %d\n",n);
X#endif
X                  }
X
X               /* select menu number */
X
X               else if (n < MAXMENU && W(menus)[n]) {
X                  int last_menu = W(menu[b]);  
X
X#ifdef DEBUG
X                  dprintf(M)(stderr,"selecting menu %d on button %d\n",n,b);
X#endif
X                  W(menu[b]) = n;
X                  if (last_menu<0 && button_state==(b?BUTTON_1:BUTTON_2))
X                     go_menu(b);
X                  }
X               else
X                  W(menu[b]) = -1;
X               }
X               break;
X
X         case E_EVENT:			/* get an event */
X               switch(cnt) {
X                  case 2:	/* append to an event */
X                  case 1:	/* set an event */
X                     W(esc)[TEXT_COUNT] = 0;
X                     if (W(esc)[cnt]>0 && (W(snarf)=malloc(W(esc)[cnt]+1))
X                                  != (char *)0) {
X                        W(flags) |= W_TEXT;
X                        W(code) = T_EVENT;
X                        }
X                     break;
X                  case 0:
X                    cnt = W(esc)[0];
X		    if( !CHK_EVENT(cnt) )
X		       break;
X                    EVENT_CLEAR_MASK(win,cnt);
X                    if (W(events)[GET_EVENT(cnt)]) {
X                       free (W(events)[GET_EVENT(cnt)]);
X                       W(events)[GET_EVENT(cnt)] = (char *) 0;
X                      }
X                    break;
X                  }
X               break;
X
X         case E_SEND:			/* send a message */
X               W(esc)[TEXT_COUNT] = 0;
X               if (W(esc)[cnt]>0 && (W(snarf)=malloc(W(esc)[cnt]+1))
X                                  != (char *)0) {
X                  W(flags) |= W_TEXT;
X                  W(code) = T_SEND;
X                  }
X               break;
X
X         case E_BITGET:			/* upload a bitmap (temporary)*/
X               {
X               int offset = W(esc)[2];
X               int which = *W(esc);
X               int size = W(esc)[1];
X               BITMAP *m = W(bitmaps)[which-1];
X
X               if (cnt>1 && which>0 && which < MAXBITMAPS &&
X                        m != (BITMAP *) 0 &&
X                        size+offset<BIT_SIZE(m))
X                  write(W(to_fd),BIT_DATA(m)+offset,size);
X               }
X               break;
X         case E_BITCRT:  		/* create/destroy a bitmap */
X               switch(cnt) {
X                  case 0:
X                     if (W(esc)[0] && W(esc[0]<=MAXBITMAPS) &&
X                                  W(bitmaps)[W(esc)[0]-1] != (BITMAP *) 0) {
X                        bit_destroy(W(bitmaps)[W(esc)[0]-1]);
X                        W(bitmaps)[W(esc)[0]-1] = (BITMAP *) 0;
X#ifdef DEBUG
X                        dprintf(B)(stderr,"%s: Destroyed bitmap %d\r\n",
X                                  W(tty),*W(esc)-1);
X#endif
X                        }
X                     break;
X                  case 2:		/* create a new bitmap */
X                     if (W(esc)[0] && W(esc[0]<=MAXBITMAPS) &&
X                                  W(bitmaps)[W(esc)[0]-1] == (BITMAP *) 0) {
X                        W(bitmaps)[W(esc)[0]-1] = 
X                              bit_alloc(Scalex(W(esc)[1]),Scalex(W(esc)[2]),
X                                        NULL_DATA,DEPTH);
X#ifdef DEBUG
X                        dprintf(B)(stderr,"%s: created bitmap %d (%d,%d)\r\n",
X                                W(tty),*W(esc),W(esc)[1],W(esc)[2]);
X#endif
X                        }
X                     break;
X                  }
X               break;
X
X         case E_BITLOAD:  		/* download a bitmap */
X               if (cnt >=2) {
X                  W(esc)[TEXT_COUNT] = 0;
X                  W(bitmap) = bit_alloc(W(esc[0]),W(esc[1]),NULL_DATA,DEPTH);
X                  if (W(bitmap) != (BITMAP *) 0) {
X                     W(flags) |= W_TEXT;
X                     W(snarf) = (char *) BIT_DATA(W(bitmap));
X                     }
X                  W(code) = T_BITMAP;
X                  }
X               break;
X
X         case E_SHAPE:  		/* reshape window, make it active */
X
X               MOUSE_OFF(mousex,mousey);
X
X               ACTIVE_OFF();
X               if (win!=active) {
X                  cursor_off();
X                  expose(win);
X                  }
X               
X               if (cnt >= 3)
X                  shape(W(esc)[cnt-3], W(esc)[cnt-2],
X                        W(esc)[cnt-1], W(esc)[cnt]);
X               else if (cnt == 1)
X                  shape(W(esc)[cnt-1], W(esc)[cnt],
X                        BIT_WIDE(W(border)),
X                        BIT_HIGH(W(border)));
X
X               ACTIVE_ON();
X               if (!(W(flags)&W_ACTIVE && mousein(mousex,mousey,win,0)))
X                  MOUSE_ON(mousex,mousey);
X
X               done++;
X               break;
X
X         case E_BITBLT: 		/* do a bit blit */
X               win_rop(win,window);
X               done++;
X               break;
X
X         case E_CIRCLE:  		/* Plot a circle (or ellipse) */
X               circle_plot(win,window);
X               break;
X
X         case E_LINE:  			/* Plot a line */
X               win_plot(win,window);
X               break;
X
X         case E_GO:  			/* Go; move graphics pointer */
X               win_go(win);
X               break;
X
X         case E_MOVE:  			/* move to x,y pixels */
X#ifdef CUT
X                  W(flags) &= ~W_SNARFABLE;
X#endif
X                  if (Do_clip())
X                     Set_cliphigh(W(x)+W(text).x+fsizewide,W(y)+W(text).y);
X		  if (cnt>0) {
X                     W(x) = Scalex(*W(esc));
X                     W(y) = Scaley(W(esc)[1]);
X                     }
X                   else {
X                     W(x) += Scalex(*W(esc));
X                     }
X                   if (W(x)+fsizewide > WIDE && !(W(flags)&W_NOWRAP))
X                      W(x) = WIDE-fsizewide;
X                   if (W(y) > HIGH)
X                      W(y) = HIGH - fsizehigh;
X                   if (Do_clip())
X                      Set_cliplow(W(x)+W(text).x,W(y)+W(text).y-fsizehigh);
X               break;
X
X         case E_CUP:  			/* move to col,row (zero based) */
X               if (cnt < 1) break;
X                  {
X                  register int x = W(esc)[cnt-1] * fsizewide;
X                  register int y = W(esc)[cnt] * fsizehigh;
X                  if (x == BETWEEN(-1,x,T_WIDE-fsizewide) &&
X                      y == BETWEEN(-1,y,T_HIGH)) {
X                      if (Do_clip())
X                        Set_cliphigh(W(x)+W(text).x+fsizewide,W(y)+W(text).y);
X                      W(y) = y+fsizehigh;
X                      W(x) = x;
X                      if (Do_clip())
X                         Set_cliplow(W(x)+W(text).x,W(y)+W(text).y-fsizehigh);
X                      }
X                  }
X               break;
X
X         case E_VI:  			/* turn on vi hack */
X               W(flags) |= W_VI;
X               break;
X
X         case E_NOVI:  			/* turn off vi hack */
X               W(flags) &= ~W_VI;
X               break;
X
X         case E_PUSH:			/* push environment */
X              win_push(win,*W(esc));
X              break;
X
X         case E_POP:			/* pop old environment */
X              MOUSE_OFF(mousex,mousey);
X              win_pop(win);
X              if (!(W(flags)&W_ACTIVE && mousein(mousex,mousey,win,0)))
X                 MOUSE_ON(mousex,mousey);
X              done++;
X              break;
X
X         case E_TEXTREGION:		/* setup text region */
X              switch (cnt) {
X                 case 1:	/* setup scrolling region (~aka vt100) */
X                      if (W(esc)[0] >=0 && W(esc)[1] >= W(esc)[0] && 
X                              	W(esc)[1]*fsizehigh < BIT_HIGH(W(window))) {
X                         W(text.x) = 0;
X                         W(text.wide) = BIT_WIDE(W(window));
X                         W(text.y) = fsizehigh*W(esc[0]);
X                         W(text.high) = fsizehigh*(1+W(esc[1])) - W(text.y);
X                         if (W(y) < W(text.y)+fsizehigh)
X                            W(y) = W(text.y) + fsizehigh;
X                         if (W(y) > W(text.high))
X                            W(y) = W(text.high);
X                         }
X                      break;
X                 case 3:		/* set up entire region */
X                      W(text.wide) = Scalex(W(esc[2]));
X                      W(text.high) = Scaley(W(esc[3]));
X                      W(text.x) = Scalex(W(esc[0]));
X                      W(text.y) = Scaley(W(esc[1]));
X                      if (W(text.high) >= fsizehigh*MIN_Y  &&
X                                       W(text.wide) >= fsizewide*MIN_X) {
X                         W(x) = 0;
X                         W(y) = fsizehigh;
X#ifdef CUT
X                         W(flags) &= ~W_SNARFABLE;
X#endif
X                         break;
X                         }
X                      W(text.x) = 0;
X                      W(text.y) = 0;
X                      W(text.wide) = 0;
X                      W(text.high) = 0;
X                      break;
X                 case 4:	/* set up entire region (use rows, cols) */
X                      W(text.x) = W(esc[0]) * fsizewide;
X                      W(text.y) = W(esc[1]) * fsizehigh;
X                      W(text.wide) = W(esc[2]) * fsizewide;
X                      W(text.high) = W(esc[3]) * fsizehigh;
X                      if (W(text.high) >= fsizehigh*MIN_Y  &&
X                                       W(text.wide) >= fsizewide*MIN_X) {
X                          W(x) = 0;
X                          W(y) = fsizehigh;
X                          break;
X                          }
X                      break;
X                 case 0: 		/* clear text region */
X#ifdef CUT
X                      if (W(text.x)%fsizewide!= 0 || W(text.y)%fsizehigh!=0)
X                         W(flags) &= ~W_SNARFABLE;
X#endif
X                      W(text.x) = 0;
X                      W(text.y) = 0;
X                      W(text.wide) = 0;
X                      W(text.high) = 0;
X                      break;
X                 }
X              done++;
X              break;
X
X         case E_SETMODE:  		/* set a window mode */
X#ifdef DEBUG
X              dprintf(E)(stderr,"%s: setting mode %d\r\n",W(tty),*W(esc));
X#endif
X              switch(W(esc)[0]) {
X		 case M_STANDOUT:
X		      standout(win);
X		      break;
X                 case M_BACKGROUND:	/* enable background writes */
X                      W(flags) |= W_BACKGROUND;
X                      break;
X                 case M_NOINPUT:	/* disable keyboard input */
X                      W(flags) |= W_NOINPUT;
X                      break;
X                 case M_AUTOEXPOSE:	/* auto expose upon write */
X                      W(flags) |= W_EXPOSE;
X                      break;
X                 case M_WOB:		/* set white on black */
X                      if (W(flags)&W_REVERSE) 
X                         break;
X#ifdef COLOR
X                      W(style) = W(style)&NOCOLOR |
X                            (~W(style))&~NOCOLOR;
X                      W(background) = W(background)&NOCOLOR |
X                            (~W(background))&~NOCOLOR;
X                      CLEAR(window,W(background));
X                      BORDER(win);
X#else
X                      W(background) = BIT_SET;
X                      W(flags)|= W_REVERSE;
X                      if (W(flags)&W_OVER)
X                         W(style) = ROP_INVERT(W(style));
X                      else
X                         W(style)= W(flags)&W_STANDOUT ?
X                                          BIT_SRC : BIT_NOT(BIT_SRC);
X                      CLEAR(window,BIT_NOT(BIT_DST));
X#endif
X                      if (Do_clip())
X                         Set_all();
X                      break;
X                 case M_NOWRAP:  	/* turn on no-wrap */
X                      W(flags) |= W_NOWRAP;
X                      break;
X                 case M_OVERSTRIKE:	/* turn on overstrike */
X                      W(style) = W(style)&~NOCOLOR | W(op)&NOCOLOR;
X                      W(flags) |= W_OVER;
X                      break;
X                 case M_ABS:		/* set absolute coordinate mode */
X                      W(flags) |= W_ABSCOORDS;
X                      break;
X                 case M_DUPKEY:		/* duplicate esc char from keyboard */
X                      W(flags) |= W_DUPKEY;;
X                      if (cnt > 0)
X                         W(dup) = W(esc[1])&0xff;
X                      else
X                         W(dup) = DUP_CHAR;
X                      break;
X                 case M_NOBUCKEY:	/* set no buckey interpretation mode */
X                      W(flags) |= W_NOBUCKEY;
X                      break;
X#ifndef NOSTACK
X                 case M_STACK:		/* enable event stacking */
X                      EVENT_SET_MASK(win,EVENT_STACK);
X                      break;
X#endif
X
X#ifdef CUT
X                 case M_SNARFLINES:	/* only cut lines */
X                      W(flags) |= W_SNARFLINES;
X                      break;
X                 case M_SNARFTABS:	/* change spaces to tabs */
X                      W(flags) |= W_SNARFTABS;
X                      break;
X                 case M_SNARFHARD:	/* snarf even if errors */
X                      W(flags) |= W_SNARFHARD;
X                      break;
X#endif
X                 case M_ACTIVATE:	/* activate the window */
X                      if (win == active) 
X                          break;
X                      
X                      MOUSE_OFF(mousex,mousey);
X
X                      cursor_off();
X                      ACTIVE_OFF();
X                      expose(win);
X                      ACTIVE_ON();
X                      cursor_on();
X                      done++;
X
X                      if (!(W(flags)&W_ACTIVE && mousein(mousex,mousey,win,0)))
X                         MOUSE_ON(mousex,mousey);
X                      break;
X                      }
X              break;
X
X         case E_CLEARMODE:  		/* clear a window mode  */
X#ifdef DEBUG
X              dprintf(E)(stderr,"%s: clearing mode %d\r\n",W(tty),*W(esc));
X#endif
X              switch(W(esc)[0]) {
X		 case M_STANDOUT:
X		      standend(win);
X		      break;
X                 case M_BACKGROUND:	/* don't permit background writes */
X                      W(flags) &= ~W_BACKGROUND;
X                      break;
X                 case M_NOINPUT:	/* permit keyboard input */
X                      W(flags) &= ~W_NOINPUT;
X                      break;
X                 case M_AUTOEXPOSE:	/* don't auto expose */
X                      W(flags) &= ~W_EXPOSE;
X                      break;
X                 case M_WOB:		/* set black-on-white */
X                      if (!(W(flags)&W_REVERSE)) 
X                         break;
X#ifdef COLOR
X                      W(style) = W(style)&NOCOLOR |
X                            (~W(style))&~NOCOLOR;
X                      W(background) = W(background)&NOCOLOR |
X                            (~W(background))&~NOCOLOR;
X                      CLEAR(window,W(background));
X                      BORDER(win);
X#else
X                      W(background) = BIT_CLR;
X                      W(flags)&= ~W_REVERSE;
X                      if(W(flags)&W_OVER)
X                         W(style) = ROP_INVERT(W(style));
X                      else
X                         W(style)= W(flags)&W_STANDOUT ?
X                                BIT_NOT(BIT_SRC) : BIT_SRC;
X                      CLEAR(window,BIT_NOT(BIT_DST));
X#endif
X                      if (Do_clip())
X                         Set_all();
X                      break;
X                 case M_NOWRAP:  	/* turn off no-wrap */
X                      W(flags) &= ~W_NOWRAP;
X                      break;
X                 case M_OVERSTRIKE:	/* turn off overstrike */
X                      if ( !(W(flags)&W_STANDOUT) ^ !(W(flags)&W_REVERSE))
X#ifdef COLOR
X                         W(style) = BIT_SRC | ~NOCOLOR & W(background);
X                      else
X                         W(style) = BIT_SRC | ~NOCOLOR & W(style);
X#else
X                         W(style) = BIT_NOT(BIT_SRC);
X                      else
X                         W(style) = BIT_SRC;
X#endif
X                      W(flags) &= ~W_OVER;
X                      break;
X                 case M_ABS:		/* set relative coordinate mode */
X                      W(flags) &= ~W_ABSCOORDS;
X                      break;
X                 case M_DUPKEY:		/* reset keyboard dup-ky mode */
X                      W(flags) &= ~W_DUPKEY;
X                      break;
X                 case M_NOBUCKEY:	/* reset no buckey interpretation mode
X					*/
X                      W(flags) &= ~W_NOBUCKEY;
X                      break;
X#ifndef NOSTACK
X                 case M_STACK:		/* enable event stacking */
X                      EVENT_CLEAR_MASK(win,EVENT_STACK);
X                      break;
X#endif
X#ifdef CUT
X                 case M_SNARFLINES:	/* only cut lines */
X                      W(flags) &= ~W_SNARFLINES;
X                      break;
X                 case M_SNARFTABS:	/* change spaces to tabs */
X                      W(flags) &= ~W_SNARFTABS;
X                      break;
X                 case M_SNARFHARD:	/* snarf even if errors */
X                      W(flags) &= ~W_SNARFHARD;
X                      break;
X#endif
X                 case M_ACTIVATE:	/* hide the window */
X                      if (!(W(flags)&W_ACTIVE) || next_window==1)
X                          break;
X                      MOUSE_OFF(mousex,mousey);
X                      if (win!=active)
X                         cursor_off();
X                      ACTIVE_OFF();
X                      hide(win);
X                      ACTIVE_ON();
X                      if (win!=active)
X                         cursor_on();
X                      if (!(W(flags)&W_ACTIVE && mousein(mousex,mousey,win,0)))
X                         MOUSE_ON(mousex,mousey);
X
X                      done++;
X                      break;
X                      }
X              break;
X
X         case E_GETINFO:  		/* send window info back to shell */
X              get_info(win,window,text);
X              break;
X                    
X         case E_MAKEWIN:		/* make or goto a new window */
X              MOUSE_OFF(mousex,mousey);
X              win_make(win,indx);
X              done++;
X              break;
X
X         case E_HALFWIN:		/* make a 1/2 window */
X              {
X              register int *p = W(esc);
X              char *tty = NULL;
X              char *half_window();
X
X              if (cnt < 3 ||  cnt > 4)
X                 break;
X              MOUSE_OFF(mousex,mousey);
X              if (win!=active)
X                 cursor_off();
X              ACTIVE_OFF();
X
X              switch (cnt) {
X                 case 4:
X                    tty = half_window(p[0],p[1],p[2],p[3],p[4]);
X                    break; 
X                 case 3:
X                    tty = half_window(p[0],p[1],p[2],p[3],-1);
X                    break; 
X                 }
X              if (tty) {
X                 write(W(to_fd),tty,strlen(tty));
X                 ACTIVE_ON();
X                 }
X              if (win!=active)
X                 cursor_on();
X              write(W(to_fd),"\r",1);
X              done++;
X              }
X              break;
X         case E_CURSOR:			/* set the mouse cursor */
X              {
X              BITMAP *map = W(bitmaps[*W(esc)]);
X              int x0=0,y0=0;
X
X              if (cnt > 0)
X                 x0 = W(esc[1]);
X              if (cnt > 0)
X                 y0 = W(esc[2]);
X
X              if (W(cursor)) {
X                 bit_destroy(W(cursor));
X                 W(cursor) = BIT_NULL;
X                 SETMOUSEICON(&mouse_arrow);
X                 }
X
X              if ( cursor_ok(map,x0,y0) && (W(cursor) = 
X                            bit_alloc(16,32,0,1)))
X                 bit_blit(W(cursor),0,0,16,32,BIT_SRC,map,x0,y0);
X              else
X                 W(cursor) = BIT_NULL;
X              }
X              break;
X
X         default:			/* not implemented */
X                    break;
X         }
X      if (!(W(flags)&W_ESCAPE))
X         W(flags) &= ~W_MINUS;
X      break;
X
X   /****************************************************************************
X    *	Normal characters
X    */
X
X   default:
X      switch(c&=0177) {
X         case ESC : 			/* turn on escape mode */
X                    W(flags) |= W_ESCAPE;
X                    W(flags) &= ~(W_MINUS);
X                    W(esc_cnt) = 0;
X                    W(esc[0]) = 0;
X                    break;
X
X         case C_NULL:			/* null character -- ignore */
X                    break;
X
X         case C_BS:			/* back space */
X                    if (Do_clip()) {
X                       Set_cliphigh(W(x)+W(text).x + fsizewide,0);
X                       }
X                    W(x) -= fsizewide;
X                    if (W(x) < 0)
X                       W(x) = 0;
X                    if (Do_clip()) {
X                       Set_cliplow(W(x)+W(text).x,10000);
X                       }
X                    break;
X
X         case C_FF:			/* form feed */
X                    CLEAR(text,W(background));
X                    W(x)=0;
X                    W(y)=fsizehigh;
X#ifdef CUT
X                    W(flags) |= W_SNARFABLE;
X#endif
X                    if (Do_clip())
X                       Set_all();
X                    done++;
X                    break;
X
X         case C_BELL:			/* ring the bell  */
X                    bell_on();
X                    if (!bell++) {
X                       CLEAR(W(window),BIT_NOT(BIT_DST));
X                       CLEAR(W(window),BIT_NOT(BIT_DST));
X                       }
X                    break;
X
X         case C_TAB:			/* tab */
X                    W(x) = ((W(x)/fsizewide +8)& ~ 7) * fsizewide;
X                    if (W(x)+fsizewide >= T_WIDE) {
X                       W(x)=0;
X                       if (W(y)+fsizehigh > T_HIGH) {
X                          scroll(win,text,0,T_HIGH,fsizehigh,W(background));
X                          done++;
X                          }
X                       else
X                          W(y) += fsizehigh;
X                       }
X                    break;
X
X         case C_RETURN:			/* return */
X                    if (Do_clip()) {
X                       Set_cliphigh(W(x)+W(text).x + fsizewide,0);
X                       Set_cliplow(W(text).x,10000);
X                       }
X                    W(x)=0;
X                    break;
X
X         case C_NL: 			/* line feed */
X                    if (W(y)+fsizehigh > T_HIGH) {
X                       scroll(win,text,0,T_HIGH,fsizehigh,W(background));
X                       done++;
X                       }
X                    else
X                       W(y) += fsizehigh;
X                    break;
X         default:			/* print a character */
X/*
X                    while (W(y) > T_HIGH) {
X                       W(y) -= fsizehigh;
X                       scroll(win,text,0,T_HIGH,fsizehigh,W(background));
X                       done++;
X                       }
X*/
X                    PUT_CHAR(text,W(x),W(y),W(font),W(style),c);
X
X                    W(x) += fsizewide;
X                    if (W(x)+fsizewide > T_WIDE && !(W(flags)&W_NOWRAP)) {
X                       if (Do_clip()) {
X                          Set_cliphigh(W(x)+W(text).x + fsizewide,0);
X                          Set_cliplow(W(text).x,10000);
X                          }
X                       W(x)=0;
X                       W(y) += fsizehigh;
X                       if (W(y) > T_HIGH) {
X                          W(y) -= fsizehigh;
X                          scroll(win,text,0,T_HIGH,fsizehigh,W(background));
X                          done++;
X                          }
X                       }
X                    break;
X         }
X      break;
X      }
X
X   if (Do_clip())
X      Set_cliphigh(W(x)+W(text).x+fsizewide,W(y)+W(text).y);
X
X   cursor_on();
X
X   MOUSE_ON(mousex,mousey);
X
X   if (text != window)		/* this is probably wrong */
X      bit_destroy(text);
X   if (sub_window) {
X      bit_destroy(window);
X      }
X
X   if (W(flags)&W_BACKGROUND && !(W(flags)&W_ACTIVE))
X      update(win, &clip);
X   return(indx);
X   }
X
X
Xstatic
Xstandout( win )
Xregister WINDOW *win;
X{
X	int	cnt;
X
X	if (W(flags)&W_STANDOUT)
X		return;
X#ifdef COLOR
X	cnt = W(style);
X	W(style) = W(background);
X	W(background) = cnt;
X#else
X
X	if (W(flags)&W_OVER) 
X		W(style) = ROP_INVERT(W(style));
X	else
X		W(style) = W(flags)&W_REVERSE ? BIT_SRC : BIT_NOT(BIT_SRC);
X#endif
X	W(flags) |= W_STANDOUT;
X}
X
X
Xstatic
Xstandend( win )
Xregister WINDOW *win;
X{
X	int	cnt;
X
X	if (!(W(flags)&W_STANDOUT))
X		return;
X#ifdef COLOR
X	cnt = W(style);
X	W(style) = W(background);
X	W(background) = cnt;
X#else
X
X	if (W(flags)&W_OVER) 
X		W(style) = ROP_INVERT(W(style));
X	else
X		W(style) = W(flags)&W_REVERSE ? BIT_NOT(BIT_SRC) : BIT_SRC;
X#endif
X	W(flags) &= ~ W_STANDOUT;
X}
END_OF_FILE
# end of 'src/put_window.c'
fi
echo shar: End of archive 61 \(of 61\).
cp /dev/null ark61isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
	21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 \
	38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 \
	55 56 57 58 59 60 61 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 61 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.