🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.windows.x.apps
Article #763

BETA Version of XPaint 2.0 -- Part 2 / 5

#763
From: David Koblas
Date: Thu, 09 Jul 1992 21:07
2013 lines
59067 bytes
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# If this archive is complete, you will see the following message at the end:
#		"End of archive 2 (of 5)."
# Contents:  BrushOp.c Colormap.c FileName.c Graphic.c Operation.c
#   PolyOp.c libpnmrw.h
# Wrapped by koblas@bananajr on Thu Jul  9 14:00:21 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'BrushOp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'BrushOp.c'\"
else
echo shar: Extracting \"'BrushOp.c'\" \(8450 characters\)
sed "s/^X//" >'BrushOp.c' <<'END_OF_FILE'
X/* +-------------------------------------------------------------------+ */
X/* | Copyright 1992, David Koblas.                                     | */
X/* |   Permission to use, copy, modify, and distribute this software   | */
X/* |   and its documentation for any purpose and without fee is hereby | */
X/* |   granted, provided that the above copyright notice appear in all | */
X/* |   copies and that both that copyright notice and this permission  | */
X/* |   notice appear in supporting documentation.  This software is    | */
X/* |   provided "as is" without express or implied warranty.           | */
X/* +-------------------------------------------------------------------+ */
X
X#include <X11/Intrinsic.h>
X#include <X11/StringDefs.h>
X#include <X11/Shell.h>
X#include <X11/Xaw/Box.h>
X#include <X11/Xaw/Form.h>
X#include <X11/Xaw/Command.h>
X#include <X11/Xaw/Toggle.h>
X#include "xpaint.h"
X#include "Paint.h"
X
X#include "bitmaps/paintA.xbm"
X#include "bitmaps/paintB.xbm"
X#include "bitmaps/paintC.xbm"
X#include "bitmaps/paintD.xbm"
X#include "bitmaps/paintE.xbm"
X#include "bitmaps/paintF.xbm"
X#include "bitmaps/paintG.xbm"
X#include "bitmaps/paintH.xbm"
X#include "bitmaps/paintI.xbm"
X#include "bitmaps/paintJ.xbm"
X#include "bitmaps/paintK.xbm"
X
X#include "bitmaps/defspray.xbm"
X
X#define WIDTH	16
X#define HEIGHT	16
X
X#define BRUSH(name)	 \
X	CONCAT(name,_bits), CONCAT(name,_width), CONCAT(name,_height)
X
Xstatic struct {
X	Pixmap	pixmap;
X	char	*bits;
X	int	width, height;
X} brushList[] = {
X	{ NULL, BRUSH(paintA) },
X	{ NULL, BRUSH(paintB) },
X	{ NULL, BRUSH(paintC) },
X	{ NULL, BRUSH(paintD) },
X	{ NULL, BRUSH(paintE) },
X	{ NULL, BRUSH(paintF) },
X	{ NULL, BRUSH(paintG) },
X	{ NULL, BRUSH(paintH) },
X	{ NULL, BRUSH(paintI) },
X	{ NULL, BRUSH(paintJ) },
X	{ NULL, BRUSH(paintK) },
X};
X
X#define default_bits	paintA_bits
X#define default_width	paintA_width
X#define default_height	paintA_height
X
Xstatic Pixmap	brushPixmap = None, sprayPixmap = None;
Xstatic Boolean	isPoped = False;
X
Xstatic void	press(Widget w, Pixmap *mask, XButtonEvent *event, OpInfo *info) 
X{
X	XRectangle	undo;
X
X	if (info->surface == opWindow && info->isFat)
X		return;
X
X	XSetClipOrigin(XtDisplay(w), info->filled_gc, event->x, event->y);
X	XSetClipMask(XtDisplay(w), info->filled_gc, *mask);
X	
X	UndoStart(w, info);
X
X	XFillRectangle(XtDisplay(w), info->drawable, info->filled_gc,
X			event->x, event->y, WIDTH, HEIGHT);
X
X	if (info->surface == opPixmap) {
X		XYtoRECT(event->x, event->y, event->x + WIDTH, event->y + HEIGHT, &undo);
X		UndoSetRectangle(w, &undo);
X		PwUpdate(w, &undo, False);
X	}
X}
X
Xstatic void	motion(Widget w, void *junk, XMotionEvent *event, OpInfo *info) 
X{
X	XRectangle	undo;
X
X	if (info->surface == opWindow && info->isFat)
X		return;
X
X	XSetClipOrigin(XtDisplay(w), info->filled_gc, event->x, event->y);
X
X	XFillRectangle(XtDisplay(w), info->drawable, info->filled_gc,
X			event->x, event->y, WIDTH, HEIGHT);
X
X	if (info->surface == opPixmap) {
X		XYtoRECT(event->x, event->y, event->x + WIDTH, event->y + HEIGHT, &undo);
X		UndoGrow(w, event->x, event->y);
X		UndoGrow(w, event->x + WIDTH, event->y + HEIGHT);
X		PwUpdate(w, &undo, False);
X	}
X}
X
Xstatic void	release(Widget w, void *junk, XButtonEvent *event, OpInfo *info) 
X{
X	XSetClipMask(XtDisplay(w), info->filled_gc, None);
X}
X
Xstatic void	setCursor(Widget w, Pixmap pix)
X{
X	static int	inited = False;
X	static XColor	white, black;
X	Cursor		c;
X
X	if (!inited) {
X		Colormap	map;
X		XColor		junk;
X
X		XtVaGetValues(w, XtNcolormap, &map, NULL);
X
X		XAllocNamedColor(XtDisplay(w), map, "black", &black, &junk);
X		XAllocNamedColor(XtDisplay(w), map, "white", &white, &junk);
X
X		inited = True;
X	}
X
X	c = XCreatePixmapCursor(XtDisplay(w), pix, pix, &black, &white, 0, 0);
X	XDefineCursor(XtDisplay(w), XtWindow(w), c);
X}
X
X/*
X**  Those public functions
X*/
Xvoid *BrushAdd(Widget w)
X{
X	OpAddEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, press, &brushPixmap);
X	OpAddEventHandler(w, opWindow|opPixmap, ButtonMotionMask, FALSE, motion, NULL);
X	OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, release, NULL);
X
X	setCursor(w, brushPixmap);
X
X	return NULL;
X}
Xvoid BrushRemove(Widget w, void *junk)
X{
X	OpRemoveEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, press, &brushPixmap);
X	OpRemoveEventHandler(w, opWindow|opPixmap, ButtonMotionMask, FALSE, motion, NULL);
X	OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, release, NULL);
X}
Xvoid *SprayAdd(Widget w)
X{
X	OpAddEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, press, &sprayPixmap);
X	OpAddEventHandler(w, opWindow|opPixmap, ButtonMotionMask, FALSE, motion, NULL);
X	OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, release, NULL);
X
X	setCursor(w, sprayPixmap);
X
X	return NULL;
X}
Xvoid SprayRemove(Widget w, void *junk)
X{
X	OpRemoveEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, press, &sprayPixmap);
X	OpRemoveEventHandler(w, opWindow|opPixmap, ButtonMotionMask, FALSE, motion, NULL);
X	OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, release, NULL);
X}
X
X/*
X**  Initializer to create a default brush
X*/
X
Xvoid	BrushInit(Widget toplevel)
X{
X	brushList[0].pixmap = XCreatePixmapFromBitmapData(
X		XtDisplay(toplevel), 
X		RootWindowOfScreen(XtScreen(toplevel)),
X		brushList[0].bits,
X		brushList[0].width,
X		brushList[0].height,
X		True, False, 1);
X
X	brushPixmap = brushList[0].pixmap;
X
X	sprayPixmap = XCreatePixmapFromBitmapData(
X		XtDisplay(toplevel), 
X		RootWindowOfScreen(XtScreen(toplevel)),
X		defspray_bits,
X		defspray_width,
X		defspray_height,
X		True, False, 1);
X}
X
X/*
X**  The brush selection dialog
X*/
X
Xstatic void	destroyPopup(Widget shell, void *junk, XEvent *event)
X{
X}
X
Xstatic void	closePopup(Widget button, Widget shell)
X{
X	isPoped = False;
X
X	XtPopdown(shell);
X}
X
Xstatic void 	selectBrush(Widget shell, Pixmap pix)
X{
X	brushPixmap = pix;
X
X	if (CurrentOp[0] == BrushAdd)
X		GraphicAll(setCursor, brushPixmap);
X}
X
Xstatic Widget	createDialog(Widget w)
X{
X	Widget		shell, form, box, icon, firstIcon = 0, close;
X	GC		gc, igc;
X	XGCValues	values;
X	int		i;
X	Pixmap		pix;
X
X	shell = XtVaCreatePopupShell("shell",
X			topLevelShellWidgetClass, w,
X			NULL);
X	
X	form = XtVaCreateManagedWidget(NULL,
X			formWidgetClass, shell,
X			NULL);
X
X	box  = XtVaCreateManagedWidget("box",
X			boxWidgetClass, form,
X			NULL);
X
X	values.foreground    = WhitePixelOfScreen(XtScreen(w));
X	values.background    = BlackPixelOfScreen(XtScreen(w));
X
X	gc = XCreateGC(XtDisplay(w), 
X			RootWindowOfScreen(XtScreen(w)),
X			GCForeground|GCBackground, &values);
X
X	values.background    = WhitePixelOfScreen(XtScreen(w));
X	values.foreground    = BlackPixelOfScreen(XtScreen(w));
X	igc = XCreateGC(XtDisplay(w), 
X			RootWindowOfScreen(XtScreen(w)),
X			GCForeground|GCBackground, &values);
X
X	for (i = 0; i < XtNumber(brushList); i++) {
X		if (brushList[i].pixmap == None)
X			brushList[i].pixmap = XCreatePixmapFromBitmapData(
X				XtDisplay(box), 
X				RootWindowOfScreen(XtScreen(box)),
X				brushList[i].bits,
X				brushList[i].width,
X				brushList[i].height,
X				True, False, 1);
X		XSetClipMask(XtDisplay(w), gc, brushList[i].pixmap);
X
X		pix = XCreatePixmap(XtDisplay(box), 
X					RootWindowOfScreen(XtScreen(box)),
X					brushList[i].width,
X					brushList[i].height,
X					DefaultDepthOfScreen(XtScreen(box)));
X
X		/*
X		**  Clear then draw the clipped rectangle in
X		*/
X		XFillRectangle(XtDisplay(w), pix, igc, 0, 0,
X				brushList[i].width, brushList[i].height);
X		XFillRectangle(XtDisplay(w), pix, gc, 0, 0,
X				brushList[i].width, brushList[i].height);
X
X		icon = XtVaCreateManagedWidget(NULL,
X				toggleWidgetClass, box,
X				XtNbitmap, pix,
X				XtNradioGroup, firstIcon,
X				NULL);
X
X		if (firstIcon == NULL) {
X			XtVaSetValues(icon, XtNstate, True, NULL);
X			firstIcon = icon;
X		}
X
X		XtAddCallback(icon, XtNcallback, 
X				selectBrush, brushList[i].pixmap);
X	}
X
X	close  = XtVaCreateManagedWidget("close",
X			commandWidgetClass, form,
X			XtNfromVert, box,
X			NULL);
X
X	XtAddCallback(close, XtNcallback, closePopup, shell);
X	XtAddEventHandler(shell, SubstructureNotifyMask|StructureNotifyMask, False, destroyPopup, shell);
X	XtAddEventHandler(shell, VisibilityChangeMask, True, destroyPopup, shell);
X
X	XFreeGC(XtDisplay(w), gc);
X	XFreeGC(XtDisplay(w), igc);
X
X	XtPopup(shell, XtGrabNone);
X
X	isPoped = True;
X
X	return shell;
X}
X
Xvoid	BrushSelect(Widget w)
X{
X	static Widget	popup = NULL;
X
X	if (popup == NULL) 
X		popup = createDialog(GetToplevel(w));
X	
X	if (isPoped) 
X		XRaiseWindow(XtDisplay(popup), XtWindow(popup));
X	else
X		XtPopup(popup, XtGrabNone);
X}

END_OF_FILE
echo shar: NEWLINE appended to \"'BrushOp.c'\"
if test 8451 -ne `wc -c <'BrushOp.c'`; then
    echo shar: \"'BrushOp.c'\" unpacked with wrong size!
fi
# end of 'BrushOp.c'
fi
if test -f 'Colormap.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Colormap.c'\"
else
echo shar: Extracting \"'Colormap.c'\" \(6471 characters\)
sed "s/^X//" >'Colormap.c' <<'END_OF_FILE'
X/* +-------------------------------------------------------------------+ */
X/* | Copyright 1992, David Koblas.                                     | */
X/* |   Permission to use, copy, modify, and distribute this software   | */
X/* |   and its documentation for any purpose and without fee is hereby | */
X/* |   granted, provided that the above copyright notice appear in all | */
X/* |   copies and that both that copyright notice and this permission  | */
X/* |   notice appear in supporting documentation.  This software is    | */
X/* |   provided "as is" without express or implied warranty.           | */
X/* +-------------------------------------------------------------------+ */
X
X#include <math.h>
X#include <X11/IntrinsicP.h>
X#include <X11/StringDefs.h>
X#include "ColormapP.h"
X
Xstatic XtResource resources[] = {
X#define offset(field) XtOffset(ColormapWidget, color.field)
X	{ XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer),
X	  offset(callbacks), XtRCallback, (XtPointer)None },
X	{ XtNcolor, XtCColor, XtRPixel, sizeof(Pixel),
X	  offset(pixel), XtRImmediate, (XtPointer)None },
X	{ XtNreadOnly, XtCReadOnly, XtRBoolean, sizeof(Boolean),
X	  offset(editable), XtRImmediate, (XtPointer)False },
X	{ XtNcellWidth, XtCCellWidth, XtRInt, sizeof(int),
X	  offset(cwidth), XtRImmediate, (XtPointer)5 },
X	{ XtNcellHeight, XtCCellHeight, XtRInt, sizeof(int),
X	  offset(cheight), XtRImmediate, (XtPointer)5 },
X	{ XtNthickness, XtCThickness, XtRInt, sizeof(int),
X	  offset(thickness), XtRImmediate, (XtPointer)1 },
X	{ XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
X	  offset(foreground), XtRString, XtDefaultForeground },
X#undef offset
X};
X
Xstatic void ResizeProc(ColormapWidget);
Xstatic void ExposeProc(ColormapWidget, XExposeEvent *);
Xstatic void InitializeProc(ColormapWidget, ColormapWidget);
Xstatic void RealizeProc(Widget, Mask *, XSetWindowAttributes *);
X
Xstatic void drawSelection(ColormapWidget w, int flag)
X{
X	XGCValues	values;
X	int		x, y;
X	GC		gc;
X	int		t = w->color.thickness, t2 = t / 2;
X	
X	values.line_width = w->color.thickness;
X	if (flag) {
X		values.foreground = w->color.foreground;
X		values.background = w->core.background_pixel;
X	} else {
X		values.foreground = w->core.background_pixel;
X		values.background = w->color.foreground;
X	}
X
X	gc = XtGetGC(w, GCForeground|GCBackground|GCLineWidth, &values);
X
X	x = (w->color.pixel % w->color.ncwidth) * w->color.cwidth;
X	y = (w->color.pixel / w->color.ncwidth) * w->color.cheight;
X
X	XDrawRectangle(XtDisplay(w), XtWindow(w), gc, 
X			x - t2, y - t2, w->color.cwidth, w->color.cheight);
X}
X
Xstatic void ColormapSelect(ColormapWidget w, XEvent* e, 
X					String* str, Cardinal* n)
X{
X	int	pixel;
X	int	x = e->xbutton.x, y = e->xbutton.y;
X	XColor	col;
X
X	if ((e->xbutton.x / w->color.cwidth) > w->color.ncwidth)
X		return;
X	if ((e->xbutton.y / w->color.cheight) > w->color.ncheight)
X		return;
X
X	
X	pixel = (e->xbutton.y / w->color.cheight) * w->color.ncwidth; 
X	pixel += e->xbutton.x / w->color.cwidth;
X
X	drawSelection(w, FALSE);
X	w->color.pixel = pixel;
X	drawSelection(w, TRUE);
X
X	col.pixel = pixel;
X	col.flags = DoRed|DoGreen|DoBlue;
X	XQueryColor(XtDisplay(w), w->core.colormap, &col);
X
X	XtCallCallbackList(w, w->color.callbacks, &col);
X}
X
Xstatic XtActionsRec actions[] =
X{
X  /* {name, procedure}, */
X    {"Set",	ColormapSelect},
X};
X
Xstatic char translations[] =
X"<BtnDown>:	Set()	\n\
X";
X
XColormapClassRec colormapClassRec = {
X  { /* core fields */
X    /* superclass		*/	(WidgetClass) &widgetClassRec,
X    /* class_name		*/	"Colormap",
X    /* widget_size		*/	sizeof(ColormapRec),
X    /* class_initialize		*/	NULL,
X    /* class_part_initialize	*/	NULL,
X    /* class_inited		*/	FALSE,
X    /* initialize		*/	InitializeProc,
X    /* initialize_hook		*/	NULL,
X    /* realize			*/	XtInheritRealize,
X    /* actions			*/	actions,
X    /* num_actions		*/	XtNumber(actions),
X    /* resources		*/	resources,
X    /* num_resources		*/	XtNumber(resources),
X    /* xrm_class		*/	NULLQUARK,
X    /* compress_motion		*/	TRUE,
X    /* compress_exposure	*/	TRUE,
X    /* compress_enterleave	*/	TRUE,
X    /* visible_interest		*/	FALSE,
X    /* destroy			*/	NULL,
X    /* resize			*/	ResizeProc,
X    /* expose			*/	ExposeProc,
X    /* set_values		*/	NULL,
X    /* set_values_hook		*/	NULL,
X    /* set_values_almost	*/	XtInheritSetValuesAlmost,
X    /* get_values_hook		*/	NULL,
X    /* accept_focus		*/	NULL,
X    /* version			*/	XtVersion,
X    /* callback_private		*/	NULL,
X    /* tm_table			*/	translations,
X    /* query_geometry		*/	XtInheritQueryGeometry,
X    /* display_accelerator	*/	XtInheritDisplayAccelerator,
X    /* extension		*/	NULL
X  },
X  { /* colormap fields */
X    /* empty			*/	0
X  }
X};
X
XWidgetClass colormapWidgetClass = (WidgetClass)&colormapClassRec;
X
Xstatic void InitializeProc(ColormapWidget w, ColormapWidget new)
X{
X	Display	*dpy = XtDisplay(w);
X	int     scrn = 0;
X
X	new->color.ncel  = DisplayCells(dpy, scrn);
X	new->color.ncwidth  = (int)sqrt((double)new->color.ncel);
X	new->color.ncheight = (new->color.ncel + new->color.ncwidth - 1) /
X					new->color.ncwidth;
X	if (new->core.width == 0) 
X		new->core.width  = new->color.cwidth * new->color.ncwidth;
X	else
X		new->color.cwidth = new->core.width /  new->color.ncwidth;
X	if (new->core.height == 0) 
X		new->core.height  = new->color.cheight * new->color.ncheight;
X	else
X		new->color.cheight = new->core.height /  new->color.ncheight;
X}
X
Xstatic void ResizeProc(ColormapWidget w)
X{
X	w->color.cwidth  = w->core.width  /  w->color.ncwidth;
X	w->color.cheight = w->core.height /  w->color.ncheight;
X}
X
Xstatic void ExposeProc(ColormapWidget w, XExposeEvent *event)
X{
X	Display	*dpy = XtDisplay(w);
X	Window	win  = XtWindow(w);
X	GC	gc   = XCreateGC(dpy, win, 0, NULL);
X	int	color = 0;
X	int	x, y, X, Y;
X	int	nvert  = w->color.ncwidth;
X	int	nhoriz = w->color.ncheight;
X	int	t      = w->color.thickness, t2 = t / 2;
X
X	for (Y = y = 0; y < nhoriz; y++, Y += w->color.cheight) {
X		for (X = x = 0; x < nvert; x++, X += w->color.cwidth) {
X			XSetForeground(dpy, gc, color++);
X			XFillRectangle(dpy, win, gc, X, Y,
X				w->color.cwidth - 1 - t, w->color.cheight - 1 - t);
X		}
X	}
X
X	XFreeGC(dpy, gc);
X	drawSelection(w, TRUE);
X}
X
Xvoid CwGetColor(Widget cw, XColor* col)
X{
X	ColormapWidget w = (ColormapWidget)cw;
X	
X	col->pixel = w->color.pixel;
X	col->flags = DoRed|DoGreen|DoBlue;
X	XQueryColor(XtDisplay(w), w->core.colormap, col);
X}
X
Xvoid CwSetColor(Widget cw, XColor* col)
X{
X	ColormapWidget w = (ColormapWidget)cw;
X	
X	col->pixel = w->color.pixel;
X	XStoreColor(XtDisplay(w), w->core.colormap, col);
X}

END_OF_FILE
echo shar: NEWLINE appended to \"'Colormap.c'\"
if test 6472 -ne `wc -c <'Colormap.c'`; then
    echo shar: \"'Colormap.c'\" unpacked with wrong size!
fi
# end of 'Colormap.c'
fi
if test -f 'FileName.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'FileName.c'\"
else
echo shar: Extracting \"'FileName.c'\" \(4558 characters\)
sed "s/^X//" >'FileName.c' <<'END_OF_FILE'
X/* +-------------------------------------------------------------------+ */
X/* | Copyright 1992, David Koblas.                                     | */
X/* |   Permission to use, copy, modify, and distribute this software   | */
X/* |   and its documentation for any purpose and without fee is hereby | */
X/* |   granted, provided that the above copyright notice appear in all | */
X/* |   copies and that both that copyright notice and this permission  | */
X/* |   notice appear in supporting documentation.  This software is    | */
X/* |   provided "as is" without express or implied warranty.           | */
X/* +-------------------------------------------------------------------+ */
X
X#include <X11/StringDefs.h>
X#include <X11/Intrinsic.h>
X#include <X11/Shell.h>
X#include <X11/Xaw/Dialog.h>
X#include <X11/Xaw/Command.h>
X#include <X11/Xaw/Toggle.h>
X#include <X11/Xaw/Form.h>
X#include <X11/Xaw/Label.h>
X#include <X11/Xaw/AsciiText.h>
X#include <X11/Xaw/Text.h>
X
X#include "xpaint.h"
X
Xstatic Widget shell = NULL, text;
Xstatic int	fileType = FT_PBM;
X
Xtypedef struct {
X	XtCallbackProc	func;
X	Widget		w;
X} arg_t;
X
Xstatic void fileTypeCallback(Widget w, int type)
X{
X	fileType = type;
X}
X
Xstatic void callback(Widget w, arg_t *arg)
X{
X	char	*string;
X
X	XtVaGetValues(text, XtNstring, &string, NULL);
X
X	if (arg->func != NULL)
X		arg->func(arg->w, string, fileType);
X
X	XtPopdown(shell);
X}
X
Xvoid GetFileName(Widget w, int op, char *def,
X			XtCallbackProc okFunc, XtCallbackProc cancelFunc)
X{
X	Position	x, y;
X	static char	buf[256];
X	static Widget	label, okButton, cancelButton;
X	Widget		form, form2, toggle;
X	static	arg_t	okArg, cancelArg;
X	static String	textAccelerators = "#override\n\
X				<Key>Return: set() notify() unset()\n\
X				<Key>Linefeed: set() notify() unset()";
X	static String	textTranslations = "#override\n\
X						 <Key>Return: no-op()\n\
X						 <Key>Linefeed: no-op()\n\
X						 Ctrl<Key>M: no-op()\n\
X						 Ctrl<Key>J: no-op()\n";
X
X	if (def != NULL && *def != '\0')
X		strcpy(buf, def);
X	else
X		buf[0] = '\0';
X
X	if (shell == NULL) {
X		XtTranslations	trans, toglt;
X		XtAccelerators	accel;
X		trans = XtParseTranslationTable(textTranslations);
X		toglt = XtParseTranslationTable(
X				"<BtnDown>,<BtnUp>: set() notify()");
X		accel = XtParseAcceleratorTable(textAccelerators);
X
X		shell = XtVaCreatePopupShell("filebrowser",
X				transientShellWidgetClass, GetToplevel(w),
X				NULL);
X		form = XtVaCreateManagedWidget(NULL,
X					formWidgetClass, shell,
X					XtNborderWidth, 0,
X					NULL);
X
X		label = XtVaCreateManagedWidget("label",
X					labelWidgetClass, form,
X					XtNborderWidth, 0,
X					NULL);
X		text = XtVaCreateManagedWidget("label",
X					asciiTextWidgetClass, form,
X					XtNfromVert, label,
X					XtNeditType, XawtextEdit,
X					XtNwrap, XawtextWrapNever,
X					XtNresize, XawtextResizeWidth,
X					XtNlength, sizeof(buf) - 1,
X					XtNtranslations, trans,
X					NULL);
X
X		form2 = XtVaCreateManagedWidget(NULL,
X					formWidgetClass, form,
X					XtNfromVert, text,
X					XtNborderWidth, 0,
X					NULL);
X
X		toggle = XtVaCreateManagedWidget("PBM",
X					toggleWidgetClass, form2,
X					XtNtranslations, toglt,
X					NULL);
X		XtVaSetValues(toggle, XtNstate, True, NULL);
X		XtAddCallback(toggle, XtNcallback, fileTypeCallback, FT_PBM);
X		toggle = XtVaCreateManagedWidget("XBM",
X					toggleWidgetClass, form2,
X					XtNfromVert, toggle,
X					XtNradioGroup, toggle,
X					XtNtranslations, toglt,
X					NULL);
X		XtAddCallback(toggle, XtNcallback, fileTypeCallback, FT_XBM);
X
X		okButton = XtVaCreateManagedWidget("ok",
X					commandWidgetClass, form,
X					XtNfromVert, form2,
X					XtNaccelerators, accel,
X					NULL);
X		cancelButton = XtVaCreateManagedWidget("cancel",
X					commandWidgetClass, form,
X					XtNfromVert, form2,
X					XtNfromHoriz, okButton,
X					NULL);
X		XtSetKeyboardFocus(form, text);
X		XtInstallAccelerators(text, okButton);
X	}
X
X	/*
X	**  Set the title to something interesting
X	*/
X	if (op) {
X		XtVaSetValues(label, XtNlabel, "SAVE -- Filename:", NULL);
X	} else {
X		XtVaSetValues(label, XtNlabel, "READ -- Filename:", NULL);
X	}
X
X	XtVaGetValues(GetToplevel(w), XtNx, &x, XtNy, &y, NULL);
X	XtVaSetValues(shell, XtNx, x + 24, XtNy, y + 24, NULL);
X	
X	/*
X	**  Make sure everything is cleared.
X	*/
X	XtVaSetValues(text, XtNstring, buf, NULL);
X
X	XtRemoveAllCallbacks(okButton, XtNcallback);
X	XtRemoveAllCallbacks(cancelButton, XtNcallback);
X
X	okArg.func     = okFunc;
X	cancelArg.func = cancelFunc;
X	okArg.w = cancelArg.w = w;
X
X	XtAddCallback(okButton, XtNcallback, callback, &okArg);
X	XtAddCallback(cancelButton, XtNcallback, callback, &cancelArg);
X
X	XtPopup(shell, XtGrabNone);
X}

END_OF_FILE
echo shar: NEWLINE appended to \"'FileName.c'\"
if test 4559 -ne `wc -c <'FileName.c'`; then
    echo shar: \"'FileName.c'\" unpacked with wrong size!
fi
# end of 'FileName.c'
fi
if test -f 'Graphic.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Graphic.c'\"
else
echo shar: Extracting \"'Graphic.c'\" \(11561 characters\)
sed "s/^X//" >'Graphic.c' <<'END_OF_FILE'
X/* +-------------------------------------------------------------------+ */
X/* | Copyright 1992, David Koblas.                                     | */
X/* |   Permission to use, copy, modify, and distribute this software   | */
X/* |   and its documentation for any purpose and without fee is hereby | */
X/* |   granted, provided that the above copyright notice appear in all | */
X/* |   copies and that both that copyright notice and this permission  | */
X/* |   notice appear in supporting documentation.  This software is    | */
X/* |   provided "as is" without express or implied warranty.           | */
X/* +-------------------------------------------------------------------+ */
X
X#include <X11/Intrinsic.h>
X#include <X11/Shell.h>
X#include <X11/StringDefs.h>
X#include <X11/Xaw/Form.h>
X#include <X11/Xaw/Viewport.h>
X#include <X11/Xaw/Box.h>
X#include <X11/Xaw/Label.h>
X#include <X11/Xaw/Toggle.h>
X#include <X11/Xaw/SmeBSB.h>
X#include <stdio.h>
X
X#include "Paint.h"
X
X#include "xpaint.h"
X#include "Cmap.h"
X
Xextern void UndoSwap(Widget w);
X
X#include "bitmaps/pattern2.xbm"
X#include "bitmaps/pattern3.xbm"
X#include "bitmaps/pattern4.xbm"
X#include "bitmaps/pattern5.xbm"
X#include "bitmaps/pattern6.xbm"
X#include "bitmaps/pattern7.xbm"
X#include "bitmaps/pattern8.xbm"
X#include "bitmaps/pattern9.xbm"
X
X#define PATTERN(name)      \
X	CONCAT(name,_bits), CONCAT(name,_width), CONCAT(name,_height)
X
Xstatic void saveFileCalback(Widget paint, char *file, int type)
X{
X	Pixmap	pix;
X	int	width, height;
X
X	PwGetPixmap(paint, &pix, &width, &height);
X
X	switch (type) {
X	case FT_XBM:
X		XWriteBitmapFile(XtDisplay(paint), file, pix, 
X					width, height, 0, 0);
X		break;
X	case FT_PBM:
X		WritePNM(paint, file, width, height, pix);
X		break;
X	default:
X		break;
X	}
X}
X
Xstatic void saveCallback(Widget w, Widget shell)
X{
X	GetFileName(shell, True, NULL, saveFileCalback, NULL);
X}
X
Xstruct callData {
X	Widget	paint;
X	Pixmap	pixmap;
X};
X
Xstruct paintWindows {
X	Widget			paint;
X	struct paintWindows	*next;
X	void			*ldata;
X};
X
Xstatic struct {
X	char	*bits;
X	int	width, height;
X} patternList[] = {
X#if 0
X	{ PATTERN(pattern0) },
X	{ PATTERN(pattern1) },
X#endif
X	{ PATTERN(pattern2) },
X	{ PATTERN(pattern3) },
X	{ PATTERN(pattern4) },
X	{ PATTERN(pattern5) },
X	{ PATTERN(pattern6) },
X	{ PATTERN(pattern7) },
X	{ PATTERN(pattern8) },
X	{ PATTERN(pattern9) },
X};
X
Xstatic PaintMenuItem	fileMenu[] = {
X	{ "save",   NULL, NULL, MF_NONE },
X	{ "close",  NULL, NULL, MF_NONE },
X};
X
Xstatic PaintMenuItem	editMenu[] = {
X	{ "undo",   NULL, NULL, MF_NONE },
X	{ "",       NULL, NULL, MF_NONE },
X	{ "cut",    NULL, NULL, MF_NONE },
X	{ "copy",   NULL, NULL, MF_NONE },
X	{ "paste",  NULL, NULL, MF_NONE },
X	{ "clear",  NULL, NULL, MF_NONE },
X	{ "",       NULL, NULL, MF_NONE },
X	{ "lock",   NULL, NULL, MF_NONE },
X	{ "unlock", NULL, NULL, MF_NONE },
X};
X
Xstatic PaintMenuItem	otherMenu[] = {
X	{ "fatbits",   NULL, NULL, MF_NONE  },
X	{ "grid",      NULL, NULL, MF_CHECK },
X};
X
Xstatic PaintMenuBar	menuBar[] = {
X	{ "file",  XtNumber(fileMenu),  fileMenu },
X	{ "edit",  XtNumber(editMenu),  editMenu },
X	{ "other", XtNumber(otherMenu), otherMenu },
X};
X
Xstatic struct paintWindows	*head = NULL;
X
Xvoid GraphicRemove(Widget paint)
X{
X	struct paintWindows	*cur, *prev = NULL;
X
X	for (cur = head; cur != NULL; prev = cur, cur=cur->next) 
X		if (cur->paint == paint) 
X			break;
X
X	if (cur == NULL)
X		return;
X
X	if (prev == NULL)
X		head = cur->next;
X	else
X		prev = cur->next;
X
X	CurrentOp[1](cur->paint, cur->ldata);
X	XtFree(cur);
X}
X
Xvoid GraphicAdd(Widget paint)
X{
X 	struct paintWindows	*new;
X
X	new = (struct paintWindows *)XtMalloc(sizeof(struct paintWindows));
X
X	if (new == NULL) {
X		/* big error XXX */
X		return;
X	}
X
X	new->next  = head;
X	head       = new;
X	new->paint = paint;
X
X	if (CurrentOp != NULL && CurrentOp[0] != NULL)
X		new->ldata = CurrentOp[0](paint);
X
X	XtAddCallback(paint, XtNdestroyCallback, GraphicRemove, NULL);
X}
X
X
Xvoid GraphicAll(void (*func)(), void *data)
X{
X	struct paintWindows	*cur;
X
X	for (cur = head; cur != NULL; cur=cur->next)
X		func(cur->paint, data);
X}
Xvoid GraphicSetOp(void *(*stop)(), void *(*start)())
X{
X	struct paintWindows	*cur;
X
X	for (cur = head; cur != NULL; cur=cur->next) {
X		if (stop != NULL)
X			stop(cur->paint, cur->ldata);
X		if (start != NULL)
X			cur->ldata = start(cur->paint);
X	}
X}
X
Xvoid	ToggleSetPattern(Widget icon, Widget paint)
X{
X	Pixmap	pix;
X
X	XtVaGetValues(icon, XtNbitmap, &pix, NULL);
X	XtVaSetValues(paint, XtNpattern, pix, NULL);
X}
X
X/*
X**  First level menu callbacks.
X*/
Xstatic void clearCallback(Widget w, Widget paint)
X{
X	PwClearRegion(paint);
X}
Xstatic void undoCallback(Widget w, Widget paint)
X{
X	UndoSwap(paint);
X}
Xstatic void closeCallback(Widget w, Widget shell)
X{
X	XtDestroyWidget(shell);
X}
X
X/*
X**  Pattern edit/add callback
X*/
Xstatic void editCallback(Widget w, Widget* wl)
X{
X	Pixmap	pix;
X
X	XtVaGetValues(wl[0], XtNpattern, &pix, NULL);
X	PatternEdit(wl[0], pix, wl[1]);
X}
Xstatic void addCallback(Widget w, Widget *wl)
X{
X	PatternEdit(wl[0], NULL, wl[1]);
X}
X
X/*
X**
X*/
Xstatic void fatCallback(Widget w, Widget paint)
X{
X	Region_t	*region;
X	if ((region = PwGetRegion(paint)) != NULL) {
X		FatbitsEdit(paint, &region->generic.bbox);
X	} else {
X		/* no region selected */
X	}
X}
Xstatic void gridCallback(Widget w, Widget paint)
X{
X	Boolean	v;
X
X	XtVaGetValues(paint, XtNgridOn, &v, NULL);
X	v = !v;
X	XtVaSetValues(paint, XtNgridOn, &v, NULL);
X
X	XtVaSetValues(w, XtNleftBitmap, v ? CheckBitmap : None, NULL);
X}
X
Xvoid graphicCreate(Widget wid, Pixmap pix, Colormap cmap)
X{
X	Widget			shell, form, viewport, pattern, bar;
X	Widget			paint, viewport2;
X	Widget			icon, firstIcon = NULL;
X	Widget			add, edit;
X	Cmap			*map;
X	GC			gc;
X	int			i;
X	int			w = 0, h = 0;
X	struct callData		*cd;
X	Widget			*wl = (Widget*)XtMalloc(sizeof(Widget) * 2);
X	static struct {
X		char	*name;
X		Pixel	pixel;
X		Boolean	doit;
X	} color[] = {
X		{ "black", 0, False },
X		{ "white", 0, False },
X		{ "red", 0, False },
X		{ "green", 0, False },
X		{ "blue", 0, False },
X		{ "cyan", 0, False },
X		{ "magenta", 0, False },
X		{ "yellow", 0, False },
X	};
X	static Boolean		inited = False;
X
X	/*
X	**  Menu Bar
X	*/
X	shell = XtVaCreatePopupShell("shell",
X			topLevelShellWidgetClass, GetToplevel(wid),
X			XtNlabel, "Untitled",
X			NULL);
X
X	if (cmap == None) {
X		map = CreateCmap(shell);
X		cmap = map->cmap;
X	} else {
X		map = CmapFind(shell, cmap);
X	}
X
X	form = XtVaCreateWidget("form", 
X			formWidgetClass, shell,
X			NULL);
X	XtVaSetValues(shell, XtNcolormap, cmap, NULL);
X	XtVaSetValues(form, XtNcolormap, cmap, NULL);
X	XtManageChild(form);
X
X	if (!inited) {
X		int	i, j;
X		XColor	col, rgb;
X
X		for (i = 0; i < XtNumber(color); i++) {
X			if (XLookupColor(XtDisplay(shell), cmap, color[i].name, &rgb, &col)) {
X				CmapAlloc(map, &col);
X				color[i].pixel = col.pixel;
X				color[i].doit  = True;
X				for (j = 0; j < i; j++)
X					if (color[i].pixel == color[j].pixel)
X						color[i].doit = False;
X					
X			}
X		}
X
X		inited = True;
X	}
X
X
X	/*
X	**  Menu area
X	*/
X	bar = MenuBarCreate(form, XtNumber(menuBar), menuBar);
X
X	/*
X	**  Drawing Area
X	*/
X	viewport = XtVaCreateManagedWidget("viewport",
X			viewportWidgetClass, form,
X			XtNfromVert, bar,
X			XtNallowVert, TRUE,
X			XtNallowHoriz, TRUE,
X			XtNuseBottom, TRUE,
X			XtNuseRight, TRUE,
X			NULL);
X
X	/*
X	**  Custom Drawing Widget here
X	**   First read the file and convert to a bitmap
X	*/
X
X	paint = XtVaCreateManagedWidget("paint",
X			paintWidgetClass, viewport,
X			XtNwidth, w,
X			XtNheight, h,
X			XtNpixmap, pix,
X			XtNcolormap, cmap,
X			XtNbackground, WhitePixelOfScreen(XtScreen(shell)), 
X			XtNforeground, BlackPixelOfScreen(XtScreen(shell)), 
X			NULL);
X
X	XtAddCallback(XtNameToWidget(bar, "edit.editMenu.undo"), 
X			XtNcallback, undoCallback, paint);
X	XtAddCallback(XtNameToWidget(bar, "edit.editMenu.clear"), 
X			XtNcallback, clearCallback, paint);
X	XtAddCallback(XtNameToWidget(bar, "file.fileMenu.save"), 
X			XtNcallback, saveCallback, paint);
X	XtAddCallback(XtNameToWidget(bar, "file.fileMenu.close"), 
X			XtNcallback, closeCallback, shell);
X	XtAddCallback(XtNameToWidget(bar, "other.otherMenu.grid"), 
X			XtNcallback, gridCallback, paint);
X	XtAddCallback(XtNameToWidget(bar, "other.otherMenu.fatbits"), 
X			XtNcallback, fatCallback, paint);
X
X	/*
X	**  Pattern Area
X	*/
X	viewport2 = XtVaCreateManagedWidget("viewport",
X			viewportWidgetClass, form,
X			XtNfromVert, viewport,
X			XtNallowVert, TRUE,
X			XtNallowHoriz, TRUE,
X			XtNuseBottom, TRUE,
X			XtNuseRight, TRUE,
X			NULL);
X	pattern = XtVaCreateManagedWidget("pattern",
X			boxWidgetClass, viewport2,
X			XtNheight, 40,
X			XtNwidth, 512,
X			NULL);
X	
X	cd = (struct callData *)XtMalloc(XtNumber(patternList) *
X						sizeof(struct callData));
X
X	gc = XCreateGC(XtDisplay(pattern), DefaultRootWindow(XtDisplay(pattern)), 0, 0);
X	for (i = 0; i < XtNumber(color); i++) {
X		Pixmap			pix;
X		char			buf[40];
X
X		if (!color[i].doit)
X			continue;
X
X		pix = XCreatePixmap(XtDisplay(pattern),
X				DefaultRootWindow(XtDisplay(pattern)),
X				32, 32,
X				DefaultDepthOfScreen(XtScreen(pattern)));
X		XSetForeground(XtDisplay(pattern), gc, color[i].pixel);
X		XFillRectangle(XtDisplay(pattern), pix, gc, 0, 0, 32, 32);
X
X		sprintf(buf, "solid%d", i);
X		icon = XtVaCreateManagedWidget(XtNewString(buf),
X				toggleWidgetClass, pattern,
X				XtNbitmap, pix,
X				XtNradioGroup, firstIcon,
X				NULL);
X		XtVaSetValues(icon, XtNradioData, icon, NULL);
X
X		if (firstIcon == NULL) {
X			XtVaSetValues(icon, XtNstate, True, NULL);
X			XtVaSetValues(paint, XtNpattern, pix, NULL);
X			firstIcon = icon;
X		}
X
X		XtAddCallback(icon, XtNcallback, ToggleSetPattern, paint);
X	}
X	XFreeGC(XtDisplay(pattern), gc);
X
X	for (i = 0; i < XtNumber(patternList); i++) {
X		Pixmap			pix;
X		char			buf[40];
X
X		pix = XCreatePixmapFromBitmapData(
X				XtDisplay(pattern), 
X				DefaultRootWindow(XtDisplay(pattern)),
X				patternList[i].bits,
X				patternList[i].width,
X				patternList[i].height,
X				WhitePixelOfScreen(XtScreen(pattern)),
X				BlackPixelOfScreen(XtScreen(pattern)),
X				DefaultDepthOfScreen(XtScreen(pattern)));
X		
X		sprintf(buf, "pattern%d", i);
X		icon = XtVaCreateManagedWidget(XtNewString(buf),
X				toggleWidgetClass, pattern,
X				XtNbitmap, pix,
X				XtNradioGroup, firstIcon,
X				NULL);
X		XtVaSetValues(icon, XtNradioData, icon, NULL);
X
X		if (firstIcon == NULL) {
X			XtVaSetValues(icon, XtNstate, True, NULL);
X			XtVaSetValues(paint, XtNpattern, pix, NULL);
X			firstIcon = icon;
X		}
X
X		XtAddCallback(icon, XtNcallback, ToggleSetPattern, paint);
X	}
X
X	edit = XtVaCreateManagedWidget("edit",
X			commandWidgetClass, form,
X			XtNfromHoriz, viewport2,
X			XtNfromVert,  viewport,
X			NULL);
X	add  = XtVaCreateManagedWidget("add",
X			commandWidgetClass, form,
X			XtNfromHoriz, viewport2,
X			XtNfromVert,  edit,
X			NULL);
X	wl[0] = paint;
X	wl[1] = firstIcon;
X	XtAddCallback(edit, XtNcallback, editCallback, wl);
X	XtAddCallback(add , XtNcallback, addCallback, wl);
X
X	XtManageChild(shell);
X	XtRealizeWidget(shell);
X
X	GraphicAdd(paint);
X}
X
Xvoid	OpenFile(Widget w, char *file, int type)
X{
X	Pixmap			pix = None;
X	Colormap		cmap;
X	unsigned int		width, height;
X	int			xHot, yHot;
X
X	if (file == NULL)
X		return;
X
X	switch (type) {
X	case FT_PBM:
X		if (ReadPNM(w, file, &width, &height, &pix, &cmap)) {
X			/* Error */
X			return;
X		}
X		break;
X	case FT_XBM:
X		if (XReadBitmapFile(XtDisplay(w), 
X				DefaultRootWindow(XtDisplay(w)),
X				file, &width, &height, &pix, 
X				&xHot, &yHot) != BitmapSuccess) {
X			/* Error */
X			return;
X		}
X		cmap = None;
X		break;
X	default:
X		printf("Unknown filetype\n"); break;
X	}
X
X	graphicCreate(w, pix, cmap);
X}
X
Xvoid GraphicCreate(Widget wid, Boolean flag)
X{
X	if (flag)
X		GetFileName(GetToplevel(wid), False, NULL, OpenFile, NULL);
X	else
X		graphicCreate(wid, None, None);
X}

END_OF_FILE
echo shar: NEWLINE appended to \"'Graphic.c'\"
if test 11562 -ne `wc -c <'Graphic.c'`; then
    echo shar: \"'Graphic.c'\" unpacked with wrong size!
fi
# end of 'Graphic.c'
fi
if test -f 'Operation.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Operation.c'\"
else
echo shar: Extracting \"'Operation.c'\" \(7373 characters\)
sed "s/^X//" >'Operation.c' <<'END_OF_FILE'
X/* +-------------------------------------------------------------------+ */
X/* | Copyright 1992, David Koblas.                                     | */
X/* |   Permission to use, copy, modify, and distribute this software   | */
X/* |   and its documentation for any purpose and without fee is hereby | */
X/* |   granted, provided that the above copyright notice appear in all | */
X/* |   copies and that both that copyright notice and this permission  | */
X/* |   notice appear in supporting documentation.  This software is    | */
X/* |   provided "as is" without express or implied warranty.           | */
X/* +-------------------------------------------------------------------+ */
X
X#include <X11/Intrinsic.h>
X#include <X11/StringDefs.h>
X#include <X11/Xaw/Form.h>
X#include <X11/Xaw/Box.h>
X#include <X11/Xaw/Toggle.h>
X#include <X11/cursorfont.h>
X
X#include <stdlib.h>
X
X#include "bitmaps/brushOp.xbm"
X#include "bitmaps/eraseOp.xbm"
X#include "bitmaps/sprayOp.xbm"
X#include "bitmaps/pencilOp.xbm"
X#include "bitmaps/lineOp.xbm"
X#include "bitmaps/arcOp.xbm"
X#include "bitmaps/fillOp.xbm"
X#include "bitmaps/textOp.xbm"
X#include "bitmaps/selectOp.xbm"
X#include "bitmaps/boxOp.xbm"
X#include "bitmaps/fboxOp.xbm"
X#include "bitmaps/ovalOp.xbm"
X#include "bitmaps/fovalOp.xbm"
X#include "bitmaps/clineOp.xbm"
X#include "bitmaps/polyOp.xbm"
X#include "bitmaps/fpolyOp.xbm"
X#include "bitmaps/selareaOp.xbm"
X
X#include "bitmaps/checkmark.xbm"
X
X#define	OP_BEGIN	0
X#define	OP_END		1
X
X#include "xpaint.h"
X#include "Paint.h"
X
Xstatic void setOperation(Widget w, Operation_t *op) 
X{
X	Operation_t	stop, start;
X
X	stop  = CurrentOp ? CurrentOp[OP_END]   : NULL;
X	start = op        ? op       [OP_BEGIN] : NULL;
X
X	GraphicSetOp(stop, start);
X
X	CurrentOp = op;
X}
X
X/*
X**  The font callback pair
X*/
Xstatic void setPaintFont(Widget w, XFontStruct *info)
X{
X	XtVaSetValues(w, XtNfont, info, NULL);
X}
Xstatic void setFont(Widget w, char *name)
X{
X	static XFontStruct	*info = NULL;
X	XFontStruct		*new;
X	Widget			top = GetToplevel(w);
X
X	if ((new = XLoadQueryFont(XtDisplay(top), name)) != NULL) {
X		GraphicAll(setPaintFont, new);
X		if (info != NULL)
X			XUnloadFont(XtDisplay(top), info->fid);
X		info = new;
X	}
X}
X
X/*
X**  The set line width callback pair
X*/
Xstatic void setWidth(Widget w, int width)
X{
X	XtVaSetValues(w, XtNlineWidth, width, NULL);
X}
Xstatic void lineWidth(Widget w, int width)
X{
X	GraphicAll(setWidth, width);
X}
X
X#define GENERATE_OP(name)				\
X	extern void *CONCAT(name,Add)(Widget w,...),	\
X		    *CONCAT(name,Remove)(Widget w,...);	\
X	static Operation_t  CONCAT(name,Op)[] = {	\
X		CONCAT(name,Add), CONCAT(name,Remove)	\
X	};
X
XGENERATE_OP(Pencil)
XGENERATE_OP(Box)
XGENERATE_OP(FBox)
XGENERATE_OP(Line)
XGENERATE_OP(Arc)
XGENERATE_OP(Oval)
XGENERATE_OP(FOval)
XGENERATE_OP(Erase)
XGENERATE_OP(Brush)
XGENERATE_OP(Font)
XGENERATE_OP(Spray)
XGENERATE_OP(Poly)
XGENERATE_OP(FPoly)
XGENERATE_OP(CLine)
XGENERATE_OP(Fill)
XGENERATE_OP(SelectBox)
XGENERATE_OP(SelectArea)
X
X#define	BITMAP(name)	\
X	CONCAT(name,Op_bits) , CONCAT(name,Op_width), CONCAT(name,Op_height)
X
Xstatic struct {
X	char	*name;
X	char	*bitmap;
X	int	width, height;
X	void	(*callback)();		/* By default setOperation() */
X	void	*data;
X} iconList[] = {
X	{ "Brush",	BITMAP(brush), NULL, BrushOp},
X	{ "Erase",	BITMAP(erase), NULL, EraseOp },
X	{ "Spray",	BITMAP(spray), NULL, SprayOp },
X	{ "Pencil",	BITMAP(pencil), NULL, PencilOp },
X	{ "Line",	BITMAP(line), NULL, LineOp },
X	{ "Arc",	BITMAP(arc), NULL, ArcOp },
X	{ "Fill",	BITMAP(fill), NULL, FillOp },
X	{ "Text",	BITMAP(text), NULL, FontOp },
X	{ "SelectBox",	BITMAP(select), NULL, SelectBoxOp },
X	{ "SelectArea",	BITMAP(selarea), NULL, SelectAreaOp },
X	{ "Box",	BITMAP(box), NULL, BoxOp },
X	{ "FBox",	BITMAP(fbox), NULL, FBoxOp },
X	{ "Oval",	BITMAP(oval), NULL, OvalOp },
X	{ "FOval",	BITMAP(foval), NULL, FOvalOp },
X#if 0
X	{ "Circle",	BITMAP(circle), NULL, CircleOp},
X	{ "FCircle",	BITMAP(fcircle), NULL, FCircleOp },
X#endif
X	{ "CLine",	BITMAP(cline), NULL, CLineOp },
X	{ "Polygon",	BITMAP(poly), NULL, PolyOp },
X	{ "FPolygon",	BITMAP(fpoly), NULL, FPolyOp },
X};
X
Xstatic PaintMenuItem fontMenu[] = {
X	{ "34pt", setFont, 
X	  "-adobe-helvetica-medium-o-normal--34-240-100-100-p-176-iso8859-1", MF_NONE },
X	{ "11pt", setFont, 
X	  "-adobe-helvetica-medium-o-normal--11-80-100-100-p-57-iso8859-1", MF_NONE },
X	{ "11pt Bold", setFont, 
X	  "-adobe-helvetica-bold-r-normal--11-80-100-100-p-60-iso8859-1", MF_NONE },
X};
Xstatic PaintMenuItem lineMenu[] = {
X	{ "0", lineWidth, (void*)0, MF_NONE },
X	{ "1", lineWidth, (void*)1, MF_NONE },
X	{ "2", lineWidth, (void*)2, MF_NONE },
X	{ "3", lineWidth, (void*)3, MF_NONE },
X	{ "4", lineWidth, (void*)4, MF_NONE },
X	{ "5", lineWidth, (void*)5, MF_NONE },
X	{ "6", lineWidth, (void*)6, MF_NONE },
X	{ "7", lineWidth, (void*)7, MF_NONE },
X	{ "8", lineWidth, (void*)8, MF_NONE },
X};
X
Xstatic PaintMenuItem otherMenu[] = {
X	{ "brushSelect", BrushSelect, NULL, MF_NONE },
X	{ "fontSelect", FontSelect, NULL, MF_NONE },
X	{ "sprayEdit", NULL, NULL, MF_NONE },
X};
X
Xstatic PaintMenuItem fileMenu[] = {
X	{ "new",   (PaintMenuCallback)GraphicCreate, (void*)False, MF_NONE },
X	{ "open",  (PaintMenuCallback)GraphicCreate, (void*)True, MF_NONE },
X	{ "",	   NULL, NULL, MF_NONE },
X	{ "quit",  exit, NULL, MF_NONE },
X};
X
Xstatic PaintMenuBar   menuBar[] = {
X	{ "file",  XtNumber(fileMenu), fileMenu },
X	{ "other",  XtNumber(otherMenu), otherMenu },
X	{ "line",  XtNumber(lineMenu), lineMenu },
X	{ "font",  XtNumber(fontMenu), fontMenu },
X};
X
Xvoid OperationInit(Widget toplevel)
X{
X	int		i;
X	Pixmap		pix;
X	Widget		form, box, icon, bar, firstIcon = NULL;
X	Pixel		fg, bg;
X	XGCValues	values;
X
X	form = XtVaCreateManagedWidget("toolbox", 
X			formWidgetClass, toplevel,
X			XtNborderWidth, 0,
X			NULL);
X	/*
X	**  Create the menu bar
X	*/
X	bar = MenuBarCreate(form, XtNumber(menuBar), menuBar);
X
X	/*
X	**  Create the operation icon list
X	*/
X	box = XtVaCreateManagedWidget("box", 
X			boxWidgetClass, form,
X			XtNfromVert, bar,
X			XtNwidth, 32 * 8,
X			NULL);
X
X	XtVaGetValues(box, XtNforeground, &fg,
X			   XtNbackground, &bg, 
X			   NULL);
X
X	for (i = 0; i < XtNumber(iconList); i++) {
X		if (iconList[i].bitmap != NULL) {
X			pix = XCreatePixmapFromBitmapData(
X					XtDisplay(box), 
X					DefaultRootWindow(XtDisplay(box)),
X					iconList[i].bitmap,
X					iconList[i].width,
X					iconList[i].height,
X					fg, bg,
X					DefaultDepthOfScreen(XtScreen(box)));
X
X		} else {
X			pix = NULL;
X		}
X		icon = XtVaCreateManagedWidget(iconList[i].name,
X			toggleWidgetClass, box,
X			XtNtranslations, 
X				XtParseTranslationTable(
X					"<BtnDown>,<BtnUp>: set() notify()"),
X			XtNbitmap, pix,
X			XtNradioGroup, firstIcon,
X			NULL);
X		if (firstIcon == NULL) {
X			XtVaSetValues(icon, XtNstate, True, NULL);
X			setOperation(icon, iconList[i].data);
X
X			firstIcon = icon;
X		}
X		if (iconList[i].callback != NULL)
X			XtAddCallback(icon, XtNcallback, 
X				iconList[i].callback, iconList[i].data);
X		else
X			XtAddCallback(icon, XtNcallback, 
X				setOperation, iconList[i].data);
X	}
X
X	CheckBitmap = XCreateBitmapFromData(XtDisplay(toplevel), 
X				DefaultRootWindow(XtDisplay(toplevel)),
X				checkmark_bits,
X				checkmark_width,
X				checkmark_height);
X
X	/*
X	**  Init the global xor gc
X	*/
X        values.background = WhitePixelOfScreen(XtScreen(toplevel));
X        values.foreground = BlackPixelOfScreen(XtScreen(toplevel));
X        values.function   = GXinvert;
X	Global.gcx  = XtGetGC(toplevel, GCFunction|GCForeground|GCBackground, &values);
X}

END_OF_FILE
echo shar: NEWLINE appended to \"'Operation.c'\"
if test 7374 -ne `wc -c <'Operation.c'`; then
    echo shar: \"'Operation.c'\" unpacked with wrong size!
fi
# end of 'Operation.c'
fi
if test -f 'PolyOp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'PolyOp.c'\"
else
echo shar: Extracting \"'PolyOp.c'\" \(6140 characters\)
sed "s/^X//" >'PolyOp.c' <<'END_OF_FILE'
X/* +-------------------------------------------------------------------+ */
X/* | Copyright 1992, David Koblas.                                     | */
X/* |   Permission to use, copy, modify, and distribute this software   | */
X/* |   and its documentation for any purpose and without fee is hereby | */
X/* |   granted, provided that the above copyright notice appear in all | */
X/* |   copies and that both that copyright notice and this permission  | */
X/* |   notice appear in supporting documentation.  This software is    | */
X/* |   provided "as is" without express or implied warranty.           | */
X/* +-------------------------------------------------------------------+ */
X
X#include <X11/Intrinsic.h>
X#include <X11/StringDefs.h>
X#include <X11/cursorfont.h>
X#include "xpaint.h"
X
X#define	FILL		0x2
X#define	POLY		0x1
X#define IsPoly(x)	(x & POLY)
X#define	IsFill(x)	(x & FILL)
X
X#define MAXP	100
X
Xtypedef struct {
X	int	flag;
X	int	startX, startY, endX, endY, button;
X	int	drawn, first, tracking, last;
X	int	npoints;
X	XPoint	points[MAXP+1];
X	XPoint	real[MAXP+1];
X	/*
X	**  Borrowed from my info structure.
X	*/
X	GC	gc;
X	Pixmap	pixmap;
X	Widget	widget;
X	Boolean	isFat;
X} LocalInfo;
X
Xstatic void	press(Widget w, LocalInfo *l, XButtonEvent *event, OpInfo *info)
X{
X	if (!l->tracking) {
X		l->endX = l->startX = event->x;
X		l->endY = l->startY = event->y;
X
X		l->button = event->button;
X
X		l->npoints = 0;
X
X		l->points[l->npoints].x = event->x;
X		l->points[l->npoints].y = event->y;
X		l->real[l->npoints].x = info->x;
X		l->real[l->npoints].y = info->y;
X		l->npoints++;
X
X		l->drawn = False;
X		l->tracking = True;
X		l->first = True;
X		l->last = False;
X
X		l->isFat = info->isFat;
X		l->gc    = info->filled_gc;
X	} else if (l->button != event->button) {
X		l->last = True;
X	}
X}
X
Xstatic void 	finish(Widget w, LocalInfo *l, Boolean flag)
X{
X	if (!l->tracking)
X		return;
X
X	l->tracking = False;
X
X	if (l->drawn)
X		XDrawLines(XtDisplay(w), XtWindow(w), Global.gcx,
X			l->points, l->npoints, CoordModeOrigin);
X	if (flag && l->drawn)
X		XDrawLine(XtDisplay(w), XtWindow(w), Global.gcx,
X			l->points[l->npoints-1].x,
X			l->points[l->npoints-1].y,
X			l->endX, l->endY);
X
X	if (IsFill(l->flag)) {
X		if (!l->isFat)
X			XFillPolygon(XtDisplay(w), XtWindow(w), l->gc,
X				l->real, l->npoints, Complex, CoordModeOrigin);
X		XFillPolygon(XtDisplay(w),  l->pixmap, l->gc, 
X				l->real, l->npoints, Complex,CoordModeOrigin);
X	} else {
X		if (IsPoly(l->flag)) {
X			l->real[l->npoints].x = l->real[0].x;
X			l->real[l->npoints].y = l->real[0].y;
X			l->npoints++;
X		}
X		if (!l->isFat)
X			XDrawLines(XtDisplay(w), XtWindow(w), l->gc,
X				l->real, l->npoints, CoordModeOrigin);
X		XDrawLines(XtDisplay(w),  l->pixmap, l->gc, 
X				l->real, l->npoints, CoordModeOrigin);
X	}
X	PwUpdate(w, NULL, False);
X}
X
Xstatic void	release(Widget w, LocalInfo *l, XButtonEvent *event, OpInfo *info)
X{
X	if (l->npoints == MAXP - 1) {
X		return;
X	}
X	if (l->first) {
X		if (info->surface == opPixmap) {
X			UndoStart(w, info);
X			l->first = False;
X			l->pixmap = info->drawable;
X			l->widget = w;
X		}
X		return;
X	}
X
X	if (info->surface == opWindow) {
X		l->endX = l->points[l->npoints].x = event->x;
X		l->endY = l->points[l->npoints].y = event->y;
X		l->startX = event->x;
X		l->startY = event->y;
X		return;
X	}
X
X	l->real[l->npoints].x   = info->x;
X	l->real[l->npoints].y   = info->y;
X	l->npoints++;
X
X	UndoGrow(w, info->x, info->y);
X
X	if (l->last)
X		finish(w, l, False);
X}
X
Xstatic void	motion(Widget w, LocalInfo *l, XMotionEvent *event, OpInfo *info)
X{
X	/*
X	**  Haven't done the first button press
X	*/
X	if (!l->tracking)
X		return;
X
X	if (l->drawn) 
X		XDrawLine(XtDisplay(w), info->drawable, Global.gcx,
X				l->startX, l->startY, l->endX, l->endY);
X
X	l->endX = event->x;
X	l->endY = event->y;
X
X	if (l->drawn = (l->startX != l->endX && l->startY != l->endY)) 
X		XDrawLine(XtDisplay(w), info->drawable, Global.gcx,
X				l->startX, l->startY, l->endX, l->endY);
X}
X
X
X/*
X**  Those public functions
X*/
Xvoid *PolyAdd(Widget w)
X{
X	LocalInfo	*l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
X
X	l->flag = POLY;
X	l->drawn = False;
X	l->first = True;
X	l->tracking = False;
X	l->last = False;
X
X	OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE, press, l);
X	OpAddEventHandler(w, opWindow, PointerMotionMask, FALSE, motion, l);
X	OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, release, l);
X	SetCrossHairCursor(w);
X
X	return l;
X}
Xvoid PolyRemove(Widget w, LocalInfo *l)
X{
X	OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE, press, l);
X	OpRemoveEventHandler(w, opWindow, PointerMotionMask, FALSE, motion, l);
X	OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, release, l);
X
X	finish(w, l, True);
X
X	XtFree(l);
X}
Xvoid *FPolyAdd(Widget w)
X{
X	LocalInfo	*l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
X
X	l->flag = POLY|FILL;
X	l->drawn = False;
X	l->first = True;
X	l->tracking = False;
X	l->last = False;
X
X	OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE, press, l);
X	OpAddEventHandler(w, opWindow, PointerMotionMask, FALSE, motion, l);
X	OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, release, l);
X	SetCrossHairCursor(w);
X
X	return l;
X}
Xvoid FPolyRemove(Widget w, LocalInfo *l)
X{
X	OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE, press, l);
X	OpRemoveEventHandler(w, opWindow, PointerMotionMask, FALSE, motion, l);
X	OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, release, l);
X
X	finish(w, l, True);
X	XtFree(l);
X}
Xvoid *CLineAdd(Widget w)
X{
X	LocalInfo	*l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
X
X	l->flag = 0;
X	l->drawn = False;
X	l->first = True;
X	l->tracking = False;
X	l->last = False;
X
X	OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE, press, l);
X	OpAddEventHandler(w, opWindow, PointerMotionMask, FALSE, motion, l);
X	OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, release, l);
X	SetCrossHairCursor(w);
X
X	return l;
X}
Xvoid CLineRemove(Widget w, LocalInfo *l)
X{
X	OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE, press, l);
X	OpRemoveEventHandler(w, opWindow, PointerMotionMask, FALSE, motion, l);
X	OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, release, l);
X
X	finish(w, l, True);
X	XtFree(l);
X}

END_OF_FILE
echo shar: NEWLINE appended to \"'PolyOp.c'\"
if test 6141 -ne `wc -c <'PolyOp.c'`; then
    echo shar: \"'PolyOp.c'\" unpacked with wrong size!
fi
# end of 'PolyOp.c'
fi
if test -f 'libpnmrw.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libpnmrw.h'\"
else
echo shar: Extracting \"'libpnmrw.h'\" \(6162 characters\)
sed "s/^X//" >'libpnmrw.h' <<'END_OF_FILE'
X/* pnmrw.h - header file for PBM/PGM/PPM read/write library
X**
X** Copyright (C) 1988, 1989, 1991 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#ifndef _PNMRW_H_
X#define _PNMRW_H_
X
X/* CONFIGURE: On some systems, malloc.h doesn't declare these, so we have
X** to do it.  On other systems, for example HP/UX, it declares them
X** incompatibly.  And some systems, for example Dynix, don't have a
X** malloc.h at all.  A sad situation.  If you have compilation problems
X** that point here, feel free to tweak or remove these declarations.
X#include <malloc.h>
X*/
X
X/* End of configurable definitions. */
X
X
X/* Definitions to make PBMPLUS work with either ANSI C or C Classic. */
X
X#if __STDC__
X#define ARGS(alist) alist
X#else /*__STDC__*/
X#define ARGS(alist) ()
X#define const
X#endif /*__STDC__*/
X
X
X/* Types. */
X
Xtypedef unsigned char bit;
X#define PBM_WHITE 0
X#define PBM_BLACK 1
X#define PBM_FORMAT_TYPE(f) ((f) == PBM_FORMAT || (f) == RPBM_FORMAT ? PBM_TYPE : -1)
X
Xtypedef unsigned char gray;
X#define PGM_MAXMAXVAL 255
X#define PGM_FORMAT_TYPE(f) ((f) == PGM_FORMAT || (f) == RPGM_FORMAT ? PGM_TYPE : PBM_FORMAT_TYPE(f))
X
Xtypedef gray pixval;
X#define PPM_MAXMAXVAL PGM_MAXMAXVAL
Xtypedef struct
X    {
X    pixval r, g, b;
X    } pixel;
X#define PPM_GETR(p) ((p).r)
X#define PPM_GETG(p) ((p).g)
X#define PPM_GETB(p) ((p).b)
X#define PPM_ASSIGN(p,red,grn,blu) do { (p).r = (red); (p).g = (grn); (p).b = (blu); } while ( 0 )
X#define PPM_EQUAL(p,q) ( (p).r == (q).r && (p).g == (q).g && (p).b == (q).b )
X#define PPM_FORMAT_TYPE(f) ((f) == PPM_FORMAT || (f) == RPPM_FORMAT ? PPM_TYPE : PGM_FORMAT_TYPE(f))
X
Xtypedef pixel xel;
Xtypedef pixval xelval;
X#define PNM_MAXMAXVAL PPM_MAXMAXVAL
X#define PNM_GET1(x) PPM_GETB(x)
X#define PNM_ASSIGN1(x,v) PPM_ASSIGN(x,0,0,v)
X#define PNM_EQUAL(x,y) PPM_EQUAL(x,y)
X#define PNM_FORMAT_TYPE(f) PPM_FORMAT_TYPE(f)
X
X
X/* Magic constants. */
X
X#define PBM_MAGIC1 'P'
X#define PBM_MAGIC2 '1'
X#define RPBM_MAGIC2 '4'
X#define PBM_FORMAT (PBM_MAGIC1 * 256 + PBM_MAGIC2)
X#define RPBM_FORMAT (PBM_MAGIC1 * 256 + RPBM_MAGIC2)
X#define PBM_TYPE PBM_FORMAT
X
X#define PGM_MAGIC1 'P'
X#define PGM_MAGIC2 '2'
X#define RPGM_MAGIC2 '5'
X#define PGM_FORMAT (PGM_MAGIC1 * 256 + PGM_MAGIC2)
X#define RPGM_FORMAT (PGM_MAGIC1 * 256 + RPGM_MAGIC2)
X#define PGM_TYPE PGM_FORMAT
X
X#define PPM_MAGIC1 'P'
X#define PPM_MAGIC2 '3'
X#define RPPM_MAGIC2 '6'
X#define PPM_FORMAT (PPM_MAGIC1 * 256 + PPM_MAGIC2)
X#define RPPM_FORMAT (PPM_MAGIC1 * 256 + RPPM_MAGIC2)
X#define PPM_TYPE PPM_FORMAT
X
X
X/* Color scaling macro -- to make writing ppmtowhatever easier. */
X
X#define PPM_DEPTH(newp,p,oldmaxval,newmaxval) \
X    PPM_ASSIGN( (newp), \
X	( (int) PPM_GETR(p) * (newmaxval) + (oldmaxval) / 2 ) / (oldmaxval), \
X	( (int) PPM_GETG(p) * (newmaxval) + (oldmaxval) / 2 ) / (oldmaxval), \
X	( (int) PPM_GETB(p) * (newmaxval) + (oldmaxval) / 2 ) / (oldmaxval) )
X
X
X/* Luminance macro. */
X
X#define PPM_LUMIN(p) ( 0.299 * PPM_GETR(p) + 0.587 * PPM_GETG(p) + 0.114 * PPM_GETB(p) )
X
X
X/* Declarations of pnmrw routines. */
X
Xvoid pnm_init2 ARGS(( char* pn ));
X
Xchar** pm_allocarray ARGS(( int cols, int rows, int size ));
X#define pnm_allocarray( cols, rows ) ((xel**) pm_allocarray( cols, rows, sizeof(xel) ))
Xchar* pm_allocrow ARGS(( int cols, int size ));
X#define pnm_allocrow( cols ) ((xel*) pm_allocrow( cols, sizeof(xel) ))
Xvoid pm_freearray ARGS(( char** its, int rows ));
X#define pnm_freearray( xels, rows ) pm_freearray( (char**) xels, rows )
Xvoid pm_freerow ARGS(( char* itrow ));
X#define pnm_freerow( xelrow ) pm_freerow( (char*) xelrow )
X
Xxel** pnm_readpnm ARGS(( FILE* file, int* colsP, int* rowsP, xelval* maxvalP, int* formatP ));
Xint pnm_readpnminit ARGS(( FILE* file, int* colsP, int* rowsP, xelval* maxvalP, int* formatP ));
Xint pnm_readpnmrow ARGS(( FILE* file, xel* xelrow, int cols, xelval maxval, int format ));
X
Xint pnm_writepnm ARGS(( FILE* file, xel** xels, int cols, int rows, xelval maxval, int format, int forceplain ));
Xint pnm_writepnminit ARGS(( FILE* file, int cols, int rows, xelval maxval, int format, int forceplain ));
Xint pnm_writepnmrow ARGS(( FILE* file, xel* xelrow, int cols, xelval maxval, int format, int forceplain ));
X
Xextern xelval pnm_pbmmaxval;
X/* This is the maxval used when a PNM program reads a PBM file.  Normally
X** it is 1; however, for some programs, a larger value gives better results
X*/
X
X
X/* File open/close that handles "-" as stdin and checks errors. */
X
XFILE* pm_openr ARGS(( char* name ));
XFILE* pm_openw ARGS(( char* name ));
Xint pm_closer ARGS(( FILE* f ));
Xint pm_closew ARGS(( FILE* f ));
X
X
X/* Colormap stuff. */
X
Xtypedef struct colorhist_item* colorhist_vector;
Xstruct colorhist_item
X    {
X    pixel color;
X    int value;
X    };
X
Xtypedef struct colorhist_list_item* colorhist_list;
Xstruct colorhist_list_item
X    {
X    struct colorhist_item ch;
X    colorhist_list next;
X    };
X
Xtypedef colorhist_list* colorhash_table;
X
Xcolorhist_vector ppm_computecolorhist ARGS(( pixel** pixels, int cols, int rows, int maxcolors, int* colorsP ));
X/* Returns a colorhist *colorsP long (with space allocated for maxcolors. */
X
Xvoid ppm_addtocolorhist ARGS(( colorhist_vector chv, int* colorsP, int maxcolors, pixel* colorP, int value, int position ));
X
Xvoid ppm_freecolorhist ARGS(( colorhist_vector chv ));
X
Xcolorhash_table ppm_computecolorhash ARGS(( pixel** pixels, int cols, int rows, int maxcolors, int* colorsP ));
X
Xint
Xppm_lookupcolor ARGS(( colorhash_table cht, pixel* colorP ));
X
Xcolorhist_vector ppm_colorhashtocolorhist ARGS(( colorhash_table cht, int maxcolors ));
Xcolorhash_table ppm_colorhisttocolorhash ARGS(( colorhist_vector chv, int colors ));
X
Xint ppm_addtocolorhash ARGS(( colorhash_table cht, pixel* colorP, int value ));
X/* Returns -1 on failure. */
X
Xcolorhash_table ppm_alloccolorhash ARGS(( void ));
X
Xvoid ppm_freecolorhash ARGS(( colorhash_table cht ));
X
X#endif /*_PNMRW_H_*/

END_OF_FILE
echo shar: NEWLINE appended to \"'libpnmrw.h'\"
if test 6163 -ne `wc -c <'libpnmrw.h'`; then
    echo shar: \"'libpnmrw.h'\" unpacked with wrong size!
fi
# end of 'libpnmrw.h'
fi
echo shar: End of archive 2 \(of 5\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 5 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 5 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
name : David Koblas                        domain: koblas@mips.com
quote: If you have sex in your car, does that make it a recreational vehicle?
Technical Details
Message-ID: <l5pajmINNmho@spim.mips.com>
Path: arc1-ca.pugleaf.net!wupost!zaphod.mps.ohio-state.edu!mips!koblas

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!wupost!zaphod.mps.ohio-state.edu!mips!koblas
From: koblas@mips.com (David Koblas)
Newsgroups: comp.windows.x.apps,alt.sources
Subject: BETA Version of XPaint 2.0  -- Part 2 / 5
Date: 9 Jul 1992 21:07:02 GMT
Organization: MIPS Computer Systems, Sunnyvale, California
Lines: 2013
Distribution: world
Message-ID: <l5pajmINNmho@spim.mips.com>
NNTP-Posting-Host: lloyd.mips.com
Originator: koblas@lloyd.mips.com