rsalz@bbn.com (Rich Salz) (04/06/88)
Submitted-by: Joe Dellinger <joe@hanauma.STANFORD.EDU> Posting-number: Volume 14, Issue 24 Archive-name: vplot/part19 #! /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 19 (of 24)." # Wrapped by rsalz@fig.bbn.com on Fri Mar 25 11:47:31 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'Vplot_Kernel/Documentation/hacker.doc.1' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Vplot_Kernel/Documentation/hacker.doc.1'\" else echo shar: Extracting \"'Vplot_Kernel/Documentation/hacker.doc.1'\" \(25049 characters\) sed "s/^X//" >'Vplot_Kernel/Documentation/hacker.doc.1' <<'END_OF_FILE' Hacker's guide to the innards of the Pen programs, X or What you need to know to support a new device well X X Joe Dellinger and Charles R. Karish X Stanford University School of Earth Sciences X INTRODUCTION The pen software package, developed by students in the Geophysics department at Stanford University over many years, allows graphical data produced by computer programs to be displayed on a wide variety of output devices, including terminals and hard copy devices. Both vector and raster output are supported. The filters allow the user to control the size, aspect ratio, and position on the page independent of the program which produces the data. Pen programs read files written in the vplot graphics metalanguage and write commands appropriate to the various output devices. The pen programs are all filters, and can be run in pipelines without loss of function. Only rudimentary provisions for interaction are provided. X Terminals now supported include color Tektronix and emulators (4105), monochrome Tektronix and emulators (4010) X(GraphOn, Selanar, Retrographics), Envision, DEC Regis (Gigi, VT125, VT220), Imagen, PostScript (e. g., Apple LaserWriter), Printronix printer, suntools, X, NEWS, and Rastertek. X FILES The source for the pen filters is located in .../vplot/filters and subdirectories. All include files (files ending in .h) are kept in X.../vplot/filters/include. Fonts are kept in X.../vplot/filters/include/vplotfonts. Each pen filter has an associated X device-dependent subroutine library, which is kept in a subdirectory of X.../vplot/filters. For example, the Envision pen filter ``envipen'' uses the directory .../vplot/filters/envilib. X PROGRAM STRUCTURE The philosophy behind vplot and pen has been to have users' programs write output in a device-independent language, and to present the results in a compatible manner on all devices. All the filters share a common user/operating system interface routine, called frontend, and a common vplot command interpreter, dovplot.c. Frontend consists of 3 parts: main_vplot, init_vplot, and proc_vplot. The routines in utillib.a are mostly low-level and device independent. Genlib.a is a set of generic routines which is capable of providing all or almost all of the functions needed to support a GKS vector output package. The programmer is free to use these routines in a device driver, or to substitute calls to high-level hardware capabilities. Loclib.a contains a subset of the seplib library, including routines for writing/reading vplot and for receiving parameters from the command line and initialization files. X The heart of the device support system is the file <dev>conf.c where <dev> is the name of the device. Inspired by the file X/usr/sys/machine/conf.c which configures the UNIX operating system to accept peripheral devices, this file is composed of three parts: X1) Declaration of the variables necessary to do self-documentation: X char name[] = "Filter name"; X char *documentation[] = {...documentation...}; X int doclength = {sizeof documentation / sizeof documentation[0] }; X X You may wish to include ``gendoc.h'' as part of your X documentation string. X X2) Declaration of the routines which have been chosen/written X to provide the various functions. X All the routines named in part 3 must be declared, as well as all the X routines which they may call. X X3) Initialization of a structure of pointers to the routines which do X the work. Since this structure is read directly by dovplot.c, X it is vital that the all entries be filled in order. X Each subroutine name can be one of three types: X X a) A device-specific subroutine name such as ``envipoint''. X (Note the first 4 characters of the name are a unique identifier X for the device, and the rest of the name tells which routine in the X table this is. The 4 letter identifier is usually tacked onto X ``pen'' to give the pen filter name (such as ``envipen'') and onto X ``lib'' to give the subdirectory name (such as ``envilib'').) X X b) A generic subroutine name such as ``genpoint''. X Generic subroutines simplify the device's work by handling X things in software. They in turn call other, simpler, device X routines. Generic routines are useful because by using them it X is very easy to rapidly support all the primitives on a device. X If the device can do things in hardware, however, it is usually X preferable to write a device-specific routine to use that capability X since that is much more efficient. X X c) The do-nothing subroutine ``nulldev''. X Nulldev is an all-purpose generic subroutine that simply X returns. It can either be used as a place holder for routines X your device doesn't use, or it can be used in cases where there X is simply no reasonable way to handle that particular primitive X on that device. X The usual procedure for creating a new driver has been to steal as much code as possible from a driver for a similar device, or from the generic library. For a Tektronix emulator, this can be as simple as checking that the mode changes are handled properly by dev.open and dev.close, and writing a devconf.c with the proper subroutine names. For a start, it should be possible to get a less-standard device going with devopen, devclose, and devplot routines, relying on generic routines for all other functions. Figure 1 contains the device structure for the Envision 220. X X--------------------------------------------------------------------------- X struct device dev = X{ X /* control routines */ X enviopen, /* open */ X envireset, /* reset */ X envimessage, /* message */ X envierase, /* erase */ X enviclose, /* close */ X X /* high level output */ X genvector, /* vector */ X genmarker, /* marker */ X gentext, /* text */ X genarea, /* area */ X genraster1, /* raster */ X envipoint, /* point */ X enviattributes, /* attributes */ X X /* input */ X envigetpoint, /* getpoint */ X geninteract, /* interact */ X X /* low level output */ X enviplot, /* plot */ X envistartpoly, /* startpoly */ X envimidpoly, /* midpoly */ X enviendpoly /* endpoly */ X}; X Figure 1: device structure for envipen X----------------------------------------------------------------------------- X VARIABLES The following variables are used to communicate information between dovplot and the device routines. X These variables must be initialized in either dev.open or dev.reset: X int dev_xmax, dev_ymax, dev_xmin, dev_ymin; X X These variables should give the device coordinates of the lower-leftmost X and upper-rightmost pixels on the device screen. It is assumed that X the device X axis is horizontal and the device Y axis is vertical, X and that dev_xmax > dev_xmin and dev_ymax > dev_ymin. If this is not X true for your device, it is up to the device routines to transform X the device coordinate system so it is true. (Examples of devices that X do this are gigipen and ipen.) X float pixels_per_inch, aspect_ratio; X X Pixels_per_inch gives the number of pixels per inch on the device X in the horizontal direction. Aspect_ratio gives the height to width X ratio of the pixels. (Aspect_ratio > 1 means that the pixels are tall X and skinny, and thus that the resolution is less in the vertical X direction than in the horizontal direction.) X int num_col; X X Num_col is the number of settable colors that the device has. X Colors that can't be reset from the host don't count. X Currently num_col can be at most 256, because this is all X the raster routines can handle (due to use of unsigned char's). X If mono=y is set, init_vplot will set num_col to zero. X X------------------- X These variables are set by dovplot but may be reset in dev.open (NOT dev.reset) if the default value is not appropriate. For the most part, resetting these variables is for the purpose of making a device-dependent default; the user is given a chance to override the value the device sets them to. X int mono=NO; X X If mono=NO, then the device is assumed to have color EVEN IF num_col is X zero. If mono=YES, then the device is monochrome. (The user cannot X override mono=YES, but can mono=NO.) See comments about the effects X of mono and num_col on color in dev.attributes below, and on raster X in dev.raster. Mono=YES forces num_col=0. X int invras=YES; X X This variable is only used in the utility routine ``dither.c'', which X dithers raster. Raster is only dithered if mono=YES and dither>0. X Normally such devices draw in black on a white page, which is the X reverse of what is normal for screen devices, and so invras=YES. X If the background color is BLACK then invras should be NO. X int dither=1; X X Default dithering style to use for this device. See vplotraster(9) X for the different values to be explained. X float greyc=1.; X X This variable is used only when dithering is being performed, X and really should only be used for hardcopy devices. It alters X the grey scale so that grey rasters come out on paper with the X same nonlinear appearance that is perceived on display devices. X See vplotraster(9) for a discussion of the parameter and how to X use it. X float pixc=1.; X X This variable is used only when dithering is being performed, X and also should only be used for hardcopy devices. It alters the X grey scale to correct for pixel overlap on the device, which X (if uncorrected) causes grey raster images to come out much darker X on paper than on graphics displays. See vplotraster(9) for a X discussion of the parameter and how to use it. X int txfont=DEFAULT_FONT, txprec=DEFAULT_PREC; X X Default text font, precision, and overlay mode. Text fonts of less X than NUMGENFONT are reserved for genvector fonts. If you want the X device to by default use some nice hardware font, you can reset X txfont to the appropriate device-dependent font number. X Alternatively, if the device is one in which plotting speed is not X a problem, txfont can be set to DEFAULT_HARDCOPY_FONT. X Txprec is pretty much ignored by genvector. Fancy output devices should X set txprec to DEFAULT_HARDCOPY_PREC to enable ligatures. Txprec may X be used by device-dependent text routines. Txprec must be in the range X 0 through 2. X float hshift=0., vshift=0.; int rotate=0; X X These values are in addition to whatever the user may set from the X command line. This provides a way for a device to rotate or translate X all plots. X int shade=YES; X X If shade=NO, then no attempt will be made by vplot to ask the device to X shade the interiors of polygons due to the vplot `a' and `A' commands. X Instead it will just outline them with vectors whenever it tries to X fill a polygon. This option is for devices that CAN fill but are X very slow to do so. X int wantras=YES; X X If wantras=NO, then no attempt will be made by vplot to ask the X device to handle raster due to the vplot `r' and `R' commands. X Instead it will just shade the raster area solid white using dev.area. X This option is for devices that CAN do raster but are very slow to X do it. X float fatmult=1., patternmult=1.; X X If fat lines are too slow, you can set fatmult=0. and disable line X fattening. The user can still turn it on again by overriding with X fatmult=1 from the command line. Patternmult can be used to scale up X or down patterns by default on a specific device. X int endpause=NO; X X If the device needs a pause at the end of the plot X (via dev.close(CLOSE_PAUSE) and then dev.interact(INT_F_PAUSE)) X then endpause should be set to YES. X int allowecho=?; X X Allowecho controls whether echoing is turned off for the duration of X plotting. Allowecho=NO turns off echoing. X If the dev.open sets allowecho, dovplot assumes that it knows what it's X doing and leaves it alone. Otherwise, X dovplot tries to decide whether allowecho should be YES or NO depending X on where the output stream pltout goes. If after calling dev.open X pltout and stderr point to the same place, then it assumes that X allowecho should be NO. The user can force allowecho to be YES X from the command line if the device or dovplot set it to be NO, X but the user cannot force it to be NO. X int (*message)()=genmessage; X X Dovplot decides where to send messages (such as error messages, for X example) in the same way that it decides how to set allowecho. X Before dev.open has been called, the device is not open and dev.message X cannot be called. Instead, it is assumed that it is safe to send all X messages to stderr by calling genmessage instead. After dev.open has X been called, dovplot checks to see whether stderr and pltout point to X the same place. If they do, then from then on all messages are routed to X dev.message. However, if they do NOT point to the same place, then it is X assumed that it is still safe to route them to stderr and messages are X still handled by genmessage. If this logic is incorrect for your device X you will need to reset this variable to dev.message in dev.open. So X far the only devices for which dovplot's logic has been wrong have X been virtual ones. The user cannot determine where messages are to X be sent. X X---------------- X These variables can usually be left at their default values, but may have to be reset for some devices. They cannot be changed by the user. X int need_end_erase=NO; X X Some devices use the ``erase'' routine to do things such as write out X a rasterized plot image as well as for erasing. For such devices it X is convenient to have dev.erase called one last time before the device X is closed (via dev.erase(ERASE_END)). To get this, set need_end_erase=YES. X int buffer_output=YES; X X If for some reason buffering the output to your device is a bad thing to X do, set buffer_output=NO. This only applies if you use the FILE *pltout X that dovplot provides. X int smart_clip=NO; X X If smart_clip=NO, then dovplot should do all clipping for you. If you X can do your own clipping, then set smart_clip=YES. You must then X handle dev.attributes(SET_WINDOW)! X int smart_raster=NO; X X If you can stretch AND clip your own raster, then set smart_raster=YES. X It is then up to you to do all the stretching and clipping (and possibly X dithering) of raster in the dev.raster routine, as dovplot will not then X do it for you. X X------------------- X These variables may be useful to refer to in dev.open, so that one pen filter can support multiple devices: X char callname[]="filename"; char wstype[]="default"; X X Callname gives the name the person invoked to run this pen filter. X (The leading path is stripped for you if present.) If the person X has ``wstype=work_station_type'' as a command line option, then X wstype will be set to the string "work_station_type". Otherwise, X it will be set to "default". Note that the only routine that X REALLY has to be defined in dev.conf is dev.open, and the only X routines that REALLY have to be defined in dev.open are dev.close, X dev.reset and dev.message. However, by the time dev.reset returns X everything had better be defined. Thus you can decide inside X dev.open which subroutines to plug into the device table, after X looking at wstype and callname to tell you which device you are X supporting. X X------------------------------------------------------------------------------ X SUBROUTINES All sizes and locations are in device units unless stated otherwise. Dovplot() uses its notions of the vplot environment (resolution, origin) and the device resolution (pixel size and shape) to call with the appropriate values. Subroutines may write to the external FILE *pltout which dovplot initializes, which may be a terminal, a pipe, or a text file, or they may open their own output file if pltout is not appropriate. In general, if the user is redirecting stdout, then that's where the output should go and no plot should actually appear anywhere. If the user is not redirecting stdout, then the user wants a plot to appear on the appropriate device. Pen filters should not easily be made to dump binary garbage out onto your screen! X We will list each routine in the device table in order. We will also list all associated generic and utility routines at the same time. X Control routines X X=========================== X dev.open() X Initialize device-dependent variables (see above) and emit hardware initialization strings. This routine is guaranteed to be the first called, and it is only called once. X X=========================== X dev.reset() X Reset the terminal. It is guaranteed that this will be called once after the first call to dev.open before any other routine is called. The one exception is in case of certain errors, in which case dev.reset is never called and instead dev.close(NOTHING) followed by dev.close(DONE) are the only other calls after the initial dev.open call. (This is the X``No input?'' error, which you've probably seen.) X X=========================== X dev.message(command, string) int command; char string[]; X Choose a command from mesgcom.h to position the cursor, set the proper text mode, and print out a message. Displaying a message will require several calls to dev.message, one per command. The meanings of the various commands are given by comments inside mesgcom.h. X Generic routines: genmessage.c Genmessage prints all messages to stderr. It doesn't try to do anything at all fancy, although it does beep as the best available completely device-independent way of ``highlighting text''. It beeps twice because some devices silently eat single beeps. X X=========================== X dev.erase(command) int command; X Choose an erase mode from erasecom.h, and erase the screen. The meanings of the various commands are given by comments inside erasecom.h. X X=========================== X dev.close(status) int status; X Choose a close status from closestat.h, and close the workstation. The meanings of the various commands are given by comments inside closestat.h. X High level output routines X X=========================== X dev.vector(x1, y1, x2, y2, nfat, dashon) int x1, y1, x2, y2, nfat, dashon; X{ X/* These can be declared by including extern.h */ extern float dashsum, dashpos; extern float dashes[/* dashon*2 */]; X Draw a (possibly) fat (possibly) dashed line from device coordinate X(x1,y1) to (x2,y2). The fatness of the line is given by nfat. Nfat=0 means the thinnest possible line. Each increase of 1 means to fatten the line by one device pixel WIDTH (the height could be quite different, depending on the value of aspect_ratio). Nfat < 0 should be checked for, and no vector should be drawn at all in that case. X If dashon>0 then a dashed line should be drawn. The pattern consists of dashon dash-gap pairs. The pattern is defined in the array dashes[2*dashon]. (ie, dashes[0] is the first dash length, dashes[1] is the first gap length, dashes[2] is the second dash length, etc.) Dovplot will call dev.attributes(NEW_DASH,...) whenever the values in this array are changed. Note that just because a dashed pattern has been put in effect does not mean it will always be used on all calls to dev.vector. Dev.vector can still be asked to draw continuous lines (ie, those for which dashon=0) without warning at any time. Dashsum gives the total length of the dash-gap pattern X(ie, dashsum = summation i=0;i<dashon*2;i++ of dashes[i]). The position in the dash pattern at the start of the vector is given in dashpos (it is the responsibility of dev.vector to update dashpos after each vector is drawn. The only time dovplot ever touches it is to reset it back to zero.) Dashpos, dashsum, and dashes are all measured in INCHES. (You should get the same size dash pattern on different devices even if they have different-sized screens!) If you are not sure whether you have supported dashed lines correctly, try using dashvec (described below) to do the dashing and see if the results are compatible. X Just as in the case of dashing, dev.attributes(NEW_FAT,...) warns when the "current fatness" has been changed. But dev.vector can still be asked to draw a line with a different fatness (such as for a polygon border) without warning at any time. X Utility routines associated with dev.vector: X These routines are meant to be called from a device-dependent dev.vector routine as utility functions. X fatvec(x1, y1, x2, y2, nfat, dashon) int x1, y1, x2, y2, nfat, dashon; X Fatvec should ONLY be called if nfat>0. Fatvec will apply Glenn Kroeger's line-fattening algorithm to the given fat vector, replacing it with several non-fat vectors. Fatvec will thus repeatedly call dev.vector with nfat=0. X(That's why it is important that your routine only call fatvec if nfat>0!) Fatvec ignores the dashon argument. X dashvec(x1, y1, x2, y2, nfat, dashon) int x1, y1, x2, y2, nfat, dashon; X Dashvec should ONLY be called if dashon>0. Dashvec will apply Joe Dellinger and Steve Cole's line-dashing algorithm to the given dashed vector, replacing it with several non-dashed vectors. Dashvec will thus repeatedly call dev.vector with dashon=0. (That's why it is important that your routine only call dashvec if dashon>0!) Dashvec ignores the nfat argument. X Note that if both dashvec and fatvec are called, dashvec must be called FIRST. X int clip(x1, y1, x2, y2) int *x1, *y1, *x2, *y2; X Clip will clip the vector {(x1,y1),(x2,y2)} to the bounds set by X{(xwmin,ywmin),(xwmax,ywmax)}. If the line is completely out of bounds and is clipped away to nothing, clip returns 1. Otherwise, clip returns 0. The standard way of using clip is: X X if(clip(&x1,&y1,&x2,&y2)) return; X Generic routines for dev.vector: genvector.c This routine will do all required clipping, fattening, and dashing. It will also keep track of the previous position, and breaks up strings of vectors for you into moves and draws. (It does this in a tricky way, re-ordering the incoming vectors and even discarding moves that can be done with draws. The idea is to make the plot come out as efficiently as possible on the device.) It calls dev.plot(x,y,flag). No other routine calls dev.plot, so if you do not use genvector then dev.plot should be nulldev. X X=========================== X dev.marker(npts, mtype, msize, coor) int npts, type, size; int coor[/* npts*2 */]; X Draw npts symbols centered at device coordinates (coor[0],coor[1]), X(coor[2],coor[3]),...,(coor[npts*2-2],coor[npts*2-1]). X Mtype is an integer from 0 to whatever, defining the type of symbol to draw. Mtype of 0 through 5 is defined as in GKS: X0,1: Smallest possible dot on the device. X2: Plus sign X3: Asterisk X4: Circle X5: Cross X6-19: Reserved by GKS, but currently undefined. These are as used in Vplot: X20: Square X21: Triangle (flat side on bottom) X22: Diamond X23: 5-pointed Star X For values that make sense as ASCII, something that looks like the corresponding ASCII character should be used. For ridiculous values of mtype, at least plot a point. X Msize is the vertical height of the symbol in VERTICAL device units. X(Ie, msize says how many pixels tall the letter `A' should be.) X Generic routines: genmarker.c Genmarker calls dev.point, dev.text, or gentext.c as needed to produce the desired symbols. For ASCII symbols the current font is used, which could either be a device-dependent font or a gentext font depending on the font number. Marker types 2 through 23 are drawn using the MATH and MISC gentext fonts. X X=========================== X dev.text(string, pathx, pathy, upx, upy); char *string; float pathx, pathy, upx, upy; X{ X/* These can be defined by including vplot.h and extern.h */ extern int txfont, txprec, txovly; struct txalign {int hor; int ver;}; extern struct txalign txalign; extern int fat; extern int xold, yold; X Print the text in string at the point (xold,yold) in device coordinates. Upon return, xold and yold should be reset to point to the END of the text. X(IE, for the normal text justification mode (TH_LEFT, TV_BASE), if the dev.text routine is called twice in a row the two printed strings should fit together nicely, as if produced by one call to dev.text with the two strings concatenated.) X The text should have fatness `fat', as defined in the section for dev.vector above. X The text should be justified according to the values of txalign.hor X(for horizontal alignment) and txalign.ver (for vertical alignment.) See vplot.h and vplottext.mn for descriptions of how text justification should work and to enumerate the various justification modes. (Our modes follow GKS, but with a couple of extensions thrown in to handle symbols and mid-text font and size changes.) X The text font value to use is given by txfont. Device-dependent text fonts start at font number NUMGENFONT. For txfont less than this, dovplot will NOT automatically call gentext. Device-dependent text routines, except for certain special cases, should begin by: X X if (txfont < NUMGENFONT) X { X gentext(...pass on all arguments here...); X return; X } X The text precision value can be used by device-dependent text routines to control the quality of text produced. (You should either follow the GKS conventions or simply produce good text and ignore this parameter.) The three different precisions are enumerated in vplot.h X The text overlay value controls whether or not an area is shaded out under the text before it is drawn, and whether or not a box should be drawn around it. The shading should be to the current background color, END_OF_FILE if test 25049 -ne `wc -c <'Vplot_Kernel/Documentation/hacker.doc.1'`; then echo shar: \"'Vplot_Kernel/Documentation/hacker.doc.1'\" unpacked with wrong size! fi # end of 'Vplot_Kernel/Documentation/hacker.doc.1' fi if test -f 'Vplot_Kernel/filters/init_vplot.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Vplot_Kernel/filters/init_vplot.c'\" else echo shar: Extracting \"'Vplot_Kernel/filters/init_vplot.c'\" \(23118 characters\) sed "s/^X//" >'Vplot_Kernel/filters/init_vplot.c' <<'END_OF_FILE' X/* X * Copyright 1987 the Board of Trustees of the Leland Stanford Junior X * University. Official permission to use this software is included in X * the documentation. It authorizes you to use this file for any X * non-commercial purpose, provided that this copyright notice is not X * removed and that any modifications made to this file are commented X * and dated in the style of my example below. X */ X X/* X * X * source file: ./filters/init_vplot.c X * X * Joe Dellinger (SEP), Feb 18 1988 X * Inserted this sample edit history entry. X * Please log any further modifications made to this file: X * X * Joe Dellinger, Feb 20 1988 X * #define GETPAR to be fetch if SEPlib version. X * X * Joe Dellinger Feb 24 1988 X * Moved gen_do_dovplot to genlib, where it belongs. X * txfont, txprec, txovly, overlay defaults remembered. X * Joe Dellinger Feb 28 1988 X * Changed fatness to scale with size of screen and scale, X * like any regular geometric attribute. X * Joe Dellinger Mar 4 1988 X * Fixed slight bug with fatness scaling and style=old. X */ X X#include <stdio.h> X#include <math.h> X#include <sys/ioctl.h> X#include <sys/types.h> X#include <sys/stat.h> X#include <sgtty.h> X#include <ctype.h> X#include <strings.h> X X#include <vplot.h> X X#include "./include/params.h" /* for machine dependencies */ X#include "./include/enum.h" X#include "./include/err.h" X#include "./include/attrcom.h" X#include "./include/intcom.h" X#include "./include/mesgcom.h" X#include "./include/erasecom.h" X#include "./include/closestat.h" X#include "./include/pat.h" X#include "./include/vertex.h" X#include "./include/round.h" X#include "./include/extern.h" X X#ifdef SEP X#define GETPAR fetch X#else X#define GETPAR getpar X#endif SEP X struct sgttyb tty_clean_state; struct sgttyb tty_plot_state; int tty_clean_local_mode; int tty_plot_local_mode; X X/* X * The following variables must ALWAYS X * be set in the device open or device reset file. X * All their defaults are set to absurd values so that X * we'll crash quickly it they're not set as required. X */ X/* Screen dimensions */ int dev_xmax = 0, dev_ymax = 0, dev_xmin = 0, dev_ymin = 0; X/* Number of pixels per inch in the horizontal (X) direction on the device */ float pixels_per_inch = 0.; X/* vertical height (on screen) / horizontal width for a single pixel */ float aspect_ratio = 0.; X/* X * Number of SETTABLE COLORS that the device has. X * Non settable colors don't count. X */ int num_col = -1; X X/* X * Other things that may need to be reset in dev.open X * (Can't reset them some of them in dev.reset, because the user may X * override from the command line.) X */ X/* Does device need erase at end? */ int need_end_erase = NO; X/* should the output be buffered? */ int buffer_output = YES; X/* should the input be buffered? */ int buffer_input = YES; X/* should pipes be allowed for input? */ int allow_pipe = YES; X/* Can the device do its own clipping? (of vectors and polygons.) */ int smart_clip = NO; X/* Can the device stretch AND clip its own raster? */ int smart_raster = NO; X X/* X * These may be reset to device-dependent defaults. X */ float fatmult = 1.; float patternmult = 1.; X X/* X * Look in extern.h for a better-organized list of the preceding. X * Here I have left things which are also filter options with the X * other filter options, even though they also belong in the above X * categories. X */ X X/* X * flags and variables X */ char wstype[25]; char callname[25]; int xcenterflag, ycenterflag; int ever_called = NO; int first_time = YES; int device_open = NO; /* used by ERR */ int out_isatty = YES; /* If NO, output is a file or pipe */ int nplots = 0; /* number of plots made */ X X/* X * coordinate variables X */ int xwmax, xwmin, ywmax, ywmin; /* window */ int xnew, ynew; /* new pen location */ int xold, yold; /* old pen location */ int xorigin = 0, yorigin = 0; /* global "origin" */ char *txbuffer; int txbuflen, vxbuflen; struct vertex *vxbuffer; int xret, yret; float mxx, mxy, myx, myy; X/* X * This is so the device can throw in a coordinate transformation X * for its convenience ON TOP OF whatever transformation the user X * wants. X */ int default_rotate = 0, default_hshift = 0, default_vshift = 0; X X/* X * attribute variables X */ int linestyle; int cur_color = DEFAULT_COLOR; int pat_color = DEFAULT_COLOR + 1; int next_color; struct txalign txalign; X int txfont = DEFAULT_FONT; int txprec = DEFAULT_PREC; int txovly = OVLY_NORMAL; int default_txfont, default_txprec, default_txovly; int fat = 0; int afat = 0; int ipat = 0; /* currently loaded pattern */ struct pat pat[NPAT + 1]; float dashsum = 0.; int dashon = NO; /* Dashed lines? */ float dashes[MAXDASH * 2]; float dashpos = 0.; /* Position in current dashing pattern */ int color_set[MAX_COL + 1][_NUM_PRIM]; extern int greycorr (); int num_col_8; X X X/* X * filter options - flags X */ X/* Monochrome device? */ int mono = NO; X/* X * Invras determines the polarity of dithered raster. X * invras=n means raster works the same way as vectors; what is normally X * WHITE on most devices is BLACK on a hardcopy black and white device. X * invras=y is the proper default to make dithered images not come out as negatives X */ int invras = YES; int window = YES; int shade = YES; int brake = NO; int framewindows = NO; int endpause = NO; int allowecho = NEVER_SET; X/* X * setting allowecho NO (which may get done X * in dev.open) means that the output device X * is the user's terminal and echoing chars X * back at the user would insert nonsense X * into the plot stream. In this case we X * explicitly shut down echoing and output X * translation until the end of the job. X * Arguably, output translation should be X * set/unset in dev.open or dev.reset as we may X * be plotting on a terminal not our own or X * the device filter may have built in X * workarounds for known output translation X * effects. I use it here as a safety measure. X */ int wantras = YES; X X/* X * filter options - enumerated X */ int style = NO_STYLE_YET; int default_style = STYLE; int rotate; int size = RELATIVE; int erase = FORCE_INITIAL | DO_LITERALS; X X/* X * filter options - valued X */ int xcenter, ycenter; /* Vplot of point to force as center */ int fatbase = 0; int epause = 0; /* time to pause before erasing screen */ int overlay = 0; /* 1=overlay 0=replace */ int default_overlay; X X/* X * 0 = none X * 1 = random X * 2 = Ordered X * 3 = Floyd-Steinberg X */ int dither = 1; /* Dithering type */ X int xWmax, xWmin, yWmax, yWmin; float hshift, vshift; /* Allow global translation of plot */ float scale; /* global scale */ float xscale; /* global x-scale */ float yscale; /* global y-scale */ float hdevscale; /* Vplot units to device units for x */ float vdevscale; /* Vplot units to device units for y */ float txscale;/* global text scale */ float mkscale;/* global marker scale */ float dashscale; /* global dashed line scale */ char interact[MAXFLEN + 1] = ""; /* Where to store coordinate X * file */ float greyc = 1.; /* Nonlinear correction */ float pixc = 1.; /* Pixel overlap correction */ X X/* filter options - resettable between plots */ int user_rotate; float user_txscale; float user_mkscale; float user_dashscale; float user_scale; float user_xscale; float user_yscale; int user_size; float user_hshift; float user_vshift; int user_xwmax_flag; float user_xwmax; int user_ywmax_flag; float user_ywmax; int user_xwmin_flag; float user_xwmin; int user_ywmin_flag; float user_ywmin; X int ifat = 0; float fatmult_orig; X X/* X * file and terminal control variables X */ int pltoutfd, stderrfd, controlfd; extern int genmessage (); int (*message) () = genmessage; struct stat stderrstat; struct stat pltoutstat; FILE *pltout, *pltin; FILE *fopen (); FILE *fdopen (); FILE *controltty; char outbuf[BUFSIZ]; char *getenv (); char *malloc (); char *realloc (); char group_name[MAXFLEN + 1]; int group_number = 0; FILE *pltinarray[MAXIN]; char pltinname[MAXIN][MAXFLEN + 1]; char pltname[MAXFLEN + 1] = ""; int infileno = 0; extern int gen_do_dovplot (); int (*genreader) () = gen_do_dovplot; X X/* X * Initialize and declare global variables. X * Use getpar and getenv to search for command-line options. X */ X init_vplot () X{ char *stringptr; int ii; char string[MAXFLEN + 1]; float ftemp; X X X txbuffer = malloc (TXBUFLEN); X txbuflen = TXBUFLEN; X/* X * Sun III lint complains about "pointer alignment problem" here, X * although the documentation makes it sound like that shouldn't X * be possible. X */ X vxbuffer = (struct vertex *) malloc (sizeof (struct vertex) * VXBUFLEN); X vxbuflen = VXBUFLEN; X X /* X * If the device can't do color, it can set mono to YES If device is X * mono, this overrides the user's insistence that it isn't. So GETPAR X * before we call dev.open. X */ X GETPAR ("mono", "1", &mono); X X strcpy (wstype, "default"); X if ((stringptr = getenv ("WSTYPE")) != NULL) X strcpy (wstype, stringptr); X /* X * Don't want to accidentally get this from a history file. Must come for X * the command line, so getpar, not GETPAR X */ X getpar ("wstype", "s", wstype); X X /* X * Initialize all patterns to be undefined. (device can create a X * device-dependent default set if it wishes) X */ X for (ii = 0; ii <= NPAT; ii++) X { X pat[ii] .patbits = NULL; X } X X/* X * The device-independent code MAY NOT actually read from X * the terminal itself. However, these variables are X * declared so that the device-dependent routines can use X * them if they wish as a courtesy. X */ X controlfd = open ("/dev/tty", 0); X controltty = fdopen (controlfd, "r"); X X /* X * Call device open before doing anything else. this finalizes pltout X */ X dev.open (); X device_open = YES; X X/* X * Beware trying to print out error messages until X * we've figured out where to connect the "message" routine! X */ X X if (buffer_output) X setbuf (pltout, outbuf); X else X setbuf (pltout, (char *) NULL); X X /* X * If graphics output going to control terminal, disable echoing and X * arrange for use of device's message routine X */ X pltoutfd = fileno (pltout); X stderrfd = fileno (stderr); X out_isatty = isatty (pltoutfd); X X if (allowecho == NEVER_SET) X { X allowecho = YES; X if (out_isatty) X { X fstat (pltoutfd, &pltoutstat); X fstat (stderrfd, &stderrstat); X#ifdef SEP X if ((pltoutstat.st_dev == stderrstat.st_dev)) X /* X * Something in seplib makes the next 2 tests not work, I X * don't know why. Unfortunately, this means the SEP versions X * aren't as good about detecting the case of sending the X * output to a different terminal than the one you're logged X * in at. We should probably get this fixed sometime. - Joe X * D. X */ X#else X if ((pltoutstat.st_dev == stderrstat.st_dev) && X (pltoutstat.st_ino == stderrstat.st_ino) && X (pltoutstat.st_rdev == stderrstat.st_rdev)) X#endif SEP X { X allowecho = NO; X message = dev.message; X } X } X } X X /* X * process YES or NO option arguments. GETPAR means it could have come X * from a seplib history file, getpar means it had to come from the X * command line. Use "getpar" when having the right value of the X * parameter is critical because setting the value overrides frontend's X * judgement. X */ X getpar ("echo", "1", &allowecho); X if (!allowecho) X { X ioctl (pltoutfd, TIOCGETP, (char *) (&tty_clean_state)); X bcopy ((char *) (&tty_clean_state), (char *) (&tty_plot_state), X sizeof (struct sgttyb)); X ioctl (pltoutfd, TIOCLGET, (char *) (&tty_clean_local_mode)); X tty_plot_local_mode = tty_clean_local_mode | LLITOUT; X ioctl (pltoutfd, TIOCLSET, (char *) (&tty_plot_local_mode)); X tty_plot_state.sg_flags &= (~ECHO); X tty_plot_state.sg_flags &= (~LCASE); X tty_plot_state.sg_flags |= (CBREAK); X ioctl (pltoutfd, TIOCSETN, (char *) (&tty_plot_state)); X } X getpar ("endpause", "1", &endpause); X GETPAR ("break", "1", &brake); X GETPAR ("shade", "1", &shade); X GETPAR ("wantras", "1", &wantras); X GETPAR ("window", "1", &window); X GETPAR ("frame", "1", &framewindows); X GETPAR ("overlay", "1", &overlay); X default_overlay = overlay; X GETPAR ("invras", "1", &invras); X X/* X * Valued arguments X */ X X getpar ("dither", "d", &dither); X getpar ("greyc", "f", &greyc); X getpar ("pixc", "f", &pixc); X X GETPAR ("txfont", "d", &txfont); X GETPAR ("txprec", "d", &txprec); X GETPAR ("txovly", "d", &txovly); X default_txfont = txfont; X default_txprec = txprec; X default_txovly = txovly; X X if (GETPAR ("erase", "s", string)) X { X if ((string[0] == 'n') || (string[0] == 'N')) X erase = NO; X else X if ((string[0] == 'o') || (string[0] == 'O')) X erase = FORCE_INITIAL; X else X if ((string[0] == 'l') || (string[0] == 'L')) X erase = DO_LITERALS; X else X erase = FORCE_INITIAL | DO_LITERALS; X } X X xcenter = 0; X ycenter = 0; X xcenterflag = NO; X ycenterflag = NO; X if (GETPAR ("xcenter", "f", &ftemp)) X { X xcenterflag = YES; X xcenter = ROUND (ftemp * RPERIN); X } X if (GETPAR ("ycenter", "f", &ftemp)) X { X ycenterflag = YES; X ycenter = ROUND (ftemp * RPERIN); X } X X if ((stringptr = getenv ("PATTERNMULT")) != NULL) X { X sscanf (stringptr, "%f", &patternmult); X } X GETPAR ("patternmult", "f", &patternmult); X X GETPAR ("interact", "s", interact); X GETPAR ("pause", "d", &epause); X X if (interact[0] != '\0') X { X epause = 0; /* interact makes it own sort of pausing */ X endpause = NO; X } X X /* X * Find the default style X */ X stringptr = NULL; X if (GETPAR ("style", "s", string)) X stringptr = string; X else X stringptr = getenv ("PLOTSTYLE"); X if (stringptr != NULL) X { X if ((stringptr[0] == 'r') || (stringptr[0] == 'R') || X (stringptr[0] == 'm') || (stringptr[0] == 'M')) X default_style = ROTATED; X else X if ((stringptr[0] == 'o') || (stringptr[0] == 'O')) X default_style = OLD; X else X if ((stringptr[0] == 'a') || (stringptr[0] == 'A')) X default_style = ABSOLUTE; X else X default_style = STANDARD; X } X X/* X * Options changeable between calls to dovplot X * (By calling reset_parameters or reset()) X * Dovplot calls reset every time it starts. It only calls X * reset_parameters the first time. X * X * Things in this category: X * user_* X * fatmult_orig, fatbase X */ X X if ((stringptr = getenv ("FATMULT")) != NULL) X { X sscanf (stringptr, "%f", &fatmult); X } X GETPAR ("fatmult", "f", &fatmult); X fatmult_orig = fatmult; X X user_rotate = 0; X GETPAR ("rotate", "d", &user_rotate); X X user_txscale = 1.0; X user_mkscale = 1.0; X user_dashscale = 1.0; X GETPAR ("txscale", "f", &user_txscale); X GETPAR ("mkscale", "f", &user_mkscale); X GETPAR ("dashscale", "f", &user_dashscale); X X user_scale = 1.0; X user_xscale = 1.0; X user_yscale = 1.0; X GETPAR ("scale", "f", &user_scale); X GETPAR ("xscale", "f", &user_xscale); X GETPAR ("yscale", "f", &user_yscale); X X user_size = size; X if (GETPAR ("size", "s", string)) X { X if ((string[0] == 'a') || (string[0] == 'A')) X user_size = ABSOLUTE; X else X user_size = RELATIVE; X } X X user_hshift = 0.; X GETPAR ("hshift xshift", "f", &user_hshift); X user_vshift = 0.; X GETPAR ("vshift yshift", "f", &user_vshift); X X user_xwmax_flag = GETPAR ("xwmax", "f", &user_xwmax); X user_ywmax_flag = GETPAR ("ywmax", "f", &user_ywmax); X user_xwmin_flag = GETPAR ("xwmin", "f", &user_xwmin); X user_ywmin_flag = GETPAR ("ywmin", "f", &user_ywmin); X X GETPAR ("fat", "d", &fatbase); X X X X/* X * These parameters can simply be changed at any time with no X * need for re-initialization of anything else: X * X * shade, wantras X * X */ X X} X init_colors () X{ int ii; X X /* X * Set up the default color table X */ X X/* X * First 7 colors are assumed to map to the standard 7 pen colors X * on ALL devices, even those with no settable colors! X */ X for (ii = 0; ii < 8; ii++) X { X color_set[ii][STATUS] = SET; X color_set[ii][_RED] = MAX_GUN * ((ii & 2) / 2); X color_set[ii][_GREEN] = MAX_GUN * ((ii & 4) / 4); X color_set[ii][_BLUE] = MAX_GUN * ((ii & 1) / 1); X color_set[ii][_GREY] = greycorr ((int) ((MAX_GUN * ii) / 7)); X } X X if (mono) X { X /* Monochrome devices are assumed to have no settable colors */ X num_col = 0; X } X X num_col_8 = (num_col > 8) ? num_col : 8; X X if (mono) X { X color_set[0][MAP] = 0; X for (ii = 1; ii <= MAX_COL; ii++) X { X color_set[ii][MAP] = 7; X } X for (ii = num_col_8; ii < 256; ii++) X { X color_set[ii][_GREY] = color_set[((ii - 8) % 7) + 1][_GREY]; X } X /* Put a grey scale in the upper half of the color table */ X for (ii = 256; ii <= MAX_COL; ii++) X { X color_set[ii][_GREY] = greycorr (ii - 256); X } X } X else X { X /* X * Unmapped colors shouldn't be mapped; ie, they map to themselves X */ X for (ii = 0; ii < num_col_8; ii++) X { X color_set[ii][MAP] = ii; X } X /* X * Colors outside the range of this terminal map cyclically back into X * colors 1 through 7 X */ X for (ii = num_col_8; ii <= MAX_COL; ii++) X { X color_set[ii][MAP] = ((ii - 8) % 7) + 1; X } X } X} X setstyle (new_style) X int new_style; X{ X /* X * Check to see if the style has changed X */ X if (new_style == style) X return; X X style = new_style; X reset_parameters (); X} X reset_parameters () X{ float inches; /* scaling base for y axis */ float screenheight, screenwidth; /* true size of the screen */ int ix, iy; X X xorigin = 0; X yorigin = 0; X X rotate = default_rotate; X rotate += user_rotate; X X txscale = user_txscale; X mkscale = user_mkscale; X dashscale = user_dashscale; X X scale = user_scale; X xscale = user_xscale; X yscale = user_yscale; X X fatmult = fatmult_orig; X X size = user_size; X X switch (style) X { X/* X * The old standard on the machine erebus. X * Pretty much dead now. Still useful for some old programs nobody's X * wanted to update. X */ X case OLD: X txscale /= 3.; X fatmult /= 3.; X scale *= 3.; X inches = STANDARD_HEIGHT; X break; X/* X * The old standard on the machine mazama. A useful coordinate system X * for geological sorts of plots. X * The Y axis goes the long way, across the screen, which is the device's X * horizontal axis. X */ X case ROTATED: X rotate += 90; X inches = ROTATED_HEIGHT; X break; X case ABSOLUTE: X size = ABSOLUTE; X case STANDARD: X default: X inches = STANDARD_HEIGHT; X break; X } X X if (rotate >= 0) X rotate = rotate % 360; X else X rotate = ((rotate % 360) + 360) % 360; X X mxx = cos (2. * 3.14159 * rotate / 360.); X myy = cos (2. * 3.14159 * rotate / 360.); X mxy = sin (2. * 3.14159 * rotate / 360.); X myx = -sin (2. * 3.14159 * rotate / 360.); X X if (size == ABSOLUTE) X { X vdevscale = pixels_per_inch / (float) (RPERIN * aspect_ratio); X hdevscale = pixels_per_inch / (float) RPERIN; X } X else X { X /* X * Fit the inches x inches unit square into a displayable box with X * aspect ratio SCREEN_RATIO X */ X screenwidth = (dev_xmax - dev_xmin) * pixels_per_inch; X screenheight = X (dev_ymax - dev_ymin) * pixels_per_inch * aspect_ratio; X if ((screenheight / screenwidth) > SCREEN_RATIO) X { X vdevscale = (SCREEN_RATIO * ((dev_xmax - dev_xmin) / aspect_ratio)) / X (inches * RPERIN); X hdevscale = vdevscale * aspect_ratio; X } X else X { X vdevscale = (dev_ymax - dev_ymin) / (inches * RPERIN); X hdevscale = vdevscale * aspect_ratio; X } X } X X hshift = default_hshift; X vshift = default_vshift; X X if (style == ROTATED) X { X vshift += dev_ymax - dev_ymin; X } X X yscale *= scale; X xscale *= scale; X mkscale *= scale; X X/* X * Set up fatness multiplication factor X */ X fatmult *= scale * hdevscale * RPERIN / FATPERIN; X X /* X * The point (xcenter,ycenter) in vplot coordinates is to be centered in X * the screen. X */ X if (xcenterflag || ycenterflag) X { X vptodevxy (xcenter, ycenter, &ix, &iy); X if (xcenterflag) X { X hshift += (dev_xmax + dev_xmin) / 2 - ix; X } X if (ycenterflag) X { X vshift += (dev_ymax + dev_ymin) / 2 - iy; X } X } X X hshift += user_hshift * pixels_per_inch; X vshift += user_vshift * pixels_per_inch / aspect_ratio; X X/* plot window parameters defaulted */ X/* to maximum size */ X X devtovpw (dev_xmin, dev_ymin, dev_xmax, dev_ymax, X &xWmin, &yWmin, &xWmax, &yWmax); X X if (user_xwmax_flag) X xWmax = ROUND (user_xwmax * RPERIN); X if (user_ywmax_flag) X yWmax = ROUND (user_ywmax * RPERIN); X if (user_xwmin_flag) X xWmin = ROUND (user_xwmin * RPERIN); X if (user_ywmin_flag) X yWmin = ROUND (user_ywmin * RPERIN); X X vptodevw (xWmin, yWmin, xWmax, yWmax, &xWmin, &yWmin, &xWmax, &yWmax); X X wlimit (dev_xmin, dev_xmax, &xWmin, &xWmax); X wlimit (dev_ymin, dev_ymax, &yWmin, &yWmax); X X xwmax = xWmax; /* plot window parameters defaulted */ X xwmin = xWmin; /* to maximum size */ X ywmax = yWmax; X ywmin = yWmin; X reset_windows (); X} X add_a_cor (filename, xcor, ycor) X char *filename; X int xcor, ycor; X{ static int first_time = YES; static FILE *outfp; X X if (first_time == YES) X { X outfp = fopen (filename, "w"); X if (outfp == NULL) X { X ERR (FATAL, name, "Can't open interact output file %s!", filename); X } X first_time = NO; X } X fprintf (outfp, "%f\t%f\n", (float) xcor / RPERIN, (float) ycor / RPERIN); X} X wlimit (min, max, xmin, xmax) X int min, max; X int *xmin, *xmax; X{ X if (*xmin < min) X *xmin = min; X X if (*xmax > max) X *xmax = max; X} X END_OF_FILE # end of 'Vplot_Kernel/filters/init_vplot.c' fi echo shar: End of archive 19 \(of 24\). cp /dev/null ark19isdone 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.