[comp.sources.misc] v02i047: sunplot - Unix plot backend for Sun

sjoerd@cs.vu.nl (Sjoerd Mullender) (02/06/88)

Comp.sources.misc: Volume 2, Issue 47

Submitted-By: "Sjoerd Mullender" <sjoerd@cs.vu.nl>

Archive-Name: sunplot


Comp.sources.misc: Volume 2, Issue 47
Submitted-By: "Sjoerd Mullender" <sjoerd@cs.vu.nl>
Archive-Name: sunplot

This is a backend for Unix plot code (see plot(5)) for the Sun workstation.
It creates a window in which the plot is displayed.

: This is a shar archive.  Extract with sh, not csh.
: This archive ends with exit, so do not worry about trailing junk.
: --------------------------- cut here --------------------------
PATH=/bin:/usr/bin:/usr/ucb
echo Extracting 'README'
sed 's/^X//' > 'README' << '+ END-OF-FILE ''README'
XThis program was written on a Sun 3/50 running SunOS 3.2.
XIt also compiles and runs on a Sun 3/50 running SunOS 3.4.
X
XTo make simply type ``make''.
XTo install, check the Makefile to see if all the names are correct.  Then
Xtype ``make install''.
X
XIf you find any bugs or if you have any suggestions or improvements, please
Xdrop me a note at the address below.
X
XYou might try the command
X	echo 0 0 1 1 2 4 3 9 4 16 | spline | graph | sunplot
Xafter which a window pops up.  Then click the ``Next Page'' button.
X
XSjoerd Mullender
XDept. of Mathematics and Computer Science
XFree University
XAmsterdam
XNetherlands
X
XEmail: sjoerd@cs.vu.nl
XIf this doesn't work, try ...!seismo!mcvax!cs.vu.nl!sjoerd or
X...!seismo!mcvax!vu44!sjoerd or sjoerd%cs.vu.nl@seismo.css.gov.
+ END-OF-FILE README
chmod 'u=rw,g=r,o=r' 'README'
set `wc -c 'README'`
count=$1
case $count in
756)	:;;
*)	echo 'Bad character count in ''README' >&2
		echo 'Count should be 756' >&2
esac
echo Extracting 'Makefile'
sed 's/^X//' > 'Makefile' << '+ END-OF-FILE ''Makefile'
X# The names of the installed binary and manual page.
X# Feel free to change.
XBINARY	= /usr/local/sunplot
XMANUAL	= /usr/man/manl/sunplot.l
X
XCFLAGS	= -O
X
Xsunplot:	sunplot.o
X		$(CC) -o sunplot sunplot.o -lsuntool -lsunwindow -lpixrect
X
Xinstall:	sunplot
X		cp sunplot $(BINARY)
X		cp sunplot.1 $(MANUAL)
X
Xclean:
X		rm -f sunplot *.o core make.out
X
Xsunplot.o:	sunplot.icon
+ END-OF-FILE Makefile
chmod 'u=rw,g=r,o=r' 'Makefile'
set `wc -c 'Makefile'`
count=$1
case $count in
364)	:;;
*)	echo 'Bad character count in ''Makefile' >&2
		echo 'Count should be 364' >&2
esac
echo Extracting 'sunplot.1'
sed 's/^X//' > 'sunplot.1' << '+ END-OF-FILE ''sunplot.1'
X.TH SUNPLOT 1
X.SH NAME
Xsunplot \- plotter backend for Sun workstation
X.SH SYNOPSIS
X.B sunplot
X[
X.B \-c
X.I canvas_size
X] [
X.B \-h
X.I horizontal_size
X] [
X.B \-v
X.I vertical_size
X] [
X.B \-f
X.I font_name
X] [
X.B \-r
X] [
X.B \-x
X] [
X.B \-y
X] [
X.B \-l
X] [
X.B \-s
X]
X.SH DESCRIPTION
X.I Sunplot
Xreads UNIX plotter code (see
X.IR plot (5))
Xfrom standard input and displays it in a Sun window.
XThe window consists of two subwindows.
XAt the top is a control panel with a number of buttons and below it is
Xa window with a canvas on which
X.I sunplot
Xdraws and a horizontal and a vertical scrollbar with which you can select
Xwhich part of the canvas you want to see in the window.
XThe buttons in the control panel have the following functions:
X.TP
X.B "Next Page"
XDraw the next page.
XPages are separated by an
X.B e
X(the
X.I erase
Xfunction in the
X.IR plot (3X)
Xlibrary).
XWhile
X.I sunplot
Xis still reading a page this button is not displayed.
X.TP
X.B Redraw
XRedraw the current page.
X.TP
X.B Zoom
XZoom the current page.
X.I Sunplot
Xfinds the most extreme x- and y-coordinates in the current page and uses
Xthose values in stead of the values given by the
X.B s
Xcommand (the
X.I space
Xfunction) for scaling.
X.TP
X.B Options
X.I Sunplot
Xdisplays a window where you can set certain options.
XSee the description below.
X.TP
X.B Dump
X.I Sunplot
Xdisplays a window with three items.
XYou should type a file name after the string
X.B Dump to file:
Xand then press the
X.B Done
Xbutton.
X.I Sunplot
Xwill then dump the plot into the named file in the format chosen with the
X.B Dump format
Xitem.
XThe dump can be in either
X.IR rasterfile (5)
Xor
X.I icon
Xformat.
XIf the file name is empty,
X.I sunplot
Xwill do nothing.
X.TP
X.B "Fit Screen"
XResize the window so that the canvas fits.
X.TP
X.B Quit
XExit
X.IR sunplot .
X.SH OPTIONS
XWhen the
X.B Options
Xbutton is pressed
X.I sunplot
Xwill display a window with the following items.
X.TP
X.B Done
XDone setting options.
X.I Sunplot
Xwill automatically do a redraw of the page with the new settings.
X.TP
X.B Rotate
XRotate the plot by 90 degrees counter-clockwise.
X.TP
X.B "X Mirror"
XMirror the plot in the x-axis.
X.TP
X.B "Y Mirror"
XMirror the plot in the y-axis.
X.TP
X.B Label
XIf on, display labels.
X.TP
X.B Square
XIf on, the canvas is square, otherwise you can set the horizontal and vertical
Xsizes of the canvas separately.
X.TP
X.B Reverse
XDisplay the canvas in reverse video.
X.TP
X.B "Font name"
XThe name of the font to be used for the labels.
XIf the name is not absolute it is taken to be relative to the system's fonts
Xdirectory /usr/lib/fonts/fixedwidthfonts.
XIf no name is given or the named file does not contain a font, the default
Xfont is used.
X.TP
X.B "Canvas size"
XThe size of the canvas.
XThe size of the canvas is measured in pixels.
XThis is only displayed when the
X.B Square
Xtoggle is on.
X.TP
X.B "Horizontal size"
XThe horizontal size of the canvas.
XThis is only displayed when the
X.B Square
Xtoggle is off.
X.TP
X.B "Vertical size"
XThe vertical size of the canvas.
XThis is only displayed when the
X.B Square
Xtoggle is off.
X.PP
XThe following command line options are recognized.
X.IP "\f3\-c\fP \f2canvas_size\fP"
XSet the canvas size.
X.I Canvas_size
Xmust be between 64 and 2048.
XThis also switches on the
X.B Square
Xtoggle.
X.IP "\f3\-h\fP \f2horizontal_size\fP"
XSet the horizontal size.
X.I Horizontal_size
Xmust be between 64 and 2048.
XThis also switches off the
X.B Square
Xtoggle.
X.IP "\f3\-v\fP \f2vertical_size\fP"
XSet the vertical size.
X.I Vertical_size
Xmust be between 64 and 2048.
XThis also switches off the
X.B Square
Xtoggle.
X.IP "\f3\-f\fP \f2font_name\fP"
XSet the font to be used for labels.
XThis is independent from the font that is used for the text in the control
Xpanel and the options and dump windows.
XA name not starting with ``/'' is taken to be relative to the system's font
Xdirectory /usr/lib/fonts/fixedwidthfonts.
X.IP \f3\-r\fP
XRotate the plot by 90 degrees counter-clockwise.
X.IP \f3\-x\fP
XMirror the plot in the x-axis.
X.IP \f3\-y\fP
XMirror the plot in the y-axis.
X.IP \f3\-l\fP
XToggle labeling.
X.IP \f3\-s\fP
XToggle square mode.
X.PP
XThe
X.BR \-r ,
X.B \-x
Xand
X.B \-y
Xoptions are evaluated left to right and can be repeated to get cumulative
Xeffect.
X.I Sunplot
Xalso recognizes the generic tool arguments; see
X.IR suntools (1)
Xfor a list of these arguments.
X.PP
XThe defaults are: batching on, labels printed, square canvas, canvas is 512
Xby 512 pixels, the point
X.I "(0,\ 0)"
Xis in the lower left-hand corner.
X.SH BUGS
XThe
X.I linemod
Xfunction is not implemented.
X.PP
XThe
X.B zoom
Xcommand doesn't take the height of labels into account.
X.SH "SEE ALSO"
X.IR plot (3X),
X.IR plot (5),
Xand
X.IR rasterfile (5).
X.SH AUTHOR
XSjoerd Mullender, Free University, Amsterdam <sjoerd@cs.vu.nl>
+ END-OF-FILE sunplot.1
chmod 'u=rw,g=r,o=r' 'sunplot.1'
set `wc -c 'sunplot.1'`
count=$1
case $count in
4672)	:;;
*)	echo 'Bad character count in ''sunplot.1' >&2
		echo 'Count should be 4672' >&2
esac
echo Extracting 'sunplot.c'
sed 's/^X//' > 'sunplot.c' << '+ END-OF-FILE ''sunplot.c'
X/*
X * Sunplot - plotter backend for Sun workstation
X *
X * Copyright (c) 1987 by Sjoerd Mullender, Vrije Universiteit, Amsterdam.
X *
X * This program may be redistributed without fee as long as this copyright
X * notice is in tact.
X * Any commercial use is strictly prohibited.
X */
X
X#include <stdio.h>
X#include <suntool/sunview.h>
X#include <suntool/scrollbar.h>
X#include <suntool/panel.h>
X#include <suntool/canvas.h>
X
X/*
X * Configurable definitions
X */
X#define INIT_CANVAS_SIZE	512
X#define DEFAULT_SPACE		4096
X#define MAX_NAME_LENGTH		128
X
X/*
X * Unconfigurable definitions
X */
X#define BIG			0x7FFFFFFF
X
X#define FORMAT_RASTER		0
X#define FORMAT_ICON		1
X
X#define LABEL			0
X#define SQUARE			1
X#define REVERSE			2
X
Xint client_object;		/* used for notifier */
Xint *me = &client_object;	/* idem */
X
Xint curx, cury;			/* current position on plot */
Xint lox, loy, hix = DEFAULT_SPACE, hiy = DEFAULT_SPACE;	/* current space */
Xint slox, shix, sloy, shiy;	/* saved space settings for zooming */
Xint minx, maxx, miny, maxy;	/* minimum and maximum values encountered */
Xint hor_size, ver_size;		/* canvas size */
Xint turned, xmirror, ymirror;	/* orientation of plot */
Xint zooming;
Xint make_label = TRUE;		/* print labels */
Xint square = TRUE;		/* canvas is square */
Xint reverse = FALSE;		/* reverse video */
XFrame frame, dump_frame, options_frame;
XPanel panel, dump_panel, options_panel;
XPanel_item next_page_item;
XPanel_item hor_size_item, ver_size_item, toggle_item, font_item;
XPanel_item dump_format, dump_file_item;
XCanvas canvas;
XPixwin *pw;
XPixfont *font;
Xchar font_name[MAX_NAME_LENGTH];
Xchar font_dir[] = "/usr/lib/fonts/fixedwidthfonts/";
X
Xshort sunplot_icon_image[] = {
X#include "sunplot.icon"
X};
Xmpr_static(sunplot_icon, 64, 64, 1, sunplot_icon_image);
X
Xchar *malloc(), *realloc();
X
X/*
X *  input module
X */
X
Xstatic char *plotcommands, *plptr;
Xstatic int plotlength;
Xstatic int maxplotlength;
Xstatic int eof_seen;
X
Xgetchr()
X{
X	register c;
X
X	if (plptr < plotcommands + plotlength)
X		return *plptr++ & 0xFF;
X	if (eof_seen || (c = getchar()) == EOF) {
X		eof_seen = 1;
X		return EOF;
X	}
X	if (plotlength >= maxplotlength) {
X		plotcommands = realloc(plotcommands, maxplotlength *= 2);
X		plptr = plotcommands + plotlength;
X	}
X	*plptr++ = c;
X	plotlength++;
X	return c;
X}
X
Xgetint()
X{
X	register n;
X
X	n = getchr();
X	n = n | getchr() << 8;
X	if (n & 0x8000)			/* sign extend */
X		n |= ~0x7FFF;
X	return n;
X}
X
Xchar *getstr()
X{
X	register i = plptr - plotcommands;
X	register c;
X
X	while ((c = getchr()) != EOF && c != '\0' && c != '\n')
X		;
X	plptr[-1] = 0;
X	return plotcommands + i;
X}
X
X/*
X * plot module
X */
X
X#define point(x,y)	pw_put(pw, plotx(x, y), ploty(x, y), !reverse)
X
X#define line(x0,y0,x1,y1)	pw_vector(pw,plotx(x0,y0),ploty(x0,y0),plotx(x1,y1),ploty(x1,y1),PIX_SRC,!reverse)
X
X#define convx(x,s)	(((x) - lox) * (s) / (hix - lox))
X#define convy(y,s)	(((y) - loy) * (s) / (hiy - loy))
X
Xinitplot()
X{
X	plptr = plotcommands = malloc(maxplotlength = 1024);
X	plotlength = 0;
X}
X
Xplotx(x, y)
X{
X	register a;
X
X	switch (turned) {
X	case 0: a = convx(x, hor_size); break;
X	case 1: a = hor_size - 1 - convy(y, hor_size); break;
X	case 2: a = hor_size - 1 - convx(x, hor_size); break;
X	case 3: a = convy(y, hor_size); break;
X	}
X	return xmirror ? hor_size - 1 - a : a;
X}
X
Xploty(x, y)
X{
X	register a;
X
X	switch (turned) {
X	case 0: a = ver_size - 1 - convy(y, ver_size); break;
X	case 1: a = ver_size - 1 - convx(x, ver_size); break;
X	case 2: a = convy(y, ver_size); break;
X	case 3: a = convx(x, ver_size); break;
X	}
X	a = ymirror ? ver_size - 1 - a : a;
X	return zooming ? a+1 : a;
X}
X
Xlabel(s)
Xchar *s;
X{
X	struct pr_size pr_size;
X
X	if (!make_label)
X		return 0;
X	pw_text(pw, plotx(curx, cury), ploty(curx, cury), reverse ? PIX_NOT(PIX_SRC)&PIX_DST : PIX_SRC|PIX_DST, font, s);
X	pr_size = pf_textwidth(strlen(s), font, s);
X	return pr_size.x * (hix - lox) / hor_size;
X}
X
Xisqrt(n)
X{
X	int a, b, c;
X
X	a = n;
X	b = n;
X	if (n > 1) {
X		while (a > 0) {
X			a = a >> 2;
X			b = b >> 1;
X		}
X		do {
X			a = b;
X			c = n / b;
X			b = (c + a) >> 1;
X		} while ((a - c) < -1 || (a - c) > 1);
X	}
X	return b;
X}
X
Xstatic setcir(x, y, a1, b1, c1, a2, b2, c2)
X{
X	if (a1 * y - b1 * x >= c1 && a2 * y - b2 * x <= c2)
X		point(x, y);
X}
X
Xarc(x, y, x1, y1, x2, y2)
X{
X	register a1 = x1 - x, b1 = y1 - y, a2 = x2 - x, b2 = y2 - y;
X	register c1 = a1 * y - b1 * x, c2 = a2 * y - b2 * x;
X	register r2 = a1 * a1 + b1 * b1;
X	register i, di, sqrt, dx, dy;
X
X	dx = (hix - lox) / hor_size;
X	dy = (hiy - loy) / ver_size;
X	di = dx < dy ? dx : dy;
X	if (di <= 0)
X		di = 1;
X	for (i = isqrt(r2 >> 1); i >= 0; i -= di) {
X		sqrt = isqrt(r2 - i * i);
X		setcir(x + i, y + sqrt, a1, b1, c1, a2, b2, c2);
X		setcir(x + i, y - sqrt, a1, b1, c1, a2, b2, c2);
X		setcir(x - i, y + sqrt, a1, b1, c1, a2, b2, c2);
X		setcir(x - i, y - sqrt, a1, b1, c1, a2, b2, c2);
X		setcir(x + sqrt, y + i, a1, b1, c1, a2, b2, c2);
X		setcir(x + sqrt, y - i, a1, b1, c1, a2, b2, c2);
X		setcir(x - sqrt, y + i, a1, b1, c1, a2, b2, c2);
X		setcir(x - sqrt, y - i, a1, b1, c1, a2, b2, c2);
X	}
X}
X
Xcircle(x, y, r)
X{
X	arc(x, y, x + r, y, x - r, y);
X	arc(x, y, x - r, y, x + r, y);
X}
X
XNotify_value input_reader(me, fd)
Xint *me;
Xint fd;
X{
X	int newx, newy, x, y, r;
X	register char *p;
X
X	do {
X		switch (getchr()) {
X		case 'm':				/* move */
X			curx = getint();
X			cury = getint();
X			if (curx < minx) minx = curx;
X			if (curx > maxx) maxx = curx;
X			if (cury < miny) miny = cury;
X			if (cury > maxy) maxy = cury;
X			break;
X		case 'n':				/* cont */
X			newx = getint();
X			newy = getint();
X			line(curx, cury, newx, newy);
X			curx = newx;
X			cury = newy;
X			if (curx < minx) minx = curx;
X			if (curx > maxx) maxx = curx;
X			if (cury < miny) miny = cury;
X			if (cury > maxy) maxy = cury;
X			break;
X		case 'p':				/* point */
X			curx = getint();
X			cury = getint();
X			point(curx, cury);
X			if (curx < minx) minx = curx;
X			if (curx > maxx) maxx = curx;
X			if (cury < miny) miny = cury;
X			if (cury > maxy) maxy = cury;
X			break;
X		case 'l':				/* line */
X			newx = getint();
X			newy = getint();
X			curx = getint();
X			cury = getint();
X			line(newx, newy, curx, cury);
X			if (newx < minx) minx = newx;
X			if (newx > maxx) maxx = newx;
X			if (newy < miny) miny = newy;
X			if (newy > maxy) maxy = newy;
X			if (curx < minx) minx = curx;
X			if (curx > maxx) maxx = curx;
X			if (cury < miny) miny = cury;
X			if (cury > maxy) maxy = cury;
X			break;
X		case 't':				/* label */
X			p = getstr();
X			curx += label(p);
X			if (curx < minx) minx = curx;
X			if (curx > maxx) maxx = curx;
X			break;
X		case 'a':				/* arc */
X			x = getint();
X			y = getint();
X			newx = getint();
X			newy = getint();
X			curx = getint();
X			cury = getint();
X			arc(x, y, newx, newy, curx, cury);
X			if (x < minx) minx = x;
X			if (x > maxx) maxx = x;
X			if (y < miny) miny = y;
X			if (y > maxy) maxy = y;
X			if (newx < minx) minx = newx;
X			if (newx > maxx) maxx = newx;
X			if (newy < miny) miny = newy;
X			if (newy > maxy) maxy = newy;
X			if (curx < minx) minx = curx;
X			if (curx > maxx) maxx = curx;
X			if (cury < miny) miny = cury;
X			if (cury > maxy) maxy = cury;
X			break;
X		case 'c':				/* circle */
X			curx = getint();
X			cury = getint();
X			r = getint();
X			circle(curx, cury, r);
X			if (curx - r < minx) minx = curx - r;
X			if (curx + r > maxx) maxx = curx + r;
X			if (cury - r < miny) miny = cury - r;
X			if (cury + r > maxy) maxy = cury + r;
X			break;
X		case 'e':				/* erase */
X			panel_set(next_page_item, PANEL_SHOW_ITEM, TRUE, 0);
X			/* fall through */
X		case EOF:
X			notify_set_input_func(me, NOTIFY_FUNC_NULL, fd);
X			if (zooming) {
X				lox = slox;
X				hix = shix;
X				loy = sloy;
X				hiy = shiy;
X				zooming = 0;
X			}
X			return NOTIFY_DONE;
X		case 'f':				/* linemod */
X			getstr();
X			break;
X		case 's':				/* space */
X			if (zooming) {
X				slox = getint();
X				sloy = getint();
X				shix = getint();
X				shiy = getint();
X			} else {
X				lox = getint();
X				loy = getint();
X				hix = getint();
X				hiy = getint();
X			}
X			break;
X		}
X	} while (plptr < plotcommands + plotlength || stdin->_cnt > 0);
X	return NOTIFY_DONE;
X}
X
X/*
X * button routines
X */
X
Xrestartplot()
X{
X	minx = BIG;
X	maxx = -BIG;
X	miny = BIG;
X	maxy = -BIG;
X	plptr = plotcommands;
X
X	/* clear the canvas */
X	pw_writebackground(pw, 0, 0, (int) window_get(canvas, CANVAS_WIDTH),
X				(int) window_get(canvas, CANVAS_HEIGHT),
X				reverse ? PIX_SET : PIX_CLR);
X}
X
Xresetplot()
X{
X	restartplot();
X	plotlength = 0;
X}
X
Xvoid redraw()
X{
X	if (zooming) {
X		lox = slox;
X		hix = shix;
X		loy = sloy;
X		hiy = shiy;
X		zooming = 0;
X	}
X	restartplot();
X	input_reader(me, fileno(stdin));
X}
X
Xvoid nextpage()
X{
X	resetplot();
X	panel_set(next_page_item, PANEL_SHOW_ITEM, FALSE, 0);
X	notify_set_input_func(me, input_reader, fileno(stdin));
X	if (stdin->_cnt > 0)
X		input_reader(me, fileno(stdin));
X}
X
Xvoid zoom()
X{
X	int a;
X
X	if (!zooming) {
X		slox = lox;
X		shix = hix;
X		sloy = loy;
X		shiy = hiy;
X		zooming = 1;
X	}
X	if (maxx == minx) {
X		maxx++;
X		minx--;
X	}
X	if (maxy == miny) {
X		maxy++;
X		miny--;
X	}
X	if ((a = (maxx-minx) * (shiy-sloy) / (shix-slox)) >= maxy-miny) {
X		loy = miny - (a - maxy + miny) / 2;
X		hiy = loy + a;
X		lox = minx;
X		hix = maxx;
X	} else {
X		a = (maxy - miny) * (shix - slox) / (shiy - sloy);
X		lox = minx - (a - maxx + minx) / 2;
X		hix = lox + a;
X		loy = miny;
X		hiy = maxy;
X	}
X	hix++;
X	hiy++;
X	restartplot();
X	input_reader(me, fileno(stdin));
X}
X
Xvoid quit()
X{
X	/* don't ask for confirmation */
X	if (font)
X		pf_close(font);
X	window_set(frame, FRAME_NO_CONFIRM, TRUE, 0);
X	window_destroy(frame);
X}
X
Xvoid turn()
X{
X	int tmp;
X
X	turned = (turned + 1) & 3;
X	tmp = xmirror;
X	xmirror = ymirror;
X	ymirror = tmp;
X}
X
Xvoid mirrorx()
X{
X	xmirror ^= 1;
X}
X
Xvoid mirrory()
X{
X	ymirror ^= 1;
X}
X
Xvoid toggle_proc()
X{
X	if ((int) panel_get(toggle_item, PANEL_TOGGLE_VALUE, SQUARE)) {
X		panel_set(ver_size_item,
X			PANEL_SHOW_ITEM,	FALSE,
X			0);
X		panel_set(hor_size_item,
X			PANEL_LABEL_STRING,	"Canvas size:     ",
X			0);
X	} else {
X		panel_set(ver_size_item,
X			PANEL_SHOW_ITEM,	TRUE,
X			0);
X		panel_set(hor_size_item,
X			PANEL_LABEL_STRING,	"Horizontal size: ",
X			0);
X	}
X}
X
Xvoid options()
X{
X	window_set(options_frame, WIN_SHOW, TRUE, 0);
X}
X
Xvoid options_done()
X{
X	register int r;
X	char *f;
X	Cursor cursor;
X
X	window_set(options_frame, WIN_SHOW, FALSE, 0);
X	r = (int) panel_get(hor_size_item, PANEL_VALUE);
X	if (r != hor_size) {
X		window_set(canvas, CANVAS_WIDTH, r, 0);
X		hor_size = r;
X	}
X	if (square)
X		r = hor_size;
X	else
X		r = (int) panel_get(ver_size_item, PANEL_VALUE);
X	if (r != ver_size) {
X		window_set(canvas, CANVAS_HEIGHT, r, 0);
X		ver_size = r;
X	}
X	f = (char *) panel_get_value(font_item);
X	if (f == 0 || *f == 0) {
X		if (font_name[0] != 0) {
X			font_name[0] = 0;
X			if (font)
X				pf_close(font);
X			font = pf_default();
X		}
X	} else {
X		if (font_name[0] == 0 || strcmp(f, font_name) != 0) {
X			strcpy(font_name, f);
X			f = font_name;
X			if (*f != '/') {
X				f = malloc(strlen(font_dir)+strlen(font_name)+1);
X				strcpy(f, font_dir);
X				strcat(f, font_name);
X			}
X			if (font)
X				pf_close(font);
X			font = pf_open(f);
X			if (f != font_name)
X				free(f);
X		}
X	}
X	if (font == 0) {
X		font_name[0] = 0;
X		font = pf_default();
X	}
X	make_label = (int) panel_get(toggle_item, PANEL_TOGGLE_VALUE, LABEL);
X	square = (int) panel_get(toggle_item, PANEL_TOGGLE_VALUE, SQUARE);
X	reverse = (int) panel_get(toggle_item, PANEL_TOGGLE_VALUE, REVERSE);
X	cursor = (Cursor) window_get(canvas, WIN_CURSOR);
X	cursor_set(cursor,
X			CURSOR_OP, reverse ? PIX_SRC^PIX_DST : PIX_SRC|PIX_DST,
X			0);
X	window_set(canvas, WIN_CURSOR, cursor, 0);
X	redraw();
X}
X
Xvoid dump()
X{
X	window_set(dump_frame, WIN_SHOW, TRUE, 0);
X}
X
Xvoid dump_done()
X{
X	char *file;
X	int width, height;
X	register int x, y;
X	register char *s;
X	register short *p;
X	FILE *f;
X
X	/* we use the fact that the canvas is retained */
X	file = (char *) panel_get_value(dump_file_item);
X	if (file != 0 && *file != 0 && (f = fopen(file, "w")) != 0) {
X		width = (int) window_get(canvas, CANVAS_WIDTH);
X		height = (int) window_get(canvas, CANVAS_HEIGHT);
X		switch ((int) panel_get_value(dump_format)) {
X		case FORMAT_RASTER:
X			pr_dump(pw->pw_prretained, f, (colormap_t *) 0,
X							RT_STANDARD, 0);
X			break;
X		case FORMAT_ICON:
X			p = mpr_d(pw->pw_prretained)->md_image;
X			fprintf(f, "\
X/* Format_version=1, Width=%d, Height=%d, Depth=1, Valid_bits_per_item=16\n\
X */\n", (width+15) & ~15, height);
X			for (y = 0; y < height; y++) {
X				s = "\t";
X				for (x = 0; x < width; x += 16) {
X					fprintf(f, "%s0x%04x,", s, *p & 0xFFFF);
X					p++;
X					s = "";
X				}
X				fprintf(f, "\n");
X			}
X			break;
X		}
X		fclose(f);
X	}
X	window_set(dump_frame, WIN_SHOW, FALSE, 0);
X}
X
Xvoid fit_screen()
X{
X	register int w, h;
X	
X	w = hor_size + (int) scrollbar_get((Scrollbar) window_get(canvas, WIN_VERTICAL_SCROLLBAR), SCROLL_THICKNESS);
X	h = ver_size + (int) scrollbar_get((Scrollbar) window_get(canvas, WIN_HORIZONTAL_SCROLLBAR), SCROLL_THICKNESS);
X	window_set(canvas, WIN_WIDTH, w, WIN_HEIGHT, h, 0);
X	window_set(canvas, CANVAS_WIDTH, hor_size, CANVAS_HEIGHT, ver_size, 0);
X	window_set(panel, WIN_WIDTH, w, 0);
X	window_fit(frame);
X}
X
X/*
X * initialization
X */
X
Xvoid dump_init()
X{
X	register Pixrect *pr;
X
X	dump_frame = window_create(frame, FRAME,
X			FRAME_DONE_PROC,	dump_done,
X			0);
X	dump_panel = window_create(dump_frame, PANEL, 0);
X	pr = panel_button_image(dump_panel, "Done", 0, (Pixfont *) 0);
X	(void) panel_create_item(dump_panel, PANEL_BUTTON,
X			PANEL_LABEL_IMAGE,	pr,
X			PANEL_NOTIFY_PROC,	dump_done,
X			0);
X	/* order of strings is important (see definitions of FORMAT_*) */
X	dump_format = panel_create_item(dump_panel, PANEL_CYCLE,
X			PANEL_LABEL_STRING,	"Dump format:",
X			PANEL_CHOICE_STRINGS,	"Rasterfile format",
X						"Icon format",
X						(char *) 0,
X			0);
X	dump_file_item = panel_create_item(dump_panel, PANEL_TEXT,
X			PANEL_LABEL_X,		ATTR_COL(0),
X			PANEL_LABEL_Y,		ATTR_ROW(1),
X			PANEL_VALUE_DISPLAY_LENGTH, 25,
X			PANEL_LABEL_STRING,	"Dump to file:",
X			0);
X	window_fit(dump_panel);
X	window_fit(dump_frame);
X}
X
Xvoid options_init()
X{
X	register Pixrect *pr;
X
X	options_frame = window_create(frame, FRAME,
X			FRAME_DONE_PROC,	options_done,
X			0);
X	options_panel = window_create(options_frame, PANEL, 0);
X
X	pr = panel_button_image(options_panel, "Done", 0, (Pixfont *) 0);
X	(void) panel_create_item(options_panel, PANEL_BUTTON,
X			PANEL_LABEL_IMAGE,	pr,
X			PANEL_NOTIFY_PROC,	options_done,
X			0);
X	pr = panel_button_image(options_panel, "Rotate", 0, (Pixfont*) 0);
X	(void) panel_create_item(options_panel, PANEL_BUTTON,
X			PANEL_NOTIFY_PROC,	turn,
X			PANEL_LABEL_IMAGE,	pr,
X			0);
X	pr = panel_button_image(options_panel, "X Mirror", 0, (Pixfont*) 0);
X	(void) panel_create_item(options_panel, PANEL_BUTTON,
X			PANEL_NOTIFY_PROC,	mirrorx,
X			PANEL_LABEL_IMAGE,	pr,
X			0);
X	pr = panel_button_image(options_panel, "Y Mirror", 0, (Pixfont*) 0);
X	(void) panel_create_item(options_panel, PANEL_BUTTON,
X			PANEL_NOTIFY_PROC,	mirrory,
X			PANEL_LABEL_IMAGE,	pr,
X			0);
X	toggle_item = panel_create_item(options_panel, PANEL_TOGGLE,
X			PANEL_LAYOUT,		PANEL_HORIZONTAL,
X			PANEL_CHOICE_STRINGS,	"Label",
X						"Square",
X						"Reverse",
X						(char *) 0,
X			PANEL_TOGGLE_VALUE,	LABEL, make_label,
X			PANEL_TOGGLE_VALUE,	SQUARE, square,
X			PANEL_TOGGLE_VALUE,	REVERSE, reverse,
X			PANEL_NOTIFY_PROC,	toggle_proc,
X			0);
X	font_item = panel_create_item(options_panel, PANEL_TEXT,
X			PANEL_VALUE_DISPLAY_LENGTH, 51,
X			PANEL_VALUE_STORED_LENGTH, MAX_NAME_LENGTH,
X			PANEL_LABEL_STRING,	"Font name:",
X			PANEL_VALUE,		font_name,
X			0);
X	hor_size_item = panel_create_item(options_panel, PANEL_SLIDER,
X			PANEL_LABEL_STRING,	"Horizontal size: ",
X			PANEL_VALUE,		hor_size,
X			PANEL_MIN_VALUE,	64,
X			PANEL_MAX_VALUE,	2048,
X			PANEL_SLIDER_WIDTH,	200,
X			0);
X	ver_size_item = panel_create_item(options_panel, PANEL_SLIDER,
X			PANEL_LABEL_STRING,	"Vertical size:   ",
X			PANEL_VALUE,		ver_size,
X			PANEL_MIN_VALUE,	64,
X			PANEL_MAX_VALUE,	2048,
X			PANEL_SLIDER_WIDTH,	200,
X			0);
X	window_fit(options_panel);
X	window_fit(options_frame);
X	if (square) {
X		panel_set(ver_size_item,
X			PANEL_SHOW_ITEM,	FALSE,
X			0);
X		panel_set(hor_size_item,
X			PANEL_LABEL_STRING,	"Canvas size:     ",
X			0);
X	}
X}
X
Xvoid panel_init()
X{
X	register Pixrect *pr;
X
X	panel = window_create(frame, PANEL, 0);
X	pr = panel_button_image(panel, "Next Page", 0, (Pixfont *) 0);
X	next_page_item = panel_create_item(panel, PANEL_BUTTON,
X			PANEL_NOTIFY_PROC,	nextpage,
X			PANEL_LABEL_IMAGE,	pr,
X			0);
X	pr = panel_button_image(panel, "Redraw", 0, (Pixfont *) 0);
X	(void) panel_create_item(panel, PANEL_BUTTON,
X			PANEL_NOTIFY_PROC,	redraw,
X			PANEL_LABEL_IMAGE,	pr,
X			0);
X	pr = panel_button_image(panel, "Zoom", 0, (Pixfont *) 0);
X	(void) panel_create_item(panel, PANEL_BUTTON,
X			PANEL_NOTIFY_PROC,	zoom,
X			PANEL_LABEL_IMAGE,	pr,
X			0);
X	pr = panel_button_image(panel, "Options", 0, (Pixfont *) 0);
X	(void) panel_create_item(panel, PANEL_BUTTON,
X			PANEL_NOTIFY_PROC,	options,
X			PANEL_LABEL_IMAGE,	pr,
X			0);
X	pr = panel_button_image(panel, "Dump", 0, (Pixfont *) 0);
X	(void) panel_create_item(panel, PANEL_BUTTON,
X			PANEL_NOTIFY_PROC,	dump,
X			PANEL_LABEL_IMAGE,	pr,
X			0);
X	pr = panel_button_image(panel, "Fit Screen", 0, (Pixfont *) 0);
X	(void) panel_create_item(panel, PANEL_BUTTON,
X			PANEL_NOTIFY_PROC,	fit_screen,
X			PANEL_LABEL_IMAGE,	pr,
X			0);
X	pr = panel_button_image(panel, "Quit", 0, (Pixfont *) 0);
X	(void) panel_create_item(panel, PANEL_BUTTON,
X			PANEL_NOTIFY_PROC,	quit,
X			PANEL_LABEL_IMAGE,	pr,
X			0);
X	window_fit_height(panel);
X}
X
Xcanvas_init()
X{
X	canvas = window_create(frame, CANVAS,
X			CANVAS_AUTO_SHRINK,	FALSE,
X			CANVAS_WIDTH,		hor_size,
X			CANVAS_HEIGHT,		ver_size,
X			CANVAS_RETAINED,	TRUE,
X			WIN_VERTICAL_SCROLLBAR,	scrollbar_create(0),
X			WIN_HORIZONTAL_SCROLLBAR, scrollbar_create(0),
X			0);
X	pw = canvas_pixwin(canvas);
X}
X
Xmain(argc, argv)
Xchar **argv;
X{
X	initplot();
X
X	hor_size = ver_size = INIT_CANVAS_SIZE;
X	frame = window_create(NULL, FRAME,
X			FRAME_LABEL,		"Sunplot",
X			FRAME_SUBWINDOWS_ADJUSTABLE, FALSE,
X			FRAME_ICON, icon_create(ICON_IMAGE, &sunplot_icon, 0),
X			FRAME_ARGC_PTR_ARGV,	&argc, argv,
X			0);
X	while (argc > 1 && argv[1][0] == '-') {
X		switch (argv[1][1]) {
X		case 'c':
X			if (argv[1][2])
X				hor_size = atoi(&argv[1][2]);
X			else if (argc > 2) {
X				hor_size = atoi(argv[2]);
X				argv[1] = argv[0];
X				argv++;
X				argc--;
X			}
X			if (hor_size < 64)
X				hor_size = 64;
X			ver_size = hor_size;
X			square = TRUE;
X			break;
X		case 'h':
X			if (argv[1][2])
X				hor_size = atoi(&argv[1][2]);
X			else if (argc > 2) {
X				hor_size = atoi(argv[2]);
X				argv[1] = argv[0];
X				argv++;
X				argc--;
X			}
X			if (hor_size < 64)
X				hor_size = 64;
X			square = FALSE;
X			break;
X		case 'v':
X			if (argv[1][2])
X				ver_size = atoi(&argv[1][2]);
X			else if (argc > 2) {
X				ver_size = atoi(argv[2]);
X				argv[1] = argv[0];
X				argv++;
X				argc--;
X			}
X			if (ver_size < 64)
X				ver_size = 64;
X			square = FALSE;
X			break;
X		case 'l':
X			make_label = !make_label;
X			break;
X		case 's':
X			square = !square;
X			break;
X		case 'r':
X			turn();
X			break;
X		case 'x':
X			mirrorx();
X			break;
X		case 'y':
X			mirrory();
X			break;
X		case 'f':
X			if (argv[1][2])
X				strcpy(font_name, &argv[1][2]);
X			else if (argc > 2) {
X				strcpy(font_name, argv[2]);
X				argv[1] = argv[0];
X				argv++;
X				argc--;
X			}
X			break;
X		}
X		argc--;
X		argv[1] = argv[0];
X		argv++;
X	}
X	dump_init();
X	options_init();
X	panel_init();
X	canvas_init();
X	if (font_name[0]) {
X		register char *f = font_name;
X
X		if (*f != '/') {
X			f = malloc(strlen(font_dir)+strlen(font_name)+1);
X			strcpy(f, font_dir);
X			strcat(f, font_name);
X		}
X		font = pf_open(f);
X		if (f != font_name)
X			free(f);
X	}
X	if (font == 0) {
X		font = pf_default();
X		font_name[0] = 0;
X	}
X
X	fit_screen();
X
X	notify_set_input_func(me, input_reader, fileno(stdin));
X
X	window_main_loop(frame);
X
X	exit(0);
X}
+ END-OF-FILE sunplot.c
chmod 'u=rw,g=r,o=r' 'sunplot.c'
set `wc -c 'sunplot.c'`
count=$1
case $count in
19634)	:;;
*)	echo 'Bad character count in ''sunplot.c' >&2
		echo 'Count should be 19634' >&2
esac
echo Extracting 'sunplot.icon'
sed 's/^X//' > 'sunplot.icon' << '+ END-OF-FILE ''sunplot.icon'
X/* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
X */
X	0x0000,0x0000,0x0000,0x0400,0x0000,0x0000,0x0000,0x0400,
X	0x0000,0x0000,0x0000,0x0800,0x0000,0x0000,0x0000,0x0800,
X	0x0000,0x0000,0x0000,0x1000,0x0000,0x0000,0x7FF0,0x1000,
X	0x0000,0x0007,0x800F,0x1000,0x0000,0x0038,0x0000,0xE000,
X	0x0000,0x00C0,0x0000,0x3800,0x2000,0x0300,0x0000,0x4600,
X	0x1800,0x0400,0x0000,0x4100,0x07FF,0x0800,0x0000,0x8080,
X	0x03FF,0xFFFC,0x0000,0x8060,0x01C1,0xFFFF,0xFFF0,0x8010,
X	0x00E0,0x8037,0xFFFF,0xF008,0x0071,0x0030,0x001F,0xFE04,
X	0x003A,0x0030,0x0002,0x0002,0x001E,0x0060,0x0002,0x0002,
X	0x000F,0x0060,0x0002,0x0001,0x000F,0x8060,0x0004,0x0000,
X	0x0011,0xC0C0,0x0004,0x0000,0x0010,0xE0C0,0x0008,0x0000,
X	0x0020,0x7180,0x0008,0x0000,0x0020,0x3B80,0x0008,0x0000,
X	0x0040,0x1F00,0x0010,0x0000,0x0040,0x0E00,0x0010,0x0000,
X	0x0040,0x1F80,0x0020,0x0000,0x0080,0x3BC0,0x0020,0x0000,
X	0x0080,0x70E0,0x0040,0x0000,0x0081,0xE070,0x0040,0x0000,
X	0x0081,0xC038,0x0040,0x0000,0x0100,0x001C,0x0080,0x0000,
X	0x0100,0x000E,0x0080,0x0000,0x0100,0x0007,0x0100,0x0000,
X	0x0100,0x0003,0x8100,0x0000,0x0100,0x0001,0xE100,0x0000,
X	0x0100,0x0000,0xF200,0x0000,0x0100,0x0000,0x3A00,0x0000,
X	0x0100,0x0000,0x1C00,0x0000,0x0100,0x0000,0x0E00,0x0000,
X	0x0100,0x0000,0x0F00,0x0000,0x0100,0x0000,0x0B80,0x0000,
X	0x0080,0x0000,0x0980,0x0000,0x0080,0x0000,0x1040,0x0000,
X	0x0080,0x0000,0x1020,0x0000,0x0080,0x0000,0x2000,0x0000,
X	0x0040,0x0000,0x2000,0x0000,0x0040,0x0000,0x2000,0x0000,
X	0x0FFF,0xFFFF,0xFFFF,0xFFE0,0x0924,0x9249,0x2492,0x4920,
X	0x0924,0x9249,0x2492,0x4920,0x0924,0x9249,0x2492,0x4920,
X	0x0800,0x0000,0x0000,0x0020,0x0800,0x0000,0x0000,0x0020,
X	0x0800,0x0000,0x0000,0x0021,0x0800,0x0000,0x0000,0x0022,
X	0x0800,0x0000,0x0000,0x0022,0x0800,0x0000,0x0000,0x0024,
X	0x0FFF,0xFFFF,0xFFFF,0xFFE8,0x0000,0x4004,0x0000,0x0010,
X	0x0000,0x3008,0x0000,0x0060,0x0000,0x0808,0x0000,0x0080,
X	0x0000,0x0410,0x0000,0x0100,0x0000,0x0310,0x0000,0x0600
+ END-OF-FILE sunplot.icon
chmod 'u=rw,g=r,o=r' 'sunplot.icon'
set `wc -c 'sunplot.icon'`
count=$1
case $count in
1933)	:;;
*)	echo 'Bad character count in ''sunplot.icon' >&2
		echo 'Count should be 1933' >&2
esac
exit 0
-- 
Sjoerd Mullender
sjoerd@cs.vu.nl