[comp.sources.sun] v01i047: Touchup 2.5 - a Sunview bitmap graphics editor, Part 05/07

mcgrew@dartagnan.rutgers.edu (Charles Mcgrew) (07/13/89)

Submitted-by: rayk@sbcs.sunysb.edu
Posting-number: Volume 1, Issue 47
Archive-name: touchup2.5/part05

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 5 (of 7)."
# Contents:  brush.c circle.c cms_rainbow.c color_palet.c command.c
#   confirmer.c cursor.c disk_io.c drawing.c
# Wrapped by rayk@sboslab3 on Tue Aug 30 00:07:31 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f brush.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"brush.c\"
else
echo shar: Extracting \"brush.c\" \(2174 characters\)
sed "s/^X//" >brush.c <<'END_OF_brush.c'
X
X/**************************************************************************
X   Touchup a bitmap graphics editor for the Sun Workstation running SunView
X   Copyright (c) 1988 by Raymond Kreisel
X   1/22/88 @ Suny Stony Brook
X
X   This program may be redistributed without fee as long as this copyright
X   notice is intact.
X
X==> PLEASE send comments and bug reports to one of the following addresses:
X
X	   Ray Kreisel
X	   CS Dept., SUNY at Stony Brook, Stony Brook NY 11794
X
X	   UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk   
X	   ARPA-Internet: rayk@sbcs.sunysb.edu			
X	   CSnet: rayk@suny-sb
X	   (If nobody is home at any of the above addresses try:
X		S72QKRE@TOWSONVX.BITNET			        )
X
X "If I get home before daylight, I just might get some sleep tonight...."
X
X**************************************************************************/
X
X#include <pixrect/pixrect_hs.h>
X
X/**************************************************************************
X	file: brush.c
X	purpose: This file contains all that differents brush styles.
X		Brushes can be created with iconedit, using the upper
X		righthand 32x32 bits.  The 64x64 image from iconedit
X		is then stripped to 32x32 by strip_icon32x32
X
X	modifications:
X		date:	Tue Mar 22 22:04:58 EST 1988
X		author:	rayk
X		changes:add comments
X**************************************************************************/
X
Xstatic short brush1_data[] = {
X#include "brush1.icon.pat"
X};
Xstatic mpr_static(brush1_pr, 32, 32, 1, brush1_data);
X
Xstatic short brush2_data[] = {
X#include "brush2.icon.pat"
X};
Xstatic mpr_static(brush2_pr, 32, 32, 1, brush2_data);
X
Xstatic short brush3_data[] = {
X#include "brush3.icon.pat"
X};
Xstatic mpr_static(brush3_pr, 32, 32, 1, brush3_data);
X
Xstatic short brush4_data[] = {
X#include "brush4.icon.pat"
X};
Xstatic mpr_static(brush4_pr, 32, 32, 1, brush4_data);
X
Xstatic short brush5_data[] = {
X#include "brush5.icon.pat"
X};
Xstatic mpr_static(brush5_pr, 32, 32, 1, brush5_data);
X
Xstatic short brush6_data[] = {
X#include "brush6.icon.pat"
X};
Xstatic mpr_static(brush6_pr, 32, 32, 1, brush6_data);
X
Xstatic short brush7_data[] = {
X#include "brush7.icon.pat"
X};
Xstatic mpr_static(brush7_pr, 32, 32, 1, brush7_data);
END_OF_brush.c
if test 2174 -ne `wc -c <brush.c`; then
    echo shar: \"brush.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f circle.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"circle.c\"
else
echo shar: Extracting \"circle.c\" \(3724 characters\)
sed "s/^X//" >circle.c <<'END_OF_circle.c'
X
X/**************************************************************************
X   Touchup a bitmap graphics editor for the Sun Workstation running SunView
X   Copyright (c) 1988 by Raymond Kreisel
X   1/22/88 @ Suny Stony Brook
X
X   This program may be redistributed without fee as long as this copyright
X   notice is intact.
X
X==> PLEASE send comments and bug reports to one of the following addresses:
X
X	   Ray Kreisel
X	   CS Dept., SUNY at Stony Brook, Stony Brook NY 11794
X
X	   UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk   
X	   ARPA-Internet: rayk@sbcs.sunysb.edu			
X	   CSnet: rayk@suny-sb
X	   (If nobody is home at any of the above addresses try:
X		S72QKRE@TOWSONVX.BITNET			        )
X
X "If I get home before daylight, I just might get some sleep tonight...."
X
X**************************************************************************/
X
X/**************************************************************************
X	file: circle.c
X	purpose: This file contains that routines that draw circles
X		on the screen. A Sunview 3.4 function "pw_polypoint"
X		is used to get the list of points that make the circle
X		on to the screen AMAZINGLY FAST.
X		The points that make up the circle are calculated with
X		bresenhams (sp?) incremental circle algorithm.
X
X	modifications:
X		date:	Tue Mar 22 22:04:58 EST 1988
X		author:	rayk
X		changes:add comments
X
X		date:	Fri Apr 22 17:11:02 EDT 1988
X		author:	rayk
X		changes:added pw_batching and bitops
X**************************************************************************/
X
X#include "header.h"
X
Xstruct  pr_pos  ptlist[MAX_PTS];
X
Xdraw_circle(center_x,center_y, radius,ROP)
Xint		center_x,center_y;
Xint                radius,ROP;
X{
Xstruct pr_pos      center;
X
X        int             x,y,
X                        error, numpts;
X
X	if (radius==0) return;
X	center.x = center_x;
X	center.y = center_y;
X
X           x = 0; y = radius; numpts = 0;
X           error = 3 - (radius << 1);
X
X           while (x < y)
X           {
X             ptlist[numpts].x=center.x+x;   ptlist[numpts++].y=center.y+y;
X             ptlist[numpts].x=center.x-x;   ptlist[numpts++].y=center.y+y;
X             ptlist[numpts].x=center.x+x;   ptlist[numpts++].y=center.y-y;
X             ptlist[numpts].x=center.x-x;   ptlist[numpts++].y=center.y-y;
X             ptlist[numpts].x=center.x+y;   ptlist[numpts++].y=center.y+x;
X             ptlist[numpts].x=center.x-y;   ptlist[numpts++].y=center.y+x;
X             ptlist[numpts].x=center.x+y;   ptlist[numpts++].y=center.y-x;
X             ptlist[numpts].x=center.x-y;   ptlist[numpts++].y=center.y-x;
X   
X             if (error < 0)
X                error = error + (x << 2) + 6;
X             else
X                error = error + ((x-y--) << 2) + 10;
X             x++;
X	     if (numpts > MAX_PTS-8)
X 	     {
X		ERROR("Circle is too larege !");
X		return;
X	     }
X           }  /* end of while (x , y) */
X   
X           if (x == y)
X           {
X             ptlist[numpts].x=center.x+x;   ptlist[numpts++].y=center.y+y;
X             ptlist[numpts].x=center.x-x;   ptlist[numpts++].y=center.y+y;
X             ptlist[numpts].x=center.x+x;   ptlist[numpts++].y=center.y-y;
X             ptlist[numpts].x=center.x-x;   ptlist[numpts++].y=center.y-y;
X           }
X
X	   my_pw_polypoint(0,0,numpts,ptlist,ROP);
X}  /* end of function draw_circle() */   
X
X
X
Xmy_pw_polypoint(off_x,off_y,count_pts,ptlist, ROP)
Xint off_x,off_y,count_pts;
Xstruct pr_pos ptlist[];
Xint ROP;
X{
X
X  if (((ROP == (PIX_SRC)) || (ROP == (PIX_SRC | PIX_DST)))
X      && (image_depth == 1))
X	 ROP = PIX_SET;
X
X    pw_batch_on(pw);
X    while(--count_pts > 0)
X    {
X      pw_rop(pw,off_x+ptlist[count_pts].x,off_y+ptlist[count_pts].y,1,1
X  	,PIX_COLOR(cur_color) | ROP ,pattern[0],0,0);
X    }
X    pw_batch_off(pw);
X}
END_OF_circle.c
if test 3724 -ne `wc -c <circle.c`; then
    echo shar: \"circle.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f cms_rainbow.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"cms_rainbow.c\"
else
echo shar: Extracting \"cms_rainbow.c\" \(3722 characters\)
sed "s/^X//" >cms_rainbow.c <<'END_OF_cms_rainbow.c'
X
X/**************************************************************************
X   Touchup a bitmap graphics editor for the Sun Workstation running SunView
X   Copyright (c) 1988 by Raymond Kreisel
X   1/22/88 @ Suny Stony Brook
X
X   This program may be redistributed without fee as long as this copyright
X   notice is intact.
X
X==> PLEASE send comments and bug reports to one of the following addresses:
X
X	   Ray Kreisel
X	   CS Dept., SUNY at Stony Brook, Stony Brook NY 11794
X
X	   UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk   
X	   ARPA-Internet: rayk@sbcs.sunysb.edu			
X	   CSnet: rayk@suny-sb
X	   (If nobody is home at any of the above addresses try:
X		S72QKRE@TOWSONVX.BITNET			        )
X
X "If I get home before daylight, I just might get some sleep tonight...."
X
X**************************************************************************/
X/**************************************************************************
X	file:  cms_rainbow.c
X	purpose: this file contains that funciton that initalizes the
X		the default color table for color sun usage
X
X	modifications:
X		date:	Tue Mar 22 22:04:58 EST 1988
X		author:	rayk
X		changes:add comments
X
X		date:	Sat Jun  4 13:22:45 EST 1988
X		author:	rayk
X		changes:fixed color pallet so that it was continious
X**************************************************************************/
X
Xextern unsigned char red[256],green[256],blue[256];
X
Xset_colorentry(i, r, g, b)
X{
X  red[i] =r;
X  green[i] =g;
X  blue[i]=b;
X}
X
X
X
X/*
X * set a rainbow color map with most all of the colors
X */
Xinit_colortable()
X{
X    int i, red, green, blue;
X    set_colorentry(0, 255, 255, 255);	/* white */
X    set_colorentry(1, 0, 0, 0);		/* black */
X    red = blue = green = 0;
X
X    for (i = 2; i < 30; i++) {
X        red += 9;
X        set_colorentry(i, red, green, blue);
X    }
X    set_colorentry(30, 255, 0, 0);      /* red */
X    red = 255; blue = green = 0;
X    for (i = 30; i < 62; i++) {
X        green += 6;
X        set_colorentry(i, red, green, blue);
X    }
X    set_colorentry(62, 255, 188, 0);    /* orange */ /* note diff = 33 */
X    red = 255; blue = 0; green = 188;
X    for (i = 63; i < 96; i++) {
X        green += 2;
X        set_colorentry(i, red, green, blue);
X    }
X    set_colorentry(96, 255, 255, 0);    /* yellow */
X    red = 255; blue = 0; green = 255;
X    for (i = 97; i < 128; i++) {
X        red -= 7;
X        set_colorentry(i, red, green, blue);
X    }
X    green = blue = 255; red=0; 
X    for (i = 128; i < 136; i++) {
X        blue -= 12;
X        set_colorentry(i, red, green, blue);
X    }
X    red = blue = 16; green = 239;
X    for (i = 136; i < 163; i++) {
X        green -= 8;
X        blue += 8;
X        set_colorentry(i, red, green, blue);
X    }
X    red = green = 50; blue = 255;
X    for (i = 163; i < 176; i++) {
X       green += 10;
X       red += 10;
X        set_colorentry(i, red, green, blue);
X    }
X    red = 70; green = 0; blue = 255;
X    for (i = 176; i < 200; i++) {
X        red += 7;
X        set_colorentry(i, red, green, blue);
X    }
X
X    red = blue = 255; green = 80;
X    for (i = 200; i < 208; i++) {
X        blue -= 13;
X        set_colorentry(i, red, green, blue);
X    }
X
X    red = blue = 112; green = 64;
X    for (i = 208; i < 218; i++) {
X        blue += 13;
X        red += 13;
X        set_colorentry(i, red, green, blue);
X    }
X    red = blue = 255; green = 105;
X    for (i = 218; i < 239; i++) {
X        green += 7;
X        set_colorentry(i, red, green, blue);
X    }
X    set_colorentry(239, 255, 255, 255); /* white */
X    red = blue = green = 255;
X    for (i = 239; i <= 255; i++) {
X        green -= 9;
X        red -= 9;
X        blue -= 9;
X        set_colorentry(i, red, green, blue);
X    }
X    set_colorentry(254, 255, 255, 255);	/* white for passive foreground */
X}
END_OF_cms_rainbow.c
if test 3722 -ne `wc -c <cms_rainbow.c`; then
    echo shar: \"cms_rainbow.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f color_palet.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"color_palet.c\"
else
echo shar: Extracting \"color_palet.c\" \(8977 characters\)
sed "s/^X//" >color_palet.c <<'END_OF_color_palet.c'
X
X/**************************************************************************
X   Touchup a bitmap graphics editor for the Sun Workstation running SunView
X   Copyright (c) 1988 by Raymond Kreisel
X   1/22/88 @ Suny Stony Brook
X
X   This program may be redistributed without fee as long as this copyright
X   notice is intact.
X
X==> PLEASE send comments and bug reports to one of the following addresses:
X
X	   Ray Kreisel
X	   CS Dept., SUNY at Stony Brook, Stony Brook NY 11794
X
X	   UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk   
X	   ARPA-Internet: rayk@sbcs.sunysb.edu			
X	   CSnet: rayk@suny-sb
X	   (If nobody is home at any of the above addresses try:
X		S72QKRE@TOWSONVX.BITNET			        )
X
X "If I get home before daylight, I just might get some sleep tonight...."
X
X**************************************************************************/
X/**************************************************************************
X	file:color_palet.c
X	purpose: This file contains that functions that handle the color
X		map for usage with color suns
X
X	modifications:
X		date:	Tue Mar 22 22:04:58 EST 1988
X		author:	rayk
X		changes:add comments
X
X		date:	Thu Jun 16 21:02:52 EDT 1988
X		author:	tnosoes!tom@mcvax.cwi.nl
X		changes:corrected problems with FRAME_INHERIT_COLOR
X			and the problem of the color table flashing
X			on and off when you move the mouse between
X			window.
X
X		date:	Sat Jun 25 00:04:28 EDT 1988
X		author:	rayk
X		changes:took out the code in my_put_colormap that would
X			reset color 1 & 254
X
X		date:	Sat Jun 25 00:04:28 EDT 1988
X		author:	tnosoes!tom@uunet.UU.NET
X		changes:added at colormap editor, so that the RGB values
X			of colormap enties can dynamiclly be changed
X
X**************************************************************************/
X
X#include "header.h"
X#include <sunwindow/cms_mono.h>
X
X/*
X * Lets go into color mode, Scotty
X *
X */
Xset_color()
X{
X  panel_set(mono_cycle,PANEL_SHOW_ITEM, FALSE,0);
X  panel_set(color_button,PANEL_SHOW_ITEM, TRUE,0);
X}
X
X
X/*
X * Back to mono mode
X *
X */
Xset_mono()
X{
X  /*
X   * set the color map to mono
X   */
X  if (((pw->pw_pixrect->pr_depth) > 1) && (!BW_mode))
X   {
X     cms_monochromeload(red,green,blue);
X     my_put_colormap();
X   }
X  panel_set(color_button,PANEL_SHOW_ITEM, FALSE,0);
X  panel_set(mono_cycle,PANEL_SHOW_ITEM, TRUE,0);
X}
X
X
X/*
X * Set the colormap for all of the windows
X */
Xunsigned char temp_red[256],temp_green[256],temp_blue[256];
Xextern struct singlecolor fore_ground,back_ground;
Xextern int fore_back_flag;
Xmy_put_colormap()
X{
XPixwin *temp_pw;
X
X  pw_setcmsname(pw, "ray kreisel");
X  pw_putcolormap(pw, 0,256,red,green,blue);
X  pw_setcmsname(fat_pw, "ray kreisel");
X  pw_putcolormap(fat_pw, 0,256,red,green,blue);
X  pw_setcmsname(color_pw, "ray kreisel");
X  pw_putcolormap(color_pw, 0,256,red,green,blue);
X
X  bcopy(red,temp_red,256);
X  bcopy(green,temp_green,256);
X  bcopy(blue,temp_blue,256);
X
X  if (fore_back_flag)
X  {
X    temp_red[0] = fore_ground.red;
X    temp_green[0] = fore_ground.green;
X    temp_blue[0] = fore_ground.blue;
X  
X    temp_red[255] = back_ground.red;
X    temp_green[255] = back_ground.green;
X    temp_blue[255] = back_ground.blue;
X  }  
X
X  temp_pw = (Pixwin *)window_get(base_frame, WIN_PIXWIN);
X  pw_setcmsname(temp_pw, "ray kreisel");
X  pw_putcolormap(temp_pw, 0,256,temp_red,temp_green,temp_blue);
X
X  temp_pw = (Pixwin *)window_get(panel, WIN_PIXWIN);
X  pw_setcmsname(temp_pw, "ray kreisel");
X  pw_putcolormap(temp_pw, 0,256,temp_red,temp_green,temp_blue);
X
X  temp_pw = (Pixwin *)window_get(command_panel, WIN_PIXWIN);
X  pw_setcmsname(temp_pw, "ray kreisel");
X  pw_putcolormap(temp_pw, 0,256,temp_red,temp_green,temp_blue);
X
X  temp_pw = (Pixwin *)window_get(region_panel, WIN_PIXWIN);
X  pw_setcmsname(temp_pw, "ray kreisel");
X  pw_putcolormap(temp_pw, 0,256,temp_red,temp_green,temp_blue);
X
X  temp_pw = (Pixwin *)window_get(pattern_panel, WIN_PIXWIN);
X  pw_setcmsname(temp_pw, "ray kreisel");
X  pw_putcolormap(temp_pw, 0,256,temp_red,temp_green,temp_blue);
X
X  temp_pw = (Pixwin *)window_get(brush_panel, WIN_PIXWIN);
X  pw_setcmsname(temp_pw, "ray kreisel");
X  pw_putcolormap(temp_pw, 0,256,temp_red,temp_green,temp_blue);
X
X  temp_pw = (Pixwin *)window_get(text_panel, WIN_PIXWIN);
X  pw_setcmsname(temp_pw, "ray kreisel");
X  pw_putcolormap(temp_pw, 0,256,temp_red,temp_green,temp_blue);
X
X  temp_pw = (Pixwin *)window_get(color_frame, WIN_PIXWIN);
X  pw_setcmsname(temp_pw, "ray kreisel");
X  pw_putcolormap(temp_pw, 0,256,temp_red,temp_green,temp_blue);
X
X  temp_pw = (Pixwin *)window_get(color_panel, WIN_PIXWIN);
X  pw_setcmsname(temp_pw, "ray kreisel");
X  pw_putcolormap(temp_pw, 0,256,temp_red,temp_green,temp_blue);
X
X  temp_pw = (Pixwin *)window_get(fat_frame, WIN_PIXWIN);
X  pw_setcmsname(temp_pw, "ray kreisel");
X  pw_putcolormap(temp_pw, 0,256,temp_red,temp_green,temp_blue);
X
X  temp_pw = (Pixwin *)window_get(fat_panel, WIN_PIXWIN);
X  pw_setcmsname(temp_pw, "ray kreisel");
X  pw_putcolormap(temp_pw, 0,256,temp_red,temp_green,temp_blue);
X}
X
X
Xcolor_mode()
X{
X    (void)window_set(color_frame, WIN_SHOW, TRUE, 0);
X    draw_colormap();
X}
X
X
X/*
X * Draw the colormap up on a canvas in the color palet window
X */
Xdraw_colormap()
X{
Xint i;
X  for (i=0;i<256;i++)
X    pw_write(color_pw,(i%16)*PALET_BLOCK,i/16*PALET_BLOCK,PALET_BLOCK,PALET_BLOCK,PIX_COLOR(i) | PIX_SRC,NILPR,0,0);
X  update_cur_color(0,0,cur_color);
X}
X
X
X
X/*
X * Get rid of the color palet
X */
Xcolor_done()
X{
X    (void)window_set(color_frame, WIN_SHOW, FALSE, 0);
X}
X
X
X/*
X * Make an event handle for the mouse envent of the color palet
X * Let the use pick a block on the color palet and set the current
X * color a cordingly
X */
Xcolor_handle_event(canvas_local, event)
XCanvas  canvas_local;
XEvent   *event;
X{
X    if (event_id(event) == MS_LEFT)
X	update_cur_color(event_x(event),event_y(event),0);
X}
X
X
X/*
X * Redraw the currrent color at the bottom of the color palet
X */
Xupdate_cur_color(x,y,value)
X{
X  if (value)
X   {
X    cur_color= value;
X   }
X  else
X   {
X     if ((x >= PALET_BLOCK*16) || (y >= PALET_BLOCK*16))
X	   return;
X     cur_color = x/PALET_BLOCK + y/PALET_BLOCK*16;
X   }
X  pw_write(color_pw,0,PALET_BLOCK*16+8,PALET_BLOCK*16,PALET_BLOCK*2,PIX_COLOR(cur_color) | PIX_SRC,NILPR,0,0);
X  col_choose();
X}
X
X
X
X/*
X * Color editing for editing RGB value of single colormap entries
X * written by: tnosoes!tom@uunet.UU.NET
X */
X
X#define	CMS_SIZE	256
X
Xint			changed_0, changed_255;
X
XPanel_item	red_slide, green_slide, blue_slide;
XPanel_item	col_file;
XPanel_item	cur_col_msg;
X
Xextern int		errno, sys_nerr;
Xextern char		*sys_errlist[];
X
X
X/*
X * update the panel message with the number of current color
X * and the proper R, G, B values for that color table entry
X */
Xcol_choose()
X{
X  char	s[5];
X
X  sprintf(s, "%d", cur_color);
X  panel_set(cur_col_msg, PANEL_LABEL_STRING, s, 0);
X  panel_set(red_slide, PANEL_VALUE, red[cur_color], 0);
X  panel_set(green_slide, PANEL_VALUE, green[cur_color], 0);
X  panel_set(blue_slide, PANEL_VALUE, blue[cur_color], 0);
X}
X
X
X/*
X * get the user's new R, G, B values from the sliders
X */
Xcol_change(item, value)
XPanel_item	item;
Xint		value;
X{
X  switch ((int) panel_get(item, PANEL_CLIENT_DATA)) {
X	case 0:
X		red[cur_color]= value;
X		break;
X	case 1:
X		green[cur_color]= value;
X		break;
X	case 2:
X		blue[cur_color]= value;
X		break;
X  }
X  my_put_colormap();
X
X  if (cur_color == 0)
X	changed_0= 1;
X  if (cur_color == 255)
X	changed_255= 1;
X}
X
X
X/*
X * Let's do file completion on what we have in the color file name prompt
X */
Xmake_new_col_name()
X{
X  char	file_name[MAX_FILE_NAME];
X
X  strcpy(file_name,(char*)panel_get_value(col_file));
X  if (complete(file_name))
X    window_bell(panel);
X  panel_set(col_file,PANEL_VALUE,file_name,0);
X}
X
X
X/*
X * get a colormap from a disk file, the filename is in the filename
X * text string from the colormap control panel
X */
Xcol_load()
X{
X  char	*name;
X  FILE	*f;
X  char	fname[MAX_FILE_NAME];
X
X  if (*(name= panel_get(col_file, PANEL_VALUE)) == '\0') {
X	ERROR("You should enter a filename first");
X	return;
X  }
X  get_full_path(name, fname);
X  if (file_is_dir(fname)) {
X	ERROR("That file is a directory");
X	return;
X  }
X  if ((f= fopen(fname, "r")) == NULL) {
X	if (errno >= sys_nerr)
X		ERROR("Cannot open that file");
X	else
X		ERROR(sys_errlist[errno]);
X	return;
X  }
X  if (!fread(red, CMS_SIZE, 1, f)
X	|| !fread(green, CMS_SIZE, 1, f)
X	|| !fread(blue, CMS_SIZE, 1, f))
X		ERROR("Load failed !");
X  fclose(f);
X  my_put_colormap();
X}
X
X
X/*
X * Save a colormap out to a disk file
X */
Xcol_save()
X{
X  char	*name;
X  FILE	*f;
X  char	fname[MAX_FILE_NAME];
X
X  if (*(name= panel_get(col_file, PANEL_VALUE)) == '\0') {
X	ERROR("You should enter a filename first");
X	return;
X  }
X  get_full_path(name, fname);
X  if (file_exist(fname)) {
X     if (!confirm("Overwrite existing file ?"))
X	 return;
X  }
X  if ((f= fopen(fname, "w")) == NULL) {
X	if (errno >= sys_nerr)
X		ERROR("Cannot open that file");
X	else
X		ERROR(sys_errlist[errno]);
X	return;
X  }
X  if (!fwrite(red, CMS_SIZE, 1, f)
X	|| !fwrite(green, CMS_SIZE, 1, f)
X	|| !fwrite(blue, CMS_SIZE, 1, f))
X		ERROR("Save failed !");
X  fclose(f);
X}
X
X
X
END_OF_color_palet.c
if test 8977 -ne `wc -c <color_palet.c`; then
    echo shar: \"color_palet.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f command.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"command.c\"
else
echo shar: Extracting \"command.c\" \(4912 characters\)
sed "s/^X//" >command.c <<'END_OF_command.c'
X
X/**************************************************************************
X   Touchup a bitmap graphics editor for the Sun Workstation running SunView
X   Copyright (c) 1988 by Raymond Kreisel
X   1/22/88 @ Suny Stony Brook
X
X   This program may be redistributed without fee as long as this copyright
X   notice is intact.
X
X==> PLEASE send comments and bug reports to one of the following addresses:
X
X	   Ray Kreisel
X	   CS Dept., SUNY at Stony Brook, Stony Brook NY 11794
X
X	   UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk   
X	   ARPA-Internet: rayk@sbcs.sunysb.edu			
X	   CSnet: rayk@suny-sb
X	   (If nobody is home at any of the above addresses try:
X		S72QKRE@TOWSONVX.BITNET			        )
X
X "If I get home before daylight, I just might get some sleep tonight...."
X
X**************************************************************************/
X
X/**************************************************************************
X	file: command.c
X	purpose: This file contains the icon data for the command icons
X		in the command menu of the righthand side of the main window
X
X	modifications:
X		date:	Tue Mar 22 22:04:58 EST 1988
X		author:	rayk
X		changes:add comments
X**************************************************************************/
X#include <pixrect/pixrect_hs.h>
X
X
Xstatic short command1_data[] = {
X#include "laso.cicon.pat"
X};
Xstatic mpr_static(command1_pr, 48, 48, 1, command1_data);
X
Xstatic short command2_data[] = {
X#include "circle_h.cicon.pat"
X};
Xstatic mpr_static(command2_pr, 48, 48, 1, command2_data);
X
Xstatic short command3_data[] = {
X#include "draw.cicon.pat"
X};
Xstatic mpr_static(command3_pr, 48, 48, 1, command3_data);
X
Xstatic short command4_data[] = {
X#include "line.cicon.pat"
X};
Xstatic mpr_static(command4_pr, 48, 48, 1, command4_data);
X
Xstatic short command5_data[] = {
X#include "mag.cicon.pat"
X};
Xstatic mpr_static(command5_pr, 48, 48, 1, command5_data);
X
Xstatic short command6_data[] = {
X#include "ffill.cicon.pat"
X};
Xstatic mpr_static(command6_pr, 48, 48, 1, command6_data);
X
Xstatic short command7_data[] = {
X#include "oval_h.cicon.pat"
X};
Xstatic mpr_static(command7_pr, 48, 48, 1, command7_data);
X
Xstatic short command8_data[] = {
X#include "poly_f.cicon.pat"
X};
Xstatic mpr_static(command8_pr, 48, 48, 1, command8_data);
X
Xstatic short command9_data[] = {
X#include "poly_h.cicon.pat"
X};
Xstatic mpr_static(command9_pr, 48, 48, 1, command9_data);
X
Xstatic short command10_data[] = {
X#include "rectan_f.cicon.pat"
X};
Xstatic mpr_static(command10_pr, 48, 48, 1, command10_data);
X
Xstatic short command11_data[] = {
X#include "rectan_h.cicon.pat"
X};
Xstatic mpr_static(command11_pr, 48, 48, 1, command11_data);
X
Xstatic short command12_data[] = {
X#include "text.cicon.pat"
X};
Xstatic mpr_static(command12_pr, 48, 48, 1, command12_data);
X
Xstatic short command13_data[] = {
X#include "sel_reg.cicon.pat"
X};
Xstatic mpr_static(command13_pr, 48, 48, 1, command13_data);
X
Xstatic short command14_data[] = {
X#include "sel_point.cicon.pat"
X};
Xstatic mpr_static(command14_pr, 48, 48, 1, command14_data);
X
Xstatic short command15_data[] = {
X#include "paint.cicon.pat"
X};
Xstatic mpr_static(command15_pr, 48, 48, 1, command15_data);
X
Xstatic short command16_data[] = {
X#include "erase.cicon.pat"
X};
Xstatic mpr_static(command16_pr, 48, 48, 1, command16_data);
X
X/*
X * SELECTED REGION COMMANDS
X */
X
Xstatic short reg_command1_data[] = {
X#include "cut.cicon.pat"
X};
Xstatic mpr_static(reg_command1_pr, 48, 48, 1, reg_command1_data);
X
Xstatic short reg_command2_data[] = {
X#include "flip_hor.cicon.pat"
X};
Xstatic mpr_static(reg_command2_pr, 48, 48, 1, reg_command2_data);
X
Xstatic short reg_command3_data[] = {
X#include "flip_ver.cicon.pat"
X};
Xstatic mpr_static(reg_command3_pr, 48, 48, 1, reg_command3_data);
X
Xstatic short reg_command4_data[] = {
X#include "inverse.cicon.pat"
X};
Xstatic mpr_static(reg_command4_pr, 48, 48, 1, reg_command4_data);
X
Xstatic short reg_command5_data[] = {
X#include "copy.cicon.pat"
X};
Xstatic mpr_static(reg_command5_pr, 48, 48, 1, reg_command5_data);
X
Xstatic short reg_command6_data[] = {
X#include "paste.cicon.pat"
X};
Xstatic mpr_static(reg_command6_pr, 48, 48, 1, reg_command6_data);
X
Xstatic short reg_command7_data[] = {
X#include "rotate.cicon.pat"
X};
Xstatic mpr_static(reg_command7_pr, 48, 48, 1, reg_command7_data);
X
Xstatic short reg_command8_data[] = {
X#include "move.cicon.pat"
X};
Xstatic mpr_static(reg_command8_pr, 48, 48, 1, reg_command8_data);
X
Xstatic short reg_command9_data[] = {
X#include "scale.cicon.pat"
X};
Xstatic mpr_static(reg_command9_pr, 48, 48, 1, reg_command9_data);
X
X/*
X * TEXT COMMANDS
X */
X
Xstatic short text_center_data[] = {
X#include "center.cicon.pat"
X};
Xstatic mpr_static(text_center_pr, 48, 48, 1, text_center_data);
X
Xstatic short text_right_data[] = {
X#include "right.cicon.pat"
X};
Xstatic mpr_static(text_right_pr, 48, 48, 1, text_right_data);
X
Xstatic short text_left_data[] = {
X#include "left.cicon.pat"
X};
Xstatic mpr_static(text_left_pr, 48, 48, 1, text_left_data);
END_OF_command.c
if test 4912 -ne `wc -c <command.c`; then
    echo shar: \"command.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f confirmer.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"confirmer.c\"
else
echo shar: Extracting \"confirmer.c\" \(2478 characters\)
sed "s/^X//" >confirmer.c <<'END_OF_confirmer.c'
X
X/**************************************************************************
X   Touchup a bitmap graphics editor for the Sun Workstation running SunView
X   Copyright (c) 1988 by Raymond Kreisel
X   1/22/88 @ Suny Stony Brook
X
X   This program may be redistributed without fee as long as this copyright
X   notice is intact.
X
X==> PLEASE send comments and bug reports to one of the following addresses:
X
X	   Ray Kreisel
X	   CS Dept., SUNY at Stony Brook, Stony Brook NY 11794
X
X	   UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk   
X	   ARPA-Internet: rayk@sbcs.sunysb.edu			
X	   CSnet: rayk@suny-sb
X
X "If I get home before daylight, I just might get some sleep tonight...."
X
X**************************************************************************/
X/**************************************************************************
X	file: confirmer.c
X	purpose: This file contains a simple confirmer copied from the
X	 Sunview manual that has been souped up a little
X
X	modifications:
X		date:	Tue Mar 22 22:04:58 EST 1988
X		author:	rayk
X		changes:add comments
X
X		date:	Sun May 15 21:21:01 EDT 1988
X		author:	rayk
X		changes:rewrote the confirmer so that it is NOT created
X			dynamiclly to try to advoid the error in the
X			window creation (no more file descriptors)
X
X
X**************************************************************************/
X
X#include "header.h"
X
X/***************************************************************
X        confirm
X        purpose: To display a window on the base_frame Sunwindow
X                force the user to answer the question by selecting
X		either YES or NO
X        parameter:
X                message: The question to asked.
X        returns:
X		1 : if the user answered YES
X		0 : if the user answered NO
X ***************************************************************/
Xextern Panel_item con_msg_string;
X
Xint confirm(message)
Xchar     *message; 
X{
X   window_bell(panel);
X   confirm_msg(message);
X   return((int)window_loop(confirmer));
X}
X
X
Xconfirm_msg(string)
Xchar *string;
X{
Xchar temp_space[55];
Xchar *temp_pt;
Xint i;
X  
X  if (strlen(string) < 50)
X  {
X    for(i=0;i<50;i++)
X      temp_space[i]= ' ';
X    temp_pt = temp_space + (50-strlen(string))/2;
X    strcpy(temp_pt,string);
X    panel_set(con_msg_string,PANEL_LABEL_STRING,temp_space,0);
X  }
X  else
X    panel_set(con_msg_string,PANEL_LABEL_STRING,string,0);
X}
X
X
X
X/*
X * yes/no notify proc 
X */
Xvoid yes_no(item)
XPanel_item   item;
X{
X        window_return(panel_get(item, PANEL_CLIENT_DATA));
X}
END_OF_confirmer.c
if test 2478 -ne `wc -c <confirmer.c`; then
    echo shar: \"confirmer.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f cursor.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"cursor.c\"
else
echo shar: Extracting \"cursor.c\" \(2900 characters\)
sed "s/^X//" >cursor.c <<'END_OF_cursor.c'
X
X#ifdef CHANGE_CURSOR
X
X/*
X * NOTE: if you do not want the changing cursors remove the compile
X * time option '-DCHANGE_CURSOR' from the Makefile
X */
X
X/*
X * This file contains the cursor definitions and some small
X * support routine(s).
X * Can't possibly claim this is very original, so no copyright from me...
X * Pell 8 Jul 88
X */
X
X/*
X * NOTE! The ffill_cur is currently not used. Could be needed if the user
X * interface for filling is changed, e.g. like M*cPaint.
X */
X
X#include <suntool/sunview.h>
X#include <suntool/canvas.h>
X
Xstatic short drawcur_data[] = {
X#include "draw.cur"
X};
Xstatic mpr_static(draw_cur_pr, 16, 16, 1, drawcur_data);
X
Xstatic short erasecur_data[] = {
X#include "erase.cur"
X};
Xstatic mpr_static(erase_cur_pr, 16, 16, 1, erasecur_data);
X
X
X/*************************
X* static short ffillcur_data[] = {
X* #include "ffill.cur"
X* };
X* static mpr_static(ffill_cur_pr, 16, 16, 1, ffillcur_data);
X***************************/
X
Xstatic short lasocur_data[] = {
X#include "laso.cur"
X};
Xstatic mpr_static(laso_cur_pr, 16, 16, 1, lasocur_data);
X
Xstatic short paintcur_data[] = {
X#include "paint.cur"
X};
Xstatic mpr_static(paint_cur_pr, 16, 16, 1, paintcur_data);
X
Xstatic short sel_pointcur_data[] = {
X#include "sel_point.cur"
X};
Xstatic mpr_static(sel_point_cur_pr, 16, 16, 1, sel_pointcur_data);
X
Xstatic short textcur_data[] = {
X#include "text.cur"
X};
Xstatic mpr_static(text_cur_pr, 16, 16, 1, textcur_data);
X
XCursor old_cur, draw_cur, erase_cur, ffill_cur, laso_cur, paint_cur,
X       sel_point_cur, text_cur;
X
X/*
X * Init all cursors from static data.
X */
X
Xinit_cursors()
X{
X  /* old_cur initialized in interface.c */
X
X  draw_cur = cursor_create(CURSOR_IMAGE, &draw_cur_pr,
X			   CURSOR_OP, PIX_SRC^PIX_DST,
X			   CURSOR_XHOT, 0,
X			   CURSOR_YHOT, 15,
X			   0);
X  erase_cur = cursor_create(CURSOR_IMAGE, &erase_cur_pr,
X			    CURSOR_OP, PIX_SRC^PIX_DST,
X			    CURSOR_XHOT, 3,
X			    CURSOR_YHOT, 12,
X			    0);
X/***************
X  ffill_cur = cursor_create(CURSOR_IMAGE, &ffill_cur_pr,
X			    CURSOR_OP, PIX_SRC^PIX_DST,
X			    CURSOR_XHOT, 13,
X			    CURSOR_YHOT, 13,
X			    0);
X*******************/
X  laso_cur = cursor_create(CURSOR_IMAGE, &laso_cur_pr,
X			   CURSOR_OP, PIX_SRC^PIX_DST,
X			   CURSOR_XHOT, 4,
X			   CURSOR_YHOT, 15,
X			   0);
X  paint_cur = cursor_create(CURSOR_IMAGE, &paint_cur_pr,
X			    CURSOR_OP, PIX_SRC^PIX_DST,
X			    CURSOR_XHOT, 2,
X			    CURSOR_YHOT, 13,
X			    0);
X  sel_point_cur = cursor_create(CURSOR_IMAGE, &sel_point_cur_pr,
X				CURSOR_OP, PIX_SRC^PIX_DST,
X				CURSOR_XHOT, 7,
X				CURSOR_YHOT, 7,
X				0);
X  text_cur = cursor_create(CURSOR_IMAGE, &text_cur_pr,
X			   CURSOR_OP, PIX_SRC^PIX_DST,
X			   CURSOR_XHOT, 5,
X			   CURSOR_YHOT, 9,
X			   0);
X}
X
X/* 
X * Change cursor. Canvas and cursor passed as parameters.
X */
X
Xchange_cursor(can, cur)
X     Canvas can;
X     Cursor cur;
X{
X  window_set(can, WIN_CURSOR, cur, 0); /* OK, maybe overkill... */
X}
X
X#endif
X
X
END_OF_cursor.c
if test 2900 -ne `wc -c <cursor.c`; then
    echo shar: \"cursor.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f disk_io.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"disk_io.c\"
else
echo shar: Extracting \"disk_io.c\" \(17586 characters\)
sed "s/^X//" >disk_io.c <<'END_OF_disk_io.c'
X
X/**************************************************************************
X   Touchup a bitmap graphics editor for the Sun Workstation running SunView
X   Copyright (c) 1988 by Raymond Kreisel
X   1/22/88 @ Suny Stony Brook
X
X   This program may be redistributed without fee as long as this copyright
X   notice is intact.
X
X==> PLEASE send comments and bug reports to one of the following addresses:
X
X	   Ray Kreisel
X	   CS Dept., SUNY at Stony Brook, Stony Brook NY 11794
X
X	   UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk   
X	   ARPA-Internet: rayk@sbcs.sunysb.edu			
X	   CSnet: rayk@suny-sb
X	   (If nobody is home at any of the above addresses try:
X		S72QKRE@TOWSONVX.BITNET			        )
X
X "If I get home before daylight, I just might get some sleep tonight...."
X
X**************************************************************************/
X/**************************************************************************
X	file: disk_io.c
X	purpose: This file handle most of the file I/O stuff
X	  mostly load, save and file completion
X
X	modifications:
X		date:	Tue Mar 22 22:04:58 EST 1988
X		author:	rayk
X		changes:add comments
X
X		date:	Thu Apr 21 20:14:58 EDT 1988
X		author:	rayk
X		changes:when you hit return in filename the caret moves
X			to textstring
X
X		date:	Thu Apr 21 20:14:58 EDT 1988
X		author:	rayk
X		changes:when you do a load cut/paste buffer it will
X			automagicly bring up the cut/paste command menu
X
X		date:	Wed Jun 1 1:22:18 EDT 1988
X		author:	rayk
X		changes:fixed bug in resize color canvases
X
X		date:	Wed Jun 15 14:40:48 EDT 1988
X		author:	rayk
X		changes:added a check in file save to check is the
X			current filename is a directory
X**************************************************************************/
X
X#include "header.h"
X
X#include <sys/types.h>
X#include <sys/dir.h>
X#include <sys/file.h>
X#include <pwd.h>
X#include <sys/stat.h>
X
Xcolormap_t colormap;
Xextern  int   errno;
X
X/*
X * Let's do file completion on what we have in the file name prompt
X */
Xmake_new_name(item, event)
XPanel_item      item;
XEvent           *event;
X{
X        strcpy(file_name,(char*)panel_get_value(file_panel));
X        if (complete(file_name))
X      	  window_bell(panel);
X        panel_set(file_panel,PANEL_VALUE,file_name,0);
X}
X
X
X/* This function, written by Marc J Newberger,
X * will do both login name completion and file name completion, DAM fast.
X * That means as fast as the csh does it.
X */
Xint complete(template)
X
X    char    *template;
X
X{
X
X    char    dirName[255];
X    char   *prefix;    
X    int     pref_len;
X    char   *suffix;     
X    char   *p, *q;
X    char    first;
X    char    nonUnique;
X    char    twiddleUserCompletion;
X
X    struct  direct     *nameEntry;
X    DIR                *dirChan;
X    struct  passwd     *pwdEntry;
X
X    /*
X     *  First do a little parsing of the input. Separate the
X     *  prefix template from the directory if there is one.
X     */
X    twiddleUserCompletion= 0;
X    prefix= template+strlen(template);
X    while (*(--prefix) != '/' && prefix >= template);
X
X    /*
X     *  See if a directory was specified:
X     */
X    if (prefix < template) {
X        /*
X         *  No /'s, could be either a username completion or
X         *  a completion in the current directory.
X         */
X        if (template[0] == '~') {
X            prefix++;
X            twiddleUserCompletion= 1;
X            }
X        else {
X            strcpy(dirName, ".");
X            }
X        }
X    else if (prefix == template) {
X        /*
X         *  Special case !! The directory excluding the trailing
X         *  '/' is zero length. It's the root:
X         */
X        strcpy(dirName, "/");
X        }
X    else {
X        /*
X         *  We're completing a file in a directory.
X         *  The directory may be lead by a ~<username> abbreviation.
X         *  If that's the case expand it.
X         */
X        if (template[0] == '~') {
X            /*
X             *  We need to do twiddle directory expansion.
X             *  See if it's our directory:
X             */
X            if (template[1] == '/') {
X                strcpy(dirName, getenv("HOME"));
X		if ( &template[1] != prefix )
X		  {
X                    p= dirName+strlen(dirName);
X    		    q= &template[1];
X                    while (q < prefix) {
X                        *p= *q;
X                        p++, q++;
X                        }
X                    *p= 0;
X		  }
X                }
X            else {
X                /*
X                 * It's someone else's. Let our fingers
X                 * do the walking. (Why the fuck do they call it
X                 * the "yellow pages" anyway. They're white pages
X                 * dammit !  If they were YELLOW pages, we could
X                 * say ypmatch "Automobile, Dealers, Retail", and
X                 * things like that !).
X                 */
X                for (p= dirName, q= &template[1];
X                        (*p= *q) != '/';
X                            p++, q++);
X                *p= 0;
X                if (!(pwdEntry= getpwnam(dirName))) {
X                    return errno;
X                    }
X                strcpy(dirName, pwdEntry->pw_dir);
X                p= dirName+strlen(dirName);
X                while (q < prefix) {
X                    *p= *q;
X                    p++, q++;
X                    }
X                *p= 0;
X                }
X            }
X        else {
X            /*
X             *  It's a vanilla directory. Strip it out.
X             */
X            strncpy(dirName, template, prefix-template);
X            dirName[prefix-template]= 0;
X            }
X        }
X    /*
X     *  Bump prefix past the '/'.
X     */
X    prefix++;
X
X    /*
X     *  Get the prefix length and a pointer to the end of the
X     *  prefix.
X     */
X    pref_len= strlen(prefix);
X    suffix= template + strlen(template);
X
X    /*
X     *  See whether we're doing filename or username completion:
X     */
X    if (!twiddleUserCompletion) {
X
X        /*
X         *  It's filename completion. Read through the directory:
X         */
X        if ((dirChan= opendir(dirName)) == 0) {
X            return errno;
X            }
X
X        first= 1;
X        nonUnique= 0;
X        for (;;) {
X            if (!(nameEntry= readdir(dirChan))) {
X                break;
X                }
X            if (!strncmp(prefix, nameEntry->d_name, pref_len)) {
X                /*
X                 *  We have a file that matches the template.
X                 *  If it's the first one, we fill the completion
X                 *  suffix with it. Otherwise we scan and pare down
X                 *  the suffix.
X                 */
X                if (first) {
X                    first=  0 ;
X                    strcpy(suffix, nameEntry->d_name+pref_len);
X                    }
X                else {
X                    nonUnique= 1;
X                    p= suffix;
X                    q= nameEntry->d_name+pref_len;
X                    while (*p == *q) {
X                        ++p; ++q;
X                        }
X                    *p= 0;
X
X                    /*
X                     *  A little optimization: If p == suffix, we
X                     *  were unable to do any extension of the name.
X                     *  We might as well quit here.
X                     */
X                    if (p == suffix) {
X                        break;
X                        }
X                    }
X                }
X            }
X
X        closedir(dirChan);
X        }
X    else {
X        /*
X         *  Do ~Username completion. Start by resetting the passwd file.
X         */
X        setpwent();
X
X        first= 1;
X        nonUnique= 0;
X        for (;;) {
X            if (!(pwdEntry= getpwent())) {
X                break;
X                }
X            if (!strncmp(prefix, pwdEntry->pw_name, pref_len)) {
X                /*
X                 *  We have a user that matches the template.
X                 *  If it's the first one, we fill the completion
X                 *  suffix with it. Otherwise we scan and pare down
X                 *  the suffix.
X                 */
X                if (first) {
X                    first=  0 ;
X                    strcpy(suffix, pwdEntry->pw_name+pref_len);
X                    }
X                else {
X                    p= suffix;
X                    q= pwdEntry->pw_name+pref_len;
X                    while (*p == *q) {
X                        ++p; ++q;
X                        }
X
X                    /*
X                     *  Here there is a possibility of seeing the
X                     *  same username twice. For this reason, we
X                     *  only set nonUnique to 1 if we're shortening
X                     *  the suffix. This means that the new name is
X                     *  distinct from any name we've seen.
X                     */
X                    if (*p) {
X                        nonUnique= 1;
X                        *p= 0;
X                        }
X
X                    /*
X                     *  A little optimization: If p == suffix, we
X                     *  were unable to do any extension of the name.
X                     *  We might as well quit here.
X                     */
X                    if (p == suffix) {
X                        break;
X                        }
X                    }
X                }
X            }
X        }
X
X    /*
X     *  If nothing matched, return a -1, if there was non-uniqueness
X     *  return -2.
X     */ 
X    if (first) {
X        return -1;
X        }
X    else if (nonUnique) {
X        return -2;
X        }
X    else {
X        return 0;
X        }
X
X}
X
X
X/*
X * We just got a "load" button event and we want to load in the current
X * filename.
X */
Xload_file()
X{
XFILE *fp,*fopen();
Xint err=0;
Xstruct rasterfile file_header;
Xint load_area;
Xchar temp_file[MAX_FILE_NAME];
Xstruct pixrect *temp_pr;
X
X  /*
X   * Copy the current filename and expand the ~ if it is there
X   */
X  strcpy(temp_file,(char*)panel_get_value(file_panel));
X  get_full_path(temp_file,file_name);
X  load_area = (int)panel_get_value(load_cycle);
X  
X  fp = fopen(file_name,"r");
X  if (fp == NULL)
X	{
X         ERRORstr("Cannot open file: ",file_name);
X	 fclose(fp);
X	 return;
X	}
X
X  /*
X   * Try to read the header of the raster file and check if it is color
X   */
X  err = pr_load_header(fp,&file_header);
X  if (file_header.ras_maplength > 3*256) err=1;
X  if (err)
X	{
X	 ERROR("Cannot load the rasterfile header.");
X	 fclose(fp);
X	 return;
X	}
X
X  if (load_area == LOAD_ALL)  
X    {
X     clear_screen();
X     colormap.map[0] = red;
X     colormap.map[1] = green;
X     colormap.map[2] = blue;
X     colormap.type = file_header.ras_maptype;
X     colormap.length = file_header.ras_maplength/3;
X     /*
X      * load in the colormap for the raster file
X      */
X     if (pr_load_colormap(fp,&file_header,&colormap))
X	{
X	 ERROR("Cannot load the rasterfile colormap.");	
X	 fclose(fp);
X	 return;
X	}
X    }
X    else
X    {
X     /*
X      * skip the colormap for the raster file
X      */
X     if (pr_load_colormap(fp,&file_header,NULL))
X	{
X	 ERROR("Cannot load the rasterfile colormap.");	
X	 fclose(fp);
X	 return;
X	}
X    }
X
X  /*
X   * reset the memory pixrect and load the baby in
X   */
X  MY_pr_destroy(undo_pr);
X  undo_pr = (struct pixrect *)pr_load_image(fp,&file_header,&colormap);
X
X  if (undo_pr == NULL)
X	{
X         ERROR("Cannot allocate pixrect for loaded image file, not enough memory!");
X	 fclose(fp);
X	 return;
X	}
X
X  fclose(fp);
X
X  /*
X   * convert 1 bit deep bitmaps to 8 bits deeps if we are on a color machine
X   */
X  if ((image_depth >1) && (undo_pr->pr_depth == 1))
X    {
X	temp_pr = my_mem_create(file_header.ras_width,file_header.ras_height,
X			image_depth);
X	pr_rop(temp_pr,0,0,file_header.ras_width,file_header.ras_height,
X			PIX_SRC,undo_pr,0,0);
X	MY_pr_destroy(undo_pr);
X	undo_pr = temp_pr;
X    }
X
X
X
X  /*
X   * We are loading to the main drawing area so lets set all
X   * the color maps
X   */
X  if (load_area == LOAD_ALL)  
X    {
X     if (image_depth > 1)
X       {
X	my_put_colormap();
X	set_color();
X        /*
X         * new fix for color retained canvases for version 2.3
X         */
X        (void)window_set(canvas,
X	    CANVAS_WIDTH,		file_header.ras_width,
X	    CANVAS_HEIGHT,		file_header.ras_height,
X	    0);
X       }
X     else
X       {
X        set_mono();
X        (void)window_set(canvas,
X	    CANVAS_WIDTH,		file_header.ras_width,
X	    CANVAS_HEIGHT,		file_header.ras_height,
X	    0);
X       }
X     panel_set(save_cycle,PANEL_VALUE, SAVE_ALL,0);
X     image_wid = file_header.ras_width;
X     image_hgt = file_header.ras_height;
X     pw_write(pw,0,0, image_wid,image_hgt, PIX_SRC, undo_pr,0,0);
X     sprintf(temp_file,"%d",image_hgt);
X     panel_set(height_text,PANEL_VALUE,temp_file,0);
X     sprintf(temp_file,"%d",image_wid);
X     panel_set(width_text,PANEL_VALUE,temp_file,0);
X    }
X  else
X    {
X    /*
X     * we load the image into the cut/paste buffer
X     */
X    MY_pr_destroy(cut_buffer_pr);
X    cut_buffer_pr = my_mem_create(file_header.ras_width,file_header.ras_height,image_depth);
X    pr_rop(cut_buffer_pr,0,0,file_header.ras_width,file_header.ras_height,
X			PIX_SRC,undo_pr,0,0);
X    MY_pr_destroy(undo_pr);
X    undo_pr = my_mem_create(image_wid,image_hgt,image_depth);
X    panel_set(region_choice,PANEL_VALUE,MOVE,0);
X    panel_set(command_choice,PANEL_VALUE,SEL_REG,0);
X    (void)window_set(brush_panel, WIN_SHOW,FALSE, 0);
X    (void)window_set(region_panel, WIN_SHOW,TRUE, 0);
X    print_msg("Object copied to Cut/Paste buffer. Hold down the RIGHT mouse button to drag the object.");
X    mouse_parms();
X    }
X}
X
X
X
X/*
X * Save a file out to the current filename
X */
Xsave_file()
X{
XFILE *fp,*fopen();
Xint type = RT_STANDARD;
Xint copy_flag = TRUE;
Xchar temp_file[MAX_FILE_NAME];
X
X hide_msg();
X /*
X  * Is the raster file to be run-length encode or not
X  */
X if((int)panel_get_value(compress_cycle))
X	type = RT_BYTE_ENCODED;
X else
X	type = RT_STANDARD;
X  
X  /*
X   * Copy the current filename and expand the ~ if it is there
X   */
X strcpy(temp_file,(char*)panel_get_value(file_panel));
X get_full_path(temp_file,file_name);
X
X if (file_is_dir(file_name))
X	{
X         ERROR("The current filename is a directory !");
X	 return;
X	}
X
X if (file_exist(file_name))
X	{
X         if (!confirm("Overwrite existing file ?"))
X	 return;
X	}
X /*
X  * dump standard SUN raster file with color table to disk file
X  */
X fp = fopen(file_name,"w");
X  if (fp == NULL)
X	{
X	 fclose(fp);
X         ERRORstr("Cannot write to file: ",file_name);
X	 return;
X	}
X /*
X  * Save the whole drawing area out to the disk file
X  */
X if (SAVE_ALL == (int)panel_get_value(save_cycle))
X   {
X     clean_point();
X     clean_region();
X     fat_done();
X     finish_text();
X     save_screen();
X
X     colormap.map[0] = red;
X     colormap.map[1] = green;
X     colormap.map[2] = blue;
X     if (image_depth > 1)
X       {
X     	colormap.type = RMT_EQUAL_RGB;
X     	colormap.length = 256;
X       }
X     else
X       {
X     	colormap.type = RMT_NONE;
X     	colormap.length = 0;
X       }
X
X     if (!undo_pr)
X        undo_pr = my_mem_create(image_wid,image_hgt,image_depth);
X     pr_rop(undo_pr,0,0,image_wid,image_hgt,PIX_SRC,pw->pw_prretained,0,0);
X     pr_dump(undo_pr,fp,&colormap,type,copy_flag);
X   }
X else
X   {
X  /*
X   * just save the cut/Paste buffer out to the file
X   */
X     if (cut_buffer_pr == NULL)
X	{
X	 ERROR("The Cut/Paste buffer is empty");
X	 fclose(fp);
X	 return;
X	}
X     colormap.map[0] = red;
X     colormap.map[1] = green;
X     colormap.map[2] = blue;
X     if (image_depth > 1)
X       {
X     	colormap.type = RMT_EQUAL_RGB;
X     	colormap.length = 256;
X       }
X     else
X       {
X     	colormap.type = RMT_NONE;
X     	colormap.length = 0;
X       }
X     pr_dump(cut_buffer_pr,fp,&colormap,type,copy_flag);
X   }
X fclose(fp);
X}
X
X
X/*
X * Check if a file exist or not
X */
Xfile_exist(file_name)
Xchar *file_name;
X{
XFILE *fp;
X  fp = fopen(file_name,"r");
X  fclose(fp);
X  if (fp != NULL)
X	return(TRUE);
X  else
X	return(FALSE);
X}
X
X
X/*
X * Check if the file is a directory
X */
Xfile_is_dir(file_name)
Xchar *file_name;
X{
Xstruct stat buf;
X
X  if (file_exist(file_name))
X  {
X    stat(file_name,&buf);
X    if (buf.st_mode & S_IFDIR)
X	return(TRUE);
X    else
X	return(FALSE);
X  }
X  else
X      return(FALSE);
X}
X
X
X/*
X * Take a filename with a ~ character at the begining and return
X * the full path name to that file
X */
Xget_full_path(template,full_path)
Xchar template[];
Xchar full_path[];
X{
X    char   *p, *q;
X    struct  passwd     *pwdEntry;
X        /*
X         *  We're completing a file in a directory.
X         *  The directory may be lead by a ~<username> abbreviation.
X         *  If that's the case expand it.
X         */
X        if (template[0] == '~') {
X            /*
X             *  We need to do twiddle directory expansion.
X             *  See if it's our directory:
X             */
X            if (template[1] == '/') {
X                strcpy(full_path, getenv("HOME"));
X		strcat(full_path,&template[1]);
X                }
X            else {
X                /*
X                 * It's someone else's. Let our fingers
X                 * do the walking. (Why the fuck do they call it
X                 * the "yellow pages" anyway. They're white pages
X                 * dammit !  If they were YELLOW pages, we could
X                 * say ypmatch "Automobile, Dealers, Retail", and
X                 * things like that !).
X                 */
X                for (p= full_path, q= &template[1];
X                        (*p= *q) != '/';
X                            p++, q++);
X                *p= 0;
X                if (!(pwdEntry= getpwnam(full_path))) {
X                    return errno;
X                    }
X                strcpy(full_path, pwdEntry->pw_dir);
X		strcat(full_path,q);
X                }
X	}
X	else
X	  	strcpy(full_path,template);
X}		 
X
END_OF_disk_io.c
if test 17586 -ne `wc -c <disk_io.c`; then
    echo shar: \"disk_io.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f drawing.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"drawing.c\"
else
echo shar: Extracting \"drawing.c\" \(23040 characters\)
sed "s/^X//" >drawing.c <<'END_OF_drawing.c'
X
X/**************************************************************************
X   Touchup a bitmap graphics editor for the Sun Workstation running SunView
X   Copyright (c) 1988 by Raymond Kreisel
X   1/22/88 @ Suny Stony Brook
X
X   This program may be redistributed without fee as long as this copyright
X   notice is intact.
X
X==> PLEASE send comments and bug reports to one of the following addresses:
X
X	   Ray Kreisel
X	   CS Dept., SUNY at Stony Brook, Stony Brook NY 11794
X
X	   UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk   
X	   ARPA-Internet: rayk@sbcs.sunysb.edu			
X	   CSnet: rayk@suny-sb
X	   (If nobody is home at any of the above addresses try:
X		S72QKRE@TOWSONVX.BITNET			        )
X
X "If I get home before daylight, I just might get some sleep tonight...."
X
X**************************************************************************/
X/**************************************************************************
X	file: drawing.c
X	purpose: This file has most of the functions that draw stuff
X	on the screen.
X
X	modifications:
X		date:	Tue Mar 22 22:04:58 EST 1988
X		author:	rayk
X		changes:add comments
X
X		date:	Fri Apr 15 02:08:11 EDT 1988
X		author:	rayk
X		changes:added scale cut/paste
X
X		date:	Tue Apr 19 14:05:10 EDT 1988
X		author:	rayk
X		changes:fixed no-borders on polygons
X
X		date:	Fri Apr 22 03:05:28 EDT 1988
X		author:	rainbow
X		changes:added FAST rotate
X
X		date:	Fri Apr 22 17:11:02 EDT 1988
X		author:	rayk
X		changes:added pw_batch to make things much FASTER
X
X		date:	Wed Jun 15 14:40:48 EDT 1988
X		author:	juang@aloft.att.com
X		changes:worked around bug in pw_stencil that
X			would not display color paint brushes properly
X			on Sun 3/160 & Sun 3/260
X
X		date:	Wed Jun 15 16:49:43 EDT 1988
X		author:	rayk
X		changes:added toggle to make it so that
X			lasso will clear the area that has been selected
X
X		date:	Fri Jul  1 22:17:49 EDT 1988
X		author:	rainbow & rayk
X		changes:added the ability to draw thick lines
X
X		date:	Sat Jul  2 01:03:38 EDT 1988
X		author:	rayk  & rainbow
X		changes:made paint so that it would always paint continuous
X			lines instead of discontinuous dots
X
X		date:	Tue Jul  5 00:36:02 EDT 1988
X		author:	rayk
X		changes:changed TEXT command so that if you hold down shift
X			it will draw with pw_ttext
X
X		date:	Thu Jul  7 23:35:57 EDT 1988
X		author:	rayk
X		changes:added 'moving' lines box for select region command
X
X               	date:   Fri Jul  8 18:51:48 MET 1988
X               	author: Pell
X               	changes:added 'register' in a couple of places, in case
X                       	there is someone who doesn't use GNU CC...
X                       	Shrunk the size of the eraser.
X			Added support for cursor switching.
X
X               	date:   Sun Jul 24 12:47:33 EDT 1988
X               	author: rayk
X               	changes:added interactive text input, and centering, left
X			and right justified text
X
X**************************************************************************/
X
X#include"header.h"
X#include<math.h>
X
Xstruct pr_pos poly_points[MAX_POLY];
Xint brush_radius[] = { 1, 2, 3, 4, 6, 8, 10};
X
Xstruct pixrect *brush_temp_pr = NULL;
X
X/*
X * What we do that someone selects a new pattern
X */
Xselect_pattern()
X{
X  panel_set(current_pattern,PANEL_LABEL_IMAGE,pattern[(int)panel_get_value(pattern_choice)],0);
X
X}
X
X
X/*
X * let the user define his own patterns to paint with
X * works for color and mono
X */
Xpattern_define()
X{
X
X  if (select_pt_x == -1)
X     {
X	ERROR("Select a point first, then select Define Pattern.");
X	set_select_mode();
X	return;
X     }
X  select_point(select_pt_x,select_pt_y);
X  if (image_depth > 1)
X   {
X      pattern[39]  = my_mem_create(PATTERN_SIZE,PATTERN_SIZE,image_depth);
X      pattern40_pr = *(pattern[39]);
X   }
X  pr_rop(pattern[39],0,0,PATTERN_SIZE,PATTERN_SIZE,
X		PIX_SRC,pw->pw_prretained,select_pt_x-PATTERN_SIZE/2,
X		select_pt_y-PATTERN_SIZE/2);
X
X  panel_paint(pattern_choice,PANEL_NO_CLEAR);
X  reset_point();
X  print_msg("The user defined pattern is now stored in the last pattern element.");
X}
X
X
X/*
X * Take the current text string and put that Baby up on the bitmap
X * in the right font
X */
Xdraw_text(x,y,str,ROP)
Xint x,y,ROP;
Xchar *str;
X{
X   if (ROP == TRANSPARENT)
X    {
X      pw_ttext(pw,x,y,PIX_COLOR(cur_color) | PIX_SRC,
X		real_font,
X		str);
X    }
X   else
X    {
X      pw_text(pw,x,y,PIX_COLOR(cur_color) | ROP,
X		real_font,
X		str);
X    }
X}
X
X
X/*
X * draw a line on the bitmap
X */
Xdraw_line(x1,y1,x2,y2,ROP,color)
Xint x1,y1,x2,y2,ROP,color;
X{
X  pw_vector(pw,x1,y1,x2,y2,ROP,color);
X}
X
X
X/*
X * draw a thick line on the bitmap
X */
Xdraw_thick_line(x1,y1,x2,y2,ROP,color,thickness)
Xint x1,y1,x2,y2,ROP,color,thickness;
X{
Xdouble r,R,q,q1,q2,s;
Xint t1,t2;
Xint npts[1];
X
X  if (thickness > 1)
X  {
X/*      R = (double)sqrt_fast((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));  */
X
X    R = (double)sqrt((double)((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)));
X
X    r = ((double)thickness);
X    q = r/R;
X    q1 = q*(double)(y1-y2);
X    q2 = q*(double)(x1-x2);
X    t1 = (int)rint((q1>0)?q1+0.01:q1-0.01);
X    t2 = (int)rint((q2>0)?q2+0.01:q2-0.01);
X    s = fabs(q1)+fabs(q2)-(double)(abs(t1)+abs(t2));
X    if (fabs(s) > 0.5)
X      if (fabs(q1-(double)t1) > fabs(q2-(double)t2))
X        t1 += ((q1-(double)t1)>0)?1:-1;
X      else t2 += ((q2-(double)t2)>0)?1:-1;
X    ptlist[0].x = x1+t1;
X    ptlist[0].y = y1-t2;
X    ptlist[1].x = x1-t1;
X    ptlist[1].y = y1+t2;
X    ptlist[2].x = x2-t1;
X    ptlist[2].y = y2+t2;
X    ptlist[3].x = x2+t1;
X    ptlist[3].y = y2-t2;
X    npts[0] = 4;
X    pw_polygon_2(pw,0,0,1,npts,ptlist,ROP | PIX_COLOR(color),
X  		pattern[(int)panel_get_value(pattern_choice)],0,0);
X  }
X  else
X    pw_vector(pw,x1,y1,x2,y2,ROP,color);
X}
X
X
X/*
X * draw a rectangle on the bitmap
X */
Xdraw_rectangle(x1,y1,x2,y2)
Xint x1,y1,x2,y2;
X{
Xint ROP,radius;
Xextern int rec_brush;
X
X  top_x = x1;
X  top_y = y1;
X  bottom_x = x2;
X  bottom_y = y2;
X  region_fix();
X  pw_batch_on(pw);
X  if ((int)panel_get_value(command_choice)==RECT_F)
X	fill_region(TRUE);
X  else
X  	select_region(pw,old_x,old_y,start_x,start_y);
X
X  if (!(ROP = get_current_ROP()))
X      ROP = PIX_SRC;
X  if ((int)panel_get_value(border_cycle)
X       && ((int)panel_get_value(command_choice)==RECT_H))
X  {
X    if (rec_brush)
X    	radius = brush_radius[rec_brush];
X    else
X	radius = 0;
X
X    draw_thick_line(top_x,top_y,bottom_x,top_y,
X			ROP,cur_color,brush_radius[rec_brush]);
X    draw_thick_line(bottom_x,top_y-radius,bottom_x,bottom_y+radius,
X			ROP,cur_color,brush_radius[rec_brush]);
X    draw_thick_line(bottom_x,bottom_y,top_x,bottom_y,
X			ROP,cur_color,brush_radius[rec_brush]);
X    draw_thick_line(top_x,bottom_y+radius,top_x,top_y-radius,
X			ROP,cur_color,brush_radius[rec_brush]);
X  }
X  if ((int)panel_get_value(border_cycle)
X       && ((int)panel_get_value(command_choice)==RECT_F))
X  {
X    pw_vector(pw,x1,y1,x2,y1,ROP,cur_color);
X    pw_vector(pw,x2,y1,x2,y2,ROP,cur_color);
X    pw_vector(pw,x2,y2,x1,y2,ROP,cur_color);
X    pw_vector(pw,x1,y2,x1,y1,ROP,cur_color);
X  }
X
X  pw_batch_off(pw);
X  reset_region();
X}
X
X
X/*
X * highlight the selected region on the drawing area by throwing up a
X * XORed rectangle
X */
Xselect_region(pw,x1,y1,x2,y2)
Xstruct pixwin *pw;
Xint x1,y1,x2,y2;
X{
X  pw_vector(pw,x1,y1,x2,y1,PIX_XOR,1);
X  pw_vector(pw,x2,y1,x2,y2,PIX_XOR,1);
X  pw_vector(pw,x2,y2,x1,y2,PIX_XOR,1);
X  pw_vector(pw,x1,y2,x1,y1,PIX_XOR,1);
X}
X
X
X/*
X * reset the current REGION
X */
Xreset_region()
X{
X  top_x=0;
X  top_y=0;
X  bottom_x=0;
X  bottom_y=0;
X}
X
X
X/*
X * draw up a point, how stupid ???
X */
Xdraw_point(pw,x,y)
Xstruct pixwin *pw;
Xint x,y;
X{
X  pw_put(pw,x,y,cur_color);
X}
X
X
X/*
X * Draw up the paint brush by copying the current pattern
X * through a stencil of the current brush
X */
Xdraw_con_brush(pw,x1,y1,x2,y2)
Xstruct pixwin *pw;
Xint x1,y1,x2,y2;
X{
Xint ROP,brush_index;
X
X  brush_index = (int)panel_get_value(brush_choice);
X  if (!(ROP = get_current_ROP()))
X    ROP = PIX_SRC;
X
X  if (brush_index)
X  {
X      if ((x1 != x2) || (y1 != y2));
X      {
X        draw_thick_line(x1,y1,x2,y2,ROP,cur_color,
X    		  brush_radius[brush_index]);
X      }
X        draw_brush(pw, x1,y1);
X  }
X  else
X      draw_line(x1,y1,x2,y2,ROP,cur_color);
X}
X
X
X/*
X * Draw up the paint brush by copying the current pattern
X * through a stencil of the current brush
X */
Xdraw_brush(pw,x,y)
Xstruct pixwin *pw;
Xint x,y;
X{
Xint ROP;
X
X  if (!(ROP = get_current_ROP()))
X    ROP = PIX_SRC;
X
X  if (brush_temp_pr == NULL)
X    brush_temp_pr = my_mem_create(PATTERN_SIZE,PATTERN_SIZE,image_depth);
X
X  if (brush_temp_pr->pr_depth != image_depth)
X  {
X        MY_pr_destroy(brush_temp_pr);
X        brush_temp_pr = my_mem_create(PATTERN_SIZE,PATTERN_SIZE,image_depth);
X  }
X
X  if (((int)panel_get_value(pattern_choice) != 39) || (image_depth == 1))
X  {
X        pr_replrop(brush_temp_pr,0,0,PATTERN_SIZE,PATTERN_SIZE, PIX_COLOR(cur_color) | PIX_SRC,pattern[(int)panel_get_value(pattern_choice)],x-PATTERN_SIZE/2,y-PATTERN_SIZE/2);
X  }
X  else
X  {
X        pr_replrop(brush_temp_pr,0,0,PATTERN_SIZE,PATTERN_SIZE, PIX_SRC,pattern[(int)panel_get_value(pattern_choice)],x,y);
X  }
X
X  pw_stencil(pw,x-PATTERN_SIZE/2,y-PATTERN_SIZE/2,PATTERN_SIZE,PATTERN_SIZE,
X  ROP, brushes[(int)panel_get_value(brush_choice)],0,0,brush_temp_pr,0,0);
X}
X
X
X/*
X * flip-flop two varibles (ints)
X */
Xswap(x,y)
Xint *x,*y;
X{
Xint temp;
X  temp = *x;
X  *x = *y;
X  *y = temp;
X}
X
X
Xregion_fix()
X{
X  if (top_x > bottom_x)
X     swap(&top_x,&bottom_x);
X  if (top_y > bottom_y)
X     swap(&top_y,&bottom_y);
X} 
X
X
X/*
X * put the eraser on the drawing area
X */
Xerase_brush(pw,x,y)
Xstruct pixwin *pw;
Xint x,y;
X{
X  pw_batch_on(pw);
X  select_region(pw,old_x,old_y,old_x+CURSOR_SIZE,old_y+CURSOR_SIZE);
X  pw_rop(pw,x-CURSOR_SIZE/2,y-CURSOR_SIZE/2,CURSOR_SIZE,CURSOR_SIZE, PIX_SRC,0,0,0);
X  old_x = x-CURSOR_SIZE/2; old_y= y-CURSOR_SIZE/2;
X  select_region(pw,old_x,old_y,old_x+CURSOR_SIZE,old_y+CURSOR_SIZE);
X  pw_batch_off(pw);
X}
X
X
X/*
X * draw up some cross hairs to be used to select a point
X */
X#define CROSS_HAIR 20
Xselect_point(x,y)
Xint x,y;
X{
X  pw_vector(pw,x-CROSS_HAIR,y,x+CROSS_HAIR,y,PIX_XOR,1);
X  pw_vector(pw,x,y-CROSS_HAIR,x,y+CROSS_HAIR,PIX_XOR,1);
X}
X
X
X/*
X * reset the currently selected point
X */
Xreset_point()
X{
X  select_pt_x = 0-1;
X  select_pt_y = 0-1;
X}
X
X
X/*
X * take a currently selected region and invert that baby ! FAST !!!
X */
Xinverse_region()
X{
X  if (top_x || top_y || bottom_x || bottom_y)
X    {
X     select_region(pw,top_x,top_y,bottom_x,bottom_y);
X     region_fix();
X     pw_replrop(pw,top_x,top_y,bottom_x-top_x,bottom_y-top_y, PIX_XOR, pattern[0],0,0);
X     select_region(pw,top_x,top_y,bottom_x,bottom_y);
X    }
X  else
X    {
X     ERROR("Select a region first, then select INVERSE.");
X     panel_set(command_choice,PANEL_VALUE,SEL_REG,0);
X#ifdef CHANGE_CURSOR
X     change_cursor(canvas, old_cur);
X#endif
X     mouse_parms();
X    }
X}
X
X
X
X/*
X * take a currently selected region and rotate around the center
X * point.  New FAST version that rotates in 3n bitblt where n is
X * number of raster lines in the source
X */
Xrotate_region()
X{
Xregister int    i, width, height;
Xint             new_x, new_y, y1, y2, n;
Xstruct pixrect	*tmp1, *tmp2;
X
X  if (top_x || top_y || bottom_x || bottom_y)
X    {
X     move_box(CLEAR);
X     region_fix();
X     width = bottom_x - top_x;
X     height = bottom_y - top_y;
X     new_x = top_x + (width - height) / 2;
X     new_y = top_y + (height - width ) /2;
X     tmp1 = my_mem_create(width+height-1, height, image_depth);
X     tmp2 = my_mem_create(width+height-1, width, image_depth);
X
X     for(i=0; i<height; i++)
X	   pr_rop(tmp1, i, i, width, 1, PIX_SRC, pw->pw_prretained, top_x, top_y+i);
X
X     for(i=0; i<=width+height-1; i++)
X        {
X	   n = (i+1<height) ? i+1 : ((i>=width) ? (width+height-1-i) : height);
X           y1 = (i<width) ? (width-1-i) : 0;
X           y2 = (i>=width) ? (i-width+1) : 0;
X           pr_rop(tmp2, i, y1, 1, n, PIX_SRC, tmp1, i, y2);
X        }
X
X     pw_batch_on(pw);
X     for(i=0; i<width; i++)
X	   pw_rop(pw, new_x, new_y+i, height, 1, PIX_SRC, tmp2, width-1-i, i);
X     pw_batch_off(pw);
X     MY_pr_destroy(tmp1);
X     MY_pr_destroy(tmp2);
X
X     top_x = new_x;
X     top_y = new_y;
X     bottom_x = new_x+height;
X     bottom_y = new_y+width;
X     move_box(CLEAR);
X    }
X  else
X    {
X     ERROR("Select a region first, then select ROTATE.");
X     panel_set(command_choice,PANEL_VALUE,SEL_REG,0);
X#ifdef CHANGE_CURSOR
X     change_cursor(canvas, old_cur);
X#endif
X     mouse_parms();
X    }
X}
X
X
X
X/*
X * take a currently selected region and make a mirror image of it
X */
Xflip_hor_region()
X{
Xregister i;
X  if (top_x || top_y || bottom_x || bottom_y)
X    {
X     move_box(CLEAR);
X     region_fix();
X     MY_pr_destroy(cut_buffer_pr);
X     cut_buffer_pr = my_mem_create(bottom_x-top_x,bottom_y-top_y,image_depth);
X     pr_rop(cut_buffer_pr,0,0,bottom_x-top_x,bottom_y-top_y,
X		PIX_SRC,pw->pw_prretained,top_x,top_y);
X     pw_batch_on(pw);
X     for (i = 0; i < cut_buffer_pr->pr_size.x; i++) {
X	    pw_rop(pw, top_x+(cut_buffer_pr->pr_size.x - i)-1,top_y,
X			1,cut_buffer_pr->pr_size.y, PIX_SRC, cut_buffer_pr,i,0);
X	}
X     move_box(CLEAR);
X     pw_batch_off(pw);
X    }
X  else
X    {
X     ERROR("Select a region first, then select MIRROR.");
X     panel_set(command_choice,PANEL_VALUE,SEL_REG,0);
X#ifdef CHANGE_CURSOR
X     change_cursor(canvas, old_cur);
X#endif
X     mouse_parms();
X    }
X}
X
X
X/*
X * take a currently selected region and turn it upside down
X */
Xflip_ver_region()
X{
Xregister i;
X  if (top_x || top_y || bottom_x || bottom_y)
X    {
X     move_box(CLEAR);
X     region_fix();
X     MY_pr_destroy(cut_buffer_pr);
X     cut_buffer_pr = my_mem_create(bottom_x-top_x,bottom_y-top_y,image_depth);
X     pw_batch_on(pw);
X     pr_rop(cut_buffer_pr,0,0,bottom_x-top_x,bottom_y-top_y,
X		PIX_SRC,pw->pw_prretained,top_x,top_y);
X     for (i = 0; i < cut_buffer_pr->pr_size.y; i++) {
X	    pw_rop(pw, top_x, top_y+(cut_buffer_pr->pr_size.y - i)-1,
X			cut_buffer_pr->pr_size.x, 1, PIX_SRC, cut_buffer_pr, 0, i);
X	}
X     move_box(CLEAR);
X     pw_batch_off(pw);
X    }
X  else
X    {
X     ERROR("Select a region first, then select FLIP VERTICAL.");
X     panel_set(command_choice,PANEL_VALUE,SEL_REG,0);
X#ifdef CHANGE_CURSOR
X     change_cursor(canvas, old_cur);
X#endif
X     mouse_parms();
X    }
X}
X
X
X/*
X * take a current Cut/Paste and scale it
X */
Xscale_region()
X{
Xint ROP;
Xfloat inc,count;
Xregister line;
Xstruct pixrect  *temp_pix;
X
X  if ((top_x || top_y || bottom_x || bottom_y) && cut_buffer_pr)
X    {
X     if (!(ROP = get_current_ROP()))
X	ROP = PIX_SRC;
X     region_fix();
X
X     temp_pix = my_mem_create(cut_buffer_pr->pr_size.x,bottom_y-top_y,image_depth);
X     inc = ((float)cut_buffer_pr->pr_size.y)/(float)(bottom_y-top_y);
X     for (count = 0.0,line = 0; count < cut_buffer_pr->pr_size.y ; count +=inc, line++)
X        {
X	   pr_rop(temp_pix,0,line,
X	     cut_buffer_pr->pr_size.x, 1, ROP, cut_buffer_pr, 0, (int)count);
X	}
X     inc = ((float)cut_buffer_pr->pr_size.x)/(float)(bottom_x-top_x);
X     pw_batch_on(pw);
X     move_box(CLEAR); 
X     for (count = 0.0, line = 0; count < cut_buffer_pr->pr_size.x;  count +=inc, line++)
X        {
X	    pw_rop(pw,top_x + line,top_y,
X		1,temp_pix->pr_size.y, ROP,temp_pix,(int)count,0);
X	}
X     move_box(CLEAR);
X     pw_batch_off(pw);
X     MY_pr_destroy(temp_pix);
X    }
X  else
X    {
X     ERROR("Select a destination region first, then select SCALE.");
X     panel_set(command_choice,PANEL_VALUE,SEL_REG,0);
X#ifdef CHANGE_CURSOR
X     change_cursor(canvas, old_cur);
X#endif
X     mouse_parms();
X    }
X}
X
X
X
X/*
X * grab what is in the Cut/Paste buffer and put it up on the drawing area
X */
Xpaste_region()
X{
Xint ROP;
X
X  if (select_pt_x == -1)
X     {
X	ERROR("Select a point first, then select PASTE.");
X	set_select_mode();
X	return;
X     }
X  if (cut_buffer_pr)
X  {
X     if (!(ROP = get_current_ROP()))
X	ROP = PIX_SRC;
X     select_point(select_pt_x,select_pt_y);
X     save_screen();
X     pw_write(pw,select_pt_x,select_pt_y,cut_buffer_pr->pr_size.x,cut_buffer_pr->pr_size.y, ROP, cut_buffer_pr,0,0);
X     reset_point();
X  }
X  else
X	ERROR("The Cut/Paste buffer is empty.");
X}
X
X
X/*
X * grab the currently selected region on the drawing area and stuff
X * it into the cut/paste buffer AND destroy the source area by
X * filling in with the current paint pattern
X */
Xcut_region()
X{
Xint t1,t2,t3,t4;
X  if (top_x || top_y || bottom_x || bottom_y)
X    {
X      t1 = top_x;
X      t2 = top_y;
X      t3 = bottom_x;
X      t4 = bottom_y;
X      copy_region();
X      top_x = t1;
X      top_y = t2;
X      bottom_x = t3;
X      bottom_y = t4;
X      move_box(CLEAR);
X      run_box=FALSE;
X      fill_region(FALSE);
X      panel_set(command_choice,PANEL_VALUE, GET_PT,0);
X#ifdef CHANGE_CURSOR
X     change_cursor(canvas, sel_point_cur);
X#endif
X      mouse_left = GET_PT;
X      print_msg("Region copied to Cut/Paste buffer, select a point and then press PASTE.");
X    }
X   else
X    {
X     ERROR("Select a region first, then select CUT.");
X     panel_set(command_choice,PANEL_VALUE,SEL_REG,0);
X#ifdef CHANGE_CURSOR
X     change_cursor(canvas, old_cur);
X#endif
X     mouse_parms();
X    }
X}
X
X
X/*
X * grab the currently selected region on the drawing area and stuff
X * it into the cut/paste buffer
X */
Xcopy_region()
X{
X  if (top_x || top_y || bottom_x || bottom_y)
X    {
X     move_box(CLEAR);
X     region_fix();
X     MY_pr_destroy(cut_buffer_pr);
X     cut_buffer_pr = my_mem_create(bottom_x-top_x,bottom_y-top_y,image_depth);
X     pr_rop(cut_buffer_pr,0,0,bottom_x-top_x,bottom_y-top_y,
X		PIX_SRC,pw->pw_prretained,top_x,top_y);
X     move_box(CLEAR);
X    }
X   else
X    {
X	ERROR("Select a region first, then select COPY.");
X        panel_set(command_choice,PANEL_VALUE,SEL_REG,0);
X#ifdef CHANGE_CURSOR
X        change_cursor(canvas, old_cur);
X#endif
X        mouse_parms();
X    }
X}
X
X
X/*
X * take the cut/paste buffer and XOR it that stuff on to the drawing area
X * so that I can move that sucker around FAST
X */
Xmove_region(old_x,old_y,new_x,new_y)
Xint old_x,old_y,new_x,new_y;
X{
X  if (cut_buffer_pr)
X    {
X     pw_batch_on(pw);
X     pw_write(pw,old_x-cut_buffer_pr->pr_size.x/2,
X		 old_y-cut_buffer_pr->pr_size.y/2,
X		 cut_buffer_pr->pr_size.x,
X		 cut_buffer_pr->pr_size.y,
X		 PIX_XOR, cut_buffer_pr,0,0);
X
X     pw_write(pw,new_x-cut_buffer_pr->pr_size.x/2,
X		 new_y-cut_buffer_pr->pr_size.y/2,
X		 cut_buffer_pr->pr_size.x,
X		 cut_buffer_pr->pr_size.y,
X		 PIX_XOR, cut_buffer_pr,0,0);
X     pw_batch_off(pw);
X    }
X   else
X    {
X       ERROR("CUT or COPY a region first, then select MOVE.");
X    }
X}
X
X
X/*
X * fill in a rectanglar region with the current paint pattern
X */
Xfill_region(sel_reg)
Xint sel_reg;
X{
Xint ROP;
X
X   if (top_x || top_y || bottom_x || bottom_y)
X    {
X      if (sel_reg)
X      	select_region(pw,top_x,top_y,bottom_x,bottom_y);
X      region_fix();
X      if (!(ROP = get_current_ROP()))
X	ROP = PIX_SRC;
X      pw_replrop(pw,top_x,top_y,bottom_x-top_x,bottom_y-top_y,PIX_COLOR(cur_color) | ROP,pattern[(int)panel_get_value(pattern_choice)],0,0);
X      reset_region();
X    }
X}
X
X
X/*
X * let the user lasso any free form region on the drawing area
X * and stuff that into the cut/paste buffer
X */
Xlaso_cut_paste()
X{
Xregister int i;
Xint no_points,npts[1];
X
X  top_x = image_wid;
X  top_y = image_hgt;
X  bottom_x = 0;
X  bottom_y = 0;
X
X  i=0;
X  while ((i<MAX_PTS) && (ptlist[i++].x != -1));
X  no_points = --i;
X  npts[0] = no_points; 
X
X  /*
X   * if the user booted with a '-l' option then clear the area in the lasso
X   * if not then just XOR the area in the lasso
X   */
X  if (!(int)panel_get(lasso_remove, PANEL_TOGGLE_VALUE,0))
X  {
X    pw_polygon_2(pw,0,0,1,npts,ptlist,PIX_XOR,pattern[0],0,0);
X    pw_polygon_2(pw,0,0,1,npts,ptlist,PIX_XOR,pattern[0],0,0);
X  }
X
X  for (i=0;i < no_points;i++)
X    {
X        top_x = MIN(top_x,ptlist[i].x);
X        top_y = MIN(top_y,ptlist[i].y);
X        bottom_x = MAX(bottom_x,ptlist[i].x);
X        bottom_y = MAX(bottom_y,ptlist[i].y);
X    	if (i>0)
X	    pw_vector(pw,ptlist[i].x,ptlist[i].y,
X    		     ptlist[i-1].x,ptlist[i-1].y,PIX_XOR,1);
X    }
X  for (i=0;i < no_points;i++)
X    {
X        ptlist[i].x -=top_x;
X        ptlist[i].y -=top_y;
X    }
X  MY_pr_destroy(cut_buffer_pr);
X  cut_buffer_pr = my_mem_create(bottom_x-top_x,bottom_y-top_y,image_depth);
X  pr_polygon_2(cut_buffer_pr,0,0,1,npts,ptlist,PIX_SRC,pw->pw_prretained,top_x,top_y);
X
X  if ((int)panel_get(lasso_remove, PANEL_TOGGLE_VALUE,0))
X  {
X    pw_polygon_2(pw,top_x,top_y,1,npts,ptlist,PIX_CLR,0,0,0);
X  }
X  reset_region();
X  print_msg("The selected area is now in the Cut/Paste buffer.");
X}
X
X
X/*
X * the user can lasso any area on the screen by just encircling the
X * object on the bitmap
X * we do this by remembering all of the points the mouse moved to
X * and make a polygon stencil from these points
X */
Xlaso_addpt(py_pts,x,y)
Xstruct pr_pos py_pts[];
Xint x,y;
X{
Xint found;
Xregister int i;
Xint npts[1];
X
X  found = FALSE;
X  i=0;
X  while ((i<MAX_PTS) && (!found))
X    {
X      if (py_pts[i++].x == -1)
X	found=TRUE;
X    }
X  i--;
X  npts[0] =i;
X        
X  py_pts[i].x = x;
X  py_pts[i].y = y;
X  if (i>0)
X    pw_vector(pw,py_pts[i].x,py_pts[i].y,py_pts[i-1].x,py_pts[i-1].y,PIX_XOR,1);
X  i++;
X  py_pts[i].x = 0-1;
X  py_pts[i].y = 0-1;
X}
X
X
X/*
X * add a point to the list of vetexs in the current polygon
X */
Xpoly_addpt(py_pts,x,y)
Xstruct pr_pos py_pts[];
Xint x,y;
X{
Xint found;
Xregister int i;
X
X  found =0;
X  i=0;
X  while (i<MAX_POLY && !found)
X    {
X      if (py_pts[i++].x == -1)
X	found=TRUE;
X    }
X  i--;
X       {
X         py_pts[i].x = x;
X         py_pts[i].y = y;
X	 i++;
X	 py_pts[i].x = 0-1;
X	 py_pts[i].y = 0-1;
X       }
X}
X
X
X/*
X * take the list of current vertexs and draw up the
X * the polygon and fill it with the current paint pattern
X */
Xdraw_poly(py_pts)
Xstruct pr_pos py_pts[];
X{
Xint npts[1];
Xint found,ROP;
Xregister int i;
X
X
X  if (py_pts[0].x == 0-1)
X	return;
X
X  found =0;
X  i=0;
X  while (i<MAX_POLY && !found)
X    {
X      if (py_pts[i++].x == -1)
X	found=TRUE;
X    }
X  i--;
X
X  npts[0] =i;
X
X  /*
X   * get the current ROP for drawing or default PIX_SRC
X   */
X  if (!(ROP = get_current_ROP()))
X	ROP = PIX_SRC;
X
X  /*
X   * erase the orginal vectors in the poly
X   */
X  {
X      i=1;
X      while (i<MAX_POLY && (py_pts[i].x != -1))
X        {
X    	pw_vector(pw,py_pts[i].x,py_pts[i].y,
X    		     py_pts[i-1].x,py_pts[i-1].y, PIX_XOR,1);
X    	i++;
X        }
X  }
X
X
X  /*
X   * do we want this baby filled ????
X   */ 
X  if ((int)panel_get_value(command_choice)==POLY_F)
X       {
X           if (!(ROP = get_current_ROP()))
X		ROP = PIX_SRC;
X
X	   pw_polygon_2(pw,0,0,1,npts,py_pts,PIX_COLOR(cur_color) | ROP,pattern[(int)panel_get_value(pattern_choice)],0,0);
X       }
X
X  /*
X   * do we want to wrap the polygon up in a vector border
X   * but if we on unfilled-poly then always do vectors
X   */
X  if (((int)panel_get_value(border_cycle)) || 
X	((int)panel_get_value(command_choice)==POLY_H))
X  {
X      i=1;
X      while (i<MAX_POLY && (py_pts[i].x != -1))
X        {
X    	pw_vector(pw,py_pts[i].x,py_pts[i].y,
X    		     py_pts[i-1].x,py_pts[i-1].y,PIX_COLOR(cur_color) | ROP,cur_color);
X    	i++;
X        }
X      i--;
X      pw_vector(pw,py_pts[i].x,py_pts[i].y,
X    		     py_pts[0].x,py_pts[0].y,PIX_COLOR(cur_color) | ROP,cur_color);
X  }
X  clean_poly();
X}
X
X
X/*
X * reset the vertex list for the current polygon
X */
Xclean_poly()
X{
X  poly_points[0].x = 0-1;
X  poly_points[0].y = 0-1;
X}
X
END_OF_drawing.c
if test 23040 -ne `wc -c <drawing.c`; then
    echo shar: \"drawing.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 5 \(of 7\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 6 7 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 7 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