[comp.sources.misc] v06i095: KironDraw v2.4B

allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (05/01/89)

Posting-number: Volume 6, Issue 95
Submitted-by: kiron@db9.cs.concordia.ca
Archive-name: kirondraw

[An earlier version of this program was released as "sundraw"; it has been
renamed to avoid confusion with the program recently released by Sun.  ++bsa]

# This is a shell archive.  Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file".  (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# README kirondraw.c kirondraw.l

echo x - README
cat > "README" << '//E*O*F README//'
KironDraw Version 2.4B
======================

	This program is essentially a bitmap graphic editor for Sun workstation
running suntools. Included in this archive are the source code and the manual page.
To create the executable code type :

	cc kirondraw.c -lcgi -lsuntool -lsunwindow -lpixrect -lm -fswitch -pipe -O -o KironDraw

This program is shareware... if you see a use for it, please send $5 to 

         Kiron Bondale
         4195 Beaconsfield Avenue
         Montreal, Quebec
         Canada
         H4A 2H4

Registering the program will ensure that you get free upgrades regularly.
(and believe me, upgrades will be MANY!!!!!)
//E*O*F README//

echo x - kirondraw.c
cat > "kirondraw.c" << '//E*O*F kirondraw.c//'
/*************************************************************************/
/* KironDraw V 2. B							 */
/* by : Kiron D. Bondale 						 */
/* logfile :								 */
/* (from Version 2 onwards... I am royally lazy at such things!!! 	 */
/* 2.1B - all icons and images are part of the program			 */
/* 2.2B - improved error checking for loading rasters/scripts		 */
/* 2.3B - Flipping/inversion/resizing of clipboard contents	       	 */
/* 2.4B - icon for program was changed... I made a boo-boo		 */
/*************************************************************************/

#include <cgipw.h>
#include <suntool/sunview.h>
#include <suntool/canvas.h>
#include <suntool/panel.h>
#include <suntool/scrollbar.h>
#include <suntool/textsw.h>
#include <pixrect/pixrect_hs.h>
#include <strings.h>
#include <math.h>
#include <stdio.h>
#include <sys/param.h>

/* Remove the following line if a Printronix printer is not used... */
#define PRINTRONIX 1

#define MAXPRINWID 1000
#define NROWS 720
#define NCOLS 560
#define NORMALW 640
#define NORMALH 544
#define SWIDTH 1088
#define SHEIGHT 1000
#define LINE_LEN 72
#define BLOCK_SIZE 512
#define SRC_SIZE 2*BLOCK_SIZE

char            src_buf[SRC_SIZE];
char            scan_line[LINE_LEN];


static short    icon_image[] = {
	0x0000,0x0000,0x0000,0x009C,0x0000,0x0000,0x0000,0x0122,
        0x0000,0x0000,0x0000,0x0261,0x0000,0x0000,0x0000,0x0791,
        0xFFFF,0xFFFF,0xFFFF,0xF989,0xFFFF,0xFFFF,0xFFFF,0xFA46,
        0xC000,0x0000,0x0000,0x1E26,0xC000,0x0000,0x0000,0x1B1A,
        0xC000,0x0000,0x0000,0x149A,0xC000,0x0000,0x0220,0x296E,
        0xC03E,0x0000,0x0440,0x5262,0xC041,0x0000,0x1100,0xA4A2,
        0xC080,0x8000,0x0881,0x498A,0xC100,0x4000,0x0222,0x928A,
        0xC200,0x2000,0x0445,0x2622,0xC200,0x2003,0x000A,0x4A22,
        0xC200,0x2004,0x0014,0x988A,0xC200,0x200C,0x0029,0x388A,
        0xC200,0x2010,0x0052,0x5A22,0xC100,0x4000,0x00A4,0x9A22,
        0xC080,0x8020,0x0149,0x188A,0xC041,0x0040,0x0292,0x188A,
        0xC03E,0x0020,0x0524,0x1A22,0xC000,0x0020,0x0A48,0x1A22,
        0xC000,0x0020,0x1490,0x188A,0xC000,0x0040,0x2920,0x188A,
        0xC000,0x0100,0x5240,0x1A22,0xC000,0x0200,0xA480,0x1A22,
        0xC000,0x3401,0x4900,0x188A,0xC000,0x4002,0x9200,0x188A,
        0xC000,0x8005,0x2400,0x1A22,0xC000,0x000A,0x4800,0x1A22,
        0xC003,0x0034,0x9000,0x188A,0xC000,0x0029,0x2000,0x188A,
        0xC000,0x0052,0x4000,0x1A22,0xC000,0x00E4,0x8000,0x1A22,
        0xC000,0x0129,0x0000,0x188A,0xC000,0x0112,0x0000,0x188A,
        0xC000,0x020C,0x0000,0x1A22,0xC000,0x0218,0x0000,0x1A22,
        0xC000,0x0660,0x0000,0x188A,0xC000,0x0780,0x0000,0x188A,
        0xC000,0x0E00,0x0000,0x1A22,0xC000,0x0C00,0x0000,0x1A22,
        0xC000,0x0300,0x0000,0x188A,0xC000,0x00C0,0x0000,0x188A,
        0xC000,0x0030,0x0000,0x1A22,0xC000,0x000C,0x0000,0x1A22,
        0xC000,0x0003,0x0000,0x188A,0xC000,0x0000,0xC000,0x188A,
        0xC000,0x0000,0x3000,0x1A22,0xC000,0x0000,0x0800,0x1A22,
        0x4440,0x0001,0xC000,0x008A,0x4805,0x0C51,0x250C,0x448A,
        0x50C6,0x9269,0x2682,0x4422,0x7044,0x1249,0x240E,0x5424,
        0x4844,0x1249,0x2412,0x5488,0x4444,0x0C49,0xC40A,0x2890,
        0x0000,0x0000,0x0000,0x0020,0x0000,0x0000,0x0000,0x0240,
        0xC000,0x0000,0x0000,0x1880,0xC000,0x0000,0x0000,0x1900,
        0xFFFF,0xFFFF,0xFFFF,0xFA00,0xFFFF,0xFFFF,0xFFFF,0xFC00
};

static short    points_dat[] = {
	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0,
	0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};
mpr_static(sued_point, 16, 16, 1, points_dat);

static short    line_dat[] = {
	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7FFE, 0x7FFE,
	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};
mpr_static(sued_line, 16, 16, 1, line_dat);

static short    box_dat[] = {
	0x0000, 0x7FFE, 0x7FFE, 0x6006, 0x6006, 0x6006, 0x6006, 0x6006,
	0x6006, 0x6006, 0x6006, 0x6006, 0x6006, 0x7FFE, 0x7FFE, 0x0000
};
mpr_static(sued_box, 16, 16, 1, box_dat);

static short    circle_dat[] = {
	0x03E0, 0x0FF8, 0x1C1C, 0x380E, 0x3006, 0x6003, 0x6003, 0x6003,
	0x6003, 0x6003, 0x3006, 0x380E, 0x1C1C, 0x0FF8, 0x03E0, 0x0000
};
mpr_static(sued_circle, 16, 16, 1, circle_dat);

static short    datflow_dat[] = {
	0x0000, 0x0000, 0x0000, 0xFFFE, 0xFFFE, 0x8000, 0x8000, 0x8000,
	0x8000, 0x8000, 0xFFFE, 0xFFFE, 0x0000, 0x0000, 0x0000, 0x0000
};
mpr_static(sued_data, 16, 16, 1, datflow_dat);

static short    some_dat[] = {
	0x0000, 0x0000, 0x0000, 0x0000, 0x1FFE, 0x1FFE, 0x3006, 0x3006,
	0x600C, 0x600C, 0x7FFC, 0x7FFC, 0x0000, 0x0000, 0x0000, 0x0000
};
mpr_static(sued_some, 16, 16, 1, some_dat);

static short    text_dat[] = {
	0x0000, 0x0000, 0x0000, 0x0000, 0x6200, 0x920C, 0x1392, 0x7250,
	0x9252, 0x7B8C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};
mpr_static(sued_text, 16, 16, 1, text_dat);

static short    ellipse_dat[] = {
	0x0000, 0x0000, 0x0000, 0x0FF0, 0x3FFC, 0x700E, 0xC003, 0x8001,
	0xC003, 0x700E, 0x3FFC, 0x0FF0, 0x0000, 0x0000, 0x0000, 0x0000
};
mpr_static(sued_ellipse, 16, 16, 1, ellipse_dat);

static short    condi_dat[] = {
	0x0000, 0x0000, 0x0180, 0x07E0, 0x0E70, 0x381C, 0x700E, 0xC003,
	0x700E, 0x381C, 0x0E70, 0x07E0, 0x0180, 0x0000, 0x0000, 0x0000
};
mpr_static(sued_condi, 16, 16, 1, condi_dat);

static short    io_dat[] = {
	0x0000, 0x0000, 0x0000, 0x7FFE, 0x7FFE, 0x6006, 0x6006, 0x7E06,
	0x7F86, 0x01E6, 0x0066, 0x0066, 0x007E, 0x007E, 0x0000, 0x0000
};
mpr_static(sued_io, 16, 16, 1, io_dat);

static short    eraser_dat[] = {
	0x0000, 0x0000, 0x0000, 0x0000, 0x0FFC, 0x100C, 0x2014, 0x2014,
	0x7FE4, 0x4028, 0x4028, 0x4030, 0x7FE0, 0x0000, 0x0000, 0x0000
};
mpr_static(sued_eraser, 16, 16, 1, eraser_dat);

static short    cut_dat[] = {
	0x7E41, 0x8041, 0x8041, 0x8041, 0x8041, 0x8041, 0x7E3E, 0x0000,
	0x0FF8, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0000
};
mpr_static(sued_cut, 16, 16, 1, cut_dat);

static short    copy_dat[] = {
	0x7C78, 0x8084, 0x8084, 0x8084, 0x8084, 0x8084, 0x7C78, 0x0000,
	0xF882, 0x8444, 0x8428, 0xF810, 0x8010, 0x8010, 0x8010, 0x8010
};
mpr_static(sued_copy, 16, 16, 1, copy_dat);

static short    paste_dat[] = {
	0xF25F, 0x8A44, 0x8A44, 0x8A44, 0xF244, 0x8244, 0x8244, 0x8244,
	0x8244, 0x8244, 0x83C4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};
mpr_static(sued_paste, 16, 16, 1, paste_dat);

static short    invert_dat[] = {
	0x0000, 0x7F80, 0x7F80, 0x7F80, 0x7FB8, 0x7F88, 0x7F9C, 0x0008,
	0x0000, 0x03FC, 0x0204, 0x0204, 0x0204, 0x0204, 0x03FC, 0x0000
};
mpr_static(sued_invert, 16, 16, 1, invert_dat);

static short    fliph_dat[] = {
	0x0000, 0x4002, 0x781E, 0x0810, 0x0810, 0x0810, 0x0890, 0x0BD0,
	0x0890, 0x0810, 0x0810, 0x0810, 0x781E, 0x4002, 0x0000, 0x0000
};
mpr_static(sued_fliph, 16, 16, 1, fliph_dat);

static short    flipv_dat[] = {
	0x0000, 0x300C, 0x1008, 0x1008, 0x1FF8, 0x0000, 0x0100, 0x0100,
	0x0380, 0x0100, 0x0000, 0x1FF8, 0x1008, 0x1008, 0x300C, 0x0000
};
mpr_static(sued_flipv, 16, 16, 1, flipv_dat);

static short    enlarge_dat[] = {
	0x0000, 0x7E10, 0x4220, 0x4278, 0x4224, 0x4214, 0x7E04, 0x0004,
	0x0018, 0x0020, 0x0E40, 0x0A00, 0x0E00, 0x0000, 0x0000, 0x0000
};
mpr_static(sued_enlarge, 16, 16, 1, enlarge_dat);

static short    reduce_dat[] = {
	0x0000, 0x7E00, 0x4200, 0x4260, 0x4210, 0x4210, 0x7E08, 0x0008,
	0x0050, 0x0060, 0x0E70, 0x0A00, 0x0E00, 0x0000, 0x0000, 0x0000
};
mpr_static(sued_reduce, 16, 16, 1, reduce_dat);

DEFINE_ICON_FROM_IMAGE(hello_icon, icon_image);

int             pattern1[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                pattern2[16] = {0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0},
                pattern3[16] = {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
                pattern4[16] = {1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1};

Pixwin         *pw, *pw2;
Ccgiwin         vpw, vpw2;
Ccoor           bottom, first, second, line[8];
Ccoorlist       lines;
int             x1, ya, x2, y2, x3, y3, x4, y4, i, newwid, newhei, arrow, ClipWidth, ClipHeight, grid, name, name2, temp1, temp2, tool, size, savetype, loadtype, printtype, scriptype, pastetype, patterntype, linewid, linetype;
Panel_item      fname_item, tname_item;
Window          frame, panel, canvas, frame2, canvas2, frame3;
Textsw          textsw;
char            intext[25], pathname[99], scriptext[80];

struct pixrect *pr1, *pr, *pr6, *pr3, *pr4;

void
push()
{
	pw_batch_on(pw);
	pw_read(pr1, 0, 0, SWIDTH, SHEIGHT, PIX_SRC, pw, 0, 0);
	pw_batch_off(pw);
}

int
checkraster(testfile)
	char            testfile[80];
{
	int             socket[2];
	char            label[80], label2[20];
	FILE           *fp;
	pipe(socket);
	if (!fork()) {
		close(socket[0]);
		close(1);
		dup(socket[1]);
		close(socket[1]);
		execlp("file", "file", testfile, 0);
		exit(1);
	}
	fp = fdopen(socket[0], "r");
	fscanf(fp, "%s %s", label, label2);
	fclose(fp);
	if (strcmp(label2, "rasterfile,") == 0)
		return (0);
	else
		return (1);
}

int
checkascii(testfile)
	char            testfile[80];
{
	int             socket[2];
	char            label[80], label2[20];
	FILE           *fp;
	pipe(socket);
	if (!fork()) {
		close(socket[0]);
		close(1);
		dup(socket[1]);
		close(socket[1]);
		execlp("file", "file", testfile, 0);
		exit(1);
	}
	fp = fdopen(socket[0], "r");
	fscanf(fp, "%s %s", label, label2);
	fclose(fp);
	if (strcmp(label2, "ascii") == 0)
		return (0);
	else
		return (1);
}

void
pop()
{
	pw_batch_on(pw);
	pw_read(pr, 0, 0, SWIDTH, SHEIGHT, PIX_SRC, pw, 0, 0);
	pw_batch_off(pw);
}

void
refr(canvas, width, height)
	Canvas          canvas;
	int             width, height;
{
	pw_batch_on(pw);
	pw_write(pw, 0, 0, width, height, PIX_SRC, pr, 0, 0);
	pw_batch_off(pw);
}

void
test(window, event)
	Window          window;
	Event          *event;
{
	int             temp, radi;
	switch (tool) {
	case 0:		/* line */
		switch (event_id(event)) {
		case MS_LEFT:
			{
				if (event_is_down(event)) {
					push();
					temp = 1;
					x1 = event_x(event);
					ya = event_y(event);
					x1 = x1 - x1 % grid;
					ya = ya - ya % grid;
					x2 = x1;
					y2 = ya;
				}
				if (event_is_up(event)) {
					pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
					line[0].x = x1;
					line[0].y = ya;
					line[1].x = x2;
					line[1].y = y2;
					lines.n = 2;
					lines.ptlist = line;
					cgipw_polyline(&vpw, &lines);
					if (scriptype == 1) {
						sprintf(scriptext, "l %d,%d,%d,%d\n", x1, ya, x2, y2);
						textsw_insert(textsw, scriptext, strlen(scriptext));
					}
					if ((arrow == 1) || (arrow == 3)) {
						bottom.x = x1;
						bottom.y = ya;
						radi = 2;
						cgipw_circle(&vpw, &bottom, radi);
					}
					if ((arrow == 2) || (arrow == 3)) {
						bottom.x = x2;
						bottom.y = y2;
						radi = 2;
						cgipw_circle(&vpw, &bottom, radi);
					}
					pop();
				}
			}
			break;
		case LOC_DRAG:
			{
				if (temp != 1)
					pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
				temp = 0;
				x2 = event_x(event);
				y2 = event_y(event);
				x2 = x2 - x2 % grid;
				y2 = y2 - y2 % grid;
				pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
			}
		}
		break;
	case 1:{		/* point */
			switch (event_id(event)) {
			case MS_LEFT:
				{
					if (event_is_down(event))
						push();
					x3 = event_x(event);
					y3 = event_y(event);
					x4 = x3;
					y4 = y3;
					line[0].x = x3 - x3 % grid;
					line[0].y = y3 - y3 % grid;
					line[1].x = x4 - x4 % grid;
					line[1].y = y4 - y4 % grid;
					lines.n = 2;
					lines.ptlist = line;
					cgipw_polyline(&vpw, &lines);
					if (scriptype == 1) {
						sprintf(scriptext, "p %d,%d\n", x3, y3);
						textsw_insert(textsw, scriptext, strlen(scriptext));
					}
					pop();
				}
				break;
			case LOC_DRAG:
				{
					x3 = x4;
					y3 = y4;
					x4 = event_x(event);
					y4 = event_y(event);
					line[0].x = x3 - x3 % grid;
					line[0].y = y3 - y3 % grid;
					line[1].x = x4 - x4 % grid;
					line[1].y = y4 - y4 % grid;
					lines.n = 2;
					lines.ptlist = line;
					cgipw_polyline(&vpw, &lines);
					if (scriptype == 1) {
						sprintf(scriptext, "p %d,%d\n", x3, y3);
						textsw_insert(textsw, scriptext, strlen(scriptext));
					}
				}
			}
		}
		break;
	case 2:		/* rectangle */
		switch (event_id(event)) {
		case MS_LEFT:
			{
				if (event_is_down(event)) {
					push();
					temp = 1;
					x1 = event_x(event);
					ya = event_y(event);
					x1 = x1 - x1 % grid;
					ya = ya - ya % grid;
					x2 = x1;
					y2 = ya;
				}
				if (event_is_up(event)) {
					x2 = event_x(event);
					y2 = event_y(event);
					x2 = x2 - x2 % grid;
					y2 = y2 - y2 % grid;
					pw_vector(pw, x1, ya, x2, ya, PIX_SRC ^ PIX_DST, 1);
					pw_vector(pw, x2, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
					pw_vector(pw, x2, y2, x1, y2, PIX_SRC ^ PIX_DST, 1);
					pw_vector(pw, x1, y2, x1, ya, PIX_SRC ^ PIX_DST, 1);
					first.x = x1;
					first.y = ya;
					second.x = x2;
					second.y = y2;
					cgipw_rectangle(&vpw, &first, &second);
					if (scriptype == 1) {
						sprintf(scriptext, "r %d,%d,%d,%d\n", x1, ya, x2, y2);
						textsw_insert(textsw, scriptext, strlen(scriptext));
					}
					pop();
				}
			}
			break;
		case LOC_DRAG:
			{
				if (temp != 1) {
					pw_vector(pw, x1, ya, x2, ya, PIX_SRC ^ PIX_DST, 1);
					pw_vector(pw, x2, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
					pw_vector(pw, x2, y2, x1, y2, PIX_SRC ^ PIX_DST, 1);
					pw_vector(pw, x1, y2, x1, ya, PIX_SRC ^ PIX_DST, 1);
				}
				temp = 0;
				x2 = event_x(event);
				y2 = event_y(event);
				x2 = x2 - x2 % grid;
				y2 = y2 - y2 % grid;
				pw_vector(pw, x1, ya, x2, ya, PIX_SRC ^ PIX_DST, 1);
				pw_vector(pw, x2, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
				pw_vector(pw, x2, y2, x1, y2, PIX_SRC ^ PIX_DST, 1);
				pw_vector(pw, x1, y2, x1, ya, PIX_SRC ^ PIX_DST, 1);
			}
		}
		break;
	case 3:		/* circle */
		switch (event_id(event)) {
		case MS_LEFT:
			{
				if (event_is_down(event)) {
					push();
					temp = 1;
					x1 = event_x(event);
					ya = event_y(event);
					x1 = x1 - x1 % grid;
					ya = ya - ya % grid;
					x2 = x1;
					y2 = ya;
				}
				if (event_is_up(event)) {
					pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
					pw_vector(pw, x1, ya, x1, ya, PIX_SRC ^ PIX_DST, 1);
					radi = (int) sqrt((double) ((x2 - x1) * (x2 - x1) + (y2 - ya) * (y2 - ya)));
					bottom.x = x1;
					bottom.y = ya;
					cgipw_circle(&vpw, &bottom, radi);
					if (scriptype == 1) {
						sprintf(scriptext, "c %d,%d,%d\n", x1, ya, radi);
						textsw_insert(textsw, scriptext, strlen(scriptext));
					}
					pop();
				}
			}
			break;
		case LOC_DRAG:
			{
				if (temp != 1)
					pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
				temp = 0;
				x2 = event_x(event);
				y2 = event_y(event);
				x2 = x2 - x2 % grid;
				y2 = y2 - y2 % grid;
				pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
			}
		}
		break;
	case 4:{		/* text tool */
			if (event_id(event) == MS_LEFT) {
				if (event_is_up(event)) {
					pw_text(pw, x3, y3, PIX_SRC | PIX_DST, NULL, intext);
					if (scriptype == 1) {
						sprintf(scriptext, "T %d,%d %s\n", x3, y3, intext);
						textsw_insert(textsw, scriptext, strlen(scriptext));
					}
					pop();
				}
				if (event_is_down(event)) {
					push();
					x3 = event_x(event);
					y3 = event_y(event);
					x3 = x3 - x3 % grid;
					y3 = y3 - y3 % grid;
					strcpy(intext, panel_get_value(tname_item));
					pw_text(pw, x3, y3, PIX_SRC ^ PIX_DST, NULL, intext);
				}
			}
			if (event_id(event) == LOC_DRAG) {
				pw_text(pw, x3, y3, PIX_SRC ^ PIX_DST, NULL, intext);
				x3 = event_x(event);
				y3 = event_y(event);
				x3 = x3 - x3 % grid;
				y3 = y3 - y3 % grid;
				pw_text(pw, x3, y3, PIX_SRC ^ PIX_DST, NULL, intext);
			}
		}
		break;
	case 5:{		/* eraser */
			i = (int) size / 2;
			switch (event_id(event)) {
			case MS_LEFT:
				{
					if (event_is_down(event)) {
						push();
						x4 = event_x(event) - i;
						y4 = event_y(event) - i;
						pw_writebackground(pw, x4, y4, size, size, PIX_SRC);
						pw_vector(pw, x4, y4, x4 + size, y4, PIX_SRC ^ PIX_DST, 1);
						pw_vector(pw, x4 + size, y4, x4 + size, y4 + size, PIX_SRC ^ PIX_DST, 1);
						pw_vector(pw, x4 + size, y4 + size, x4, y4 + size, PIX_SRC ^ PIX_DST, 1);
						pw_vector(pw, x4, y4 + size, x4, y4, PIX_SRC ^ PIX_DST, 1);
						if (scriptype == 1) {
							sprintf(scriptext, "E %d,%d\n", x4, y4);
							textsw_insert(textsw, scriptext, strlen(scriptext));
						}
					}
					if (event_is_up(event)) {
						pw_writebackground(pw, x4, y4, size, size, PIX_SRC);
						pw_vector(pw, x4, y4, x4 + size, y4, PIX_NOT(PIX_SRC) & PIX_DST, 1);
						pw_vector(pw, x4 + size, y4, x4 + size, y4 + size, PIX_NOT(PIX_SRC) & PIX_DST, 1);
						pw_vector(pw, x4 + size, y4 + size, x4, y4 + size, PIX_NOT(PIX_SRC) & PIX_DST, 1);
						pw_vector(pw, x4, y4 + size, x4, y4, PIX_NOT(PIX_SRC) & PIX_DST, 1);
						if (scriptype == 1) {
							sprintf(scriptext, "E %d,%d\n", x4, y4);
							textsw_insert(textsw, scriptext, strlen(scriptext));
						}
						pop();
					}
				}
				break;
			case MS_RIGHT:
				push();
				pw_writebackground(pw, x4, y4, size, size, PIX_SRC);
				break;
			case MS_MIDDLE:
				push();
				pw_writebackground(pw, x4, y4, size, size, PIX_SRC);
				break;
			case LOC_DRAG:
				{
					pw_writebackground(pw, x4, y4, size, size, PIX_SRC);
					pw_vector(pw, x4, y4, x4 + size, y4, PIX_NOT(PIX_SRC) & PIX_DST, 1);
					pw_vector(pw, x4 + size, y4, x4 + size, y4 + size, PIX_NOT(PIX_SRC) & PIX_DST, 1);
					pw_vector(pw, x4 + size, y4 + size, x4, y4 + size, PIX_NOT(PIX_SRC) & PIX_DST, 1);
					pw_vector(pw, x4, y4 + size, x4, y4, PIX_NOT(PIX_SRC) & PIX_DST, 1);
					x4 = event_x(event) - i;
					y4 = event_y(event) - i;
					if (scriptype == 1) {
						sprintf(scriptext, "E %d,%d\n", x4, y4);
						textsw_insert(textsw, scriptext, strlen(scriptext));
					}
					pw_writebackground(pw, x4, y4, size, size, PIX_SRC);
					pw_vector(pw, x4, y4, x4 + size, y4, PIX_SRC ^ PIX_DST, 1);
					pw_vector(pw, x4 + size, y4, x4 + size, y4 + size, PIX_SRC ^ PIX_DST, 1);
					pw_vector(pw, x4 + size, y4 + size, x4, y4 + size, PIX_SRC ^ PIX_DST, 1);
					pw_vector(pw, x4, y4 + size, x4, y4, PIX_SRC ^ PIX_DST, 1);
				}
			}
		}
		break;
	case 6:		/* ellipse */
		switch (event_id(event)) {
		case MS_LEFT:
			{
				if (event_is_down(event)) {
					push();
					temp = 1;
					x1 = event_x(event);
					ya = event_y(event);
					x1 = x1 - x1 % grid;
					ya = ya - ya % grid;
					x2 = x1;
					y2 = ya;
				}
				if (event_is_up(event)) {
					pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
					pw_vector(pw, x1, ya, x1, ya, PIX_SRC ^ PIX_DST, 1);
					bottom.x = x1;
					bottom.y = ya;
					cgipw_ellipse(&vpw, &bottom, (x2 - x1), (y2 - ya));
					if (scriptype == 1) {
						sprintf(scriptext, "e %d,%d,%d,%d\n", x1, ya, x2 - x1, y2 - ya);
						textsw_insert(textsw, scriptext, strlen(scriptext));
					}
					pop();
				}
			}
			break;
		case LOC_DRAG:
			{
				if (temp != 1)
					pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
				temp = 0;
				x2 = event_x(event);
				y2 = event_y(event);
				x2 = x2 - x2 % grid;
				y2 = y2 - y2 % grid;
				pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
			}
		}
		break;
	case 7:{		/* dataflow tool */
			switch (event_id(event)) {
			case MS_LEFT:
				{
					if (event_is_down(event)) {
						push();
						temp = 1;
						x1 = event_x(event);
						ya = event_y(event);
						x1 = x1 - x1 % grid;
						ya = ya - ya % grid;
						x2 = x1;
						y2 = ya;
					}
					if (event_is_up(event)) {
						pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
						pw_vector(pw, x1, ya, x1, ya, PIX_SRC ^ PIX_DST, 1);
						line[0].x = x2;
						line[0].y = ya;
						line[1].x = x1;
						line[1].y = ya;
						line[2].x = x1;
						line[2].y = y2;
						line[3].x = x2;
						line[3].y = y2;
						lines.n = 4;
						lines.ptlist = line;
						cgipw_polyline(&vpw, &lines);
						if (scriptype == 1) {
							sprintf(scriptext, "d %d,%d,%d,%d\n", x1, ya, x2, y2);
							textsw_insert(textsw, scriptext, strlen(scriptext));
						}
						pop();
					}
				}
				break;
			case LOC_DRAG:
				{
					if (temp != 1)
						pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
					temp = 0;
					x2 = event_x(event);
					y2 = event_y(event);
					x2 = x2 - x2 % grid;
					y2 = y2 - y2 % grid;
					pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
				}
			}
		} break;
	case 8:{		/* conditional tool */
			switch (event_id(event)) {
			case MS_LEFT:
				{
					if (event_is_down(event)) {
						push();
						temp = 1;
						x1 = event_x(event);
						ya = event_y(event);
						x1 = x1 - x1 % grid;
						ya = ya - ya % grid;
						x2 = x1;
						y2 = ya;
					}
					if (event_is_up(event)) {
						pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
						pw_vector(pw, x1, ya, x1, ya, PIX_SRC ^ PIX_DST, 1);
						temp1 = (int) ((x2 - x1) / 2);
						temp2 = (int) ((y2 - ya) / 2);
						line[0].x = x1 + temp1;
						line[0].y = ya;
						line[1].x = x1;
						line[1].y = ya + temp2;
						line[2].x = x1 + temp1;
						line[2].y = y2;
						line[3].x = x2;
						line[3].y = ya + temp2;
						line[4].x = x1 + temp1;
						line[4].y = ya;
						lines.n = 5;
						lines.ptlist = line;
						cgipw_polyline(&vpw, &lines);
						if (scriptype == 1) {
							sprintf(scriptext, "C %d,%d,%d,%d\n", x1, ya, x2, y2);
							textsw_insert(textsw, scriptext, strlen(scriptext));
						}
						pop();
					}
				}
				break;
			case LOC_DRAG:
				{
					if (temp != 1)
						pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
					temp = 0;
					x2 = event_x(event);
					y2 = event_y(event);
					x2 = x2 - x2 % grid;
					y2 = y2 - y2 % grid;
					pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
				}
			}
		}
		break;
	case 9:{		/* Printout tool */
			switch (event_id(event)) {
			case MS_LEFT:
				{
					if (event_is_down(event)) {
						push();
						temp = 1;
						x1 = event_x(event);
						ya = event_y(event);
						x1 = x1 - x1 % grid;
						ya = ya - ya % grid;
						x2 = x1;
						y2 = ya;
					}
					if (event_is_up(event)) {
						pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
						pw_vector(pw, x1, ya, x1, ya, PIX_SRC ^ PIX_DST, 1);
						temp1 = (int) ((x2 - x1) / 3);
						temp2 = (int) ((y2 - ya) / 3);
						line[0].x = x1;
						line[0].y = ya;
						line[1].x = x2;
						line[1].y = ya;
						line[2].x = x2;
						line[2].y = y2;
						line[3].x = x2 - temp1;
						line[3].y = y2;
						line[4].x = x1 + temp1;
						line[4].y = ya + temp2;
						line[5].x = x1;
						line[5].y = ya + temp2;
						line[6].x = x1;
						line[6].y = ya;
						lines.n = 7;
						lines.ptlist = line;
						cgipw_polyline(&vpw, &lines);
						if (scriptype == 1) {
							sprintf(scriptext, "P %d,%d,%d,%d\n", x1, ya, x2, y2);
							textsw_insert(textsw, scriptext, strlen(scriptext));
						}
						pop();
					}
				}
				break;
			case LOC_DRAG:
				{
					if (temp != 1)
						pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
					temp = 0;
					x2 = event_x(event);
					y2 = event_y(event);
					x2 = x2 - x2 % grid;
					y2 = y2 - y2 % grid;
					pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
				}
			}
		}
		break;
	case 10:{		/* IO */
			switch (event_id(event)) {
			case MS_LEFT:
				{
					if (event_is_down(event)) {
						push();
						temp = 1;
						x1 = event_x(event);
						ya = event_y(event);
						x1 = x1 - x1 % grid;
						ya = ya - ya % grid;
						x2 = x1;
						y2 = ya;
					}
					if (event_is_up(event)) {
						pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
						pw_vector(pw, x1, ya, x1, ya, PIX_SRC ^ PIX_DST, 1);
						temp1 = (int) ((x2 - x1) / 3);
						line[0].x = x1;
						line[0].y = y2;
						line[1].x = x1 + temp1;
						line[1].y = ya;
						line[2].x = x2;
						line[2].y = ya;
						line[3].x = x2 - temp1;
						line[3].y = y2;
						line[4].x = x1;
						line[4].y = y2;
						lines.n = 5;
						lines.ptlist = line;
						cgipw_polyline(&vpw, &lines);
						if (scriptype == 1) {
							sprintf(scriptext, "i %d,%d,%d,%d\n", x1, ya, x2, y2);
							textsw_insert(textsw, scriptext, strlen(scriptext));
						}
						pop();
					}
				}
				break;
			case LOC_DRAG:
				{
					if (temp != 1)
						pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
					temp = 0;
					x2 = event_x(event);
					y2 = event_y(event);
					x2 = x2 - x2 % grid;
					y2 = y2 - y2 % grid;
					pw_vector(pw, x1, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
				}
			}
		}
		break;
	case 11:{
			/* copy */
			switch (event_id(event)) {
			case MS_LEFT:
				{
					if (event_is_down(event)) {
						push();
						temp = 1;
						x1 = event_x(event);
						ya = event_y(event);
						x2 = x1;
						y2 = ya;
					}
					if (event_is_up(event)) {
						pw_vector(pw, x1, ya, x2, ya, PIX_SRC ^ PIX_DST, 1);
						pw_vector(pw, x2, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
						pw_vector(pw, x2, y2, x1, y2, PIX_SRC ^ PIX_DST, 1);
						pw_vector(pw, x1, y2, x1, ya, PIX_SRC ^ PIX_DST, 1);
						pw_read(pr6, 0, 0, (x2 - x1), (y2 - ya), PIX_SRC, pw, x1, ya);
						ClipWidth = x2 - x1;
						ClipHeight = y2 - ya;
					}
				}
				break;
			case LOC_DRAG:
				{
					if (temp != 1) {
						pw_vector(pw, x1, ya, x2, ya, PIX_SRC ^ PIX_DST, 1);
						pw_vector(pw, x2, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
						pw_vector(pw, x2, y2, x1, y2, PIX_SRC ^ PIX_DST, 1);
						pw_vector(pw, x1, y2, x1, ya, PIX_SRC ^ PIX_DST, 1);
					}
					temp = 0;
					x2 = event_x(event);
					y2 = event_y(event);
					pw_vector(pw, x1, ya, x2, ya, PIX_SRC ^ PIX_DST, 1);
					pw_vector(pw, x2, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
					pw_vector(pw, x2, y2, x1, y2, PIX_SRC ^ PIX_DST, 1);
					pw_vector(pw, x1, y2, x1, ya, PIX_SRC ^ PIX_DST, 1);
				}
			}
		}
		break;
	case 12:{
			/* cut */
			switch (event_id(event)) {
			case MS_LEFT:
				{
					if (event_is_down(event)) {
						push();
						temp = 1;
						x1 = event_x(event);
						ya = event_y(event);
						x2 = x1;
						y2 = ya;
					}
					if (event_is_up(event)) {
						pw_vector(pw, x1, ya, x2, ya, PIX_SRC ^ PIX_DST, 1);
						pw_vector(pw, x2, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
						pw_vector(pw, x2, y2, x1, y2, PIX_SRC ^ PIX_DST, 1);
						pw_vector(pw, x1, y2, x1, ya, PIX_SRC ^ PIX_DST, 1);
						pw_read(pr6, 0, 0, (x2 - x1), (y2 - ya), PIX_SRC, pw, x1, ya);
						ClipWidth = x2 - x1;
						ClipHeight = y2 - ya;
						pw_writebackground(pw, x1, ya, (x2 - x1), (y2 - ya), PIX_SRC);
						pop();
					}
				}
				break;
			case LOC_DRAG:
				{
					if (temp != 1) {
						pw_vector(pw, x1, ya, x2, ya, PIX_SRC ^ PIX_DST, 1);
						pw_vector(pw, x2, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
						pw_vector(pw, x2, y2, x1, y2, PIX_SRC ^ PIX_DST, 1);
						pw_vector(pw, x1, y2, x1, ya, PIX_SRC ^ PIX_DST, 1);
					}
					temp = 0;
					x2 = event_x(event);
					y2 = event_y(event);
					pw_vector(pw, x1, ya, x2, ya, PIX_SRC ^ PIX_DST, 1);
					pw_vector(pw, x2, ya, x2, y2, PIX_SRC ^ PIX_DST, 1);
					pw_vector(pw, x2, y2, x1, y2, PIX_SRC ^ PIX_DST, 1);
					pw_vector(pw, x1, y2, x1, ya, PIX_SRC ^ PIX_DST, 1);
				}
			}
		}
		break;
	case 13:{		/* paste */
			if (event_id(event) == MS_LEFT) {
				if (event_is_down(event)) {
					push();
					x3 = event_x(event);
					y3 = event_y(event);
					pw_write(pw, x3 - (int) ClipWidth / 2, y3 - (int) ClipHeight / 2, ClipWidth, ClipHeight, PIX_SRC ^ PIX_DST, pr6, 0, 0);
				}
				if (event_is_up(event)) {
					if (pastetype == 0)
						pw_write(pw, x3 - (int) ClipWidth / 2, y3 - (int) ClipHeight / 2, ClipWidth, ClipHeight, PIX_SRC | PIX_DST, pr6, 0, 0);
					else
						pw_write(pw, x3 - (int) ClipWidth / 2, y3 - (int) ClipHeight / 2, ClipWidth, ClipHeight, PIX_SRC, pr6, 0, 0);
					pop();
				}
			}
			if (event_id(event) == LOC_DRAG) {
				pw_write(pw, x3 - (int) ClipWidth / 2, y3 - (int) ClipHeight / 2, ClipWidth, ClipHeight, PIX_SRC ^ PIX_DST, pr6, 0, 0);
				x3 = event_x(event);
				y3 = event_y(event);
				pw_write(pw, x3 - (int) ClipWidth / 2, y3 - (int) ClipHeight / 2, ClipWidth, ClipHeight, PIX_SRC ^ PIX_DST, pr6, 0, 0);
			}
		}
	}
}

void
which2(item, value, event)
	Panel_item      item;
	unsigned int    value;
	Event          *event;
{
	patterntype = value;
	if (scriptype == 1) {
		sprintf(scriptext, "F %d\n", patterntype);
		textsw_insert(textsw, scriptext, strlen(scriptext));
	}
	if (value > 1) {
		switch (value) {
		case 2:
			hatch_index(2);
			break;
		case 3:
			hatch_index(3);
			break;
		case 4:
			hatch_index(4);
			break;
		case 5:
			hatch_index(5);
			break;
		}
		cgipw_interior_style(&vpw, HATCH, ON);
	}
	if (value == 0)
		cgipw_interior_style(&vpw, HOLLOW, ON);
	if (value == 1)
		cgipw_interior_style(&vpw, SOLIDI, ON);
}

void
which3(item, value, event)
	Panel_item      item;
	unsigned int    value;
	Event          *event;
{
	linetype = value;
	if (scriptype == 1) {
		sprintf(scriptext, "t %d\n", linetype);
		textsw_insert(textsw, scriptext, strlen(scriptext));
	}
	switch (value) {
	case 0:{
			cgipw_line_type(&vpw, SOLID);
			cgipw_perimeter_type(&vpw, SOLID);
		} break;
	case 1:{
			cgipw_line_type(&vpw, DOTTED);
			cgipw_perimeter_type(&vpw, DOTTED);
		} break;
	case 2:{
			cgipw_line_type(&vpw, DASHED);
			cgipw_perimeter_type(&vpw, DASHED);
		} break;
	}
}

void
which4(item, value, event)
	Panel_item      item;
	unsigned int    value;
	Event          *event;
{
	Cfloat          some;
	linewid = value;
	if (scriptype == 1) {
		sprintf(scriptext, "w %d\n", linewid);
		textsw_insert(textsw, scriptext, strlen(scriptext));
	}
	some = (int) value / 4;
	cgipw_line_width(&vpw, some);
	cgipw_perimeter_width(&vpw, some);
}

void
which6(item, value, event)
	Panel_item      item;
	unsigned int    value;
	Event          *event;
{
	loadtype = value;
}

void
which(item, value, event)
	Panel_item      item;
	unsigned int    value;
	Event          *event;
{
	tool = value;
}

void
arrowtyp(item, value, event)
	Panel_item      item;
	unsigned int    value;
	Event          *event;
{
	arrow = value;
	if (scriptype == 1) {
		sprintf(scriptext, "A %d\n", arrow);
		textsw_insert(textsw, scriptext, strlen(scriptext));
	}
}

#ifdef PRINTRONIX

void
Change(item, value, event)
	Panel_item      item;
	unsigned int    value;
	Event          *event;
{
	printtype = value;
}

#endif

void
puttype(item, value, event)
	Panel_item      item;
	unsigned int    value;
	Event          *event;
{
	pastetype = value;
}

void
Scrip(item, value, event)
	Panel_item      item;
	unsigned int    value;
	Event          *event;
{
	scriptype = value;
	if (scriptype == 1) {
		sprintf(scriptext, "%d,%d\n", window_get(canvas, WIN_WIDTH), window_get(canvas, WIN_HEIGHT));
		textsw_insert(textsw, scriptext, strlen(scriptext));
		sprintf(scriptext, "A %d\nw %d\nt %d\ns %d\nF %d\n", arrow, linewid, linetype, size, patterntype);
		textsw_insert(textsw, scriptext, strlen(scriptext));
	}
}



void
eraser(item, value, event)
	Panel_item      item;
	unsigned int    value;
	Event          *event;
{
	size = value;
	if (scriptype == 1) {
		sprintf(scriptext, "s %d\n", size);
		textsw_insert(textsw, scriptext, strlen(scriptext));
	}
}

void
GRID(item, value, event)
	Panel_item      item;
	unsigned int    value;
	Event          *event;
{
	grid = value * 10;
	if (grid == 0)
		grid = 1;
}

void
undo()
{
	Textsw_index    first, last_plus_one;
	pw_batch_on(pw);
	pw_write(pw, 0, 0, SWIDTH, SHEIGHT, PIX_SRC, pr1, 0, 0);
	pop();
	pw_batch_off(pw);
	if (scriptype == 1) {
		first = (int) window_get(textsw, TEXTSW_INSERTION_POINT) - strlen(scriptext);
		last_plus_one = (int) window_get(textsw, TEXTSW_INSERTION_POINT);
		textsw_erase(textsw, first, last_plus_one);
	}
}

void
inve()
{
	pr_rop(pr6, 0, 0, ClipWidth, ClipHeight, PIX_NOT(PIX_DST), pr6, 0, 0);
}

void
fliphoriz()
{
	int             i, j, k, l, temp;
	for (i = 1; i <= ClipWidth / 2; i++) {
		for (j = 1; j <= ClipHeight; j++) {
			k = (int) pr_get(pr6, i, j);
			l = (int) pr_get(pr6, ClipWidth - i, j);
			temp = k;
			k = l;
			l = temp;
			pr_put(pr6, i, j, k);
			pr_put(pr6, ClipWidth - i, j, l);
		}
	}
}

void
flipvert()
{
	int             i, j, k, l, temp;
	for (i = 1; i <= ClipHeight / 2; i++) {
		for (j = 1; j <= ClipWidth; j++) {
			k = (int) pr_get(pr6, j, i);
			l = (int) pr_get(pr6, j, ClipHeight - i);
			temp = k;
			k = l;
			l = temp;
			pr_put(pr6, j, i, k);
			pr_put(pr6, j, ClipHeight - i, l);
		}
	}
}

void
enlarge()
{
	struct pixrect *pr7;
	int             i, j, k, l, m;
	pr7 = mem_create(ClipWidth * 2, ClipHeight * 2, 1);
	for (i = 1; i < ClipWidth; i++) {
		for (j = 1; j < ClipHeight; j++) {
			k = (int) pr_get(pr6, i, j);
			l = (i - 1) * 2 + 1;
			m = (j - 1) * 2 + 1;
			pr_put(pr7, l, m, k);
			pr_put(pr7, l + 1, m, k);
			pr_put(pr7, l + 1, m + 1, k);
			pr_put(pr7, l, m + 1, k);
		}
	}
	ClipHeight     *= 2;
	ClipWidth      *= 2;
	pr_rop(pr6, 0, 0, ClipWidth, ClipHeight, PIX_SRC, pr7, 0, 0);
	pr_destroy(pr7);
}

void 
reduce()
{
	struct pixrect *pr7;
	int             i, j, k, l, m;
	pr7 = mem_create(ClipWidth * 2, ClipHeight * 2, 1);
	for (i = 1; i <= ClipWidth / 2; i++) {
		for (j = 1; j <= ClipHeight / 2; j++) {
			l = (i - 1) * 2 + 1;
			m = (j - 1) * 2 + 1;
			k = (int) pr_get(pr6, l, m) + (int) pr_get(pr6, l + 1, m) + (int) pr_get(pr6, l, m + 1) + (int) pr_get(pr6, l + 1, m + 1);
			if (k > 0)
				k = 1;
			else
				k = 0;
			pr_put(pr7, i, j, k);
		}
	}
	ClipHeight / = 2;
	ClipWidth / = 2;
	pr_rop(pr6, 0, 0, ClipWidth, ClipHeight, PIX_SRC, pr7, 0, 0);
	pr_destroy(pr7);

}

static void
quit()
{
	textsw_reset(textsw, 0, 0);
	window_destroy(frame);
	window_destroy(frame2);
	window_destroy(frame3);
	pr_destroy(pr);
	pr_destroy(pr6);
	pr_destroy(pr1);
	pr_destroy(pr3);
	close_cgi_pw(&vpw);
	close_cgi_pw(&vpw2);
	close_pw_cgi();
}

unpack_bits(source, dest, len)
	char           *(*source), *(*dest);
int             len;
{
	char           *d, count, ch;

	for (d = (*dest); (*dest) - d < len;)
		if ((count = *(*source)++) < 0) {
			ch = *(*source)++;
			for (count = 1 - count; count > 0; count--)
				*(*dest)++ = ch;
		} else
			for (count += 1; count > 0; count--)
				*(*dest)++ = *(*source)++;
}

display_line(row, line, length, screen)
	char            line[LINE_LEN];
int             row, length;
struct pixrect *screen;
{
	int             i, j, col;
	char            ich;
	/* loop over bytes per line */
	for (col = 0, i = 0; i < length; i++) {
		ich = line[i];
		/* loop over 8 bits per byte */
		for (j = col + 7; j >= col; j--) {
			pr_put(screen, j, row, (ich & 1));
			ich = ich >> 1;
		}
		col += 8;
	}
}


static void
load()
{
	char            frame_label[80], real[80], real2[85];
	FILE           *fil9, *fil2, *fil3;
	struct pixrect *picture;
	int             row;
	char            ch, *src, *dest;
	struct pixrect *pic;
	struct rasterfile rh;

	sprintf(frame_label, "KironDraw : %s", panel_get_value(fname_item));
	sprintf(real, "%s", panel_get_value(fname_item));
	sprintf(real2, "%sinfo", panel_get_value(fname_item));
	window_set(frame, FRAME_LABEL, frame_label, 0);
	pw_writebackground(pw, 0, 0, SWIDTH, SHEIGHT, PIX_SRC);
	if (checkraster(real) == 0) {
		if (loadtype == 0) {
			fil9 = fopen(real, "rb");
			if (fil9 == NULL) {
				window_set(canvas, WIN_WIDTH, NORMALW, WIN_HEIGHT, NORMALH, 0);
				window_fit(frame);
			} else {
				pr_load_header(fil9, &rh);
				newwid = rh.ras_width;
				newhei = rh.ras_height;
				window_set(canvas, WIN_WIDTH, rh.ras_width, WIN_HEIGHT, rh.ras_height, 0);
				window_fit(frame);
				fclose(fil9);
			}
			fil3 = fopen(real, "rb");
			if (fil3 != NULL) {
				pic = mem_create(window_get(canvas, WIN_WIDTH), window_get(canvas, WIN_HEIGHT), 1);
				pic = pr_load(fil3, NULL);
				pw_write(pw, 0, 0, newwid, newhei, PIX_SRC, pic, 0, 0);
				pop();
				pr_destroy(pic);
				fclose(fil3);
			}
		} else if (loadtype == 1) {
			newhei = NROWS;
			newwid = NCOLS;
			window_set(canvas, WIN_WIDTH, newwid, WIN_HEIGHT, newhei, 0);
			window_fit(frame);
			fil2 = fopen(real, "rb");
			if (fil2 != NULL) {
				fseek(fil2, 512L, 0);
				fread(src_buf, SRC_SIZE, 1, fil2);
				src = src_buf;
				picture = mem_create(NCOLS, NROWS, 1);
				for (row = 0; row < NROWS; row++) {
					dest = scan_line;
					unpack_bits(&src, &dest, LINE_LEN);
					if (src > src_buf + SRC_SIZE - BLOCK_SIZE) {
						memcpy(src_buf, src_buf + SRC_SIZE - BLOCK_SIZE, BLOCK_SIZE);
						fread(src_buf + BLOCK_SIZE, SRC_SIZE - BLOCK_SIZE, 1, fil2);
						src -= SRC_SIZE - BLOCK_SIZE;
					}
					display_line(row, scan_line, LINE_LEN, picture);
				}
				fclose(fil2);
				pw_batch_on(pw);
				pw_write(pw, 0, 0, NCOLS, NROWS, PIX_SRC, picture, 0, 0);
				pw_batch_off(pw);
				pop();
			}
		}
	}
}

static void
clearwin()
{
	window_set(canvas, WIN_WIDTH, NORMALW, WIN_HEIGHT, NORMALH, 0);
	window_fit(frame);
	pw_batch_on(pw);
	pw_writebackground(pw, 0, 0, SWIDTH, SHEIGHT, PIX_SRC);
	pw_read(pr, 0, 0, SWIDTH, SHEIGHT, PIX_SRC, pw, 0, 0);
	pw_batch_off(pw);
	textsw_reset(textsw, 0, 0);
}

static void
sasc()
{
	char            real[80], real2[80];
	FILE           *fil;
	sprintf(real, "%s.script", panel_get_value(fname_item));
	sprintf(real2, "rm %s.script", panel_get_value(fname_item));
	fil = fopen(real, "r");
	if (fil != NULL)
		system(real2);
	sprintf(scriptext, "#D\nz\n");
	textsw_insert(textsw, scriptext, strlen(scriptext));
	textsw_store_file(textsw, real, 0, 0);
}

static void
save()
{
	char            frame_label[80], real[80], real2[85];
	FILE           *fil;
	struct pixrect *pic;
	sprintf(frame_label, "KironDraw : %s", panel_get_value(fname_item));
	sprintf(real, "%s", panel_get_value(fname_item));
	window_set(frame, FRAME_LABEL, frame_label, 0);
	if (savetype == 0) {
		sprintf(real2, "%sinfo", panel_get_value(fname_item));
		fil = fopen(real, "wb");
		pic = mem_create(window_get(canvas, WIN_WIDTH), window_get(canvas, WIN_HEIGHT), 1);
		pw_read(pic, 0, 0, window_get(canvas, WIN_WIDTH), window_get(canvas, WIN_HEIGHT), PIX_SRC, pw, 0, 0);
		pr_dump(pic, fil, NULL, RT_STANDARD, TRUE);
		pr_destroy(pic);
		fclose(fil);
	}
}

#ifdef PRINTRONIX
static void
print()
{
	FILE           *fil;
	char            real2[80];
	struct pixrect *pic;
	fil = fopen("/usr/tmp/KironDrawtemp", "wb");
	pic = mem_create(window_get(canvas, WIN_WIDTH), window_get(canvas, WIN_HEIGHT), 1);
	pw_read(pic, 0, 0, window_get(canvas, WIN_WIDTH), window_get(canvas, WIN_HEIGHT), PIX_SRC, pw, 0, 0);
	pr_dump(pic, fil, NULL, RT_STANDARD, TRUE);
	pr_destroy(pic);
	fclose(fil);
	if ((int) window_get(canvas, WIN_WIDTH) > MAXPRINWID) {
		if (printtype == 0)
			system("rotate < /usr/tmp/KironDrawtemp | printronix | lpr -l");
		else {
			sprintf(real2, "rotate < /usr/tmp/KironDrawtemp  | printronix > %s", panel_get_value(fname_item));
			system(real2);
		}
	} else {
		if (printtype == 0)
			system("printronix < /usr/tmp/KironDrawtemp | lpr -l");
		else {
			sprintf(real2, "printronix < /usr/tmp/KironDrawtemp > %s", panel_get_value(fname_item));
		}
		system(real2);
	}
	system("rm /usr/tmp/KironDrawtemp");
}
#endif

static void
excs()
{
	char            filename[80];
	FILE           *fil;
	Cfloat          some;
	int             exar, exes;
	int             width, height, ax1, ax2, radi;
	char            type, type2;
	char            writext[80], *label2;
	sprintf(filename, "%s.script", panel_get_value(fname_item));
	if (checkascii(filename) == 0) {
		window_set(textsw, TEXTSW_FILE, filename, 0);
		window_set(textsw, TEXTSW_INSERTION_POINT, window_get(textsw, TEXTSW_LENGTH), 0);
		fil = fopen(filename, "r");
		if (fil != NULL) {
			pw_writebackground(pw2, 0, 0, SWIDTH, SHEIGHT, PIX_SRC);
			fscanf(fil, "%d,%d\n", &width, &height);
			fscanf(fil, "%c%c", &type, &type2);
			exar = 0;
			exes = 1;
			cgipw_line_type(&vpw2, SOLID);
			cgipw_perimeter_type(&vpw2, SOLID);
			cgipw_interior_style(&vpw2, HOLLOW, ON);
			cgipw_line_width(&vpw2, 1);
			cgipw_perimeter_width(&vpw2, 1);
			do {
				switch (type) {
				case 'l':{	/* line script	 */
						fscanf(fil, "%d,%d,%d,%d\n", &line[0].x, &line[0].y, &line[1].x, &line[1].y);
						lines.n = 2;
						lines.ptlist = line;
						cgipw_polyline(&vpw2, &lines);
						if ((exar == 1) || (exar == 3)) {
							first.x = line[0].x;
							first.y = line[0].y;
							radi = 2;
							cgipw_circle(&vpw2, &first, radi);
						}
						if ((exar == 2) || (exar == 3)) {
							first.x = line[1].x;
							first.y = line[1].y;
							radi = 2;
							cgipw_circle(&vpw2, &first, radi);
						}
						fscanf(fil, "%c%c", &type, &type2);
					}
					break;
				case 'r':{	/* rectangle script	 */
						fscanf(fil, "%d,%d,%d,%d\n", &first.x, &first.y, &second.x, &second.y);
						cgipw_rectangle(&vpw2, &first, &second);
						fscanf(fil, "%c%c", &type, &type2);
					}
					break;
				case 'c':{	/* circle script	 */
						fscanf(fil, "%d,%d,%d\n", &first.x, &first.y, &ax1);
						cgipw_circle(&vpw2, &first, ax1);
						fscanf(fil, "%c%c", &type, &type2);
					}
					break;
				case 'e':{	/* ellipse script	 */
						fscanf(fil, "%d,%d,%d,%d\n", &first.x, &first.y, &ax1, &ax2);
						cgipw_ellipse(&vpw2, &first, ax1, ax2);
						fscanf(fil, "%c%c", &type, &type2);
					}
					break;
				case 'd':{	/* dataflow tool script	 */
						fscanf(fil, "%d,%d,%d,%d\n", &first.x, &first.y, &second.x, &second.y);
						line[0].x = second.x;
						line[0].y = first.y;
						line[1].x = first.x;
						line[1].y = first.y;
						line[2].x = first.x;
						line[2].y = second.y;
						line[3].x = second.x;
						line[3].y = second.y;
						lines.n = 4;
						lines.ptlist = line;
						cgipw_polyline(&vpw2, &lines);
						fscanf(fil, "%c%c", &type, &type2);
					}
					break;
				case 'C':{	/* conditional tool	 */
						fscanf(fil, "%d,%d,%d,%d\n", &first.x, &first.y, &second.x, &second.y);
						temp1 = (int) ((second.x - first.x) / 2);
						temp2 = (int) ((second.y - first.y) / 2);
						line[0].x = first.x + temp1;
						line[0].y = first.y;
						line[1].x = first.x;
						line[1].y = first.y + temp2;
						line[2].x = first.x + temp1;
						line[2].y = second.y;
						line[3].x = second.x;
						line[3].y = first.y + temp2;
						line[4].x = first.x + temp1;
						line[4].y = first.y;
						lines.n = 5;
						lines.ptlist = line;
						cgipw_polyline(&vpw2, &lines);
						fscanf(fil, "%c%c", &type, &type2);
					}
					break;
				case 'i':{	/* IO tool		 */
						fscanf(fil, "%d,%d,%d,%d\n", &first.x, &first.y, &second.x, &second.y);
						temp1 = (int) ((second.x - first.x) / 3);
						line[0].x = first.x;
						line[0].y = second.y;
						line[1].x = first.x + temp1;
						line[1].y = first.y;
						line[2].x = second.x;
						line[2].y = first.y;
						line[3].x = second.x - temp1;
						line[3].y = second.y;
						line[4].x = first.x;
						line[4].y = second.y;
						lines.n = 5;
						lines.ptlist = line;
						cgipw_polyline(&vpw2, &lines);
						fscanf(fil, "%c%c", &type, &type2);
					}
					break;
				case 'p':{	/* Point tool 	 */
						fscanf(fil, "%d,%d\n", &line[0].x, &line[0].y);
						fscanf(fil, "%c ", &type);
						while (type == 'p') {
							fscanf(fil, "%d,%d\n", &line[1].x, &line[1].y);
							lines.n = 2;
							lines.ptlist = line;
							cgipw_polyline(&vpw2, &lines);
							line[0].x = line[1].x;
							line[0].y = line[1].y;
							fscanf(fil, "%c%c", &type, &type2);
						}
					}
					break;
				case 'E':{	/* Eraser tool	 */
						do {
							fscanf(fil, "%d,%d\n", &ax1, &ax2);
							pw_writebackground(pw2, ax1, ax2, exes, exes, PIX_SRC);
							fscanf(fil, "%c%c", &type, &type2);
						} while (type == 'E');
					}
					break;
				case 'P':{	/* Printout tool	 */
						fscanf(fil, "%d,%d,%d,%d\n", &first.x, &first.y, &second.x, &second.y);
						temp1 = (int) ((second.x - first.x) / 3);
						temp2 = (int) ((second.y - first.y) / 2);
						line[0].x = first.x;
						line[0].y = first.y;
						line[1].x = second.x;
						line[1].y = first.y;
						line[2].x = second.x;
						line[2].y = second.y;
						line[3].x = second.x - temp1;
						line[3].y = second.y;
						line[4].x = first.x + temp1;
						line[4].y = first.y + temp2;
						line[5].x = first.x;
						line[5].y = first.y + temp2;
						line[6].x = first.x;
						line[6].y = first.y;
						lines.n = 7;
						lines.ptlist = line;
						cgipw_polyline(&vpw2, &lines);
						fscanf(fil, "%c%c", &type, &type2);
					}
					break;
				case 'F':{	/* Fill Pattern	 */
						fscanf(fil, "%d\n", &ax1);
						if (ax1 > 1) {
							switch (ax1) {
							case 2:
								hatch_index(2);
								break;
							case 3:
								hatch_index(3);
								break;
							case 4:
								hatch_index(4);
								break;
							case 5:
								hatch_index(5);
								break;
							}
							cgipw_interior_style(&vpw2, HATCH, ON);
						}
						if (ax1 == 0)
							cgipw_interior_style(&vpw2, HOLLOW, ON);
						if (ax1 == 1)
							cgipw_interior_style(&vpw2, SOLIDI, ON);
						fscanf(fil, "%c%c", &type, &type2);
					}
					break;
				case 'T':{	/* text tool	 */
						fscanf(fil, "%d,%d ", &ax1, &ax2, &type2);
						label2 = fgets(writext, 80, fil);
						pw_text(pw2, ax1, ax2, PIX_SRC | PIX_DST, NULL, label2);
						fscanf(fil, "\n");
						fscanf(fil, "%c%c", &type, &type2);
					}
					break;
				case 't':{	/* line type 	 */
						fscanf(fil, "%d\n", &ax1);
						switch (ax1) {
						case 0:{
								cgipw_line_type(&vpw2, SOLID);
								cgipw_perimeter_type(&vpw2, SOLID);
							} break;
						case 1:{
								cgipw_line_type(&vpw2, DOTTED);
								cgipw_perimeter_type(&vpw2, DOTTED);
							} break;
						case 2:{
								cgipw_line_type(&vpw2, DASHED);
								cgipw_perimeter_type(&vpw2, DASHED);
							} break;
						}
						fscanf(fil, "%c%c", &type, &type2);
					}
					break;
				case 'w':{	/* line width	 */
						fscanf(fil, "%d\n", &ax1);
						some = (int) ax1 / 4;
						cgipw_line_width(&vpw2, some);
						cgipw_perimeter_width(&vpw2, some);
						fscanf(fil, "%c%c", &type, &type2);
					}
					break;
				case 's':{	/* eraser width	 */
						fscanf(fil, "%d\n", &ax1);
						exes = ax1;
						fscanf(fil, "%c%c", &type, &type2);
					}
					break;
				case 'A':{	/* arrows		 */
						fscanf(fil, "%d\n", &ax1);
						exar = ax1;
						fscanf(fil, "%c%c", &type, &type2);
					}
					break;
				case '#':{	/* command lines */
						switch (type2) {
						case 'N':{
								fscanf(fil, "\n");
								pw_writebackground(pw2, 0, 0, SWIDTH, SHEIGHT, PIX_SRC);
								fscanf(fil, "%c%c", &type, &type2);
							}
							break;
						case 'D':{
								fscanf(fil, "\n");
								window_set(canvas, WIN_WIDTH, width, WIN_HEIGHT, height, 0);
								window_fit(frame);
								push();
								pw_batch_on(pw2);
								pw_read(pr4, 0, 0, SWIDTH, SHEIGHT, PIX_SRC, pw2, 0, 0);
								pw_write(pw, 0, 0, SWIDTH, SHEIGHT, PIX_SRC, pr4, 0, 0);
								pw_batch_off(pw2);
								pop();
								fscanf(fil, "%c%c", &type, &type2);
							}
						case 'P':{
								fscanf(fil, "\n");
								pw_batch_on(pw2);
								pw_read(pr6, 0, 0, width, height, PIX_SRC, pw2, 0, 0);
								ClipWidth = width;
								ClipHeight = height;
								pw_batch_off(pw2);
								fscanf(fil, "%c%c", &type, &type2);
							}
						}
					}
				}
			} while (type != 'z');
		}
		fclose(fil);
	}
}

main(argc, argv)
	int             argc;
	char          **argv;
{
	frame = window_create(NULL, FRAME, FRAME_NO_CONFIRM, TRUE, FRAME_ICON, &hello_icon, FRAME_LABEL, "KironDraw Version 2.4b by Kiron D. Bondale / last update 9/04/89", 0);
	frame2 = window_create(NULL, FRAME, FRAME_NO_CONFIRM, TRUE, FRAME_ICON, &hello_icon, WIN_ROWS, 15, FRAME_LABEL, "KironDraw Tools - KironDraw Version 2.4b by Kiron D. Bondale / last update 9/04/89", 0);
	frame3 = window_create(NULL, FRAME, FRAME_NO_CONFIRM, TRUE, 0);
	panel = window_create(frame2, PANEL, WIN_ROWS, 7, 0);
	textsw = window_create(frame2, TEXTSW, WIN_ROWS, 8, 0);
	fname_item = panel_create_item(panel, PANEL_TEXT, PANEL_LABEL_STRING, "Filename : ", PANEL_VALUE_DISPLAY_LENGTH, 23, PANEL_VALUE_STORED_LENGTH, 80, 0);
	tname_item = panel_create_item(panel, PANEL_TEXT, PANEL_LABEL_STRING, "Text: ", PANEL_VALUE_DISPLAY_LENGTH, 35, PANEL_VALUE_STORED_LENGTH, 35, 0);
	panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(panel, "New", 4, 0), PANEL_NOTIFY_PROC, clearwin, 0);
	panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(panel, "Load", 5, 0), PANEL_NOTIFY_PROC, load, 0);
	panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(panel, "Save", 5, 0), PANEL_NOTIFY_PROC, save, 0);
	panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(panel, "Undo", 5, 0), PANEL_NOTIFY_PROC, undo, 0);
#ifdef PRINTRONIX
	panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(panel, "Print", 6, 0), PANEL_NOTIFY_PROC, print, 0);
#endif
	panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(panel, "Quit", 5, 0), PANEL_NOTIFY_PROC, quit, 0);
	panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(panel, "Execute Script", 11, 0), PANEL_NOTIFY_PROC, excs, 0);
	panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(panel, "Save Script", 11, 0), PANEL_NOTIFY_PROC, sasc, 0);
	panel_create_item(panel, PANEL_CYCLE, PANEL_LABEL_STRING, "Load type ", PANEL_CHOICE_STRINGS, "Sun RasterFiles", "MacPaint", 0, PANEL_NOTIFY_PROC, which6, 0);
	panel_create_item(panel, PANEL_SLIDER, PANEL_LABEL_STRING, "Eraser size ", PANEL_VALUE, 1, PANEL_MIN_VALUE, 1, PANEL_MAX_VALUE, 100, PANEL_SLIDER_WIDTH, 100, PANEL_NOTIFY_PROC, eraser, 0);
	panel_create_item(panel, PANEL_CHOICE, PANEL_CHOICE_IMAGES, &sued_line, &sued_point, &sued_box, &sued_circle, &sued_text, &sued_eraser, &sued_ellipse, &sued_data, &sued_condi, &sued_io, &sued_some, &sued_copy, &sued_cut, &sued_paste, 0, PANEL_MENU_CHOICE
_STRINGS, "Line", "Point", "Rect", "Circle", "Text", "Erase", "Ellipse", "Dataflow", "Conditional", "Printout", "I/O", "Copy", "Cut", "Paste", 0, PANEL_NOTIFY_PROC, which, PANEL_FEEDBACK, PANEL_INVERTED, PANEL_NOMARK_IMAGES, 0, 0);
#ifdef PRINTRONIX
	panel_create_item(panel, PANEL_CYCLE, PANEL_LABEL_STRING, "Print type ", PANEL_CHOICE_STRINGS, "To Printer", "To File", 0, PANEL_NOTIFY_PROC, Change, 0);
#endif
	panel_create_item(panel, PANEL_CYCLE, PANEL_LABEL_STRING, "Scripting ", PANEL_CHOICE_STRINGS, "No", "Yes", 0, PANEL_NOTIFY_PROC, Scrip, 0);
	panel_create_item(panel, PANEL_CYCLE, PANEL_LABEL_STRING, "Grid size ", PANEL_CHOICE_STRINGS, "0", "1", "2", "3", "4", "5", "6", 0, PANEL_NOTIFY_PROC, GRID, 0);
	panel_create_item(panel, PANEL_CYCLE, PANEL_LABEL_STRING, "Patterns ", PANEL_CHOICE_STRINGS, "Hollow", "Solid", "White", "25% grey", "50% grey", "75% grey", 0, PANEL_NOTIFY_PROC, which2, 0);
	panel_create_item(panel, PANEL_CYCLE, PANEL_LABEL_STRING, "Line Styles ", PANEL_CHOICE_STRINGS, "Solid", "Dotted", "Dashed", 0, PANEL_NOTIFY_PROC, which3, 0);
	panel_create_item(panel, PANEL_CYCLE, PANEL_LABEL_STRING, "Arrows ", PANEL_CHOICE_STRINGS, "None", "Beginning", "End", "Both", 0, PANEL_NOTIFY_PROC, arrowtyp, 0);
	panel_create_item(panel, PANEL_SLIDER, PANEL_LABEL_STRING, "Line width ", PANEL_VALUE, 1, PANEL_MIN_VALUE, 1, PANEL_MAX_VALUE, 20, PANEL_SLIDER_WIDTH, 50, PANEL_NOTIFY_PROC, which4, 0);
	panel_create_item(panel, PANEL_CYCLE, PANEL_LABEL_STRING, "Put Type ", PANEL_CHOICE_STRINGS, "transparent", "solid", 0, PANEL_NOTIFY_PROC, puttype, 0);
	panel_create_item(panel, PANEL_MESSAGE, PANEL_LABEL_STRING, "Clipboard Operations", 0);
	panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_IMAGE, &sued_invert, PANEL_NOTIFY_PROC, inve, 0);
	panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_IMAGE, &sued_fliph, PANEL_NOTIFY_PROC, fliphoriz, 0);
	panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_IMAGE, &sued_flipv, PANEL_NOTIFY_PROC, flipvert, 0);
	panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_IMAGE, &sued_enlarge, PANEL_NOTIFY_PROC, enlarge, 0);
	panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_IMAGE, &sued_reduce, PANEL_NOTIFY_PROC, reduce, 0);
	canvas2 = window_create(frame3, CANVAS, 0);
	pw2 = canvas_pixwin(canvas2);
	canvas = window_create(frame, CANVAS, 0);
	pw = canvas_pixwin(canvas);
	open_pw_cgi();
	open_cgi_pw(pw, &vpw, &name);
	open_cgi_pw(pw2, &vpw2, &name2);
	pattern_table(2, 4, 4, pattern1);
	pattern_table(3, 4, 4, pattern2);
	pattern_table(4, 4, 4, pattern3);
	pattern_table(5, 4, 4, pattern4);
	pr1 = mem_create(SWIDTH, SHEIGHT, 1);
	pr = mem_create(SWIDTH, SHEIGHT, 1);
	pr6 = mem_create(SWIDTH, SHEIGHT, 1);
	pr3 = mem_create(SWIDTH, SHEIGHT, 1);
	pr4 = mem_create(SWIDTH, SHEIGHT, 1);
	pastetype = 0;
	linetype = 0;
	linewid = 1;
	patterntype = 0;
	size = 1;
	grid = 1;
	window_set(canvas, CANVAS_RESIZE_PROC, refr, CANVAS_FAST_MONO, TRUE, WIN_CONSUME_PICK_EVENT, LOC_DRAG, WIN_CONSUME_PICK_EVENT, LOC_TRAJECTORY, WIN_CONSUME_PICK_EVENT, WIN_IN_TRANSIT_EVENTS, WIN_EVENT_PROC, test, 0);
	getwd(pathname);
	panel_set_value(fname_item, pathname);
	window_set(frame2, WIN_SHOW, TRUE, 0);
	window_main_loop(frame);
	exit(0);
}
//E*O*F kirondraw.c//

echo x - kirondraw.l
cat > "kirondraw.l" << '//E*O*F kirondraw.l//'
.TH KIRONDRAW 1 "9 April 1989"
.SH NAME
KironDraw \- bitmap graphic editor for the SunView environment (Version 2.4b)
.SH SYNOPSIS
\fBKironDraw\fP
.SH DESCRIPTION
.br
.br
.SH Introduction
.br
.br
KironDraw supports the following :
.br
	Drawing Tools, Attribute modifiers, Bitmap tools, IO functions, scripting tools, and Clipboard tools.
.br
.br
.SH Human Interface
.br
.br
	When invoked with the "KironDraw" command, the following two windows will appear :  a canvas window which is used for drawing, and a tool window which is used for accessing KironDraw's functions.
.br
	All input to KironDraw is accomplished by means of the left-button on the mouse, and the keyboard.
.br
.br
.SH Drawing Tools
.br
.br
	The drawing tools may be selected from the Tool Panel by clicking one of the drawing tool pictograms.  The following tools are available : Line, Point, Rectangle, Circle, Text, Ellipse, Eraser, Data source, IO, Conditional.	
.br
	The Line tool is used to draw straight lines.  To use it, click at the starting point of the line, and drag to the end point.  Once the button is released, the line is drawn.
.br
	The Point tool is used for freehand drawing of curves or other intricate figures.  To use it, click at the starting point of the figure, and drag around the canvas.  
.br
	The Rectangle tool is used to draw rectangles.  To use it, click at the top-left-hand corner of the rectangle, and drag to the lower-right-hand corner.  Once the button is released, the rectangle is drawn.
.br
	The Circle tool is used to draw circles.  To use it, click at the center of the circle you wish drawn, and drag to a point on the outer rim of the circle.  Once the button is released, the circle is drawn.
.br
	The Text tool is used to place text on the canvas.  To use it, first type some text in the text item of the panel, click the text tool pictogram and click on the canvas.  The placed text may then be dragged around the canvas. When you are satisfied as to
 the positioning of the text, release the button.
.br
	The Ellipse tool is used in an identical fashion to the circle tool.
.br
	The Eraser tool is used to remove pixels from the canvas. Usage consists of clicking at the starting position on the canvas, and dragging the eraser around to erase objects.
.br
	The Data source, IO, and Conditional tools are used in an identical fashion to the rectangle tool.
.br
.br
.SH Attribute Modifiers
.br
.br
	Attribute modifiers may be selected from the Tool Panel by clicking one of the following items :
.br
	Grid size, Line width, Line type, Fill type, Eraser size, Paste type, and Arrows.  Modifiers are used by clicking on their selection fields to change their types.
.br
	Grid size is a modifier that is used to align shapes to an "invisible grid" on the canvas.  A grid size of zero signifies that shapes may be placed anywhere on the canvas, and may have any dimension.  A larger grid size will constrain objects to certain 
positions and sizes.  It is useful for creating congruent shapes, or lining shapes up.  All drawing tools are affected by grid size.
.br
	Line width is a modifier that changes the width of lines used by all drawing tools.  The default line width is one pixel.  Line widths may vary from one to twenty pixels.
.br
	Line type is a modifier that changes the type of lines used by all drawing tools.  The default line type is solid.  Line types can solid, dotted, or dashed.
.br
	Fill type is a modifier that changes the interior of certain drawn shapes.  The affected tools are the rectangle tool, the circle tool, and the ellipse tool.  The default fill type is hollow.  Fill types can be hollow, white, black, 25% grey, 50% grey, o
r 75% grey.
.br
	Eraser size is a modifier that affects the eraser size only.  The default eraser size is one pixel by  one pixel.  Eraser sizes can vary from one pixel squared to one hundred pixels squared.
.br
	Put type is a modifier that decides how a cut or copied bitmap will be saved.  Default is transparent.  Selecting solid will delete the rectangle below the placed bitmap, selecting transparent will show what is under the placed bitmap.
.br
	Arrows is a modifier that affects the line tool only.  The default arrow type is no arrows.  Arrow types can be no arrows, arrow at beginning, arrow at end, or arrow at beginning and end.
.br
.br
.SH Bitmap tools
.br
.br
	Bitmap tools may be selected from the Tool Panel by clicking the Cut, Copy, or Paste pictograms, or by clicking the Undo button.  Bitmap tools are tools that operate on regions of the canvas.
.br
	The Cut tool is used to remove a rectangular region of the canvas and maintain it on a "clipboard" for future use by the Paste tool.  It is used in a similar manner to the Rectangle tool.
.br
	The Copy tool is  identical to the Cut tool,  except that the original region is not removed.
.br
	The Paste tool is used to place the clipboard contents onto the canvas.  It is used by selecting the Paste tool, and clicking on the canvas.  The clipboard contents will appear on the canvas and can be dragged around the canvas.  Once the button is relea
sed, the image will be "pasted" onto the canvas.  Pasting the clipboard contents does not remove the contents from the clipboard, hence it is possible to duplicate intricate shapes many times instead of re-drawing them every time.
.br
	The Undo tool simply undoes the previous operation.  
.br
.br
.SH IO tools
.br
.br
	IO tools are used for saving, loading, and printing KironDraw files.  They are the Load, Save, New, Quit, and Print buttons.  Modifiers for these are Print type, and Load type.
.br
	The Load tool is used to load a KironDraw file.  Clicking on the Load button will cause the file specified by the Filename field and the current Load type to be loaded.  The loaded file's name will become the canvas frame's new label.
.br
	The Save tool is used to save a KironDraw file.  Clicking on the Save button will cause the file specified by the Filename field to be saved.  The saved file's name will become the canvas frame's new label.
.br
	The New tool is used to clear the canvas.  Clicking the New button will delete the contents of the canvas and blank the canvas's frame label.
.br
	The Quit tool is used to quit KironDraw.  When clicked, KironDraw will terminate.
.br
	The Print tool is used to print an image.  When clicked, the current image will be dumped to the current Print type.  Presently the Print command only works with Printronix printers...
.br
	The Print type modifier is used to change the print destination.  The default Print type is the printer.  Print types can be printer, or a file.  If the Print type is file, then the file specified by the Filename field will contain the image.  This file 
can then be integrated with other text files for eventual printing.  Presently the Print command only works with Printronix printers...
.br
	The Load type modifier is used to change the type of file that is loaded when the Load button is clicked.  The default Load type is Sun Rasterfile.  Load types can be Sun Rasterfile, or MacPaint file.  If the Load type is MacPaint file, then a previously
 saved MacPaint binary file is loaded when the Load button is clicked.
.br
.br
.SH Scripting tools
.br
.br
	"Scripting" is the act of creating a text file that contains graphic commands for creating a KironDraw document... it's usefulness is in permitting the creation or edition of images without being at a Sun station.  Presently it is only possible to load s
cripts into KironDraw : This is accomplished by creating a script file (in vi or whatever) with the name : xxxxxxx.script where xxxxxxx can be any filename, specifying this name in the filename prompt in KironDraw (without the .script extension) and then 
clicking "execute script".
.br
	Script files are composed of the following :
.br
.br
	Header
.br
	Rules
.br
	Command Lines
.br
Header : Presently, all that is in the header is width, height
.br
Rules : Any or all of the following
.br
	l x1,y1,x2,y2	-	draws a line from x1,y1 to x2,y2
.br
.br
	r x1,y1,x2,y2	-	draws a rectangle from x1,y1 (top left) to x2,y2(lower right)
.br
.br
	c x1,y1,radius  -	draws a circle with at center x1,y1
.br
.br
	e x1,y1,m1,m2	-	draws an ellipse at center x1,y1 with major axis m1, minor axis m2...(note m1 > m2)
.br
.br
	d x1,y1,x2,y2 	-	draws a datasink similar to rectangle
.br
.br
	C x1,y1,x2,y2	-	draws a conditional box, similar to rectangle
.br
.br
	i x1,y1,x2,y2	-	draws an IO box, similar to rectangle
.br
.br
	p x1,y1	
.br
	p x2,y2
.br
	 ...
.br
	p xn,yn		-	draws lines between p1 - pn
.br
.br
	E x1,y1
.br
	E x2,y2
.br
	 ...
.br
	E xn,yn		-	erases squares with topleft corner xa,ya with sides as current eraser size.
.br
.br
	P x1,y1,x2,y2	-	draws a printout tool, similar to rectangle
.br
.br
	F x		-	defines the fill pattern for shapes, x defined as one of these :
.br
					0	hollow
					1	black
					2	white
					3	25% grey
					4	50% grey
					5	75% grey
.br
.br
	T x1,y1 <some string>  - draws text defined by <some string> at x1,y1
.br
.br
	t x		-	changes the line type : x defined as
					0	solid
					1	dotted
					2	dashed
.br
.br
	w x		-	changes the line width
.br
.br
	s x		-	changes the eraser width
.br
.br
	A x		-	changes the arrow type : x defined as
					0	none
					1	beginning
					2	end
					3	at both ends
.br
.br
Command Lines
.br
Command lines start with a # and are immediately followed by :
.br
N	-	clear the screen
.br
D	-	dump current script image to screen
.br
P	-	dump current script image to clipboard
.br
.br
	REMEMBER THOUGH, ALL SPACES WHERE SHOWN IN THE RULES AND COMMAND LANGUAGE ARE IMPORTANT... NOT FOLLOWING THE LANGUAGE SYNTAX WILL CAUSE TROUBLE.
.br
	Luckily, scripts file need not only be made by hand... it is possible to create a script automatically by selecting the scripting choice item, and then using KironDraw as usual.  What will happen however that is different from normal use, is that script 
code will be generated for you by KironDraw.  Giving a filename in the File field and clicking the Save Script button will save the script for future use.
.br
.br
.SH Clipboard Tools
.br
.br
	The Clipboard tools modify the contents of the clipboard and are the following : Invert, Flip Horizontal, Flip Vertical, Enlarge, Reduce.
.br
	Invert will invert the contents of the clipboard (ie. black -> white, white -> black)
.br
	Flip Horizontal will flip the contents of the clipboard in the horizontal direction.
.br
	Flip Vertical will flip the contents of the clipboard in the vertical direction.
.br
	Enlarge will enlarge the contents of the clipboard by 200%.  It can be used many times to enlarge the contents 200,400,800...%.
.br
	Reduce will reduce the contents of the clipboard by 50%.  It can be used many times to reduce the contents 50,25,12.5...%.
.br
.br
.SH GLOSSARY
.br
	Clicking : The act of pressing the left mouse button.
	Dragging : The act of moving the mouse while the left mouse button is depressed.
.br
.br
.SH VARIOUS
.br
	KironDraw windows can be closed, re-sized, and moved like any other SunView program windows.
.br
.br
.SH WARNING
	Please do not print diagrams with MANY dark areas since you might find yourself buying a new printer ribbon.
.br
.br
.SH BUGS
	Screen redraws for large canvas sizes are slow, please be patient.
.br
	The program is optimized for use on Suns with Math Coprocessors,but will work on ALL machines equipped with mice.
.br
.br
.SH NOTES
.br
	Depending on drawing sizes, image files can take up from 10 to 180K on disk.  KironDraw will not warn you if your quota is exceeded,so please make sure you have enough disk space before you save a file.
.br
	KironDraw makes no file backups;  saving to a file that already exists will overwrite the previous contents of the file.
.br
	A new version of KironDraw will be posted every few days, so  if you see any modifications to the program, please read this MAN page under the section UPDATES.
.br
	For any questions concerning KironDraw usage, please contact Kiron Bondale.
.br
.br
.SH AUTHOR
Kiron D. Bondale
(kiron@sunkisd.cs.concordia.ca)
//E*O*F kirondraw.l//

exit 0