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