v08i055: wscrawl, Part03/05

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


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

#! /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 3 (of 5)."
# Contents:  wscrawl/xad
# Wrapped by argv at turnpike on Sun Jul 15 11:47:11 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'wscrawl/xad' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'wscrawl/xad'\"
else
echo shar: Extracting \"'wscrawl/xad'\" \(35313 characters\)
sed "s/^X//" >'wscrawl/xad' <<'END_OF_FILE'
X		  disp_info[input_disp].prompt_width, 
X		  disp_info[input_disp].cur_pos.y);
X
X	        push_letter_to_history(input_disp, the_char[0]);
X
X                disp_info[input_disp].cur_pos.x = disp_info[input_disp].orig_x;
X                disp_info[input_disp].cur_pos.y += 
X					     disp_info[input_disp].char_height;
X
X	        /*draw the cursor*/
X	        disp_info[input_disp].cursor_on = TRUE;
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 + 
X		  disp_info[input_disp].prompt_width, 
X		  disp_info[input_disp].cur_pos.y);
X            }
X            else if ((the_char[0] == 8) ||     /*8 == Backspace*/
X                     (the_char[0] == 127))     /*127 == Del or Rubout*/
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 + 
X		  disp_info[input_disp].prompt_width, 
X		  disp_info[input_disp].cur_pos.y);
X		backspace_letter_from_history(input_disp);
X
X	        /*draw the cursor*/
X	        disp_info[input_disp].cursor_on = TRUE;
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 + 
X		  disp_info[input_disp].prompt_width, 
X		  disp_info[input_disp].cur_pos.y);
X            }
X            else     /*it is a valid letter*/
X            {
X		push_letter_to_history(input_disp, the_char[0]);
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 + 
X		  disp_info[input_disp].prompt_width, 
X		  disp_info[input_disp].cur_pos.y);
X
X                for (i=0; i< num_of_disps; i++)
X                {
X                    if (disp_info[i].in_session_bool) /*if window is alive*/
X                    {
X	                XDrawString(disp_info[i].disp, disp_info[i].win_id,
X		            disp_info[input_disp].win_gc[i], 
X			    disp_info[input_disp].cur_pos.x, 
X			    disp_info[input_disp].cur_pos.y, the_char, 1);
X                        XFlush(disp_info[i].disp);
X                    }
X                }
X		disp_info[input_disp].cur_pos.x += 
X		             XTextWidth(disp_info[input_disp].the_font_struct, 
X		             the_char, 1);
X
X	        /*draw the cursor*/
X	        disp_info[input_disp].cursor_on = TRUE;
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 + 
X		  disp_info[input_disp].prompt_width, 
X		  disp_info[input_disp].cur_pos.y);
X            }
X	}
X    }
X}
X
X
X/*
X * push_letter_to_history - this function takes a pointer to the top of
X *              the history stack and adds the character passed in to that
X *              stack.  This is to save the characters for future backspacing.
X */
Xpush_letter_to_history(input_disp, the_char)
Xint input_disp;
Xchar the_char;
X{
X    struct char_node *temp;
X
X    temp = (struct char_node *) malloc(sizeof(struct char_node));
X    temp->the_char = the_char;
X    temp->next = disp_info[input_disp].type_history;
X
X    if (the_char == 13)   /*carriage return*/
X    {
X	temp->x = disp_info[input_disp].cur_pos.x;
X	temp->y = disp_info[input_disp].cur_pos.y;
X    }
X
X    disp_info[input_disp].type_history = temp;
X}
X
X
X/*
X * backspace_letter_from_history - this function returns the most recently 
X *                 typed character from the history stack, and sets the top of
X *                 the stack pointer appropriately.
X */
Xbackspace_letter_from_history(input_disp)
Xint input_disp;
X{
X    int dr, far, fdr, i;
X    struct char_node *char_node;
X    XCharStruct the_fnt_strct;
X
X    if (disp_info[input_disp].type_history == NULL)
X	return(0);
X    else
X    {
X        char_node = disp_info[input_disp].type_history;
X
X        if (char_node->the_char == 13)     /*it was a carriage return*/
X	{
X	    disp_info[input_disp].cur_pos.x = char_node->x;
X	    disp_info[input_disp].cur_pos.y = char_node->y;
X	}
X        else                               /*it was a normal letter*/
X	{
X            disp_info[input_disp].cur_pos.x -= XTextWidth(
X	      disp_info[input_disp].the_font_struct,&(char_node->the_char), 1);
X
X            XTextExtents(disp_info[input_disp].the_font_struct, 
X	      &(char_node->the_char), 1, &dr, &far, &fdr, &the_fnt_strct);
X
X            for (i=0; i< num_of_disps; i++)
X	    {
X	        XClearArea(disp_info[i].disp, disp_info[i].win_id, 
X		      disp_info[input_disp].cur_pos.x,
X		      disp_info[input_disp].cur_pos.y - the_fnt_strct.ascent,
X		      the_fnt_strct.lbearing + the_fnt_strct.rbearing,
X		      the_fnt_strct.ascent + the_fnt_strct.descent, False);
X	    }
X	}
X
X	/* now pop the top char node from the history stack */
X        disp_info[input_disp].type_history = 
X				      disp_info[input_disp].type_history->next;
X        free(char_node);
X    }
X}
X
X
X/*
X * draw_status_win_message - this function spits (in camel like fashion) out 
X *                      the status window message to the display indicated.
X */
Xdraw_status_win_message(disp_num)
X{
X    int i, num_disps;
X    char mesg[510], *cur_loc_ptr;
X
X    for (i=0, num_disps=0; i< num_of_disps; i++)
X	if (disp_info[i].in_session_bool)  /*only if this window is alive*/
X            num_disps++;
X
X    if (num_disps == 1)
X        sprintf(mesg, "STATUS:  1 scrawl window currently open.  -->  ");
X    else
X        sprintf(mesg, "STATUS:  %d scrawl windows currently open.  -->  ", 
X		num_disps);
X
X    cur_loc_ptr = mesg + strlen(mesg);
X
X    for (i=0; i< num_of_disps; i++)
X    {
X	if (disp_info[i].in_session_bool)  /*only if this window is alive*/
X	{
X	    strncpy(cur_loc_ptr, disp_args[i], 25);
X	    cur_loc_ptr += strlen(disp_args[i]);
X	    cur_loc_ptr[0] = ',';
X	    cur_loc_ptr[1] = ' ';          /*space delineates*/
X	    cur_loc_ptr += 2;
X	}
X    }
X    cur_loc_ptr -= 2;
X    cur_loc_ptr[0] = '\0';     /*end the string*/
X
X    XClearWindow(disp_info[disp_num].disp, disp_info[disp_num].status_win_id);
X    XDrawString(disp_info[disp_num].disp, disp_info[disp_num].status_win_id, 
X		   disp_info[disp_num].fg_menu_gc, 10, 14, mesg, strlen(mesg));
X    XFlush(disp_info[disp_num].disp);
X}
X
X
X/*
X * draw_rubber_pointer - this function draws the rubber cursor of the input
X *                 disp on the target disp at the indicated location.  The
X *                 indicated location is the upper left corner of the cursor
X *                 area, NOT the hotspot.  This simulated cursor consists of
X *                 the machine name that is drawing, and a small arrow pointing
X *                 to the lower left corner.
X */
Xdraw_rubber_pointer(input_disp, target_disp, x, y)
Xint input_disp, target_disp;
X{
X    XDrawString(disp_info[target_disp].disp, disp_info[target_disp].win_id,
X		disp_info[target_disp].fg_menu_gc,
X		x + 15, y + disp_info[input_disp].rubber_pointer.height - 15, 
X		disp_args[input_disp], strlen(disp_args[input_disp]));
X
X    XDrawLine(disp_info[target_disp].disp, disp_info[target_disp].win_id,
X	      disp_info[target_disp].fg_menu_gc,
X	      x+2, y - 2 + disp_info[input_disp].rubber_pointer.height, 
X	      x+12, y - 12 + disp_info[input_disp].rubber_pointer.height);
X    XDrawLine(disp_info[target_disp].disp, disp_info[target_disp].win_id,
X	      disp_info[target_disp].fg_menu_gc,
X	      x+3, y - 2 + disp_info[input_disp].rubber_pointer.height, 
X	      x+3, y - 9 + disp_info[input_disp].rubber_pointer.height);
X    XDrawLine(disp_info[target_disp].disp, disp_info[target_disp].win_id,
X	      disp_info[target_disp].fg_menu_gc,
X	      x+3, y - 2 + disp_info[input_disp].rubber_pointer.height, 
X	      x+9, y - 2 + disp_info[input_disp].rubber_pointer.height);
X}
X
X
X/*
X * place_and_draw_status_win - this function places the status window at the
X *                      correct location on the scrawl window, and draws
X *                      the contents.  (Also updates the contents of all
X *                      other scrawl windows, but DOES NOT change their 
X *                      locations.)
X */
Xplace_and_draw_status_win(disp_num)
Xint disp_num;
X{
X    XWindowAttributes window_attr;
X
X    if (disp_info[disp_num].in_session_bool == FALSE)
X	return(0);    /*This window is no longer active*/
X	
X    XGetWindowAttributes(disp_info[disp_num].disp, 
X			 disp_info[disp_num].win_id, &window_attr);
X    XMoveResizeWindow(disp_info[disp_num].disp, 
X			 disp_info[disp_num].status_win_id, 
X			 0, window_attr.height - 24, window_attr.width-4, 20);
X
X    draw_status_win_message(disp_num);
X}
X
X
X/*
X * draw_on_screens - this function draws the segment that is indicated
X *                   by the current mouse position and previous mouse 
X *                   position on the display passed to it as an argument.
X *                   This segment is drawn to ALL displays currently open.
X *                   If this dude is airbrushing, then of course an airbrush
X *                   pattern is sprayed all over, and if it is an eraser,
X *                   then erasing happens.  If it is a rubber pointer, rubber
X *                   pointing happens.
X */
Xdraw_on_screens(input_disp)
Xint input_disp;
X{
X    Window rr, cr;
X    unsigned int mskr;
X    int i, j, left, top, oldleft, oldtop, rxr, ryr, win_x, win_y;
X
X    if (disp_info[input_disp].scrawl_mode == SCRAWLING)
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].last_point.x = win_x;
X	    disp_info[input_disp].last_point.y = win_y;
X	    disp_info[input_disp].first_point_bool = FALSE;
X        }
X
X        XQueryPointer(disp_info[input_disp].disp, disp_info[input_disp].win_id, 
X                      &rr, &cr, &rxr, &ryr, &win_x, &win_y, &mskr);
X        for (i=0; i< num_of_disps; i++)
X        {
X	    if (disp_info[i].in_session_bool) /*only if this window is alive*/
X	    {
X                XDrawLine(disp_info[i].disp,disp_info[i].win_id,
X		          disp_info[input_disp].win_gc[i],
X	                  disp_info[input_disp].last_point.x, 
X	                  disp_info[input_disp].last_point.y, win_x, win_y);
X                XFlush(disp_info[i].disp);
X	    }
X        }
X    
X        disp_info[input_disp].last_point.x = win_x;
X        disp_info[input_disp].last_point.y = win_y;
X    }
X    else if (disp_info[input_disp].scrawl_mode == AIRBRUSHING)
X    {
X        XQueryPointer(disp_info[input_disp].disp, disp_info[input_disp].win_id, 
X                      &rr, &cr, &rxr, &ryr, &win_x, &win_y, &mskr);
X        for (i=0; i< num_of_disps; i++)
X        {
X	    if (disp_info[i].in_session_bool) /*only if this window is alive*/
X	    {
X                airbrush(input_disp, disp_info[i].disp, disp_info[i].win_id, 
X		         disp_info[input_disp].win_gc[i], win_x, win_y);
X                XFlush(disp_info[i].disp);
X	    }
X        }
X    }
X    else if (disp_info[input_disp].scrawl_mode == ERASING)
X    {
X        XQueryPointer(disp_info[input_disp].disp, disp_info[input_disp].win_id, 
X                      &rr, &cr, &rxr, &ryr, &win_x, &win_y, &mskr);
X	XMoveWindow(disp_info[input_disp].disp, 
X		    disp_info[input_disp].eraser_win_id, 
X		    win_x - disp_info[input_disp].pen_width/2, 
X		    win_y - disp_info[input_disp].pen_width/2);
X
X        for (i=0; i< num_of_disps; i++)
X        {
X	    if (disp_info[i].in_session_bool) /*only if this window is alive*/
X	    {
X                XClearArea(disp_info[i].disp, disp_info[i].win_id, 
X			  win_x - disp_info[input_disp].pen_width/2, 
X			  win_y - disp_info[input_disp].pen_width/2, 
X			  disp_info[input_disp].pen_width, 
X			  disp_info[input_disp].pen_width, False);
X                XFlush(disp_info[i].disp);
X	    }
X        }
X    }
X    else if (disp_info[input_disp].scrawl_mode == RUBBER_POINTING)
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].last_point.x = win_x;
X	    disp_info[input_disp].last_point.y = win_y;
X	    disp_info[input_disp].first_point_bool = FALSE;
X	    /*
X	     * turn off any other cursors that are on before getting the
X	     * background pixmap.  (So you we don't copy the cursors as
X	     * part of the background.)
X	     */
X            for (i=0; i< num_of_disps; i++)
X            {
X	        if (disp_info[i].in_session_bool)   /*only if window is alive*/
X	        {
X                    if (disp_info[i].rubber_pointer.is_mapped_bool == TRUE)
X		    {
X	                oldleft = disp_info[i].last_point.x;
X	                oldtop = disp_info[i].last_point.y - 
X			          disp_info[i].rubber_pointer.height;
X                        for (j=0; j< num_of_disps; j++)
X	                    if (disp_info[j].in_session_bool) 
X                            {
X		                XCopyArea(disp_info[j].disp, 
X		              disp_info[i].rubber_pointer.rubber_pointer_pix[j],
X		                  disp_info[j].win_id, disp_info[i].win_gc[j],
X		                  0, 0, disp_info[i].rubber_pointer.width, 
X		                  disp_info[i].rubber_pointer.height, oldleft,
X		                  oldtop);
X		                XFlush(disp_info[j].disp);
X			    }
X		    }
X	        }
X            }
X	    /*
X	     * now get the background pixmap.
X	     */
X	    left = win_x;
X	    top = win_y - disp_info[input_disp].rubber_pointer.height;
X            for (i=0; i< num_of_disps; i++)
X            {
X	        if (disp_info[i].in_session_bool)   /*only if window is alive*/
X	        {
X		    XCopyArea(disp_info[i].disp, 
X			  disp_info[i].win_id,
X		     disp_info[input_disp].rubber_pointer.rubber_pointer_pix[i],
X		          disp_info[input_disp].win_gc[i],
X		          left, top, disp_info[input_disp].rubber_pointer.width,
X		          disp_info[input_disp].rubber_pointer.height, 0, 0);
X	        }
X            }
X	    /*
X	     * draw (map) all of the cursors that are supposed to be mapped
X	     */
X            disp_info[input_disp].rubber_pointer.is_mapped_bool = TRUE;
X            for (i=0; i< num_of_disps; i++)
X	        if (disp_info[i].in_session_bool)   /*only if window is alive*/
X		{
X                    if (disp_info[i].rubber_pointer.is_mapped_bool == TRUE)
X		    {
X	                left = disp_info[i].last_point.x;
X	                top = disp_info[i].last_point.y - 
X			           disp_info[i].rubber_pointer.height;
X                        for (j=0; j< num_of_disps; j++)
X	                    if (disp_info[j].in_session_bool) 
X		                draw_rubber_pointer(i, j, left, top);
X		    }
X		}
X        }
X
X        XQueryPointer(disp_info[input_disp].disp, disp_info[input_disp].win_id, 
X                      &rr, &cr, &rxr, &ryr, &win_x, &win_y, &mskr);
X	if ((win_x != disp_info[input_disp].last_point.x) ||
X	    (win_y != disp_info[input_disp].last_point.y))
X        {
X	    /*
X	     * turn off any other cursors that are on before getting the
X	     * background pixmap.  (So we don't copy the cursors as
X	     * part of the background.)
X	     */
X            for (i=0; i< num_of_disps; i++)
X            {
X	        if (disp_info[i].in_session_bool)   /*only if window is alive*/
X	        {
X                    if (disp_info[i].rubber_pointer.is_mapped_bool == TRUE)
X		    {
X	                oldleft = disp_info[i].last_point.x;
X	                oldtop = disp_info[i].last_point.y - 
X			          disp_info[i].rubber_pointer.height;
X                        for (j=0; j< num_of_disps; j++)
X	                    if (disp_info[j].in_session_bool) 
X                            {
X		                XCopyArea(disp_info[j].disp, 
X		              disp_info[i].rubber_pointer.rubber_pointer_pix[j],
X		                  disp_info[j].win_id, disp_info[i].win_gc[j],
X		                  0, 0, disp_info[i].rubber_pointer.width, 
X		                  disp_info[i].rubber_pointer.height, oldleft,
X		                  oldtop);
X			    }
X		    }
X	        }
X            }
X
X	    /*
X	     * save new cursor area for the input cursor
X	     */
X	    left = win_x;
X	    top = win_y - disp_info[input_disp].rubber_pointer.height;
X            for (i=0; i< num_of_disps; i++)
X            {
X	        if (disp_info[i].in_session_bool)   /*only if window is alive*/
X	        {
X		    XCopyArea(disp_info[i].disp, 
X		     disp_info[i].win_id,
X		     disp_info[input_disp].rubber_pointer.rubber_pointer_pix[i],
X		     disp_info[input_disp].win_gc[i],
X		     left, top, disp_info[input_disp].rubber_pointer.width, 
X		     disp_info[input_disp].rubber_pointer.height, 0, 0);
X	        }
X            }
X
X            disp_info[input_disp].last_point.x = win_x;
X            disp_info[input_disp].last_point.y = win_y;
X	    /*
X	     * now draw (map) all of the cursors that are currently unmapped
X	     */
X            for (i=0; i< num_of_disps; i++)
X	        if (disp_info[i].in_session_bool)   /*only if window is alive*/
X	        {
X                    if (disp_info[i].rubber_pointer.is_mapped_bool == TRUE)
X	            {
X	                left = disp_info[i].last_point.x;
X	                top = disp_info[i].last_point.y - 
X			           disp_info[i].rubber_pointer.height;
X                        for (j=0; j< num_of_disps; j++)
X	                    if (disp_info[j].in_session_bool) 
X		                draw_rubber_pointer(i, j, left, top);
X		    }
X                }
X            for (i=0; i< num_of_disps; i++)
X	        if (disp_info[i].in_session_bool)   /*only if window is alive*/
X		    XFlush(disp_info[i].disp);
X	}
X    }
X}
X
X
X/*
X * parse_command_line - this function parses the command line and sets the
X *             various global variables for the opening display
X *             and color party coming up.  Sorry that this routine is so
X *             ugly, but just go slow, and it's not too bad.  I'd look at
X *             the "command_line_err()" routine to understand what each
X *             of the command line options mean.
X *             (ex. % wscrawl -d hpcvxbw:0 -d hpcvxca:0 -pc red -cs CapRound
X *                    -pw 45 -bs off -nd 50 -ps airbrush)
X */
Xparse_command_line(argv, argc)
Xchar *argv[];
Xint argc;
X{
X     int i, current_arg, W_SET = 0;
X
X     strncpy(PEN_COLOR, "magenta", 40);            /*defaults set here*/
X     strncpy(BACKGROUND_COLOR, "white", 40);
X     strncpy(MENU_FOREGROUND_COLOR, "black", 40);
X     strncpy(MENU_BACKGROUND_COLOR, "wheat", 40);
X     strncpy(MENU_HIGHLIGHT_COLOR, "black", 40);
X     strncpy(PEN_STYLE, "dot", 40);
X     strncpy(FONT, "vgl-40", 100);
X     strncpy(disp_args[0], "", 30);
X     TYPE_NOT_DRAW = FALSE;
X     CAP_STYLE = CapRound;
X     PEN_WIDTH = 8;
X     NUM_DOTS = 50;
X     for (i=0; i< num_of_disps; i++)
X     {
X         disp_info[i].pen_width = 8;
X     }
X
X     for (current_arg = 1; current_arg < argc; current_arg+=2)
X     {
X	 if (strcmp(argv[current_arg],"-d") == 0)
X	 {
X	     strncpy(disp_args[num_of_disps], argv[current_arg+1], 48);
X	     num_of_disps++;
X         }
X	 else if (strcmp(argv[current_arg],"-mfg") == 0)
X	 {
X	     if (current_arg != argc-1)
X	         strncpy(MENU_FOREGROUND_COLOR, argv[current_arg+1], 40);
X	     else
X		 command_line_err();     /*no color was specified*/
X	 }
X	 else if (strcmp(argv[current_arg],"-mbg") == 0)
X	 {
X	     if (current_arg != argc-1)
X	         strncpy(MENU_BACKGROUND_COLOR, argv[current_arg+1], 40);
X	     else
X		 command_line_err();     /*no color was specified*/
X	 }
X	 else if (strcmp(argv[current_arg],"-mhc") == 0)
X	 {
X	     if (current_arg != argc-1)
X	         strncpy(MENU_HIGHLIGHT_COLOR, argv[current_arg+1], 40);
X	     else
X		 command_line_err();     /*no color was specified*/
X	 }
X	 else if (strcmp(argv[current_arg],"-bg") == 0)
X	 {
X	     if (current_arg != argc-1)
X	         strncpy(BACKGROUND_COLOR, argv[current_arg+1], 40);
X	     else
X		 command_line_err();     /*no color was specified*/
X	 }
X	 else if (strcmp(argv[current_arg],"-pc") == 0)
X	 {
X	     if (current_arg != argc-1)
X	         strncpy(PEN_COLOR, argv[current_arg+1], 40);
X	     else
X		 command_line_err();     /*no color was specified*/
X	 }
X	 else if (strcmp(argv[current_arg],"-fn") == 0)
X	 {
X	     if (current_arg != argc-1)
X	         strncpy(FONT, argv[current_arg+1], 220);
X	     else
X		 command_line_err();     /*no color was specified*/
X	 }
X	 else if (strcmp(argv[current_arg],"-tm") == 0)
X	 {
X	     TYPE_NOT_DRAW = TRUE;
X 	     current_arg--;  /*type message is an argumentless option*/
X	 }
X	 else if (strcmp(argv[current_arg],"-nd") == 0)
X	 {
X	     if (current_arg != argc-1)
X	     {
X	         sscanf(argv[current_arg+1], "%d", &NUM_DOTS);
X		 if ((NUM_DOTS < 1) || (NUM_DOTS > 500))
X		     command_line_err(); /*incorrect range*/
X	     }
X	     else
X		 command_line_err();     /*no number was specified*/
X	 }
X	 else if (strcmp(argv[current_arg],"-ps") == 0)
X	 {
X	     if (current_arg != argc-1)
X	     {
X		 if ((strcmp(argv[current_arg+1],"dot") == 0) || 
X		     (strcmp(argv[current_arg+1],"airbrush")) == 0)
X		 {
X		    strncpy(PEN_STYLE, argv[current_arg+1], 40);
X		    if ((strcmp(PEN_STYLE,"airbrush") == 0) && !W_SET)
X			disp_info[0].pen_width = 40; /*default penwidth*/
X		 }
X		 else
X		     command_line_err();     /*incorrect pen style specified*/
X	     }
X	     else
X		 command_line_err();     /*no pen style was specified*/
X	 }
X	 else if (strcmp(argv[current_arg],"-pw") == 0)
X	 {
X	     if (current_arg != argc-1)
X	     {
X	         sscanf(argv[current_arg+1], "%d", &PEN_WIDTH);
X		 W_SET = TRUE;           /*the width has been set*/
X	     }
X	     else
X		 command_line_err();     /*no pen width was specified*/
X	 }
X	 else if (strcmp(argv[current_arg],"-cs") == 0)
X	 {
X	     if (current_arg != argc-1)
X	     {
X		 if (strcmp(argv[current_arg+1],"CapButt") == 0)
X		     CAP_STYLE = CapButt;
X		 else if (strcmp(argv[current_arg+1],"CapNotLast") == 0)
X		     CAP_STYLE = CapNotLast;
X		 else if (strcmp(argv[current_arg+1],"CapRound") == 0)
X		     CAP_STYLE = CapRound;
X		 else if (strcmp(argv[current_arg+1],"CapProjecting") == 0)
X		     CAP_STYLE = CapProjecting;
X		 else
X                     command_line_err();     /*bad cap style was specified*/
X	     }
X	     else
X                 command_line_err();     /*no cap style was specified*/
X	 }
X	 else
X	 {
X             command_line_err();
X	 }
X     }
X}
X
X
X/* 
X * command_line_err - this function spits out a standard error message and
X *                    exits the program.
X */
Xcommand_line_err()
X{
X    printf("\nBad command line option dude.\n");
X    printf("Try: wscrawl\n");
X    printf("  [-d displayname1 -d displayname2 . . .]\n");
X    printf("  [-bg background_color]\n");
X    printf("  [-mfg menu_foreground_color]\n");
X    printf("  [-mbg menu_background_color]\n");
X    printf("  [-mhc menu_highlight_color]\n");
X    printf("  [-pc pen_color]\n");
X    printf("  [-pw pen_width]\n");
X    printf("  [-ps pen_style]  (dot,airbrush)\n");
X    printf("  [-cs cap_style]  (CapButt,CapNotLast,CapRound,CapProjecting)\n");
X    printf("  [-nd num_dots]   (number of dots in the airbrush (1-500))\n");
X    printf("  [-tm]            (type a message, don't draw)\n");
X    printf("  [-fn font]       (name of font to use if typing a message)\n\n");
X    exit(0);
X}
X
X
X/*
X * add_a_new_display - this function opens a new display to the scrawl
X *                     session.  It calls the function that initializes 
X *                     all the windows, and it transfers the image.
X */
Xadd_a_new_display(disp_name)
Xchar *disp_name;
X{
X    int i, k, found_source, disp_num, source_disp_num, width, height;
X    XWindowAttributes new_win_attr, old_win_attr, root_win_attr;
X    int cur_depth, print_it, win_left, win_top, left, top, fully_printed;
X    char *mesg;
X    Window dummy;
X
X    set_paused_cursors();         /*this is going to take a while*/
X
X    if (XOpenDisplay(disp_name) == NULL)
X    {
X        printf("XOpenDisplay failed on the Added Display: %s\n", disp_name);
X        unset_paused_cursors();         /*done*/
X        return(0);
X    }
X
X
X    for (disp_num=0; disp_num<num_of_disps; disp_num++)
X        if (disp_info[disp_num].in_session_bool == FALSE) /*this is available*/
X	    break;
X	   
X    if (disp_num == num_of_disps)
X    {
X        num_of_disps++;            /*it goes after all the rest*/
X    }
X
X    disp_info[disp_num].in_session_bool = TRUE;    /*this is the one*/
X    strncpy(disp_args[disp_num], disp_name, 48);
X
X    if (initialize_a_single_display(disp_num, &num_people_drawing) != TRUE)
X    {
X        printf("ERROR: Could not add display %s for some reason.\n",
X	       disp_args[disp_num]);
X        disp_info[disp_num].in_session_bool = FALSE;
X        unset_paused_cursors();         /*done*/
X	return(0);
X    }
X
X    else
X    {
X        if (NOTHING_DRAWN_YET == TRUE)   /*global variable*/
X	{
X            for (k=0; k<num_of_disps; k++)
X                if (disp_info[k].in_session_bool)
X                      place_and_draw_status_win(k);
X	    unset_paused_cursors();         /*we are done*/
X	    return(1);
X	}
X
X	/*
X	 * now figure out what window we should get an image from to
X	 * put onto this new window.  Best case is one that is the same
X         * depth and fully visible, next best case is the most depth, etc...
X         */
X        XGetWindowAttributes(disp_info[disp_num].disp, 
X		           disp_info[disp_num].win_id, &new_win_attr);
X
X        /*
X         * get the same depth image fully on screen, if at all possible
X         */
X        for (i=0,found_source=FALSE;(i<num_of_disps)&&(found_source==FALSE);i++)
X        {
X            if ((disp_info[i].in_session_bool==TRUE) && (i!=disp_num))
X            {  
X                XGetWindowAttributes(disp_info[i].disp, disp_info[i].win_id,
X			         &old_win_attr);
X	        if (old_win_attr.depth == new_win_attr.depth)
X	        {
X	            XTranslateCoordinates(disp_info[i].disp, 
X			    disp_info[i].win_id, RootWindow(disp_info[i].disp,
X			    DefaultScreen(disp_info[i].disp)),
X			    0, 0, &left, &top, &dummy);
X                    XGetWindowAttributes(disp_info[i].disp, 
X			    RootWindow(disp_info[i].disp, 
X			    DefaultScreen(disp_info[i].disp)), 
X			    &root_win_attr);
X                    if (((left + old_win_attr.width) < root_win_attr.width) &&
X                        ((top + old_win_attr.height) < root_win_attr.height)) 
X		    {
X		        source_disp_num = i;   /*we found the ideal case*/
X		        found_source = TRUE;   /*same depth, fully on monitor*/
X		        break;
X		    }
X	        }
X	    }
X	}
X
X        if (found_source == FALSE)
X	{
X            /*
X             * get the same depth image if at all possible, not fully on screen
X             */
X            for (i=0; (i<num_of_disps) && (found_source==FALSE); i++)
X            {
X                if ((disp_info[i].in_session_bool==TRUE) && (i!=disp_num))
X                {  
X                    XGetWindowAttributes(disp_info[i].disp, disp_info[i].win_id,
X			             &old_win_attr);
X	            if (old_win_attr.depth == new_win_attr.depth)
X	            {
X		        source_disp_num = i;   /*we found an OK case*/
X		        found_source = TRUE;   /*same depth, part on monitor*/
X		        break;
X	            }
X	        }
X	    }
X        }
X
X        if (found_source == FALSE)
X	{
X	    /*
X	     * we didn't find a display of equal depth, so look for the one of
X	     * the greatest depth in the session.  It is the best one to use.
X	     */
X            for (i=0, cur_depth=0; (i<num_of_disps)&&(found_source==FALSE); i++)
X            {
X                if ((disp_info[i].in_session_bool==TRUE) && (i!=disp_num))
X                {  
X                    XGetWindowAttributes(disp_info[i].disp, disp_info[i].win_id,
X			     &old_win_attr);
X	            if (old_win_attr.depth > cur_depth)
X		    {
X                        source_disp_num = i;
X			cur_depth = old_win_attr.depth;
X		    }
X	        }
X	    }
X        }
X
X	/*
X	 * now that we have our favorite choice, make sure we don't get any
X	 * image from a part of a window that is offscreen.  This is 
X	 * not allowed and causes core dump.
X	 */
X	XTranslateCoordinates(disp_info[source_disp_num].disp, 
X			    disp_info[source_disp_num].win_id, 
X			    RootWindow(disp_info[source_disp_num].disp,
X			    DefaultScreen(disp_info[source_disp_num].disp)),
X			    0, 0, &left, &top, &dummy);
X        XGetWindowAttributes(disp_info[source_disp_num].disp, 
X			    RootWindow(disp_info[source_disp_num].disp, 
X			    DefaultScreen(disp_info[source_disp_num].disp)), 
X			    &root_win_attr);
X
X        fully_printed = TRUE;
X        print_it = TRUE;
X
X        if (left < 0)
X	{
X	    printf("ERROR: Get the dang window from out from under the ");
X	    printf("left edge of the monitor.\n");
X	    print_it = FALSE;
X        }
X	else
X	    win_left = 0;
X
X        if (top < 0)
X	{
X	    printf("ERROR: Get the dang window from out from under the ");
X	    printf("top edge of the monitor.\n");
X	    print_it = FALSE;
X        }
X	else
X	    win_top = 0;
X
X        if ((left + old_win_attr.width) < root_win_attr.width)
X	    width = old_win_attr.width;          /*we are inside the boundary*/
X	else                                  
X	{
X	    width = root_win_attr.width - left;  /*we are outside the boundary*/
X            fully_printed = FALSE;
X	}
X
X        if ((top + old_win_attr.height) < root_win_attr.height)
X	    height = old_win_attr.height;        /*we are inside the boundary*/
X	else                                  
X	{
X	    height = root_win_attr.height - top; /*we are outside the boundary*/
X            fully_printed = FALSE;
X	}
X
X        if (print_it == TRUE)
X	{
X            transfer_image_between_displays(source_disp_num, disp_num,win_left,
X					win_top, width, height);
X	}
X	else
X	{
X	    printf("WARNING: image not displayed on display %s.\n",
X		       disp_args[disp_num]);
X
X	    left = 0;
X	    top = 0;
X            width = old_win_attr.width;
X            height = old_win_attr.height;
X
X	    mesg = "You are missing an image here.";
X	    XDrawString(disp_info[disp_num].disp, disp_info[disp_num].win_id,
X		            disp_info[disp_num].fg_menu_gc, 
X			    (left + (width/2) - 88), (top + (height/2) + 5),
X			     mesg, strlen(mesg));
X	}
X
X        if (fully_printed == FALSE)
X	{  
X            printf("WARNING: image not fully displayed on display %s.\n",
X	                disp_args[disp_num]);
X	}
X
X        for (k=0; k<num_of_disps; k++)
X            if (disp_info[k].in_session_bool)
X                  place_and_draw_status_win(k);
X        unset_paused_cursors();         /*we are done*/
X    }
X}
X
X
X/*
X * transfer_image_between_displays - this function tranfers an image from
X *                      one display to another as specified by the upper 
X *                      left corner x, y and the width and height parameters.
X *                      Currently this is done using the "save to disk" and
X *                      "restore from disk" functions as an easy shortcut. 
X */
Xtransfer_image_between_displays(source_disp_num, dest_disp_num, x, y, width, 
X				height)
Xint source_disp_num, dest_disp_num, x, y, width, height;
X{
X    XImage *the_full_screen_image;
X    char *mesg, temp_file_name[256];
X    int depth;
X
X    sprintf(temp_file_name, "/tmp/wscr.%d", getpid());
X
X    save_image_on_disk(disp_info[source_disp_num].disp, 
X		       disp_info[source_disp_num].win_id, x, y, width, height, 
X		       temp_file_name);
X
X    if ((the_full_screen_image = read_image_from_disk(
X				     disp_info[dest_disp_num].disp, 
X				     disp_info[dest_disp_num].win_id, 
X				     temp_file_name, &width,
X			             &height, &depth)) == NULL)
X    {  
X        printf("WARNING: image not displayed on display %s.\n",
X	                disp_args[dest_disp_num]);
X        XClearArea(disp_info[dest_disp_num].disp, 
X	           disp_info[dest_disp_num].win_id, 
X	           0, 0, width, height, False);
X
X        XSetLineAttributes(disp_info[dest_disp_num].disp, 
X                               disp_info[dest_disp_num].rubber_band_gc, 3, 
X			       LineSolid, CapButt, JoinBevel);
X	if ((width > 4) && (height > 4))
X	{
X            XDrawRectangle(disp_info[dest_disp_num].disp, 
X	                   disp_info[dest_disp_num].win_id,
X                           disp_info[dest_disp_num].rubber_band_gc,
X                           2, 2, width - 4, height - 4);
X	}
X	XSetLineAttributes(disp_info[dest_disp_num].disp, 
X                               disp_info[dest_disp_num].rubber_band_gc, 0, 
X			       LineSolid, CapButt, JoinBevel);
X
X	mesg = "You are missing an image here.";
X	XDrawString(disp_info[dest_disp_num].disp, 
X		    disp_info[dest_disp_num].win_id,
X                    disp_info[dest_disp_num].fg_menu_gc, (width/2) - 88, 
X		    (height/2) + 5, mesg, strlen(mesg));
X    } 
X    else if (DefaultDepth(disp_info[dest_disp_num].disp, 
X		     DefaultScreen(disp_info[dest_disp_num].disp)) != depth)
X    {
X        printf("WARNING: image not displayed on display %s. ",
X		               disp_args[dest_disp_num]);
X        printf("(Inconsistent depths.)\n");
X        XDestroyImage(the_full_screen_image);
X    }
X    else
X    {
X        XPutImage(disp_info[dest_disp_num].disp, 
X	   	  disp_info[dest_disp_num].win_id,
X	          disp_info[dest_disp_num].win_gc[dest_disp_num], 
X		  the_full_screen_image, 
X	          0, 0, x, y, width, height);
X        XFlush(disp_info[dest_disp_num].disp);
X        XDestroyImage(the_full_screen_image);
X    }
X}
X
X
X/*
X * initialize_a_single_display - this function creates all the win_ids, gcs,
X *                      etc, for a new display assuming that the the "disp_num"
X *                      passed in is the location in the global disp_info 
X *                      structure of the display, and that all the other 
X *                      displays are set up VERY well (i.e. the 
X *                      "in_session_bool" field is accurate.  This function
X *                      also allocates gc's to draw on THIS NEW DISPLAY from
X *                      the previous existing displays.
X */
Xinitialize_a_single_display(disp_num, num_people_drawing)
Xint disp_num, *num_people_drawing;
X{
X    unsigned long nothing_mask = 0;
X    unsigned long alter_these_mask = GCSubwindowMode | GCLineWidth | 
X				     GCForeground | GCCapStyle | GCFont |
X				     GCBackground | GCGraphicsExposures;
X    unsigned long alter_menu_mask =  GCSubwindowMode | GCForeground | GCFont |
X				     GCBackground | GCLineWidth;
X    unsigned long alter_these2_mask = CWEventMask | CWBackPixel | 
X				   CWBackingStore | CWWinGravity |
X				   CWBitGravity | CWSaveUnder;
X    unsigned long alter_menu2_mask = CWEventMask | CWBackPixel | CWSaveUnder |
X				     CWBackingStore | CWWinGravity;
X    unsigned long gc_copy_mask = GCSubwindowMode | GCLineWidth | 
X				     GCForeground | GCCapStyle | GCFont |
X				     GCBackground | GCGraphicsExposures;
X    XSizeHints win_size_hints;
X    Cursor the_cursor, menu_cursor;
X    XColor scrn_def_ret, exact_def_ret, scrn_def_ret2, exact_def_ret2;
END_OF_FILE
if test 35313 -ne `wc -c <'wscrawl/xad'`; then
    echo shar: \"'wscrawl/xad'\" unpacked with wrong size!
fi
# end of 'wscrawl/xad'
fi
echo shar: End of archive 3 \(of 5\).
cp /dev/null ark3isdone
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