v08i054: wscrawl, Part02/05

Brian Wilson brianw at hpcvlx.cv.hp.com
Mon Jul 16 04:57:15 AEST 1990


Submitted-by: Brian Wilson <brianw at hpcvlx.cv.hp.com>
Posting-number: Volume 8, Issue 54
Archive-name: wscrawl/part02

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix at uunet.uu.net if you want that tool.
# If this archive is complete, you will see the following message at the end:
#		"End of archive 2 (of 5)."
# Contents:  wscrawl/README wscrawl/xac
# Wrapped by argv at turnpike on Sun Jul 15 11:47:10 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'wscrawl/README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'wscrawl/README'\"
else
echo shar: Extracting \"'wscrawl/README'\" \(3336 characters\)
sed "s/^X//" >'wscrawl/README' <<'END_OF_FILE'
X
X                               WSCRAWL 
X         (multi-display, multi-user, communications program)
X	          by Brian Wilson, brianw at cv.hp.com
X
X
XWhat "wscrawl" is:
X------------------
X
X    The program "wscrawl" is a demo of the networking capabilities of
XX-Windows.  The word "wscrawl" stands for "window-scrawl".  The user may 
Xthink of wscrawl as a paint program shared by any number of people at 
Xthe same time.  When wscrawl is run, it opens up a separate window on each 
Xparticipant's display.  From that point onward, each participant sees 
Xthe actions and ideas of every other participant as they occur. Each individual
Xmay simply watch, or participate at any moment.  Any individual may exit
Xout of the session at any time without affecting the other participants.  
X
X
X
XTo quickly get the concept of wscrawl:
X--------------------------------------
X
X     1) set your DISPLAY environment variable appropriately.  
X        (example for me at my workstation: "export DISPLAY=hpcvxbw:0")
X
X     2) have a friend (with X11 running) xhost your workstation
X	(example for my friend: "xhost +"  <-- xhost everyone in the world)
X
X     3) start a wscrawl session between the two of you
X	(example for me: "wscrawl -d hpcvxca:0" <-- my friend is hpcvxca:0)
X
X     4) push the left mouse button down and move the mouse.  For some menu
X	options, click on the menus at the top of the wscrawl window.
X
X     5) Concepts to try:
X
X	  a) Play tic-tac-toe between two workstations.  Change colors of pen 
X	     and draw the board in the center of the wscrawl window.  Each 
X	     player should use a different color.
X          
X          b) type a message to your friend.  This is done by selecting the
X	     "Type" item from the "Control" menu, then clicking the left
X	     button somewhere.  Type on the keyboard.  Try changine fonts.
X
X          c) Wscrawl to someone out of sight earshot.  Wscrawl to them,
X	     and then call them on the telephone.  By talking and scrawling
X	     diagrams, you can simulate being there with an pad and pencil.
X
X          d) resize your wscrawl window.  Notice that ALL wscrawl windows
X	     on ALL displays will resize accordingly.  This guarantees you
X	     are all seeing the same picture at all times.  Resize your window
X	     to the size of the display you are working at.
X
X          e) any person out of the total group may select "Close Window" from
X	     the "Control" menu at any time.  This change is duely noted in
X	     the "STATUS" window at the bottom of each wscrawl window.  The
X	     other people may continue to scrawl with no problems.
X
X	  f) scrawl a picture, then pull down the "Control" menu and select
X	     "Add a Display".  Type the name of your friend into the dialog
X	     box and hit return.  After a few seconds, your friend will see
X	     this new picture.
X
X          g) Fire up several wscrawl windows on your one display.  For me,
X	     I would type "wscrawl -d hpcvxbw:0 -d hpcvxbw:0 -d hpcvxbw:0".  
X	     See how it behaves.
X
X          h) Try some "File I/O".  Wscrawl saves and reads both standard
X	     X bitmap files and xwd standard files.  Import or export some
X	     of your favorite bitmaps, or dump a window using "xwd" and 
X	     load it into wscrawl.
X
X
XQuestions, comments, hacked source code: 
X----------------------------------------
XBrian Wilson
Xbrianw at cv.hp.com
X
END_OF_FILE
if test 3336 -ne `wc -c <'wscrawl/README'`; then
    echo shar: \"'wscrawl/README'\" unpacked with wrong size!
fi
# end of 'wscrawl/README'
fi
if test -f 'wscrawl/xac' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'wscrawl/xac'\"
else
echo shar: Extracting \"'wscrawl/xac'\" \(37771 characters\)
sed "s/^X//" >'wscrawl/xac' <<'END_OF_FILE'
X	       "-adobe-courier-medium-r-normal--12-120-75-75-m-70-iso8859-1");
X    else if (strcmp(font_file_name, "courR14") == 0)
X	strcpy(xlfd_string, 
X	       "-adobe-courier-medium-r-normal--14-140-75-75-m-90-iso8859-1");
X    else if (strcmp(font_file_name, "timBI18") == 0)
X	strcpy(xlfd_string, 
X	       "-adobe-times-bold-i-normal--18-180-75-75-p-98-iso8859-1");
X    else if (strcmp(font_file_name, "courR24") == 0)
X	strcpy(xlfd_string, 
X	       "-adobe-courier-medium-r-normal--24-240-75-75-m-150-iso8859-1");
X    else if (strcmp(font_file_name, "timR24") == 0)
X	strcpy(xlfd_string, 
X	       "-adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1");
X    else if (strcmp(font_file_name, "timBI24") == 0)
X	strcpy(xlfd_string, 
X	       "-adobe-times-bold-i-normal--24-240-75-75-p-128-iso8859-1");
X    else if (strcmp(font_file_name, "ncenR24") == 0)
X	strcpy(xlfd_string, 
X "-adobe-new century schoolbook-medium-r-normal--24-240-75-75-p-137-iso8859-1");
X    else if (strcmp(font_file_name, "vbee-36") == 0)
X	strcpy(xlfd_string, "vbee-36");
X    else if (strcmp(font_file_name, "vr-40") == 0)
X	strcpy(xlfd_string, "vr-40");
X    else if (strcmp(font_file_name, "vgl-40") == 0)
X	strcpy(xlfd_string, "vgl-40");
X    else if (strcmp(font_file_name, "vgl-40") == 0)
X	strcpy(xlfd_string, "vsgn-57");
X    else
X	return(FALSE);  /*not one of these fonts*/
X
X    if ((the_font_struct = XLoadQueryFont(disp_info[i].disp,
X          xlfd_string)) != NULL)
X    {
X        gcvalues.font = the_font_struct->fid;
X        disp_info[disp_num].the_font_struct = the_font_struct;
X        gcvalues.font = the_font_struct->fid;
X        XChangeGC(disp_info[i].disp, disp_info[disp_num].win_gc[i], GCFont, 
X                &gcvalues);
X        return(TRUE);
X     }
X     else 
X        return(FALSE);
X}
X
X
X/*
X * menu_selection - this function does the appropriate actions as specified
X *              by the menu referenced by the menu_num and item_num passed as
X *              parameters.
X */
Xmenu_selection(disp_num, menu_num, num_people_drawing, item_num)
Xint disp_num, menu_num, *num_people_drawing, item_num;
X{
X     int i, temp_num;
X     XColor scrn_def_ret, exact_def_ret;
X     XFontStruct *the_font_struct;
X     XWindowAttributes attr_ret;
X
X     switch (menu_num)
X     {
X	 case 0:                       /*Control menu*/
X	     switch (item_num)
X	     {
X		 case 1:	      /*scrawl*/
X	             if (disp_info[disp_num].cursor_on == TRUE)
X	             {
X			 disp_info[disp_num].cursor_on = FALSE;
X         	         XDrawLine(disp_info[disp_num].disp, 
X		         disp_info[disp_num].win_id,
X		         disp_info[disp_num].cursor_gc, 
X		         disp_info[disp_num].cur_pos.x, 
X		         disp_info[disp_num].cur_pos.y, 
X		         disp_info[disp_num].cur_pos.x + 
X		         disp_info[disp_num].prompt_width, 
X		         disp_info[disp_num].cur_pos.y);
X                     }
X		     if (disp_info[disp_num].scrawl_mode == TYPING)
X                         (*num_people_drawing)--;  /*stopped input for now*/
X 		     disp_info[disp_num].scrawl_mode = SCRAWLING;
X		     disp_info[disp_num].menu[menu_num].checked_item = 1;
X		     disp_info[disp_num].pen_width = 
X					 disp_info[disp_num].pen_widths.scrawl;
X		     for (i=1; i<disp_info[disp_num].menu[2].num_items; i++)
X		     {   /*determine which pen width we have*/
X	                 sscanf(menu_text[2][i], "%d", &temp_num);
X                         if (temp_num >= disp_info[disp_num].pen_width)
X			 {
X		             disp_info[disp_num].menu[2].checked_item=i;
X			     break;
X                         }
X		     }
X	             for (i=0; i<num_of_disps; i++)
X	             {
X			 if (disp_info[i].in_session_bool)
X			 {
X                             gcvalues.line_width =disp_info[disp_num].pen_width;
X	                     XChangeGC(disp_info[i].disp, 
X			           disp_info[disp_num].win_gc[i], 
X			           GCLineWidth, &gcvalues);
X			 }
X	             }
X		     XDefineCursor(disp_info[disp_num].disp,
X		        disp_info[disp_num].win_id,
X			XCreateFontCursor(disp_info[disp_num].disp, XC_dot));
X		     break;
X		 case 2:	      /*airbrush*/
X	             if (disp_info[disp_num].cursor_on == TRUE)
X	             {
X			 disp_info[disp_num].cursor_on = FALSE;
X         	         XDrawLine(disp_info[disp_num].disp, 
X		         disp_info[disp_num].win_id,
X		         disp_info[disp_num].cursor_gc, 
X		         disp_info[disp_num].cur_pos.x, 
X		         disp_info[disp_num].cur_pos.y, 
X		         disp_info[disp_num].cur_pos.x + 
X		         disp_info[disp_num].prompt_width, 
X		         disp_info[disp_num].cur_pos.y);
X                     }
X		     if (disp_info[disp_num].scrawl_mode == TYPING)
X                         (*num_people_drawing)--;  /*stopped input for now*/
X		     disp_info[disp_num].scrawl_mode = AIRBRUSHING;
X		     disp_info[disp_num].menu[menu_num].checked_item = 2;
X		     disp_info[disp_num].pen_width = 
X				       disp_info[disp_num].pen_widths.airbrush;
X		     for (i=1; i<disp_info[disp_num].menu[2].num_items; i++)
X		     {   /*determine which pen width we have*/
X	                 sscanf(menu_text[2][i], "%d", &temp_num);
X                         if (temp_num >= disp_info[disp_num].pen_width)
X			 {
X		             disp_info[disp_num].menu[2].checked_item=i;
X			     break;
X                         }
X		     }
X		     XDefineCursor(disp_info[disp_num].disp,
X		        disp_info[disp_num].win_id,
X			XCreateFontCursor(disp_info[disp_num].disp, 
X			XC_spraycan));
X		     break;
X		 case 3:	      /*type*/
X		     if (disp_info[disp_num].scrawl_mode != TYPING)
X                         (*num_people_drawing)++;  /*started input for now*/
X		     disp_info[disp_num].scrawl_mode = TYPING;
X		     disp_info[disp_num].menu[menu_num].checked_item = 3;
X		     XDefineCursor(disp_info[disp_num].disp,
X		        disp_info[disp_num].win_id,
X			XCreateFontCursor(disp_info[disp_num].disp, XC_xterm));
X		     break;
X		 case 4:	       /*eraser*/
X	             if (disp_info[disp_num].cursor_on == TRUE)
X	             {
X			 disp_info[disp_num].cursor_on = FALSE;
X         	         XDrawLine(disp_info[disp_num].disp, 
X		         disp_info[disp_num].win_id,
X		         disp_info[disp_num].cursor_gc, 
X		         disp_info[disp_num].cur_pos.x, 
X		         disp_info[disp_num].cur_pos.y, 
X		         disp_info[disp_num].cur_pos.x + 
X		         disp_info[disp_num].prompt_width, 
X		         disp_info[disp_num].cur_pos.y);
X                     }
X		     if (disp_info[disp_num].scrawl_mode == TYPING)
X                         (*num_people_drawing)--;  /*stopped input for now*/
X		     disp_info[disp_num].scrawl_mode = ERASING;
X		     disp_info[disp_num].menu[menu_num].checked_item = 4;
X		     disp_info[disp_num].pen_width = 
X				       disp_info[disp_num].pen_widths.eraser;
X		     for (i=1; i<disp_info[disp_num].menu[2].num_items; i++)
X		     {   /*determine which pen width we have*/
X	                 sscanf(menu_text[2][i], "%d", &temp_num);
X                         if (temp_num >= disp_info[disp_num].pen_width)
X			 {
X		             disp_info[disp_num].menu[2].checked_item=i;
X			     break;
X                         }
X		     }
X		     XDefineCursor(disp_info[disp_num].disp,
X		        disp_info[disp_num].win_id,
X			XCreateFontCursor(disp_info[disp_num].disp, 
X			XC_draped_box));
X		     break;
X		 case 5:	       /*shapes*/
X	             if (disp_info[disp_num].cursor_on == TRUE)
X	             {
X			 disp_info[disp_num].cursor_on = FALSE;
X         	         XDrawLine(disp_info[disp_num].disp, 
X		         disp_info[disp_num].win_id,
X		         disp_info[disp_num].cursor_gc, 
X		         disp_info[disp_num].cur_pos.x, 
X		         disp_info[disp_num].cur_pos.y, 
X		         disp_info[disp_num].cur_pos.x + 
X		         disp_info[disp_num].prompt_width, 
X		         disp_info[disp_num].cur_pos.y);
X                     }
X		     if (disp_info[disp_num].scrawl_mode == TYPING)
X                         (*num_people_drawing)--;  /*stopped input for now*/
X		     disp_info[disp_num].scrawl_mode = SELECTING_AN_AREA;
X		     disp_info[disp_num].menu[menu_num].checked_item = 5;
X		     disp_info[disp_num].pen_width = 
X					 disp_info[disp_num].pen_widths.shape;
X		     for (i=1; i<disp_info[disp_num].menu[2].num_items; i++)
X		     {   /*determine which pen width we have*/
X	                 sscanf(menu_text[2][i], "%d", &temp_num);
X                         if (temp_num >= disp_info[disp_num].pen_width)
X			 {
X		             disp_info[disp_num].menu[2].checked_item = i;
X			     break;
X                         }
X		     }
X		     disp_info[disp_num].dialog_what = DRAW_SHAPE;
X	             for (i=0; i<num_of_disps; i++)
X	             {
X			 if (disp_info[i].in_session_bool)
X			 {
X                             gcvalues.line_width =disp_info[disp_num].pen_width;
X	                     XChangeGC(disp_info[i].disp, 
X			           disp_info[disp_num].win_gc[i], 
X			           GCLineWidth, &gcvalues);
X			 }
X	             }
X		     XDefineCursor(disp_info[disp_num].disp,
X		        disp_info[disp_num].win_id,
X			XCreateFontCursor(disp_info[disp_num].disp, 
X			XC_crosshair));
X		     break;
X		 case 6:	       /*Rubber Pointer*/
X	             if (disp_info[disp_num].cursor_on == TRUE)
X	             {
X			 disp_info[disp_num].cursor_on = FALSE;
X         	         XDrawLine(disp_info[disp_num].disp, 
X		         disp_info[disp_num].win_id,
X		         disp_info[disp_num].cursor_gc, 
X		         disp_info[disp_num].cur_pos.x, 
X		         disp_info[disp_num].cur_pos.y, 
X		         disp_info[disp_num].cur_pos.x + 
X		         disp_info[disp_num].prompt_width, 
X		         disp_info[disp_num].cur_pos.y);
X                     }
X		     if (disp_info[disp_num].scrawl_mode == TYPING)
X                         (*num_people_drawing)--;  /*stopped input for now*/
X 		     disp_info[disp_num].scrawl_mode = RUBBER_POINTING;
X		     disp_info[disp_num].menu[menu_num].checked_item = 6;
X		     XDefineCursor(disp_info[disp_num].disp,
X		        disp_info[disp_num].win_id,
X			XCreateFontCursor(disp_info[disp_num].disp, XC_target));
X		     break;
X		 case 7:	       /*clear all windows*/
X	             for (i=0; i<num_of_disps; i++)
X	             {
X			 if (disp_info[i].in_session_bool)
X			 {
X			     XGetWindowAttributes(disp_info[i].disp, 
X				              disp_info[i].win_id, &attr_ret);
X			     XClearArea(disp_info[i].disp, 
X				    disp_info[i].win_id, 0, 0, attr_ret.width,
X				    attr_ret.height, False);
X                             XFlush(disp_info[i].disp);
X
X	                     if (disp_info[i].cursor_on == TRUE)
X	                     {/*we must turn it BACK ON, because XClear offed*/
X         	                 XDrawLine(disp_info[i].disp, 
X		                 disp_info[i].win_id,
X		                 disp_info[i].cursor_gc, 
X		                 disp_info[i].cur_pos.x, 
X		                 disp_info[i].cur_pos.y, 
X		                 disp_info[i].cur_pos.x + 
X		                 disp_info[i].prompt_width, 
X		                 disp_info[i].cur_pos.y);
X                             }
X			 }
X	             }
X		     NOTHING_DRAWN_YET = TRUE;
X		     break;
X		 case 8:	      /*dotted line (not a valid choice)*/
X		     break;
X		 case 9:	      /*Add Display*/
X		     disp_info[disp_num].previous_scrawl_mode = 
X				             disp_info[disp_num].scrawl_mode;
X	             if (disp_info[disp_num].cursor_on == TRUE)
X	             {
X			 disp_info[disp_num].cursor_on = FALSE;
X         	         XDrawLine(disp_info[disp_num].disp, 
X		         	disp_info[disp_num].win_id,
X		         	disp_info[disp_num].cursor_gc, 
X		         	disp_info[disp_num].cur_pos.x, 
X		         	disp_info[disp_num].cur_pos.y, 
X		         	disp_info[disp_num].cur_pos.x + 
X		         	disp_info[disp_num].prompt_width, 
X		         	disp_info[disp_num].cur_pos.y);
X                     }
X		     if (disp_info[disp_num].scrawl_mode == TYPING)
X                         (*num_people_drawing)--;  /*stopped input for now*/
X		     XDefineCursor(disp_info[disp_num].disp,
X		                   disp_info[disp_num].win_id,
X			           XCreateFontCursor(disp_info[disp_num].disp, 
X					  XC_cross));
X		     disp_info[disp_num].dialog_reply_index = 0;
X		     disp_info[disp_num].dialog_text_prompt = 
X					           "Enter Display To Add:";
X		     put_up_dialog(disp_num);
X		     disp_info[disp_num].scrawl_mode = RESPONDING_TO_DIALOG;
X		     disp_info[disp_num].dialog_what = ADD_A_DISPLAY;
X		     break;
X		 case 10:	      /*close window. Succeed from the session*/
X		     if (disp_info[disp_num].scrawl_mode == TYPING)
X                         (*num_people_drawing)--;  /*stopped input for now*/
X                     XDestroyWindow(disp_info[disp_num].disp, 
X				    disp_info[disp_num].win_id);
X                     disp_info[disp_num].in_session_bool = FALSE; /*no window*/
X                     XCloseDisplay(disp_info[disp_num].disp);
X                     for (i=temp_num=0; i< num_of_disps; i++)
X                     {
X                        if (disp_info[i].in_session_bool)
X	                {
X	                    temp_num = TRUE;
X	                    break;
X	                }
X	             }
X	             if (temp_num)
X		     {
X                         for (i=0; i<num_of_disps; i++)
X	                 {
X	                     if (disp_info[i].in_session_bool)
X	                         place_and_draw_status_win(i);
X	                 }
X		     }
X		     else
X	                exit(0);/*if no one is still in session, stop running*/
X		     break;
X	     }
X	     break;
X	 case 1:                       /*PenColor menu*/
X	     strncpy(disp_info[disp_num].pen_color_str, menu_text[1][item_num],
X		     40);
X	     disp_info[disp_num].menu[menu_num].checked_item = item_num;
X	     for (i=0; i<num_of_disps; i++)
X	     {
X                 if (disp_info[i].in_session_bool)
X	         {
X                     if (!XAllocNamedColor(disp_info[i].disp, DefaultColormap(
X		         disp_info[i].disp, DefaultScreen(disp_info[i].disp)), 
X		         menu_text[1][item_num], &scrn_def_ret, &exact_def_ret))
X	             {
X		         continue;        /*sorry, no good. No colors left.*/
X	             }
X                     gcvalues.foreground = scrn_def_ret.pixel;
X		     XChangeGC(disp_info[i].disp, 
X		           disp_info[disp_num].win_gc[i], GCForeground, 
X		           &gcvalues);
X		 }
X	     }
X	     break;
X	 case 2:                       /*PenWidth menu*/
X	     sscanf(menu_text[2][item_num], "%d", &temp_num);
X	     disp_info[disp_num].pen_width = temp_num;
X	     disp_info[disp_num].menu[menu_num].checked_item = item_num;
X	     switch(disp_info[disp_num].scrawl_mode)
X	     {
X		 case SCRAWLING: 
X	             disp_info[disp_num].pen_widths.scrawl = temp_num;
X		     break;
X		 case AIRBRUSHING: 
X	             disp_info[disp_num].pen_widths.airbrush = temp_num;
X		     break;
X		 case ERASING: 
X	             disp_info[disp_num].pen_widths.eraser = temp_num;
X		     break;
X		 case SELECTING_AN_AREA: 
X	             disp_info[disp_num].pen_widths.shape = temp_num;
X		     break;
X		 default: 
X		     break;
X	     }
X		     
X	     for (i=0; i<num_of_disps; i++)
X	     {
X                 if (disp_info[i].in_session_bool)
X	         {
X                     gcvalues.line_width = temp_num;
X	             XChangeGC(disp_info[i].disp, 
X			   disp_info[disp_num].win_gc[i], 
X			   GCLineWidth, &gcvalues);
X		 }
X	     }
X	     break;
X	 case 3:                       /*PenCapStyle menu*/
X             switch(item_num)
X	     {
X		 case 1: temp_num = CapRound; break;
X		 case 2: temp_num = CapButt; break;
X		 case 3: temp_num = CapNotLast; break;
X		 case 4: temp_num = CapProjecting; break;
X	     }
X	     disp_info[disp_num].capstyle = temp_num;
X	     disp_info[disp_num].menu[menu_num].checked_item = item_num;
X	     for (i=0; i<num_of_disps; i++)
X	     {
X                 if (disp_info[i].in_session_bool)
X	         {
X                     gcvalues.cap_style = temp_num;
X	             XChangeGC(disp_info[i].disp, 
X			   disp_info[disp_num].win_gc[i], 
X			   GCCapStyle, &gcvalues);
X		 }
X	     }
X	     break;
X	 case 4:                       /*Font menu*/
X	     strncpy(disp_info[disp_num].font_str, menu_text[4][item_num],
X		     250);
X
X	     for (i=0; i<num_of_disps; i++)
X	     {
X                 if (disp_info[i].in_session_bool)
X	         {
X	             if ((the_font_struct=XLoadQueryFont(disp_info[i].disp,
X		              menu_text[4][item_num])) != NULL)
X	             {
X		             gcvalues.font = the_font_struct->fid;
X		             disp_info[disp_num].the_font_struct = 
X				                  the_font_struct;
X                             gcvalues.font = the_font_struct->fid;
X		             XChangeGC(disp_info[i].disp, 
X		                   disp_info[disp_num].win_gc[i], GCFont, 
X		                   &gcvalues);
X	             }
X		     else if (load_moron_fonts(disp_num, i, 
X				  menu_text[4][item_num]) == FALSE)
X		     {
X		         printf("Couldn't allocate font.\n");
X		     }
X		 }
X	     }
X
X	     if (disp_info[disp_num].cursor_on == TRUE)     /*turn it off   */
X	     {						    /*and don't tell*/
X                 XDrawLine(disp_info[disp_num].disp, 
X		     disp_info[disp_num].win_id,
X	             disp_info[disp_num].cursor_gc, 
X	             disp_info[disp_num].cur_pos.x, 
X	             disp_info[disp_num].cur_pos.y, 
X	             disp_info[disp_num].cur_pos.x + 
X	             disp_info[disp_num].prompt_width, 
X	             disp_info[disp_num].cur_pos.y);
X             }
X
X             disp_info[disp_num].prompt_width = 
X	               disp_info[disp_num].the_font_struct->max_bounds.width;
X	     disp_info[disp_num].char_height = 
X	           (disp_info[disp_num].the_font_struct)->max_bounds.ascent +
X	           (disp_info[disp_num].the_font_struct)->max_bounds.descent;
X	     disp_info[disp_num].type_history = NULL;
X	     disp_info[disp_num].menu[menu_num].checked_item = item_num;
X         
X	     if (disp_info[disp_num].cursor_on == TRUE)   /*it is really off*/
X	     {                                            /*'cause look above*/
X	         disp_info[disp_num].cursor_on = TRUE;
X                 XDrawLine(disp_info[disp_num].disp, 
X		     disp_info[disp_num].win_id,
X	             disp_info[disp_num].cursor_gc, 
X	             disp_info[disp_num].cur_pos.x, 
X	             disp_info[disp_num].cur_pos.y, 
X	             disp_info[disp_num].cur_pos.x + 
X	             disp_info[disp_num].prompt_width, 
X	             disp_info[disp_num].cur_pos.y);
X             }
X	     break;
X	 case 5:                       /*Shape menu*/
X	     menu_selection(disp_num, 0, num_people_drawing, 5);/*choose shape*/
X	     disp_info[disp_num].menu[menu_num].checked_item = item_num;
X             switch(item_num)
X	     {
X		 case 1: 
X		     disp_info[disp_num].current_shape = STRAIGHT_LINE;
X		     break;
X		 case 2: 
X		     disp_info[disp_num].current_shape = OUTLINE_RECT;
X		     break;
X		 case 3: 
X		     disp_info[disp_num].current_shape = FILLED_RECT;
X		     break;
X		 case 4: 
X		     disp_info[disp_num].current_shape = OUTLINE_OVAL;
X		     break;
X		 case 5: 
X		     disp_info[disp_num].current_shape = FILLED_OVAL;
X		     break;
X		 default: break;
X	     }
X	     break;
X	 case 6:                       /*File I/O menu*/
X             switch(item_num)
X	     {
X		 case 1:          /*Save Bitmap*/
X	             if (disp_info[disp_num].cursor_on == TRUE)
X	             {
X			 disp_info[disp_num].cursor_on = FALSE;
X         	         XDrawLine(disp_info[disp_num].disp, 
X		         	disp_info[disp_num].win_id,
X		         	disp_info[disp_num].cursor_gc, 
X		         	disp_info[disp_num].cur_pos.x, 
X		         	disp_info[disp_num].cur_pos.y, 
X		         	disp_info[disp_num].cur_pos.x + 
X		         	disp_info[disp_num].prompt_width, 
X		         	disp_info[disp_num].cur_pos.y);
X                     }
X		     if (disp_info[disp_num].scrawl_mode == TYPING)
X                         (*num_people_drawing)--;  /*stopped input for now*/
X		     disp_info[disp_num].previous_scrawl_mode = 
X		                            disp_info[disp_num].scrawl_mode;
X		     disp_info[disp_num].scrawl_mode = SELECTING_AN_AREA;
X		     disp_info[disp_num].dialog_what = SAVE_BITMAP;
X		     XDefineCursor(disp_info[disp_num].disp,
X		                   disp_info[disp_num].win_id,
X			           XCreateFontCursor(disp_info[disp_num].disp, 
X					  XC_crosshair));
X		     break;
X		 case 2:         /*Read In Bitmap*/
X	             if (disp_info[disp_num].cursor_on == TRUE)
X	             {
X			 disp_info[disp_num].cursor_on = FALSE;
X         	         XDrawLine(disp_info[disp_num].disp, 
X		         	disp_info[disp_num].win_id,
X		         	disp_info[disp_num].cursor_gc, 
X		         	disp_info[disp_num].cur_pos.x, 
X		         	disp_info[disp_num].cur_pos.y, 
X		         	disp_info[disp_num].cur_pos.x + 
X		         	disp_info[disp_num].prompt_width, 
X		         	disp_info[disp_num].cur_pos.y);
X                     }
X		     if (disp_info[disp_num].scrawl_mode == TYPING)
X                         (*num_people_drawing)--;  /*stopped input for now*/
X		     XDefineCursor(disp_info[disp_num].disp,
X		                   disp_info[disp_num].win_id,
X			           XCreateFontCursor(disp_info[disp_num].disp, 
X					  XC_cross));
X		     disp_info[disp_num].dialog_reply_index = 0;
X		     disp_info[disp_num].dialog_text_prompt = 
X					           "File To Read Bitmap From:";
X		     put_up_dialog(disp_num);
X		     disp_info[disp_num].previous_scrawl_mode = 
X		                            disp_info[disp_num].scrawl_mode;
X		     disp_info[disp_num].scrawl_mode = RESPONDING_TO_DIALOG;
X		     disp_info[disp_num].dialog_what = READ_IN_BITMAP;
X		     break;
X		 case 3:             /*Read Text File*/
X	             if (disp_info[disp_num].cursor_on == TRUE)
X	             {
X			 disp_info[disp_num].cursor_on = FALSE;
X         	         XDrawLine(disp_info[disp_num].disp, 
X		         	disp_info[disp_num].win_id,
X		         	disp_info[disp_num].cursor_gc, 
X		         	disp_info[disp_num].cur_pos.x, 
X		         	disp_info[disp_num].cur_pos.y, 
X		         	disp_info[disp_num].cur_pos.x + 
X		         	disp_info[disp_num].prompt_width, 
X		         	disp_info[disp_num].cur_pos.y);
X                     }
X		     if (disp_info[disp_num].scrawl_mode == TYPING)
X                         (*num_people_drawing)--;  /*stopped input for now*/
X		     XDefineCursor(disp_info[disp_num].disp,
X		                   disp_info[disp_num].win_id,
X			           XCreateFontCursor(disp_info[disp_num].disp, 
X					  XC_cross));
X		     disp_info[disp_num].dialog_reply_index = 0;
X		     disp_info[disp_num].dialog_text_prompt = 
X					           "File To Read Text From:";
X		     put_up_dialog(disp_num);
X		     disp_info[disp_num].previous_scrawl_mode = 
X		                            disp_info[disp_num].scrawl_mode;
X		     disp_info[disp_num].scrawl_mode = RESPONDING_TO_DIALOG;
X		     disp_info[disp_num].dialog_what = READ_TEXTFILE;
X		     break;
X		 case 4:          /*Save Image*/
X	             if (disp_info[disp_num].cursor_on == TRUE)
X	             {
X			 disp_info[disp_num].cursor_on = FALSE;
X         	         XDrawLine(disp_info[disp_num].disp, 
X		         	disp_info[disp_num].win_id,
X		         	disp_info[disp_num].cursor_gc, 
X		         	disp_info[disp_num].cur_pos.x, 
X		         	disp_info[disp_num].cur_pos.y, 
X		         	disp_info[disp_num].cur_pos.x + 
X		         	disp_info[disp_num].prompt_width, 
X		         	disp_info[disp_num].cur_pos.y);
X                     }
X		     if (disp_info[disp_num].scrawl_mode == TYPING)
X                         (*num_people_drawing)--;  /*stopped input for now*/
X		     disp_info[disp_num].previous_scrawl_mode = 
X		                            disp_info[disp_num].scrawl_mode;
X		     disp_info[disp_num].scrawl_mode = SELECTING_AN_AREA;
X		     disp_info[disp_num].dialog_what = SAVE_IMAGE;
X		     XDefineCursor(disp_info[disp_num].disp,
X		                   disp_info[disp_num].win_id,
X			           XCreateFontCursor(disp_info[disp_num].disp, 
X					  XC_crosshair));
X		     break;
X		 case 5:         /*Read In Image*/
X	             if (disp_info[disp_num].cursor_on == TRUE)
X	             {
X			 disp_info[disp_num].cursor_on = FALSE;
X         	         XDrawLine(disp_info[disp_num].disp, 
X		         	disp_info[disp_num].win_id,
X		         	disp_info[disp_num].cursor_gc, 
X		         	disp_info[disp_num].cur_pos.x, 
X		         	disp_info[disp_num].cur_pos.y, 
X		         	disp_info[disp_num].cur_pos.x + 
X		         	disp_info[disp_num].prompt_width, 
X		         	disp_info[disp_num].cur_pos.y);
X                     }
X		     if (disp_info[disp_num].scrawl_mode == TYPING)
X                         (*num_people_drawing)--;  /*stopped input for now*/
X		     XDefineCursor(disp_info[disp_num].disp,
X		                   disp_info[disp_num].win_id,
X			           XCreateFontCursor(disp_info[disp_num].disp, 
X					  XC_cross));
X		     disp_info[disp_num].dialog_reply_index = 0;
X		     disp_info[disp_num].dialog_text_prompt = 
X					           "File To Read Image From:";
X		     put_up_dialog(disp_num);
X		     disp_info[disp_num].previous_scrawl_mode = 
X		                            disp_info[disp_num].scrawl_mode;
X		     disp_info[disp_num].scrawl_mode = RESPONDING_TO_DIALOG;
X		     disp_info[disp_num].dialog_what = READ_IN_IMAGE;
X		     break;
X	     }
X	     break;
X	 default:
X	     printf("ERROR: Unknown menu number in menu_selection().\n");
X	     exit(0);
X	     break;
X     }
X}
X
X
X/*
X * draw_menu_text - this function draws the menu contents such as text 
X *              and checkmarks as specified by the display and the menu_num. 
X *              This is usually called in response to an expose event, etc.
X */
Xdraw_menu_text(disp_num, menu_num)
Xint disp_num, menu_num;
X{
X    int i;
X
X    /*
X     * draw the bar under the menu heading
X     */
X    XDrawLine(disp_info[disp_num].disp,
X	      disp_info[disp_num].menu[menu_num].win_id,
X	      disp_info[disp_num].fg_menu_gc, 0, MENU_ITEM_HEIGHT+1, 
X	      MENU_ITEM_WIDTH, MENU_ITEM_HEIGHT+1);
X
X    /*
X     * draw all the text
X     */
X    for (i=0; i<disp_info[disp_num].menu[menu_num].num_items; i++)
X    {
X        XDrawString(disp_info[disp_num].disp,
X	       disp_info[disp_num].menu[menu_num].win_id, 
X	       disp_info[disp_num].fg_menu_gc, 15, i*MENU_ITEM_HEIGHT + 18, 
X	       menu_text[menu_num][i], strlen(menu_text[menu_num][i]));
X    }
X
X    /*
X     * draw the check mark of the current menu as long as the menu has a check
X     */
X    if (menu_num != 6)
X    {
X        XDrawLine(disp_info[disp_num].disp,
X	      disp_info[disp_num].menu[menu_num].win_id,
X	      disp_info[disp_num].fg_menu_gc, 4, 
X	      disp_info[disp_num].menu[menu_num].checked_item * 
X	      MENU_ITEM_HEIGHT + 15, 
X	      7, disp_info[disp_num].menu[menu_num].checked_item * 
X	      MENU_ITEM_HEIGHT + 18);
X        XDrawLine(disp_info[disp_num].disp,
X	      disp_info[disp_num].menu[menu_num].win_id,
X	      disp_info[disp_num].fg_menu_gc, 7, 
X	      disp_info[disp_num].menu[menu_num].checked_item * 
X	      MENU_ITEM_HEIGHT + 18, 
X	      12, disp_info[disp_num].menu[menu_num].checked_item * 
X	      MENU_ITEM_HEIGHT + 9);
X    }
X    XFlush(disp_info[disp_num].disp);
X}
X
X
X/*
X * draw_menu - this function draws the menus on the display whose index is
X *              passed as the argument.  This function is invoked usually
X *              when someone has just boinked the menu, causing it to unroll
X *              out with all the choices.  It can also be invoked when someone
X *              has let up the mouse button, probably making a choice. 
X *              The "current_menu" field of the disp_info struct should be
X *              set to the menu which changed.
X */
Xdraw_menu(disp_num)
Xint disp_num;
X{
X    int menu_num;
X    XWindowChanges new_dim;
X
X    menu_num = disp_info[disp_num].current_menu;
X
X    if (disp_info[disp_num].pointer_state != IN_MENU)    /*retract menu*/
X    {
X        new_dim.height = MENU_ITEM_HEIGHT;
X    }
X    else                                                 /*extend a menu*/
X    {
X        new_dim.height = disp_info[disp_num].menu[menu_num].num_items * 
X		     MENU_ITEM_HEIGHT;
X    }
X    XConfigureWindow(disp_info[disp_num].disp, 
X	       disp_info[disp_num].menu[menu_num].win_id, CWHeight, &new_dim);
X
X    /*
X     * The following is commented out because an expose event will occur,
X     * causing the menu text to be displayed WITHOUT this line.  Why keep
X     * it here you ask me?  Well, I can't answer that; it would reveal the
X     * location of insidious bugs in certain HP systems.  :-)
X     */
X    /*
X    draw_menu_text(disp_num, menu_num);
X     */
X}
X
X
X/*
X * slide_rubberband_box - this function waves the fixed size rubberband
X *                  box all over the window, waiting for the user to
X *                  click the button, thus placing the bitmap or image on all
X *                  of the displays.
X */
Xslide_rubberband_box(disp_num, num_people_drawing)
Xint disp_num, *num_people_drawing;
X{
X    Window rr, cr;          /* <-- These here are good variables, buckwheat.*/
X    unsigned int mskr;
X    int rxr, ryr, win_x, win_y;
X    int top, left, width, height, old_top, old_left;
X
X    width = disp_info[disp_num].rubber_band_width;
X    height = disp_info[disp_num].rubber_band_height;
X
X    if (disp_info[disp_num].first_point_bool)
X    {  
X        XQueryPointer(disp_info[disp_num].disp, 
X			  disp_info[disp_num].win_id, &rr, &cr, &rxr, 
X			  &ryr, &win_x, &win_y,&mskr);
X        disp_info[disp_num].cur_pos.x = win_x;
X        disp_info[disp_num].cur_pos.y = win_y;
X        disp_info[disp_num].first_point_bool = FALSE;
X        (*num_people_drawing)++;     /*slide this around till you click*/
X
X	top = disp_info[disp_num].cur_pos.y - 
X	                disp_info[disp_num].rubber_band_height/2;
X	left = disp_info[disp_num].cur_pos.x - 
X	                disp_info[disp_num].rubber_band_width/2;
X
X	XDrawRectangle(disp_info[disp_num].disp, disp_info[disp_num].win_id,
X	       disp_info[disp_num].rubber_band_gc,
X	       left, top, width, height);
X        XFlush(disp_info[disp_num].disp);
X    }
X
X    XQueryPointer(disp_info[disp_num].disp, 
X			  disp_info[disp_num].win_id, &rr, &cr, &rxr, 
X			  &ryr, &win_x, &win_y,&mskr);
X    if ((disp_info[disp_num].cur_pos.x != win_x) ||
X        (disp_info[disp_num].cur_pos.y != win_y))
X    {
X	/*
X	 * erase the old rubber band box
X	 */
X	old_top = disp_info[disp_num].cur_pos.y - 
X	                disp_info[disp_num].rubber_band_height/2;
X	old_left = disp_info[disp_num].cur_pos.x - 
X	                disp_info[disp_num].rubber_band_width/2;
X	XDrawRectangle(disp_info[disp_num].disp, disp_info[disp_num].win_id,
X	       disp_info[disp_num].rubber_band_gc,
X	       old_left, old_top, width, height);
X	/*
X	 * draw the new rubber band box
X	 */
X        disp_info[disp_num].cur_pos.x = win_x;
X        disp_info[disp_num].cur_pos.y = win_y;
X	top = disp_info[disp_num].cur_pos.y - height/2;
X	left = disp_info[disp_num].cur_pos.x - width/2;
X	XDrawRectangle(disp_info[disp_num].disp, disp_info[disp_num].win_id,
X	       disp_info[disp_num].rubber_band_gc, left, top, width, height);
X    }
X}
X
X
X/*
X * type_on_dialog - this routine is called once a cycle if the user is 
X *                  currently supposed to be typing in the dialog box.
X *                  This function handles the text, etc.
X *                  Global index: disp_info[disp_num].dialog_reply_index
X */
Xtype_on_dialog(disp_num)
Xint disp_num;
X{
X    XEvent the_event;
X    KeySym ksr;
X    char the_char[256];
X    int index;
X
X    if (XPending(disp_info[disp_num].disp))   /*check if there is a KeyPress*/
X    {
X	XNextEvent(disp_info[disp_num].disp, &the_event);
X        if (the_event.type != KeyPress)
X	{
X            XPutBackEvent(disp_info[disp_num].disp, &the_event);
X	    return(0);
X	}
X	else    /*it IS a KeyPressedEvent*/
X	{
X	    index = disp_info[disp_num].dialog_reply_index;
X            the_char[0] = 0;
X            XLookupString((XKeyEvent *) (&the_event),the_char,10, &ksr, NULL);
X            if (the_char[0] == 0)
X                return(0);                /*it was a shift or some such*/
X            else if (the_char[0] == 8)  /*8 == Backspace*/
X            {
X		if (index != 0)
X		{
X		    index--;
X                    (disp_info[disp_num].dialog_reply_index)--;
X		     XClearArea(disp_info[disp_num].disp,
X	                    disp_info[disp_num].dialog_win_id, 
X			    14 + index*FIXED_CHAR_WIDTH, DIALOG_WIN_HEIGHT-27,
X			    FIXED_CHAR_WIDTH, 19, False);
X		}
X	    }
X            else if (the_char[0] == 13)   /*13 == Carriage Return*/
X            {
X	        /*unmap dialog and take action*/
X                XUnmapWindow(disp_info[disp_num].disp, 
X			   disp_info[disp_num].dialog_win_id);
X		XSync(disp_info[disp_num].disp, False);
X		disp_info[disp_num].dialog_text_return[index] = '\0';
X		parse_and_fix_dialog_text(disp_num);
X		do_dialog_action(disp_num);
X	    }
X            else
X	    {
X		XDrawString(disp_info[disp_num].disp, 
X			disp_info[disp_num].dialog_win_id,
X			disp_info[disp_num].fg_menu_gc, 
X			14 + index*FIXED_CHAR_WIDTH, DIALOG_WIN_HEIGHT - 12,
X			the_char, 1);
X		disp_info[disp_num].dialog_text_return[index] = the_char[0];
X		(disp_info[disp_num].dialog_reply_index)++;
X	    }
X        }
X    }
X}
X
X
X/*
X * parse_and_fix_dialog_text - this function parses the dialog text
X *                  and replaces anything like a tilda or etc with the
X *                  appropriate environment variable or string.
X */
Xparse_and_fix_dialog_text(disp_num)
Xint disp_num;
X{
X    char temp_str[512], temp_str2[512], current_line[512], login_name[512];
X    char temp_str3[512];
X    char *tmp_ptr;
X    int index, i, c, length_name;
X    FILE *fp;
X
X    strncpy(temp_str, disp_info[disp_num].dialog_text_return, 510);
X
X    for (index=0; temp_str[index] != '\0'; index++)
X	if (temp_str[index] != ' ')
X	    break;
X
X    if ((temp_str[index] == '~') && (temp_str[index+1] == '/'))
X    {
X	strncpy(temp_str2, getenv("HOME"), 250);
X	strncat(temp_str2, (char *)&(temp_str[index+1]), 250);
X	strncpy(disp_info[disp_num].dialog_text_return, temp_str2, 510);
X	disp_info[disp_num].dialog_reply_index = strlen(temp_str2);
X	return(1);
X    }
X    else if (temp_str[index] == '~')
X    {
X	for (i=index+1; (temp_str[i] != '/') && (temp_str[i] != '\0'); i++)
X            login_name[i-index-1] = temp_str[i];
X	login_name[i-index-1] = '\0';
X        length_name = strlen(login_name);
X
X        if ((fp = fopen("/etc/passwd", "r")) == NULL)
X        {
X            printf("ERROR: Could not open /etc/passwd.\n");
X	    return(0);
X	}
X	while ((c = getc(fp)) != EOF)
X	{
X	    ungetc(c, fp);
X	    fgets(current_line, 510, fp);       /*get the line*/
X	    strncpy(temp_str2, current_line, length_name);
X	    temp_str2[length_name] = '\0';
X            if (strcmp(temp_str2, login_name) == 0)    /*this is the line*/
X	    {
X                tmp_ptr = &strpbrk(&strpbrk(&strpbrk(&strpbrk(&strpbrk(
X		                   current_line, ":")[1], 
X				   ":")[1], ":")[1], ":")[1], ":")[1];
X
X		for (i=0; tmp_ptr[i] != ':'; i++)
X		     temp_str2[i] = tmp_ptr[i];
X		temp_str2[i] = '\0';
X
X	        sprintf(temp_str3, "%s%s", temp_str2, 
X			(char *)&(temp_str[index+1+length_name]));
X                fclose(fp);
X
X	        strncpy(disp_info[disp_num].dialog_text_return, temp_str3, 510);
X	        disp_info[disp_num].dialog_reply_index = strlen(temp_str3);
X                return(1);
X	    }
X	}
X        fclose(fp);
X	printf("ERROR: user specified was not found in /etc/passwd.\n");
X	return(0);
X    }
X}
X
X
X/*
X * type_on_screens - this function types on the screens of all the people
X *                   by reading if any keys have been depressed, and if so,
X *                   it puts that character up on all the displays currently
X *                   open.  <-- Darn smart, eh?  You probably couldn't have
X *                   figured out that on your own.  ;-)
X */
Xtype_on_screens(input_disp)
Xint input_disp;
X{
X    XEvent the_event;
X    Window rr, cr;                 /* <-- These here are variables, son.*/
X    KeySym ksr;
X    unsigned int mskr;
X    int i, rxr, ryr, win_x, win_y;
X    char the_char[256];
X
X    if (disp_info[input_disp].first_point_bool)
X    {
X        XQueryPointer(disp_info[input_disp].disp, 
X			  disp_info[input_disp].win_id, &rr, &cr, &rxr, 
X			  &ryr, &win_x, &win_y,&mskr);
X	disp_info[input_disp].orig_x = win_x;
X        disp_info[input_disp].cur_pos.x = win_x;
X        disp_info[input_disp].cur_pos.y = win_y;
X        disp_info[input_disp].first_point_bool = FALSE;
X        disp_info[input_disp].prompt_width = 
X	         disp_info[input_disp].the_font_struct->max_bounds.width;
X	disp_info[input_disp].char_height = 
X	   (disp_info[input_disp].the_font_struct)->max_bounds.ascent +
X	   (disp_info[input_disp].the_font_struct)->max_bounds.descent;
X	disp_info[input_disp].type_history = NULL;
X
X	/*draw the cursor*/
X	disp_info[input_disp].cursor_on = TRUE;
X	XDrawLine(disp_info[input_disp].disp, disp_info[input_disp].win_id,
X		  disp_info[input_disp].cursor_gc, 
X		  disp_info[input_disp].cur_pos.x, 
X		  disp_info[input_disp].cur_pos.y, 
X		  disp_info[input_disp].cur_pos.x + 
X		  disp_info[input_disp].prompt_width, 
X		  disp_info[input_disp].cur_pos.y);
X    }
X
X    if (XPending(disp_info[input_disp].disp))  /*check if there is a KeyPress*/
X    {
X	XNextEvent(disp_info[input_disp].disp, &the_event);
X        if (the_event.type != KeyPress)
X	{
X            XPutBackEvent(disp_info[input_disp].disp, &the_event);
X	    return(0);
X	}
X	else    /*it IS a KeyPressedEvent*/
X	{
X            the_char[0] = 0;
X            XLookupString((XKeyEvent *) (&the_event),the_char,10, &ksr, NULL);
X            if (the_char[0] == 0)
X                return(0);                /*it was a shift or some such*/
X            if (the_char[0] == 13)        /*13 == Carriage Return*/
X            {
X	        /*erase the cursor*/
X	        disp_info[input_disp].cursor_on = FALSE;
X	        XDrawLine(disp_info[input_disp].disp, 
X		  disp_info[input_disp].win_id,
X		  disp_info[input_disp].cursor_gc, 
X		  disp_info[input_disp].cur_pos.x, 
X		  disp_info[input_disp].cur_pos.y, 
X		  disp_info[input_disp].cur_pos.x + 
END_OF_FILE
if test 37771 -ne `wc -c <'wscrawl/xac'`; then
    echo shar: \"'wscrawl/xac'\" unpacked with wrong size!
fi
# end of 'wscrawl/xac'
fi
echo shar: End of archive 2 \(of 5\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 5 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 5 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
dan
----------------------------------------------------
O'Reilly && Associates   argv at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.



More information about the Comp.sources.x mailing list