home *** CD-ROM | disk | FTP | other *** search
- Subject: v14i027: Device-independant graphics system, with drivers
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- 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
-