If no graphics files are provided, standard input is read.
x79 is an \*(Xw program that can display on a color graphics window a graphics file encoded in a simple ASCII format produced by PLOT79 or other graphics programs, such as tkvecs(1), which converts Tektronix graphics files to this format, or a file in Tektronix format. Line width selection, rotation, pan, zoom, smoothing, undo, and redo are available for examination of the plot. Views can be saved in a graphics file.
The IBM RS/6000 AIX xinit normally does not support backing store; however, it has an undocumented switch that can remedy that. Invoke it as xinit -bs to get backing store support. As of January 1991, it seems to be buggy; some aixterm and info windows will not be restored correctly after an expose when backing store is enabled.
_________________________________________________ | Table 1: debug output selection masks | | Mask Selection | | 0x001 show clipping decisions | | 0x002 show color remappings | | 0x004 show input collection | | 0x008 show matrix inversion | | 0x010 show polyline processing | | 0x020 show smoothing calculations | | 0x040 show input data statistics | | 0x080 show Tektronix input collection | | 0x100 show window clipping boxes | | 0x200 show transformation matrices | | 0x400 suppress keyboard grabbing and ungrabbing| |________________________________________________|
The sum may be specified in decimal, octal (leading zero), or hexadecimal (leading 0x).
With the -exactcolormap switch, you request that a private colormap be created for the graphics window, with each color set to exactly the (red, green, blue) values specified in the graphics input file. On all but the most expensive systems, this will result in the colors of inactive windows being modified. When the mouse cursor leaves the graphics window, the original colormap will be restored and the other windows will regain their correct colors; the graphics window will then have incorrect colors.
Because this change of screen colors can be distracting, this switch is not the default.
Some window managers (e.g. aixwm and twm) do not support private colormaps; for them, -exactcolormap will not be useful. The OSF/Motif window manager, mwm, works very nicely with this option.
Any color name acceptable to the \*(Xw may be given, including hexadecimal strings of the form #rgb, #rrggbb, #rrrgggbbb, and #rrrrggggbbbb, giving values for the red, green, and blue components respectively. If a definition of the named color cannot be located, then the color definition from the graphics file is used instead.
This option is useful for changing a small number of colors without having to edit the graphics files. In particular, small pen numbers in the PLOT79 ptXlib library are mapped into the standard CORE system colors as follows: 0 = black, 1 = red, 2 = green, 3 = yellow, 4 = blue, 5 = magenta, 6 = cyan, and 7 = white. Since the default pen is 1, the result is red lines on a black background, which does not provide good contrast. For a monochrome plot, you would therefore probably want to use something like -remap 1 white.
This switch can be specified as many times as needed.
Color index 0 is always the background color, and color index 1 is always the foreground color. Color specifications for those two indexes will override the background and foreground color settings, unless they follow this switch, and the graphics file itself contains no color settings.
Once the first data file has been read, x79 creates a window on the workstation defined by the -display command-line switch, or if that is not specified, by the DISPLAY environment variable, and displays the plot in it. The window size and position can be set explicitly by the -geometry command-line switch; otherwise, the internal defaults will be used.
The graphics window can be resized arbitrarily, from the full screen, down to a very small square only a few pixels on edge; the maximum and minimum sizes can be set in a resource file.
The aspect ratio of the data is maintained exactly; the plot will never be distorted in a window that is unusually wide or high.
The terminal window from which x79 was started is used for status messages and debug output; you may choose to make this window an icon (the PLOT79 library, ptXlib, works that way) so you are not bothered by the message output, or you can shrink it down to a few lines.
Once the plot has been displayed, x79 sits in the normal window program event loop, waiting for requests from the keyboard or mouse, or events that require redrawing the picture.
With complex plots, this drawing can take many seconds to complete, so x79 normally arranges for the X server to use backing store if available, and provides its own if not. That way, if the graphics window is covered, and then uncovered, redisplay is almost instantaneous. Users familiar with the irritatingly slow redrawing in Tektronix windows under xterm(1) will appreciate the difference. The +pixmap option can be used to suppress creation of the window copy; its use may make graphics display faster.
Plotting may be interrupted at any time by a key press, button press, or by resizing or moving of the window; if you did this unintentionally, just refresh the display by typing a Ctl-L, or press the Re-Do, or Again, key, if your keyboard has one.
To allow detailed examination of the plot, x79 allows you to zoom, pan, change the line width, and even to request tensioned spline interpolation of all polylines. The latter is useful primarily to keep zoomed pictures smooth; quite humorous, but useless, effects can be seen when smoothing is applied to normal pictures. During zooming and translation, the window size and position remains constant; the picture moves inside the window.
Because the \*(Xw stores coordinates as 16-bit values (i.e. a coordinate range of -32768 .. +32767), with large zoom factors, integer overflow will eventually cause coordinate wraparound, and the resulting nonsense coordinate points will corrupt the plot, causing incorrect polylines to be drawn. It should normally be possible to zoom up to at least a factor of 32 before this becomes a problem; zooming down will correct it in any event.
Zooming and panning are controlled either from the mouse alone, or from the mouse and the keyboard while the mouse cursor is in the graphics window.
If the keyboard is to be used for zooming, the mouse must first select the center point for zooming. The default zoom center, called the zoom point, is initially at the center of the screen, but once selected, moves with the plot if it is translated. That way, the zoom point is attached to part of the picture, not to a fixed position on the screen. The C or c key will move the zoom point to the exact center of the bounding box of the input data.
If the mouse is moved while any button is down, a dotted rubber-band rectangle will be displayed. When the mouse button is released, the region inside that rectangle will be translated and zoomed to fill the screen, preserving the aspect ratio of the original data. The zoom point is moved to the center of the new display.
Key bindings are at present hard-coded into the program (that restriction must be lifted; see the TO DO section below); the best way to determine them is to press the Help key (if your keyboard has one), or type a query, ?, in the graphics window. The terminal window will then show the supported bindings. Because keyboards vary somewhat between different workstations, functions are usually available on several keys.
In general, arrow keys and Emacs-style cursor commands can be used to translate the picture; the Z, z, and keypad *, /, [, and ] keys request zooming up or down. The normal *, /, <, and > keys control the line width. Smoothing is toggled on and off with the S key, and the T and t keys adjust the spline tension up or down. @ rotates the view by 90 degrees clockwise about the current zoom point; a numeric argument (see below) can provide alternate rotation angles.
Press the D or d key to make a dump of the portion of the plot visible in the current view; see the -plotfile option above. Polylines that are not in the view are excluded from the output. The original coordinate values are preserved; the bounding box is reduced instead to reproduce the view. However, any existing rotation is not applied to the dumped polyline coordinates.
The dump command should prove useful for extracting portions of zoomed views, or removing margin labels. The dump is a file in the standard x79 text-file format. The original color definitions are preserved, except for those that have been altered by the -remap option; they will have red, green, and blue values corresponding to the remapped color. Line widths of the current view are sent to the output.
All input file lines beginning with a comment starter in column 1 are preserved and output as an auxiliary header, so as to preserve information about the origin of the original data.
x79 keeps a record of all changes to viewing parameters in a dynamically-expanded undo list. You can move backwards through this list, undoing previous views, with keyboard U, u, Ctl-_, or UNDO keys, and forwards with keyboard R, r, Ctl-R, AGAIN or REDO keys. This makes it safe to make exploratory viewing excursions from a view that you want to return to.
All commands take prefix optionally-signed numeric arguments, including Emacs-style Ctl-U modifiers. Thus, you can type 10T to set the tension to 10, or 125 Up-Arrow to move the picture 125 pixels up. Each Ctl-U multiplies the current argument by 4; thus, Ctl-U Ctl-U Z will zoom the picture to 16 times its original size.
As in Emacs, ESCape starts a new numeric argument, but so does a digit, so ESCape can normally be omitted.
If you are zooming and panning, it is easy to get lost; press the Home key (or O or o key) to restore the picture to its original size and attributes.
Finally, to quit viewing the plot, type DELete, Ctl-C, Q, or q with the cursor in the graphics window.
When you quit, x79 will clear the graphics window, and display the next requested file. When there are no more graphics files to process, it will remove the graphics window and exit to the parent shell.
You can move forward in the file list by typing N (for next), and backward by typing P (for previous). Both take numeric arguments: 3N will move ahead 3 files, and Ctl-U P will move back 4 files.
If you want to terminate x79 before it has displayed all requested plots, move the cursor to the invoking terminal window, and type Ctl-C, or whatever your normal program interrupt character is.
x79 goes to consider trouble to provide fast display of plots. Use of backing store on the server, or in private memory when that is unavailable, was already noted above. When neither is possible, exposure events are handled by redrawing only those polylines that lie partially, or entirely, inside the minimal rectangle containing the exposed regions.
A minimal bounding box is maintained for each polyline to allow fast rejection of polylines that lie outside the visible window; this is particularly beneficial during zooming or panning.
For convenience, Tektronix graphics files are also recognized, provided that they start with the standard Tektronix screen clear command, ESC FF.
On the other hand, extensive experience with \*(Ps, which also uses text encoding, instead of binary, has demonstrated the considerable utility of such a format; it is much easier to debug, to transport from system to system via magnetic media, network transfer, or electronic mail, to produce with other programs, and to apply common UNIX filter tools to.
The code needed to read this data file represents less than 3% of the total in x79; it is therefore anticipated that support for other graphics file formats, such as Tektronix and HPGL, can be profitably, and without undue effort, added.
The x79 graphics commands are encoded one per input line. A sharp sign, #, marks a comment that continues to end of line; it may appear anywhere on a line, including after input data.
Numbers are encoded in free format, separated by whitespace. Blank lines, and unparsable text, are silently ignored. This provides a degree of downward compatibility; if the file format is later extended, new commands will be ignored, but old ones will still be recognized and processed.
Commands consist of a small integer operation code, followed by the required number of numeric arguments. The currently-supported commands are shown in the following table:
_________________________________________________________________ | Table 2: x79 graphics commands | |Command Opcode Operands | |initialize 1 xmin xmax ymin ymax size-in-cm | |terminate 2 | |absolute move 3 x y | |absolute draw 4 x y | |relative move 5 dx dy | |relative draw 6 dx dy | |define color 7 index red max-red green max-green blue max-blue| |select color 8 index | |set linewidth 9 width-in-dots | |_______________________________________________________________|
Normally, the first command will be an initialize, and the last one a terminate. However, any command may precede the initialize, which serves only to define the extents of the world coordinate system. Because all commands are collected before any plotting is carried out, the initialize can in fact come anywhere, and could even be omitted, since the actual extents of the plot are computed as the data is processed, and the actual limits would be used in place of those from the initialize command. The coordinates on move and draw commands are arbitrary integer values; they are scaled into a rectangular region according to the extents from the initialize command, and that region is then mapped onto an X window, preserving the aspect ratio.
Even though the \*(Xw is currently implemented on screen displays having resolution only up to about 2000 pixels, it is advantageous to provide higher precision in the input data to preserve accuracy during zoom operations. The PLOT79 ptXlib library accordingly uses coordinate ranges of 0 .. +32767.
The terminate command must of course come last; it tells x79 that there is no more data. An explicit command for this purpose is required, since it is anticipated that future versions of x79 will support data arriving asynchronously through a network connection, or a pipe, where detection of a true end-of-file indication may be inconvenient. See the -interactive switch description for more details.
A polyline is defined as a move command followed by one or more draw commands. A polyline is terminated by the arrival of another move, or by a line width or color change. The latter apply to all following polylines, until they are overridden by subsequent line width or color selections.
Coordinates may be in absolute integer values, or relative to the current point established by the last move or draw command. Relative coordinates are often useful in reducing the data volume, and the PLOT79 ptXlib library uses them for all draw commands.
The define color command specifies a color index in the range 0 .. 255 (a limit that can easily be increased), [TO DO: make color limit a resource setting] matching the limits of most low-end color workstations, together with the red, green, and blue color components, expressed as ratios of adjacent pairs.
The \*(Xw uses 16-bit color specifications internally, so ranges of 0 .. 65535 are the widest usefully resolvable, and that is what the PLOT79 library selects. Output from a 3-plane color system would probably set the color denominators to 8.
Normally, each color will be defined only once; later redefinitions will override earlier ones, since the complete set of input color specifications is collected before plotting begins. [This is not strictly true in the -interactive case, since only part of the file may have been read when plotting begins.]
Because the \*(Xw supports multiple color windows whose color demands may conflict, it views color as a resource that can be requested, but not necessarily supplied. The workstation's set of possible colors (usually 256, except on more expensive systems) is managed as a pool for all windows; a request for a specific color from a particular window will be mapped to that color, provided that an unused color table slot is available. Otherwise, the closest available color is supplied instead. Thus, depending on what colors are already in use, you may get somewhat different colors from the same input data on different runs. This is a feature of the \*(Xw; it is not a bug in x79!
The select color command chooses a color for subsequent plotting; the color should have been previously defined by a define color command; otherwise, you will get whatever color happens to be in the requested color table slot. Select color completes any polyline being collected, and takes effect with the next polyline.
The set linewidth command sets the line width in pixels for subsequent drawing operations, and also completes any open polyline.
The convention of the \*(Xw is that a line width of zero means a line one pixel wide, drawn by the fastest method the hardware and software can support. Line widths of one or more carry certain restrictions that may require slower implementations. x79 assumes line width zero unless instructed otherwise, because for graphics, speed is often of critical concern.
The PLOT79 ptXlib library and tkvecs(1) each produce about 25 lines of initial comments that document the file format, in the interests of making it possible to parse the data after you have forgotten just where all those numbers came from, or what they represent. The comments also include the name of the program that created the file, the file name, the user name and host computer name, and a time stamp.
The first line in the file is a comment that has a rather special format to take advantage of a useful feature of UNIX command dispatching; it defines the name of the program to be run if the file is invoked as a command, and that program is given the rest of the file as its input. The format produced by PLOT79 therefore begins
#!/usr/local/plot79/x79and the graphics files produced by ptXlib and tkvecs(1) are given execute permission (on UNIX variants that make this possible). The graphics files are then self-executing; just type their name on the command line to have them displayed on your workstation; you do not even have to know how to run x79 to do so!
The \*(Xw is an imposing programming effort, representing over 2 million lines of code. The basic \*(Xw library, libX11.a, contains over 1000 external names. On top of this are the X Toolkit library, libXt.a, (800+ externals), the Athena Widget library, libXaw.a, (550+ externals), the X extensions library, libXext.a, (300+ externals), and the miscellaneous utilities library, libXmu.a, (180+ externals).
These more than 3000 routines, and an additional 3500+ access macros defined in C header files, are still not enough to provide a complete windows programming interface! They only form the core of the \*(Xw that all workstation vendors offer. Prior to release 4 of X version 11 in January 1990, the toolkit library did not provide adequate support for the construction of menus, sliders, dials, and other widgets, as they have come to be called.
Instead, several widget libraries have been developed: the X11R4 Athena widget library from Project Athena at MIT (a joint effort of MIT, DEC, and IBM), Open Look/XView from AT&T and Sun, and OSF/Motif (offered by DEC and IBM). Several complete books have been written about each of these libraries.
It is the widget libraries which provide the distinctive look and feel of the windows that the application creates. The problem for a program such as x79, which must be portable across all vendor architectures, is that none of this widget support is universally available. The Athena widgets are attractive, since all vendors should offer them; however, support is available only at X11R4, and all vendor-supported implementations (in early 1991) are still at X11R3. The XView implementation of the Open Look specification is publicly available, but is vendor-supported only on Sun systems. OSF/Motif is a commercial product that is not publicly available; it is licensed for a fee.
Eventually, it may be necessary to provide support in x79 for all three environments, but because of the size of the libraries involved, it will require a very large learning effort to do so.
An easier task is to add support for resources, so that xrdb(1) and .Xresources or .Xdefaults files can be used to modify the default behavior of x79. Resource support is described in the next section.
When compiled with one of the available toolkit support options, x79 recognizes all standard \*(Xw command-line arguments and resources. If you wish to customize x79, the simplest thing to do is to run it with the -dumpresources option, capture the output in a file, and then modify it as desired. Under X11R4, you can also use the appres(1) utility to obtain the same information. You can then install the settings in your .Xdefaults file.
The \*(Xw apparently has no way of recovering color names once they have been converted to color values, so the dumped colors are recorded as hexadecimal strings. A similar problem exists with cursor names. In both cases, hand editing will be desirable.
Here is a list of all the resource settings recognized by x79:
_______________________________________________________________________ |_____________________________________________________________________| |Option Resource Class Default Value | |_____________________________________________________________________| |-background background Background "XtDefaultBackground"| |-bg background Background "XtDefaultBackground"| |-backingpixmap backingPixmap Boolean "TRUE" | |-backingstore backingStore Boolean "TRUE" | | capStyle String "CapRound" | | cursor Cursor "dotbox" | |-cr cursorColor Color "XtDefaultForeground"| | cursorBackColor Color "XtDefaultBackground"| |-debug debug Value 0 | |-dumpresources dumpResources Boolean "FALSE" | |-exactcolormap exactColormap Boolean "FALSE" | | fillStyle String "FillSolid" | |-foreground foreground Foreground "XtDefaultForeground"| |-fg foreground Foreground "XtDefaultForeground"| |-geometry geometry Geometry | |= geometry Geometry | | height Height 256 | | iconGeometry IconGeometry | | iconName IconName | | joinStyle String "JoinRound" | | lineStyle String "LineSolid" | | maxHeight MaxHeight 32767 | | maxWidth MaxWidth 32767 | | minHeight MinHeight 5 | | minWidth MinWidth 5 | |-interactive interactive Boolean "FALSE" | |-ms pointerColor Color "XtDefaultForeground"| |-quiet quiet Boolean "FALSE" | |-remap remap String | |-reverse reverseVideo ReverseVideo "FALSE" | |-linewidth thickness Thickness 0 | |-lw thickness Thickness 0 | |-T title Title "X79" | |-title title Title "X79" | | width Width 256 | | x X 0 | | y Y 0 | | zoomBig Value 1.5 | |_____________________________________________________________________|
Note that some of these can only be set in a resource file; no command-line option exists.
! Sample x79 defaults file. ! ! All resources recognized by x79 are given here, together ! with short comments. They are in alphabetical order for ! convenience only; any order is acceptable, and later ! redefinitions override earlier ones. ! ! Blank lines can appear anywhere, and comments, like this ! one, run from an exclamation point to end of line. Long ! strings can be continued on multiple lines with a ! backslash-newline pair which is discarded when the input ! is read. ! ! Letter case in resource names is SIGNIFICANT. The X ! Window System convention is that multiword resource names ! have all but the first word capitalized. However, letter ! case in Boolean values and color names does not matter. ! Multiword color names should be collapsed into a single ! word. X79.background: Black X79.backingPixmap: TRUE X79.backingStore: TRUE X79.capStyle: CapRound ! You can use any cursor found in the standard list given in ! /usr/include/X11/cursorfont.h; just delete the initial XC_ ! prefix to get the name to use here. X79.cursor: dotbox X79.cursorBackColor: Black X79.cursorColor: White X79.debug: 0 X79*dumpResources: FALSE X79.exactColormap: FALSE X79.fillStyle: FillSolid X79.foreground: White ! No default geometry is set; instead, default width, ! height, x, and y are given. A command-line -geometry ! switch will override them. X79.geometry: X79.height: 256 X79.iconGeometry: 32x32 X79.iconName: X79 X79.interactive: FALSE X79*joinStyle: JoinRound X79.lineStyle: LineSolid ! You can constrain the size range of plots by setting these ! four limits X79.maxHeight: 32767 X79.maxWidth: 32767 X79.minHeight: 5 X79.minWidth: 5 X79.quiet: FALSE ! Remap the first 7 colors to those of the rainbow. ! Remember the order from our childhood friend Roy G. Biv ! (Red orange yellow Green. Blue indigo violet). The ! standard color data base file, rgb.txt, doesn't have ! indigo, so we use blueviolet instead. X79.remap: 0 Red 1 orange 2 yellow \ 3 Green \ 4 Blue 5 blueviolet 6 violet X79.reverseVideo: FALSE ! Thickness is the default line width for polyline plotting A ! value of 0 gives fastest plotting X79.thickness: 0 X79.title: New X79 X79.width: 256 X79.x: -5 X79.y: -10 X79.zoomBig: 1.5 X79.zoomSmall: 1.1
Center for Scientific Computing
Department of Mathematics
University of Utah
Salt Lake City, UT 84112
Tel: +1 801 581 5254
FAX: +1 801 581 4148
E-mail: <beebe@math.utah.edu>