[comp.sources.sun] v01i049: Touchup 2.5 - a Sunview bitmap graphics editor, Part07/07

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

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

#! /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 7 (of 7)."
# Contents:  magnify.c oval.c pattern.c touchup.c
# Wrapped by rayk@sboslab3 on Tue Aug 30 00:07:43 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f magnify.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"magnify.c\"
else
echo shar: Extracting \"magnify.c\" \(1789 characters\)
sed "s/^X//" >magnify.c <<'END_OF_magnify.c'
X#include "header.h"
X
X/*
X *  Magnifying glass		(for Sun-3 workstations)
X *
X *  Copyright 1986, 1987 by Scott Schwartz
X *  This program may be copied with the provision that this copyright 
X *  message remains, and that further distribution of this code and it's 
X *  derivatives is not subject to additional restrictions.
X * 
X *  Lots of changes, but no Copyright, by Mark Weiser.
X * 
X *  compile with -lsuntool -lsunwindow -lpixrect
X *
X */
X
X
X/* global vars */
Xstatic struct pixrect	*tmpdst=NULL;
X
X
Xquit_mag()
X{
X MY_pr_destroy(tmpdst);
X}
X
X
Xinit_mag()
X{
X MY_pr_destroy(tmpdst);
X tmpdst = my_mem_create(SCREEN_MAX_X, SCREEN_MAX_Y, image_depth);
X}
X
X
X/*
X * pw_mag copies a magnified view of spr to dpw using pixel replication.
X * the arguments are the same as those to the pw_rop library call, except
X * that magnification is passed instead of raster-op.
X */
Xvoid pw_mag(dpw, dx, dy, w, h, mag, spr, sx, sy)
X	Pixwin *dpw;	/* destination pixwin */
X	int dx, dy;  	/* destination x,y */
X	int w, h;	/* width and height of block to copy */
X	int mag; 	/* magnification */
X	struct pixrect *spr;	/* source pixrect */
X	int sx,sy;	/* location in source to copy from */
X{
X	/* locals */
X	register short jmax = h/mag + 1, imax = w/mag + 1;
X	register short x, y, delta;
X
X	struct pixrect r;	/* holds the size of the drawing region when */
X			/* gaining access to the screen */
X	r.pr_size.x = w;
X	r.pr_size.y = h;
X
X	for (x = 0; x < imax; x += 1) {
X		for (delta = 0; delta < mag; delta += 1) {
X			pr_rop(tmpdst, x*mag+delta, 0, 1, jmax, PIX_SRC|PIX_DONTCLIP, spr, sx+x, sy);
X		}
X	}
X	for (y = jmax; y >= 0; y -= 1) {
X		for (delta = 0; delta < mag; delta += 1) {
X			pr_rop(tmpdst, 0, y*mag+delta, w, 1, PIX_SRC|PIX_DONTCLIP, tmpdst, 0, y);
X		}
X	}
X
X	/* draw */
X	pw_rop(dpw, dx, dy, w, h, PIX_SRC, tmpdst, 0, 0);
X}
END_OF_magnify.c
if test 1789 -ne `wc -c <magnify.c`; then
    echo shar: \"magnify.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f oval.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"oval.c\"
else
echo shar: Extracting \"oval.c\" \(4144 characters\)
sed "s/^X//" >oval.c <<'END_OF_oval.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: oval.c
X	purpose: this file contain the functions that draw ovals
X
X	modifications:
X		date:	Tue Mar 22 22:04:58 EST 1988
X		author:	rayk
X		changes:add comments
X**************************************************************************/
X
X#include"header.h"
X
X
X/*
X * draw an oval by making the sides by vectors and ends by semicircles
X */
X     draw_oval(pw, center_x,center_y, curr_pos_x,curr_pos_y,ROP,flag)
X
X       Pixwin            *pw;
X       int		 center_x,center_y,curr_pos_x,curr_pos_y;
X       int                flag,ROP;
X   
X     {    
X       struct  pr_pos     center,
X                         curr_pos;
X        int             x, y, radius,
X			error, npts,
X		        h_width, h_height,
X			x_off, y_off;
X
X	center.x = center_x;
X	center.y = center_y;
X	curr_pos.x = curr_pos_x;
X	curr_pos.y = curr_pos_y;
X
X          h_width = abs(curr_pos.x - center.x);
X          h_height = abs(curr_pos.y - center.y);
X          radius = MIN(h_width, h_height);
X  
X         /*
X	  * draw line section of oval
X          */
X          if (radius == h_height)
X           { x_off = h_width-radius;   y_off = 0;
X             pw_vector(pw, center.x-x_off, center.y+radius,
X                       center.x+x_off, center.y+radius, ROP, cur_color);
X             pw_vector(pw, center.x-x_off, center.y-radius,
X                       center.x+x_off, center.y-radius, ROP, cur_color);
X           }
X          else
X           { x_off = 0;   y_off = h_height-radius;
X             pw_vector(pw, center.x-radius, center.y-y_off,
X                       center.x-radius, center.y+y_off, ROP, cur_color);
X             pw_vector(pw, center.x+radius, center.y-y_off,
X                       center.x+radius, center.y+y_off, ROP, cur_color);
X           }
X	   /*
X	    * draw rounded corners of oval
X	    */
X	   x = 0;  y = radius; npts = 0;
X	   error = 3 - (radius << 1);
X
X         while (x < y)
X         {
X           ptlist[npts].x=center.x+(x+x_off); ptlist[npts++].y=center.y+(y+y_off);
X           ptlist[npts].x=center.x-(x+x_off); ptlist[npts++].y=center.y+(y+y_off);
X           ptlist[npts].x=center.x+(x+x_off); ptlist[npts++].y=center.y-(y+y_off);
X           ptlist[npts].x=center.x-(x+x_off); ptlist[npts++].y=center.y-(y+y_off);
X           ptlist[npts].x=center.x+(y+x_off); ptlist[npts++].y=center.y+(x+y_off);
X           ptlist[npts].x=center.x-(y+x_off); ptlist[npts++].y=center.y+(x+y_off);
X           ptlist[npts].x=center.x+(y+x_off); ptlist[npts++].y=center.y-(x+y_off);
X           ptlist[npts].x=center.x-(y+x_off); ptlist[npts++].y=center.y-(x+y_off);
X             
X           if (error < 0)
X              error = error + (x << 2) + 6;
X           else
X              error = error + ((x-y--) << 2) + 10;
X           x++;
X          }  /* end of while (x , y) */
X 
X          if (x == y)
X          {
X           ptlist[npts].x=center.x+(x+x_off); ptlist[npts++].y=center.y+(y+y_off);
X           ptlist[npts].x=center.x-(x+x_off); ptlist[npts++].y=center.y+(y+y_off);
X           ptlist[npts].x=center.x+(x+x_off); ptlist[npts++].y=center.y-(y+y_off);
X           ptlist[npts].x=center.x-(x+x_off); ptlist[npts++].y=center.y-(y+y_off);
X          }
X          if (flag)
X		my_pw_polypoint(0,0,npts,ptlist,ROP);
X}  /* end of function draw_oval() */
X
END_OF_oval.c
if test 4144 -ne `wc -c <oval.c`; then
    echo shar: \"oval.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f pattern.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"pattern.c\"
else
echo shar: Extracting \"pattern.c\" \(6279 characters\)
sed "s/^X//" >pattern.c <<'END_OF_pattern.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: pattern.c
X	purpose: this file has all of the paint patterns
X
X	modifications:
X		date:	Tue Mar 22 22:04:58 EST 1988
X		author:	rayk
X		changes:add comments
X**************************************************************************/
X
X#include <pixrect/pixrect_hs.h>
X
X
Xstatic short pattern1_data[] = {
X#include "pattern1.icon.pat"
X};
Xstatic mpr_static(pattern1_pr, 32, 32, 1, pattern1_data);
X
Xstatic short pattern2_data[] = {
X#include "pattern2.icon.pat"
X};
Xstatic mpr_static(pattern2_pr, 32, 32, 1, pattern2_data);
X
Xstatic short pattern3_data[] = {
X#include "pattern3.icon.pat"
X};
Xstatic mpr_static(pattern3_pr, 32, 32, 1, pattern3_data);
X
Xstatic short pattern4_data[] = {
X#include "pattern4.icon.pat"
X};
Xstatic mpr_static(pattern4_pr, 32, 32, 1, pattern4_data);
X
Xstatic short pattern5_data[] = {
X#include "pattern5.icon.pat"
X};
Xstatic mpr_static(pattern5_pr, 32, 32, 1, pattern5_data);
X
Xstatic short pattern6_data[] = {
X#include "pattern6.icon.pat"
X};
Xstatic mpr_static(pattern6_pr, 32, 32, 1, pattern6_data);
X
Xstatic short pattern7_data[] = {
X#include "pattern7.icon.pat"
X};
Xstatic mpr_static(pattern7_pr, 32, 32, 1, pattern7_data);
X
Xstatic short pattern8_data[] = {
X#include "pattern8.icon.pat"
X};
Xstatic mpr_static(pattern8_pr, 32, 32, 1, pattern8_data);
X
Xstatic short pattern9_data[] = {
X#include "pattern9.icon.pat"
X};
Xstatic mpr_static(pattern9_pr, 32, 32, 1, pattern9_data);
X
Xstatic short pattern10_data[] = {
X#include "pattern10.icon.pat"
X};
Xstatic mpr_static(pattern10_pr, 32, 32, 1, pattern10_data);
X
Xstatic short pattern11_data[] = {
X#include "pattern11.icon.pat"
X};
Xstatic mpr_static(pattern11_pr, 32, 32, 1, pattern11_data);
X
Xstatic short pattern12_data[] = {
X#include "pattern12.icon.pat"
X};
Xstatic mpr_static(pattern12_pr, 32, 32, 1, pattern12_data);
X
Xstatic short pattern13_data[] = {
X#include "pattern13.icon.pat"
X};
Xstatic mpr_static(pattern13_pr, 32, 32, 1, pattern13_data);
X
Xstatic short pattern14_data[] = {
X#include "pattern14.icon.pat"
X};
Xstatic mpr_static(pattern14_pr, 32, 32, 1, pattern14_data);
X
Xstatic short pattern15_data[] = {
X#include "pattern15.icon.pat"
X};
Xstatic mpr_static(pattern15_pr, 32, 32, 1, pattern15_data);
X
Xstatic short pattern16_data[] = {
X#include "pattern16.icon.pat"
X};
Xstatic mpr_static(pattern16_pr, 32, 32, 1, pattern16_data);
X
Xstatic short pattern17_data[] = {
X#include "pattern17.icon.pat"
X};
Xstatic mpr_static(pattern17_pr, 32, 32, 1, pattern17_data);
X
Xstatic short pattern18_data[] = {
X#include "pattern18.icon.pat"
X};
Xstatic mpr_static(pattern18_pr, 32, 32, 1, pattern18_data);
X
Xstatic short pattern19_data[] = {
X#include "pattern19.icon.pat"
X};
Xstatic mpr_static(pattern19_pr, 32, 32, 1, pattern19_data);
X
Xstatic short pattern20_data[] = {
X#include "pattern20.icon.pat"
X};
Xstatic mpr_static(pattern20_pr, 32, 32, 1, pattern20_data);
X
Xstatic short pattern21_data[] = {
X#include "pattern21.icon.pat"
X};
Xstatic mpr_static(pattern21_pr, 32, 32, 1, pattern21_data);
X
Xstatic short pattern22_data[] = {
X#include "pattern22.icon.pat"
X};
Xstatic mpr_static(pattern22_pr, 32, 32, 1, pattern22_data);
X
Xstatic short pattern23_data[] = {
X#include "pattern23.icon.pat"
X};
Xstatic mpr_static(pattern23_pr, 32, 32, 1, pattern23_data);
X
Xstatic short pattern24_data[] = {
X#include "pattern24.icon.pat"
X};
Xstatic mpr_static(pattern24_pr, 32, 32, 1, pattern24_data);
X
Xstatic short pattern25_data[] = {
X#include "pattern25.icon.pat"
X};
Xstatic mpr_static(pattern25_pr, 32, 32, 1, pattern25_data);
X
Xstatic short pattern26_data[] = {
X#include "pattern26.icon.pat"
X};
Xstatic mpr_static(pattern26_pr, 32, 32, 1, pattern26_data);
X
Xstatic short pattern27_data[] = {
X#include "pattern27.icon.pat"
X};
Xstatic mpr_static(pattern27_pr, 32, 32, 1, pattern27_data);
X
Xstatic short pattern28_data[] = {
X#include "pattern28.icon.pat"
X};
Xstatic mpr_static(pattern28_pr, 32, 32, 1, pattern28_data);
X
Xstatic short pattern29_data[] = {
X#include "pattern29.icon.pat"
X};
Xstatic mpr_static(pattern29_pr, 32, 32, 1, pattern29_data);
X
Xstatic short pattern30_data[] = {
X#include "pattern30.icon.pat"
X};
Xstatic mpr_static(pattern30_pr, 32, 32, 1, pattern30_data);
X
Xstatic short pattern31_data[] = {
X#include "pattern31.icon.pat"
X};
Xstatic mpr_static(pattern31_pr, 32, 32, 1, pattern31_data);
X
Xstatic short pattern32_data[] = {
X#include "pattern32.icon.pat"
X};
Xstatic mpr_static(pattern32_pr, 32, 32, 1, pattern32_data);
X
Xstatic short pattern33_data[] = {
X#include "pattern33.icon.pat"
X};
Xstatic mpr_static(pattern33_pr, 32, 32, 1, pattern33_data);
X
Xstatic short pattern34_data[] = {
X#include "pattern34.icon.pat"
X};
Xstatic mpr_static(pattern34_pr, 32, 32, 1, pattern34_data);
X
Xstatic short pattern35_data[] = {
X#include "pattern35.icon.pat"
X};
Xstatic mpr_static(pattern35_pr, 32, 32, 1, pattern35_data);
X
Xstatic short pattern36_data[] = {
X#include "pattern36.icon.pat"
X};
Xstatic mpr_static(pattern36_pr, 32, 32, 1, pattern36_data);
X
Xstatic short pattern37_data[] = {
X#include "pattern37.icon.pat"
X};
Xstatic mpr_static(pattern37_pr, 32, 32, 1, pattern37_data);
X
Xstatic short pattern38_data[] = {
X#include "pattern38.icon.pat"
X};
Xstatic mpr_static(pattern38_pr, 32, 32, 1, pattern38_data);
X
Xstatic short pattern39_data[] = {
X#include "pattern39.icon.pat"
X};
Xstatic mpr_static(pattern39_pr, 32, 32, 1, pattern39_data);
X
Xstatic short pattern40_data[] = {
X#include "pattern40.icon.pat"
X};
Xstatic mpr_static(pattern40_pr, 32, 32, 1, pattern40_data);
X
X
END_OF_pattern.c
if test 6279 -ne `wc -c <pattern.c`; then
    echo shar: \"pattern.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f touchup.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"touchup.c\"
else
echo shar: Extracting \"touchup.c\" \(33970 characters\)
sed "s/^X//" >touchup.c <<'END_OF_touchup.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: touchup.c
X	purpose: this file has misc functions that do different crap
X		but mostly the event handler for the main drawing
X		area
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 00:33:52 EDT 1988
X		author:	rayk
X		changes:added user definable ROPs and default ROPs
X
X		date:	Tue Apr 19 21:45:52 EDT 1988
X		author:	rayk
X		changes:added LOC_TRAJECTORY for paint command so that
X			it does not skip that much when you move the cursor
X			quickly
X
X		date:	Thu Apr 21 20:14:58 EDT 1988
X		author:	rayk
X		changes:change the interface to text, so that you can
X			drag the text
X
X		date:	Thu Apr 25 3:02:23  EDT 1988
X		author:	rainbow
X		changes:made "undo" so that it toggle between buffers
X
X		date:	Mon May  2 22:18:11 EDT 1988
X		author:	rayk
X		changes:corrected a bug of not setting the correct
X			colormap fields on boot up, bug noted by:
X			   mcgill-vision!amadeus!gamin
X
X		date:	Fri Jun  3 22:13:11 EDT 1988
X		author:	rayk
X		changes:corrected a bug of returning the pointer
X			to a pixrect in my_mem_create, bug noted by:
X			   weiser.pa@Xerox.com
X			
X		date:	Wed Jun 15 22:04:25 EDT 1988
X		author:	juang@aloft.att.com
X		changes:fixed SunView command line arguments that
X			are passsed to the base frame
X
X		date:	Fri Jun 24 16:12:53 EDT 1988
X		author:	rayk  (suggested by mesard@WILMA.BBN.COM)
X		changes:fixed PENCIL command so that it would draw
X			continious lines instead of single points
X
X		date:	Tue Jun 28 12:34:29 EDT 1988
X		author:	rainier!pell@uunet.UU.NET
X		changes:corrected a declaration error for old_x ....
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:	Mon Jul  4 22:45:44 EDT 1988
X		author:	rayk
X		changes:added a new command line option to toggle if the
X			window foreground and background color will ALWAYS
X			be used, i.e. even if the colormap says different
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 19:20:26 MET 1988
X		author: pell@rainier.se
X		changes:added support for cursor switching
X
X		date:   Fri Jul 22 12:54:58 EDT 1988
X		author: rayk
X		changes:added a Black & White mode for mono bitmap editing
X			on color Suns
X
X		date:   Sun Jul 24 12:47:33 EDT 1988
X		author: rainbow
X		changes:fixed moving box so that looks like it snakes around
X			the corners.
X
X**************************************************************************/
X
Xextern int cur_text_x,cur_text_y,org_text_x, text_cursor;
Xextern char cur_text_str[];
X#include "header.h"
X
Xunsigned char red[256],green[256],blue[256];
Xint image_wid=DEFAULT_IMAGE_WID, image_hgt=DEFAULT_IMAGE_HGT,image_depth=1;
Xint top_x=0,top_y=0,bottom_x=0,bottom_y=0;
Xint cur_color=1,grid_size=0;
Xint magnify_fac=8,fat_x,fat_y,fat_source_x=0-1,fat_source_y=0-1;
Xint mouse_left=PAINT,undo_flag=TRUE;
Xint select_pt_x=0-1,select_pt_y=0-1;
Xint old_x=0, old_y=0;
Xint start_x=0, start_y=0;
Xint fore_back_flag=FALSE;
Xchar file_name[MAX_FILE_NAME];
Xstruct pixrect *cut_buffer_pr=NULL,
X		*undo_pr=NULL;
Xstruct singlecolor fore_ground,back_ground;
Xint paint_brush=3,line_brush=2,rec_brush=1;
X
Xstruct pixfont *main_font=NULL;
Xint box_off=0;
Xint run_box=FALSE;
Xint BW_mode=FALSE;
X
Xextern Notify_error notify_dispatch();
Xstatic Notify_value notice_destroy_event();
X
X
X/*
X * this event proc will resize the canvas the size given in
X * width_text and height_text, in the EXPERT command panel
X */
Xresize_canvas()
X{
Xint width, height;
X
X  width = atoi((char*)panel_get_value(width_text));
X  height = atoi((char*)panel_get_value(height_text));
X
X  if ((width > 0) &&
X     (height > 0) &&
X     (width < 10000) &&
X     (height < 10000))
X  {
X	image_wid = width;
X	image_hgt = height;
X        (void)window_set(canvas,
X	  	CANVAS_WIDTH,		image_wid,
X	    	CANVAS_HEIGHT,		image_hgt,
X	    	0);
X	if (undo_flag)
X	  {
X	     MY_pr_destroy(undo_pr);
X	     undo_pr = my_mem_create(image_wid,image_hgt,image_depth);
X	  }
X  }
X  else
X 	ERROR("Bad canvas size, either too small or too large");
X}
X
X
X/*
X * Get_ROP: this function will get the check user specified bitmap OP
X * sot that we know how to paint the new objects on to the bitmap
X */
Xint get_current_ROP()
X{
X  switch((int)panel_get_value(ROP_cycle)) {
X     case 0 : return(0);
X     case 1 : return(PIX_XOR);
X     case 2 : return(PIX_SRC & PIX_DST);
X     case 3 : return(PIX_SRC | PIX_DST);
X     case 4 : return(PIX_SRC);
X  }
X  return(0);
X}
X
X
X/*
X * When the brush size is changed this function will update the
X * correct brush storage, depending on what mode you were in
X */
Xchange_brush()
X{
X  switch((int)panel_get_value(command_choice)) {
X    case PAINT:
X	paint_brush = (int)panel_get_value(brush_choice);
X	break;
X    case LINE:
X	line_brush = (int)panel_get_value(brush_choice);
X	break;
X    case RECT_H:
X	rec_brush = (int)panel_get_value(brush_choice);
X	break;
X  }
X}
X
X
X
X/*
X * this is the event handler for the special cut/paste command menu
X */
Xregion_handle()
X{
X    switch((int)panel_get_value(region_choice)) {
X	case CUT:
X		cut_region();
X			break;
X	case COPY:
X		print_msg("Region copied to Cut/Paste buffer. Hold down the RIGHT mouse button to drag the object.");
X		panel_set(region_choice,PANEL_VALUE,MOVE,0);
X		copy_region();
X			break;
X	case FLIP_HOR:
X		flip_hor_region();
X			break;
X	case FLIP_VER:
X		flip_ver_region();
X			break;
X	case ROTATE:
X		rotate_region();
X			break;
X	case INVERSE:
X		inverse_region();
X			break;
X	case PASTE:
X                paste_region();
X			break;
X	case MOVE:
X		print_msg("Hold down the RIGHT mouse button and drag the object.");
X			break;
X	case SCALE:
X		scale_region();
X                        break;
X    }
X
X}
X
X
X/*
X * this is the event handler for the main comand menu
X */
Xcommand_handle(item, event)
XPanel_item      item;
XEvent           *event;
X{
X  hide_msg();
X  if ((int)panel_get_value(command_choice) != GET_PT)
X	{
X	  (void)window_set(region_panel, WIN_SHOW, FALSE, 0);
X	  panel_set(region_choice,PANEL_VALUE,PASTE,0);
X	}
X  (void)window_set(brush_panel, WIN_SHOW, FALSE, 0);
X  (void)window_set(text_panel, WIN_SHOW, FALSE, 0);
X  finish_text();
X
X    switch((int)panel_get_value(command_choice)) {
X	case TEXT:
X		  cur_text_str[0] = '\0';
X		  print_msg("Press the LEFT mouse button to pick text position, then type.");
X		  (void)window_set(text_panel, WIN_SHOW, TRUE, 0);
X
X#ifdef CHANGE_CURSOR
X		  change_cursor(canvas, text_cur);
X#endif
X		  mouse_parms();
X			break;
X	case LASO:
X		  print_msg("Hold down the LEFT mouse button and encircle a object.");
X#ifdef CHANGE_CURSOR
X		  change_cursor(canvas, laso_cur);
X#endif
X		  mouse_parms();
X			break;
X	case CIRCLE:
X		  print_msg("Hold down the LEFT mouse button and extend to radius of the circle.");
X#ifdef CHANGE_CURSOR
X		  change_cursor(canvas, old_cur);
X#endif
X		  mouse_parms();
X			break;
X	case DRAW:
X		  print_msg("Press the LEFT mouse button to DRAW.");
X#ifdef CHANGE_CURSOR
X		  change_cursor(canvas, draw_cur);
X#endif
X		  mouse_parms();
X			break;
X	case LINE:
X		  print_msg("Hold down the LEFT mouse button and extend to end of the line.");
X		  panel_set(brush_choice,PANEL_VALUE, line_brush,0);
X		  (void)window_set(brush_panel, WIN_SHOW, TRUE, 0);
X#ifdef CHANGE_CURSOR
X		  change_cursor(canvas, old_cur);
X#endif
X		  mouse_parms();
X			break;
X	case MAGNIFY:
X		  print_msg("Use LEFT button to draw, hold down MIDDLE button to move.");
X#ifdef CHANGE_CURSOR
X		  change_cursor(canvas, old_cur);
X#endif
X		  fat_mode();
X			break;
X	case FFILL:
X		  fill_mode();
X  		  panel_set(command_choice,PANEL_VALUE, GET_PT,0);
X		  mouse_parms();
X			break;
X	case OVAL:
X   		  print_msg("Hold down the LEFT mouse button and extend to edge of the oval.");
X#ifdef CHANGE_CURSOR
X		  change_cursor(canvas, old_cur);
X#endif
X		  mouse_parms();
X			break;
X	case POLY_F:
X	case POLY_H:
X		  print_msg("Press the LEFT mouse button to select a vertex.");
X#ifdef CHANGE_CURSOR
X		  change_cursor(canvas, old_cur);
X#endif
X		  mouse_parms();
X			break;
X	case RECT_H:
X		  panel_set(brush_choice,PANEL_VALUE, rec_brush,0);
X		  (void)window_set(brush_panel, WIN_SHOW, TRUE, 0);
X	case RECT_F:
X		  print_msg("Hold down the LEFT mouse button and extend to the opposite corner.");
X#ifdef CHANGE_CURSOR
X		  change_cursor(canvas, old_cur);
X#endif
X		  mouse_parms();
X			break;
X	case PAINT:
X		  print_msg("Press the LEFT mouse button to PAINT.");
X		  mouse_parms();
X#ifdef CHANGE_CURSOR
X		  change_cursor(canvas, paint_cur);
X#endif
X		  panel_set(brush_choice,PANEL_VALUE, paint_brush,0);
X		  (void)window_set(brush_panel, WIN_SHOW, TRUE, 0);
X			break;
X	case SEL_REG:
X		  print_msg("Hold down the LEFT mouse button and extend to the opposite corner.");
X#ifdef CHANGE_CURSOR
X		  change_cursor(canvas, old_cur);
X#endif
X		  if (mouse_left == SEL_REG)
X		    {
X		      clean_region();
X		      top_x = 0;
X		      top_y = 0;
X	    	      bottom_x = image_wid;
X		      bottom_y = image_hgt;
X		      move_box(CLEAR);
X		      run_box = TRUE;
X		      start_region();
X		      print_msg("Entire drawing area is now selected.");
X		    }
X		  else
X		    {
X		      mouse_parms();
X		    }
X		  (void)window_set(region_panel, WIN_SHOW, TRUE, 0);
X		  break;
X	case GET_PT:
X		  print_msg("Press the LEFT mouse button to select a point.");
X#ifdef CHANGE_CURSOR
X		  change_cursor(canvas, sel_point_cur);
X#endif
X		  mouse_parms();
X			break;
X	case ERASE:
X		  print_msg("Press the LEFT MOUSE button to ERASE.");
X		  if ((mouse_left == ERASE) &&  (confirm("Erase entire drawing area ?")))
X		    {
X		    clear_screen();
X		    }
X		  else
X                    if (top_x || top_y || bottom_x || bottom_y)
X        	    {
X		     move_box(CLEAR);
X		     start_region();
X  		     region_fix();
X  	  	     pw_rop(pw,top_x,top_y,bottom_x-top_x,bottom_y-top_y,PIX_SRC,0,0,0);
X		     move_box(CLEAR);
X		     panel_set(command_choice,PANEL_VALUE,SEL_REG,0);
X		     (void)window_set(region_panel, WIN_SHOW, TRUE, 0);
X		     return;
X        	    }
X#ifdef CHANGE_CURSOR
X		  change_cursor(canvas, erase_cur);
X#endif
X		  mouse_parms();
X			break;
X
X    }
X
X}     
X
X
Xclear_text_cursor()
X{
Xstruct pr_size text_wid;
X
X  if (cur_text_str[0]) 
X   {	 
X    text_wid = pf_textwidth(strlen(cur_text_str),
X	real_font,cur_text_str);
X    pw_replrop(pw,cur_text_x+ text_wid.x ,cur_text_y- TEXT_HGT,
X	1,TEXT_HGT, PIX_XOR, pattern[0],0,0);
X   }
X  else if (text_cursor) 
X   {	 
X    pw_replrop(pw,cur_text_x,cur_text_y- TEXT_HGT,
X	1,TEXT_HGT, PIX_XOR, pattern[0],0,0);
X   }
X}
X
X
X/*
X * save the screen to a temp bitmap for the undo command
X */
Xsave_screen()
X{
Xstruct pr_size text_wid;
X
X  if (undo_flag)
X  {
X    if (undo_pr == NULL)
X  	undo_pr =my_mem_create(image_wid,image_hgt,image_depth);
X
X    clear_text_cursor();
X    pr_rop(undo_pr,0,0,image_wid,image_hgt,PIX_SRC,pw->pw_prretained,0,0);
X    clear_text_cursor();
X  }
X}     
X
X
X/*
X * go back to the last saved bitmap
X */
Xundo_screen()
X{
X  if (undo_flag)
X  {
X    clean_region();
X    clean_point();
X    clean_poly();
X    finish_text();
X    fat_done();
X    pw_batch_on(pw);
X    pr_swap(pw,undo_pr);
X    pw_batch_off(pw);
X  }
X}     
X
X
X/*
X * this function was written by rainbow@sbcs.sunysb.edu (Hong Min)
X *
X * this function will swap the pixrect "pr2" with the pixwin "pw" by
X * coping 25 lines at a time. This is needed so that full size color
X * pixwins (1 meg of memory) can be exchanged with out the need of
X * a third buffer
X */
Xpr_swap(pw, pr2)
X	Pixwin		 *pw;
X	struct pixrect	 *pr2;
X{
X	struct pixrect		*buf;
X	int 	i, start, loop, rem, width, height, buf_size;
X
X	width = pr2->pr_size.x;
X	height = pr2->pr_size.y;
X	buf_size = 25;
X
X	buf = my_mem_create(width, buf_size, image_depth);
X	loop = height / buf_size;
X	rem = height % buf_size;
X	
X	for(i=0; i<loop; i++)
X	{
X	   pr_rop(buf, 0, 0, width, buf_size, PIX_SRC, pw->pw_prretained, 0, i*buf_size);
X	   pw_rop(pw, 0, i*buf_size, width, buf_size, PIX_SRC, pr2, 0, i*buf_size);
X	   pr_rop(pr2, 0, i*buf_size, width, buf_size, PIX_SRC, buf, 0, 0);
X	}
X
X	if (rem != 0)
X	{
X	   start = (loop-1)*buf_size;
X	   pr_rop(buf, 0, 0, width, rem, PIX_SRC, pw->pw_prretained, 0, start);
X	   pw_rop(pw, 0, start, width, rem, PIX_SRC, pr2, 0, start);
X	   pr_rop(pr2, 0, start, width, rem, PIX_SRC, buf, 0, 0);
X	}
X	MY_pr_destroy(buf);
X}
X
X
X/*
X * clear the drawing area
X */
Xclear_screen()
X{
X  clean_point();
X  clean_region();
X  finish_text();
X  fat_done();
X  save_screen();
X  pw_write( pw,0,0,1280,1280,PIX_SRC,0,0,0);
X  pw_write( fat_pw,0,0,1280,1280,PIX_SRC,0,0,0);
X}
X
X
X/*
X * if there is a region that is select the deselect it
X */
Xclean_region()
X{
X  if (top_x || top_y || bottom_x || bottom_y)
X    {
X     move_box(CLEAR);
X     run_box=FALSE;
X     start_region();
X     reset_region();
X    }
X}
X
X
X/*
X * if there is a point that is selected then deselecte it
X */
Xclean_point()
X{
X  if (select_pt_x != -1)
X    {
X     select_point(select_pt_x,select_pt_y);
X     select_pt_x = -1;
X     select_pt_y = -1;
X    }
X}
X
X
X/*
X * deselect any points and regions and get the current command mode
X */
Xmouse_parms()
X{
X  clean_point();
X  clean_region();
X  fat_done();
X  mouse_left = (int)panel_get_value(command_choice);
X}
X
X
X/*
X * set it to select a point mode
X */
Xset_select_mode()
X{
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_parms();
X}
X
X
X
Xint first_time=TRUE;
X
X/*
X * this the main event handler that makes the whole thing go
X * this event handle is for that canvas that is the main drawing area
X */
Xhandle_event(canvas_local, event)
XCanvas  canvas_local;
XEvent   *event;
X{
X    Pixwin      *pw     = canvas_pixwin(canvas_local);
Xstatic int ROP;
X
X
X    if (grid_size)
X     {
X	event_set_x(event,event_x(event) + grid_size/2 - (event_x(event)%grid_size));
X        event_set_y(event,event_y(event) + grid_size/2 - (event_y(event)%grid_size));
X     }
X
X    if (event_is_ascii(event))
X	{
X	  if ((mouse_left != TEXT) || (!text_cursor))
X		return;
X	  else
X	    {
X	  	new_draw_text(event);
X		return;
X	    }
X	}
X
X
X    if (event_is_up(event))
X	{
X   	 if (event_id(event) == MS_LEFT)
X		{
X		switch(mouse_left) {
X		case RECT_H :
X		case RECT_F :
X		   draw_rectangle(start_x,start_y,event_x(event), event_y(event));
X		   break;
X
X		case LINE :
X		   if (!(ROP = get_current_ROP()))
X			ROP = PIX_SRC;
X		   draw_line(start_x,start_y,event_x(event), event_y(event),PIX_XOR,1);
X		   draw_thick_line(start_x,start_y,event_x(event),
X			   event_y(event),ROP,cur_color,
X			   brush_radius[(int)panel_get_value(brush_choice)]);
X		   break;
X
X		case ERASE :
X	               select_region(pw,old_x,old_y,old_x+CURSOR_SIZE,old_y+CURSOR_SIZE);
X		   break;
X
X		case CIRCLE :
X		   if (!(ROP = get_current_ROP()))
X			ROP = PIX_SRC;
X 		   draw_line(start_x,start_y,old_x,old_y,PIX_XOR,1);
X		   draw_circle(start_x,start_y,distance(old_x,old_y,start_x,start_y),ROP);
X		   break;
X
X		case OVAL :
X		   if (!(ROP = get_current_ROP()))
X			ROP = PIX_SRC;
X		   if (ROP == (PIX_XOR))
X		        draw_oval(pw,start_x,start_y,old_x,old_y,ROP,FALSE);
X		   draw_oval(pw,start_x,start_y,old_x,old_y,ROP,TRUE);
X		   break;
X
X		case GET_PT :
X  		   select_pt_x = event_x(event);
X		   select_pt_y = event_y(event);
X		   break;
X
X		case LASO :
X		   laso_cut_paste();
X		   panel_set(region_choice,PANEL_VALUE,MOVE,0);
X		   panel_set(command_choice,PANEL_VALUE,SEL_REG,0);
X#ifdef CHANGE_CURSOR
X		  change_cursor(canvas, old_cur);
X#endif
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		   break;
X
X		case TEXT :
X		   finish_text();
X		   text_cursor = TRUE;
X		   org_text_x = cur_text_x = event_x(event);
X		   cur_text_y = event_y(event);
X		   cur_text_str[0] = '\0';
X		   pw_replrop(pw,cur_text_x,cur_text_y-TEXT_HGT,1,TEXT_HGT, PIX_XOR, pattern[0],0,0);
X		   break;
X
X		}
X                if (fat_source_x != -1)
X                   fat_update(0,0);
X	      }
X   	 if (event_id(event) == MS_RIGHT)
X		{
X                  if (((int)panel_get_value(region_choice) == MOVE) && (cut_buffer_pr != NULL))
X			{
X		         if (!(ROP = get_current_ROP()))
X				ROP = PIX_SRC | PIX_DST;
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		       pw_write(pw,event_x(event)-cut_buffer_pr->pr_size.x/2,
X				   event_y(event)-cut_buffer_pr->pr_size.y/2,
X				 cut_buffer_pr->pr_size.x,
X				 cut_buffer_pr->pr_size.y,
X				 ROP, cut_buffer_pr,0,0);
X			}
X		}
X         return;
X	}
X    switch (event_id(event)) {
X	 case MS_LEFT:
X
X  		first_time = FALSE;
X
X		if ((mouse_left != POLY_H) && (mouse_left != POLY_F)
X		     && (mouse_left != GET_PT) && (mouse_left != SEL_REG))
X			save_screen();
X		old_x = event_x(event);
X		old_y = event_y(event);
X		start_x = old_x;
X		start_y = old_y;
X		switch(mouse_left) {
X
X		case LINE:
X			   draw_line(old_x,old_y,start_x,start_y,PIX_XOR,1);
X			   break;
X		case POLY_F:
X		case POLY_H:
X			   if (poly_points[0].x == -1)
X				save_screen();			
X			   poly_addpt(poly_points,start_x,start_y);
X			   print_msg("Press the LEFT button to select a vertex or press the RIGHT mouse button to end the polygon.");
X			   break;
X		case DRAW:
X			   draw_point(pw,event_x(event), event_y(event));
X			   if (!(ROP = get_current_ROP()))
X			       ROP = PIX_SRC;			   
X			   break;
X		case PAINT:
X			   draw_brush(pw, event_x(event), event_y(event));
X			   break;
X		case ERASE:
X			   old_x = event_x(event)-CURSOR_SIZE/2; old_y= event_y(event)-CURSOR_SIZE/2;
X			   select_region(pw,old_x,old_y,old_x+CURSOR_SIZE,old_y+CURSOR_SIZE);
X			   erase_brush(pw, event_x(event), event_y(event));
X			   break;
X		case CIRCLE:
X 		           draw_line(start_x,start_y,old_x,old_y,PIX_XOR,1);
X			   break;
X		case OVAL:
X		           draw_oval(pw,start_x,start_y,old_x,old_y,PIX_XOR,FALSE);
X			   break;
X		case GET_PT:
X  		   	   if (select_pt_x != -1)
X  			      select_point(select_pt_x,select_pt_y);
X    		   	   old_x = event_x(event);
X  		           old_y = event_y(event);
X  		           select_point(old_x,old_y);
X			   break;
X
X		case SEL_REG:
X		  	   if (top_x || top_y || bottom_x || bottom_y)
X				move_box(CLEAR);
X			   save_screen();
X  	          	   top_x = event_x(event);
X		 	   top_y = event_y(event);
X  	          	   bottom_x = event_x(event);
X		 	   bottom_y = event_y(event);
X			   pw_batch_on(pw);
X			   move_box(CLEAR);
X			   pw_batch_off(pw);
X			   run_box = TRUE;
X	 	 	   start_region();
X			   break;
X		case LASO:
X			   ptlist[0].x = -1;
X			   ptlist[0].y = -1;
X			   laso_addpt(ptlist,start_x,start_y);
X			   break;
X		}
X
X		break;
X
X          case MS_MIDDLE:
X
X		if (event_shift_is_down(event) != FALSE)
X		    {
X			undo_screen();
X			break;
X		    }
X		switch(mouse_left) {
X		case SEL_REG:
X			if (top_x || top_y || bottom_x || bottom_y)
X			{
X			  pw_batch_on(pw);
X			  move_box(CLEAR);
X  	        	  bottom_x = event_x(event);
X			  bottom_y = event_y(event);
X			  move_box(CLEAR);
X			  pw_batch_off(pw);
X			}
X			break;
X		}	  
X		break;
X          case MS_RIGHT:
X
X		if (((mouse_left==POLY_F) || (mouse_left ==POLY_H))
X		   && (poly_points[0].x != -1))
X		 {
X			   poly_addpt(poly_points,event_x(event),event_y(event));
X			   draw_poly(poly_points);
X		 }
X                if (((int)panel_get_value(region_choice) == MOVE) && (cut_buffer_pr != NULL))
X			{
X			clean_region();
X			clean_point();
X			save_screen();
X			old_x = event_x(event);
X			old_y = event_y(event);
X			start_x = old_x;
X			start_y = old_y;
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		break;
X          case LOC_DRAG:
X            if (window_get(canvas_local, WIN_EVENT_STATE, MS_LEFT))
X		{
X		if (first_time)
X		{
X		  first_time = FALSE;
X		  old_x = event_x(event);
X		  old_y = event_y(event);
X		  return;
X		}
X		switch(mouse_left) {
X		case PAINT:
X			draw_con_brush(pw, event_x(event), event_y(event),old_x,old_y);
X			old_x = event_x(event);
X			old_y = event_y(event);
X			break;
X		case DRAW:
X			pw_vector(pw,old_x,old_y,event_x(event), event_y(event),ROP,cur_color);
X			old_x = event_x(event);
X			old_y = event_y(event);
X			break;
X		case ERASE :
X			erase_brush(pw, event_x(event), event_y(event));
X			break;
X		case LINE:
X			   pw_batch_on(pw);
X			   draw_line(old_x,old_y,start_x,start_y,PIX_XOR,1);
X  			   old_x = event_x(event);
X			   old_y = event_y(event);
X			   draw_line(old_x,old_y,start_x,start_y,PIX_XOR,1);
X			   pw_batch_off(pw);
X			break;
X		case RECT_F :
X		case RECT_H :
X			   pw_batch_on(pw);
X			   select_region(pw,old_x,old_y,start_x,start_y);
X	  		   old_x = event_x(event);
X			   old_y = event_y(event);
X			   select_region(pw,old_x,old_y,start_x,start_y);
X			   pw_batch_off(pw);
X			break;
X		case CIRCLE:
X			   draw_line(old_x,old_y,start_x,start_y,PIX_XOR,1);
X	  		   old_x = event_x(event);
X			   old_y = event_y(event);
X			   draw_line(old_x,old_y,start_x,start_y,PIX_XOR,1);
X			break;
X		case OVAL:
X			   pw_batch_on(pw);
X			   draw_oval(pw,start_x,start_y,old_x,old_y,PIX_XOR,FALSE);
X	  		   old_x = event_x(event);
X			   old_y = event_y(event);
X			   draw_oval(pw,start_x,start_y,old_x,old_y,PIX_XOR,FALSE);
X			   pw_batch_off(pw);
X			break;
X		case GET_PT:
X			   select_point(old_x,old_y);
X  		   	   select_pt_x = event_x(event);
X		   	   select_pt_y = event_y(event);
X	  		   old_x = event_x(event);
X			   old_y = event_y(event);
X			   select_point(old_x,old_y);
X			break;
X		case SEL_REG:
X			  pw_batch_on(pw);
X			  move_box(CLEAR);
X  	        	  bottom_x = event_x(event);
X			  bottom_y = event_y(event);
X			  move_box(CLEAR);
X			  pw_batch_off(pw);
X			break;
X		case LASO:
X			   laso_addpt(ptlist,event_x(event),event_y(event));
X			}
X		case POLY_F:
X		case POLY_H:
X			if (poly_points[0].x != -1)
X		 	{
X			   draw_line(old_x,old_y,start_x,start_y,PIX_XOR,1);
X	  		   old_x = event_x(event);
X			   old_y = event_y(event);
X			   draw_line(old_x,old_y,start_x,start_y,PIX_XOR,1);
X			}
X		  }
X            if (window_get(canvas_local, WIN_EVENT_STATE, MS_RIGHT))
X		{
X                if ((int)panel_get_value(region_choice) == MOVE)
X			{
X			  move_region(old_x,old_y,event_x(event),event_y(event));
X	  		  old_x = event_x(event);
X			  old_y = event_y(event);
X			}
X		}
X	    break;
X          case LOC_MOVE:
X		if (((mouse_left == POLY_F) || (mouse_left == POLY_H)) &&
X			 (poly_points[0].x != -1))
X		 {
X		   draw_line(old_x,old_y,start_x,start_y,PIX_XOR,1);
X  		   old_x = event_x(event);
X		   old_y = event_y(event);
X		   draw_line(old_x,old_y,start_x,start_y,PIX_XOR,1);
X		 }
X	    break;
X	}
X}
X
X
X
X/*
X * we got a "quit" button, say bye bye
X */
Xquit()
X{
X  window_done(base_frame);
X}
X
X
X/*
X * get all the current values for some stuff
X */
Xchange_parms()
X{
X  if (image_depth == 1)
X     cur_color = (int)panel_get_value(mono_cycle);
X  magnify_fac = (int)panel_get_value(magnify_cycle) + 1;
X  grid_size = (int)panel_get_value(grid_cycle)*5;
X}
X
X
X
X/*
X * this is the main that start the show and then goes into
X * window main loop
X */
Xmain(argc,argv) int argc; char *argv[];
X{
Xint targc;
Xchar **targv;
Xchar *s;
Xchar temp_str[10];
Xextern colormap_t colormap;
X
X/*
X * get the options
X */
X        targc = argc; targv = argv;
X        while (--argc > 0 && (*++argv)[0] == '-')
X                for (s = argv[0]+1;*s != '\0';s++)
X          switch (*s) {
X                  case 'n':
X                            undo_flag = FALSE;
X                            break;
X                  case 'f':
X                            fore_back_flag = TRUE;
X                            break;
X                  case 'b':
X                            BW_mode = TRUE;
X                            break;
X                  case 'p':
X                            image_hgt = DEFAULT_IMAGE_WID;
X                            image_wid = DEFAULT_IMAGE_HGT;
X                            break;
X                  case 'y':
X                                ++argv; argc--;
X                            image_hgt = atoi(argv[0]);
X                            break;
X                  case 'x':
X                                ++argv; argc--;
X                            image_wid = atoi(argv[0]);
X                            break;
X                  default:
X                            break;
X	  }
X/*
X * leftovers are potential window option arguments
X */
X
X  clean_poly();
X
X  /*
X   * get the font used in all of the panels
X   */
X  main_font = pf_open(MAIN_FONT);
X  if (!main_font)
X    {
X     printf("ERROR loading the main font !!!!\n");
X     exit(1);
X    }
X
X  init_font();
X  getcwd(file_name,MAX_FILE_NAME-2);
X  strcat(file_name,"/");
X  init_windows(&targc,targv);
X#ifdef CHANGE_CURSOR
X  init_cursors();
X#endif
X  
X
X/*
X * some sanity check for option arguments
X */
X        while (--targc > 0 && (*++targv)[0] == '-')
X                for (s = targv[0]+1;*s != '\0';s++)
X          switch (*s) {
X                  case 'n':
X                  case 'f':
X                  case 'b':
X                  case 'p':
X                            break;
X                  case 'y':
X                  case 'x':
X                                ++targv; targc--;
X                            break;
X                  default:
X                        printf("Usage: touchup [-x width] [-y height] [-n] [-p] [-f] [-b]\n");
X                                exit(0);
X                            break;
X	  }
X  if (targc > 0)
X    {
X      printf("Usage: touchup [-x width] [-y height] [-n] [-p] [-f] [-b]\n");
X      exit(0);
X    }
X			    
X  sprintf(temp_str,"%d",image_hgt);
X  panel_set(height_text,PANEL_VALUE,temp_str,0);
X  sprintf(temp_str,"%d",image_wid);
X  panel_set(width_text,PANEL_VALUE,temp_str,0);
X  /*
X   * are we on a color machine ????
X   */
X  image_depth = pw->pw_pixrect->pr_depth;
X  if (BW_mode)
X	image_depth = 1;
X
X  if (image_depth > 1)
X    {
X	init_colortable();
X
X	fore_ground = *((struct singlecolor *) window_get(base_frame,
X					FRAME_BACKGROUND_COLOR));
X	back_ground = *((struct singlecolor *) window_get(base_frame,
X					FRAME_BACKGROUND_COLOR));
X        red[0] = fore_ground.red;
X        green[0] = fore_ground.green;
X        blue[0] = fore_ground.blue;  
X        red[255] = back_ground.red;
X        green[255] = back_ground.green;
X        blue[255] = back_ground.blue;
X
X	my_put_colormap();
X	set_color();
X	colormap.map[0] = red;
X	colormap.map[1] = green;
X	colormap.map[2] = blue;
X	colormap.type = RMT_EQUAL_RGB;
X	colormap.length = 256;
X    }
X  else
X	set_mono();
X
X  window_set(canvas, CANVAS_RETAINED, TRUE, 0);
X
X  if (undo_flag)
X     undo_pr = my_mem_create(image_wid,image_hgt,image_depth);
X  else
X     panel_set(undo_button,PANEL_SHOW_ITEM, FALSE,0);
X
X  brush_temp_pr = my_mem_create(PATTERN_SIZE,PATTERN_SIZE,1);
X  init_mag();
X#ifdef CHANGE_CURSOR
X  change_cursor(canvas, paint_cur);
X#endif
X  print_msg("Press the LEFT mouse button to PAINT.");
X
X          
X /*
X  * set up an interposed event handler so we know when to quit
X  *	-mark weiser
X  */
X  (void)notify_interpose_destroy_func(base_frame, notice_destroy_event);
X
X  window_main_loop(base_frame);
X}
X
X
X
X/***************************************************************
X        hide_msg
X        purpose: To clear the masssage display area.
X        parameter:
X        returns:
X ***************************************************************/
Xhide_msg()
X{
X         panel_set(msg_string,PANEL_LABEL_STRING,"",0);
X}
X
X
X/***************************************************************
X        print_msg
X        purpose: To print a message on the window and center it
X        parameter:
X                string: The string to be printed.
X        returns:
X ***************************************************************/
Xprint_msg(string)
Xchar *string;
X{
Xchar temp_space[132];
Xchar *temp_pt;
Xint i;
X  
X  if (strlen(string) < 132)
X  {
X    for(i=0;i<132;i++)
X      temp_space[i]= ' ';
X    temp_pt = temp_space + (132-strlen(string))/2;
X    strcpy(temp_pt,string);
X    panel_set(msg_string,PANEL_LABEL_STRING,temp_space,0);
X  }
X  else
X    panel_set(msg_string,PANEL_LABEL_STRING,string,0);
X}
X
XERROR(msg)
Xchar *msg;
X{ 
X  print_msg(msg);
X  window_bell(panel);
X}
X
XERRORstr(msg,str)
Xchar *msg,*str;
X{
Xchar temp[200];
X  strcpy(temp,msg);
X  print_msg(strcat(temp,str));
X  window_bell(panel);
X}
X
X
X
X/***************************************************************
X	sqrt_fast
X        purpose: To do a fast integer square root
X        parameter:
X		n :  the int to take the sqrt of
X        returns: 
X		the integer square root of n
X ***************************************************************/
Xint sqrt_fast(n)
Xint n;
X{
X   int a,b,c;
X   a = n;
X   b = n;
X   if (n>1){
X        while (a>0) {
X            a = a >> 2;
X            b = b >> 1;
X	}
X        do {
X            a = b;
X            c = n / b;
X            b = (c + a) >> 1;
X	} while ( (a-c)<-1 || (a-c)>1 );
X   }
X    return(b);
X}
X
X/*
X * find the distance between any two points
X */
Xdistance(x1,y1,x2,y2)
Xint x1,y1,x2,y2;
X{
X  return(sqrt_fast((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
X}
X
X
X/*
X * check if we have enough memory to create those LARGE bitmaps
X */
Xstruct pixrect *my_mem_create(wid,hgt,dep)
Xint wid,hgt,dep;
X{
Xstruct pixrect* temp_pr;
X
X    temp_pr = mem_create(wid,hgt,dep);
X    if (temp_pr== NULL)
X        {
X  	printf("Not enough memory, memory allocation problems!!!\n");
X  	exit(0);
X        }
X    return(temp_pr);  /* this is the line that was missing in version 2.2 */
X}
X
X
X
X
X/*
X * pixrect data for horizontal dashed lines for 'moving box'
X */
Xshort box_x_bits[] = {
X        0xff00, 0xff00
X};
X
X/*
X * pixrect data for vertical dashed lines for 'moving box'
X */
Xshort box_y_bits[] = {
X        0xffff, 0xffff,
X        0xffff, 0xffff,
X        0xffff, 0xffff,
X        0xffff, 0xffff,
X        0x0000, 0x0000,
X        0x0000, 0x0000,
X        0x0000, 0x0000,
X	0x0000, 0x0000
X};
Xstatic mpr_static(bufx, 16, 1, 1, box_x_bits);
Xstatic mpr_static(bufy, 16, 16, 1, box_y_bits);
X
X
X#define ITIMER_NULL ((struct itimerval *)0)
Xint box_running=FALSE;
X
X/*
X * this is the function that is will get called when the sigalarm
X * goes off
X */
XNotify_value move_boxz()
X{
X  pw_batch_on(pw);
X  move_box(NO_CLEAR);
X  pw_batch_off(pw);
X  return(NOTIFY_DONE);
X}
X
Xint my_client_object;
Xint *me = &my_client_object;
X
X
X
X/*
X * call this function to get the box moving, once this function
X * has been called the box will continue to move
X *
X *    run_box:TRUE  -- this means that we want to move the box
X *    box_running:TRUE  -- this means the the box is already running
X */
Xstart_region()
X{
X  if (run_box && !box_running)
X    {
X        struct itimerval timer;
X
X        timer.it_interval.tv_usec = 1000;
X        timer.it_interval.tv_sec = 0;
X        timer.it_value.tv_usec = 1000;
X        timer.it_value.tv_sec = 0;
X        notify_set_itimer_func(me, move_boxz,
X                ITIMER_REAL, &timer, ITIMER_NULL);
X	box_running = TRUE;
X    }
X  else if (!run_box && box_running)
X    {
X	(void)notify_set_itimer_func(me,move_boxz,
X		ITIMER_REAL,ITIMER_NULL, ITIMER_NULL);
X	box_running = FALSE;
X    }
X}
X
X
X/*
X * this function is called to move all of the dashed lines
X * 1 increment. if 'clear' is true that it this function will
X * just erase the box from the last time but it will not
X * draw up the new box
X */
Xmove_box(clear)
Xint clear;
X{
Xint ztop_x,ztop_y;
Xint zbottom_x,zbottom_y;
X
X  if (top_x > bottom_x)
X    {
X     ztop_x = bottom_x;
X     zbottom_x = top_x;
X    }
X  else
X    {
X     ztop_x = top_x;
X     zbottom_x = bottom_x;
X    }
X
X  if (top_y > bottom_y)
X    {
X     ztop_y = bottom_y;
X     zbottom_y = top_y;
X    }
X  else
X    {
X     ztop_y = top_y;
X     zbottom_y = bottom_y;
X    }
X
X  pw_replrop(pw, ztop_x, ztop_y, zbottom_x-ztop_x, 1,
X                        PIX_XOR, &bufx, box_off, 0);
X  pw_replrop(pw, ztop_x, zbottom_y, zbottom_x-ztop_x, 1,
X                        PIX_XOR, &bufx, box_off+(zbottom_y-ztop_y), 0);
X  pw_replrop(pw, ztop_x, ztop_y, 1, zbottom_y-ztop_y,
X                        PIX_XOR, &bufy, 0, box_off); 
X  pw_replrop(pw, zbottom_x, ztop_y, 1, zbottom_y-ztop_y,
X                        PIX_XOR, &bufy, 0, box_off+(zbottom_x-ztop_x));
X  if (!clear)
X     {
X	  box_off++;
X          pw_replrop(pw, ztop_x, ztop_y, zbottom_x-ztop_x, 1,
X                        PIX_XOR, &bufx, ++box_off, 0);
X          pw_replrop(pw, ztop_x, zbottom_y, zbottom_x-ztop_x, 1,
X                        PIX_XOR, &bufx, box_off+(zbottom_y-ztop_y), 0);
X          pw_replrop(pw, ztop_x, ztop_y, 1, zbottom_y-ztop_y,
X                        PIX_XOR, &bufy, 0, box_off);
X          pw_replrop(pw, zbottom_x, ztop_y, 1, zbottom_y-ztop_y,
X                        PIX_XOR, &bufy, 0, box_off+(zbottom_x-ztop_x));
X     }
X}
X
X
X
Xclean_box()
X{
X  if (run_box)
X	move_box(CLEAR);
X  run_box = FALSE;
X  start_region();
X}
X
X
X
X/* 
X * a service routine that gets called when the frame is destroyed
X * by someone selecting 'quit'.  this is basically right out of the 
X * manual.	-mark weiser
X */
Xstatic Notify_value
Xnotice_destroy_event(frame, status)
X        Frame *frame;
X        Destroy_status status;
X{
X        if (status != DESTROY_CHECKING) {
X                run_box = FALSE;
X		start_region();
X	}
X        return (notify_next_destroy_func(frame,status));
X}
X
X
END_OF_touchup.c
if test 33970 -ne `wc -c <touchup.c`; then
    echo shar: \"touchup.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 7 \(of 7\).
cp /dev/null ark7isdone
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