[comp.sources.unix] v14i027: Device-independant graphics system, with drivers

rsalz@bbn.com (Rich Salz) (04/07/88)

Submitted-by: Joe Dellinger <joe@hanauma.STANFORD.EDU>
Posting-number: Volume 14, Issue 27
Archive-name: vplot/part22

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 22 (of 24)."
# Wrapped by rsalz@fig.bbn.com on Fri Mar 25 11:47:34 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Vplot_Kernel/Documentation/hacker.doc.2' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Vplot_Kernel/Documentation/hacker.doc.2'\"
else
echo shar: Extracting \"'Vplot_Kernel/Documentation/hacker.doc.2'\" \(29413 characters\)
sed "s/^X//" >'Vplot_Kernel/Documentation/hacker.doc.2' <<'END_OF_FILE'
color 0. The box should be of the same color and fatness as the text.
Which value of txovly corresponds to what action is defined in vplot.h.
It is up to the device to decide how big a box around the text is
appropriate for a given font. (It is probably a good idea to follow
gentext's example in this.)
X
Pathx, pathy, upx, and upy define the size, shape, and orientation of
the text. Pathx and upx are in HORIZONTAL device units, and pathy and upy
are in VERTICAL device units. (This distinction is important if your device
does not have aspect_ratio=1..) Note that all 4 values are FLOATS, not ints.
X
The vector (pathx,pathy) defines the text path, and the vector (upx,upy)
defines the character up vector. (This is just like in the GKS text
notation conventions.) To understand the meaning of these two vectors,
consider normal horizontal text with a height of 100 pixels. (We'll
assume our device has square pixels for the moment.)
For this text, (pathx,pathy) = (100.,0.) and (upx,upy) = (0.,100.).
Now the position of any point on this text can be expressed as
a linear combination of the path vector and the up vector.
This is how dev.text should represent all text internally.
In this way, if we linearly transform just the path vector and
the up vector, then we do the transform to every point of the text too.
If we rotate both the path and up vectors, the text rotates.
if we multiply both the path and up vectors by two, the text gets twice
as big. If the path and up vectors are not orthogonal, the text gets
sheared.
X
To test a device-dependent text routine, try switching between a
device-dependent font and one of the gentext fonts (txfont<NUMGENFONT).
If your device-dependent test routine is correctly working, the text
should always appear the same as far as height, direction, and position
in both cases.
X
Generic routines: gentext.c
Gentext.c produces text by mixing vectors and filled areas. It calls
dev.vector, dev.area, and dev.attributes. It also recognizes many
special escape sequences in the text. Gentext is documented in vplottext(9).
X
X===========================
X
X#include "vertex.h"
X#include "pat.h"
dev.area(npts, verlist)
int npts;
struct vertex *verlist;
X{
X/* These can be defined by including extern.h */
extern int xwmin, xwmax, ywmin, ywmax;
extern int ipat;
extern struct pat pat[];
X
Dev.area fills a polygon with a user-defined pattern. Npts is the number
of vertices of the polygon. The coordinates of the vertices themselves
are stored in the doubly linked list verlist.
X
Here is vertex.h:
X
struct vertex
X{
X	int x;				/* X coordinate of vertex */
X	int y;				/* Y coordinate of vertex */
X	struct vertex *next;		/* pointer to next vertex */
X	struct vertex *last;		/* pointer to last vertex */
X	struct vertex *soft;		/* pointer to some other vertex */
X};
X
The coordinates are in device units. It is up to the device to clip
the polygon! The lower-leftmost displayable point is (xwmin,ywmin) and
the upper-rightmost displayable point is (xwmax,ywmax).
X
The pattern to fill with is given in the external pat[ipat], which is a
structure of type pat.
Here is pat.h:
X
struct pat
X{
X	int    ydim;					/* Slow dimension */
X	int    xdim;					/* Fast dimension */
X	int    ydim_orig;
X	int    xdim_orig;
X	int   patbits[/*xdim*ydim*/];	/* Array of color numbers */
X};
X
Pat.patbits is an array of pat.xdim by pat.ydim color values, with
one element in the array for each device pixel. The pattern is repeated
to fill the polygon. The position of the origin of the pattern does not
matter, but should not depend on the particular polygon. (In other words,
if two polygons tiled with the same pattern overlap, the pattern should
be continuous across the two.)
X
The horizontal dimension of the pattern is length pat.xdim. This is
the fast axis. The vertical dimension of the pattern is length pat.ydim.
This is the slow axis. The pattern is scanned on the screen TV-style.
X(In other words, pat.patbits[0] is at the upper-left hand corner,
pat.patbits[pat.xdim-1] is the upper-right hand corner, and
pat.patbits[pat.ydim*pat.xdim-1] is the lower right hand corner.)
X
If either pat.xdim or pat.ydim is 0 for a given polygon, dev.area is
never even called and so no filling is done. If your device cannot fill
with an arbitrary pattern, it is OK to fill solidly with the current
color instead.
X
Dovplot will use a 1 by 1 pattern for polygons generated by the
VP_OLDAREA command if the device uses color, regardless of the requested
pattern (this is part of the definition of the VP_OLDAREA command).
XXdim_orig and ydim_orig contain the values that xdim and ydim would have
had if the device had been black and white. This is provided so that
no information needed to reconstruct the original vplot command is lost.
X
Dovplot will call dev.attributes(NEW_PAT,ipat) whenever the pattern
defined by pat[ipat] is loaded or updated.
X
Generic routines: vecarea.c, genarea.c, genpatarea.c
Vecarea fills the polygon with the current color by drawing vertical
and horizontal vectors. It shows the size of the pattern by the line spacing.
Vecarea calls dev.vector and dev.attributes.
X
Genarea clips the given polygon (if smart_clip=NO), possibly generating
more than one polygon out of the pieces. It then calls dev.startpoly,
dev.midpoly, and dev.endpoly to do the actual filling of the polygons.
X
Genpatarea fills the polygon with the correct pattern one raster line
at a time by calling dev.raster. It uses the ``dumb'' format for
dev.raster, so you cannot use genpatarea if smart_raster=YES.
X
X===========================
X
Dev.raster has 2 formats, depending on the value of smart_raster.
X
If smart_raster=NO, then the raster will be stretched to device
coordinates, clipped (regardless of the value of smart_clip),
color mapped, dithered (if appropriate), and broken up into individual
scan lines. Dev.raster will be called once for each scan line of the
raster image.
X
If smart_raster=YES, then the raster will be read in and color mapped,
but nothing else. It is up to the device to dither it (if appropriate),
stretch it, and clip it. The entire block of raster will be passed with
one call to dev.raster.
X
X/* Dumb format, smart_raster=NO */
dev.raster(count, out_of, xpos, ypos, rlength, orient, raster, dummy1, dummy2)
int count, out_of, xpos, ypos, rlength, orient, dummy1, dummy2;
unsigned char raster[/*rlength*/];
X
Draw a line of raster, starting at the point (xpos,ypos) and extending
for a total of length pixels in a direction determined by orient.
Orient is measured in units of 90 degrees clockwise from the device's
XX (horizontal) axis. Thus for orient=0 you draw the line right,
for orient=1 you draw down, for orient=2 left, and for orient=3 up.
X
The line of raster itself is in the array raster, which is of
dimension rlength. Each element of the array is a color number which
determines the color of one device pixel.
X
Some devices may be able to handle more than one line of raster at
a time. The variables count and out_of are provided so that the device
can know how many dev.raster calls will be made in a row. Count is
zero for the first call, and increases by 1 each time until it reaches
out_of-1 on the last call. (Thus out_of is the total number of raster
lines.)
X
Scanning is done TV-style. (Thus, for orient=0, ypos decrements by 1
for each call; for orient=1, xpos decrements by 1 for each call; for
orient=2, ypos increments by 1 for each call; for orient=3, xpos
increments by 1 for each call.) Genraster1 gives you a good example
of how to write a routine that builds up blocks of raster over several
calls.
X
Dummy1 and dummy2 are not used; they are provided only so that both forms
of the command have the same string of arguments.
X
Generic routines, dumb format: genraster.c, genraster1.c
Genraster does vector draws along scan lines to produce raster output.
It does one raster line at a time. Some fast but stupid devices can
actually do raster reasonably fast this way. Genraster calls
dev.attributes (to set the colors) and dev.vector.
X
Genraster1 attempts to be a little smarter than genraster. It saves up
many lines worth of raster at a time, and sorts the vectors by color
and length. It does all the vectors of one color at a time, so as to
save on calls to dev.attribute to change the color. It also finds
the parts of the image that can be more efficiently drawn via dev.point,
and makes a second pass for those. (If the device has a point mode this
is considerably more efficient.) Genraster1 calls dev.attributes,
dev.vector, and dev.point.
X
X/* Smart format, smart_raster=YES */
dev.raster (xpix, ypix, xmin, ymin, xmax, ymax,
X	raster_block, orient, dither_it)
int xpix, ypix, xmin, ymin, xmax, ymax, orient, dither_it;
unsigned char raster_block[/*xpix*ypix*/];
X{
X/* Including "extern.h" defines these. */
extern int xwmin, xwmax, ywmin, ywmax;
X
Draw the block of raster in the array raster_block.
If dither_it=NO, raster_block is an array of color numbers.
If dither_it=YES, raster_block is an array of grey levels
X(0 is black, 255 is white).
X
Raster_block has dimensions xpix times ypix, with xpix the fast
axis. If orient=0, the raster is painted on the screen TV-style.
The first array value is the upper-leftmost point. Each line of
raster (xpix long) fills from left to right. Each new line of
raster (ypix lines in all) is below the previous one.
X
If orient=1, we rotate the raster 90 degrees clockwise. Thus the
first value is the upper rightmost point, and the raster fills in
top to bottom and then right to left. For orient=2 we rotate another
X90 degrees and fill in right to left and then bottom to top. For
orient=3 we fill the raster in bottom to top and then left to right.
X
The lower-leftmost pixel in the raster image should appear on the screen
at device coordinate (xmin, ymin) (assuming it isn't clipped, of course).
The raster image should be (xmax-xmin) horizontal device units wide
and (ymax-ymin) vertical device units tall. Thus, the pixel (xmax,ymax)
is not the upper-rightmost pixel in the raster image, but is the first
pixel above and to the right of the one that is. (I know this sounds
strange. But when you actually code this up you'll see that it makes
sense to do it this way, and that this is probably what you actually
would have done even if I had told you to make sure that the point
X(xmax,ymax) was in the image.)
X
Finally, the resulting image must be clipped so that (xwmin,ywmin) is
the lower-leftmost pixel that can appear, and (xwmax,ywmax) is the
upper-rightmost pixel that can appear. (Note that this time the corner
IS in the image. Just trying to be confusing.)
X
Generic routines: NONE
X
X===========================
X
dev.point(x1, y1)
int x1, y1;
X
Change the pixel at device coordinate (x1,y1) to the current color.
X
Generic routines: genpoint.c
Genpoint calls dev.vector with zero length. Somethings wrong with
the dev.vector for your device if it doesn't do anything in this case.
X
X===========================
X
dev.attributes(command, value, v1, v2, v3)
int command, value, v1, v2, v3;
X
Set various attributes (color table, current color, clipping window, etc)
using device-specific routines. Commands are defined and documented
in include file attrcom.h. Value and v[1-3] are used to pass
parameters as needed. Sometimes some of the 4 will be dummy arguments.
X
Comments about color:
X	The device tells dovplot how many colors it has by setting num_col
and mono. Num_col is the number of settable colors. The color for
color table numbers num_col and up will never attempt to be defined
by dovplot. If num_col is zero, the device has no settable colors,
and dev.attributes(SET_COLOR_TABLE,...) will never be called at all.
X
X	Devices with no settable colors can still have color. If mono=NO,
dovplot assumes that colors 0 through 7 correspond to the standard
Vplot colors (as listed in vplot.h). Dovplot will not attempt to set
the current color outside of the range 0 through 7 if num_col=0.
X(There is no provision for devices with more than 8 colors but no
settable colors.)
X
X	Rather than forcing people to change the colors on their terminal
to have vplot's colors come out right, you should map the color numbers
dovplot asks for onto the correct device color numbers so that the
factory default setting gives the correct colors. (Don't forget to
similarly map the color table numbers too.)
X	
X	Calls to dev.attributes(SET_COLOR,...) by dovplot will only set
colors in the range 0 through MAX(7,num_col-1).
X
X	If mono=YES, dovplot will force num_col=0 and will only ever
try to set the current color to be either 0 (meaning background)
or 7 (meaning NOT background).
X
X	Calls to device routines should NEVER upset the current color. If
for some reason they should change it, they should always put it back
again when they are done. (Dovplot keeps track of the current color,
and only calls dev.attributes(SET_COLOR,...) when necessary.) Calls to
generic routines are guaranteed to never (permanently) change the
current color.
X
X	Color tables should usually be set to factory default settings at
the beginning of every plot, if it is possible to do this in such a
way that the former settings can be restored again afterwards.
X
X	Every device should AT LEAST keep track of whether or not the current
drawing color is color 0 or not. Color 0 always defines the background
color. If the device cannot draw (or rather undraw) in the background
color, then it SHOULDN'T DRAW AT ALL when the current color is 0.
X
Generic routines: NONE
X
X-------------------------------------------------------------
X
Input routines
X
X==============================
X
int dev.getpoint(termout, x, y)
FILE *termout;
int *x, *y;
X{
int status;
X
return status;
X}
X
Turn on the cursor and let the user pick a point. Return the device
coordinate of the picked point in (*x,*y), and return 0. If the
user indicated that he doesn't want to pick any more points, return 1.
X(The value in (*x,*y) is then considered to be junk by dovplot.)
Returned values should be in the normal range of device coordinates.
If (*x,*y) is returned unchanged, this will also indicate that no point
was picked and no more points should be picked.
X
Termout is a stream pointer reading from ``/dev/tty''. You can use it if
it is convenient and correct to do so, or ignore it.
X
Generic routines: nulldev
Linking in nulldev for this routine will simulate a user that always
declines to enter any points at all, since (*x,*y) is returned unchanged.
X
X==============================
X
dev.interact(command, termout, string)
int command;
FILE *termout;
char string[];
X
This routine handles string input from the user and pausing.
The various possible commands are described in
X".../vplot/filters/include/intcom.h".
X
Generic routines: nulldev, geninteract
Linking in nulldev will rudely zoom past all prompts to the user without
waiting. This is a reasonable thing to do for hardcopy devices.
X
Geninteract will read the required input from termout, which is connected
to read from "/dev/tty".
X
X--------------------------------------------------------------------------
X
Low level output routines --- only called by certain generic routines
X
X=================================
X
int lost = YES;
dev.plot(x, y, draw)
int x, y, draw;
X
Move or draw to device coordinate (x,y).
Draw=0 for move, 1 for draw.
X
This routine MUST declare the global flag ``lost''. It is the responsibility
of all the device routines to set this to YES whenever anything happens
that may cause genvector's idea of the ``current device pen position''
to be wrong.  (For example, printing an error message, doing hardware text,
filling a polygon, etc.) Generic routines do not present a difficulty, since
they can't output anything directly to the device.
X
When lost is set to YES, it is guaranteed that the next call to dev.plot
will by a move, and not a draw.
X
When genvector's idea of the current position is correct again (for example
when dev.plot has been called) lost should be set to NO. This is important;
genvector only looks at the value of lost, it doesn't set it. Leaving
lost YES all the time will greatly slow down plotting by forcing one move
for each draw!
X
Generic routines: nulldev
Link in nulldev here as a placeholder if you didn't use genvector as
your vector routine.
X
X=================================
X
dev.startpoly(npts)
int npts;
X
dev.midpoly(x,y)
int x, y;
X
dev.endpoly(last)
int last;
X
Polygon-drawing routines called only by genarea.
X
Dev.startpoly is called once at the beginning of every polygon.
Npts gives the number of points in the polygon. After dev.startpoly
has been called, then dev.midpoly is called once for each point in
the polygon. (x,y) gives the device coordinate of the vertex.
X
Dev.endpoly is called once at the end of each polygon. Genarea may fragment
one polygon into several. If this polygon just defined is the last polygon
in a set of polygons that were fragmented from one, then last will be 1.
If there are more fragments in this set to go, last will be 0. It is
guaranteed that no other routines but these three will be called after
the first dev.startpoly call and before dev.endpoly(last=YES) is called.
X
The genarea algorithm will fail for certain very complicated crossed
polygons, unless the multiple polygons fragmented from the one original
one are shaded as a unit. Some devices such as the Tek4105 allow this
to be done. That is why the ``last'' flag is provided. There is no
great harm in shading each polygon as it comes. Occasionally interior
voids will be filled twice instead of not filled at all, that's all.
X
If the device can fill with an arbitrary pattern, it should do so.
The pattern is available to these routines in the same way as described
under dev.area. If the device cannot fill with a user-defined pattern,
filling solidly with the current color is the next best thing.
X
Generic routines: nulldev.c
If you did not use genarea as your dev.area routine, then none of
these routines are ever called so you just need to put in nulldev
as a placeholder.
X
X-------------------------------------------------------------------------
HANDLING ERRORS:
Device routines SHOULD NOT simply exit when they get a fatal error!
All errors should be handled via the provided utility routine "ERR"!
X
X#include "err.h"
ERR (type, filter, fmt, a1, a2, a3)
int type;
char *filter;
char *fmt;
double a1, a2, a3;
X
X"Type" is one of the possibilities from "err.h". Currently there are three
possibilities: COMMENT, WARN, FATAL. Case COMMENT is just for making
remarks, not really error messages per se. Case WARN should be used when
something is wrong, but the filter can take reasonable corrective action.
Case FATAL is for errors that should cause abnormal termination of the
program. Calls to ERR with type FATAL will not return.
X
X"Filter" should be the name of the filter generating the error or comment
as you want it to appear in the message. Normally this should just be
the variable "name" defined in <dev>conf.c.
X
From here on ERR has the same syntax as "printf", except that ERR will
automatically throw a carriage-return line-feed on for you (so you don't
want to end with "\n").
X
After ERR has been called with type FATAL, dovplot and frontend will do
necessary cleaning up, in the process calling dev.close. Device-dependent
cleaning up should be done by that routine at that time.
X
The define ERR is used so that conflicts with other subroutines named
X"error", "err", etc, can be avoided. Currently "ERR" is defined to be
X"filtererror", a name we haven't had any trouble with.
X
X-------------------------------------------------------------------------
BEING TRICKY ABOUT THE ORDER THINGS ARE PLOTTED
X
The external variable
extern int (*genreader) ();
can be changed in dev.open to point to your own routine for processing
input files. You should only need to change this variable if for some
reason you want to be able to change the order or way in which input files
are handled, or if you want to know the actual file names of the input plot
files. (You might find this handy if you are creating an interactive vplot
editor, for example.)
X
The default input file handling routine, which is what you get if you
ignore this section of the documentation, is the following. Frontend
already does the job of finding all the input files, verifying that
they exist, and opening them for reading.
X
gen_do_dovplot (nn, inpltin, innames)
int     nn;
FILE ** inpltin;
char    innames[][MAXFLEN+1];
X{
X    int     ii;
X
X    for (ii = 0; ii < nn; ii++)
X    {
X	pltin = inpltin[ii];
X	strcpy (pltname, innames[ii]);
X	dovplot ();
X	fclose (pltin);
X    }
X}
X
X"Nn" is the number of input files. "Inpltin" is an array of nn stream
pointers each of which point to an open (but unread-upon) input stream.
X"Innames" is the corresponding array of strings giving the associated
name of the input file for each of the streams in inpltin.
X
The external integer "buffer_input" can be set to NO in dev.open to
assure that all the input streams are unbuffered. The external integer
X"allow_pipe" can be set to NO in dev.open to assure that all the input
streams are seekable on.
X
It is possible to change most variables set by command line arguments
between calls to dovplot without ill effect. There are comments in
init_vplot at the end of the section of code where command line arguments
are processed listing which variables have been explicitly set up to be
changeable in this way.
X
Variables controlling the mapping between the device's and vplot's
coordinate system can also be changed, but the subroutine
X"reset_parameters()" in frontend must be called afterwards to
reinitialize all the related variables that may need it.
X
X./filters/vplib/vpdovplot.c is an example of a routine that makes
X2 passes through a vplot file, doing things differently the second
time around.
X
X-------------------------------------------------------------------------
THINGS THAT GET RESET BETWEEN FRAMES (AND THINGS THAT DON'T)
X
Vplot has many "global" parameters. Some of these get reset between
frames (or between input files); a few don't.
X
The following parameters get reset (by reset()) at the start of
every new frame:
clipping windows, drawing fatness, current drawing color, text alignment
mode, text font, text precision, text overlay mode, raster overlay mode,
dash line pattern.
X
The plot style also gets reset at the start of every new frame, but
it is handled separately.
X
The following DO NOT GET RESET AT ALL:
color tables, current pen position
X
The global vplot origin command is another special case. Generally,
this command is only used when you are creating a figure "by hand"
using plas. It is reset when reset_parameters() is called, but is
global otherwise. It has no libvplot command on purpose.
X
X-------------------------------------------------------------------------
GROUPS
X
The begin-end group commands are provided so that a "MacDraw"-like
vplot editor may be created. The device knows when groups are
opened and closed, and their positions within the current plot file,
via the dev.attributes(BEGIN_GROUP,...) and dev.attributes(END_GROUP,...)
calls. You can use fseek to reposition the plot stream to the beginning
of a desired group, and then call dovplot to plot the group again.
When the group open (number one, not zero) command is processed, the device
gets a chance to reset global attributes from their "initialized" values.
X(For example, to change the color.) When the group close (number one)
command is processed, the device gets a chance to to reposition pltin
to the end of the file and so cause dovplot to think it's done and return.
X
It is possible for the user to violate the grouping laws, ie:
begin-group and end-group commands must be paired within a file,
erases may not be contained within a group.
Dovplot will warn the user if this happens. How the device handles
such an error, however, is up to it. Caveat user.
X
A group number 0 is generated by dovplot itself for each plot frame,
and consists of everything in the plot frame excepting erases. Erases
lie between groups. Initial erase and style commands are not contained
in the first group numbered 0. Groups generated by the begin-end group
commands in the vplot file are numbered from 1 on up.
X
The external integer "group_number" gives the number of currently
open groups.
X
X-------------------------------------------------------------------------
SEPLIB TRICKS
X
If you don't use the seplib versions of the filters, you can ignore
this section.
X
Pen filters have to do some tricky things with SEPlib since the
standard defaults are inappropriate. Normally seplib wants to send
the header to standard out. Since the output of Pen filters are usually
not redirected, this would dump the header on your screen and possibly
interfere with your plot. By the same token, the data output usually
SHOULD go to your screen, instead of being saved in a file or sent
down a pipe. The normal SEPlib method of self-documenting also
has to be subverted in order to be consistent between the SEP and non-SEP
versions of the programs.
X
To accomplish this, several things are done:
X
A library "tseplib" is provided that contains routines for
which the standard seplib versions had to be modified. This
should be linked AHEAD of seplib so that the modified versions
get taken. The routines are documented as to how they differ and why.
X
X"OUT" and "HEAD" are defined to be the external variables "sepoutwhere"
and "sepheadwhere", respectively. These are normally "/dev/tty" and
X"/dev/null". (These values are grabbed from the routine "sepwhere"
in tseplib.) If these values are inappropriate for your filter (unlikely
to be the case for most filters; see Vppen for an example of one) you can
create your own version of this routine and make sure it gets linked in
ahead of tseplib.
X
If head=/dev/null and this was the default in sepheadwhere and
standard out is redirected, then it is assumed the user really wants
some sort of header despite the fact that the Pen filter killed the
real one and so a "fake" one will be created for them by frontend.
Frontend will only actually write something into it if "out"
is not standard out (to avoid mixing header and data). The
device-dependent code may do so if it wishes, though (see Raspen for
an example). The device should only use "Puthead" to write to the header,
to make sure everything is done properly. The "fake" header has the
advantage that information can be added to it at any time.
Normal SEPlib headers must be closed before any data can be written.
Thus only fake headers can have "n3=number_of_frames" added onto
the header. (This is why Raspen uses fake headers.)
X
X-------------------------------------------------------------------------
FRONTEND, and DOING IT YOURSELF
X
The system-user interface is split among three routines, which together
are called the "frontend".
X
Main_vplot is responsible for finding the input files and opening them,
deciding where the output should go for devices that aren't strong-willed
enough to insist on figuring it out for themselves, setting up signal
catching, interfacing with SEPlib, and doing self-documentation.
It also calls the other 2 routines, init_vplot and proc_vplot.
X
Init_vplot initializes all variables and calls dev.open to open the
device.
X
Proc_vplot processes the input files.
X
It is possible to skip main_vplot and call init_vplot and proc_vplot
yourself directly. However, init_vplot and proc_vplot expect certain
things to be set before they are called.
X
Init_vplot expects:
X
XXargc and xargv are just copies of main's argc and argv, but declared
globally so that other routines (namely getpar) have access to them.
XXargc and xargv should be declared in the calling program.
X
Callname is a string which gives the "pen filter name" of the set of
device-dependent routines you want. It should have the path stripped.
The device-dependent code may want to know callname in order to pick
between similar devices. Callname should be declared external.
X
Pltout is just a copy of stdout. It is an external FILE *.
X
Proc_vplot expects:
X
Infileno gives the number of input files. It is an external integer.
X
Pltinname[infileno] gives the names of the input files. It is
an external array of pointers to chars.
X
Pltinarray[infileno] gives the already-open stream pointers for the
afore-mentioned files. It is an external array of FILE *'s.
X
That's it.
It is also possible to bypass even calling proc_vplot. See sample.c
in .../vplot/filters for an example of how to do this.
X
X-------------------------------------------------------------------------
AUTHORS
The present generation of pen filters were created by Joe Dellinger.
The original pen programs were written by Jeff Thorson and Rob Clayton.
Glenn Kroeger and Michel Debiche cleaned up the organization of the code.
Wes Monroe, Chuck Karish, Rick Ottolini, Doug Wilson, and Jean-Luc Guiziou
have added support for new devices. Steve Cole added dithering. Stew Levin
has found and fixed obscure bugs.
X
COPYRIGHT
Vplot is copyrighted. Please read the copyright in the accompanying
X"Vplot" manual page. The copyright is not very restrictive. If you
want to include vplot (or derivatives thereof) as part of some other
X"public domain" or "nearly public domain" package, we can probably
work something out. The desired effect of the copyright is to permit
widespread distribution without somebody trying to grab control of
it for themselves or trying to sell it.
X
SEE ALSO
vplot(L) pen(L) plas(L) pldb(L) seplib(L) getpar(L)
END_OF_FILE
if test 29413 -ne `wc -c <'Vplot_Kernel/Documentation/hacker.doc.2'`; then
    echo shar: \"'Vplot_Kernel/Documentation/hacker.doc.2'\" unpacked with wrong size!
fi
# end of 'Vplot_Kernel/Documentation/hacker.doc.2'
fi
echo shar: End of archive 22 \(of 24\).
cp /dev/null ark22isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 24 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.