v15i069: Graphics benchmark toolkit for X, Part02/02

Rich Salz rsalz at bbn.com
Tue Jun 14 05:36:14 AEST 1988


Submitted-by: Craig Dunwoody <dunwoody at lurch.stanford.edu>
Posting-number: Volume 15, Issue 69
Archive-name: gbench/part02

#! /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 2 (of 2)."
# Contents:  gbench.man ops.c
# Wrapped by rsalz at fig.bbn.com on Mon Jun 13 15:32:52 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'gbench.man' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'gbench.man'\"
else
echo shar: Extracting \"'gbench.man'\" \(17835 characters\)
sed "s/^X//" >'gbench.man' <<'END_OF_FILE'
X.TH GBENCH 1 "1 March 1988" "InterViews" "InterViews Reference Manual"
X.SH NAME
Xgbench \- graphics benchmark
X.SH SYNOPSIS
X\fBgbench\fP [-\fIcommandname\fP [\fIparameters\fP]]*
X.SH DESCRIPTION
X\fIgbench\fP is a graphics benchmark tool.  It currently supports 2D
Ximmediate-mode graphics and runs on top of the X Window System, both Version 10
Xand Version 11.  It is written in C and it directly calls the low-level window
Xsystem client library; no toolkit is used.
X.PP
XWhen \fIgbench\fP starts, it creates a window and begins processing
Xcommands.  You may supply any number of commands as arguments to the
Xprogram.  Once these commands have been processed, commands are read from
Xstandard input, one per line.  Each command directs \fIgbench\fP to
Xrepeatedly perform a particular drawing operation.  \fIgbench\fP copies the
Xcommand to the outfile (default:  standard output), executes the command,
Xand prints on the outfile the host load average, the time for each
Xiteration, and the number of iterations per second.
X.PP
XAll times are measured in real (wall-clock) time.  You should establish that
Xthe host(s) and network (if used) are unloaded so that valid numbers may be
Xobtained.
X.PP
XWhen \fIgbench\fP performs a sequence of drawing operations, each operation
Xis shifted by one pixel in x and y from the previous one.  This shifting
Xgoes back and forth over a user-definable range (default: 32 pixels), the
Xintent being to average out the effects of pixel alignment in the frame
Xbuffer.  Pixel alignment can affect the performance of many graphics
Xsystems, both low-end memory-mapped frame buffers and high-end systems with
Xinterleaved pixel processors.
X.PP
XYou can use \fIgbench\fP either interactively, by typing
Xcommands and viewing the results immediately, or in batch mode,
Xwith standard input redirected to a script file and output
Xredirected to a log file.  To avoid cluttering up the log when
Xoutput is redirected to a file, certain outputs that are only useful in
Xinteractive use are directed to standard error rather than the outfile.
X.PP
X\fBCommands\fP
X.PP
XEach command consists of a command name followed by zero or more optional
Xparameters separated by white space.  You may abbreviate command names to
Xtheir smallest unique prefix.  Ambiguous command names are resolved to the
Xfirst matching name.  Any command name may be prefixed with the @ character,
Xwhich forces all output from the command to standard error rather than
Xthe outfile.  This is useful for preventing selected commands from
Xgoing into a log file.
X.PP
XThe optional parameters consist of zero or more positional parameters of the
Xform \fIvalue\fP, followed by zero or more keyword parameters of the form
X\fIname\fP=\fIvalue\fP.  Each positional parameter has a name and may be
Xspecified in keyword form as well.  The positional form is more convenient
Xfor interactive input, while the keyword form is more suited for creating
Xself-documenting script files.
X.PP
XTo provide values for parameters that are not specified in a command,
X\fIgbench\fP maintains a set of global defaults that may be displayed and
Xchanged using the 'default' command.  Each default value has a name and may
Xbe overridden in a command using a \fIname\fP=\fIvalue\fP parameter.
XThe names of all global default values are given below.  The
X'init' command restores all global defaults to their initial values.
X.PP
XThe first positional parameter for each command is \fIopts\fP.  It is a
Xcomma-separated list of option flags, the meanings of which are described
Xbelow.  Option flags may be supplied in any order.  If the \fIopts\fP
Xparameter is given in positional form, the global default option list is
Xprepended to the given list; if it is given in keyword form, the given
Xlist is used as is, overriding the global default option list.
X.PP
XThe commands are:
X.TP
Xarc [\fIopts\fP] [\fIsize\fP] [\fIaspect\fP] [\fIangle\fP] [\fIlwidth\fP] [\fIname\fP=\fIvalue\fP]*
XDraws an arc of an ellipse.  The ellipse is drawn in a bounding box with an
Xarea of \fIsize\fP squared pixels and a height/width ratio of \fIaspect\fP.
XThe default value of \fIaspect\fP is 1.0, yielding a circular arc.
XThe arc begins at the 3 o'clock position and continues counterclockwise for
X\fIangle\fP degrees.  This command works only in the X11 version.
X.TP
Xblit [\fIopts\fP] [\fIsize\fP] [\fIoffset\fP] [\fIname\fP=\fIvalue\fP]*
XCopies a square area of the window, \fIsize\fP pixels on a side, to
Xan area offset by \fIoffset\fP*\fIsize\fP pixels.  The default value for
X\fIoffset\fP is 0.5.
X.TP
Xmap [\fIopts\fP] [\fIsize\fP] [\fInwin\fP] [\fIname\fP=\fIvalue\fP]*
XMaps and then unmaps \fInwin\fP square subwindows, each \fIsize\fP
Xpixels on a side.
X.TP
Xnop [\fIopts\fP] [\fIname\fP=\fIvalue\fP]*
XPerforms a window server no-op.  This command works only in the X11 version.
X.TP
Xpoint [\fIopts\fP]
XDraws a point.  This command works only in the X11 version.
X.TP
Xpoly [\fIopts\fP] [\fIsize\fP] [\fInvert\fP] [\fIlwidth\fP] [\fIname\fP=\fIvalue\fP]*
XDraws a polygon with the specified number of vertices and linewidth,
Xinscribed in a circle of radius \fIsize\fP pixels.
X.TP
Xrect [\fIopts\fP] [\fIsize\fP] [\fIlwidth\fP] [\fIname\fP=\fIvalue\fP]*
XDraws an axis-aligned square, \fIsize\fP pixels on a side, with the specified
Xlinewidth.
X.TP
Xtext [\fIopts\fP] [\fInchar\fP] [\fIptsize\fP] [\fIname\fP=\fIvalue\fP]*
XDraws a text string with the specified number of characters, at the
Xspecified point size.  The closest available point size is chosen.
X.TP
Xvec [\fIopts\fP] [\fIsize\fP] [\fIangle\fP] [\fIlwidth\fP] [\fIname\fP=\fIvalue\fP]*
XDraws a vector \fIsize\fP pixels long, with the specified linewidth and
Xangle (given in degrees counterclockwise from the 3 o'clock position).
X.TP
Xconfig
XPrints the host name, display name, window system version, current time,
Xand tag (see below) on the outfile.
X.TP
Xdefaults [\fIname\fP=\fIvalue\fP]*
XPrints the defaults on standard error and optionally changes them.  The
Xnames of the default values are given below.
X.TP
Xhelp
XPrints a help message on the outfile listing the available commands and
Xoption flags.
X.TP
Xinit
XRestores all defaults to their initial value, and prints the updated
Xset of values on standard error.
X.TP
Xscript [\fIfilename\fP]
XRun the given script file, which may itself use the 'script' command.  If
Xno file is given, the built-in script is run.
X.TP
Xquit
XExits \fIgbench\fP.
X.TP
X!
XRepeat:  Re-issue the previous drawing command, with parameters defaulting
Xto the values used when that command was executed, rather than to the global
Xdefault values.  Positional and keyword parameters for the command may be
Xgiven in the normal manner to override the defaults.  As usual, if the
X\fIopts\fP parameter is given in positional form, the default option
Xlist is prepended to the given list, whereas if it is given in keyword
Xform, the given list overrides the default option list.
X.TP
X#
XComment:  causes \fIgbench\fP to write the rest of the command to
Xthe outfile. This is useful for putting comments in script files.  After
Xechoing and executing each command, \fIgbench\fP writes a result line
Xto the outfile.  Since each result line begins with the comment
Xcharacter, \fIgbench\fP output logs are also valid \fIgbench\fP input
Xscripts.  You can run a log through \fIgbench\fP several times using
Xdifferent hardware configurations.  In the resulting log, each command
Xwill be followed by a series of result lines, one for each configuration.
X.PP
X\fBOptions\fP
X.PP
XThe option flags are as follows:
X.TP 8
Xac
XAlternate the drawing color between black and white on each drawing
Xoperation.  This measures the effect of changing one element of the
Xgraphics state for each drawing operation.
X.TP
Xaf
XUse a separate text item, with its own font identifier, for each character
Xin the 'text' command.  The same font is used for all characters.  This
Xoption works only in the X11 version.
X.TP
Xag
XAlternate the graphics context on each drawing operation.  The two graphics
Xcontexts used are identical except that one draws with white and the other
Xdraws with black.  The ac and ag flags can be used to compare the cost of
Xchanging one element of the graphics state with the cost of swapping the
Xentire graphics state.
X.TP
Xaw
XAlternate windows on each drawing operation.  This flag makes it possible
Xto measure the performance impact of context-switching between windows.
XIt is important to keep this overhead low in order to support applications
Xthat do real-time drawing in multiple windows simultaneously.
X.TP
Xd
XDragging.  You are prompted to move the mouse around in the window while
Xholding down a mouse button.  Every time a mouse motion event is received,
X\fIgbench\fP draws a background-color rectangle to erase the results of the
Xprevious drawing operations, then performs one drawing iteration.  This
Xoption allows you to measure the frame rate that the system can achieve
Xduring interactive animation.
X.TP
Xf
XFill the arc, polygon, or rectangle with a solid color.
X.TP
Xi
XDraw by inverting pixel values rather than painting.  This measures
Xthe additional cost of reading pixels from the frame buffer before writing.
X.TP
Xm
XMonitor for profiling.  Profiling information is accumulated while this
Xcommand is executing.  If \fIgbench\fP has been compiled and linked for
X\fIgprof\fP profiling, this information is written to the file "gmon.out"
Xin the current directory when \fIgbench\fP exits.
X.TP
Xn
XNo options.  If you choose no options and you supply \fIopt\fP as
Xa positional parameter, you must use the n flag as a placeholder.
X.TP
Xo
XOverlap the object being drawn with a very small window.  The overlapping
Xwindow is made small to avoid a significant change in the number of pixels
Xdrawn.  This measures the cost of clipping.
X.TP
Xos
XUse an offscreen pixel map identical in size and depth to the graphics window
Xas the source for blits.  This option works only in the X11 version.
X.TP
Xod
XUse an offscreen pixel map identical in size and depth to the graphics window
Xas the destination for drawing operations.  After the command has been
Xcompleted and timed, the contents of the offscreen pixel map are blitted
Xinto the graphics window so correct drawing can be verified.  This option
Xworks only in the X11 version.  Together, the os and od options allow you
Xto measure the performance impact of offscreen rendering and the cost
Xof moving pixels to and from offscreen memory.
X.TP
Xp
XPolling.  Used in conjunction with the d flag, this flag specifies that
X\fIgbench\fP should loop continuously, reading the mouse position and
Xperforming a drawing iteration, rather than responding to mouse motion
Xevents.  This measures the performance difference between polling and
Xevent-driven input.
X.TP
Xps
XPolygon self-intersecting.  Draw a polygon with the same vertices and number
Xof edges as usual, but self-intersecting.  \fInvert\fP will be rounded up
Xto an odd number if necessary.
X.TP
Xpw
XFill polygons using the non-zero winding number rule rather than the
Xdefault even-odd rule.  This option works only in the X11 version.
X.TP
Xr
XReset defaults.  Copy the set of parameters used in this command to the
Xset of global defaults.
X.TP
Xs
XUse a stipple pattern when drawing.  The stipple pattern is a bitmap that is
Xtessellated over the drawing area.  When a drawing operation is performed,
Xthe only pixels that are actually drawn are those inside the shape being
Xdrawn that correspond to a '1' in the stipple pattern.  These pixels are
Xdrawn in the foreground color.  Stippling is fully supported only in the X11
Xversion.
X.TP
Xt
XUse a tile when drawing.  The tile is a pixel map that is tessellated over
Xthe drawing area.  When a drawing operation is performed, the pixel value
Xfor each pixel inside the shape being drawn is obtained from the tile.
XWhen the s and t flags are used simultaneously, the stipple pattern is used
Xas a tile, with '0' pixels in the stipple pattern selecting the background
Xcolor and '1' pixels selecting the foreground color.  This combination works
Xonly in the X11 version.
X.TP
Xu
XUnbatched.  Normally the window system client library will batch many
Xrequests into a single message to the window server in order to minimize
Xcommunication overhead.  This option causes the client's request buffer
Xto be flushed after each operation, thereby preventing batching.  This
Xmakes it possible to directly measure the performance benefit of batching.
X.PP
X\fBGlobal defaults\fP
X.PP
XThe following global defaults may be displayed and set using the 'defaults'
Xcommand:
X.TP 8
Xtimegoal
XWhen a command is executed, \fIgbench\fP should repeat the drawing
Xoperation under test enough times to get an accurate measurement of its
Xcost, but not so many times that the command takes an inordinate amount of
Xtime to execute.  \fIgbench\fP allows you to specify a time goal, which
Xis the number of seconds that each command should take to execute (default:
X1).  \fIgbench\fP performs as many iterations as are necessary to reach
Xthis goal.  Setting timegoal to 0 forces \fIgbench\fP to execute a
Xsingle iteration.
X.TP
Xcount
XSpecifies the number of times to perform the primitive drawing operation
Xon \fIeach\fP iteration.  This defines the unit of work being measured.
XFor example, to measure the time it takes to draw a 1000-polygon object,
Xgive the command 'p count=1000' and \fIgbench\fP will repeatedly draw
X1000 polygons.  To get the feel of dragging around a 1000-polygon object,
Xgive the command 'p d count=1000' and \fIgbench\fP will draw 1000 polygons
Xevery time the mouse moves.  If you want exact control over the number
Xof drawing operations executed for each command, set \fItimegoal\fP to 0
Xand set \fIcount\fP as desired.
X.TP
Xangle
XThe angle in degrees used for the 'arc' and 'vec' commands.
X.TP
Xaspect
XA floating point value representing the height to width ratio of the
Xbounding box for the 'arc' command.  The default value is 1.0, which
Xyields circular arcs.
X.TP
Xfont
XA comma-separated list of font names for \fIgbench\fP to load.
XIn the X11 version, each name may contain the wild-card characters * and ?.
XA maximum of 16 fonts may be loaded.
X.TP
Xptsize
XThe font size, given in points, used in the 'text' command.
X.TP
Xlwidth
XThe line width used in the drawing operations.
X.TP
Xmaxshift
XEach drawing operation is shifted by one pixel in x and y from the previous
Xoperation.  The shifting goes back and forth over a range of \fImaxshift\fP
Xpixels.
X.TP
Xoffset
XThe 'blit' command multiplies the size of the square being blitted by this
Xfloating point value to determine how far to move it.  The default value
Xis 0.5, which causes the destination square to overlap the source square.
X.TP
Xnchar
XThe length in characters of the string drawn by the 'text' command.
X.TP
Xnwin
XThe number of windows mapped by the 'map' command.
X.TP
Xnvert
XThe number of vertices drawn by the 'poly' command.
X.TP
Xopts
XThe option list that is prepended to the option list that is given as
Xthe first positional parameter of a command.  It can be used to run scripts
X(including the built-in script) with different lists of options.
X.TP
Xoutfile
XThe name of the file that output is appended to (default:  standard output).
X.TP
Xsize
XThe size in pixels of the objects drawn by the various drawing commands.
X.TP
Xtag
XAn uninterpreted string that is included in the output of the 'config'
Xcommand and at the beginning of each result line.  It is useful for
Xassociating each result line with a named configuration when a log file is
Xrun through \fIgbench\fP several times to accumulate result lines for
Xdifferent configurations.  For example:
X
Xgbench - at d tag=configname <oldlog >newlog
X
XNote the use of the '@' on the 'defaults' command to prevent the tag-setting
Xcommand from going into the log.  A suggested tag format is a quadruple of
Xthe form
X
X<\fIrcpu\fP>.<\fIlcpu\fP>.<\fIwsys\fP>.<\fIgxsys\fP>
X
Xwhere \fIrcpu\fP is the type of the remote CPU running \fIgbench\fP (if any),
X\fIlcpu\fP is the type of the local CPU running the window server, \fIwsys\fP
Xis the name of the window system, and \fIgxsys\fP is the type of graphics
Xhardware being used.  Each of these components can be encoded in two or three
Xcharacters.
X.TP
Xwinsize
XThe edge length (in pixels) of the square drawing window.
X.SH VERSION
XThis documentation applies to Version 1.0 of \fIgbench\fP.
X.SH BUGS
XThere is apparently a bug in the beta release of the awm window manager
Xfor X11R2 that causes the "map" command to hang \fIgbench\fP.  For this
Xreason, we have removed "map" from the default script.  We have not
Xfound this problem under any of the other X11R2 window managers, including
Xthe standard uwm.
X.SH EXTENSIONS
XDifferent drawable depths should be supported.  3D graphics and image
Xprocessing operations should be supported when they become available.
XFilters should be written to combine and format raw log files.
X.SH AUTHOR
X\fIgbench\fP is being developed by Craig Dunwoody and Mark Linton at Stanford
XUniversity's Computer Systems Lab under the Quantum project, through a gift
Xfrom Digital Equipment Corporation.
X.SH ADDRESS
XPlease send any comments, bugfixes, scripts, or results to:
X
XInternet: gbench at lurch.stanford.edu
X
XUSEnet:   {ucbvax,decvax}!decwrl!lurch.stanford.edu!gbench
X
X.SH COPYRIGHT
X Copyright (c) 1988 by The Board of Trustees
X of the Leland Stanford Junior University.
X
X Permission to use, copy, modify, and distribute this
X software and its documentation for any purpose and without
X fee is hereby granted, provided that the above copyright
X notice appear in all copies and that both that copyright
X notice and this permission notice appear in supporting
X documentation, and that the name of Stanford not be used in
X advertising or publicity pertaining to distribution of the
X software without specific, written prior permission.
X
X Stanford makes no representations about the suitability of
X this software for any purpose.  The Software is provided "as is"
X without express or implied warranty.
END_OF_FILE
if test 17835 -ne `wc -c <'gbench.man'`; then
    echo shar: \"'gbench.man'\" unpacked with wrong size!
fi
# end of 'gbench.man'
fi
if test -f 'ops.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ops.c'\"
else
echo shar: Extracting \"'ops.c'\" \(10777 characters\)
sed "s/^X//" >'ops.c' <<'END_OF_FILE'
X#include <gbench.h>
X
Xvoid StartArc(sp,cp)
X    State*  sp;
X    Cmd*    cp;
X{
X    double  adjust;
X    int	    area = cp->p.size*cp->p.size;
X    int	    origin;
X    double  theta;
X
X    cp->size[0] = sqrt(area/cp->p.aspect);
X    cp->size[1] = sqrt(area*cp->p.aspect);
X    if (cp->p.aspect!=1.) {
X	theta = cp->p.angle*Pi/180;
X	if (theta<(Pi/2)) adjust = 0.;
X	else if (theta<(3*Pi/2)) adjust = Pi;
X	else adjust = 2*Pi;
X	theta = atan(tan(theta)/cp->p.aspect)+adjust;
X	cp->size[2] = theta*180/Pi*64;
X    }
X    else cp->size[2] = cp->p.angle*64;
X    origin = Border+cp->p.lwidth;
X    cp->x = cp->y = Border;
X    cp->bbx = cp->size[0]+2*cp->p.lwidth;
X    cp->bby = cp->size[1]+2*cp->p.lwidth;
X    if (cp->o.fill) {
X	MoveClip(
X	    sp,cp,cp->x+cp->bbx/2-OverlapSize,cp->y+cp->bby/2-OverlapSize
X	);
X    }
X    else MoveClip(sp,cp,cp->x,cp->y+cp->bby/2);
X    Start(sp,cp);
X}
X
Xvoid DoArc(sp,cp)
X    State*  sp;
X    Cmd*    cp;
X{
X    int i;
X    int x = cp->x+cp->p.lwidth;
X    int y = cp->y+cp->p.lwidth;
X
X    for (i=0;i<cp->p.count;i++) {
X	StartIteration(sp,cp);
X#	ifdef X11
X	    if (cp->o.fill) {
X		XFillArc(
X		    sp->d,cp->dest,cp->gc,x,y,cp->size[0],cp->size[1],0,
X		    cp->size[2]
X		);
X	    }
X	    else {
X		XDrawArc(
X		    sp->d,cp->dest,cp->gc,x,y,cp->size[0],cp->size[1],0,
X		    cp->size[2]
X		);
X	    }
X#	endif X11
X    }
X}
X
Xvoid StartBlit(sp,cp)
X    State*  sp;
X    Cmd*    cp;
X{
X    Pixel   colorfg;
X    int	    i;
X
X    Start(sp,cp);
X    cp->bbx = cp->bby = 0;
X    colorfg = cp->colorfg;
X    MoveClip(sp,cp,Border+cp->p.size/2,Border+cp->p.size/2);
X    for (i=0;i<2;i++) {
X	StartIteration(sp,cp);
X#	ifdef X10
X	    XPixFill(
X		cp->w,Border,Border,cp->p.size,cp->p.size,colorfg,0,cp->func,
X		AllPlanes
X	    );
X#	else
X	    XFillRectangle(
X		sp->d,cp->src,sp->gc1,Border,Border,cp->p.size,cp->p.size
X	    );
X#	endif
X    }
X    cp->x = cp->y = Border;
X    cp->size[0] = cp->p.offset*cp->p.size;
X}
X
Xvoid DoBlit(sp,cp)
X    State*  sp;
X    Cmd*    cp;
X{
X    XEvent		    e;
X    int			    i;
X    XGraphicsExposeEvent*   xep;
X
X#   ifdef X10
X	xep = (XGraphicsExposeEvent*)&e;
X#   else
X	xep = &e.xgraphicsexpose;
X#   endif
X    for (i=0;i<cp->p.count;i++) {
X	StartIteration(sp,cp);
X#	ifdef X10
X	    XCopyArea(
X		cp->w,Border,Border,cp->x+cp->size[0],cp->y+cp->size[0],
X		cp->p.size,cp->p.size,cp->func,AllPlanes
X	    );
X	    if (cp->o.overlap) do {
X		XMaskEvent(ExposeRegion|ExposureMask,&e);
X		if (e.type==ExposeRegion) {
X		    XPixFill(
X			cp->w,xep->x,xep->y,xep->width,xep->height,cp->colorfg,
X			0,cp->func,AllPlanes
X		    );
X		}
X	    } while (e.type!=ExposureMask);
X#	else
X	    XCopyArea(
X		sp->d,cp->src,cp->dest,cp->gc,Border,Border,cp->p.size,
X		cp->p.size,cp->x+cp->size[0],cp->y+cp->size[0]
X	    );
X	    if (cp->o.overlap) do {
X		XMaskEvent(sp->d,ExposureMask,&e);
X		if (e.type==GraphicsExpose) {
X		    XFillRectangle(
X			sp->d,cp->dest,cp->gc,xep->x,xep->y,xep->width,
X			xep->height
X		    );
X		}
X	    } while ((e.type==GraphicsExpose)&&xep->count);
X#	endif
X    }
X}
X
Xvoid StartMap(sp,cp)
X    State*  sp;
X    Cmd*    cp;
X{
X    int	    wheight;
X    int	    i;
X    int	    ncols = _DisplayWidth/cp->p.size;
X#   ifdef X11
X        XSetWindowAttributes swa;
X#   endif X11
X
X    cp->x = cp->y = cp->bbx = cp->bby = 0;
X    cp->p.nwin = Limit(cp->p.nwin,1,ncols*_DisplayHeight/cp->p.size);
X    cp->o.altwin = false;
X    wheight = cp->p.size*(1+cp->p.nwin/ncols);
X    Start(sp,cp);
X    UnmapWin(sp,cp->w);
X    cp->w = XCreateSimpleWindow(
X	DARGC _RootWindow,0,0,_DisplayWidth,wheight,1,WhitePixmap,BlackPixmap
X    );
X    for (i=0;i<cp->p.nwin;i++) {
X	XCreateSimpleWindow(
X	    DARGC cp->w,cp->p.size*(i%ncols),cp->p.size*(i/ncols),cp->p.size,
X	    cp->p.size,1,WhitePixmap,BlackPixmap
X	);
X    }
X#   ifdef X11
X        swa.override_redirect = 1;
X        XChangeWindowAttributes(sp->d,cp->w,CWOverrideRedirect,&swa);
X#   endif X11
X    XRaiseWindow(DARGC cp->w);
X    XMapWindow(DARGC cp->w);
X    XSelectInput(DARGC cp->w,InputMask(cp));
X}
X
Xvoid DoMap(sp,cp)
X    State*  sp;
X    Cmd*    cp;
X{
X    int i;
X
X    for (i=0;i<cp->p.count;i++) {
X	XMapSubwindows(DARGC cp->w);
X	XUnmapSubwindows(DARGC cp->w);
X    }
X}
X
Xvoid FinishMap(sp,cp)
X    State*  sp;
X    Cmd*    cp;
X{
X    Finish(sp,cp);
X    XUnmapWindow(DARGC cp->w);
X    XDestroyWindow(DARGC cp->w);
X    cp->w = sp->w1;
X    MapWin(sp,cp->w);
X    XFlush(DARG);
X}
X
Xvoid DoNop(sp,cp)
X    State*  sp;
X    Cmd*    cp;
X{
X    int	i;
X
X#   ifdef X11
X	for (i=0;i<cp->p.count;i++) XNoOp(sp->d);
X#   endif X11
X}
X
Xvoid StartPoint(sp,cp)
X    State*  sp;
X    Cmd*    cp;
X{
X    cp->x = cp->y = Border;
X    cp->bbx = cp->bby = 1;
X    MoveClip(sp,cp,cp->x,cp->y);
X    Start(sp,cp);
X}
X
Xvoid DoPoint(sp,cp)
X    State*  sp;
X    Cmd*    cp;
X{
X    int i;
X    
X#   ifdef X11
X	for (i=0;i<cp->p.count;i++) {
X	    StartIteration(sp,cp);
X	    XDrawPoint(sp->d,cp->dest,cp->gc,cp->x,cp->y);
X	}
X#   endif
X}
X
Xvoid StartPoly(sp,cp)
X    State*  sp;
X    Cmd*    cp;
X{
X    int	    fillrule;
X    int	    i;
X    int	    index;
X    int	    origin = Border+cp->p.lwidth;
X    int	    r = cp->p.size/2;
X    double  theta;
X
X    if (cp->o.polyself) cp->p.nvert = cp->p.nvert/2*2+1;
X    theta = 2*Pi/cp->p.nvert;
X    cp->x = cp->y = Border;
X    cp->bbx = cp->bby = cp->p.size+2*cp->p.lwidth;
X    for (i=0;i<=cp->p.nvert;i++) {
X	index = cp->o.polyself?(i*(cp->p.nvert/2))%cp->p.nvert:i;
X	sp->v[i].x = origin+r*(1+cos(PolyAngle+index*theta));
X	sp->v[i].y = origin+r*(1-sin(PolyAngle+index*theta));
X    }
X#   ifdef X10
X	sp->v[0].flags = VertexStartClosed;
X	for (i=1;i<cp->p.nvert;i++) sp->v[i].flags = 0;
X	sp->v[cp->p.nvert].flags = VertexEndClosed;
X#   else
X	fillrule = cp->o.polywind?WindingRule:EvenOddRule;
X	XSetFillRule(sp->d,sp->gc1,fillrule);
X	XSetFillRule(sp->d,sp->gc2,fillrule);
X#   endif
X    if (cp->o.fill) MoveClip(sp,cp,cp->x+r,cp->x+r);
X    else MoveClip(sp,cp,sp->v[0].x,sp->v[0].y);
X    Start(sp,cp);
X}
X
Xvoid DoPoly(sp,cp)
X    State*  sp;
X    Cmd*    cp;
X{
X    int i;
X#   ifdef X11
X	int shape = cp->o.polyself?Complex:Convex;
X#   endif X11
X
X    MoveVert(sp,cp,cp->p.nvert);
X    for (i=0;i<cp->p.count;i++) {
X	StartIteration(sp,cp);
X#	ifdef X10
X	    X10Draw(sp,cp,cp->p.nvert+1);
X#	else
X	    if (cp->o.fill) {
X		XFillPolygon(
X		    sp->d,cp->dest,cp->gc,sp->v,cp->p.nvert,shape,
X		    CoordModeOrigin
X		);
X	    }
X	    else {
X		XDrawLines(
X		    sp->d,cp->dest,cp->gc,sp->v,cp->p.nvert+1,CoordModeOrigin
X		);
X	    }
X#	endif
X    }
X}
X
Xvoid StartRect(sp,cp)
X    State*  sp;
X    Cmd*    cp;
X{
X    int i;
X    int origin = Border+cp->p.lwidth;
X
X    cp->x = cp->y = Border;
X    cp->bbx = cp->bby = cp->p.size+2*cp->p.lwidth;
X#   ifdef X10
X	for (i=0;i<5;i++) {
X	    sp->v[i].x = origin;
X	    sp->v[i].y = origin;
X	}
X	sp->v[1].x += cp->p.size;
X	sp->v[2].x += cp->p.size;
X	sp->v[2].y += cp->p.size;
X	sp->v[3].y += cp->p.size;
X	sp->v[0].flags = VertexStartClosed;
X	for (i=1;i<4;i++) sp->v[i].flags = 0;
X	sp->v[4].flags = VertexEndClosed;
X#   endif X10
X    if (cp->o.fill) MoveClip(sp,cp,cp->x+cp->bbx/2,cp->y+cp->bby/2);
X    else MoveClip(sp,cp,cp->x,cp->y);
X    Start(sp,cp);
X}
X
Xvoid DoRect(sp,cp)
X    State*  sp;
X    Cmd*    cp;
X{
X    int	i;
X    int x = cp->x+cp->p.lwidth;
X    int y = cp->y+cp->p.lwidth;
X
X#   ifdef X10
X    if (!cp->o.fill) MoveVert(sp,cp,5);
X#   endif X10
X    for (i=0;i<cp->p.count;i++) {
X	StartIteration(sp,cp);
X#	ifdef X10
X	    if (cp->o.fill) {
X		if (cp->o.tile) {
X		    XTileFill(
X			cp->w,x,y,cp->p.size,cp->p.size,sp->tile,0,cp->func,
X			AllPlanes
X		    );
X		}
X		else {
X		    XPixFill(
X			cp->w,x,y,cp->p.size,cp->p.size,cp->colorfg,0,cp->func,
X			AllPlanes
X		    );
X		}
X	    }
X	    else X10Draw(sp,cp,5);
X#	else
X	    if (cp->o.fill) {
X		XFillRectangle(
X		    sp->d,cp->dest,cp->gc,x,y,cp->p.size,cp->p.size
X		);
X	    }
X	    else {
X		XDrawRectangle(
X		    sp->d,cp->dest,cp->gc,x,y,cp->p.size,cp->p.size
X		);
X	    }
X#	endif
X    }
X}
X
Xvoid StartText(sp,cp)
X    State*  sp;
X    Cmd*    cp;
X{
X    int findex = FontIndex(sp,&cp->p.ptsize);
X    int	i;
X
X    cp->x = cp->y = Border;
X    Start(sp,cp);
X    if (findex<0) {
X	cp->p.ptsize = 0;
X	cp->fontid = nil;
X	cp->bbx = cp->bby = 0;
X	cp->result = NoFonts;
X    }
X    else {
X#	ifdef X10
X	    cp->p.ptsize = sp->fontinfo[findex]->height;
X	    cp->fontid = sp->fontinfo[findex]->id;
X	    cp->bbx = cp->p.nchar*sp->fontinfo[findex]->width;
X	    cp->bby = sp->fontinfo[findex]->height;
X#	else
X	    cp->p.ptsize = sp->fontinfo[findex]->ascent;
X	    XSetFont(sp->d,sp->gc1,sp->fontinfo[findex]->fid);
X	    XSetFont(sp->d,sp->gc2,sp->fontinfo[findex]->fid);
X	    cp->fontid = sp->fontinfo[findex]->fid;
X	    cp->size[0] = sp->fontinfo[findex]->max_bounds.ascent;
X	    cp->bbx = cp->p.nchar*sp->fontinfo[findex]->max_bounds.width;
X	    cp->bby = cp->size[0]+sp->fontinfo[findex]->max_bounds.descent;
X	    if (cp->o.altfont) for (i=0;i<cp->p.nchar;i++) {
X		sp->texts[i].font = cp->fontid;
X	    }
X#	endif
X    }
X    MoveClip(sp,cp,cp->x+cp->bbx/2,cp->y+cp->bby/2);
X}
X
Xvoid DoText(sp,cp)
X    State*  sp;
X    Cmd*    cp;
X{
X    int	i;
X
X    if (cp->result==NoFonts) return;
X    for (i=0;i<cp->p.count;i++) {
X	StartIteration(sp,cp);
X#	ifdef X10
X	    if (cp->o.tile) {
X		XTextPad(
X		    cp->w,cp->x,cp->y,sp->outstr,cp->p.nchar,cp->fontid,0,0,
X		    cp->colorfg,cp->colorbg,cp->func,AllPlanes
X		);
X	    }
X	    else {
X		XTextMaskPad(
X		    cp->w,cp->x,cp->y,sp->outstr,cp->p.nchar,cp->fontid,0,0,
X		    cp->colorfg,cp->func,AllPlanes
X		);
X	    }
X#	else
X	    if (cp->o.altfont) {
X		XDrawText(
X		    sp->d,cp->dest,cp->gc,cp->x,cp->y+cp->size[0],sp->texts,
X		    cp->p.nchar
X		);
X	    }
X	    else if (cp->o.tile) {
X		XDrawImageString(
X		    sp->d,cp->dest,cp->gc,cp->x,cp->y+cp->size[0],sp->outstr,
X		    cp->p.nchar
X		);
X	    }
X	    else {
X		XDrawString(
X		    sp->d,cp->dest,cp->gc,cp->x,cp->y+cp->size[0],sp->outstr,
X		    cp->p.nchar
X		);
X	    }
X#	endif
X    }
X}
X
Xvoid StartVec(sp,cp)
X    State*  sp;
X    Cmd*    cp;
X{
X    double  theta = cp->p.angle*Pi/180;
X    int	    xoffset = cp->p.lwidth*Sign(cos(theta));
X    int	    yoffset = cp->p.lwidth*Sign(-sin(theta));
X    int	    xorigin = sp->winsize/2;
X    int	    yorigin = sp->winsize/2;
X
X#   ifdef X10
X	sp->v[0].flags = 0;
X	sp->v[1].flags = 0;
X#   endif X10
X    cp->x = xorigin;
X    cp->y = yorigin;
X    xorigin += xoffset;
X    yorigin += yoffset;
X    cp->bbx = cp->p.size*cos(theta);
X    cp->bby = cp->p.size*-sin(theta);
X    sp->v[0].x = xorigin;
X    sp->v[0].y = yorigin;
X    sp->v[1].x = xorigin+cp->bbx;
X    sp->v[1].y = yorigin+cp->bby;
X    cp->bbx += 2*xoffset;
X    cp->bby += 2*yoffset;
X    cp->o.fill = false;
X    MoveClip(sp,cp,cp->x+cp->bbx/2,cp->y+cp->bby/2);
X    Start(sp,cp);
X}
X
Xvoid DoVec(sp,cp)
X    State*  sp;
X    Cmd*    cp;
X{
X    int i;
X
X    MoveVert(sp,cp,2);
X    for (i=0;i<cp->p.count;i++) {
X	StartIteration(sp,cp);
X#	ifdef X10
X	    X10Draw(sp,cp,2);
X#	else
X	    XDrawLine(
X		sp->d,cp->dest,cp->gc,sp->v[0].x,sp->v[0].y,sp->v[1].x,
X		sp->v[1].y
X	    );
X#	endif
X    }
X}
END_OF_FILE
if test 10777 -ne `wc -c <'ops.c'`; then
    echo shar: \"'ops.c'\" unpacked with wrong size!
fi
# end of 'ops.c'
fi
echo shar: End of archive 2 \(of 2\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    rm -f ark[1-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 at uunet.uu.net.



More information about the Comp.sources.unix mailing list