groff
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Groff] pic animation


From: M Bianchi
Subject: [Groff] pic animation
Date: Mon, 14 Mar 2005 09:32:32 -0500

I've been discussing the pic animation with Brian Kernighan,
who pointed me at the archived code, and he sent along the following ...

----- Forwarded message from Brian Kernighan -----

Subject: anim

mike --

your mail triggered a dim memory.  doug gwyn sent along some anim fixes
several years ago that i never reacted to.  but it might be a better place
to start.  he surely won't mind, though it would be polite to ask him.
the stuff is attached.

brian


Date:     Thu, 13 Jun 2002 13:29:51 EDT
From: Doug Gwyn (CISD) <address@hidden>
Subject:  bundle of anim/movie fixes

#!/bin/sh
# Self-unpacking archive format.  To unbundle, sh this file.
#
#       Here is the complete set of source files including my changes;
#       the first file ANIM_DAG_DIF is a reduced "dircmp" listing of the 
changes,
#       flagged in the sources by my initials "DAG".  I removed all the "DAG"
#       flags from the sources before bundling them into this shell archive.
#
echo 'ANIM_DAG_DIFF' 1>&2
cat >'ANIM_DAG_DIFF' <<'END OF ANIM_DAG_DIFF'
===== diff of anim.c in anim.netlib and anim.new:

100c100
< #define       eq(s,t) (strcmp((char *) s, (char *) t) == 0)
---
> #define       eq(s,t) (strcmp((char *) (s), (char *) (t)) == 0)       /* DAG 
> -- added parens */
191,192c191,193
< #define       Tabove  40
< #define       Tbelow  50
---
> #define       Tvcenter (1*32) /* DAG -- added */
> #define       Tabove  (2*32)  /* DAG -- was 40 */
> #define       Tbelow  (3*32)  /* DAG -- was 40 */
217c218,220
<                       's', Tsmall, 'm', Tmedium, 'b', Tbig, 'B', Tbigbig, 0 };
---
>                       's', Tsmall, 'm', Tmedium, 'b', Tbig, 'B', Tbigbig,
>                       'x', Tvcenter, 'a', Tabove, 'u', Tbelow, /* DAG added */
>                        0 };
226a230
> #define       DorS    S       /* DAG: experiment; seems to work better */
262a267
> int   /* DAG -- added */
306c311
<       exit(0);
---
>       return 0;       /* DAG -- was exit(0); */
787c792,793
<       case '#':               /* comments */
---
> /* DAG        case '#':               /* comments */
>       default:        /* DAG -- added (supports old 'b' command) */
949c955,956
<       output[0] = n;  /* for now, just use first digit */
---
>       output[0] = n;  /* for now, just use first "digit" */
>       output[2] = 0;  /* DAG -- bug fix (need to establish default color) */
952c959
<                       output[2] = *opts++ - '0';
---
>                       output[2] = *opts - '0';        /* DAG - fixed ++ bug */
1008,1009c1015
<       ip--;
<       if (ip < inbuf)
---
>       if (ip <= inbuf)        /* DAG -- reordered (bug fix) */
1010a1017,1018
>       else
>               ip--;
1022c1030
<       if (ip > nextinp)
---
>       if (ip >= nextinp)      /* DAG -- was > (bug fix) */
1054c1062
<       int c, r, thick, n, shift, head, color, rgbcolor, fill;
---
>       int c, r, thick, n, shift, vshift, head, color, rgbcolor, fill; /* DAG 
> -- added vshift */
1109,1110c1117,1119
<               n = strlen(tp);
<               shift = (ip->opts[0]/10) * 10;  /* ought to be a macro! */
---
>               n = strwidth(font, tp); /* DAG -- compute width the right way */
>               shift = (ip->opts[0] & 31) / 10 * 10; /* ought to be a macro! */
>                       /* DAG -- "& 31" strips off vertical alignment codes */
1113,1117c1122,1137
<               else if (shift == Tcenter)
<                       shift = (9 * n) / 2;    /* 9 = char width */
<               else
<                       shift = 9 * n;
<               string(&screen, sub(p0, Pt(shift,6)), font, tp, mode);
---
>               else if (shift == Trjust)
>                       shift = n;
>               else    /* Tcenter */
>                       shift = (n + 1) / 2;
>
>               /* DAG -- added code to handle above/below: */
>               vshift = ip->opts[0] / 32 * 32;
>
>               if (vshift == Tabove)
>                       vshift = font->height;
>               else if (vshift == Tbelow)
>                       vshift = 0;
>               else    /* Tvcenter */
>                       vshift = (font->height + 1) / 2;
>
>               string(&screen, sub(p0, Pt(shift,vshift)), font, tp, mode);

===== diff of fdevelop.c in anim.netlib and anim.new:

17a18,19
> #include <string.h>   /* DAG -- added */
> #include <stdlib.h>   /* DAG -- added */
51c53
< extern void   exit();
---
> /* extern void        exit(); /* DAG */
58c60
< extern float  stof();
---
> /* extern float       stof(); /* DAG -- unused */
102c104
<       "cm0",  /* TEXT:   center, medium, black        */
---
>       "cmx0", /* TEXT:   center, medium, vcenter, black   DAG added vcenter */
116,117d117
<       TEXT,   0,      "above",        'a',
<       TEXT,   0,      "below",        'b',
122,137c122,141
<       TEXT,   2,      "c0",           '0',
<       TEXT,   2,      "c1",           '1',
<       TEXT,   2,      "c2",           '2',
<       TEXT,   2,      "c3",           '3',
<       TEXT,   2,      "c4",           '4',
<       TEXT,   2,      "c5",           '5',
<       TEXT,   2,      "c6",           '6',
<       TEXT,   2,      "c7",           '7',
<       TEXT,   2,      "black",        '0',
<       TEXT,   2,      "red",          '1',
<       TEXT,   2,      "green",        '2',
<       TEXT,   2,      "yellow",       '3',
<       TEXT,   2,      "blue",         '4',
<       TEXT,   2,      "magenta",      '5',
<       TEXT,   2,      "cyan",         '6',
<       TEXT,   2,      "white",        '7',
---
>       /* DAG -- made vertical alignment separate: */
>       TEXT,   2,      "vcenter",      'x',
>       TEXT,   2,      "above",        'a',
>       TEXT,   2,      "below",        'u',    /* DAG -- was 'b', conflict */
>       TEXT,   3,      "c0",           '0',
>       TEXT,   3,      "c1",           '1',
>       TEXT,   3,      "c2",           '2',
>       TEXT,   3,      "c3",           '3',
>       TEXT,   3,      "c4",           '4',
>       TEXT,   3,      "c5",           '5',
>       TEXT,   3,      "c6",           '6',
>       TEXT,   3,      "c7",           '7',
>       TEXT,   3,      "black",        '0',
>       TEXT,   3,      "red",          '1',
>       TEXT,   3,      "green",        '2',
>       TEXT,   3,      "yellow",       '3',
>       TEXT,   3,      "blue",         '4',
>       TEXT,   3,      "magenta",      '5',
>       TEXT,   3,      "cyan",         '6',
>       TEXT,   3,      "white",        '7',
213c217
< extern double atof();
---
> /* extern double atof();      /* DAG */
215a220
> int   /* DAG -- added */
244c249
<       /* tempfname = "/tmp/dev.XXXXXX";
---
>       /* tempfname = "/usr/tmp/dev.XXXXXX";
256a262
>       return 0;       /* DAG -- was missing */
713c719,720
< #define       steq(s, n, p) (p->innum == n && ((p->instr == s) || 
eq(p->instr,s)))
---
> #define       steq(s, n, p) ((p)->innum == (n) && \
>                       (((p)->instr == (s)) || eq((p)->instr,s)))      /* DAG 
> -- added parens */
1010c1017
<       extern char *malloc();
---
> /*    extern char *malloc();  /* DAG */
1015c1022
<               if ((hmallocfp = fopen("/tmp/malloc.hist", "w")) == NULL)
---
>               if ((hmallocfp = fopen("/usr/tmp/malloc.hist", "w")) == NULL)   
> /* DAG -- was /tmp */
1019c1026
<       p = malloc((unsigned) n);
---
>       p = malloc((size_t) n); /* DAG -- was (unsigned) */

===== diff of int.def in anim.netlib and anim.new:

20a21
>                               special strings: bullet dot circle times        
> DAG -- added
35,36d35
<                       above   a
<                       below   b
40a40,50
>               3       vcenter x       DAG -- made v-pos orthogonal to others
>                       above   a
>                       below   u
>               4       black   0       DAG -- documented
>                       red     1
>                       green   2
>                       yellow  3
>                       blue    4
>                       magenta 5
>                       cyan    6
>                       white   7
49a60,67
>               3       black   0       DAG -- documented
>                       red     1
>                       green   2
>                       yellow  3
>                       blue    4
>                       magenta 5
>                       cyan    6
>                       white   7
51a70,77
>               2       black   0       DAG -- documented
>                       red     1
>                       green   2
>                       yellow  3
>                       blue    4
>                       magenta 5
>                       cyan    6
>                       white   7
53a80,88
>               2       black   0       DAG -- documented
>                       red     1
>                       green   2
>                       yellow  3
>                       blue    4
>                       magenta 5
>                       cyan    6
>                       white   7
>

===== diff of isort.gen in anim.netlib and anim.new:

1c1,4
< awk '
---
> #!/bin/sh
> AWK=nawk      # DAG -- parameterized
>
> exec $AWK '

===== diff of libXg/clipline.c in anim.netlib and anim.new:

135c135
< static
---
> static int    /* DAG -- added "int" */

===== diff of libXg/gcs.c in anim.netlib and anim.new:

135c135
<       static clipset = 0;
---
>       static int clipset = 0; /* DAG -- added "int" */

===== diff of libXg/libc.h in anim.netlib and anim.new:

9a10
> #if 0 /* DAG -- not used */
17a19,20
> #endif        /* DAG */
> #include <stdio.h>    /* DAG -- to properly declare sprintf */

===== diff of libXg/Makefile in anim.netlib and anim.new:

48c50
< nuke: clean
---
> clobber nuke: clean   # DAG -- added "clobber"

===== diff of libXg/mkfont.c in anim.netlib and anim.new:

4a5,6
> #include <stdlib.h>   /* DAG -- for declarations of malloc, free */
> extern char *strdup(const char *);    /* DAG -- was missing */

===== diff of libXg/rdfontfile.c in anim.netlib and anim.new:

6a7,8
> #include <stdlib.h>   /* DAG -- for declarations of malloc, free */
> extern char *strdup(const char *);    /* DAG -- was missing */

===== diff of libXg/rune.c in anim.netlib and anim.new:

171c171
<       return 0;
---
> /*    return 0;       /* DAG -- not reached */
192c192
<       return 0;
---
> /*    return 0;       /* DAG -- not reached */

===== diff of libXg/xtbinit.c in anim.netlib and anim.new:

400c400
<       XtSetArg(args[n], XtNscreen, &scr);     i++;
---
>       XtSetArg(args[i], XtNscreen, &scr);     i++;    /* DAG -- was [n] */

===== diff of Makefile in anim.netlib and anim.new:

6,7d5
< CFLAGS = -g -n -D_POSIX_SOURCE -D_LIBXG_EXTENSION -DSYSV -IlibXg 
-I/usr/include
< 
9a8,10
> GOPT = -g -n  # DAG -- parameterized
> CFLAGS = $(GOPT) -D_POSIX_SOURCE -D_LIBXG_EXTENSION -DSYSV -I$(LIBXG) # 
> -I/usr/include        # DAG -- tweaks to -I
> 
10a12
> #     change LIB=... to match in movie, stills, develop       # DAG -- moved
13c15
< LIB = .
---
> #DAG#LIB = .
16c18
< BIN = .
---
> #DAG#BIN = .
17a20,21
> MAN = /usr/man/man1   # DAG -- added
>
24,25c28,29
< anim: anim.o
<       $(CC) anim.o libXg/libXg.a -lXt -lX11 -lc -lm -o anim
---
> anim: anim.o $(LIBXG)/libXg.a # added library dependency
>       $(CC) -o anim anim.o $(LIBXG)/libXg.a -lXt -lX11 -lc -lm        # DAG 
> -- option before file arg
32c36,37
<       cd libXg; ar x ../libXg.src.a; make -DCC=$(CC); cd ..
---
> #DAG# cd libXg; ar x ../libXg.src.a; make -DCC=$(CC); cd ..
>       cd libXg; sh ../libXg.bundle; make -DCC=$(CC); cd ..
33a39,41
> libXg/libXg.a:        libXg   # DAG -- added
>       cd libXg; make; cd ..
>
38c46
<       $(CC) -g -o fdevelop fdevelop.c
---
>       $(CC) $(GOPT) -o fdevelop fdevelop.c    # DAG -- parameterized GOPT
43,46c51,58
< install:
<       echo change LIB=... in movie, stills, develop, makefile
<       echo then cp develop fdevelop stills.awk anim newer "$LIB"
<       echo then cp stills movie /usr/bin
---
> install:      anim fdevelop newer movie.1
>       # DAG -- changed instructions to actions:
>       @if [ -d $(BIN) ]; then :; else mkdir $(BIN); fi
>       @if [ -d $(LIB) ]; then :; else mkdir $(LIB); fi
>       @if [ -d $(MAN) ]; then :; else mkdir $(MAN); fi
>       cp movie.1 $(MAN)
>       cp develop fdevelop stills.awk anim newer $(LIB)
>       cp stills movie $(BIN)
57a70,72
> clobber nuke: clean   # DAG -- added
>       rm -f anim newer fdevelop
>
60,61c75,76
< realclean:
<       rm -fr *.o $(LIBXG) anim newer fdevelop
---
> realclean:    clobber # DAG -- use subroutine
>       rm -fr libXg

===== diff of movie in anim.netlib and anim.new:

5a6
> OPT=  # DAG -- added
11c12,14
<       -d)     OPT="$OPT -d"; shift ;;
---
>       -d|-a[0-9.][0-9.]*|-m[0-9][0-9]*|-t[0-9][0-9]*) # DAG -- added -a,-m,-t
>                       OPT="$OPT $1"; shift ;;
>       -a|-m|-t)       OPT="$OPT $1$2"; shift; shift ;;        # DAG -- added
18,20c21,23
<       trap "rm -f /tmp/movie$$.i" 0 1 2 15
<       $LIB/fdevelop >/tmp/movie$$.i
<       $LIB/anim $OPT /tmp/movie$$.i
---
>       trap "rm -f /usr/tmp/movie$$.i" 0 1 2 15        # DAG -- was /tmp
>       $LIB/fdevelop >/usr/tmp/movie$$.i
>       $LIB/anim $OPT /usr/tmp/movie$$.i

===== diff of movie.1 in anim.netlib and anim.new:

6a7
> '\"DAG -- added options:
7a9,20
> .BI -a aspect
> ]
> [
> .BI -d
> ]
> [
> .BI -m memory
> ]
> [
> .BI -t etimerval
> ]
> [
19c32,41
< into an internal representation, then displays it in a window on an X11 
system.
---
> into an internal representation, then displays it in a window on
> an X11 system.
> '\" DAG -- following added to parameterize name of constant-width font:
> .ie n \{'
> .ds CW I
> '\}
> .el \{'
> .ds CW (CW
> '\".ds CW C\" DAG -- if necessary
> '\}
21c43
< \f2file\f(CW.s\f1,
---
> \f2file\f\*(CW.s\f1,
24c46
< \f2file\f(CW.i\f1,
---
> \f2file\f\*(CW.i\f1,
26c48,69
< \f2file\f(CW.s\f1.
---
> \f2file\f\*(CW.s\f1.
> '\"DAG -- added options:
> The options are:
> .TP
> .BI -a aspect
> Change the aspect ratio within which
> a swept zoom window will be made square to
> .I aspect
> (default 0.75).
> .TP
> .B -d
> Print the program version on the standard error output then terminate.
> .TP
> .BI -m mem
> Use
> .I mem
> bytes of terminal memory instead of the default.
> .TP
> .BI -t etimerval
> Change the event-loop timer to
> .I etimerval
> (default 25).
28c71
< In the terminal, button 1 stops and starts the movie;
---
> In the terminal window, button 1 stops and starts the movie;  \" DAG -- added 
> "window"
74a118
> '\" DAG -- added following:
75a120,133
> Each of the above can also have a color option: one of
> .B black
> .B red
> .B green
> .B yellow
> .B blue
> .B magenta
> .B cyan
> .BR white ;
> alternatively these can be specified as
> .B c0
> through
> .BR c7 .
> .br
78a137
> .br   \" DAG -- was missing
118,120c177,179
< .TF stills.awk
< .TP
< .F develop
---
> '\" DAG -- removed .TF and .F; changed to standard .TP usage:
> .TP "\w'\f\*(CWstills.awk\fP   'u"
> \f\*(CWdevelop\fP
123c182
< .F fdevelop
---
> \f\*(CWfdevelop\fP
126c185
< .F stills.awk
---
> \f\*(CWstills.awk\fP
130c189
< .F anim
---
> \f\*(CWanim\fP
137c196
< .F newer
---
> \f\*(CWnewer\fP
149a209,210
> .br
> The 5620 and 630 terminals are no longer supported.   \" DAG -- added

===== diff of newer.c in anim.netlib and anim.new:

11a12
> int   /* DAG -- added */

===== diff of README in anim.netlib and anim.new:

46,47c46,48
< to make a movie or a set of stills.  For more information,
< see our papers:
---
> to make a movie or a set of stills.  This uses a newish
> (circa 1985) version of awk (typically available as "nawk").
> For more information, see our papers:
77c78,79
<       Under X11, creates a new window for the movie.
---
>       Host program processes output of develop;
>       under X11, creates a new window for the movie.

===== diff of script.def in anim.netlib and anim.new:

15c15
<           [center]  ljust  rjust  above  below
---
>           [center]  ljust  rjust
16a17,19
>           [vcenter]  above  below     DAG -- made these orthogonal
>           [black]  red  green  yellow  blue  magenta  cyan  white     DAG -- 
> documented
>           (above colors can also be specified as c0 .. c7)
23a27,28
>           [black]  red  green  yellow  blue  magenta  cyan  white     DAG -- 
> documented
>           (above colors can also be specified as c0 .. c7)
26a32,33
>           [black]  red  green  yellow  blue  magenta  cyan  white     DAG -- 
> documented
>           (above colors can also be specified as c0 .. c7)
30a38,39
>           [black]  red  green  yellow  blue  magenta  cyan  white     DAG -- 
> documented
>           (above colors can also be specified as c0 .. c7)

===== diff of show.clicks in anim.netlib and anim.new:

1c1,4
< awk ' # show.clicks:  make a new view counting clicks
---
> #!/bin/sh
> AWK=nawk      # DAG -- parameterized
>
> exec $AWK ' # show.clicks:  make a new view counting clicks

===== diff of stills in anim.netlib and anim.new:

7a8
> AWK=nawk      # DAG -- parameterized
17c18
< awk -f $LIB/stills.awk develop=$LIB/develop $*
---
> exec $AWK -f $LIB/stills.awk develop=$LIB/develop $*

===== diff of view.clicks in anim.netlib and anim.new:

0a1
> #!/bin/sh
2a4,5
> AWK=nawk      # DAG -- parameterized
>
4c7
< awk '
---
> exec $AWK '
END OF ANIM_DAG_DIFF
echo 'README' 1>&2
cat >'README' <<'END OF README'

        anim -- Algorithm Animation

        Jon Bentley (address@hidden)
        Brian Kernighan (address@hidden)


EXECUTIVE SUMMARY

Create a description of an animation in the language
described in script.def, using whatever tools you like
(e.g., awk programs, C programs).
Show the movie on an X11 system with movie.
Print selected frames through pic and troff with stills.

        Suntools support withdrawn 12/87;
        Teletype 5620 and 630 support withdrawn 8/90.
        This version assumes X11R5.
        Plan 9 emulation library updated 6/93 to include unicode.

An animation is normally produced by adding print statements
to a program.  Each statement requests the drawing or erasing
of some piece of the animation.  Objects may be lines, boxes,
circles, or text, positioned arbitrarily.  Anim scales
coordinates so that the display always fits the screen.  The
display may contain multiple independent views that depict
different aspects of interest; these views are completely
independent of each other and are scaled separately.

When anim is used interactively, the viewer can control the
speed of display, proceed forward or backward through time,
and change the screen layout to emphasize certain views.  It
is also possible to mark interesting points in time and step
from event to event interactively.

When anim is used to produce stills, a simple language
permits the selection and positioning of arbitrary
collections of interesting frames and views.


LANGUAGE

The language is defined but not explained much in script.def.
The awk program isort.gen can be run to give an example of
data in the script language, then processed subsequently
to make a movie or a set of stills.  This uses a newish
(circa 1985) version of awk (typically available as "nawk").
For more information, see our papers:

   "A System for Algorithm Animation -- Tutorial and User Manual"
   Computing Science Tech Report 132, January, 1987.
   Available in PostScript:
        echo send research/cstr/132 | mail address@hidden
   
   "A System for Algorithm Animation."
   Computing Systems, Vol 4, #1, pp 5-30, Winter 1991.


PRIMARY PROGRAMS

movie
        shell script
        "movie file.s" develops file.s if necessary to make file.i,
        then displays it on an X-window terminal using anim.

stills
        shell script, invoking giant awk program stills.awk.
        A troff preprocessor that creates pic pictures of
        selected frames.  Input language defined in stills.def

develop
        shell script, called by movie and stills.
        Input language defined in script.def, output language
                ("intermediate") defined in int.def.
        Uses fdevelop (C program) to do the work.

anim
        Host program processes output of develop;
        under X11, creates a new window for the movie.

        Try
                isort.gen >dev.s (an example in this directory)
                movie dev.s
                        (equivalent to fdevelop dev.s >dev.i; anim dev.i)

        The files test.s and test.i can be used for experimenting
        with the host and terminal programs before worrying about
        develop.  qsort.[is] is a bigger and more interesting example.


SUPPORT PROGRAMS

show.clicks     make a new view to count clicks
view.clicks     print summary of views and clicks
newer.c         tests file ages;  install if needed (used in develop)


INSTALLATION

        You may have to change some directory names and other parameters in
                movie
                stills
                develop
                Makefile

        BIN = directory where movie and stills are (e.g., /usr/bin)
        LIB = directory where develop, fdevelop, stills.awk, anim
                are (e.g., /usr/lib).

        Then
                mkdir libXg
                cd libXg
                sh ../libXg.bundle
                make
                cd ..
                make all

        anim uses a graphics library called libXg that is
        included here.  The makefile isn't very clever about
        making this, nor about noticing if it has changed.
        Pay attention!


PROBLEMS

        The locations of compilers, libraries, and similar things
        vary wildly from system to system.  Although we have tried
        to parameterize these in the makefiles, you will surely
        have to fiddle with file names and perhaps defined constants
        in the makefiles.  Even then, you may be stymied by incompatible
        header files that you didn't even know you needed.  Sorry.

        This package assumes X11 Release 5 and uses the Xt toolkit.

        This code also assumes an ANSI C compiler.  If you don't
        have one, you will have to edit, or, better, get one.


UPDATES

        New menu items Zoom in and Zoom out let you do just that.
        If a null rectangle is selected on zooming in, the previous
        zoomed-in rectangle is used.

        If the aspect ratio of the screen or a zoom rectangle is
        between .75 and 1.25, the picture aspect ratio is forced to 1.
        The -a option controls this; e.g., -a.9 sets it to 0.9.

        The run/1-step menu has been augmented with a third state,
        "cycle", which plays the movie repeatedly until interrupted.

        A rudimentary color capability has been added, but the job
        isn't complete.  It does filled circles and boxes and lines
        of various colors for now.

        It is possible to provide .i-format input in your own
        coordinate system instead of the default [0,9999],[0,9999].
        The command
                d s v x y x y
        causes input in view v to be scaled under the assumption
        that inputs for that view are in the range [x,y],[x,y].

        We are, as  always, in the middle of adding new features,
        so things may well be shakier than normal.  Complaints welcome.


HEARTFELT ACKNOWLEDGEMENT

        The code for the animation system owes an enormous debt to
        Howard Trickey, who first figured out how to deal with
        the egregious Suntools and X window systems, and then wrote
        and continued to upgrade the X11 graphics library included here.
        None of this would work without Howard's code, which is included
        with his permission.


COPYRIGHT INFORMATION

Copyright (C) AT&T 1992  
All Rights Reserved

Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of AT&T or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.

AT&T DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL AT&T OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
END OF README
echo 'movie.1' 1>&2
cat >'movie.1' <<'END OF movie.1'
.TH MOVIE 1 
.CT 1 files prog_other
.SH NAME
movie, stills \- algorithm animation
.SH SYNOPSIS
.B movie
[
.BI -a aspect
]
[
.BI -d
]
[
.BI -m memory
]
[
.BI -t etimerval
]
[
.I file
]
.br
.B stills
[
.I files ...
]
.SH DESCRIPTION
.PP
.I Movie
converts a script in a movie language
into an internal representation, then displays it in a window on
an X11 system.
'\" following supports parameterizing the name of the constant-width font:
.ie n \{'
.ds CW I
'\}
.el \{'
.ds CW (CW
'\".ds CW C\" if necessary
'\}
If the filename is of the form
\f2file\f\*(CW.s\f1,
.I movie
creates the intermediate form in
\f2file\f\*(CW.i\f1,
which will be used in subsequent calls if it is more recent than
\f2file\f\*(CW.s\f1.
The options are:
.TP
.BI -a aspect
Change the aspect ratio within which
a swept zoom window will be made square to
.I aspect
(default 0.75).
.TP
.B -d
Print the program version on the standard error output then terminate.
.TP
.BI -m mem
Use
.I mem
bytes of terminal memory instead of the default.
.TP
.BI -t etimerval
Change the event-loop timer to
.I etimerval
(default 25).
.PP
In the terminal window, button 1 stops and starts the movie;
button 2 adjusts view sizes and selects clicks;
button 3 sets various parameters.
.PP
.SS Movie language
.br
.B text
.I options x y string.
Text is centered and medium size by default;  options: one of
.B "center
.B ljust
.B rjust
.B above
.BR below ,
and one of
.BR "small
.B medium
.B big
.BR bigbig .
A leading quote is stripped from
.IR string ,
as is a trailing quote if a leading one is present.
.br
.BI line
.I "options x1 y1 x2 y2.
Lines are solid by default;  options: one of
.B "fat
.B fatfat
.B dotted
.B dashed
and one of
.B "->
.B <-
.BR <-> .
.br
.BI box
.I "options xmin ymin xmax ymax.
A box may
.BR fill ed.
.br
.BI circle 
.I "options x1 y1 radius.
Radius is measured in the
.I x
dimension.
A circle may be
.BR fill ed.
.br
Each of the above can also have a color option: one of
.B black
.B red
.B green
.B yellow
.B blue
.B magenta
.B cyan
.BR white ;
alternatively these can be specified as
.B c0
through
.BR c7 .
.br
Any text or geometrical object may be labeled with a name and colon.
A subsequent appearance of a label in the same view erases the previous
object with that label.
.br
.BI erase
.I label
erases the object explicitly.
.B clear
erases all objects currently in the current view.
.br
.BI click
.I "optional name
leaves a mark in the intermediate with this name;
clicks are used to control stepping in a movie or to define frames
for a set of stills.
.br
A movie may consist of multiple independent views,
each presented as a rectangular sub-window.
.BI view 
.I name
associates
subsequent objects with this view,
until changed again.
Labels and coordinates are local to views.
If no view statements appear, there is a single implicit view
.BR def.view .
.br
Comments follow #; blank lines are ignored.
.PP
.I Stills
converts selected frames of a movie into
commands for
.IR pic (1).
Commands for
.I stills
begin with
.B .begin stills
and end with
.B .end
.BR stills .
.SH FILES
All files are in
.BR /usr/lib/movie .
.TP "\w'\f\*(CWstills.awk\fP   'u"
\f\*(CWdevelop\fP
Shell script to control conversion from script language to internal form.
.TP
\f\*(CWfdevelop\fP
C program that does the work.
.TP
\f\*(CWstills.awk\fP
Awk program to process stills language into
.IR pic (1).
.TP
\f\*(CWanim\fP
Animation program itself.
This supports a
.B \-m
option for changing the default amount of memory
allocated to the movie.
.TP
\f\*(CWnewer\fP
Test whether one file is newer than another.
.SH "SEE ALSO"
J. L. Bentley and B. W. Kernighan,
.IR "A System for Algorithm Animation" ,
AT&T Bell Laboratories CSTR 132, January, 1987.
For a copy in PostScript, 
.br
.B "     echo send research/cstr/132 | mail address@hidden
.SH BUGS
There are several compiled-in limits that ought to be dynamic.
.br
The "slower" menu selection doesn't work under X11.
.br
The 5620 and 630 terminals are no longer supported.
END OF movie.1
echo 'script.def' 1>&2
cat >'script.def' <<'END OF script.def'
                Definition of Script Language

OBJECTS
Text
%   text <options> <x> <y> <string>
        Quote rules for string:
            If no leading quote, string starts at first character not
                space or tab and goes for rest of line
            If leading quote, later leading white space is kept and
                trailing quote at end of line is stripped (if present);
                intermediate quotes are kept
        Some strings may be recognized by some processors:
            bullet, dot, circle, times
        Options -- [default] in brackets
            [center]  ljust  rjust
            small  [medium]  big  bigbig
            [vcenter]  above  below
            [black]  red  green  yellow  blue  magenta  cyan  white
            (above colors can also be specified as c0 .. c7)
        Option format (for text and geometry):
            list of option names (possibly null) terminated by first number
Geometry
%   line <options> <x1> <y1> <x2> <y2>
        Options
            [solid]  fat  fatfat  dotted  dashed
            [-]  ->  <-  <->
            [black]  red  green  yellow  blue  magenta  cyan  white
            (above colors can also be specified as c0 .. c7)
%   box <options> <xmin> <ymin> <xmax> <ymax>
        Options
            [nofill]  fill
            [black]  red  green  yellow  blue  magenta  cyan  white
            (above colors can also be specified as c0 .. c7)
%   circle <options> <x1> <y1> <radius>
        Radius measured in x dimension
        Options
            [nofill]  fill
            [black]  red  green  yellow  blue  magenta  cyan  white
            (above colors can also be specified as c0 .. c7)

HOUSEKEEPING
Erasing
%   (label:) <text or geometric command>
        At most one label per line
%   erase <label>
        Distinct name space for each view
        ``foo: command'' implicitly deletes previous foo
        Error if object never defined or already deleted
%   clear
        Erase all objects currently in current view
Time
%   click <optional name>
Independent views
%   view <name>
        If no view statements appear, there is a single implicit view def.view
        If geometry appears before any view statement, it goes in the
            first view mentioned, and a warning is generated

MISC
Comments follow #; blank lines ignored
END OF script.def
echo 'stills.def' 1>&2
cat >'stills.def' <<'END OF stills.def'
                Definition of Stills Language

USAGE
typical troff preprocessor: converts its input language (bracketed by
    .begin stills and .end) into pic, and passes all else through

STATEMENTS (A file and print are mandatory; all else optional.)

#   comment -- must be first nonblank character on line

view <name> <optional title, with blanks>
    named views appear in order
    if no view statements, all views are displayed
    if title is enclosed in quotes, leading space is kept
    if no title is given on a line, view name is used as a title

print statements (any number of the following forms)
    print all                   Every click
    print final                 End of file
    print <clickname> all       All clicks of clickname
    print <clickname> <int>+    Designated click numbers of clickname

Parameter settings
    General form: <attribute> <value>
        numeric values may be of form -n, n, +n, or missing (zero default)
        all parameters reset to default at every begin statement
    Attributes:
        Mandatory: file
            give file name as <basename>.s
            stills develops .s to get .i, if needed
        Text sizes: small medium big bigbig
            ``small -2'' does a .ps -2 for small text
        Line widths: solid fat fatfat
            ``fat +4'' does a .ps +4 for fat lines
        Directions: across down
            ``across 5'' gives 5 time snapshots across the page; views go
                top to bottom; across 0 is default
            ``down'' or ``down 0'' gives as many snapshots as will fit down
                an 8-inch page; views go left to right
        Frame: frameht framewid margin
            height and width in inches, default 1.5
            margin is white space around data, default 0.05 = 5%
        Optional parts: frames times
            values are ``vis'' and ``invis''; default ``vis''
            frames surround pictures; times are from print statements

WISH LIST
New Parameter Settings
    Spread between frames       
Frame control like GRAP ``graph with'', both for layout within
    time snapshots and positioning of new snapshot w.r.t. previous
END OF stills.def
echo 'int.def' 1>&2
cat >'int.def' <<'END OF int.def'
                Definition of Intermediate Language

Cmd     Abbrev  Operands / Comments
comment #                       only at start of line
blank   b       s <vnum>        start blanking; erase commands follow
                e <vnum>        end blanking current view
click   c       <clicknum>
define  d       v <number> <viewname> <minx> <miny> <maxx> <maxy>
                c <number> <clickname>
                p e     pragma -- end of defs at front of file
                        Other possible ``pragmas'':                     ???
                                Number of (lines, bytes) in file
                                Number of slots ever used
erase   e       <line repeated here, except for leading g>
                        Object is deletable
geom    g       <slotn> l <vnum> <opts> <x1> <y1> <x2> <y2>     line
                        b <vnum> <opts> <x1> <y1> <x2> <y2>     box
                        c <vnum> <opts> <x> <y> <rad>           circle
                        t <vnum> <opts> <x> <y> <text string>   text
                                one separating tab; string unquoted
                                special strings: bullet dot circle times
                            <opts> format: string of characters, in order
                            <slotn> == 0 => line never erased

At beginning of file:
        d v <number> <view name> <minx> <miny> <maxx> <maxy>
        d c <number> <click name>
        d p <various pragmas here>
        d p e

Options for geometric objects
        OBJECT  POS     NAME    ABBREV
        text    1       center  c
                        ljust   l
                        rjust   r
                2       medium  m
                        small   s
                        big     b
                        bigbig  B
                3       vcenter x
                        above   a
                        below   u
                4       black   0
                        red     1
                        green   2
                        yellow  3
                        blue    4
                        magenta 5
                        cyan    6
                        white   7
        line    1       solid   s
                        fat     f
                        fatfat  F
                        dotted  o
                        dashed  a
                2       -       -
                        ->      >
                        <-      <
                        <->     x
                3       black   0
                        red     1
                        green   2
                        yellow  3
                        blue    4
                        magenta 5
                        cyan    6
                        white   7
        box     1       nofill  n
                        fill    f
                2       black   0
                        red     1
                        green   2
                        yellow  3
                        blue    4
                        magenta 5
                        cyan    6
                        white   7
        circle  1       nofill  n
                        fill    f
                2       black   0
                        red     1
                        green   2
                        yellow  3
                        blue    4
                        magenta 5
                        cyan    6
                        white   7

    Default is first in position
    Example: "line small" has code "cs"
END OF int.def
echo 'isort.gen' 1>&2
cat >'isort.gen' <<'END OF isort.gen'
#!/bin/sh
AWK=nawk

exec $AWK '
function draw(i)  {
    print "a" i ": text", i, x[i], "bullet"
    print "b" i ": circle fill", i, x[i], .1
}
function swap(i,j,   t) {
    t = x[i];  x[i] = x[j];  x[j] = t
    draw(i); draw(j)
    print "click swaps"
}
function less(i,j) {
    print "compline: line <-> fat", i, -8, j, -8
    print "click comps"
    if (x[i] < x[j]) { return 1 } else { return 0 }
}
BEGIN { n=10
        for (i = 1; i <= n; i++) {
                x[i] = int(100*rand())
                draw(i)
        }
        for (i = 2; i <= n; i++)
                for (j = i; j > 1 && less(j, j-1); j--)
                        swap(j-1, j)
}'
END OF isort.gen
chmod +x 'isort.gen'
echo 'test.i' 1>&2
cat >'test.i' <<'END OF test.i'
d       v       0       def.view        0.9     -8      10.1    89.1
d       c       0       comps
d       c       1       swaps
d       p       e
g       1       t       0       cm0     108     9782    bullet
g       2       c       0       f0      108     9782    109
g       3       t       0       cm0     1195    1441    bullet
g       4       c       0       f0      1195    1441    109
g       5       t       0       cm0     2282    8855    bullet
g       6       c       0       f0      2282    8855    109
g       7       t       0       cm0     3369    9988    bullet
g       8       c       0       f0      3369    9988    108
g       9       t       0       cm0     4456    1544    bullet
g       10      c       0       f0      4456    1544    108
g       11      t       0       cm0     5542    4016    bullet
g       12      c       0       f0      5542    4016    109
g       13      t       0       cm0     6629    823     bullet
g       14      c       0       f0      6629    823     109
g       15      t       0       cm0     7716    5251    bullet
g       16      c       0       f0      7716    5251    109
g       17      t       0       cm0     8803    926     bullet
g       18      c       0       f0      8803    926     109
g       19      t       0       cm0     9890    3295    bullet
g       20      c       0       f0      9890    3295    109
g       21      l       0       fx0     1195    0       108     0
c       0
e       1       t       0       cm0     108     9782    bullet
g       1       t       0       cm0     108     1441    bullet
e       2       c       0       f0      108     9782    109
g       2       c       0       f0      108     1441    109
e       3       t       0       cm0     1195    1441    bullet
g       3       t       0       cm0     1195    9782    bullet
e       4       c       0       f0      1195    1441    109
g       4       c       0       f0      1195    9782    109
c       1
e       21      l       0       fx0     1195    0       108     0
g       21      l       0       fx0     2282    0       1195    0
c       0
e       3       t       0       cm0     1195    9782    bullet
g       3       t       0       cm0     1195    8855    bullet
e       4       c       0       f0      1195    9782    109
g       4       c       0       f0      1195    8855    109
e       5       t       0       cm0     2282    8855    bullet
g       5       t       0       cm0     2282    9782    bullet
e       6       c       0       f0      2282    8855    109
g       6       c       0       f0      2282    9782    109
c       1
e       21      l       0       fx0     2282    0       1195    0
g       21      l       0       fx0     1195    0       108     0
c       0
e       21      l       0       fx0     1195    0       108     0
g       21      l       0       fx0     3369    0       2282    0
c       0
e       21      l       0       fx0     3369    0       2282    0
g       21      l       0       fx0     4456    0       3369    0
c       0
e       7       t       0       cm0     3369    9988    bullet
g       7       t       0       cm0     3369    1544    bullet
e       8       c       0       f0      3369    9988    108
g       8       c       0       f0      3369    1544    108
e       9       t       0       cm0     4456    1544    bullet
g       9       t       0       cm0     4456    9988    bullet
e       10      c       0       f0      4456    1544    108
g       10      c       0       f0      4456    9988    108
c       1
e       21      l       0       fx0     4456    0       3369    0
g       21      l       0       fx0     3369    0       2282    0
c       0
e       5       t       0       cm0     2282    9782    bullet
g       5       t       0       cm0     2282    1544    bullet
e       6       c       0       f0      2282    9782    109
g       6       c       0       f0      2282    1544    109
e       7       t       0       cm0     3369    1544    bullet
g       7       t       0       cm0     3369    9782    bullet
e       8       c       0       f0      3369    1544    108
g       8       c       0       f0      3369    9782    108
c       1
e       21      l       0       fx0     3369    0       2282    0
g       21      l       0       fx0     2282    0       1195    0
c       0
e       3       t       0       cm0     1195    8855    bullet
g       3       t       0       cm0     1195    1544    bullet
e       4       c       0       f0      1195    8855    109
g       4       c       0       f0      1195    1544    109
e       5       t       0       cm0     2282    1544    bullet
g       5       t       0       cm0     2282    8855    bullet
e       6       c       0       f0      2282    1544    109
g       6       c       0       f0      2282    8855    109
c       1
e       21      l       0       fx0     2282    0       1195    0
g       21      l       0       fx0     1195    0       108     0
c       0
e       21      l       0       fx0     1195    0       108     0
g       21      l       0       fx0     5542    0       4456    0
c       0
e       9       t       0       cm0     4456    9988    bullet
g       9       t       0       cm0     4456    4016    bullet
e       10      c       0       f0      4456    9988    108
g       10      c       0       f0      4456    4016    108
e       11      t       0       cm0     5542    4016    bullet
g       11      t       0       cm0     5542    9988    bullet
e       12      c       0       f0      5542    4016    109
g       12      c       0       f0      5542    9988    109
c       1
e       21      l       0       fx0     5542    0       4456    0
g       21      l       0       fx0     4456    0       3369    0
c       0
e       7       t       0       cm0     3369    9782    bullet
g       7       t       0       cm0     3369    4016    bullet
e       8       c       0       f0      3369    9782    108
g       8       c       0       f0      3369    4016    108
e       9       t       0       cm0     4456    4016    bullet
g       9       t       0       cm0     4456    9782    bullet
e       10      c       0       f0      4456    4016    108
g       10      c       0       f0      4456    9782    108
c       1
e       21      l       0       fx0     4456    0       3369    0
g       21      l       0       fx0     3369    0       2282    0
c       0
e       5       t       0       cm0     2282    8855    bullet
g       5       t       0       cm0     2282    4016    bullet
e       6       c       0       f0      2282    8855    109
g       6       c       0       f0      2282    4016    109
e       7       t       0       cm0     3369    4016    bullet
g       7       t       0       cm0     3369    8855    bullet
e       8       c       0       f0      3369    4016    108
g       8       c       0       f0      3369    8855    108
c       1
e       21      l       0       fx0     3369    0       2282    0
g       21      l       0       fx0     2282    0       1195    0
c       0
e       21      l       0       fx0     2282    0       1195    0
g       21      l       0       fx0     6629    0       5542    0
c       0
e       11      t       0       cm0     5542    9988    bullet
g       11      t       0       cm0     5542    823     bullet
e       12      c       0       f0      5542    9988    109
g       12      c       0       f0      5542    823     109
e       13      t       0       cm0     6629    823     bullet
g       13      t       0       cm0     6629    9988    bullet
e       14      c       0       f0      6629    823     109
g       14      c       0       f0      6629    9988    109
c       1
e       21      l       0       fx0     6629    0       5542    0
g       21      l       0       fx0     5542    0       4456    0
c       0
e       9       t       0       cm0     4456    9782    bullet
g       9       t       0       cm0     4456    823     bullet
e       10      c       0       f0      4456    9782    108
g       10      c       0       f0      4456    823     108
e       11      t       0       cm0     5542    823     bullet
g       11      t       0       cm0     5542    9782    bullet
e       12      c       0       f0      5542    823     109
g       12      c       0       f0      5542    9782    109
c       1
e       21      l       0       fx0     5542    0       4456    0
g       21      l       0       fx0     4456    0       3369    0
c       0
e       7       t       0       cm0     3369    8855    bullet
g       7       t       0       cm0     3369    823     bullet
e       8       c       0       f0      3369    8855    108
g       8       c       0       f0      3369    823     108
e       9       t       0       cm0     4456    823     bullet
g       9       t       0       cm0     4456    8855    bullet
e       10      c       0       f0      4456    823     108
g       10      c       0       f0      4456    8855    108
c       1
e       21      l       0       fx0     4456    0       3369    0
g       21      l       0       fx0     3369    0       2282    0
c       0
e       5       t       0       cm0     2282    4016    bullet
g       5       t       0       cm0     2282    823     bullet
e       6       c       0       f0      2282    4016    109
g       6       c       0       f0      2282    823     109
e       7       t       0       cm0     3369    823     bullet
g       7       t       0       cm0     3369    4016    bullet
e       8       c       0       f0      3369    823     108
g       8       c       0       f0      3369    4016    108
c       1
e       21      l       0       fx0     3369    0       2282    0
g       21      l       0       fx0     2282    0       1195    0
c       0
e       3       t       0       cm0     1195    1544    bullet
g       3       t       0       cm0     1195    823     bullet
e       4       c       0       f0      1195    1544    109
g       4       c       0       f0      1195    823     109
e       5       t       0       cm0     2282    823     bullet
g       5       t       0       cm0     2282    1544    bullet
e       6       c       0       f0      2282    823     109
g       6       c       0       f0      2282    1544    109
c       1
e       21      l       0       fx0     2282    0       1195    0
g       21      l       0       fx0     1195    0       108     0
c       0
e       1       t       0       cm0     108     1441    bullet
g       0       t       0       cm0     108     823     bullet
e       2       c       0       f0      108     1441    109
g       0       c       0       f0      108     823     109
e       3       t       0       cm0     1195    823     bullet
g       3       t       0       cm0     1195    1441    bullet
e       4       c       0       f0      1195    823     109
g       4       c       0       f0      1195    1441    109
c       1
e       21      l       0       fx0     1195    0       108     0
g       21      l       0       fx0     7716    0       6629    0
c       0
e       13      t       0       cm0     6629    9988    bullet
g       13      t       0       cm0     6629    5251    bullet
e       14      c       0       f0      6629    9988    109
g       14      c       0       f0      6629    5251    109
e       15      t       0       cm0     7716    5251    bullet
g       15      t       0       cm0     7716    9988    bullet
e       16      c       0       f0      7716    5251    109
g       16      c       0       f0      7716    9988    109
c       1
e       21      l       0       fx0     7716    0       6629    0
g       21      l       0       fx0     6629    0       5542    0
c       0
e       11      t       0       cm0     5542    9782    bullet
g       11      t       0       cm0     5542    5251    bullet
e       12      c       0       f0      5542    9782    109
g       12      c       0       f0      5542    5251    109
e       13      t       0       cm0     6629    5251    bullet
g       13      t       0       cm0     6629    9782    bullet
e       14      c       0       f0      6629    5251    109
g       14      c       0       f0      6629    9782    109
c       1
e       21      l       0       fx0     6629    0       5542    0
g       21      l       0       fx0     5542    0       4456    0
c       0
e       9       t       0       cm0     4456    8855    bullet
g       9       t       0       cm0     4456    5251    bullet
e       10      c       0       f0      4456    8855    108
g       10      c       0       f0      4456    5251    108
e       11      t       0       cm0     5542    5251    bullet
g       11      t       0       cm0     5542    8855    bullet
e       12      c       0       f0      5542    5251    109
g       12      c       0       f0      5542    8855    109
c       1
e       21      l       0       fx0     5542    0       4456    0
g       21      l       0       fx0     4456    0       3369    0
c       0
e       21      l       0       fx0     4456    0       3369    0
g       21      l       0       fx0     8803    0       7716    0
c       0
e       15      t       0       cm0     7716    9988    bullet
g       15      t       0       cm0     7716    926     bullet
e       16      c       0       f0      7716    9988    109
g       16      c       0       f0      7716    926     109
e       17      t       0       cm0     8803    926     bullet
g       17      t       0       cm0     8803    9988    bullet
e       18      c       0       f0      8803    926     109
g       18      c       0       f0      8803    9988    109
c       1
e       21      l       0       fx0     8803    0       7716    0
g       21      l       0       fx0     7716    0       6629    0
c       0
e       13      t       0       cm0     6629    9782    bullet
g       13      t       0       cm0     6629    926     bullet
e       14      c       0       f0      6629    9782    109
g       14      c       0       f0      6629    926     109
e       15      t       0       cm0     7716    926     bullet
g       15      t       0       cm0     7716    9782    bullet
e       16      c       0       f0      7716    926     109
g       16      c       0       f0      7716    9782    109
c       1
e       21      l       0       fx0     7716    0       6629    0
g       21      l       0       fx0     6629    0       5542    0
c       0
e       11      t       0       cm0     5542    8855    bullet
g       11      t       0       cm0     5542    926     bullet
e       12      c       0       f0      5542    8855    109
g       12      c       0       f0      5542    926     109
e       13      t       0       cm0     6629    926     bullet
g       13      t       0       cm0     6629    8855    bullet
e       14      c       0       f0      6629    926     109
g       14      c       0       f0      6629    8855    109
c       1
e       21      l       0       fx0     6629    0       5542    0
g       21      l       0       fx0     5542    0       4456    0
c       0
e       9       t       0       cm0     4456    5251    bullet
g       9       t       0       cm0     4456    926     bullet
e       10      c       0       f0      4456    5251    108
g       10      c       0       f0      4456    926     108
e       11      t       0       cm0     5542    926     bullet
g       11      t       0       cm0     5542    5251    bullet
e       12      c       0       f0      5542    926     109
g       12      c       0       f0      5542    5251    109
c       1
e       21      l       0       fx0     5542    0       4456    0
g       21      l       0       fx0     4456    0       3369    0
c       0
e       7       t       0       cm0     3369    4016    bullet
g       7       t       0       cm0     3369    926     bullet
e       8       c       0       f0      3369    4016    108
g       8       c       0       f0      3369    926     108
e       9       t       0       cm0     4456    926     bullet
g       9       t       0       cm0     4456    4016    bullet
e       10      c       0       f0      4456    926     108
g       10      c       0       f0      4456    4016    108
c       1
e       21      l       0       fx0     4456    0       3369    0
g       21      l       0       fx0     3369    0       2282    0
c       0
e       5       t       0       cm0     2282    1544    bullet
g       5       t       0       cm0     2282    926     bullet
e       6       c       0       f0      2282    1544    109
g       6       c       0       f0      2282    926     109
e       7       t       0       cm0     3369    926     bullet
g       0       t       0       cm0     3369    1544    bullet
e       8       c       0       f0      3369    926     108
g       0       c       0       f0      3369    1544    108
c       1
e       21      l       0       fx0     3369    0       2282    0
g       21      l       0       fx0     2282    0       1195    0
c       0
e       3       t       0       cm0     1195    1441    bullet
g       0       t       0       cm0     1195    926     bullet
e       4       c       0       f0      1195    1441    109
g       0       c       0       f0      1195    926     109
e       5       t       0       cm0     2282    926     bullet
g       0       t       0       cm0     2282    1441    bullet
e       6       c       0       f0      2282    926     109
g       0       c       0       f0      2282    1441    109
c       1
e       21      l       0       fx0     2282    0       1195    0
g       21      l       0       fx0     1195    0       108     0
c       0
e       21      l       0       fx0     1195    0       108     0
g       21      l       0       fx0     9890    0       8803    0
c       0
e       17      t       0       cm0     8803    9988    bullet
g       17      t       0       cm0     8803    3295    bullet
e       18      c       0       f0      8803    9988    109
g       18      c       0       f0      8803    3295    109
e       19      t       0       cm0     9890    3295    bullet
g       0       t       0       cm0     9890    9988    bullet
e       20      c       0       f0      9890    3295    109
g       0       c       0       f0      9890    9988    109
c       1
e       21      l       0       fx0     9890    0       8803    0
g       21      l       0       fx0     8803    0       7716    0
c       0
e       15      t       0       cm0     7716    9782    bullet
g       15      t       0       cm0     7716    3295    bullet
e       16      c       0       f0      7716    9782    109
g       16      c       0       f0      7716    3295    109
e       17      t       0       cm0     8803    3295    bullet
g       0       t       0       cm0     8803    9782    bullet
e       18      c       0       f0      8803    3295    109
g       0       c       0       f0      8803    9782    109
c       1
e       21      l       0       fx0     8803    0       7716    0
g       21      l       0       fx0     7716    0       6629    0
c       0
e       13      t       0       cm0     6629    8855    bullet
g       13      t       0       cm0     6629    3295    bullet
e       14      c       0       f0      6629    8855    109
g       14      c       0       f0      6629    3295    109
e       15      t       0       cm0     7716    3295    bullet
g       0       t       0       cm0     7716    8855    bullet
e       16      c       0       f0      7716    3295    109
g       0       c       0       f0      7716    8855    109
c       1
e       21      l       0       fx0     7716    0       6629    0
g       21      l       0       fx0     6629    0       5542    0
c       0
e       11      t       0       cm0     5542    5251    bullet
g       11      t       0       cm0     5542    3295    bullet
e       12      c       0       f0      5542    5251    109
g       12      c       0       f0      5542    3295    109
e       13      t       0       cm0     6629    3295    bullet
g       0       t       0       cm0     6629    5251    bullet
e       14      c       0       f0      6629    3295    109
g       0       c       0       f0      6629    5251    109
c       1
e       21      l       0       fx0     6629    0       5542    0
g       21      l       0       fx0     5542    0       4456    0
c       0
e       9       t       0       cm0     4456    4016    bullet
g       0       t       0       cm0     4456    3295    bullet
e       10      c       0       f0      4456    4016    108
g       0       c       0       f0      4456    3295    108
e       11      t       0       cm0     5542    3295    bullet
g       0       t       0       cm0     5542    4016    bullet
e       12      c       0       f0      5542    3295    109
g       0       c       0       f0      5542    4016    109
c       1
e       21      l       0       fx0     5542    0       4456    0
g       0       l       0       fx0     4456    0       3369    0
c       0
END OF test.i
echo 'test.s' 1>&2
cat >'test.s' <<'END OF test.s'
a1: text 1 87 bullet
b1: circle fill 1 87 0.1
a2: text 2 6 bullet
b2: circle fill 2 6 0.1
a3: text 3 78 bullet
b3: circle fill 3 78 0.1
a4: text 4 89 bullet
b4: circle fill 4 89 0.1
a5: text 5 7 bullet
b5: circle fill 5 7 0.1
a6: text 6 31 bullet
b6: circle fill 6 31 0.1
a7: text 7 0 bullet
b7: circle fill 7 0 0.1
a8: text 8 43 bullet
b8: circle fill 8 43 0.1
a9: text 9 1 bullet
b9: circle fill 9 1 0.1
a10: text 10 24 bullet
b10: circle fill 10 24 0.1
compline: line <-> fat 2 -8 1 -8
click comps
a1: text 1 6 bullet
b1: circle fill 1 6 0.1
a2: text 2 87 bullet
b2: circle fill 2 87 0.1
click swaps
compline: line <-> fat 3 -8 2 -8
click comps
a2: text 2 78 bullet
b2: circle fill 2 78 0.1
a3: text 3 87 bullet
b3: circle fill 3 87 0.1
click swaps
compline: line <-> fat 2 -8 1 -8
click comps
compline: line <-> fat 4 -8 3 -8
click comps
compline: line <-> fat 5 -8 4 -8
click comps
a4: text 4 7 bullet
b4: circle fill 4 7 0.1
a5: text 5 89 bullet
b5: circle fill 5 89 0.1
click swaps
compline: line <-> fat 4 -8 3 -8
click comps
a3: text 3 7 bullet
b3: circle fill 3 7 0.1
a4: text 4 87 bullet
b4: circle fill 4 87 0.1
click swaps
compline: line <-> fat 3 -8 2 -8
click comps
a2: text 2 7 bullet
b2: circle fill 2 7 0.1
a3: text 3 78 bullet
b3: circle fill 3 78 0.1
click swaps
compline: line <-> fat 2 -8 1 -8
click comps
compline: line <-> fat 6 -8 5 -8
click comps
a5: text 5 31 bullet
b5: circle fill 5 31 0.1
a6: text 6 89 bullet
b6: circle fill 6 89 0.1
click swaps
compline: line <-> fat 5 -8 4 -8
click comps
a4: text 4 31 bullet
b4: circle fill 4 31 0.1
a5: text 5 87 bullet
b5: circle fill 5 87 0.1
click swaps
compline: line <-> fat 4 -8 3 -8
click comps
a3: text 3 31 bullet
b3: circle fill 3 31 0.1
a4: text 4 78 bullet
b4: circle fill 4 78 0.1
click swaps
compline: line <-> fat 3 -8 2 -8
click comps
compline: line <-> fat 7 -8 6 -8
click comps
a6: text 6 0 bullet
b6: circle fill 6 0 0.1
a7: text 7 89 bullet
b7: circle fill 7 89 0.1
click swaps
compline: line <-> fat 6 -8 5 -8
click comps
a5: text 5 0 bullet
b5: circle fill 5 0 0.1
a6: text 6 87 bullet
b6: circle fill 6 87 0.1
click swaps
compline: line <-> fat 5 -8 4 -8
click comps
a4: text 4 0 bullet
b4: circle fill 4 0 0.1
a5: text 5 78 bullet
b5: circle fill 5 78 0.1
click swaps
compline: line <-> fat 4 -8 3 -8
click comps
a3: text 3 0 bullet
b3: circle fill 3 0 0.1
a4: text 4 31 bullet
b4: circle fill 4 31 0.1
click swaps
compline: line <-> fat 3 -8 2 -8
click comps
a2: text 2 0 bullet
b2: circle fill 2 0 0.1
a3: text 3 7 bullet
b3: circle fill 3 7 0.1
click swaps
compline: line <-> fat 2 -8 1 -8
click comps
a1: text 1 0 bullet
b1: circle fill 1 0 0.1
a2: text 2 6 bullet
b2: circle fill 2 6 0.1
click swaps
compline: line <-> fat 8 -8 7 -8
click comps
a7: text 7 43 bullet
b7: circle fill 7 43 0.1
a8: text 8 89 bullet
b8: circle fill 8 89 0.1
click swaps
compline: line <-> fat 7 -8 6 -8
click comps
a6: text 6 43 bullet
b6: circle fill 6 43 0.1
a7: text 7 87 bullet
b7: circle fill 7 87 0.1
click swaps
compline: line <-> fat 6 -8 5 -8
click comps
a5: text 5 43 bullet
b5: circle fill 5 43 0.1
a6: text 6 78 bullet
b6: circle fill 6 78 0.1
click swaps
compline: line <-> fat 5 -8 4 -8
click comps
compline: line <-> fat 9 -8 8 -8
click comps
a8: text 8 1 bullet
b8: circle fill 8 1 0.1
a9: text 9 89 bullet
b9: circle fill 9 89 0.1
click swaps
compline: line <-> fat 8 -8 7 -8
click comps
a7: text 7 1 bullet
b7: circle fill 7 1 0.1
a8: text 8 87 bullet
b8: circle fill 8 87 0.1
click swaps
compline: line <-> fat 7 -8 6 -8
click comps
a6: text 6 1 bullet
b6: circle fill 6 1 0.1
a7: text 7 78 bullet
b7: circle fill 7 78 0.1
click swaps
compline: line <-> fat 6 -8 5 -8
click comps
a5: text 5 1 bullet
b5: circle fill 5 1 0.1
a6: text 6 43 bullet
b6: circle fill 6 43 0.1
click swaps
compline: line <-> fat 5 -8 4 -8
click comps
a4: text 4 1 bullet
b4: circle fill 4 1 0.1
a5: text 5 31 bullet
b5: circle fill 5 31 0.1
click swaps
compline: line <-> fat 4 -8 3 -8
click comps
a3: text 3 1 bullet
b3: circle fill 3 1 0.1
a4: text 4 7 bullet
b4: circle fill 4 7 0.1
click swaps
compline: line <-> fat 3 -8 2 -8
click comps
a2: text 2 1 bullet
b2: circle fill 2 1 0.1
a3: text 3 6 bullet
b3: circle fill 3 6 0.1
click swaps
compline: line <-> fat 2 -8 1 -8
click comps
compline: line <-> fat 10 -8 9 -8
click comps
a9: text 9 24 bullet
b9: circle fill 9 24 0.1
a10: text 10 89 bullet
b10: circle fill 10 89 0.1
click swaps
compline: line <-> fat 9 -8 8 -8
click comps
a8: text 8 24 bullet
b8: circle fill 8 24 0.1
a9: text 9 87 bullet
b9: circle fill 9 87 0.1
click swaps
compline: line <-> fat 8 -8 7 -8
click comps
a7: text 7 24 bullet
b7: circle fill 7 24 0.1
a8: text 8 78 bullet
b8: circle fill 8 78 0.1
click swaps
compline: line <-> fat 7 -8 6 -8
click comps
a6: text 6 24 bullet
b6: circle fill 6 24 0.1
a7: text 7 43 bullet
b7: circle fill 7 43 0.1
click swaps
compline: line <-> fat 6 -8 5 -8
click comps
a5: text 5 24 bullet
b5: circle fill 5 24 0.1
a6: text 6 31 bullet
b6: circle fill 6 31 0.1
click swaps
compline: line <-> fat 5 -8 4 -8
click comps
END OF test.s
echo 'qsort.i' 1>&2
cat >'qsort.i' <<'END OF qsort.i'
d       v       0       current 1       1       50      100
d       v       1       history 1       -9      50      -1
d       c       0       rec.stage
d       c       1       swap
d       c       2       comp
d       p       e
g       1       t       0       cm0     0       8787    bullet
g       2       t       0       cm0     204     606     bullet
g       3       t       0       cm0     408     7878    bullet
g       4       t       0       cm0     612     8989    bullet
g       5       t       0       cm0     816     707     bullet
g       6       t       0       cm0     1020    3131    bullet
g       7       t       0       cm0     1224    0       bullet
g       8       t       0       cm0     1428    4343    bullet
g       9       t       0       cm0     1632    101     bullet
g       10      t       0       cm0     1836    2424    bullet
g       11      t       0       cm0     2040    9595    bullet
g       12      t       0       cm0     2244    1717    bullet
g       13      t       0       cm0     2448    0       bullet
g       14      t       0       cm0     2652    4545    bullet
g       15      t       0       cm0     2856    5757    bullet
g       16      t       0       cm0     3060    4646    bullet
g       17      t       0       cm0     3264    3434    bullet
g       18      t       0       cm0     3469    8888    bullet
g       19      t       0       cm0     3673    5252    bullet
g       20      t       0       cm0     3877    3636    bullet
g       21      t       0       cm0     4081    3535    bullet
g       22      t       0       cm0     4285    4141    bullet
g       23      t       0       cm0     4489    1919    bullet
g       24      t       0       cm0     4693    5252    bullet
g       25      t       0       cm0     4897    7979    bullet
g       26      t       0       cm0     5101    3636    bullet
g       27      t       0       cm0     5305    6565    bullet
g       28      t       0       cm0     5509    1414    bullet
g       29      t       0       cm0     5713    7070    bullet
g       30      t       0       cm0     5917    7979    bullet
g       31      t       0       cm0     6121    8282    bullet
g       32      t       0       cm0     6325    2323    bullet
g       33      t       0       cm0     6529    6060    bullet
g       34      t       0       cm0     6734    404     bullet
g       35      t       0       cm0     6938    6868    bullet
g       36      t       0       cm0     7142    3434    bullet
g       37      t       0       cm0     7346    5959    bullet
g       38      t       0       cm0     7550    9696    bullet
g       39      t       0       cm0     7754    4646    bullet
g       40      t       0       cm0     7958    8787    bullet
g       41      t       0       cm0     8162    8787    bullet
g       42      t       0       cm0     8366    3838    bullet
g       43      t       0       cm0     8570    3232    bullet
g       44      t       0       cm0     8774    1212    bullet
g       45      t       0       cm0     8978    101     bullet
g       46      t       0       cm0     9182    5757    bullet
g       47      t       0       cm0     9386    1818    bullet
g       48      t       0       cm0     9590    1515    bullet
g       49      t       0       cm0     9794    3535    bullet
g       50      t       0       cm0     9999    6262    bullet
c       0
g       0       l       1       s-0     0       9999    9999    9999
e       1       t       0       cm0     0       8787    bullet
g       1       t       0       cm0     0       2323    bullet
e       32      t       0       cm0     6325    2323    bullet
g       32      t       0       cm0     6325    8787    bullet
c       1
g       51      l       0       s-0     0       2323    9999    2323
g       52      l       0       s-0     0       1161    0       6161
g       53      l       0       s-0     204     0       204     9999
c       2
e       2       t       0       cm0     204     606     bullet
g       2       t       0       cm0     204     606     bullet
e       2       t       0       cm0     204     606     bullet
g       2       t       0       cm0     204     606     bullet
c       1
e       52      l       0       s-0     0       1161    0       6161
g       52      l       0       s-0     204     1161    204     6161
e       53      l       0       s-0     204     0       204     9999
g       53      l       0       s-0     408     0       408     9999
c       2
e       53      l       0       s-0     408     0       408     9999
g       53      l       0       s-0     612     0       612     9999
c       2
e       53      l       0       s-0     612     0       612     9999
g       53      l       0       s-0     816     0       816     9999
c       2
e       3       t       0       cm0     408     7878    bullet
g       3       t       0       cm0     408     707     bullet
e       5       t       0       cm0     816     707     bullet
g       5       t       0       cm0     816     7878    bullet
c       1
e       52      l       0       s-0     204     1161    204     6161
g       52      l       0       s-0     408     1161    408     6161
e       53      l       0       s-0     816     0       816     9999
g       53      l       0       s-0     1020    0       1020    9999
c       2
e       53      l       0       s-0     1020    0       1020    9999
g       53      l       0       s-0     1224    0       1224    9999
c       2
e       4       t       0       cm0     612     8989    bullet
g       4       t       0       cm0     612     0       bullet
e       7       t       0       cm0     1224    0       bullet
g       7       t       0       cm0     1224    8989    bullet
c       1
e       52      l       0       s-0     408     1161    408     6161
g       52      l       0       s-0     612     1161    612     6161
e       53      l       0       s-0     1224    0       1224    9999
g       53      l       0       s-0     1428    0       1428    9999
c       2
e       53      l       0       s-0     1428    0       1428    9999
g       53      l       0       s-0     1632    0       1632    9999
c       2
e       5       t       0       cm0     816     7878    bullet
g       5       t       0       cm0     816     101     bullet
e       9       t       0       cm0     1632    101     bullet
g       9       t       0       cm0     1632    7878    bullet
c       1
e       52      l       0       s-0     612     1161    612     6161
g       52      l       0       s-0     816     1161    816     6161
e       53      l       0       s-0     1632    0       1632    9999
g       53      l       0       s-0     1836    0       1836    9999
c       2
e       53      l       0       s-0     1836    0       1836    9999
g       53      l       0       s-0     2040    0       2040    9999
c       2
e       53      l       0       s-0     2040    0       2040    9999
g       53      l       0       s-0     2244    0       2244    9999
c       2
e       6       t       0       cm0     1020    3131    bullet
g       6       t       0       cm0     1020    1717    bullet
e       12      t       0       cm0     2244    1717    bullet
g       12      t       0       cm0     2244    3131    bullet
c       1
e       52      l       0       s-0     816     1161    816     6161
g       52      l       0       s-0     1020    1161    1020    6161
e       53      l       0       s-0     2244    0       2244    9999
g       53      l       0       s-0     2448    0       2448    9999
c       2
e       7       t       0       cm0     1224    8989    bullet
g       7       t       0       cm0     1224    0       bullet
e       13      t       0       cm0     2448    0       bullet
g       13      t       0       cm0     2448    8989    bullet
c       1
e       52      l       0       s-0     1020    1161    1020    6161
g       52      l       0       s-0     1224    1161    1224    6161
e       53      l       0       s-0     2448    0       2448    9999
g       53      l       0       s-0     2652    0       2652    9999
c       2
e       53      l       0       s-0     2652    0       2652    9999
g       53      l       0       s-0     2856    0       2856    9999
c       2
e       53      l       0       s-0     2856    0       2856    9999
g       53      l       0       s-0     3060    0       3060    9999
c       2
e       53      l       0       s-0     3060    0       3060    9999
g       53      l       0       s-0     3264    0       3264    9999
c       2
e       53      l       0       s-0     3264    0       3264    9999
g       53      l       0       s-0     3469    0       3469    9999
c       2
e       53      l       0       s-0     3469    0       3469    9999
g       53      l       0       s-0     3673    0       3673    9999
c       2
e       53      l       0       s-0     3673    0       3673    9999
g       53      l       0       s-0     3877    0       3877    9999
c       2
e       53      l       0       s-0     3877    0       3877    9999
g       53      l       0       s-0     4081    0       4081    9999
c       2
e       53      l       0       s-0     4081    0       4081    9999
g       53      l       0       s-0     4285    0       4285    9999
c       2
e       53      l       0       s-0     4285    0       4285    9999
g       53      l       0       s-0     4489    0       4489    9999
c       2
e       8       t       0       cm0     1428    4343    bullet
g       8       t       0       cm0     1428    1919    bullet
e       23      t       0       cm0     4489    1919    bullet
g       23      t       0       cm0     4489    4343    bullet
c       1
e       52      l       0       s-0     1224    1161    1224    6161
g       52      l       0       s-0     1428    1161    1428    6161
e       53      l       0       s-0     4489    0       4489    9999
g       53      l       0       s-0     4693    0       4693    9999
c       2
e       53      l       0       s-0     4693    0       4693    9999
g       53      l       0       s-0     4897    0       4897    9999
c       2
e       53      l       0       s-0     4897    0       4897    9999
g       53      l       0       s-0     5101    0       5101    9999
c       2
e       53      l       0       s-0     5101    0       5101    9999
g       53      l       0       s-0     5305    0       5305    9999
c       2
e       53      l       0       s-0     5305    0       5305    9999
g       53      l       0       s-0     5509    0       5509    9999
c       2
e       9       t       0       cm0     1632    7878    bullet
g       9       t       0       cm0     1632    1414    bullet
e       28      t       0       cm0     5509    1414    bullet
g       28      t       0       cm0     5509    7878    bullet
c       1
e       52      l       0       s-0     1428    1161    1428    6161
g       52      l       0       s-0     1632    1161    1632    6161
e       53      l       0       s-0     5509    0       5509    9999
g       53      l       0       s-0     5713    0       5713    9999
c       2
e       53      l       0       s-0     5713    0       5713    9999
g       53      l       0       s-0     5917    0       5917    9999
c       2
e       53      l       0       s-0     5917    0       5917    9999
g       53      l       0       s-0     6121    0       6121    9999
c       2
e       53      l       0       s-0     6121    0       6121    9999
g       53      l       0       s-0     6325    0       6325    9999
c       2
e       53      l       0       s-0     6325    0       6325    9999
g       53      l       0       s-0     6529    0       6529    9999
c       2
e       53      l       0       s-0     6529    0       6529    9999
g       53      l       0       s-0     6734    0       6734    9999
c       2
e       10      t       0       cm0     1836    2424    bullet
g       10      t       0       cm0     1836    404     bullet
e       34      t       0       cm0     6734    404     bullet
g       34      t       0       cm0     6734    2424    bullet
c       1
e       52      l       0       s-0     1632    1161    1632    6161
g       52      l       0       s-0     1836    1161    1836    6161
e       53      l       0       s-0     6734    0       6734    9999
g       53      l       0       s-0     6938    0       6938    9999
c       2
e       53      l       0       s-0     6938    0       6938    9999
g       53      l       0       s-0     7142    0       7142    9999
c       2
e       53      l       0       s-0     7142    0       7142    9999
g       53      l       0       s-0     7346    0       7346    9999
c       2
e       53      l       0       s-0     7346    0       7346    9999
g       53      l       0       s-0     7550    0       7550    9999
c       2
e       53      l       0       s-0     7550    0       7550    9999
g       53      l       0       s-0     7754    0       7754    9999
c       2
e       53      l       0       s-0     7754    0       7754    9999
g       53      l       0       s-0     7958    0       7958    9999
c       2
e       53      l       0       s-0     7958    0       7958    9999
g       53      l       0       s-0     8162    0       8162    9999
c       2
e       53      l       0       s-0     8162    0       8162    9999
g       53      l       0       s-0     8366    0       8366    9999
c       2
e       53      l       0       s-0     8366    0       8366    9999
g       53      l       0       s-0     8570    0       8570    9999
c       2
e       53      l       0       s-0     8570    0       8570    9999
g       53      l       0       s-0     8774    0       8774    9999
c       2
e       11      t       0       cm0     2040    9595    bullet
g       11      t       0       cm0     2040    1212    bullet
e       44      t       0       cm0     8774    1212    bullet
g       44      t       0       cm0     8774    9595    bullet
c       1
e       52      l       0       s-0     1836    1161    1836    6161
g       52      l       0       s-0     2040    1161    2040    6161
e       53      l       0       s-0     8774    0       8774    9999
g       53      l       0       s-0     8978    0       8978    9999
c       2
e       12      t       0       cm0     2244    3131    bullet
g       12      t       0       cm0     2244    101     bullet
e       45      t       0       cm0     8978    101     bullet
g       45      t       0       cm0     8978    3131    bullet
c       1
e       52      l       0       s-0     2040    1161    2040    6161
g       52      l       0       s-0     2244    1161    2244    6161
e       53      l       0       s-0     8978    0       8978    9999
g       53      l       0       s-0     9182    0       9182    9999
c       2
e       53      l       0       s-0     9182    0       9182    9999
g       53      l       0       s-0     9386    0       9386    9999
c       2
e       13      t       0       cm0     2448    8989    bullet
g       13      t       0       cm0     2448    1818    bullet
e       47      t       0       cm0     9386    1818    bullet
g       47      t       0       cm0     9386    8989    bullet
c       1
e       52      l       0       s-0     2244    1161    2244    6161
g       52      l       0       s-0     2448    1161    2448    6161
e       53      l       0       s-0     9386    0       9386    9999
g       53      l       0       s-0     9590    0       9590    9999
c       2
e       14      t       0       cm0     2652    4545    bullet
g       14      t       0       cm0     2652    1515    bullet
e       48      t       0       cm0     9590    1515    bullet
g       48      t       0       cm0     9590    4545    bullet
c       1
e       52      l       0       s-0     2448    1161    2448    6161
g       52      l       0       s-0     2652    1161    2652    6161
e       53      l       0       s-0     9590    0       9590    9999
g       53      l       0       s-0     9794    0       9794    9999
c       2
e       53      l       0       s-0     9794    0       9794    9999
g       53      l       0       s-0     9999    0       9999    9999
c       2
e       53      l       0       s-0     9999    0       9999    9999
e       52      l       0       s-0     2652    1161    2652    6161
e       1       t       0       cm0     0       2323    bullet
g       1       t       0       cm0     0       1515    bullet
e       14      t       0       cm0     2652    1515    bullet
g       0       t       0       cm0     2652    2323    bullet
c       1
c       0
g       0       l       1       s-0     0       8749    2448    8749
e       1       t       0       cm0     0       1515    bullet
g       1       t       0       cm0     0       101     bullet
e       12      t       0       cm0     2244    101     bullet
g       12      t       0       cm0     2244    1515    bullet
c       1
g       14      l       0       s-0     0       101     2448    101
g       52      l       0       s-0     0       50      0       1212
g       53      l       0       s-0     204     0       204     2323
c       2
e       53      l       0       s-0     204     0       204     2323
g       53      l       0       s-0     408     0       408     2323
c       2
e       53      l       0       s-0     408     0       408     2323
g       53      l       0       s-0     612     0       612     2323
c       2
e       2       t       0       cm0     204     606     bullet
g       2       t       0       cm0     204     0       bullet
e       4       t       0       cm0     612     0       bullet
g       4       t       0       cm0     612     606     bullet
c       1
e       52      l       0       s-0     0       50      0       1212
g       52      l       0       s-0     204     50      204     1212
e       53      l       0       s-0     612     0       612     2323
g       53      l       0       s-0     816     0       816     2323
c       2
e       53      l       0       s-0     816     0       816     2323
g       53      l       0       s-0     1020    0       1020    2323
c       2
e       53      l       0       s-0     1020    0       1020    2323
g       53      l       0       s-0     1224    0       1224    2323
c       2
e       3       t       0       cm0     408     707     bullet
g       3       t       0       cm0     408     0       bullet
e       7       t       0       cm0     1224    0       bullet
g       7       t       0       cm0     1224    707     bullet
c       1
e       52      l       0       s-0     204     50      204     1212
g       52      l       0       s-0     408     50      408     1212
e       53      l       0       s-0     1224    0       1224    2323
g       53      l       0       s-0     1428    0       1428    2323
c       2
e       53      l       0       s-0     1428    0       1428    2323
g       53      l       0       s-0     1632    0       1632    2323
c       2
e       53      l       0       s-0     1632    0       1632    2323
g       53      l       0       s-0     1836    0       1836    2323
c       2
e       53      l       0       s-0     1836    0       1836    2323
g       53      l       0       s-0     2040    0       2040    2323
c       2
e       53      l       0       s-0     2040    0       2040    2323
g       53      l       0       s-0     2244    0       2244    2323
c       2
e       53      l       0       s-0     2244    0       2244    2323
g       53      l       0       s-0     2448    0       2448    2323
c       2
e       53      l       0       s-0     2448    0       2448    2323
e       52      l       0       s-0     408     50      408     1212
e       1       t       0       cm0     0       101     bullet
g       1       t       0       cm0     0       0       bullet
e       3       t       0       cm0     408     0       bullet
g       0       t       0       cm0     408     101     bullet
c       1
c       0
g       0       l       1       s-0     0       7499    204     7499
e       1       t       0       cm0     0       0       bullet
g       1       t       0       cm0     0       0       bullet
e       2       t       0       cm0     204     0       bullet
g       0       t       0       cm0     204     0       bullet
c       1
g       2       l       0       s-0     0       0       204     0
g       3       l       0       s-0     0       0       0       50
g       52      l       0       s-0     204     0       204     101
c       2
e       52      l       0       s-0     204     0       204     101
e       3       l       0       s-0     0       0       0       50
e       1       t       0       cm0     0       0       bullet
g       1       t       0       cm0     0       0       bullet
e       1       t       0       cm0     0       0       bullet
g       0       t       0       cm0     0       0       bullet
c       1
e       2       l       0       s-0     0       0       204     0
c       0
c       0
g       0       l       1       s-0     612     7499    2448    7499
e       4       t       0       cm0     612     606     bullet
g       4       t       0       cm0     612     1818    bullet
e       13      t       0       cm0     2448    1818    bullet
g       13      t       0       cm0     2448    606     bullet
c       1
g       2       l       0       s-0     612     1818    2448    1818
g       1       l       0       s-0     612     959     612     2070
g       3       l       0       s-0     816     101     816     2323
c       2
e       5       t       0       cm0     816     101     bullet
g       5       t       0       cm0     816     101     bullet
e       5       t       0       cm0     816     101     bullet
g       5       t       0       cm0     816     101     bullet
c       1
e       1       l       0       s-0     612     959     612     2070
g       1       l       0       s-0     816     959     816     2070
e       3       l       0       s-0     816     101     816     2323
g       3       l       0       s-0     1020    101     1020    2323
c       2
e       6       t       0       cm0     1020    1717    bullet
g       6       t       0       cm0     1020    1717    bullet
e       6       t       0       cm0     1020    1717    bullet
g       6       t       0       cm0     1020    1717    bullet
c       1
e       1       l       0       s-0     816     959     816     2070
g       1       l       0       s-0     1020    959     1020    2070
e       3       l       0       s-0     1020    101     1020    2323
g       3       l       0       s-0     1224    101     1224    2323
c       2
e       7       t       0       cm0     1224    707     bullet
g       7       t       0       cm0     1224    707     bullet
e       7       t       0       cm0     1224    707     bullet
g       7       t       0       cm0     1224    707     bullet
c       1
e       1       l       0       s-0     1020    959     1020    2070
g       1       l       0       s-0     1224    959     1224    2070
e       3       l       0       s-0     1224    101     1224    2323
g       3       l       0       s-0     1428    101     1428    2323
c       2
e       3       l       0       s-0     1428    101     1428    2323
g       3       l       0       s-0     1632    101     1632    2323
c       2
e       8       t       0       cm0     1428    1919    bullet
g       8       t       0       cm0     1428    1414    bullet
e       9       t       0       cm0     1632    1414    bullet
g       9       t       0       cm0     1632    1919    bullet
c       1
e       1       l       0       s-0     1224    959     1224    2070
g       1       l       0       s-0     1428    959     1428    2070
e       3       l       0       s-0     1632    101     1632    2323
g       3       l       0       s-0     1836    101     1836    2323
c       2
e       9       t       0       cm0     1632    1919    bullet
g       9       t       0       cm0     1632    404     bullet
e       10      t       0       cm0     1836    404     bullet
g       10      t       0       cm0     1836    1919    bullet
c       1
e       1       l       0       s-0     1428    959     1428    2070
g       1       l       0       s-0     1632    959     1632    2070
e       3       l       0       s-0     1836    101     1836    2323
g       3       l       0       s-0     2040    101     2040    2323
c       2
e       10      t       0       cm0     1836    1919    bullet
g       10      t       0       cm0     1836    1212    bullet
e       11      t       0       cm0     2040    1212    bullet
g       11      t       0       cm0     2040    1919    bullet
c       1
e       1       l       0       s-0     1632    959     1632    2070
g       1       l       0       s-0     1836    959     1836    2070
e       3       l       0       s-0     2040    101     2040    2323
g       3       l       0       s-0     2244    101     2244    2323
c       2
e       11      t       0       cm0     2040    1919    bullet
g       11      t       0       cm0     2040    1515    bullet
e       12      t       0       cm0     2244    1515    bullet
g       12      t       0       cm0     2244    1919    bullet
c       1
e       1       l       0       s-0     1836    959     1836    2070
g       1       l       0       s-0     2040    959     2040    2070
e       3       l       0       s-0     2244    101     2244    2323
g       3       l       0       s-0     2448    101     2448    2323
c       2
e       12      t       0       cm0     2244    1919    bullet
g       12      t       0       cm0     2244    606     bullet
e       13      t       0       cm0     2448    606     bullet
g       0       t       0       cm0     2448    1919    bullet
c       1
e       1       l       0       s-0     2040    959     2040    2070
g       1       l       0       s-0     2244    959     2244    2070
e       3       l       0       s-0     2448    101     2448    2323
e       1       l       0       s-0     2244    959     2244    2070
e       4       t       0       cm0     612     1818    bullet
g       4       t       0       cm0     612     606     bullet
e       12      t       0       cm0     2244    606     bullet
g       0       t       0       cm0     2244    1818    bullet
c       1
c       0
g       0       l       1       s-0     612     6249    2040    6249
e       4       t       0       cm0     612     606     bullet
g       4       t       0       cm0     612     1414    bullet
e       8       t       0       cm0     1428    1414    bullet
g       8       t       0       cm0     1428    606     bullet
c       1
g       12      l       0       s-0     612     1414    2040    1414
g       1       l       0       s-0     612     757     612     1616
g       3       l       0       s-0     816     101     816     1818
c       2
e       5       t       0       cm0     816     101     bullet
g       5       t       0       cm0     816     101     bullet
e       5       t       0       cm0     816     101     bullet
g       5       t       0       cm0     816     101     bullet
c       1
e       1       l       0       s-0     612     757     612     1616
g       1       l       0       s-0     816     757     816     1616
e       3       l       0       s-0     816     101     816     1818
g       3       l       0       s-0     1020    101     1020    1818
c       2
e       3       l       0       s-0     1020    101     1020    1818
g       3       l       0       s-0     1224    101     1224    1818
c       2
e       6       t       0       cm0     1020    1717    bullet
g       6       t       0       cm0     1020    707     bullet
e       7       t       0       cm0     1224    707     bullet
g       7       t       0       cm0     1224    1717    bullet
c       1
e       1       l       0       s-0     816     757     816     1616
g       1       l       0       s-0     1020    757     1020    1616
e       3       l       0       s-0     1224    101     1224    1818
g       3       l       0       s-0     1428    101     1428    1818
c       2
e       7       t       0       cm0     1224    1717    bullet
g       7       t       0       cm0     1224    606     bullet
e       8       t       0       cm0     1428    606     bullet
g       8       t       0       cm0     1428    1717    bullet
c       1
e       1       l       0       s-0     1020    757     1020    1616
g       1       l       0       s-0     1224    757     1224    1616
e       3       l       0       s-0     1428    101     1428    1818
g       3       l       0       s-0     1632    101     1632    1818
c       2
e       8       t       0       cm0     1428    1717    bullet
g       8       t       0       cm0     1428    404     bullet
e       9       t       0       cm0     1632    404     bullet
g       9       t       0       cm0     1632    1717    bullet
c       1
e       1       l       0       s-0     1224    757     1224    1616
g       1       l       0       s-0     1428    757     1428    1616
e       3       l       0       s-0     1632    101     1632    1818
g       3       l       0       s-0     1836    101     1836    1818
c       2
e       9       t       0       cm0     1632    1717    bullet
g       9       t       0       cm0     1632    1212    bullet
e       10      t       0       cm0     1836    1212    bullet
g       10      t       0       cm0     1836    1717    bullet
c       1
e       1       l       0       s-0     1428    757     1428    1616
g       1       l       0       s-0     1632    757     1632    1616
e       3       l       0       s-0     1836    101     1836    1818
g       3       l       0       s-0     2040    101     2040    1818
c       2
e       3       l       0       s-0     2040    101     2040    1818
e       1       l       0       s-0     1632    757     1632    1616
e       4       t       0       cm0     612     1414    bullet
g       4       t       0       cm0     612     1212    bullet
e       9       t       0       cm0     1632    1212    bullet
g       0       t       0       cm0     1632    1414    bullet
c       1
c       0
g       0       l       1       s-0     612     4999    1428    4999
e       4       t       0       cm0     612     1212    bullet
g       4       t       0       cm0     612     1212    bullet
e       4       t       0       cm0     612     1212    bullet
g       4       t       0       cm0     612     1212    bullet
c       1
g       9       l       0       s-0     612     1212    1428    1212
g       1       l       0       s-0     612     656     612     1313
g       3       l       0       s-0     816     101     816     1414
c       2
e       5       t       0       cm0     816     101     bullet
g       5       t       0       cm0     816     101     bullet
e       5       t       0       cm0     816     101     bullet
g       5       t       0       cm0     816     101     bullet
c       1
e       1       l       0       s-0     612     656     612     1313
g       1       l       0       s-0     816     656     816     1313
e       3       l       0       s-0     816     101     816     1414
g       3       l       0       s-0     1020    101     1020    1414
c       2
e       6       t       0       cm0     1020    707     bullet
g       6       t       0       cm0     1020    707     bullet
e       6       t       0       cm0     1020    707     bullet
g       6       t       0       cm0     1020    707     bullet
c       1
e       1       l       0       s-0     816     656     816     1313
g       1       l       0       s-0     1020    656     1020    1313
e       3       l       0       s-0     1020    101     1020    1414
g       3       l       0       s-0     1224    101     1224    1414
c       2
e       7       t       0       cm0     1224    606     bullet
g       7       t       0       cm0     1224    606     bullet
e       7       t       0       cm0     1224    606     bullet
g       7       t       0       cm0     1224    606     bullet
c       1
e       1       l       0       s-0     1020    656     1020    1313
g       1       l       0       s-0     1224    656     1224    1313
e       3       l       0       s-0     1224    101     1224    1414
g       3       l       0       s-0     1428    101     1428    1414
c       2
e       8       t       0       cm0     1428    404     bullet
g       8       t       0       cm0     1428    404     bullet
e       8       t       0       cm0     1428    404     bullet
g       8       t       0       cm0     1428    404     bullet
c       1
e       1       l       0       s-0     1224    656     1224    1313
g       1       l       0       s-0     1428    656     1428    1313
e       3       l       0       s-0     1428    101     1428    1414
e       1       l       0       s-0     1428    656     1428    1313
e       4       t       0       cm0     612     1212    bullet
g       4       t       0       cm0     612     404     bullet
e       8       t       0       cm0     1428    404     bullet
g       0       t       0       cm0     1428    1212    bullet
c       1
c       0
g       0       l       1       s-0     612     3749    1224    3749
e       4       t       0       cm0     612     404     bullet
g       4       t       0       cm0     612     707     bullet
e       6       t       0       cm0     1020    707     bullet
g       6       t       0       cm0     1020    404     bullet
c       1
g       8       l       0       s-0     612     707     1224    707
g       1       l       0       s-0     612     404     612     959
g       3       l       0       s-0     816     101     816     1212
c       2
e       5       t       0       cm0     816     101     bullet
g       5       t       0       cm0     816     101     bullet
e       5       t       0       cm0     816     101     bullet
g       5       t       0       cm0     816     101     bullet
c       1
e       1       l       0       s-0     612     404     612     959
g       1       l       0       s-0     816     404     816     959
e       3       l       0       s-0     816     101     816     1212
g       3       l       0       s-0     1020    101     1020    1212
c       2
e       6       t       0       cm0     1020    404     bullet
g       6       t       0       cm0     1020    404     bullet
e       6       t       0       cm0     1020    404     bullet
g       6       t       0       cm0     1020    404     bullet
c       1
e       1       l       0       s-0     816     404     816     959
g       1       l       0       s-0     1020    404     1020    959
e       3       l       0       s-0     1020    101     1020    1212
g       3       l       0       s-0     1224    101     1224    1212
c       2
e       7       t       0       cm0     1224    606     bullet
g       7       t       0       cm0     1224    606     bullet
e       7       t       0       cm0     1224    606     bullet
g       7       t       0       cm0     1224    606     bullet
c       1
e       1       l       0       s-0     1020    404     1020    959
g       1       l       0       s-0     1224    404     1224    959
e       3       l       0       s-0     1224    101     1224    1212
e       1       l       0       s-0     1224    404     1224    959
e       4       t       0       cm0     612     707     bullet
g       4       t       0       cm0     612     606     bullet
e       7       t       0       cm0     1224    606     bullet
g       0       t       0       cm0     1224    707     bullet
c       1
c       0
g       0       l       1       s-0     612     2499    1020    2499
e       4       t       0       cm0     612     606     bullet
g       4       t       0       cm0     612     101     bullet
e       5       t       0       cm0     816     101     bullet
g       5       t       0       cm0     816     606     bullet
c       1
g       7       l       0       s-0     612     101     1020    101
g       1       l       0       s-0     612     101     612     404
g       3       l       0       s-0     816     101     816     707
c       2
e       3       l       0       s-0     816     101     816     707
g       3       l       0       s-0     1020    101     1020    707
c       2
e       3       l       0       s-0     1020    101     1020    707
e       1       l       0       s-0     612     101     612     404
e       4       t       0       cm0     612     101     bullet
g       4       t       0       cm0     612     101     bullet
e       4       t       0       cm0     612     101     bullet
g       0       t       0       cm0     612     101     bullet
c       1
c       0
g       0       l       1       s-0     816     1249    1020    1249
e       5       t       0       cm0     816     606     bullet
g       5       t       0       cm0     816     606     bullet
e       5       t       0       cm0     816     606     bullet
g       5       t       0       cm0     816     606     bullet
c       1
g       4       l       0       s-0     816     606     1020    606
g       1       l       0       s-0     816     353     816     656
g       3       l       0       s-0     1020    101     1020    707
c       2
e       6       t       0       cm0     1020    404     bullet
g       6       t       0       cm0     1020    404     bullet
e       6       t       0       cm0     1020    404     bullet
g       6       t       0       cm0     1020    404     bullet
c       1
e       1       l       0       s-0     816     353     816     656
g       1       l       0       s-0     1020    353     1020    656
e       3       l       0       s-0     1020    101     1020    707
e       1       l       0       s-0     1020    353     1020    656
e       5       t       0       cm0     816     606     bullet
g       0       t       0       cm0     816     404     bullet
e       6       t       0       cm0     1020    404     bullet
g       0       t       0       cm0     1020    606     bullet
c       1
e       4       l       0       s-0     816     606     1020    606
c       0
e       7       l       0       s-0     612     101     1020    101
c       0
e       8       l       0       s-0     612     707     1224    707
c       0
e       9       l       0       s-0     612     1212    1428    1212
c       0
c       0
g       0       l       1       s-0     1836    4999    2040    4999
e       10      t       0       cm0     1836    1717    bullet
g       10      t       0       cm0     1836    1515    bullet
e       11      t       0       cm0     2040    1515    bullet
g       0       t       0       cm0     2040    1717    bullet
c       1
g       11      l       0       s-0     1836    1515    2040    1515
g       9       l       0       s-0     1836    1464    1836    1666
g       8       l       0       s-0     2040    1414    2040    1818
c       2
e       8       l       0       s-0     2040    1414    2040    1818
e       9       l       0       s-0     1836    1464    1836    1666
e       10      t       0       cm0     1836    1515    bullet
g       10      t       0       cm0     1836    1515    bullet
e       10      t       0       cm0     1836    1515    bullet
g       0       t       0       cm0     1836    1515    bullet
c       1
e       11      l       0       s-0     1836    1515    2040    1515
c       0
e       12      l       0       s-0     612     1414    2040    1414
c       0
e       2       l       0       s-0     612     1818    2448    1818
c       0
e       14      l       0       s-0     0       101     2448    101
c       0
c       0
g       0       l       1       s-0     2856    8749    9999    8749
e       15      t       0       cm0     2856    5757    bullet
g       15      t       0       cm0     2856    4141    bullet
e       22      t       0       cm0     4285    4141    bullet
g       22      t       0       cm0     4285    5757    bullet
c       1
g       14      l       0       s-0     2856    4141    9999    4141
g       2       l       0       s-0     2856    3232    2856    7070
g       12      l       0       s-0     3060    2323    3060    9999
c       2
e       12      l       0       s-0     3060    2323    3060    9999
g       12      l       0       s-0     3264    2323    3264    9999
c       2
e       16      t       0       cm0     3060    4646    bullet
g       16      t       0       cm0     3060    3434    bullet
e       17      t       0       cm0     3264    3434    bullet
g       17      t       0       cm0     3264    4646    bullet
c       1
e       2       l       0       s-0     2856    3232    2856    7070
g       2       l       0       s-0     3060    3232    3060    7070
e       12      l       0       s-0     3264    2323    3264    9999
g       12      l       0       s-0     3469    2323    3469    9999
c       2
e       12      l       0       s-0     3469    2323    3469    9999
g       12      l       0       s-0     3673    2323    3673    9999
c       2
e       12      l       0       s-0     3673    2323    3673    9999
g       12      l       0       s-0     3877    2323    3877    9999
c       2
e       17      t       0       cm0     3264    4646    bullet
g       17      t       0       cm0     3264    3636    bullet
e       20      t       0       cm0     3877    3636    bullet
g       20      t       0       cm0     3877    4646    bullet
c       1
e       2       l       0       s-0     3060    3232    3060    7070
g       2       l       0       s-0     3264    3232    3264    7070
e       12      l       0       s-0     3877    2323    3877    9999
g       12      l       0       s-0     4081    2323    4081    9999
c       2
e       18      t       0       cm0     3469    8888    bullet
g       18      t       0       cm0     3469    3535    bullet
e       21      t       0       cm0     4081    3535    bullet
g       21      t       0       cm0     4081    8888    bullet
c       1
e       2       l       0       s-0     3264    3232    3264    7070
g       2       l       0       s-0     3469    3232    3469    7070
e       12      l       0       s-0     4081    2323    4081    9999
g       12      l       0       s-0     4285    2323    4285    9999
c       2
e       12      l       0       s-0     4285    2323    4285    9999
g       12      l       0       s-0     4489    2323    4489    9999
c       2
e       12      l       0       s-0     4489    2323    4489    9999
g       12      l       0       s-0     4693    2323    4693    9999
c       2
e       12      l       0       s-0     4693    2323    4693    9999
g       12      l       0       s-0     4897    2323    4897    9999
c       2
e       12      l       0       s-0     4897    2323    4897    9999
g       12      l       0       s-0     5101    2323    5101    9999
c       2
e       19      t       0       cm0     3673    5252    bullet
g       19      t       0       cm0     3673    3636    bullet
e       26      t       0       cm0     5101    3636    bullet
g       26      t       0       cm0     5101    5252    bullet
c       1
e       2       l       0       s-0     3469    3232    3469    7070
g       2       l       0       s-0     3673    3232    3673    7070
e       12      l       0       s-0     5101    2323    5101    9999
g       12      l       0       s-0     5305    2323    5305    9999
c       2
e       12      l       0       s-0     5305    2323    5305    9999
g       12      l       0       s-0     5509    2323    5509    9999
c       2
e       12      l       0       s-0     5509    2323    5509    9999
g       12      l       0       s-0     5713    2323    5713    9999
c       2
e       12      l       0       s-0     5713    2323    5713    9999
g       12      l       0       s-0     5917    2323    5917    9999
c       2
e       12      l       0       s-0     5917    2323    5917    9999
g       12      l       0       s-0     6121    2323    6121    9999
c       2
e       12      l       0       s-0     6121    2323    6121    9999
g       12      l       0       s-0     6325    2323    6325    9999
c       2
e       12      l       0       s-0     6325    2323    6325    9999
g       12      l       0       s-0     6529    2323    6529    9999
c       2
e       12      l       0       s-0     6529    2323    6529    9999
g       12      l       0       s-0     6734    2323    6734    9999
c       2
e       20      t       0       cm0     3877    4646    bullet
g       20      t       0       cm0     3877    2424    bullet
e       34      t       0       cm0     6734    2424    bullet
g       34      t       0       cm0     6734    4646    bullet
c       1
e       2       l       0       s-0     3673    3232    3673    7070
g       2       l       0       s-0     3877    3232    3877    7070
e       12      l       0       s-0     6734    2323    6734    9999
g       12      l       0       s-0     6938    2323    6938    9999
c       2
e       12      l       0       s-0     6938    2323    6938    9999
g       12      l       0       s-0     7142    2323    7142    9999
c       2
e       21      t       0       cm0     4081    8888    bullet
g       21      t       0       cm0     4081    3434    bullet
e       36      t       0       cm0     7142    3434    bullet
g       36      t       0       cm0     7142    8888    bullet
c       1
e       2       l       0       s-0     3877    3232    3877    7070
g       2       l       0       s-0     4081    3232    4081    7070
e       12      l       0       s-0     7142    2323    7142    9999
g       12      l       0       s-0     7346    2323    7346    9999
c       2
e       12      l       0       s-0     7346    2323    7346    9999
g       12      l       0       s-0     7550    2323    7550    9999
c       2
e       12      l       0       s-0     7550    2323    7550    9999
g       12      l       0       s-0     7754    2323    7754    9999
c       2
e       12      l       0       s-0     7754    2323    7754    9999
g       12      l       0       s-0     7958    2323    7958    9999
c       2
e       12      l       0       s-0     7958    2323    7958    9999
g       12      l       0       s-0     8162    2323    8162    9999
c       2
e       12      l       0       s-0     8162    2323    8162    9999
g       12      l       0       s-0     8366    2323    8366    9999
c       2
e       22      t       0       cm0     4285    5757    bullet
g       22      t       0       cm0     4285    3838    bullet
e       42      t       0       cm0     8366    3838    bullet
g       42      t       0       cm0     8366    5757    bullet
c       1
e       2       l       0       s-0     4081    3232    4081    7070
g       2       l       0       s-0     4285    3232    4285    7070
e       12      l       0       s-0     8366    2323    8366    9999
g       12      l       0       s-0     8570    2323    8570    9999
c       2
e       23      t       0       cm0     4489    4343    bullet
g       23      t       0       cm0     4489    3232    bullet
e       43      t       0       cm0     8570    3232    bullet
g       43      t       0       cm0     8570    4343    bullet
c       1
e       2       l       0       s-0     4285    3232    4285    7070
g       2       l       0       s-0     4489    3232    4489    7070
e       12      l       0       s-0     8570    2323    8570    9999
g       12      l       0       s-0     8774    2323    8774    9999
c       2
e       12      l       0       s-0     8774    2323    8774    9999
g       12      l       0       s-0     8978    2323    8978    9999
c       2
e       24      t       0       cm0     4693    5252    bullet
g       24      t       0       cm0     4693    3131    bullet
e       45      t       0       cm0     8978    3131    bullet
g       45      t       0       cm0     8978    5252    bullet
c       1
e       2       l       0       s-0     4489    3232    4489    7070
g       2       l       0       s-0     4693    3232    4693    7070
e       12      l       0       s-0     8978    2323    8978    9999
g       12      l       0       s-0     9182    2323    9182    9999
c       2
e       12      l       0       s-0     9182    2323    9182    9999
g       12      l       0       s-0     9386    2323    9386    9999
c       2
e       12      l       0       s-0     9386    2323    9386    9999
g       12      l       0       s-0     9590    2323    9590    9999
c       2
e       12      l       0       s-0     9590    2323    9590    9999
g       12      l       0       s-0     9794    2323    9794    9999
c       2
e       25      t       0       cm0     4897    7979    bullet
g       25      t       0       cm0     4897    3535    bullet
e       49      t       0       cm0     9794    3535    bullet
g       49      t       0       cm0     9794    7979    bullet
c       1
e       2       l       0       s-0     4693    3232    4693    7070
g       2       l       0       s-0     4897    3232    4897    7070
e       12      l       0       s-0     9794    2323    9794    9999
g       12      l       0       s-0     9999    2323    9999    9999
c       2
e       12      l       0       s-0     9999    2323    9999    9999
e       2       l       0       s-0     4897    3232    4897    7070
e       15      t       0       cm0     2856    4141    bullet
g       15      t       0       cm0     2856    3535    bullet
e       25      t       0       cm0     4897    3535    bullet
g       0       t       0       cm0     4897    4141    bullet
c       1
c       0
g       0       l       1       s-0     2856    7499    4693    7499
e       15      t       0       cm0     2856    3535    bullet
g       15      t       0       cm0     2856    3838    bullet
e       22      t       0       cm0     4285    3838    bullet
g       22      t       0       cm0     4285    3535    bullet
c       1
g       25      l       0       s-0     2856    3838    4693    3838
g       2       l       0       s-0     2856    3080    2856    3989
g       12      l       0       s-0     3060    2323    3060    4141
c       2
e       16      t       0       cm0     3060    3434    bullet
g       16      t       0       cm0     3060    3434    bullet
e       16      t       0       cm0     3060    3434    bullet
g       16      t       0       cm0     3060    3434    bullet
c       1
e       2       l       0       s-0     2856    3080    2856    3989
g       2       l       0       s-0     3060    3080    3060    3989
e       12      l       0       s-0     3060    2323    3060    4141
g       12      l       0       s-0     3264    2323    3264    4141
c       2
e       17      t       0       cm0     3264    3636    bullet
g       17      t       0       cm0     3264    3636    bullet
e       17      t       0       cm0     3264    3636    bullet
g       17      t       0       cm0     3264    3636    bullet
c       1
e       2       l       0       s-0     3060    3080    3060    3989
g       2       l       0       s-0     3264    3080    3264    3989
e       12      l       0       s-0     3264    2323    3264    4141
g       12      l       0       s-0     3469    2323    3469    4141
c       2
e       18      t       0       cm0     3469    3535    bullet
g       18      t       0       cm0     3469    3535    bullet
e       18      t       0       cm0     3469    3535    bullet
g       18      t       0       cm0     3469    3535    bullet
c       1
e       2       l       0       s-0     3264    3080    3264    3989
g       2       l       0       s-0     3469    3080    3469    3989
e       12      l       0       s-0     3469    2323    3469    4141
g       12      l       0       s-0     3673    2323    3673    4141
c       2
e       19      t       0       cm0     3673    3636    bullet
g       19      t       0       cm0     3673    3636    bullet
e       19      t       0       cm0     3673    3636    bullet
g       19      t       0       cm0     3673    3636    bullet
c       1
e       2       l       0       s-0     3469    3080    3469    3989
g       2       l       0       s-0     3673    3080    3673    3989
e       12      l       0       s-0     3673    2323    3673    4141
g       12      l       0       s-0     3877    2323    3877    4141
c       2
e       20      t       0       cm0     3877    2424    bullet
g       20      t       0       cm0     3877    2424    bullet
e       20      t       0       cm0     3877    2424    bullet
g       20      t       0       cm0     3877    2424    bullet
c       1
e       2       l       0       s-0     3673    3080    3673    3989
g       2       l       0       s-0     3877    3080    3877    3989
e       12      l       0       s-0     3877    2323    3877    4141
g       12      l       0       s-0     4081    2323    4081    4141
c       2
e       21      t       0       cm0     4081    3434    bullet
g       21      t       0       cm0     4081    3434    bullet
e       21      t       0       cm0     4081    3434    bullet
g       21      t       0       cm0     4081    3434    bullet
c       1
e       2       l       0       s-0     3877    3080    3877    3989
g       2       l       0       s-0     4081    3080    4081    3989
e       12      l       0       s-0     4081    2323    4081    4141
g       12      l       0       s-0     4285    2323    4285    4141
c       2
e       22      t       0       cm0     4285    3535    bullet
g       22      t       0       cm0     4285    3535    bullet
e       22      t       0       cm0     4285    3535    bullet
g       22      t       0       cm0     4285    3535    bullet
c       1
e       2       l       0       s-0     4081    3080    4081    3989
g       2       l       0       s-0     4285    3080    4285    3989
e       12      l       0       s-0     4285    2323    4285    4141
g       12      l       0       s-0     4489    2323    4489    4141
c       2
e       23      t       0       cm0     4489    3232    bullet
g       23      t       0       cm0     4489    3232    bullet
e       23      t       0       cm0     4489    3232    bullet
g       23      t       0       cm0     4489    3232    bullet
c       1
e       2       l       0       s-0     4285    3080    4285    3989
g       2       l       0       s-0     4489    3080    4489    3989
e       12      l       0       s-0     4489    2323    4489    4141
g       12      l       0       s-0     4693    2323    4693    4141
c       2
e       24      t       0       cm0     4693    3131    bullet
g       24      t       0       cm0     4693    3131    bullet
e       24      t       0       cm0     4693    3131    bullet
g       24      t       0       cm0     4693    3131    bullet
c       1
e       2       l       0       s-0     4489    3080    4489    3989
g       2       l       0       s-0     4693    3080    4693    3989
e       12      l       0       s-0     4693    2323    4693    4141
e       2       l       0       s-0     4693    3080    4693    3989
e       15      t       0       cm0     2856    3838    bullet
g       15      t       0       cm0     2856    3131    bullet
e       24      t       0       cm0     4693    3131    bullet
g       0       t       0       cm0     4693    3838    bullet
c       1
c       0
g       0       l       1       s-0     2856    6249    4489    6249
e       15      t       0       cm0     2856    3131    bullet
g       15      t       0       cm0     2856    3232    bullet
e       23      t       0       cm0     4489    3232    bullet
g       23      t       0       cm0     4489    3131    bullet
c       1
g       24      l       0       s-0     2856    3232    4489    3232
g       2       l       0       s-0     2856    2777    2856    3535
g       12      l       0       s-0     3060    2323    3060    3838
c       2
e       12      l       0       s-0     3060    2323    3060    3838
g       12      l       0       s-0     3264    2323    3264    3838
c       2
e       12      l       0       s-0     3264    2323    3264    3838
g       12      l       0       s-0     3469    2323    3469    3838
c       2
e       12      l       0       s-0     3469    2323    3469    3838
g       12      l       0       s-0     3673    2323    3673    3838
c       2
e       12      l       0       s-0     3673    2323    3673    3838
g       12      l       0       s-0     3877    2323    3877    3838
c       2
e       16      t       0       cm0     3060    3434    bullet
g       16      t       0       cm0     3060    2424    bullet
e       20      t       0       cm0     3877    2424    bullet
g       20      t       0       cm0     3877    3434    bullet
c       1
e       2       l       0       s-0     2856    2777    2856    3535
g       2       l       0       s-0     3060    2777    3060    3535
e       12      l       0       s-0     3877    2323    3877    3838
g       12      l       0       s-0     4081    2323    4081    3838
c       2
e       12      l       0       s-0     4081    2323    4081    3838
g       12      l       0       s-0     4285    2323    4285    3838
c       2
e       12      l       0       s-0     4285    2323    4285    3838
g       12      l       0       s-0     4489    2323    4489    3838
c       2
e       17      t       0       cm0     3264    3636    bullet
g       17      t       0       cm0     3264    3131    bullet
e       23      t       0       cm0     4489    3131    bullet
g       23      t       0       cm0     4489    3636    bullet
c       1
e       2       l       0       s-0     3060    2777    3060    3535
g       2       l       0       s-0     3264    2777    3264    3535
e       12      l       0       s-0     4489    2323    4489    3838
e       2       l       0       s-0     3264    2777    3264    3535
e       15      t       0       cm0     2856    3232    bullet
g       15      t       0       cm0     2856    3131    bullet
e       17      t       0       cm0     3264    3131    bullet
g       0       t       0       cm0     3264    3232    bullet
c       1
c       0
g       0       l       1       s-0     2856    4999    3060    4999
e       15      t       0       cm0     2856    3131    bullet
g       15      t       0       cm0     2856    2424    bullet
e       16      t       0       cm0     3060    2424    bullet
g       0       t       0       cm0     3060    3131    bullet
c       1
g       16      l       0       s-0     2856    2424    3060    2424
g       17      l       0       s-0     2856    2373    2856    2828
g       2       l       0       s-0     3060    2323    3060    3232
c       2
e       2       l       0       s-0     3060    2323    3060    3232
e       17      l       0       s-0     2856    2373    2856    2828
e       15      t       0       cm0     2856    2424    bullet
g       15      t       0       cm0     2856    2424    bullet
e       15      t       0       cm0     2856    2424    bullet
g       0       t       0       cm0     2856    2424    bullet
c       1
e       16      l       0       s-0     2856    2424    3060    2424
c       0
c       0
g       0       l       1       s-0     3469    4999    4489    4999
e       18      t       0       cm0     3469    3535    bullet
g       18      t       0       cm0     3469    3535    bullet
e       18      t       0       cm0     3469    3535    bullet
g       18      t       0       cm0     3469    3535    bullet
c       1
g       16      l       0       s-0     3469    3535    4489    3535
g       15      l       0       s-0     3469    3383    3469    3686
g       17      l       0       s-0     3673    3232    3673    3838
c       2
e       17      l       0       s-0     3673    3232    3673    3838
g       17      l       0       s-0     3877    3232    3877    3838
c       2
e       19      t       0       cm0     3673    3636    bullet
g       19      t       0       cm0     3673    3434    bullet
e       20      t       0       cm0     3877    3434    bullet
g       20      t       0       cm0     3877    3636    bullet
c       1
e       15      l       0       s-0     3469    3383    3469    3686
g       15      l       0       s-0     3673    3383    3673    3686
e       17      l       0       s-0     3877    3232    3877    3838
g       17      l       0       s-0     4081    3232    4081    3838
c       2
e       20      t       0       cm0     3877    3636    bullet
g       20      t       0       cm0     3877    3434    bullet
e       21      t       0       cm0     4081    3434    bullet
g       21      t       0       cm0     4081    3636    bullet
c       1
e       15      l       0       s-0     3673    3383    3673    3686
g       15      l       0       s-0     3877    3383    3877    3686
e       17      l       0       s-0     4081    3232    4081    3838
g       17      l       0       s-0     4285    3232    4285    3838
c       2
e       17      l       0       s-0     4285    3232    4285    3838
g       17      l       0       s-0     4489    3232    4489    3838
c       2
e       17      l       0       s-0     4489    3232    4489    3838
e       15      l       0       s-0     3877    3383    3877    3686
e       18      t       0       cm0     3469    3535    bullet
g       18      t       0       cm0     3469    3434    bullet
e       20      t       0       cm0     3877    3434    bullet
g       0       t       0       cm0     3877    3535    bullet
c       1
c       0
g       0       l       1       s-0     3469    3749    3673    3749
e       18      t       0       cm0     3469    3434    bullet
g       18      t       0       cm0     3469    3434    bullet
e       19      t       0       cm0     3673    3434    bullet
g       0       t       0       cm0     3673    3434    bullet
c       1
g       19      l       0       s-0     3469    3434    3673    3434
g       20      l       0       s-0     3469    3333    3469    3484
g       15      l       0       s-0     3673    3232    3673    3535
c       2
e       15      l       0       s-0     3673    3232    3673    3535
e       20      l       0       s-0     3469    3333    3469    3484
e       18      t       0       cm0     3469    3434    bullet
g       18      t       0       cm0     3469    3434    bullet
e       18      t       0       cm0     3469    3434    bullet
g       0       t       0       cm0     3469    3434    bullet
c       1
e       19      l       0       s-0     3469    3434    3673    3434
c       0
c       0
g       0       l       1       s-0     4081    3749    4489    3749
e       21      t       0       cm0     4081    3636    bullet
g       21      t       0       cm0     4081    3535    bullet
e       22      t       0       cm0     4285    3535    bullet
g       22      t       0       cm0     4285    3636    bullet
c       1
g       19      l       0       s-0     4081    3535    4489    3535
g       18      l       0       s-0     4081    3535    4081    3686
g       20      l       0       s-0     4285    3535    4285    3838
c       2
e       20      l       0       s-0     4285    3535    4285    3838
g       20      l       0       s-0     4489    3535    4489    3838
c       2
e       20      l       0       s-0     4489    3535    4489    3838
e       18      l       0       s-0     4081    3535    4081    3686
e       21      t       0       cm0     4081    3535    bullet
g       21      t       0       cm0     4081    3535    bullet
e       21      t       0       cm0     4081    3535    bullet
g       0       t       0       cm0     4081    3535    bullet
c       1
c       0
g       0       l       1       s-0     4285    2499    4489    2499
e       22      t       0       cm0     4285    3636    bullet
g       22      t       0       cm0     4285    3636    bullet
e       23      t       0       cm0     4489    3636    bullet
g       0       t       0       cm0     4489    3636    bullet
c       1
g       23      l       0       s-0     4285    3636    4489    3636
g       21      l       0       s-0     4285    3585    4285    3737
g       18      l       0       s-0     4489    3535    4489    3838
c       2
e       18      l       0       s-0     4489    3535    4489    3838
e       21      l       0       s-0     4285    3585    4285    3737
e       22      t       0       cm0     4285    3636    bullet
g       22      t       0       cm0     4285    3636    bullet
e       22      t       0       cm0     4285    3636    bullet
g       0       t       0       cm0     4285    3636    bullet
c       1
e       23      l       0       s-0     4285    3636    4489    3636
c       0
e       19      l       0       s-0     4081    3535    4489    3535
c       0
e       16      l       0       s-0     3469    3535    4489    3535
c       0
e       24      l       0       s-0     2856    3232    4489    3232
c       0
e       25      l       0       s-0     2856    3838    4693    3838
c       0
c       0
g       0       l       1       s-0     5101    7499    9999    7499
e       26      t       0       cm0     5101    5252    bullet
g       26      t       0       cm0     5101    6868    bullet
e       35      t       0       cm0     6938    6868    bullet
g       35      t       0       cm0     6938    5252    bullet
c       1
g       25      l       0       s-0     5101    6868    9999    6868
g       24      l       0       s-0     5101    5504    5101    8433
g       16      l       0       s-0     5305    4141    5305    9999
c       2
e       27      t       0       cm0     5305    6565    bullet
g       27      t       0       cm0     5305    6565    bullet
e       27      t       0       cm0     5305    6565    bullet
g       27      t       0       cm0     5305    6565    bullet
c       1
e       24      l       0       s-0     5101    5504    5101    8433
g       24      l       0       s-0     5305    5504    5305    8433
e       16      l       0       s-0     5305    4141    5305    9999
g       16      l       0       s-0     5509    4141    5509    9999
c       2
e       16      l       0       s-0     5509    4141    5509    9999
g       16      l       0       s-0     5713    4141    5713    9999
c       2
e       16      l       0       s-0     5713    4141    5713    9999
g       16      l       0       s-0     5917    4141    5917    9999
c       2
e       16      l       0       s-0     5917    4141    5917    9999
g       16      l       0       s-0     6121    4141    6121    9999
c       2
e       16      l       0       s-0     6121    4141    6121    9999
g       16      l       0       s-0     6325    4141    6325    9999
c       2
e       16      l       0       s-0     6325    4141    6325    9999
g       16      l       0       s-0     6529    4141    6529    9999
c       2
e       28      t       0       cm0     5509    7878    bullet
g       28      t       0       cm0     5509    6060    bullet
e       33      t       0       cm0     6529    6060    bullet
g       33      t       0       cm0     6529    7878    bullet
c       1
e       24      l       0       s-0     5305    5504    5305    8433
g       24      l       0       s-0     5509    5504    5509    8433
e       16      l       0       s-0     6529    4141    6529    9999
g       16      l       0       s-0     6734    4141    6734    9999
c       2
e       29      t       0       cm0     5713    7070    bullet
g       29      t       0       cm0     5713    4646    bullet
e       34      t       0       cm0     6734    4646    bullet
g       34      t       0       cm0     6734    7070    bullet
c       1
e       24      l       0       s-0     5509    5504    5509    8433
g       24      l       0       s-0     5713    5504    5713    8433
e       16      l       0       s-0     6734    4141    6734    9999
g       16      l       0       s-0     6938    4141    6938    9999
c       2
e       30      t       0       cm0     5917    7979    bullet
g       30      t       0       cm0     5917    5252    bullet
e       35      t       0       cm0     6938    5252    bullet
g       35      t       0       cm0     6938    7979    bullet
c       1
e       24      l       0       s-0     5713    5504    5713    8433
g       24      l       0       s-0     5917    5504    5917    8433
e       16      l       0       s-0     6938    4141    6938    9999
g       16      l       0       s-0     7142    4141    7142    9999
c       2
e       16      l       0       s-0     7142    4141    7142    9999
g       16      l       0       s-0     7346    4141    7346    9999
c       2
e       31      t       0       cm0     6121    8282    bullet
g       31      t       0       cm0     6121    5959    bullet
e       37      t       0       cm0     7346    5959    bullet
g       37      t       0       cm0     7346    8282    bullet
c       1
e       24      l       0       s-0     5917    5504    5917    8433
g       24      l       0       s-0     6121    5504    6121    8433
e       16      l       0       s-0     7346    4141    7346    9999
g       16      l       0       s-0     7550    4141    7550    9999
c       2
e       16      l       0       s-0     7550    4141    7550    9999
g       16      l       0       s-0     7754    4141    7754    9999
c       2
e       32      t       0       cm0     6325    8787    bullet
g       32      t       0       cm0     6325    4646    bullet
e       39      t       0       cm0     7754    4646    bullet
g       39      t       0       cm0     7754    8787    bullet
c       1
e       24      l       0       s-0     6121    5504    6121    8433
g       24      l       0       s-0     6325    5504    6325    8433
e       16      l       0       s-0     7754    4141    7754    9999
g       16      l       0       s-0     7958    4141    7958    9999
c       2
e       16      l       0       s-0     7958    4141    7958    9999
g       16      l       0       s-0     8162    4141    8162    9999
c       2
e       16      l       0       s-0     8162    4141    8162    9999
g       16      l       0       s-0     8366    4141    8366    9999
c       2
e       33      t       0       cm0     6529    7878    bullet
g       33      t       0       cm0     6529    5757    bullet
e       42      t       0       cm0     8366    5757    bullet
g       42      t       0       cm0     8366    7878    bullet
c       1
e       24      l       0       s-0     6325    5504    6325    8433
g       24      l       0       s-0     6529    5504    6529    8433
e       16      l       0       s-0     8366    4141    8366    9999
g       16      l       0       s-0     8570    4141    8570    9999
c       2
e       34      t       0       cm0     6734    7070    bullet
g       34      t       0       cm0     6734    4343    bullet
e       43      t       0       cm0     8570    4343    bullet
g       43      t       0       cm0     8570    7070    bullet
c       1
e       24      l       0       s-0     6529    5504    6529    8433
g       24      l       0       s-0     6734    5504    6734    8433
e       16      l       0       s-0     8570    4141    8570    9999
g       16      l       0       s-0     8774    4141    8774    9999
c       2
e       16      l       0       s-0     8774    4141    8774    9999
g       16      l       0       s-0     8978    4141    8978    9999
c       2
e       35      t       0       cm0     6938    7979    bullet
g       35      t       0       cm0     6938    5252    bullet
e       45      t       0       cm0     8978    5252    bullet
g       45      t       0       cm0     8978    7979    bullet
c       1
e       24      l       0       s-0     6734    5504    6734    8433
g       24      l       0       s-0     6938    5504    6938    8433
e       16      l       0       s-0     8978    4141    8978    9999
g       16      l       0       s-0     9182    4141    9182    9999
c       2
e       36      t       0       cm0     7142    8888    bullet
g       36      t       0       cm0     7142    5757    bullet
e       46      t       0       cm0     9182    5757    bullet
g       46      t       0       cm0     9182    8888    bullet
c       1
e       24      l       0       s-0     6938    5504    6938    8433
g       24      l       0       s-0     7142    5504    7142    8433
e       16      l       0       s-0     9182    4141    9182    9999
g       16      l       0       s-0     9386    4141    9386    9999
c       2
e       16      l       0       s-0     9386    4141    9386    9999
g       16      l       0       s-0     9590    4141    9590    9999
c       2
e       37      t       0       cm0     7346    8282    bullet
g       37      t       0       cm0     7346    4545    bullet
e       48      t       0       cm0     9590    4545    bullet
g       48      t       0       cm0     9590    8282    bullet
c       1
e       24      l       0       s-0     7142    5504    7142    8433
g       24      l       0       s-0     7346    5504    7346    8433
e       16      l       0       s-0     9590    4141    9590    9999
g       16      l       0       s-0     9794    4141    9794    9999
c       2
e       16      l       0       s-0     9794    4141    9794    9999
g       16      l       0       s-0     9999    4141    9999    9999
c       2
e       38      t       0       cm0     7550    9696    bullet
g       38      t       0       cm0     7550    6262    bullet
e       50      t       0       cm0     9999    6262    bullet
g       50      t       0       cm0     9999    9696    bullet
c       1
e       24      l       0       s-0     7346    5504    7346    8433
g       24      l       0       s-0     7550    5504    7550    8433
e       16      l       0       s-0     9999    4141    9999    9999
e       24      l       0       s-0     7550    5504    7550    8433
e       26      t       0       cm0     5101    6868    bullet
g       26      t       0       cm0     5101    6262    bullet
e       38      t       0       cm0     7550    6262    bullet
g       0       t       0       cm0     7550    6868    bullet
c       1
c       0
g       0       l       1       s-0     5101    6249    7346    6249
e       26      t       0       cm0     5101    6262    bullet
g       26      t       0       cm0     5101    4646    bullet
e       32      t       0       cm0     6325    4646    bullet
g       32      t       0       cm0     6325    6262    bullet
c       1
g       38      l       0       s-0     5101    4646    7346    4646
g       24      l       0       s-0     5101    4393    5101    5757
g       16      l       0       s-0     5305    4141    5305    6868
c       2
e       16      l       0       s-0     5305    4141    5305    6868
g       16      l       0       s-0     5509    4141    5509    6868
c       2
e       16      l       0       s-0     5509    4141    5509    6868
g       16      l       0       s-0     5713    4141    5713    6868
c       2
e       16      l       0       s-0     5713    4141    5713    6868
g       16      l       0       s-0     5917    4141    5917    6868
c       2
e       16      l       0       s-0     5917    4141    5917    6868
g       16      l       0       s-0     6121    4141    6121    6868
c       2
e       16      l       0       s-0     6121    4141    6121    6868
g       16      l       0       s-0     6325    4141    6325    6868
c       2
e       16      l       0       s-0     6325    4141    6325    6868
g       16      l       0       s-0     6529    4141    6529    6868
c       2
e       16      l       0       s-0     6529    4141    6529    6868
g       16      l       0       s-0     6734    4141    6734    6868
c       2
e       27      t       0       cm0     5305    6565    bullet
g       27      t       0       cm0     5305    4343    bullet
e       34      t       0       cm0     6734    4343    bullet
g       34      t       0       cm0     6734    6565    bullet
c       1
e       24      l       0       s-0     5101    4393    5101    5757
g       24      l       0       s-0     5305    4393    5305    5757
e       16      l       0       s-0     6734    4141    6734    6868
g       16      l       0       s-0     6938    4141    6938    6868
c       2
e       16      l       0       s-0     6938    4141    6938    6868
g       16      l       0       s-0     7142    4141    7142    6868
c       2
e       16      l       0       s-0     7142    4141    7142    6868
g       16      l       0       s-0     7346    4141    7346    6868
c       2
e       28      t       0       cm0     5509    6060    bullet
g       28      t       0       cm0     5509    4545    bullet
e       37      t       0       cm0     7346    4545    bullet
g       37      t       0       cm0     7346    6060    bullet
c       1
e       24      l       0       s-0     5305    4393    5305    5757
g       24      l       0       s-0     5509    4393    5509    5757
e       16      l       0       s-0     7346    4141    7346    6868
e       24      l       0       s-0     5509    4393    5509    5757
e       26      t       0       cm0     5101    4646    bullet
g       26      t       0       cm0     5101    4545    bullet
e       28      t       0       cm0     5509    4545    bullet
g       0       t       0       cm0     5509    4646    bullet
c       1
c       0
g       0       l       1       s-0     5101    4999    5305    4999
e       26      t       0       cm0     5101    4545    bullet
g       26      t       0       cm0     5101    4343    bullet
e       27      t       0       cm0     5305    4343    bullet
g       0       t       0       cm0     5305    4545    bullet
c       1
g       27      l       0       s-0     5101    4343    5305    4343
g       28      l       0       s-0     5101    4242    5101    4494
g       24      l       0       s-0     5305    4141    5305    4646
c       2
e       24      l       0       s-0     5305    4141    5305    4646
e       28      l       0       s-0     5101    4242    5101    4494
e       26      t       0       cm0     5101    4343    bullet
g       26      t       0       cm0     5101    4343    bullet
e       26      t       0       cm0     5101    4343    bullet
g       0       t       0       cm0     5101    4343    bullet
c       1
e       27      l       0       s-0     5101    4343    5305    4343
c       0
c       0
g       0       l       1       s-0     5713    4999    7346    4999
e       29      t       0       cm0     5713    4646    bullet
g       29      t       0       cm0     5713    6060    bullet
e       37      t       0       cm0     7346    6060    bullet
g       37      t       0       cm0     7346    4646    bullet
c       1
g       27      l       0       s-0     5713    6060    7346    6060
g       26      l       0       s-0     5713    5353    5713    6464
g       28      l       0       s-0     5917    4646    5917    6868
c       2
e       30      t       0       cm0     5917    5252    bullet
g       30      t       0       cm0     5917    5252    bullet
e       30      t       0       cm0     5917    5252    bullet
g       30      t       0       cm0     5917    5252    bullet
c       1
e       26      l       0       s-0     5713    5353    5713    6464
g       26      l       0       s-0     5917    5353    5917    6464
e       28      l       0       s-0     5917    4646    5917    6868
g       28      l       0       s-0     6121    4646    6121    6868
c       2
e       31      t       0       cm0     6121    5959    bullet
g       31      t       0       cm0     6121    5959    bullet
e       31      t       0       cm0     6121    5959    bullet
g       31      t       0       cm0     6121    5959    bullet
c       1
e       26      l       0       s-0     5917    5353    5917    6464
g       26      l       0       s-0     6121    5353    6121    6464
e       28      l       0       s-0     6121    4646    6121    6868
g       28      l       0       s-0     6325    4646    6325    6868
c       2
e       28      l       0       s-0     6325    4646    6325    6868
g       28      l       0       s-0     6529    4646    6529    6868
c       2
e       32      t       0       cm0     6325    6262    bullet
g       32      t       0       cm0     6325    5757    bullet
e       33      t       0       cm0     6529    5757    bullet
g       33      t       0       cm0     6529    6262    bullet
c       1
e       26      l       0       s-0     6121    5353    6121    6464
g       26      l       0       s-0     6325    5353    6325    6464
e       28      l       0       s-0     6529    4646    6529    6868
g       28      l       0       s-0     6734    4646    6734    6868
c       2
e       28      l       0       s-0     6734    4646    6734    6868
g       28      l       0       s-0     6938    4646    6938    6868
c       2
e       33      t       0       cm0     6529    6262    bullet
g       33      t       0       cm0     6529    5252    bullet
e       35      t       0       cm0     6938    5252    bullet
g       35      t       0       cm0     6938    6262    bullet
c       1
e       26      l       0       s-0     6325    5353    6325    6464
g       26      l       0       s-0     6529    5353    6529    6464
e       28      l       0       s-0     6938    4646    6938    6868
g       28      l       0       s-0     7142    4646    7142    6868
c       2
e       34      t       0       cm0     6734    6565    bullet
g       34      t       0       cm0     6734    5757    bullet
e       36      t       0       cm0     7142    5757    bullet
g       36      t       0       cm0     7142    6565    bullet
c       1
e       26      l       0       s-0     6529    5353    6529    6464
g       26      l       0       s-0     6734    5353    6734    6464
e       28      l       0       s-0     7142    4646    7142    6868
g       28      l       0       s-0     7346    4646    7346    6868
c       2
e       35      t       0       cm0     6938    6262    bullet
g       35      t       0       cm0     6938    4646    bullet
e       37      t       0       cm0     7346    4646    bullet
g       37      t       0       cm0     7346    6262    bullet
c       1
e       26      l       0       s-0     6734    5353    6734    6464
g       26      l       0       s-0     6938    5353    6938    6464
e       28      l       0       s-0     7346    4646    7346    6868
e       26      l       0       s-0     6938    5353    6938    6464
e       29      t       0       cm0     5713    6060    bullet
g       29      t       0       cm0     5713    4646    bullet
e       35      t       0       cm0     6938    4646    bullet
g       0       t       0       cm0     6938    6060    bullet
c       1
c       0
g       0       l       1       s-0     5713    3749    6734    3749
e       29      t       0       cm0     5713    4646    bullet
g       29      t       0       cm0     5713    5757    bullet
e       32      t       0       cm0     6325    5757    bullet
g       32      t       0       cm0     6325    4646    bullet
c       1
g       35      l       0       s-0     5713    5757    6734    5757
g       26      l       0       s-0     5713    5201    5713    5908
g       28      l       0       s-0     5917    4646    5917    6060
c       2
e       30      t       0       cm0     5917    5252    bullet
g       30      t       0       cm0     5917    5252    bullet
e       30      t       0       cm0     5917    5252    bullet
g       30      t       0       cm0     5917    5252    bullet
c       1
e       26      l       0       s-0     5713    5201    5713    5908
g       26      l       0       s-0     5917    5201    5917    5908
e       28      l       0       s-0     5917    4646    5917    6060
g       28      l       0       s-0     6121    4646    6121    6060
c       2
e       28      l       0       s-0     6121    4646    6121    6060
g       28      l       0       s-0     6325    4646    6325    6060
c       2
e       31      t       0       cm0     6121    5959    bullet
g       31      t       0       cm0     6121    4646    bullet
e       32      t       0       cm0     6325    4646    bullet
g       32      t       0       cm0     6325    5959    bullet
c       1
e       26      l       0       s-0     5917    5201    5917    5908
g       26      l       0       s-0     6121    5201    6121    5908
e       28      l       0       s-0     6325    4646    6325    6060
g       28      l       0       s-0     6529    4646    6529    6060
c       2
e       32      t       0       cm0     6325    5959    bullet
g       32      t       0       cm0     6325    5252    bullet
e       33      t       0       cm0     6529    5252    bullet
g       33      t       0       cm0     6529    5959    bullet
c       1
e       26      l       0       s-0     6121    5201    6121    5908
g       26      l       0       s-0     6325    5201    6325    5908
e       28      l       0       s-0     6529    4646    6529    6060
g       28      l       0       s-0     6734    4646    6734    6060
c       2
e       28      l       0       s-0     6734    4646    6734    6060
e       26      l       0       s-0     6325    5201    6325    5908
e       29      t       0       cm0     5713    5757    bullet
g       29      t       0       cm0     5713    5252    bullet
e       32      t       0       cm0     6325    5252    bullet
g       0       t       0       cm0     6325    5757    bullet
c       1
c       0
g       0       l       1       s-0     5713    2499    6121    2499
e       29      t       0       cm0     5713    5252    bullet
g       29      t       0       cm0     5713    5252    bullet
e       29      t       0       cm0     5713    5252    bullet
g       29      t       0       cm0     5713    5252    bullet
c       1
g       32      l       0       s-0     5713    5252    6121    5252
g       26      l       0       s-0     5713    4949    5713    5504
g       28      l       0       s-0     5917    4646    5917    5757
c       2
e       28      l       0       s-0     5917    4646    5917    5757
g       28      l       0       s-0     6121    4646    6121    5757
c       2
e       30      t       0       cm0     5917    5252    bullet
g       30      t       0       cm0     5917    4646    bullet
e       31      t       0       cm0     6121    4646    bullet
g       0       t       0       cm0     6121    5252    bullet
c       1
e       26      l       0       s-0     5713    4949    5713    5504
g       26      l       0       s-0     5917    4949    5917    5504
e       28      l       0       s-0     6121    4646    6121    5757
e       26      l       0       s-0     5917    4949    5917    5504
e       29      t       0       cm0     5713    5252    bullet
g       0       t       0       cm0     5713    4646    bullet
e       30      t       0       cm0     5917    4646    bullet
g       0       t       0       cm0     5917    5252    bullet
c       1
e       32      l       0       s-0     5713    5252    6121    5252
c       0
c       0
g       0       l       1       s-0     6529    2499    6734    2499
e       33      t       0       cm0     6529    5959    bullet
g       33      t       0       cm0     6529    5757    bullet
e       34      t       0       cm0     6734    5757    bullet
g       0       t       0       cm0     6734    5959    bullet
c       1
g       34      l       0       s-0     6529    5757    6734    5757
g       32      l       0       s-0     6529    5757    6529    5908
g       30      l       0       s-0     6734    5757    6734    6060
c       2
e       30      l       0       s-0     6734    5757    6734    6060
e       32      l       0       s-0     6529    5757    6529    5908
e       33      t       0       cm0     6529    5757    bullet
g       33      t       0       cm0     6529    5757    bullet
e       33      t       0       cm0     6529    5757    bullet
g       0       t       0       cm0     6529    5757    bullet
c       1
e       34      l       0       s-0     6529    5757    6734    5757
c       0
e       35      l       0       s-0     5713    5757    6734    5757
c       0
c       0
g       0       l       1       s-0     7142    3749    7346    3749
e       36      t       0       cm0     7142    6565    bullet
g       36      t       0       cm0     7142    6262    bullet
e       37      t       0       cm0     7346    6262    bullet
g       0       t       0       cm0     7346    6565    bullet
c       1
g       37      l       0       s-0     7142    6262    7346    6262
g       35      l       0       s-0     7142    6161    7142    6565
g       34      l       0       s-0     7346    6060    7346    6868
c       2
e       34      l       0       s-0     7346    6060    7346    6868
e       35      l       0       s-0     7142    6161    7142    6565
e       36      t       0       cm0     7142    6262    bullet
g       36      t       0       cm0     7142    6262    bullet
e       36      t       0       cm0     7142    6262    bullet
g       0       t       0       cm0     7142    6262    bullet
c       1
e       37      l       0       s-0     7142    6262    7346    6262
c       0
e       27      l       0       s-0     5713    6060    7346    6060
c       0
e       38      l       0       s-0     5101    4646    7346    4646
c       0
c       0
g       0       l       1       s-0     7754    6249    9999    6249
e       39      t       0       cm0     7754    8787    bullet
g       39      t       0       cm0     7754    7979    bullet
e       49      t       0       cm0     9794    7979    bullet
g       49      t       0       cm0     9794    8787    bullet
c       1
g       38      l       0       s-0     7754    7979    9999    7979
g       27      l       0       s-0     7754    7423    7754    8989
g       37      l       0       s-0     7958    6868    7958    9999
c       2
e       37      l       0       s-0     7958    6868    7958    9999
g       37      l       0       s-0     8162    6868    8162    9999
c       2
e       37      l       0       s-0     8162    6868    8162    9999
g       37      l       0       s-0     8366    6868    8366    9999
c       2
e       40      t       0       cm0     7958    8787    bullet
g       40      t       0       cm0     7958    7878    bullet
e       42      t       0       cm0     8366    7878    bullet
g       42      t       0       cm0     8366    8787    bullet
c       1
e       27      l       0       s-0     7754    7423    7754    8989
g       27      l       0       s-0     7958    7423    7958    8989
e       37      l       0       s-0     8366    6868    8366    9999
g       37      l       0       s-0     8570    6868    8570    9999
c       2
e       41      t       0       cm0     8162    8787    bullet
g       41      t       0       cm0     8162    7070    bullet
e       43      t       0       cm0     8570    7070    bullet
g       43      t       0       cm0     8570    8787    bullet
c       1
e       27      l       0       s-0     7958    7423    7958    8989
g       27      l       0       s-0     8162    7423    8162    8989
e       37      l       0       s-0     8570    6868    8570    9999
g       37      l       0       s-0     8774    6868    8774    9999
c       2
e       37      l       0       s-0     8774    6868    8774    9999
g       37      l       0       s-0     8978    6868    8978    9999
c       2
e       37      l       0       s-0     8978    6868    8978    9999
g       37      l       0       s-0     9182    6868    9182    9999
c       2
e       37      l       0       s-0     9182    6868    9182    9999
g       37      l       0       s-0     9386    6868    9386    9999
c       2
e       37      l       0       s-0     9386    6868    9386    9999
g       37      l       0       s-0     9590    6868    9590    9999
c       2
e       37      l       0       s-0     9590    6868    9590    9999
g       37      l       0       s-0     9794    6868    9794    9999
c       2
e       37      l       0       s-0     9794    6868    9794    9999
g       37      l       0       s-0     9999    6868    9999    9999
c       2
e       37      l       0       s-0     9999    6868    9999    9999
e       27      l       0       s-0     8162    7423    8162    8989
e       39      t       0       cm0     7754    7979    bullet
g       39      t       0       cm0     7754    7070    bullet
e       41      t       0       cm0     8162    7070    bullet
g       0       t       0       cm0     8162    7979    bullet
c       1
c       0
g       0       l       1       s-0     7754    4999    7958    4999
e       39      t       0       cm0     7754    7070    bullet
g       39      t       0       cm0     7754    7878    bullet
e       40      t       0       cm0     7958    7878    bullet
g       40      t       0       cm0     7958    7070    bullet
c       1
g       41      l       0       s-0     7754    7878    7958    7878
g       27      l       0       s-0     7754    7373    7754    7928
g       37      l       0       s-0     7958    6868    7958    7979
c       2
e       40      t       0       cm0     7958    7070    bullet
g       40      t       0       cm0     7958    7070    bullet
e       40      t       0       cm0     7958    7070    bullet
g       40      t       0       cm0     7958    7070    bullet
c       1
e       27      l       0       s-0     7754    7373    7754    7928
g       27      l       0       s-0     7958    7373    7958    7928
e       37      l       0       s-0     7958    6868    7958    7979
e       27      l       0       s-0     7958    7373    7958    7928
e       39      t       0       cm0     7754    7878    bullet
g       0       t       0       cm0     7754    7070    bullet
e       40      t       0       cm0     7958    7070    bullet
g       0       t       0       cm0     7958    7878    bullet
c       1
e       41      l       0       s-0     7754    7878    7958    7878
c       0
c       0
g       0       l       1       s-0     8366    4999    9999    4999
e       42      t       0       cm0     8366    8787    bullet
g       42      t       0       cm0     8366    9696    bullet
e       50      t       0       cm0     9999    9696    bullet
g       50      t       0       cm0     9999    8787    bullet
c       1
g       41      l       0       s-0     8366    9696    9999    9696
g       40      l       0       s-0     8366    8837    8366    9847
g       39      l       0       s-0     8570    7979    8570    9999
c       2
e       43      t       0       cm0     8570    8787    bullet
g       43      t       0       cm0     8570    8787    bullet
e       43      t       0       cm0     8570    8787    bullet
g       43      t       0       cm0     8570    8787    bullet
c       1
e       40      l       0       s-0     8366    8837    8366    9847
g       40      l       0       s-0     8570    8837    8570    9847
e       39      l       0       s-0     8570    7979    8570    9999
g       39      l       0       s-0     8774    7979    8774    9999
c       2
e       44      t       0       cm0     8774    9595    bullet
g       44      t       0       cm0     8774    9595    bullet
e       44      t       0       cm0     8774    9595    bullet
g       44      t       0       cm0     8774    9595    bullet
c       1
e       40      l       0       s-0     8570    8837    8570    9847
g       40      l       0       s-0     8774    8837    8774    9847
e       39      l       0       s-0     8774    7979    8774    9999
g       39      l       0       s-0     8978    7979    8978    9999
c       2
e       45      t       0       cm0     8978    7979    bullet
g       45      t       0       cm0     8978    7979    bullet
e       45      t       0       cm0     8978    7979    bullet
g       45      t       0       cm0     8978    7979    bullet
c       1
e       40      l       0       s-0     8774    8837    8774    9847
g       40      l       0       s-0     8978    8837    8978    9847
e       39      l       0       s-0     8978    7979    8978    9999
g       39      l       0       s-0     9182    7979    9182    9999
c       2
e       46      t       0       cm0     9182    8888    bullet
g       46      t       0       cm0     9182    8888    bullet
e       46      t       0       cm0     9182    8888    bullet
g       46      t       0       cm0     9182    8888    bullet
c       1
e       40      l       0       s-0     8978    8837    8978    9847
g       40      l       0       s-0     9182    8837    9182    9847
e       39      l       0       s-0     9182    7979    9182    9999
g       39      l       0       s-0     9386    7979    9386    9999
c       2
e       47      t       0       cm0     9386    8989    bullet
g       47      t       0       cm0     9386    8989    bullet
e       47      t       0       cm0     9386    8989    bullet
g       47      t       0       cm0     9386    8989    bullet
c       1
e       40      l       0       s-0     9182    8837    9182    9847
g       40      l       0       s-0     9386    8837    9386    9847
e       39      l       0       s-0     9386    7979    9386    9999
g       39      l       0       s-0     9590    7979    9590    9999
c       2
e       48      t       0       cm0     9590    8282    bullet
g       48      t       0       cm0     9590    8282    bullet
e       48      t       0       cm0     9590    8282    bullet
g       48      t       0       cm0     9590    8282    bullet
c       1
e       40      l       0       s-0     9386    8837    9386    9847
g       40      l       0       s-0     9590    8837    9590    9847
e       39      l       0       s-0     9590    7979    9590    9999
g       39      l       0       s-0     9794    7979    9794    9999
c       2
e       49      t       0       cm0     9794    8787    bullet
g       49      t       0       cm0     9794    8787    bullet
e       49      t       0       cm0     9794    8787    bullet
g       49      t       0       cm0     9794    8787    bullet
c       1
e       40      l       0       s-0     9590    8837    9590    9847
g       40      l       0       s-0     9794    8837    9794    9847
e       39      l       0       s-0     9794    7979    9794    9999
g       39      l       0       s-0     9999    7979    9999    9999
c       2
e       50      t       0       cm0     9999    8787    bullet
g       50      t       0       cm0     9999    8787    bullet
e       50      t       0       cm0     9999    8787    bullet
g       50      t       0       cm0     9999    8787    bullet
c       1
e       40      l       0       s-0     9794    8837    9794    9847
g       40      l       0       s-0     9999    8837    9999    9847
e       39      l       0       s-0     9999    7979    9999    9999
e       40      l       0       s-0     9999    8837    9999    9847
e       42      t       0       cm0     8366    9696    bullet
g       42      t       0       cm0     8366    8787    bullet
e       50      t       0       cm0     9999    8787    bullet
g       0       t       0       cm0     9999    9696    bullet
c       1
c       0
g       0       l       1       s-0     8366    3749    9794    3749
e       42      t       0       cm0     8366    8787    bullet
g       42      t       0       cm0     8366    8787    bullet
e       49      t       0       cm0     9794    8787    bullet
g       49      t       0       cm0     9794    8787    bullet
c       1
g       50      l       0       s-0     8366    8787    9794    8787
g       40      l       0       s-0     8366    8383    8366    9241
g       39      l       0       s-0     8570    7979    8570    9696
c       2
e       39      l       0       s-0     8570    7979    8570    9696
g       39      l       0       s-0     8774    7979    8774    9696
c       2
e       39      l       0       s-0     8774    7979    8774    9696
g       39      l       0       s-0     8978    7979    8978    9696
c       2
e       43      t       0       cm0     8570    8787    bullet
g       43      t       0       cm0     8570    7979    bullet
e       45      t       0       cm0     8978    7979    bullet
g       45      t       0       cm0     8978    8787    bullet
c       1
e       40      l       0       s-0     8366    8383    8366    9241
g       40      l       0       s-0     8570    8383    8570    9241
e       39      l       0       s-0     8978    7979    8978    9696
g       39      l       0       s-0     9182    7979    9182    9696
c       2
e       39      l       0       s-0     9182    7979    9182    9696
g       39      l       0       s-0     9386    7979    9386    9696
c       2
e       39      l       0       s-0     9386    7979    9386    9696
g       39      l       0       s-0     9590    7979    9590    9696
c       2
e       44      t       0       cm0     8774    9595    bullet
g       44      t       0       cm0     8774    8282    bullet
e       48      t       0       cm0     9590    8282    bullet
g       48      t       0       cm0     9590    9595    bullet
c       1
e       40      l       0       s-0     8570    8383    8570    9241
g       40      l       0       s-0     8774    8383    8774    9241
e       39      l       0       s-0     9590    7979    9590    9696
g       39      l       0       s-0     9794    7979    9794    9696
c       2
e       39      l       0       s-0     9794    7979    9794    9696
e       40      l       0       s-0     8774    8383    8774    9241
e       42      t       0       cm0     8366    8787    bullet
g       42      t       0       cm0     8366    8282    bullet
e       44      t       0       cm0     8774    8282    bullet
g       0       t       0       cm0     8774    8787    bullet
c       1
c       0
g       0       l       1       s-0     8366    2499    8570    2499
e       42      t       0       cm0     8366    8282    bullet
g       42      t       0       cm0     8366    8282    bullet
e       42      t       0       cm0     8366    8282    bullet
g       42      t       0       cm0     8366    8282    bullet
c       1
g       44      l       0       s-0     8366    8282    8570    8282
g       40      l       0       s-0     8366    8130    8366    8534
g       39      l       0       s-0     8570    7979    8570    8787
c       2
e       43      t       0       cm0     8570    7979    bullet
g       43      t       0       cm0     8570    7979    bullet
e       43      t       0       cm0     8570    7979    bullet
g       43      t       0       cm0     8570    7979    bullet
c       1
e       40      l       0       s-0     8366    8130    8366    8534
g       40      l       0       s-0     8570    8130    8570    8534
e       39      l       0       s-0     8570    7979    8570    8787
e       40      l       0       s-0     8570    8130    8570    8534
e       42      t       0       cm0     8366    8282    bullet
g       0       t       0       cm0     8366    7979    bullet
e       43      t       0       cm0     8570    7979    bullet
g       0       t       0       cm0     8570    8282    bullet
c       1
e       44      l       0       s-0     8366    8282    8570    8282
c       0
c       0
g       0       l       1       s-0     8978    2499    9794    2499
e       45      t       0       cm0     8978    8787    bullet
g       45      t       0       cm0     8978    8787    bullet
e       49      t       0       cm0     9794    8787    bullet
g       49      t       0       cm0     9794    8787    bullet
c       1
g       44      l       0       s-0     8978    8787    9794    8787
g       43      l       0       s-0     8978    8787    8978    9241
g       42      l       0       s-0     9182    8787    9182    9696
c       2
e       42      l       0       s-0     9182    8787    9182    9696
g       42      l       0       s-0     9386    8787    9386    9696
c       2
e       42      l       0       s-0     9386    8787    9386    9696
g       42      l       0       s-0     9590    8787    9590    9696
c       2
e       42      l       0       s-0     9590    8787    9590    9696
g       42      l       0       s-0     9794    8787    9794    9696
c       2
e       42      l       0       s-0     9794    8787    9794    9696
e       43      l       0       s-0     8978    8787    8978    9241
e       45      t       0       cm0     8978    8787    bullet
g       45      t       0       cm0     8978    8787    bullet
e       45      t       0       cm0     8978    8787    bullet
g       0       t       0       cm0     8978    8787    bullet
c       1
c       0
g       0       l       1       s-0     9182    1249    9794    1249
e       46      t       0       cm0     9182    8888    bullet
g       46      t       0       cm0     9182    8989    bullet
e       47      t       0       cm0     9386    8989    bullet
g       47      t       0       cm0     9386    8888    bullet
c       1
g       45      l       0       s-0     9182    8989    9794    8989
g       43      l       0       s-0     9182    8888    9182    9342
g       42      l       0       s-0     9386    8787    9386    9696
c       2
e       47      t       0       cm0     9386    8888    bullet
g       47      t       0       cm0     9386    8888    bullet
e       47      t       0       cm0     9386    8888    bullet
g       0       t       0       cm0     9386    8888    bullet
c       1
e       43      l       0       s-0     9182    8888    9182    9342
g       43      l       0       s-0     9386    8888    9386    9342
e       42      l       0       s-0     9386    8787    9386    9696
g       42      l       0       s-0     9590    8787    9590    9696
c       2
e       42      l       0       s-0     9590    8787    9590    9696
g       42      l       0       s-0     9794    8787    9794    9696
c       2
e       48      t       0       cm0     9590    9595    bullet
g       48      t       0       cm0     9590    8787    bullet
e       49      t       0       cm0     9794    8787    bullet
g       0       t       0       cm0     9794    9595    bullet
c       1
e       43      l       0       s-0     9386    8888    9386    9342
g       43      l       0       s-0     9590    8888    9590    9342
e       42      l       0       s-0     9794    8787    9794    9696
e       43      l       0       s-0     9590    8888    9590    9342
e       46      t       0       cm0     9182    8989    bullet
g       46      t       0       cm0     9182    8787    bullet
e       48      t       0       cm0     9590    8787    bullet
g       0       t       0       cm0     9590    8989    bullet
c       1
c       0
g       0       l       1       s-0     9182    0       9386    0
e       46      t       0       cm0     9182    8787    bullet
g       46      t       0       cm0     9182    8787    bullet
e       46      t       0       cm0     9182    8787    bullet
g       46      t       0       cm0     9182    8787    bullet
c       1
g       48      l       0       s-0     9182    8787    9386    8787
g       43      l       0       s-0     9182    8787    9182    8888
g       42      l       0       s-0     9386    8787    9386    8989
c       2
e       42      l       0       s-0     9386    8787    9386    8989
e       43      l       0       s-0     9182    8787    9182    8888
e       46      t       0       cm0     9182    8787    bullet
g       46      t       0       cm0     9182    8787    bullet
e       46      t       0       cm0     9182    8787    bullet
g       0       t       0       cm0     9182    8787    bullet
c       1
e       48      l       0       s-0     9182    8787    9386    8787
c       0
e       45      l       0       s-0     9182    8989    9794    8989
c       0
e       44      l       0       s-0     8978    8787    9794    8787
c       0
e       50      l       0       s-0     8366    8787    9794    8787
c       0
e       41      l       0       s-0     8366    9696    9999    9696
c       0
e       38      l       0       s-0     7754    7979    9999    7979
c       0
e       25      l       0       s-0     5101    6868    9999    6868
c       0
e       14      l       0       s-0     2856    4141    9999    4141
c       0
e       51      l       0       s-0     0       2323    9999    2323
c       0
END OF qsort.i
echo 'qsort.s' 1>&2
cat >'qsort.s' <<'END OF qsort.s'
view current
a1: text 1 88 bullet
a2: text 2 7 bullet
a3: text 3 79 bullet
a4: text 4 90 bullet
a5: text 5 8 bullet
a6: text 6 32 bullet
a7: text 7 1 bullet
a8: text 8 44 bullet
a9: text 9 2 bullet
a10: text 10 25 bullet
a11: text 11 96 bullet
a12: text 12 18 bullet
a13: text 13 1 bullet
a14: text 14 46 bullet
a15: text 15 58 bullet
a16: text 16 47 bullet
a17: text 17 35 bullet
a18: text 18 89 bullet
a19: text 19 53 bullet
a20: text 20 37 bullet
a21: text 21 36 bullet
a22: text 22 42 bullet
a23: text 23 20 bullet
a24: text 24 53 bullet
a25: text 25 80 bullet
a26: text 26 37 bullet
a27: text 27 66 bullet
a28: text 28 15 bullet
a29: text 29 71 bullet
a30: text 30 80 bullet
a31: text 31 83 bullet
a32: text 32 24 bullet
a33: text 33 61 bullet
a34: text 34 5 bullet
a35: text 35 69 bullet
a36: text 36 35 bullet
a37: text 37 60 bullet
a38: text 38 97 bullet
a39: text 39 47 bullet
a40: text 40 88 bullet
a41: text 41 88 bullet
a42: text 42 39 bullet
a43: text 43 33 bullet
a44: text 44 13 bullet
a45: text 45 2 bullet
a46: text 46 58 bullet
a47: text 47 19 bullet
a48: text 48 16 bullet
a49: text 49 36 bullet
a50: text 50 63 bullet
click rec.stage
view history
line  1 -1 50 -1
view current
a1: text 1 24 bullet
a32: text 32 88 bullet
click swap
p1: line 1 24 50 24
partline: line 1 12.5 1 62
compline: line 2 1 2 100
click comp
a2: text 2 7 bullet
a2: text 2 7 bullet
click swap
partline: line 2 12.5 2 62
compline: line 3 1 3 100
click comp
compline: line 4 1 4 100
click comp
compline: line 5 1 5 100
click comp
a3: text 3 8 bullet
a5: text 5 79 bullet
click swap
partline: line 3 12.5 3 62
compline: line 6 1 6 100
click comp
compline: line 7 1 7 100
click comp
a4: text 4 1 bullet
a7: text 7 90 bullet
click swap
partline: line 4 12.5 4 62
compline: line 8 1 8 100
click comp
compline: line 9 1 9 100
click comp
a5: text 5 2 bullet
a9: text 9 79 bullet
click swap
partline: line 5 12.5 5 62
compline: line 10 1 10 100
click comp
compline: line 11 1 11 100
click comp
compline: line 12 1 12 100
click comp
a6: text 6 18 bullet
a12: text 12 32 bullet
click swap
partline: line 6 12.5 6 62
compline: line 13 1 13 100
click comp
a7: text 7 1 bullet
a13: text 13 90 bullet
click swap
partline: line 7 12.5 7 62
compline: line 14 1 14 100
click comp
compline: line 15 1 15 100
click comp
compline: line 16 1 16 100
click comp
compline: line 17 1 17 100
click comp
compline: line 18 1 18 100
click comp
compline: line 19 1 19 100
click comp
compline: line 20 1 20 100
click comp
compline: line 21 1 21 100
click comp
compline: line 22 1 22 100
click comp
compline: line 23 1 23 100
click comp
a8: text 8 20 bullet
a23: text 23 44 bullet
click swap
partline: line 8 12.5 8 62
compline: line 24 1 24 100
click comp
compline: line 25 1 25 100
click comp
compline: line 26 1 26 100
click comp
compline: line 27 1 27 100
click comp
compline: line 28 1 28 100
click comp
a9: text 9 15 bullet
a28: text 28 79 bullet
click swap
partline: line 9 12.5 9 62
compline: line 29 1 29 100
click comp
compline: line 30 1 30 100
click comp
compline: line 31 1 31 100
click comp
compline: line 32 1 32 100
click comp
compline: line 33 1 33 100
click comp
compline: line 34 1 34 100
click comp
a10: text 10 5 bullet
a34: text 34 25 bullet
click swap
partline: line 10 12.5 10 62
compline: line 35 1 35 100
click comp
compline: line 36 1 36 100
click comp
compline: line 37 1 37 100
click comp
compline: line 38 1 38 100
click comp
compline: line 39 1 39 100
click comp
compline: line 40 1 40 100
click comp
compline: line 41 1 41 100
click comp
compline: line 42 1 42 100
click comp
compline: line 43 1 43 100
click comp
compline: line 44 1 44 100
click comp
a11: text 11 13 bullet
a44: text 44 96 bullet
click swap
partline: line 11 12.5 11 62
compline: line 45 1 45 100
click comp
a12: text 12 2 bullet
a45: text 45 32 bullet
click swap
partline: line 12 12.5 12 62
compline: line 46 1 46 100
click comp
compline: line 47 1 47 100
click comp
a13: text 13 19 bullet
a47: text 47 90 bullet
click swap
partline: line 13 12.5 13 62
compline: line 48 1 48 100
click comp
a14: text 14 16 bullet
a48: text 48 46 bullet
click swap
partline: line 14 12.5 14 62
compline: line 49 1 49 100
click comp
compline: line 50 1 50 100
click comp
erase compline
erase partline
a1: text 1 16 bullet
a14: text 14 24 bullet
click swap
click rec.stage
view history
line  1 -2 13 -2
view current
a1: text 1 2 bullet
a12: text 12 16 bullet
click swap
p2: line 1 2 13 2
partline: line 1 1.5 1 13
compline: line 2 1 2 24
click comp
compline: line 3 1 3 24
click comp
compline: line 4 1 4 24
click comp
a2: text 2 1 bullet
a4: text 4 7 bullet
click swap
partline: line 2 1.5 2 13
compline: line 5 1 5 24
click comp
compline: line 6 1 6 24
click comp
compline: line 7 1 7 24
click comp
a3: text 3 1 bullet
a7: text 7 8 bullet
click swap
partline: line 3 1.5 3 13
compline: line 8 1 8 24
click comp
compline: line 9 1 9 24
click comp
compline: line 10 1 10 24
click comp
compline: line 11 1 11 24
click comp
compline: line 12 1 12 24
click comp
compline: line 13 1 13 24
click comp
erase compline
erase partline
a1: text 1 1 bullet
a3: text 3 2 bullet
click swap
click rec.stage
view history
line  1 -3 2 -3
view current
a1: text 1 1 bullet
a2: text 2 1 bullet
click swap
p3: line 1 1 2 1
partline: line 1 1 1 1.5
compline: line 2 1 2 2
click comp
erase compline
erase partline
a1: text 1 1 bullet
a1: text 1 1 bullet
click swap
erase p3
click rec.stage
click rec.stage
view history
line  4 -3 13 -3
view current
a4: text 4 19 bullet
a13: text 13 7 bullet
click swap
p3: line 4 19 13 19
partline: line 4 10.5 4 21.5
compline: line 5 2 5 24
click comp
a5: text 5 2 bullet
a5: text 5 2 bullet
click swap
partline: line 5 10.5 5 21.5
compline: line 6 2 6 24
click comp
a6: text 6 18 bullet
a6: text 6 18 bullet
click swap
partline: line 6 10.5 6 21.5
compline: line 7 2 7 24
click comp
a7: text 7 8 bullet
a7: text 7 8 bullet
click swap
partline: line 7 10.5 7 21.5
compline: line 8 2 8 24
click comp
compline: line 9 2 9 24
click comp
a8: text 8 15 bullet
a9: text 9 20 bullet
click swap
partline: line 8 10.5 8 21.5
compline: line 10 2 10 24
click comp
a9: text 9 5 bullet
a10: text 10 20 bullet
click swap
partline: line 9 10.5 9 21.5
compline: line 11 2 11 24
click comp
a10: text 10 13 bullet
a11: text 11 20 bullet
click swap
partline: line 10 10.5 10 21.5
compline: line 12 2 12 24
click comp
a11: text 11 16 bullet
a12: text 12 20 bullet
click swap
partline: line 11 10.5 11 21.5
compline: line 13 2 13 24
click comp
a12: text 12 7 bullet
a13: text 13 20 bullet
click swap
partline: line 12 10.5 12 21.5
erase compline
erase partline
a4: text 4 7 bullet
a12: text 12 19 bullet
click swap
click rec.stage
view history
line  4 -4 11 -4
view current
a4: text 4 15 bullet
a8: text 8 7 bullet
click swap
p4: line 4 15 11 15
partline: line 4 8.5 4 17
compline: line 5 2 5 19
click comp
a5: text 5 2 bullet
a5: text 5 2 bullet
click swap
partline: line 5 8.5 5 17
compline: line 6 2 6 19
click comp
compline: line 7 2 7 19
click comp
a6: text 6 8 bullet
a7: text 7 18 bullet
click swap
partline: line 6 8.5 6 17
compline: line 8 2 8 19
click comp
a7: text 7 7 bullet
a8: text 8 18 bullet
click swap
partline: line 7 8.5 7 17
compline: line 9 2 9 19
click comp
a8: text 8 5 bullet
a9: text 9 18 bullet
click swap
partline: line 8 8.5 8 17
compline: line 10 2 10 19
click comp
a9: text 9 13 bullet
a10: text 10 18 bullet
click swap
partline: line 9 8.5 9 17
compline: line 11 2 11 19
click comp
erase compline
erase partline
a4: text 4 13 bullet
a9: text 9 15 bullet
click swap
click rec.stage
view history
line  4 -5 8 -5
view current
a4: text 4 13 bullet
a4: text 4 13 bullet
click swap
p5: line 4 13 8 13
partline: line 4 7.5 4 14
compline: line 5 2 5 15
click comp
a5: text 5 2 bullet
a5: text 5 2 bullet
click swap
partline: line 5 7.5 5 14
compline: line 6 2 6 15
click comp
a6: text 6 8 bullet
a6: text 6 8 bullet
click swap
partline: line 6 7.5 6 14
compline: line 7 2 7 15
click comp
a7: text 7 7 bullet
a7: text 7 7 bullet
click swap
partline: line 7 7.5 7 14
compline: line 8 2 8 15
click comp
a8: text 8 5 bullet
a8: text 8 5 bullet
click swap
partline: line 8 7.5 8 14
erase compline
erase partline
a4: text 4 5 bullet
a8: text 8 13 bullet
click swap
click rec.stage
view history
line  4 -6 7 -6
view current
a4: text 4 8 bullet
a6: text 6 5 bullet
click swap
p6: line 4 8 7 8
partline: line 4 5 4 10.5
compline: line 5 2 5 13
click comp
a5: text 5 2 bullet
a5: text 5 2 bullet
click swap
partline: line 5 5 5 10.5
compline: line 6 2 6 13
click comp
a6: text 6 5 bullet
a6: text 6 5 bullet
click swap
partline: line 6 5 6 10.5
compline: line 7 2 7 13
click comp
a7: text 7 7 bullet
a7: text 7 7 bullet
click swap
partline: line 7 5 7 10.5
erase compline
erase partline
a4: text 4 7 bullet
a7: text 7 8 bullet
click swap
click rec.stage
view history
line  4 -7 6 -7
view current
a4: text 4 2 bullet
a5: text 5 7 bullet
click swap
p7: line 4 2 6 2
partline: line 4 2 4 5
compline: line 5 2 5 8
click comp
compline: line 6 2 6 8
click comp
erase compline
erase partline
a4: text 4 2 bullet
a4: text 4 2 bullet
click swap
click rec.stage
view history
line  5 -8 6 -8
view current
a5: text 5 7 bullet
a5: text 5 7 bullet
click swap
p8: line 5 7 6 7
partline: line 5 4.5 5 7.5
compline: line 6 2 6 8
click comp
a6: text 6 5 bullet
a6: text 6 5 bullet
click swap
partline: line 6 4.5 6 7.5
erase compline
erase partline
a5: text 5 5 bullet
a6: text 6 7 bullet
click swap
erase p8
click rec.stage
erase p7
click rec.stage
erase p6
click rec.stage
erase p5
click rec.stage
click rec.stage
view history
line  10 -5 11 -5
view current
a10: text 10 16 bullet
a11: text 11 18 bullet
click swap
p5: line 10 16 11 16
partline: line 10 15.5 10 17.5
compline: line 11 15 11 19
click comp
erase compline
erase partline
a10: text 10 16 bullet
a10: text 10 16 bullet
click swap
erase p5
click rec.stage
erase p4
click rec.stage
erase p3
click rec.stage
erase p2
click rec.stage
click rec.stage
view history
line  15 -2 50 -2
view current
a15: text 15 42 bullet
a22: text 22 58 bullet
click swap
p2: line 15 42 50 42
partline: line 15 33 15 71
compline: line 16 24 16 100
click comp
compline: line 17 24 17 100
click comp
a16: text 16 35 bullet
a17: text 17 47 bullet
click swap
partline: line 16 33 16 71
compline: line 18 24 18 100
click comp
compline: line 19 24 19 100
click comp
compline: line 20 24 20 100
click comp
a17: text 17 37 bullet
a20: text 20 47 bullet
click swap
partline: line 17 33 17 71
compline: line 21 24 21 100
click comp
a18: text 18 36 bullet
a21: text 21 89 bullet
click swap
partline: line 18 33 18 71
compline: line 22 24 22 100
click comp
compline: line 23 24 23 100
click comp
compline: line 24 24 24 100
click comp
compline: line 25 24 25 100
click comp
compline: line 26 24 26 100
click comp
a19: text 19 37 bullet
a26: text 26 53 bullet
click swap
partline: line 19 33 19 71
compline: line 27 24 27 100
click comp
compline: line 28 24 28 100
click comp
compline: line 29 24 29 100
click comp
compline: line 30 24 30 100
click comp
compline: line 31 24 31 100
click comp
compline: line 32 24 32 100
click comp
compline: line 33 24 33 100
click comp
compline: line 34 24 34 100
click comp
a20: text 20 25 bullet
a34: text 34 47 bullet
click swap
partline: line 20 33 20 71
compline: line 35 24 35 100
click comp
compline: line 36 24 36 100
click comp
a21: text 21 35 bullet
a36: text 36 89 bullet
click swap
partline: line 21 33 21 71
compline: line 37 24 37 100
click comp
compline: line 38 24 38 100
click comp
compline: line 39 24 39 100
click comp
compline: line 40 24 40 100
click comp
compline: line 41 24 41 100
click comp
compline: line 42 24 42 100
click comp
a22: text 22 39 bullet
a42: text 42 58 bullet
click swap
partline: line 22 33 22 71
compline: line 43 24 43 100
click comp
a23: text 23 33 bullet
a43: text 43 44 bullet
click swap
partline: line 23 33 23 71
compline: line 44 24 44 100
click comp
compline: line 45 24 45 100
click comp
a24: text 24 32 bullet
a45: text 45 53 bullet
click swap
partline: line 24 33 24 71
compline: line 46 24 46 100
click comp
compline: line 47 24 47 100
click comp
compline: line 48 24 48 100
click comp
compline: line 49 24 49 100
click comp
a25: text 25 36 bullet
a49: text 49 80 bullet
click swap
partline: line 25 33 25 71
compline: line 50 24 50 100
click comp
erase compline
erase partline
a15: text 15 36 bullet
a25: text 25 42 bullet
click swap
click rec.stage
view history
line  15 -3 24 -3
view current
a15: text 15 39 bullet
a22: text 22 36 bullet
click swap
p3: line 15 39 24 39
partline: line 15 31.5 15 40.5
compline: line 16 24 16 42
click comp
a16: text 16 35 bullet
a16: text 16 35 bullet
click swap
partline: line 16 31.5 16 40.5
compline: line 17 24 17 42
click comp
a17: text 17 37 bullet
a17: text 17 37 bullet
click swap
partline: line 17 31.5 17 40.5
compline: line 18 24 18 42
click comp
a18: text 18 36 bullet
a18: text 18 36 bullet
click swap
partline: line 18 31.5 18 40.5
compline: line 19 24 19 42
click comp
a19: text 19 37 bullet
a19: text 19 37 bullet
click swap
partline: line 19 31.5 19 40.5
compline: line 20 24 20 42
click comp
a20: text 20 25 bullet
a20: text 20 25 bullet
click swap
partline: line 20 31.5 20 40.5
compline: line 21 24 21 42
click comp
a21: text 21 35 bullet
a21: text 21 35 bullet
click swap
partline: line 21 31.5 21 40.5
compline: line 22 24 22 42
click comp
a22: text 22 36 bullet
a22: text 22 36 bullet
click swap
partline: line 22 31.5 22 40.5
compline: line 23 24 23 42
click comp
a23: text 23 33 bullet
a23: text 23 33 bullet
click swap
partline: line 23 31.5 23 40.5
compline: line 24 24 24 42
click comp
a24: text 24 32 bullet
a24: text 24 32 bullet
click swap
partline: line 24 31.5 24 40.5
erase compline
erase partline
a15: text 15 32 bullet
a24: text 24 39 bullet
click swap
click rec.stage
view history
line  15 -4 23 -4
view current
a15: text 15 33 bullet
a23: text 23 32 bullet
click swap
p4: line 15 33 23 33
partline: line 15 28.5 15 36
compline: line 16 24 16 39
click comp
compline: line 17 24 17 39
click comp
compline: line 18 24 18 39
click comp
compline: line 19 24 19 39
click comp
compline: line 20 24 20 39
click comp
a16: text 16 25 bullet
a20: text 20 35 bullet
click swap
partline: line 16 28.5 16 36
compline: line 21 24 21 39
click comp
compline: line 22 24 22 39
click comp
compline: line 23 24 23 39
click comp
a17: text 17 32 bullet
a23: text 23 37 bullet
click swap
partline: line 17 28.5 17 36
erase compline
erase partline
a15: text 15 32 bullet
a17: text 17 33 bullet
click swap
click rec.stage
view history
line  15 -5 16 -5
view current
a15: text 15 25 bullet
a16: text 16 32 bullet
click swap
p5: line 15 25 16 25
partline: line 15 24.5 15 29
compline: line 16 24 16 33
click comp
erase compline
erase partline
a15: text 15 25 bullet
a15: text 15 25 bullet
click swap
erase p5
click rec.stage
click rec.stage
view history
line  18 -5 23 -5
view current
a18: text 18 36 bullet
a18: text 18 36 bullet
click swap
p5: line 18 36 23 36
partline: line 18 34.5 18 37.5
compline: line 19 33 19 39
click comp
compline: line 20 33 20 39
click comp
a19: text 19 35 bullet
a20: text 20 37 bullet
click swap
partline: line 19 34.5 19 37.5
compline: line 21 33 21 39
click comp
a20: text 20 35 bullet
a21: text 21 37 bullet
click swap
partline: line 20 34.5 20 37.5
compline: line 22 33 22 39
click comp
compline: line 23 33 23 39
click comp
erase compline
erase partline
a18: text 18 35 bullet
a20: text 20 36 bullet
click swap
click rec.stage
view history
line  18 -6 19 -6
view current
a18: text 18 35 bullet
a19: text 19 35 bullet
click swap
p6: line 18 35 19 35
partline: line 18 34 18 35.5
compline: line 19 33 19 36
click comp
erase compline
erase partline
a18: text 18 35 bullet
a18: text 18 35 bullet
click swap
erase p6
click rec.stage
click rec.stage
view history
line  21 -6 23 -6
view current
a21: text 21 36 bullet
a22: text 22 37 bullet
click swap
p6: line 21 36 23 36
partline: line 21 36 21 37.5
compline: line 22 36 22 39
click comp
compline: line 23 36 23 39
click comp
erase compline
erase partline
a21: text 21 36 bullet
a21: text 21 36 bullet
click swap
click rec.stage
view history
line  22 -7 23 -7
view current
a22: text 22 37 bullet
a23: text 23 37 bullet
click swap
p7: line 22 37 23 37
partline: line 22 36.5 22 38
compline: line 23 36 23 39
click comp
erase compline
erase partline
a22: text 22 37 bullet
a22: text 22 37 bullet
click swap
erase p7
click rec.stage
erase p6
click rec.stage
erase p5
click rec.stage
erase p4
click rec.stage
erase p3
click rec.stage
click rec.stage
view history
line  26 -3 50 -3
view current
a26: text 26 69 bullet
a35: text 35 53 bullet
click swap
p3: line 26 69 50 69
partline: line 26 55.5 26 84.5
compline: line 27 42 27 100
click comp
a27: text 27 66 bullet
a27: text 27 66 bullet
click swap
partline: line 27 55.5 27 84.5
compline: line 28 42 28 100
click comp
compline: line 29 42 29 100
click comp
compline: line 30 42 30 100
click comp
compline: line 31 42 31 100
click comp
compline: line 32 42 32 100
click comp
compline: line 33 42 33 100
click comp
a28: text 28 61 bullet
a33: text 33 79 bullet
click swap
partline: line 28 55.5 28 84.5
compline: line 34 42 34 100
click comp
a29: text 29 47 bullet
a34: text 34 71 bullet
click swap
partline: line 29 55.5 29 84.5
compline: line 35 42 35 100
click comp
a30: text 30 53 bullet
a35: text 35 80 bullet
click swap
partline: line 30 55.5 30 84.5
compline: line 36 42 36 100
click comp
compline: line 37 42 37 100
click comp
a31: text 31 60 bullet
a37: text 37 83 bullet
click swap
partline: line 31 55.5 31 84.5
compline: line 38 42 38 100
click comp
compline: line 39 42 39 100
click comp
a32: text 32 47 bullet
a39: text 39 88 bullet
click swap
partline: line 32 55.5 32 84.5
compline: line 40 42 40 100
click comp
compline: line 41 42 41 100
click comp
compline: line 42 42 42 100
click comp
a33: text 33 58 bullet
a42: text 42 79 bullet
click swap
partline: line 33 55.5 33 84.5
compline: line 43 42 43 100
click comp
a34: text 34 44 bullet
a43: text 43 71 bullet
click swap
partline: line 34 55.5 34 84.5
compline: line 44 42 44 100
click comp
compline: line 45 42 45 100
click comp
a35: text 35 53 bullet
a45: text 45 80 bullet
click swap
partline: line 35 55.5 35 84.5
compline: line 46 42 46 100
click comp
a36: text 36 58 bullet
a46: text 46 89 bullet
click swap
partline: line 36 55.5 36 84.5
compline: line 47 42 47 100
click comp
compline: line 48 42 48 100
click comp
a37: text 37 46 bullet
a48: text 48 83 bullet
click swap
partline: line 37 55.5 37 84.5
compline: line 49 42 49 100
click comp
compline: line 50 42 50 100
click comp
a38: text 38 63 bullet
a50: text 50 97 bullet
click swap
partline: line 38 55.5 38 84.5
erase compline
erase partline
a26: text 26 63 bullet
a38: text 38 69 bullet
click swap
click rec.stage
view history
line  26 -4 37 -4
view current
a26: text 26 47 bullet
a32: text 32 63 bullet
click swap
p4: line 26 47 37 47
partline: line 26 44.5 26 58
compline: line 27 42 27 69
click comp
compline: line 28 42 28 69
click comp
compline: line 29 42 29 69
click comp
compline: line 30 42 30 69
click comp
compline: line 31 42 31 69
click comp
compline: line 32 42 32 69
click comp
compline: line 33 42 33 69
click comp
compline: line 34 42 34 69
click comp
a27: text 27 44 bullet
a34: text 34 66 bullet
click swap
partline: line 27 44.5 27 58
compline: line 35 42 35 69
click comp
compline: line 36 42 36 69
click comp
compline: line 37 42 37 69
click comp
a28: text 28 46 bullet
a37: text 37 61 bullet
click swap
partline: line 28 44.5 28 58
erase compline
erase partline
a26: text 26 46 bullet
a28: text 28 47 bullet
click swap
click rec.stage
view history
line  26 -5 27 -5
view current
a26: text 26 44 bullet
a27: text 27 46 bullet
click swap
p5: line 26 44 27 44
partline: line 26 43 26 45.5
compline: line 27 42 27 47
click comp
erase compline
erase partline
a26: text 26 44 bullet
a26: text 26 44 bullet
click swap
erase p5
click rec.stage
click rec.stage
view history
line  29 -5 37 -5
view current
a29: text 29 61 bullet
a37: text 37 47 bullet
click swap
p5: line 29 61 37 61
partline: line 29 54 29 65
compline: line 30 47 30 69
click comp
a30: text 30 53 bullet
a30: text 30 53 bullet
click swap
partline: line 30 54 30 65
compline: line 31 47 31 69
click comp
a31: text 31 60 bullet
a31: text 31 60 bullet
click swap
partline: line 31 54 31 65
compline: line 32 47 32 69
click comp
compline: line 33 47 33 69
click comp
a32: text 32 58 bullet
a33: text 33 63 bullet
click swap
partline: line 32 54 32 65
compline: line 34 47 34 69
click comp
compline: line 35 47 35 69
click comp
a33: text 33 53 bullet
a35: text 35 63 bullet
click swap
partline: line 33 54 33 65
compline: line 36 47 36 69
click comp
a34: text 34 58 bullet
a36: text 36 66 bullet
click swap
partline: line 34 54 34 65
compline: line 37 47 37 69
click comp
a35: text 35 47 bullet
a37: text 37 63 bullet
click swap
partline: line 35 54 35 65
erase compline
erase partline
a29: text 29 47 bullet
a35: text 35 61 bullet
click swap
click rec.stage
view history
line  29 -6 34 -6
view current
a29: text 29 58 bullet
a32: text 32 47 bullet
click swap
p6: line 29 58 34 58
partline: line 29 52.5 29 59.5
compline: line 30 47 30 61
click comp
a30: text 30 53 bullet
a30: text 30 53 bullet
click swap
partline: line 30 52.5 30 59.5
compline: line 31 47 31 61
click comp
compline: line 32 47 32 61
click comp
a31: text 31 47 bullet
a32: text 32 60 bullet
click swap
partline: line 31 52.5 31 59.5
compline: line 33 47 33 61
click comp
a32: text 32 53 bullet
a33: text 33 60 bullet
click swap
partline: line 32 52.5 32 59.5
compline: line 34 47 34 61
click comp
erase compline
erase partline
a29: text 29 53 bullet
a32: text 32 58 bullet
click swap
click rec.stage
view history
line  29 -7 31 -7
view current
a29: text 29 53 bullet
a29: text 29 53 bullet
click swap
p7: line 29 53 31 53
partline: line 29 50 29 55.5
compline: line 30 47 30 58
click comp
compline: line 31 47 31 58
click comp
a30: text 30 47 bullet
a31: text 31 53 bullet
click swap
partline: line 30 50 30 55.5
erase compline
erase partline
a29: text 29 47 bullet
a30: text 30 53 bullet
click swap
erase p7
click rec.stage
click rec.stage
view history
line  33 -7 34 -7
view current
a33: text 33 58 bullet
a34: text 34 60 bullet
click swap
p7: line 33 58 34 58
partline: line 33 58 33 59.5
compline: line 34 58 34 61
click comp
erase compline
erase partline
a33: text 33 58 bullet
a33: text 33 58 bullet
click swap
erase p7
click rec.stage
erase p6
click rec.stage
click rec.stage
view history
line  36 -6 37 -6
view current
a36: text 36 63 bullet
a37: text 37 66 bullet
click swap
p6: line 36 63 37 63
partline: line 36 62 36 66
compline: line 37 61 37 69
click comp
erase compline
erase partline
a36: text 36 63 bullet
a36: text 36 63 bullet
click swap
erase p6
click rec.stage
erase p5
click rec.stage
erase p4
click rec.stage
click rec.stage
view history
line  39 -4 50 -4
view current
a39: text 39 80 bullet
a49: text 49 88 bullet
click swap
p4: line 39 80 50 80
partline: line 39 74.5 39 90
compline: line 40 69 40 100
click comp
compline: line 41 69 41 100
click comp
compline: line 42 69 42 100
click comp
a40: text 40 79 bullet
a42: text 42 88 bullet
click swap
partline: line 40 74.5 40 90
compline: line 43 69 43 100
click comp
a41: text 41 71 bullet
a43: text 43 88 bullet
click swap
partline: line 41 74.5 41 90
compline: line 44 69 44 100
click comp
compline: line 45 69 45 100
click comp
compline: line 46 69 46 100
click comp
compline: line 47 69 47 100
click comp
compline: line 48 69 48 100
click comp
compline: line 49 69 49 100
click comp
compline: line 50 69 50 100
click comp
erase compline
erase partline
a39: text 39 71 bullet
a41: text 41 80 bullet
click swap
click rec.stage
view history
line  39 -5 40 -5
view current
a39: text 39 79 bullet
a40: text 40 71 bullet
click swap
p5: line 39 79 40 79
partline: line 39 74 39 79.5
compline: line 40 69 40 80
click comp
a40: text 40 71 bullet
a40: text 40 71 bullet
click swap
partline: line 40 74 40 79.5
erase compline
erase partline
a39: text 39 71 bullet
a40: text 40 79 bullet
click swap
erase p5
click rec.stage
click rec.stage
view history
line  42 -5 50 -5
view current
a42: text 42 97 bullet
a50: text 50 88 bullet
click swap
p5: line 42 97 50 97
partline: line 42 88.5 42 98.5
compline: line 43 80 43 100
click comp
a43: text 43 88 bullet
a43: text 43 88 bullet
click swap
partline: line 43 88.5 43 98.5
compline: line 44 80 44 100
click comp
a44: text 44 96 bullet
a44: text 44 96 bullet
click swap
partline: line 44 88.5 44 98.5
compline: line 45 80 45 100
click comp
a45: text 45 80 bullet
a45: text 45 80 bullet
click swap
partline: line 45 88.5 45 98.5
compline: line 46 80 46 100
click comp
a46: text 46 89 bullet
a46: text 46 89 bullet
click swap
partline: line 46 88.5 46 98.5
compline: line 47 80 47 100
click comp
a47: text 47 90 bullet
a47: text 47 90 bullet
click swap
partline: line 47 88.5 47 98.5
compline: line 48 80 48 100
click comp
a48: text 48 83 bullet
a48: text 48 83 bullet
click swap
partline: line 48 88.5 48 98.5
compline: line 49 80 49 100
click comp
a49: text 49 88 bullet
a49: text 49 88 bullet
click swap
partline: line 49 88.5 49 98.5
compline: line 50 80 50 100
click comp
a50: text 50 88 bullet
a50: text 50 88 bullet
click swap
partline: line 50 88.5 50 98.5
erase compline
erase partline
a42: text 42 88 bullet
a50: text 50 97 bullet
click swap
click rec.stage
view history
line  42 -6 49 -6
view current
a42: text 42 88 bullet
a49: text 49 88 bullet
click swap
p6: line 42 88 49 88
partline: line 42 84 42 92.5
compline: line 43 80 43 97
click comp
compline: line 44 80 44 97
click comp
compline: line 45 80 45 97
click comp
a43: text 43 80 bullet
a45: text 45 88 bullet
click swap
partline: line 43 84 43 92.5
compline: line 46 80 46 97
click comp
compline: line 47 80 47 97
click comp
compline: line 48 80 48 97
click comp
a44: text 44 83 bullet
a48: text 48 96 bullet
click swap
partline: line 44 84 44 92.5
compline: line 49 80 49 97
click comp
erase compline
erase partline
a42: text 42 83 bullet
a44: text 44 88 bullet
click swap
click rec.stage
view history
line  42 -7 43 -7
view current
a42: text 42 83 bullet
a42: text 42 83 bullet
click swap
p7: line 42 83 43 83
partline: line 42 81.5 42 85.5
compline: line 43 80 43 88
click comp
a43: text 43 80 bullet
a43: text 43 80 bullet
click swap
partline: line 43 81.5 43 85.5
erase compline
erase partline
a42: text 42 80 bullet
a43: text 43 83 bullet
click swap
erase p7
click rec.stage
click rec.stage
view history
line  45 -7 49 -7
view current
a45: text 45 88 bullet
a49: text 49 88 bullet
click swap
p7: line 45 88 49 88
partline: line 45 88 45 92.5
compline: line 46 88 46 97
click comp
compline: line 47 88 47 97
click comp
compline: line 48 88 48 97
click comp
compline: line 49 88 49 97
click comp
erase compline
erase partline
a45: text 45 88 bullet
a45: text 45 88 bullet
click swap
click rec.stage
view history
line  46 -8 49 -8
view current
a46: text 46 90 bullet
a47: text 47 89 bullet
click swap
p8: line 46 90 49 90
partline: line 46 89 46 93.5
compline: line 47 88 47 97
click comp
a47: text 47 89 bullet
a47: text 47 89 bullet
click swap
partline: line 47 89 47 93.5
compline: line 48 88 48 97
click comp
compline: line 49 88 49 97
click comp
a48: text 48 88 bullet
a49: text 49 96 bullet
click swap
partline: line 48 89 48 93.5
erase compline
erase partline
a46: text 46 88 bullet
a48: text 48 90 bullet
click swap
click rec.stage
view history
line  46 -9 47 -9
view current
a46: text 46 88 bullet
a46: text 46 88 bullet
click swap
p9: line 46 88 47 88
partline: line 46 88 46 89
compline: line 47 88 47 90
click comp
erase compline
erase partline
a46: text 46 88 bullet
a46: text 46 88 bullet
click swap
erase p9
click rec.stage
erase p8
click rec.stage
erase p7
click rec.stage
erase p6
click rec.stage
erase p5
click rec.stage
erase p4
click rec.stage
erase p3
click rec.stage
erase p2
click rec.stage
erase p1
click rec.stage
END OF qsort.s
echo 'movie' 1>&2
cat >'movie' <<'END OF movie'
#!/bin/sh

# movie: "movie fname" projects movie stored in fname.s/fname.i

LIB=${LIB-/usr/lib/movie}
OPT=
FILE=""

while true
do
        case $1 in
        -d|-a[0-9.][0-9.]*|-m[0-9][0-9]*|-t[0-9][0-9]*) OPT="$OPT $1"; shift ;;
        -a|-m|-t)       OPT="$OPT $1$2"; shift; shift ;;
        *)      FILE=$1; break ;;
        esac
done

case $FILE in
"")
        trap "rm -f /usr/tmp/movie$$.i" 0 1 2 15
        $LIB/fdevelop >/usr/tmp/movie$$.i
        $LIB/anim $OPT /usr/tmp/movie$$.i
        ;;
*.i)
        $LIB/anim $OPT $FILE
        ;;
*.s)
        bn=`echo $FILE | sed s/.s$//`
        $LIB/develop $bn.s
        $LIB/anim $OPT $bn.i
        ;;
*)
        echo 'Usage: movie file.s' 1>&2
        exit 1
        ;;
esac

exit 0
END OF movie
chmod +x 'movie'
echo 'stills' 1>&2
cat >'stills' <<'END OF stills'
#!/bin/sh

# stills: filter to convert stills language to pic
#       typical troff preprocessor:
#       stills statements are bracketed by .begin stills/.end

LIB=${LIB-/usr/lib/movie}
AWK=nawk

for i in $*     # quicker than compiling a big awk program
do
        if [ ! -r $i ]
        then
                echo "stills: can't open file $i" 1>&2; exit 1
        fi
done

exec $AWK -f $LIB/stills.awk develop=$LIB/develop $*
END OF stills
chmod +x 'stills'
echo 'stills.awk' 1>&2
cat >'stills.awk' <<'END OF stills.awk'
BEGIN {
  # develop is set from first argument of form develop=filename

  fillstring =  "; line from GL.n  to GL.s; line from GL.e  to GL.w "\
                "; line from GL.ne to GL.sw; line from GL.nw to GL.se"
  set(textname, "small s medium m big b bigbig B")
  set(linename, "solid s fat f fatfat F")
  set(justtr, "l ljust r rjust a above b below")
  set(linetr, "o dotted a dashed"); linetr["s"] = linetr["f"] = linetr["F"] = ""
  set(arrowtr, "< <- > -> x <->"); arrowtr["-"] = ""
  set(convert, "dot \\v'-.2m'\\s+3.\\s-3\\v'.2m' "\
        "bullet \\v'.2m'\\s+2\\(bu\\s-2\\v'-.2m' "\
        "times \\s-3\\(mu\\s+3 circle \\s-3\\(ob\\s+3")
  instills = 0
}

instills == 0         { if ($1 == ".begin" && /^\.begin[ \t]+stills/) {
                                instills = 1; startstills()
                        } else print
                        next
                      }
/^\.end/              { instills = 0; endstills(); next }
END                   { if (instills) fatal("eof inside begin/end") }

                      { inputline = $0; sub(/\#.*$/, "") }
/^[ \t]*$/            { next }
$1 == "view"          { viewnum[$2] = viewct++
                        if (NF <= 2) text = $2
                        else {  text = rest(3)
                                if (text ~ /^"/) {
                                    if (text !~ /"$/) text = substr(text,2)
                                    else text=substr(text,2,length(text)-2)
                                }
                        }
                        inviewtitle[$2] = text
                        next
                      }
$1 == "print"         { sawprint = 1
                        if ($2 == "all") printglobal = 1
                        else if ($2 == "final") printfinal = 1
                        else { # print <clickname> ...
                                if ($3 == "all") { # print <clickname> all
                                        allnamearr[$2] = 1
                                } else { # print <clickname> v1 v2 ...
                                        if (!($2 in snamenum))
                                                snamenum[$2] = snamenumct++
                                        for (i = 3; i <= NF; i++)
                                            printsome[snamenum[$2] "." $i]=1
                                }
                        }
                        next
                      }
/./                   { # parameter assignments
                        n = $2; sub(/^\+/, "", n); n = 0 + n
                        if      ($1 == "file")          infile = $2
                        else if ($1 == "across")        across = n
                        else if ($1 == "down")          down = n
                        else if ($1 == "margin")        margin = n
                        else if ($1 == "frameht")       frameht = n
                        else if ($1 == "framewid")      framewid = n
                        else if ($1 in textname)        textinc[textname[$1]] = 
n
                        else if ($1 in linename)        lineinc[linename[$1]] = 
n
                        else if ($1 ~ /^times?$/) {
                                wanttime = 1;  if ($2 == "invis") wanttime = 0
                        } else if ($1 ~ /^frames?$/) {
                                wantframe = 1; if ($2 == "invis") wantframe = 0
                        } else warn("unrecognized command")
                        next 
                      }

function rest(f,  s, i) { # rest of $0, starting at $f
        if (NF <= f) return $f
        s = $0
        sub(/^[ \t]+/, "", s)
        for (i = 1; i < f; i++)
                sub(/^[^ \t]+[ \t]+/, "", s)
        return s
}

function dump(time,  i, gtype, vnum, x1, x2, y1, y2,
                opts, text, delta, btype) {
        btype = ""; if (wantframe == 0) btype = " invis"
        if (goacross == 0) { # time goes down the page, views go across
                if (colcnt >= colmax) {
                        delta = .1; if (wanttime) delta += .8
                        print "A0: box invis wid 0 ht 0 with .sw at A0.sw + ("\
                                viewct*framewid + delta " , 0)"
                        print "B0: box invis wid 0 ht 0 with .sw at A0.sw"
                        colcnt = 0
                }
                print "B0: box" btype " wid framewid ht frameht with .n at B0.s"
                for (i = 1; i < viewct; i++)
                        print "B" i ":  box" btype\
                            " wid framewid ht frameht with .w at B" i-1 ".e"
                if (colcnt == 0)
                        for (i = 0; i < viewct; i++)
                                if (viewtitle[i] != "")
                                        print "\"" viewtitle[i] "\" at B"\
                                                viewbase[i] ".n + (0, .1)"
                if (wanttime)
                        print "\"" time "\" ljust at B" viewct-1 ".e + (.1,0)"
        } else { # time goes across the page, views go down
                if (colcnt >= colmax) {
                        delta = .1; if (wanttime) delta += .3
                        print "A0: box invis wid 0 ht 0 with .c at A0.c - (0,"\
                                viewct*frameht + delta ")"
                        print "B0: box invis wid 0 ht 0 with .c at A0.c"
                        colcnt = 0
                }
                print "B0: box" btype " wid framewid ht frameht with .w at B0.e"
                for (i = 1; i < viewct; i++)
                        print "B" i ":  box" btype\
                            " wid framewid ht frameht with .n at B" i-1 ".s"
                if (colcnt == 0)
                        for (i = 0; i < viewct; i++)
                                if (viewtitle[i] != "")
                                        print "\"" viewtitle[i] "\" rjust at B"\
                                                viewbase[i] ".w - (.1, 0)"
                if (wanttime)
                        print "\"" time "\" at B" viewct-1 ".s + (0,-.15)"
        }
        colcnt++
        for (i = 1; i <= slotcnt; i++)
                if (slot[i] != "") {
                        if (slot[i] ~ /^g\t/) slot[i] = makepic(slot[i])
                        print slot[i]
                }
        for (i = 1; i <= staticcnt; i++)
                print static[i]
}

function pos(x, y) {
        return sprintf("B%d.sw+(%.3g,%.3g)", basenum,\
                framexfac*(frameborder+x), frameyfac*(frameborder+y))
}

function makepic(istring,    fields, gtype, vnum, pstring, just,
                        x1, x2, y1, y2, opts, text, i, t, linemode, arrow,
                        inc, ss, es) { # convert int file string to pic
        fields = split(istring, f, "\t")
        gtype=f[3]; vnum=f[4]; opts=f[5]; x1=f[6]; y1=f[7]
        basenum = viewbase[vnum]
        if (gtype == "l") { # line
                x2 = f[8]; y2 = f[9]
                linemode = substr(opts,1,1) # solid,fat,fatfat,dotted,dashed
                arrow = substr(opts,2,1) # -,->,<-, <->
                pstring = "line " linetr[linemode] " " arrowtr[arrow]\
                          " from " pos(x1, y1) " to " pos(x2, y2)
                if (linemode != "f" && linemode != "F") linemode = "s"
                inc = lineinc[linemode]
                if (inc != 0) {
                        if (inc < 0) { ss = inc; es = "+" 0-inc }
                        else         { ss = "+" inc; es = "-" inc }
                        pstring = ".ps " ss "\n" pstring "\n.ps " es
                }
        } else if (gtype == "b") { # box
                x2 = f[8]; y2 = f[9]
                if (x1 > x2) { t = x1; x1 = x2; x2 = t }
                if (y1 > y2) { t = y1; y1 = y2; y2 = t }
                pstring = "GL: box with .sw at " pos(x1,y1)\
                                " ht "  (y2-y1)*frameyfac\
                                " wid " (x2-x1)*framexfac
                if (substr(opts,1,1) == "f") pstring = pstring fillstring
        } else if (gtype == "c") { # circle
                pstring = "GL: circle radius " framexfac*f[8]\
                        " at " pos(x1, y1)
                if (substr(opts,1,1) == "f") pstring = pstring fillstring
        } else if (gtype == "t") { # text
                if (fields == 8) text = f[8]
                for (i = 9; i <= fields; i++) text = text "\t" f[i]
                if (text in convert) text = convert[text]
                just = justtr[substr(opts,1,1)]
                pstring = "\"" text "\" " just " at " pos(x1, y1)
                inc = textinc[substr(opts,2,1)]
                if (inc != 0) {
                        if (inc < 0) { ss = inc; es = "+" 0-inc }
                        else         { ss = "+" inc; es = "-" inc }
                        pstring = ".ps " ss "\n" pstring "\n.ps " es
                }
        } else warn("int file bug: illegal modifier after g")
        return pstring
}

function warn(s) {
        print "stills warning: " s >"/dev/tty"
        print "  near input line " NR ": " inputline >"/dev/tty"
}
function fatal(s) {
        print "stills fatal error: " s >"/dev/tty"
        print "  near input line " NR ": " inputline >"/dev/tty"
        exit
}

function startstills() {
        set(textinc, "s -2 m 0 b 3 B 8")
        set(lineinc, "s 0 f 3 F 8")
        infile = ""; sawprint = 0
        frameht = 1.5; framewid = 1.5; margin = 0.05
        wanttime = wantframe = 1 
        printglobal = printfinal = 0
        across = 0; down = -1
        clear(allnamearr)
        clear(allnumarr)
        clear(clickname)
        clear(inviewtitle)
        clear(printsome)
        clear(slot)     ; slotcnt = 0
        clear(somenum)
        clear(snamenum) ; snamenumct = 0        
        clear(static)   ; staticcnt = 0
        clear(timectr)
        clear(viewactive)
        clear(viewtitle)
        clear(viewnum)  ; viewct = 0    
        print ".PS"
        print "A0: B0: box invis wid 0 ht 0"
}

function clear(a, i) {
        for (i in a) delete a[i]
}
function set(a, s,  i, n, q) {
        n = split(s, q)
        for (i = 1; i < n; i += 2)
                a[q[i]] = q[i+1]
}

function endstills() {
if (sawprint = 0) warn("no print statements")
if (viewct == 0) viewglobal = 1
if (down < 0) {
        goacross = 1; colmax = across; ratio = 6/framewid
} else {
        goacross = 0; colmax = down; ratio = 8/frameht
}
if (colmax <= 0) colmax = int(ratio)
inputrange = 10000                      # 0..9999
frameborder = inputrange * margin       # border of whitespace
framexfac = framewid/(inputrange + 2*frameborder)
frameyfac =  frameht/(inputrange + 2*frameborder)
print "frameht  = " frameht
print "framewid = " framewid
if (infile == "") fatal("missing script file name")
if (infile !~ /\.s$/) fatal("script file name must end in .s")
system(develop " " infile)
sub(".s$", ".i", infile)
OFMT = "%.3g"
FS = "\t"
while ((getline <infile) > 0) {
        if ($1 == "g") {
                if (viewactive[$4]) {
                        snum = $2
                        if (snum > slotcnt) slotcnt = snum
                        if (snum != 0) slot[snum] = $0
                        else static[++staticcnt] = makepic($0)
                }
        } else if ($1 == "e") { # erase
                if (viewactive[$4]) slot[$2] = ""
        } else if ($1 == "c") { # click
                ++timectr[$2]
                if (printglobal || allnumarr[$2] ||
                          (somenum[$2] "." timectr[$2] in printsome))
                        dump(clickname[$2] ": " timectr[$2])
        } else if ($1 == "#") { # comment -- ignore it
        } else if ($1 == "b") { # blank the current view by enclosed erases
        } else if ($1 == "d") { # define
                if ($2 == "c") { # click
                        clickname[$3] = $4
                        allnumarr[$3] = 0
                        if ($4 in allnamearr) allnumarr[$3] = 1
                        somenum[$3] = -1
                        if ($4 in snamenum) somenum[$3] = snamenum[$4]
                } else if ($2 == "v") { # view
                        viewactive[$3] = 0
                        if ($4 in viewnum) {
                                viewactive[$3] = 1
                                viewbase[$3] = viewnum[$4]
                                viewtitle[$3] = inviewtitle[$4]
                        } else if (viewglobal) {
                                viewactive[$3] = 1
                                viewbase[$3] = viewct++
                                viewtitle[$3] = $4
                        }
                } else if ($2 == "p") { # ``pragmas'' -- check here?
                } else warn("int file bug: illegal modifier following d")
        } else warn("int file bug: unrecognized command")
}
close(infile)
if (printfinal) dump("final")
print ".PE"
FS = " "
}
END OF stills.awk
echo 'develop' 1>&2
cat >'develop' <<'END OF develop'
#!/bin/sh

# develop: "develop fname.s" makes fname.i from fname.s

# intended to be called only from movie and stills

LIB=${LIB-/usr/lib/movie}

case $# in
0)      echo 'Usage: develop file.s ...' 1>&2; exit 1 ;;
*)      ;;
esac

for i in $*
do
        case $# in
        1)      ;;
        *)      echo $i: ;;
        esac

        case $i in
        *.s)    bn=`echo $i | sed s/.s$//` ;;   # foo.s; bn = foo
        *)      echo 'Usage: develop file.s ...' 1>&2; exit 1 ;;
        esac

        if [ ! -r $bn.s ]
        then
                echo 1>&2 "develop: can't open $bn.s"; exit 2
        elif [ ! -r $bn.i ] || $LIB/newer $bn.s $bn.i
        then
                $LIB/fdevelop $bn.s >$bn.i
        fi
done
exit 0
END OF develop
chmod +x 'develop'
echo 'view.clicks' 1>&2
cat >'view.clicks' <<'END OF view.clicks'
#!/bin/sh
# view.clicks -- describe views and clicks in $1.s/$1.i; develop if needed

AWK=nawk

develop $1.s
exec $AWK '
$1=="d" && $2=="v"    { printf "view %-12s x == [%g,%g], y == [%g,%g]\n",
                                $4 ":", $5, $7, $6, $8
                      }
$1=="d" && $2=="c"    { cstring = cstring "  " $4 }
$1!="d"               { print "clicks:" cstring; exit }
' $1.i
END OF view.clicks
chmod +x 'view.clicks'
echo 'show.clicks' 1>&2
cat >'show.clicks' <<'END OF show.clicks'
#!/bin/sh
AWK=nawk

exec $AWK ' # show.clicks:  make a new view counting clicks
NR==1 && $1!="view"   { print "view", (oldview = "default.view") }
$1 == "view"          { oldview = $2 }
$1 == "click"         { if ((cname = $2) == "") cname = "no.name"
                        print "view click.count"
                        if ((n=cnum[cname]) == 0) {
                                n = cnum[cname] = ++clicks
                                print "l" n ": text rjust 0", -n, cname ": "
                        }
                        print "v" n ": text ljust 0", -n, "\" " ++ccnt[n]
                        print "last: text ljust 0", -n, "bullet"
                        print "view " oldview
                      }
                      { print $0 }
' $*
END OF show.clicks
echo 'Makefile' 1>&2
cat >'Makefile' <<'END OF Makefile'

# you need to use an ansi c compiler, or convert to older c...

CC = cc

LIBXG = libXg

GOPT = -g -n
CFLAGS = $(GOPT) -D_POSIX_SOURCE -D_LIBXG_EXTENSION -DSYSV -I$(LIBXG) # 
-I/usr/include

# pick one for yourself:
#       change LIB=... to match in movie, stills, develop

LIB = /usr/lib/movie
#LIB = .

BIN = /usr/bin
#BIN = .

MAN = /usr/man/man1

FILES = README movie.1 script.def stills.def int.def \
        isort.gen test.i test.s qsort.i qsort.s \
        movie stills stills.awk develop view.clicks show.clicks \
        Makefile \
        anim.c fdevelop.c newer.c

anim:   anim.o $(LIBXG)/libXg.a # added library dependency
        $(CC) -o anim anim.o $(LIBXG)/libXg.a -lXt -lX11 -lc -lm

anim.o: $(LIBXG)
        $(CC) -c $(CFLAGS) anim.c

libXg:
        mkdir libXg
#       cd libXg; ar x ../libXg.src.a; make CC=$(CC); cd ..
        cd libXg; sh ../libXg.bundle; make CC=$(CC); cd ..

libXg/libXg.a:  libXg
        cd libXg; make; cd ..

all:    anim fdevelop newer
        chmod +x movie develop stills show.clicks view.clicks

fdevelop: fdevelop.c
        $(CC) $(GOPT) -o fdevelop fdevelop.c

newer:  newer.c
        $(CC) -o newer newer.c

install:        anim fdevelop newer movie.1
        @if [ -d $(BIN) ]; then :; else mkdir $(BIN); fi
        @if [ -d $(LIB) ]; then :; else mkdir $(LIB); fi
        @if [ -d $(MAN) ]; then :; else mkdir $(MAN); fi
        cp movie.1 $(MAN)
        cp develop fdevelop stills.awk anim newer $(LIB)
        cp stills movie $(BIN)

bundle:
        @cd libXg; make bundle >../libXg.bundle; cd ..
        @bundle $(FILES) libXg.bundle

netlib:
        make bundle >/n/pyxis/netlib/1127/anim

clean:
        rm -f a.out *.o $(LIBXG)/*.o $(LIBXG)/libXg.a

clobber nuke:   clean
        rm -f anim newer fdevelop

# you better be sure you want to do this one:

realclean:      clobber
        rm -fr libXg
END OF Makefile
echo 'anim.c' 1>&2
cat >'anim.c' <<'END OF anim.c'
/****************************************************************
Copyright (C) AT&T 1992  
All Rights Reserved

Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of AT&T or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.

AT&T DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL AT&T OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/

/*

WISH LIST:

        .s input instead of .i
                auto scaling
                default view, so minimal input
                options
                make common code
        text attached to other objects
        prespecification of views, etc.
        bitmaps
        frame counter on screen
        better color.  a way to define colors?
        manual
        programmable?

BUGS/FEATURES:

        delay still isn't right -- kludgy , unpredictable.
                doesn't work at all backwards.
        this is in part an X issue, since it is hard to control
                speed for an X terminal.

FIXES/FEATURES:

        default: works if no view given at front of .i
        d s v# x y x y
                input scale for view instead of default 0 0 10000 10000

*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <ctype.h>

#define _LIBG_EXTENSION
#include <u.h>
#include <libc.h>
#include <libg.h>

#ifdef PLAN9
#define xtbinit(a,b,c,d)        binit(a,b, "anim")
#endif

#define ONES    (~0)

int     BUTCHECK        = 1;    /* how often to look for mouse events; */
                                /* should be ~1 on X, ~32 on plan 9 */

#define INPUTSCALE      10000   /* inherited from fdevelop */
int     inputscale      = INPUTSCALE;

#define NZOOM   20
Rectangle zoomr[NZOOM]; /* for zooming in and out */
int     nzoom = 0;      /* current one */

Bitmap myscreen;        /* this really should be a rectangle */

typedef struct {
        char    type;
        char    view;
        char    opts[3];        /* misc, unused, color */
        unsigned char   textlen;
        Point   p0;
        union {
                Point   p1;
                char    text[8];
                char    *ptext;
        } u;
} Obj;
        

#define eq(s,t) (strcmp((char *) (s), (char *) (t)) == 0)

/* holds data for all input objects */

long    memsize = 100000;       /* Objs in input buffer */
Obj     *inbuf;                 /* input collected here */
Obj     *input;                 /* leave a null at front */
Obj     *nextinp;               /* next free slot in input */
int     overflow = 0;           /* 1 => too much input */

int     show(FILE *);
Obj     *show_step(Obj *);
int     do_input(FILE *);
Obj     *read_obj(FILE *);
Obj     *rcv_obj(FILE *);
int     skipline(FILE *);
int     skipbl(FILE *);
Obj     *badfile(FILE *, char *);
int     sendopt(int[], char *);
int     erase(Obj *);
int     fatline(Point, Point, Fcode, int, int);
int     fatcircle(Point, int, Fcode, int, int);
int     arrow(Point, Point, int, int, Fcode, int);

int     clear(void);
int     view_setup(int);
int     init_params(void);
int     checkmouse(void);
int     domouse(void);

Obj     *draw_obj(Obj *, Fcode, int);
Obj     *step_obj(Obj *, Fcode, int);
void    draw_dummy(void);
Obj     *prev_obj(Obj *);
Obj     *next_obj(Obj *);
Obj     *refresh(Obj *, int);
FILE    *newfile(FILE *);
void    advance(void);
void    colorinit(void);
int     zoomin(void);
void    drawrect(Rectangle r, Fcode mode);
Rectangle square(Rectangle);
Rectangle shrink(Rectangle, int);

Point   fetchpt(int, Point);
Point   scalept(int, Point);
Point   inscale(int v, double x, double y);
int     xscale(int v, double x);

void    putstring(char *);

int     reshaped        = 0;    /* set to 1 in ereshaped */

Mouse   mouse;
int     buttondown(void);

char    kbdline [100];
int     do_kbd(void);

#define MAXVIEW 20
char    *viewname[MAXVIEW];
Rectangle viewpt[MAXVIEW];
int     curview = 0;
int     nview   = 0;

struct Frect {
        double  minx, miny, maxx, maxy;
} viewscale[MAXVIEW];   /* scaling of input coords done with this */

#define INSET   4       /* picture inset from frame */

#define AW      8       /* arrowhead width and height */
#define AH      10

#define MARGINPCT       5
int     margin  = MARGINPCT;    /* percent margin around edges */

#define MAXCLICK        20
char    *clickname[MAXCLICK];           /* click names */
int     clickval[MAXCLICK];             /* 1 => click on this */
int     clicking = 0;                   /* number of active clicks */
int     nclick  = 0;

enum colors { Black = 0, Red, Green, Yellow, Blue, Magenta, Cyan, White };
        /* this order was defined by the manual, but is sort of arbitrary */

/* options for various commands */

#define Tcenter 10
#define Tljust  20
#define Trjust  30
#define Tvcenter (1*32)
#define Tabove  (2*32)
#define Tbelow  (3*32)
#define Tsmall  1
#define Tmedium 2
#define Tbig    3
#define Tbigbig 4

#define Lsolid  10
#define Lfat    20
#define Lfatfat 30
#define Ldotted 40
#define Ldashed 50
#define Lline   1
#define Larrow1 2
#define Larrow2 3
#define Larrow3 4

#define Bnofill 10
#define Bfill   20

#define Cnofill 10
#define Cfill   20

int     boxops[]  ={    'n', Bnofill, 'f', Bfill, 0 }; 
int     circops[] ={    'n', Cnofill, 'f', Cfill, 0 }; 
int     textops[] ={    'c', Tcenter, 'l', Tljust, 'r', Trjust,
                        's', Tsmall, 'm', Tmedium, 'b', Tbig, 'B', Tbigbig,
                        'x', Tvcenter, 'a', Tabove, 'u', Tbelow,
                         0 };
int     lineops[] ={    's', Lsolid, 'f', Lfat, 'F', Lfatfat, 'o', Ldotted, 
'a', Ldashed,
                        '-', Lline, '>', Larrow1, '<', Larrow2, 'x', Larrow3, 0 
};

enum    { Fwd = 1, Back = 0 };

int     delay           = 1;    /* how long to delay between things */
int     singstep        = 0;    /* single step if 1, cycle if 2 */
int     dir             = Fwd;          /* 1 = fwd, 0 = backward */
int     fatness         = 0;            /* n => draw with 2n+1 lines */
#define DorS    S       /* experiment; seems to work better */
Fcode   xormode         = DxorS;        /* otherwise OR/CLR */

enum Menuitems {
        Again = 0,              /* Menu items -- must be 0, other in order */
        Faster,
        Slower,
        Step,
        Forward,
        Fatter,
        Thinner,
        Zoomin,
        Zoomout,
        Xor,
        Newfile,
        Quit,
        Backward ,
        Proceed,
        Hit,
        Refresh,
        Cycle
};

char    *m3[]   = { "again", "faster", "slower", "1 step", "backward",
                    "fatter", "thinner", "zoom in", "zoom out",
                    "or mode", "new file", "Quit?", 0 };
char    *stepmenu[]     = { "1 step", "cycle", "run" };
char    *dirmenu[]      = { "forward", "backward" };
char    *modemenu[]     = { "or mode", "xor mode" };

int     last_hit;
int     last_but;
int     Etimer;
int     etimerval = 25;
double  aspect  = 0.75; /* make square if aspect < dx/dy < 2-aspect */


int
main(int argc, char *argv[])
{
        FILE *fp = stdin;

        xtbinit(0, 0, &argc, argv);
        einit(Emouse|Ekeyboard);
        colorinit();
        setbuf(stderr, NULL);

        myscreen = screen;
        while (argc > 1 && argv[1][0] == '-') {
                switch (argv[1][1]) {
                case 'm':
                case 'l':
                        memsize = atoi(&argv[1][2]);
                        break;
                case 't':
                        etimerval = atoi(&argv[1][2]);
                        break;
                case 'a':
                        aspect = atof(&argv[1][2]);
                        break;
                case 'd':       /* not a very general mechanism! */
                        fprintf(stderr, "anim version October 18. 1992\n");
                        exit(0);
                }
                argv++;
                argc--;
        }
        Etimer = etimer(0, etimerval);
        if (inbuf == NULL && (inbuf = (Obj *) calloc(memsize, sizeof(Obj))) == 
NULL) {
                fprintf(stderr, "can't allocate %ld bytes", memsize);
                exit(1);
        }
        if (argc == 1)
                fp = stdin;
        else if ((fp = fopen(argv[1], "r")) == NULL) {
                fprintf(stderr, "can't open file %s\n", argv[1]);
                exit(1);
        }

        while (show(fp) != Quit)        /* should check for Newfile here */
                ;
        return 0;
}

int show(FILE *fp)
{
        Obj *ip;
        int n;

  top:
        init_params();
        if ((n = do_input(fp)) == Quit || n == Newfile)
                return n;
        ip = nextinp;
  again:
        for (; ip; ) {
                checkmouse();   /* waits for a menu selection */
                n = domouse();
                if (n == Quit)
                        return Quit;
                if (n == Hit || n == Refresh)
                        continue;
                if (n == Forward) {     /* change from fwd to back -- fiddle ip 
*/
                        ip = next_obj(ip);
                        continue;
                }
                if (n == Backward) {
                        ip = prev_obj(ip);
                        continue;
                }
                if (n == Newfile) {
                        if ((fp = newfile(fp)) != 0)
                                goto top;
                        continue;
                }
                if (n == Zoomin || n == Zoomout) {
                        dir = Fwd;
                        ip = refresh(ip, Fwd);
                        continue;
                }
                if (n == Again) {
                        if (reshaped) {
                                view_setup(nview);
                                reshaped = 0;
                        }
                        clear();
                        dir = Fwd;
                        ip = input;
                }
                ip = show_step(ip);
        }
        if (ip == 0)
                ip = dir == Fwd ? nextinp : input;
        goto again;
}

Obj *show_step(Obj *ip)
{
        int i;

        if (singstep == 1)
                ip = step_obj(ip, xormode, dir);
        else {          /* free running */
           cycle:
                while (ip) {
                        static int j = 0;
                        ip = step_obj(ip, xormode, dir);
                        if ((++j & BUTCHECK) == 0 && buttondown()) {    /* 
someone has touched the mouse */
                                singstep = 0;
                                break;          /* back round main loop */
                        }
                        for (i = delay-1; i>0; i--) {
                                draw_dummy();
                                /* Event tev; */
                                /* eread(Etimer, &tev); */
                        }
                }
                if (singstep == 2) {
                        clear();
                        dir = Fwd;
                        ip = input;
                        goto cycle;
                }

        }
        return ip;
}

int do_input(FILE *fp)
{
        int n;
        Obj *ip;

        while ((ip = rcv_obj(fp)) != 0) {       /* also draws it */
                if (!buttondown())
                        continue;
                checkmouse();

                switch (n = domouse()) {
                case Quit:
                        return n;
                case Newfile:           /* BUG: not yet thought about... */
                        if ((fp = newfile(fp)) == 0)
                                return Quit;    /* give up for now */
                        break;
                case Hit:
                        break;

                /* more of this stuff ought to be common with show() */
                case Zoomin:
                case Zoomout:
                        dir = Fwd;
                        refresh(ip, Fwd);
                        break;
                case Again:
                case Refresh:
                case Forward:
                        if (reshaped) {
                                view_setup(nview);
                                reshaped = 0;
                        }
                        dir = Fwd;
                        refresh(ip, Fwd);
                        break;

                case Backward:
                        refresh(ip, Back);
                        clear();        /* covers up errors */
                        sleep(2);       /* probably not a good idea */
                        refresh(ip, dir = Fwd);
                        break;

                /* more stuff goes here... */

                default:
                        break;
                }
        }
        return 0;
}

domouse(void)
{
        int i, n;
        Rectangle r;

        if (last_but == 1)
                return Proceed;
        if (last_but == 3) {
                switch (last_hit) {
                case Again:
                        return Again;
                case Faster:
                        if (delay > 1)
                                delay /= 2;
                        return Hit;
                case Slower:
                        delay *= 2;
                        return Hit;
                case Step:
                        singstep = (singstep+1) % 3;
                        return Hit;
                case Forward:
                        dir = 1 - dir;
                        if (xormode == DorS)
                                xormode = Zero;
                        else if (xormode == Zero)
                                xormode = DorS;
                        return dir == Fwd ? Forward : Backward;
                case Fatter:
                        fatness++;
                        return Refresh;
                case Thinner:
                        if (fatness > 0)
                                fatness--;
                        return Refresh;
                case Zoomin:
                        return zoomin();
                case Zoomout:
                        if (nzoom > 0)
                                nzoom--;
                        return Zoomout;
                case Xor:
                        if (xormode == DorS || xormode == Zero)
                                xormode = DxorS;
                        else if (dir == Fwd)
                                xormode = DorS;
                        else
                                xormode = Zero;
                        return Refresh;
                case Newfile:
                        return Newfile;
                case Quit:
                        return Quit;
                default:
                        return Hit;
                }
        } else if (last_but == 2) {
                Rectangle r;
                if (last_hit == -1)
                        return Hit;
                else if (last_hit < nview) {
                        r = getrect(2, &mouse);         /* really ought to be 
2,3 */
                        if (r.min.x == 0 && r.max.x == 0)       /* bailed out */
                                return Hit;
                        if (Dx(r) < 10 || Dy(r) < 10)   /* too small */
                                return Hit;
                        if (eqpt(r.min, r.max))
                                r = inset(myscreen.r, INSET);
                        drawrect(inset(viewpt[last_hit], -(INSET+fatness)), 
Zero);
                        drawrect(r, DorS);
                        viewpt[last_hit] = r = inset(r, INSET+fatness);
                        return Refresh;
                } else {        /* a click */
                        if (clickval[last_hit-nview]) { /* was on, so turn off 
*/
                                clickval[last_hit-nview] = 0;
                                clicking--;
                        } else {
                                clickval[last_hit-nview] = 1;
                                clicking++;
                        }
                        return Hit;
                }
        }
}

Obj *refresh(Obj *cp, int dir)  /* redraw the screen up to cp */
{
        Obj *ip, *ep;
        int i, n = 0;

        if (dir == Fwd)
                clear();
        ip = dir == Fwd ? input : cp;
        ep = dir == Fwd ? cp : input;
        for (; ip != 0 && ip != ep; ) {
                ip = step_obj(ip, xormode, dir);
                if ((++n & BUTCHECK) == 0 && buttondown())
                        break;
        }
        return ip;
}

init_params(void)
{
        int i;

        for (i = 0; i < MAXCLICK; i++)
                if (clickname[i]) {
                        free(clickname[i]);
                        clickname[i] = 0;
                        clickval[i] = 0;
                }
        for (i = 0; i < MAXVIEW; i++) {
                viewscale[i].minx = viewscale[i].miny = 0;
                viewscale[i].maxx = viewscale[i].maxy = inputscale;
                if (viewname[i]) {
                        free(viewname[i]);
                        viewname[i] = 0;
                }
        }
        nview = nclick = clicking = curview = overflow = 0;
        delay = 1;
        fatness = 0;
        singstep = 0;
        xormode = DxorS;
        input = inbuf;          /* beginning of input Objs */
        nextinp = inbuf;        /* next free slot */
        dir = Fwd;
        myscreen.r = inset(screen.r, INSET);
        zoomr[0] = myscreen.r = square(myscreen.r);
        nzoom = 0;
        clear();
}


FILE *newfile(FILE *fp)
{
        char buf[100];

        fprintf(stderr, "filename? ");
        putstring("filename? ");
        if (do_kbd() == 0)
                return 0;
        fclose(fp);
        if ((fp = fopen(kbdline, "r")) == NULL) {
                sprintf(buf, "can't open %s", kbdline);
                fprintf(stderr, "%s\n", buf);
                putstring(buf);
                return 0;
        }
        init_params();
        return fp;
}


/*

monochrome assumptions (ldepth == 0):

        "circle fill" means "draw a disk in the foreground color."
        the background is typically white so this means a black disk,
        or the opposite in reverse video mode.

        all colors except white are treated as black.

        in libxg monochrome, ONES means foreground, 0 means background.

color assumptions (ldepth > 0):

        8 colors, in the order listed.  background assumed white,
        so white objects will not be visible against the background.

        this is also true for gray scale terminals.

        color ought to be done in Store mode, not Xor, but then
        going backwards is even less satisfactory.

enum colors { Black = 0, Red, Green, Yellow, Blue, Magenta, Cyan, White };

*/

RGB colordefs[] = {
        {0x00000000,    0x00000000,     0x00000000},    /* black */
        {0xFFFFFFFF,    0x00000000,     0x00000000},    /* red */
        {0x00000000,    0xFFFFFFFF,     0x00000000},    /* green */
        {0xFFFFFFFF,    0xFFFFFFFF,     0x00000000},    /* yellow */
        {0x00000000,    0x00000000,     0xFFFFFFFF},    /* blue */
        {0xFFFFFFFF,    0x00000000,     0xFFFFFFFF},    /* magenta */
        {0x00000000,    0xFFFFFFFF,     0xFFFFFFFF},    /* cyan */
        {0xFFFFFFFF,    0xFFFFFFFF,     0xFFFFFFFF},    /* white */
};

#define numberof(d)     (sizeof(d) / sizeof(d[0]))

unsigned long rgbval[numberof(colordefs)];
Bitmap  *rgbbitmap[numberof(colordefs)];

void colorinit(void)    /* set up color definitions */
{
        int i;

        for (i = 0; i < numberof(colordefs); i++) {
                if (screen.ldepth == 0) /* monochrome */
                        rgbval[i] = i != White ? ONES : rgbpix(&screen, 
colordefs[White]);
                else
                        rgbval[i] = rgbpix(&screen, colordefs[i]);
                rgbbitmap[i] = balloc(Rect(0,0,1,1), screen.ldepth);
                point(rgbbitmap[i], Pt(0,0), rgbval[i], S);
        }
}

view_setup(int n)
{
        int i, j, v, dx, dy, r, c;
        Rectangle sr;

        sr = square(myscreen.r);
        switch (n) {
        case 0:         /* nothing was provided, so fake it */
                r = c = 1;
                n = nview = 1;
                viewname[0] = malloc(strlen("def")+1);
                strcpy(viewname[0], "def");
                break;
        case 1: r = 1; c = 1; break;
        case 2: r = 2; c = 1; break;
        case 3: case 4: r = 2; c = 2; break;
        case 5: case 6: r = 3; c = 2; break;
        default: r = (n+2)/3; c = 3; break; /* finking out */
        }
        dx = Dx(sr) / c;
        dy = Dy(sr) / r;
        v = 0;
        for (i = 0; i < r && v < n; i++)
                for (j = 0; j < c && v < n; j++) {
                        viewpt[v] = sr;
                        viewpt[v].min.x = sr.min.x + j * dx;
                        viewpt[v].max.x = sr.min.x + (j+1) * dx;
                        viewpt[v].min.y = sr.min.y + i * dy;
                        viewpt[v].max.y = sr.min.y + (i+1) * dy;
                        v++;
                }
        for (i = 0; i < n; i++) {
                viewpt[i] = shrink(viewpt[i], margin);
        }
        zoomr[nzoom] = myscreen.r;
}

void ereshaped(Rectangle r)
{
        reshaped = 1;
        myscreen = screen;
        myscreen.r = inset(myscreen.r, INSET);
        zoomr[0] = myscreen.r = square(myscreen.r);
        nzoom = 0;
}

void drawrect(Rectangle r, Fcode mode)
{
        /* should use border() */
        segment(&screen, r.min, Pt(r.min.x,r.max.y), ONES, mode);
        segment(&screen, r.min, Pt(r.max.x,r.min.y), ONES, mode);
        segment(&screen, r.max, Pt(r.min.x,r.max.y), ONES, mode);
        segment(&screen, r.max, Pt(r.max.x,r.min.y), ONES, mode);
}

Rectangle shrink(Rectangle r, int pct)  /* shrink rectangle by 2*pct */
{
        int dx = (r.max.x-r.min.x) * pct / 100;
        int dy = (r.max.y-r.min.y) * pct / 100;
        r.min = add(r.min, Pt(dx,dy));
        r.max = sub(r.max, Pt(dx,dy));
        return r;
}

Rectangle square(Rectangle r)   /* return largest square within r */
{
        double ar;

        ar = (double) Dy(r)/Dx(r);      /* y/x aspect ratio */
        if (ar < aspect || ar > 2-aspect)       /* leave it alone */
                return r;
        if (ar <= 1)    /* x is longer than y */
                r.max.x = r.min.x + Dy(r);
        else            /* y is longer */
                r.max.y = r.min.y + Dx(r);
        return r;
}

int zoomin(void)
{
        Rectangle r;

        r = getrect(3, &mouse);
        if (r.min.x == 0)       /* no selection */
                return Hit;
        if (Dx(r) < 10 || Dy(r) < 10) { /* very small */
                if (Dx(zoomr[nzoom+1]) < 10)    /* no previous one */
                        return Hit;
                r = zoomr[nzoom+1];     /* use previous one */
        } else          /* preserve aspect ratio if near square */
                r = square(r);

        /* either new one or zoom back in */
        if (nzoom < NZOOM-1)
                zoomr[++nzoom] = r;
        return Zoomin;
}

Obj *rcv_obj(FILE *fp)
{
        int i;
        Obj *ip = read_obj(fp);

        draw_obj(ip, DxorS, Fwd);
        for (i = delay-1; i>0; i--)
                draw_dummy();
        bflush(); /* BUG: performance -- putting this in costs 10-20% */
        return ip;
}

Obj *read_obj(FILE *fp)
{
        int c, b, i, v;
        double x1, x2, y1, y2;
        int junk, emode, len;
        char opts[100];
        char text[1000];
        char *p;
        Obj *ip;

        ip = nextinp;
  again:                /* DIRTY */
        b = c = getc(fp);
        switch (c) {
        case EOF:
                return 0;
        case ' ':
        case '\t':
        case '\n':
                goto again;
/*      case '#':               /* comments */
        default:        /* (supports old 'b' command) */
                skipline(fp);
                goto again;

        case 'd':       /* definition of some sort */
                switch (c = skipbl(fp)) {

                case 's':       /* scale */
                        if (fscanf(fp, "%d", &v) != 1)
                                return badfile(fp, "scale error");
                        if (fscanf(fp, "%lg %lg %lg %lg",
                                &viewscale[v].minx, &viewscale[v].miny,
                                &viewscale[v].maxx, &viewscale[v].maxy) != 4)
                                        return badfile(fp, "scale error");
                        break;

                case 'v':       /* view */
                case 'c':       /* click */
                        if (fscanf(fp, "%d %s", &i, text) != 2)
                                return badfile(fp, "view/click error");
                        if (c == 'c') {
                                clickname[i] = malloc(strlen(text)+1);
                                strcpy(clickname[i], text);
                                nclick++;
                        } else {        /* c == 'v' */
                                viewname[i] = malloc(strlen(text)+1);
                                strcpy(viewname[i], text);
                                nview++;
                        }
                        skipline(fp);   /* might be a title there */
                        break;
                case 'p':       /* only pragma is 'e' for end */
                        skipline(fp);
                        view_setup(nview);
                        break;
                default:
                        return badfile(fp, "weird define");
                }
                goto again;

        case 'c':               /* click */
                if (fscanf(fp, "%d", &i) != 1)
                        return badfile(fp, "illegal click");
                ip->type = 'c';
                ip->view = i;   /* click number */
                skipline(fp);
                break;

        case 'e':               /* erase: same info as geom */
        case 'g':               /* geom:  draw line, box, circle, ... */
                if (nview == 0) /* cya in case no view specified */
                        view_setup(0);
                if (fscanf(fp, "%d", &junk) != 1)
                        return badfile(fp, "missing view in g or e");
                emode = c == 'e';

                switch (c = skipbl(fp)) {
                case 'l':
                case 'b':
                        if (fscanf(fp, "%d %s %lg %lg %lg %lg", &v, opts, &x1, 
&y1, &x2, &y2) != 6)
                                return badfile(fp, "bad box or line");
                        ip->type = emode ? toupper(c) : c;
                        ip->view = v;
                        setopt(ip->opts, c=='b' ? boxops : lineops, opts);      
/* options */
                        ip->p0 = inscale(v, x1, y1);
                        ip->u.p1 = inscale(v, x2, y2);
                        break;

                case 'c':       /* circle */
                        if (fscanf(fp, "%d %s %lg %lg %lg", &v, opts, &x1, &y1, 
&x2) != 5)
                                return badfile(fp, "bad circle");
                        ip->type = emode ? toupper('o') : 'o';  /* 'o' is for 
circle */
                        ip->view = v;
                        setopt(ip->opts, circops, opts);
                        ip->p0 = inscale(v, x1, y1);
                        ip->u.p1.x = xscale(v, x2);
                        break;

                case 't':       /* text */
                        if (fscanf(fp, "%d %s %lg %lg", &v, opts, &x1, &y1) != 
4)
                                return badfile(fp, "bad text");
                        ip->type = emode ? toupper('t') : 't';
                        ip->view = v;
                        setopt(ip->opts, textops, opts);
                        ip->p0 = inscale(v, x1, y1);
                        getc(fp);       /* skip 1 separator; no quotes */
                        for (p = text; (c = getc(fp)) != '\n'; )
                                *p++ = c;
                        *p = 0;
                        len = p - text;
                        ungetc('\n', fp);

                        if (eq(text, "bullet"))
                                strcpy(text, "*"), len = 1;
                        else if (eq(text, "dot"))
                                strcpy(text, "."), len = 1;
                        else if (eq(text, "circle"))
                                strcpy(text, "o"), len = 1;
                        else if (eq(text, "times"))
                                strcpy(text, "x"), len = 1;

                        if (ip->textlen >= sizeof(ip->u.text)) /* free old one 
*/
                                free(ip->u.ptext);
                        if (len >= sizeof(ip->u.text)) { /* need a new one */
                                ip->u.ptext = malloc(len + 1);
                                strcpy(ip->u.ptext, text);
                        } else
                                strcpy(ip->u.text, text);
                        ip->textlen = len;
                                
                        break;

                default:
                        return badfile(fp, "bad geom object");
                }
                break;

        }
        advance();
        return ip;
}

void advance(void)
{
        nextinp++;
        if (nextinp >= inbuf + memsize) {
                char buf[10];
                Point p = Pt(screen.r.min.x+1, screen.r.max.y-10);
                nextinp = inbuf;
                if (overflow > 0) {
                        sprintf(buf, "%d", overflow);
                        string(&screen, p, font, buf, DxorS);
                }
                overflow++;     /* we've wrapped around */
                sprintf(buf, "%d", overflow);
                string(&screen, p, font, buf, DxorS);
        }
        if (overflow)
                input = nextinp;        /* beginning of old material */
}

Obj *badfile(FILE *fp, char *s)
{
        fprintf(stderr, "input file is not in .i format: %s\n", s);
        while (getc(fp) != EOF)
                ;
        fclose(fp);
        return 0;
}

setopt(char output[3], int optvals[], char *opts)
{
        int i, n;
        char *oopts = opts;

        n = 0;
        for (i = 0; optvals[i] && opts; i += 2) {
                if (*opts == optvals[i]) {
                        n += optvals[i+1];
                        opts++;
                }
        }
        output[0] = n;  /* for now, just use first "digit" */
        output[2] = 0;  /* establish default color */
        for (opts = oopts; *opts; opts++) {
                if (isdigit(*opts)) {   /* 0 = black, etc. */
                        output[2] = *opts - '0';
                }
        }
        return n;
}

clear(void)     /* screen */
{
        bitblt(&screen, screen.r.min, &screen, screen.r, Zero);
}

Point inscale(int v, double x, double y)        /* scale input according to 
viewscale[] */
{
        x = (inputscale * (x - viewscale[v].minx)) / (viewscale[v].maxx - 
viewscale[v].minx);
        y = (inputscale * (y - viewscale[v].miny)) / (viewscale[v].maxy - 
viewscale[v].miny);
        return Pt((int) (x+0.5), (int) (y+0.5));
}

int xscale(int v, double x)     /* scale input according to viewscale[] */
{
        return (inputscale * x) / (viewscale[v].maxx - viewscale[v].minx) + 0.5;
}

Point scalept(int v, Point p)
{
        p.x = (p.x * Dx(viewpt[v])) / inputscale;
        p.y = Dy(viewpt[v]) - (p.y * Dy(viewpt[v])) / inputscale;
        return p;
}

scalex(int v, int x)
{
        int i;
        double nx = ((double) x * Dx(viewpt[v])) / inputscale;

        for (i = 1; i <= nzoom; i++)
                nx *= (double)Dx(myscreen.r) / Dx(zoomr[i]);
        return nx + 0.5;
}

Point fetchpt(int v, Point pt)
{
        int i;

        pt = scalept(v, pt);
        pt = add(pt, viewpt[v].min);
        for (i = 1; i <= nzoom; i++) {
                pt.x = (pt.x-zoomr[i].min.x) * (double) Dx(zoomr[0]) / 
Dx(zoomr[i]);
                pt.y = (pt.y-zoomr[i].min.y) * (double) Dy(zoomr[0]) / 
Dy(zoomr[i]);
        }
        return pt;
}


Obj *prev_obj(Obj *ip)
{
        if (ip <= inbuf)
                ip = inbuf + memsize - 1;
        else
                ip--;
        if (ip >= nextinp)      /* BUG - lots of boundary errors here! */
                return 0;
        else
                return ip;
}

Obj *next_obj(Obj *ip)
{
        ip++;
        if (ip >= inbuf + memsize)
                ip = inbuf;
        if (ip >= nextinp)
                return 0;
        else
                return ip;
}

Obj *step_obj(Obj *ip, Fcode mode, int dir)     /* draw objs until one that 
changes something */
{
        int c;
        Obj *oip;

        if (clicking) {
                for (;;) {
                        oip = ip;
                        ip = draw_obj(ip, mode, dir);
                        if (ip == 0 || (oip && oip->type == 'c' && 
clickval[oip->view]))
                                return ip;
                }

        } else {        /* stepping */
                while (ip) {
                        c = tolower(ip->type);
                        ip = draw_obj(ip, mode, dir);
                        if (c == 'b' || c == 'l' || c == 't' || c == 'e' || c 
== 'o')
                                return ip;
                }
                return ip;
        }
}

Obj *draw_obj(Obj *ip, Fcode mode, int dir)     /* draw obj from coords at ip */
{
        int c, r, thick, n, shift, vshift, head, color, rgbcolor, fill;
        Point p0, p1, p2;
        char *tp;

        if (ip == 0)
                return 0;
        color = ip->opts[2];
        fill = ip->opts[0] - ip->opts[0]%10;    /* BUG!!!!! */
        rgbcolor = rgbval[color];
        switch (c = tolower(ip->type)) {
        case 'b':
                p0 = fetchpt(ip->view, ip->p0);
                p1 = fetchpt(ip->view, ip->u.p1);
                if (fill != Bnofill) {
                        if (p0.y < p1.y)        /* BUG: rect should be 
canonicalized */
                                texture(&screen, Rpt(p0, p1), rgbbitmap[color], 
S);
                        else
                                texture(&screen, Rect(p0.x,p1.y,p1.x,p0.y), 
rgbbitmap[color], S);
                } else {
                        segment(&screen, p0, Pt(p0.x,p1.y), rgbcolor, mode);
                        segment(&screen, Pt(p0.x,p1.y), p1, rgbcolor, mode);
                        segment(&screen, p1, Pt(p1.x,p0.y), rgbcolor, mode);
                        segment(&screen, Pt(p1.x,p0.y), p0, rgbcolor, mode);
                }
                break;
        case 'l':
                p0 = fetchpt(ip->view, ip->p0);
                p1 = fetchpt(ip->view, ip->u.p1);
                thick = ip->opts[0]/10; /* ought to be a macro! */
                if (thick == Ldotted/10 || thick == Ldashed/10)
                        thick = 1;
                thick = 2 * thick - 1;  /* 1,3,5 */
                fatline(p0, p1, mode, rgbcolor, thick);
                head = ip->opts[0]%10;  /* ditto */
                if (head == Larrow1 || head == Larrow3)
                        arrow(p0, p1, AW, AH, mode, rgbcolor);
                if (head == Larrow2 || head == Larrow3)
                        arrow(p1, p0, AW, AH, mode, rgbcolor);
                break;
        case 'o':
                p0 = fetchpt(ip->view, ip->p0);
                r = scalex(ip->view, ip->u.p1.x);
                if (r < 1)
                        r = 1;
                if (fill == Cnofill)
                        fatcircle(p0, r, mode, rgbcolor, 1);
                else
                        disc(&screen, p0, r + fatness, rgbcolor, mode);
                break;
        case 't':
                p0 = fetchpt(ip->view, ip->p0);
                if (ip->textlen >= sizeof(ip->u.text))
                        tp = ip->u.ptext;
                else
                        tp = ip->u.text;
                n = strwidth(font, tp); /* compute width the right way */
                shift = (ip->opts[0] & 31) / 10 * 10; /* ought to be a macro! */
                        /* "& 31" strips off vertical alignment codes */
                if (shift == Tljust)
                        shift = 0;
                else if (shift == Trjust)
                        shift = n;
                else    /* Tcenter */
                        shift = (n + 1) / 2;

                /* code to handle above/below: */
                vshift = ip->opts[0] / 32 * 32;

                if (vshift == Tabove)
                        vshift = font->height;
                else if (vshift == Tbelow)
                        vshift = 0;
                else    /* Tvcenter */
                        vshift = (font->height + 1) / 2;

                string(&screen, sub(p0, Pt(shift,vshift)), font, tp, mode);
                break;
        case 'c':
                break;
        default:
                break;
        }
        if (dir == Fwd)
                ip = next_obj(ip);
        else
                ip = prev_obj(ip);
        return ip;
}

erase(Obj *ip)
{
        Fcode mode = DxorS;

        if (xormode == DorS || xormode == Zero)
                mode = dir == Fwd ? Zero : DorS;
        draw_obj(ip, mode, Fwd);
}

void draw_dummy(void)   /* send some no-effect work to the screen */
{
        int r = Dx(myscreen.r)/2;
        Point pt;

        pt.x = myscreen.r.min.x + Dx(myscreen.r)/2;
        pt.y = myscreen.r.min.y + Dy(myscreen.r)/2;
        disc(&screen, pt, r, ONES, D);
        bflush();
}

#define abs(x) ((x) >= 0 ? (x) : -(x))

fatline(Point p0, Point p1, Fcode mode, int rgbcolor, int thick)
{
        int i, fat, beg, nl;

        fat = thick * (2 * fatness + 1);
        beg = fat / 2;
        if (abs(p1.x-p0.x) >= abs(p1.y-p0.y)) { /* horizontal */
                for (nl = 0, i = -beg; nl < fat; nl++, i++)
                        segment(&screen, add(p0, Pt(0,i)), add(p1, Pt(0,i)), 
rgbcolor, mode);
        } else {
                for (nl = 0, i = -beg; nl < fat; nl++, i++)
                        segment(&screen, add(p0, Pt(i,0)), add(p1, Pt(i,0)), 
rgbcolor, mode);
        } 
}

fatcircle(Point p0, int r, Fcode mode, int rgbcolor, int thick)
{
        int i, fat, beg, nl;

        fat = thick * (2 * fatness + 1);
        beg = fat / 2;
        for (nl = 0, i = -beg; nl < fat; nl++, i++)
                circle(&screen, p0, r+i, rgbcolor, mode);
}

arrow(Point p1, Point p2, int w, int h, Fcode c, int rgbcolor)
        /* draw arrow of height,width (h,w) at p2 of segment p1,p2 */
{
        Point d;
        int norm, qx, qy, lx, ly;

        d = sub(p2, p1);
        norm = sqrt((long)d.x*d.x + (long)d.y*d.y);
        if (norm == 0)  /* shouldn't happen, but ... */
                return 0;
        qx = p2.x - (h * d.x) / norm;
        qy = p2.y - (h * d.y) / norm;
        lx = (w/2 * -d.y) / norm;
        ly = (w/2 * d.x) / norm;
        segment(&screen, Pt(qx+lx, qy+ly), p2, rgbcolor, c);
        segment(&screen, Pt(qx-lx, qy-ly), p2, rgbcolor, c);
}

skipbl(FILE *fp)
{
        int c;

        while ((c = getc(fp)) == ' ' || c == '\t')
                ;
        return c;
}

skipline(FILE *fp)
{
        int c;

        while ((c = getc(fp)) != '\n')
                ;
        ungetc('\n', fp);
}


/* ===== MOUSE & KEYBOARD STUFF ===== */

char    *m3gen(int);
char    *m2gen(int);

Menu    mbut3   = { (char **) 0, m3gen, 0 };
Menu    mbut2   = { (char **) 0, m2gen, 0 };

char *m3gen(int n)
{
        static char buf[50];

        if (n < 0 || n > Quit)
                return 0;
        else if (n == Faster) {
                sprintf(buf, "faster %d", delay);
                return buf;
        } else if (n == Slower) {
                sprintf(buf, "slower %d", delay);
                return buf;
        } else if (n == Step) {
                return stepmenu[singstep];
        } else if (n == Forward) {
                return dirmenu[dir];
        } else if (n == Fatter) {
                sprintf(buf, "fatter %d", fatness+1);
                return buf;
        } else if (n == Thinner) {
                sprintf(buf, "thinner %d", fatness+1);
                return buf;
        } else if (n == Xor) {
                return xormode == DxorS ? modemenu[0] : modemenu[1];
        } else
                return m3[n];
}

char *m2gen(int n)
{
        static char buf[50];

        if (n < 0 || n >= nview+nclick)
                return 0;
        else if (n < nview) {
                sprintf(buf, "view %s", viewname[n]);
                return buf;
        } else {
                sprintf(buf, "click %s%s",
                        clickname[n-nview], clickval[n-nview] ? "*" : "");
                return buf;
        }
}


#define button3(b)      ((b) & 4)
#define button2(b)      ((b) & 2)
#define button1(b)      ((b) & 1)
#define button23(b)     ((b) & 6)
#define button123(b)    ((b) & 7)

int buttondown(void)    /* report state of buttons, if any */
{
        if (!ecanmouse())       /* no event pending */
                return 0;
        mouse = emouse();       /* something, but it could be motion */
        return mouse.buttons & 7;
}

int waitdown(void)      /* wait until some button is down */
{
        while (!(mouse.buttons & 7))
                mouse = emouse();
        return mouse.buttons & 7;
}

int waitup(void)
{
        while (mouse.buttons & 7)
                mouse = emouse();
        return mouse.buttons & 7;
}

checkmouse(void)        /* return button touched if any */
{
        int c, b;
        char *p = NULL;
        extern int confirm(int);

        b = waitdown();
        last_but = 0;
        last_hit = -1;
        c = 0;
        if (button3(b)) {
                last_hit = menuhit(3, &mouse, &mbut3);
                last_but = 3;
        } else if (button2(b)) {
                last_hit = menuhit(2, &mouse, &mbut2);
                last_but = 2;
        } else {                /* button1() */
                last_but = 1;
        }
        waitup();
        if (last_but == 3 && last_hit >= 0) {
                p = m3[last_hit];
                c = p[strlen(p) - 1];
        }
        if (c == '?' && !confirm(last_but))
                last_hit = -1;
        return last_but;
}

Cursor deadmouse = {
        { 0, 0},        /* offset */
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
          0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41,
          0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0,
          0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
          0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41,
          0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0,
          0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }
};

Cursor skull ={
        { 0, 0 },
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03,
          0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0,
          0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27,
          0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03,
          0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0,
          0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27,
          0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }
};

confirm(int but)        /* ask for confirmation if menu item ends with '?' */
{
        int c;
        static int but_cvt[8] = { 0, 1, 2, 0, 3, 0, 0, 0 };

        cursorswitch(&skull);
        c = waitdown();
        waitup();
        cursorswitch(0);
        return but == but_cvt[c];
}


do_kbd(void)    /* read a line from keyboard */
{
        char *p;

        for (p = kbdline; (*p = ekbd()) != '\n' && *p != '\r'; p++) {
                fprintf(stderr, "%c", *p);
                if (*p == '\b')
                        p -= 2;
                if (p < kbdline) {
                        p = kbdline;
                        *p = 0;
                }
                p[1] = 0;
                putstring(kbdline);
                
        }
        *p = 0;
        fprintf(stderr, "\n");
        /* fprintf(stderr, "\nfilename is [%s]\n", kbdline); */
        return strlen(kbdline);
}

void putstring(char *buf)
{
        Point p;
        static int jmax = 0, l;

        p = add(screen.r.min, Pt(20,20));
        bitblt(&screen, p, &screen, Rect(p.x, p.y, p.x+jmax, p.y+font->height), 
Zero);
        string(&screen, p, font, buf, DorS);
        if ((l = strwidth(font, buf)) > jmax)
                jmax = l;
}
END OF anim.c
echo 'fdevelop.c' 1>&2
cat >'fdevelop.c' <<'END OF fdevelop.c'
/* fdevelop: convert script to intermediate language in two passes
        Input defined in script.def, output in int.def
        Pass 1 reads named file or stdin, writes intermediate file
        Pass 2 reads intermediate, writes output
        Intermediate file is like output, with these differences:
                Header lines (d v, d c, etc.) absent
                Erase commands: refer to line numbers in int file and
                        do not have geometric command following
                Geometry commands: numbers not yet scaled, slots not
                        assigned
   fdevelop is a filter, transforming stdin or one named file to stdout
        the shell script develop uses this program to develop foo.s
          into foo.i, if needed
 */

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>

typedef struct Symbol { /* symbol table entry */
        struct Symbol   *next;
        char    *instr;
        int     innum;
        int     outnum;
} Symbol;

#define eq(s, t)        (strcmp(s,t) == 0)

extern char     *cmdname;
extern int      lineno;

extern char     *NULLSTR;
extern Symbol   *lookup();
extern          insert(), delete(), opensymtab(), closesymtab();

#define FATAL   1
#define WARN    0
extern          error();
extern char     *emalloc();
extern          efree();

#define MAXSTR  40      /* view names, click names, etc. */
#define MAXBUF  500     /* text strings */
#define LINEMAX 150000  /* input lines */
#define SLOTMAX 10000   /* for erasures */

extern int      moreinput();
extern          lex(), lexstr(), gobble();
extern          char buf[];
extern          lexsaweof;

extern char     *mktemp();


#define SCALE   9999

extern  dox(), doy();

/* SLOTS */
int     slotmax = SLOTMAX;

/* STATUS OF EACH LINE IN INTERMEDIATE FILE*/
int     linemax = LINEMAX;
char    *linevec;       /* malloc'ed to [linemax] before pass 1 */

#define MAXVIEWS        10
                          /* if >10 views, change one-byte getc in pass2 */
#define ERASED          11
#define NOTGEOM         12

/* VIEWS */
extern          recordx(), recordy();
extern int      scalex(), scaley();
int     viewcnt = 0;
struct  Viewelmt {
        char    name[MAXSTR];   /* character string name */
        float   maxx;           /* range of values, both coords */
        float   minx;
        float   maxy;
        float   miny;
        float   factorx;        /* factors used by scalex and scaley */
        float   factory;
        int     initx;          /* max and min set yet? */
        int     inity;
}       viewarr[MAXVIEWS];

/* CLICKS */
#define MAXCLICKS       30
int     clickcnt = 0;
char    clickname [MAXCLICKS] [MAXSTR];

/* OPTIONS FOR GEOMETRIC OBJECTS */
extern  getoptions();
#define OPTMAX 10
char    optstring[OPTMAX];
#define TEXT    0
#define LINE    1
#define BOX     2
#define CIRCLE  3
char    *defaulttab[] = { /* match with above defines */
        "cmx0", /* TEXT:   center, medium, vcenter, black */
        "s-0",  /* LINE:   solid, -, black              */
        "n0",   /* BOX:    nofill, black                */
        "n0"    /* CIRCLE: nofill, black                */
};
struct  Geoelmt {
        int     cmd;
        int     pos;
        char    *name;
        char    val;
} geooptarr[] = {
        TEXT,   0,      "center",       'c',
        TEXT,   0,      "ljust",        'l',
        TEXT,   0,      "rjust",        'r',
        TEXT,   1,      "medium",       'm',
        TEXT,   1,      "small",        's',
        TEXT,   1,      "big",          'b',
        TEXT,   1,      "bigbig",       'B',
        TEXT,   2,      "vcenter",      'x',
        TEXT,   2,      "above",        'a',
        TEXT,   2,      "below",        'u',
        TEXT,   3,      "c0",           '0',
        TEXT,   3,      "c1",           '1',
        TEXT,   3,      "c2",           '2',
        TEXT,   3,      "c3",           '3',
        TEXT,   3,      "c4",           '4',
        TEXT,   3,      "c5",           '5',
        TEXT,   3,      "c6",           '6',
        TEXT,   3,      "c7",           '7',
        TEXT,   3,      "black",        '0',
        TEXT,   3,      "red",          '1',
        TEXT,   3,      "green",        '2',
        TEXT,   3,      "yellow",       '3',
        TEXT,   3,      "blue",         '4',
        TEXT,   3,      "magenta",      '5',
        TEXT,   3,      "cyan",         '6',
        TEXT,   3,      "white",        '7',
        LINE,   0,      "solid",        's',
        LINE,   0,      "fat",          'f',
        LINE,   0,      "fatfat",       'F',
        LINE,   0,      "dotted",       'o',
        LINE,   0,      "dashed",       'a',
        LINE,   1,      "-",            '-',
        LINE,   1,      "->",           '>',
        LINE,   1,      "<-",           '<',
        LINE,   1,      "<->",          'x',
        LINE,   2,      "c0",           '0',
        LINE,   2,      "c1",           '1',
        LINE,   2,      "c2",           '2',
        LINE,   2,      "c3",           '3',
        LINE,   2,      "c4",           '4',
        LINE,   2,      "c5",           '5',
        LINE,   2,      "c6",           '6',
        LINE,   2,      "c7",           '7',
        LINE,   2,      "black",        '0',
        LINE,   2,      "red",          '1',
        LINE,   2,      "green",        '2',
        LINE,   2,      "yellow",       '3',
        LINE,   2,      "blue",         '4',
        LINE,   2,      "magenta",      '5',
        LINE,   2,      "cyan",         '6',
        LINE,   2,      "white",        '7',
        BOX,    0,      "nofill",       'n',
        BOX,    0,      "fill",         'f',
        BOX,    1,      "c0",           '0',
        BOX,    1,      "c1",           '1',
        BOX,    1,      "c2",           '2',
        BOX,    1,      "c3",           '3',
        BOX,    1,      "c4",           '4',
        BOX,    1,      "c5",           '5',
        BOX,    1,      "c6",           '6',
        BOX,    1,      "c7",           '7',
        BOX,    1,      "black",        '0',
        BOX,    1,      "red",          '1',
        BOX,    1,      "green",        '2',
        BOX,    1,      "yellow",       '3',
        BOX,    1,      "blue",         '4',
        BOX,    1,      "magenta",      '5',
        BOX,    1,      "cyan",         '6',
        BOX,    1,      "white",        '7',
        CIRCLE, 0,      "nofill",       'n',
        CIRCLE, 0,      "fill",         'f',
        CIRCLE, 1,      "c0",           '0',
        CIRCLE, 1,      "c1",           '1',
        CIRCLE, 1,      "c2",           '2',
        CIRCLE, 1,      "c3",           '3',
        CIRCLE, 1,      "c4",           '4',
        CIRCLE, 1,      "c5",           '5',
        CIRCLE, 1,      "c6",           '6',
        CIRCLE, 1,      "c7",           '7',
        CIRCLE, 1,      "black",        '0',
        CIRCLE, 1,      "red",          '1',
        CIRCLE, 1,      "green",        '2',
        CIRCLE, 1,      "yellow",       '3',
        CIRCLE, 1,      "blue",         '4',
        CIRCLE, 1,      "magenta",      '5',
        CIRCLE, 1,      "cyan",         '6',
        CIRCLE, 1,      "white",        '7'
};
int     geooptcnt = (sizeof(geooptarr) / sizeof(struct Geoelmt));

/* VARIABLES FOR LEXICAL ANALYSIS */
char    buf[MAXBUF];
int     lexsaweof = 0;

/* UTILITY VARIABLES */
char    *NULLSTR = "";
char    *cmdname;
int     lineno, outlineno;
char    *tempfname;
FILE    *infp, *tempfp;

#define STOF(s) ((float) atof(s))

int
main(argc, argv)
        char *argv[];
{
        register int    i;

        cmdname = argv[0];
        while (argc > 1 && argv[1][0] == '-') {
                switch (argv[1][1]) {
                case 'l':
                case 'm':
                        linemax = atoi(&argv[1][2]);
                        break;
                case 's':
                        slotmax = atoi(&argv[1][2]);
                        break;
                }
                argc--;
                argv++;
        }
        if (argc == 1)
                infp = stdin;
        else {
                if ((infp = fopen(argv[1], "r")) == NULL)
                        error(FATAL, "can't open input file");
        }
        linevec = emalloc(linemax);
        for (i = 0; i < linemax; i++)
                linevec[i] = 0;
        /* tempfname = "/usr/tmp/dev.XXXXXX";
        /* mktemp(tempfname);
        /* DEBUG tempfname = "djunk"; */

        tempfname = tmpnam(NULL);
        if ((tempfp = fopen(tempfname, "w")) == NULL)
                error(FATAL, "can't open temp file");
        pass1();
        fclose(tempfp);
        if ((tempfp = fopen(tempfname, "r")) == NULL)
                error(FATAL, "can't open temp file");
        pass2();
        unlink(tempfname); /* DEBUG */
        return 0;
}

pass1()
{
        int     currentview;            /* view number */
        int     erased[MAXVIEWS];       /* last line erased */
        int     badlabel;               /* 1 if label, 0 if geom */
        char    savelabel[MAXSTR];      /* label */
        int     geomalready = 0;        /* seen any geometry yet? */
        struct Symbol   *sp;
        int     i;

#define DOGEOM          badlabel = 0;\
                        geomalready = 1;\
                        linevec[outlineno] = currentview;

#define DOERASE(L)      linevec[(L)] = ERASED;\
                        linevec[outlineno] = NOTGEOM;\
                        fprintf(tempfp, "e\t%d\n", (L));\
                        outlineno++;

        /* init */
        currentview = 0;
        for (i = 0; i < MAXVIEWS; i++)
                erased[i] = 0;
        opensymtab();

        /* read and process file */
        lineno = 0;
        outlineno = 1;
        while (moreinput(infp)) {
                if (++lineno > linemax)
                        error(FATAL, "too many input lines");
                if (outlineno > linemax - 3)
                        error(FATAL, "too many output lines");
                /* fprintf(stderr, "STARTING TO PROCESS INPUT LINE %d\n",
                        lineno); */
                linevec[outlineno] = NOTGEOM;
                lex(infp);
                if (buf[0] == '#') {
                        gobble2(infp);
                        continue;
                }
                badlabel = 0;
                if (buf[strlen(buf)-1] == ':') {
                        buf[strlen(buf)-1] = '\0';
                        badlabel = 1;
                        strcpy(savelabel, buf);
                        sp = lookup(buf, currentview);
                        if (sp != NULL) {
                                if (linevec[sp->outnum] == currentview) {
                                        DOERASE(sp->outnum)
                                }
                                sp->outnum = outlineno;
                        } else {
                                insert(buf, currentview, outlineno);
                        }
                        lex(infp);
                }
                if (eq(buf, "text")) {
                        DOGEOM
                        getoptions(TEXT);
                        fprintf(tempfp, "g\t0\tt\t%d\t%s",
                                currentview, optstring);
                        dox(currentview);
                        lex(infp);
                        doy(currentview);
                        lexstr(infp);
                        fprintf(tempfp, "\t%s\n", buf);
                        outlineno++;
                } else if (eq(buf, "circle")) {
                        float savex, savey, rad;
                        DOGEOM
                        getoptions(CIRCLE);
                        fprintf(tempfp, "g\t0\tc\t%d\t%s",
                                currentview, optstring);
                        dox(currentview);
                        savex = STOF(buf);
                        lex(infp);
                        doy(currentview);
                        savey = STOF(buf);
                        lex(infp);
                        if (!strisnum(buf)) {
                                error(WARN, "radius not a number");
                                strcpy(buf, "0");
                        }
                        rad = STOF(buf);
                        if (rad < 0.0)
                                error(WARN, "radius is negative");
                        recordx(currentview, savex-rad);
                        recordx(currentview, savex+rad);
        /* bwk: added stuff to record y as well as x here */
                        recordy(currentview, savey-rad);
                        recordy(currentview, savey+rad);
                        fprintf(tempfp, "\t%s\n", buf); 
                        outlineno++;
                        gobble(infp);
                } else if (eq(buf, "line") || eq(buf, "box")) {
                        char cmdchar;
                        DOGEOM
                        if (eq(buf, "line")) {
                                getoptions(LINE);
                                cmdchar = 'l';
                        } else {
                                getoptions(BOX);
                                cmdchar = 'b';
                        }
                        fprintf(tempfp, "g\t0\t%c\t%d\t%s",
                                cmdchar, currentview, optstring);
                        dox(currentview);
                        lex(infp);
                        doy(currentview);
                        lex(infp);
                        dox(currentview);
                        lex(infp);
                        doy(currentview);
                        fprintf(tempfp, "\n");
                        outlineno++;
                        gobble(infp);
                } else if (eq(buf, "view")) {
                        lex(infp);
                        if (eq(buf,NULLSTR)) {
                                error(WARN, "no name in view statement");
                                strcpy(buf, "def.view");
                        }
                        if (viewcnt == 0 && geomalready)
                                error(WARN, "first view after geom");
                        for (i = 0; i < viewcnt; i++)
                                if (eq(buf, viewarr[i].name))
                                        break;
                        if (i >= viewcnt) {
                                viewcnt++;
                                if (i >= MAXVIEWS)
                                        error(FATAL, "too many views");
                                strcpy(viewarr[i].name, buf);
                                viewarr[i].initx = viewarr[i].inity = 0;
                        }
                        currentview = i;
                        gobble(infp);
                } else if (eq(buf, "click")) {
                        lex(infp);
                        if (eq(buf,NULLSTR))
                                strcpy(buf, "def.click");
                        for (i = 0; i < clickcnt; i++)
                                if (eq(buf, clickname[i]))
                                        break;
                        if (i >= clickcnt) {
                                clickcnt++;
                                if (i >= MAXCLICKS)
                                        error(FATAL, "too many click names");
                                strcpy(clickname[i], buf);
                        }
                        fprintf(tempfp, "c\t%d\n", i);
                        outlineno++;
                        gobble(infp);
                } else if (eq(buf, "erase")) {
                        lex(infp);
                        if (eq(buf,NULLSTR))
                                error(WARN, "no label in erase statement");
                        sp = lookup(buf, currentview);
                        if (sp != NULL) {
                                if (linevec[sp->outnum] == currentview) {
                                        DOERASE(sp->outnum)
                                }
                                delete(buf, currentview);
                        } else {
                                error(WARN, "undefined label");
                        }
                        gobble(infp);
                } else if (eq(buf, "clear")) {
                        int i, endline;
                        fprintf(tempfp, "b\ts\t%d\n", currentview);
                        endline = outlineno++;
                        for (i = erased[currentview]+1; i <= endline; i++) {
                                if (linevec[i] == currentview) {
                                        DOERASE(i)
                                }
                        }
                        erased[currentview] = outlineno;
                        fprintf(tempfp, "b\te\t%d\n", currentview);
                        linevec[outlineno] = NOTGEOM;
                        outlineno++;
                        gobble(infp);
                } else {
                        if (!eq(buf, NULLSTR))
                                error(WARN, "unrecognized command");
                        gobble(infp);
                }
                if (badlabel) {
                        error(WARN, "label on nongeometric object");
                        delete(savelabel, currentview);
                }
        }
        /* tidy up */
        lineno = 0;
        closesymtab();
        if (viewcnt == 0) {
                viewcnt = 1;
                strcpy(viewarr[0].name, "def.view");
        }
}


pass2()
{
        typedef struct Slot {
                union {
                        int     i;
                        char    *p;
                } v;
        } Slot;
        char    cmd;            /* first char on a line */
        int     tlineno;        /* line number in temp file */
        int     slothead;       /* ptr to free list within slots */
        Slot    *slotarr;       /* init by malloc to slotmax elmts */
        int     i;
        int     c;
        int     v;
        struct Viewelmt *vp;

        /* Init */
        opensymtab();
        slotarr = (Slot *) emalloc(slotmax * sizeof(Slot));
        for (i = 1; i <= slotmax-2; i++)
                slotarr[i].v.i = i+1;
        slothead = 1;
        /* Write header for output file */
        for (i = 0; i < viewcnt; i++) {
                vp = &viewarr[i];
                printf("d\tv\t%d\t%s\t%g\t%g\t%g\t%g\n", i,
                        vp->name, vp->minx, vp->miny, vp->maxx, vp->maxy);
        }
        for (i = 0; i < clickcnt; i++)
                printf("d\tc\t%d\t%s\n", i, clickname[i]);
        printf("d\tp\te\n");
        /* Calculate view factors used to scale */
        for (v = 0; v < viewcnt; v++) {
                vp = &viewarr[v];
                if (vp->minx == vp->maxx) {
                        vp->minx = 0.0;
                        vp->maxx = 2*vp->maxx;
                        if (vp->maxx == 0.0) {
                                vp->minx = -1.0;
                                vp->maxx =  1.0;
                        }
                }
                vp->factorx = SCALE / (vp->maxx-vp->minx);
                if (vp->miny == vp->maxy) {
                        vp->miny = 0.0;
                        vp->maxy = 2*vp->maxy;
                        if (vp->maxy == 0.0) {
                                vp->miny = -1.0;
                                vp->maxy =  1.0;
                        }
                }
                vp->factory = SCALE / (vp->maxy-vp->miny);
        }
        /* Read and process intermediate file */
        tlineno = 0;
        while ((c = getc(tempfp)) != EOF) {
                tlineno++;
                cmd = c;
                getc(tempfp);   /* gobble tab */
                putchar(cmd);
                putchar('\t');
                if (cmd == 'g') {
                        int snum, vnum;
                        char gcmd;
                        char opts[OPTMAX];
                        float x1, y1, x2, y2;
                        int   i1, j1, i2, j2;
                        char bufa[MAXBUF+100];
                        /* fscanf(tempfp, "%d %c %d", &snum, &gcmd, &vnum); */
                          getc(tempfp); /* don't need snum -- always zero */
                          getc(tempfp); /* gobble tab */
                          gcmd = getc(tempfp);
                          getc(tempfp); /* gobble tab */
                          vnum = getc(tempfp) - '0';
                        fscanf(tempfp, "%s %f %f", opts, &x1, &y1);
                        if (linevec[tlineno] != ERASED)
                                snum = 0;
                        else {
                                snum = slothead;
                                slothead = slotarr[snum].v.i;
                                if (slothead == 0)
                                        error(FATAL, "ran out of slots");
                        }
                        insert(NULLSTR, tlineno, snum);
                        i1 = scalex(vnum, x1);
                        j1 = scaley(vnum, y1);
                        if (gcmd == 'b' || gcmd == 'l') {
                                fscanf(tempfp, "%f %f", &x2, &y2);
                                if (getc(tempfp) != '\n')
                                        error(FATAL, "develop bug: missing 
newline");
                                i2 = scalex(vnum, x2);
                                j2 = scaley(vnum, y2);
                                if (gcmd == 'b') {
                                        int t; /* normalize: min, max */
                                        if (i1 > i2) { t=i1; i1=i2; i2=t; }
                                        if (j1 > j2) { t=j1; j1=j2; j2=t; }
                                }
                                sprintf(bufa, "%d\t%c\t%d\t%s\t%d\t%d\t%d\t%d",
                                        snum, gcmd, vnum, opts, i1, j1, i2, j2);
                        } else if (gcmd == 'c') {
                                fscanf(tempfp, "%f", &x2);
                                if (getc(tempfp) != '\n')
                                        error(FATAL, "develop bug: missing 
newline");
                                i2 = scalex(vnum, x1+x2) - i1;
                                if (i2 < 0)
                                        i2 = -i2;
                                if (i2 == 0)
                                        i2 = 1;
                                sprintf(bufa, "%d\t%c\t%d\t%s\t%d\t%d\t%d",
                                        snum, gcmd, vnum, opts, i1, j1, i2);
                        } else if (gcmd == 't') {
                                getc(tempfp); /* gobble tab */
                                lexrest(tempfp);
                                sprintf(bufa, "%d\t%c\t%d\t%s\t%d\t%d\t%s",
                                        snum, gcmd, vnum, opts, i1, j1, buf);
                        } else error(FATAL, "develop bug: invalid g cmd");
                        slotarr[snum].v.p = emalloc(strlen(bufa)+1);
                        strcpy(slotarr[snum].v.p, bufa);
                        puts(bufa);
                } else if (cmd == 'e') {
                        int linenum, slotnum;
                        Symbol *sp;
                        fscanf(tempfp, "%d", &linenum);
                        if (getc(tempfp) != '\n')
                                error(FATAL, "develop bug: missing newline");
                        sp = lookup(NULLSTR, linenum);
                        if (sp == NULL)
                                error(FATAL, "develop bug: bad erase lookup");
                        slotnum = sp->outnum;
                        puts(slotarr[slotnum].v.p);
                        efree(slotarr[slotnum].v.p);
                        slotarr[slotnum].v.i = slothead;
                        slothead = slotnum;
                        delete(NULLSTR, linenum);
                } else {
                        lexrest(tempfp);
                        puts(buf);
                }
        }
        /* tidy up */
                /* closesymtab(); delete stuff in slots? */
}

recordx(vnum, t)
        int vnum;
        float t;
{
        struct Viewelmt *vp;

        vp = &viewarr[vnum];
        if (vp->initx != 1) {
                vp->initx = 1;
                vp->minx = t;   
                vp->maxx = t;
        } else {
                if (t < vp->minx)
                        vp->minx = t;   
                if (t > vp->maxx)
                        vp->maxx = t;
        }
}

recordy(vnum, t)
        int vnum;
        float t;
{
        struct Viewelmt *vp;

        vp = &viewarr[vnum];
        if (vp->inity != 1) {
                vp->inity = 1;
                vp->miny = t;   
                vp->maxy = t;
        } else {
                if (t < vp->miny)
                        vp->miny = t;   
                if (t > vp->maxy)
                        vp->maxy = t;
        }
}

int scalex(vnum, t)
        int vnum;
        float t;
{
        struct Viewelmt *vp;

        vp = &viewarr[vnum];
        return (int) ((t - vp->minx) * vp->factorx);
}

int scaley(vnum, t)
        int vnum;
        float t;
{
        struct Viewelmt *vp;

        vp = &viewarr[vnum];
        return (int) ((t - vp->miny) * vp->factory);
}

getoptions(cmdtype)     /* put options into optstring */
        int cmdtype;
{
        int i;
        struct Geoelmt *gp;

        strcpy(optstring, defaulttab[cmdtype]);
        for (lex(infp); !eq(buf,NULLSTR) && !strisnum(buf); lex(infp)) {
                for (i = 0; i < geooptcnt; i++) {
                        gp = &geooptarr[i];
                        if (cmdtype == gp->cmd && eq(buf, gp->name))
                                break;
                }
                if (i < geooptcnt)
                        optstring[gp->pos] = gp -> val;
                else
                        error(WARN, "unrecognized option");
        }
}

dox(view)       /* handle x in input file */
        int view;
{
        if (!strisnum(buf)) {
                error(WARN, "x value not a number");
                strcpy(buf, "0");
        }
        recordx(view, STOF(buf));
        fprintf(tempfp, "\t%s", buf);   
}

doy(view)       /* handle y in input file */
        int view;
{
        if (!strisnum(buf)) {
                error(WARN, "y value not a number");
                strcpy(buf, "0");
        }
        recordy(view, STOF(buf));
        fprintf(tempfp, "\t%s", buf);   
}



/* symbol.c:
        General: functions for mapping {string} x {int} -> {int}
        In pass 1: {name} x {viewnum} -> {int file line num}
        In pass 2: {} x {int file line num} -> {slot num}
                   Therefore be careful with blank strings
 */

#define steq(s, n, p) ((p)->innum == (n) && \
                        (((p)->instr == (s)) || eq((p)->instr,s)))

#define SIZE    2053
Symbol  *head[SIZE];

int hash(s, n)  /* form hash value */
        register char *s;
        register int n;
{
        register int hashval;

        for (hashval = 0; *s != '\0'; s++)
                hashval = (*s + 31 * hashval) % SIZE;
        hashval = (31 * hashval + 1259 * n) % SIZE;
        return hashval;
}

Symbol *lookup(s, n)    /* return element with s, n */
        register char *s;
        register int n;
{
        register Symbol *p;
        for (p = head[hash(s, n)]; p != NULL; p = p->next)
                if (steq(s, n, p))
                        return p;
        return NULL;
}

insert(s, n, v) /* insert s, n with value v */
        register char *s;
        register int n;
        int v;
{
        register Symbol *p;
        char *q;
        int i;

        /* fprintf(stderr, "Inserting: |%s|, %d with hash %d\n",
                s, n, hash(s,n)); */
        if (*s == '\0')
                q = NULLSTR;
        else {
                q = emalloc(strlen(s)+1);
                strcpy(q, s);
        }
        p = (Symbol *) emalloc(sizeof(Symbol));
        p->instr = q;
        p->innum = n;
        p->outnum = v;
        i = hash(s, n);
        p->next = head[i];
        head[i] = p;
}

delete(s, n)    /* remove s, n */
        char *s;
        int n;
{
        Symbol *p, *pp;
        int i;

        /* fprintf(stderr, "Deleting:  |%s|, %d with hash %d\n",
                s, n, hash(s,n)); */
        i = hash(s, n);
        pp = NULL;
        for (p = head[i]; p != NULL; p = p->next) {
                if (steq(s, n, p))
                        break;
                pp = p;
        }
        if (p == NULL)
                error(FATAL, "symtab bug: bad delete");
        if (p->instr != NULLSTR)
                efree(p->instr);
        if (pp == NULL) {
                head[i] = p->next;
        } else {
                pp->next = p->next;
        }
        efree((char *) p);
}

opensymtab()    /* init table */
{
        int i;

        for (i = 0; i < SIZE; i++)
                head[i] = NULL;
}

closesymtab()   /* reclaim storage */
{
        int i;
        Symbol *p, *np;

        for (i = 0; i < SIZE; i++)
                for (p = head[i]; p != NULL; p = np) {
                        if (p->instr != NULLSTR)
                                efree(p->instr);
                        np = p->next;
                        efree((char *) p);
                }
}



/* util.c: utility routines */


error(f, s)
        int f;
        char *s;
{
        fprintf(stderr, "%s: %s\n", cmdname, s);
        if (lineno)
                fprintf(stderr, " source line number %d\n", lineno);
        if (f)
                exit(2);
}

int strisnum(p)         /* 1 if string p represents a float */
        register char *p;
{
        register int digits = 0;
        register int n;
                                                /* REG EXPR:    */
        if (*p == '-')                          /* -?           */
                p++;
        while (isdigit(*p)) {
                digits++;                       /* [0-9]*       */
                p++;
        }
        if (*p == '.') {                        /* (.[0-9]*)?   */
                p++;
                while (isdigit(*p)) {
                        digits++;
                        p++;
                }
        }
        if (digits == 0)                        /* >0 digits    */
                return 0;
        if (tolower(*p) == 'e') {               /* ([eE]        */
                *p++;
                if (*p == '+' || *p == '-')     /*  [+-]?       */
                        p++;
                digits = 1;
                if (!isdigit(*p))               /*  [0-9]       */
                        return 0;
                n = *p++ - '0';
                while (isdigit(*p)) {           /*  [0-9]+      */
                        digits++;
                        n = 10*n + *p++ - '0';
                        if (n > 30)
                                return 0;
                }
                if (digits == 0)
                        return 0;               /*        )?    */
        }
        return (*p == '\0');
}

int moreinput(fp)
        FILE *fp;
{
        int c;

        if (lexsaweof)
                return 0;
        c = getc(fp);
        if (c == EOF)
                return 0;
        ungetc(c, fp);
        return 1;
}

#define CHECKEOF                if (c == EOF) {\
                lexsaweof = 1;\
                error(WARN, "file does not end with newline");\
                return;\
        }


lex(fp)         /* put next string of non-white into buf */
        register FILE *fp;
{
        register int c;
        register char *p, *danger;

        danger = &buf[MAXSTR-1];
        while ((c = getc(fp)) == ' ' || c == '\t')
                ;
        CHECKEOF
        if (c == '\n') {
                ungetc(c, fp);
                buf[0] = '\0';
                return;
        }
        p = buf;
        *p++ = c;
        while ((c = getc(fp)) != EOF && c != ' ' && c != '\t' && c != '\n') {
                if (p < danger) 
                        *p++ = c;
                else if (p == danger)
                        error(WARN, "string too long -- truncated");
        }
        *p = '\0';
        CHECKEOF
        if (c == '\n')
                ungetc(c, fp);
/* fprintf(stderr, "lex returning: %s\n", buf); */
}


lexstr(fp)              /* like lex, but go til newline and handle quotes */
        FILE *fp;
{
        int c;
        int quoted = 0;
        char *p, *danger;

        while ((c = getc(fp)) == ' ' || c == '\t')
                ;
        CHECKEOF
        if (c == '\"') {
                quoted = 1;
                c = getc(fp);
                CHECKEOF
        }
        if (c == '\n') {
                buf[0] = '\0';
                return;
        }
        p = buf;
        *p++ = c;
        danger = &buf[MAXBUF-1];
        while ((c = getc(fp)) != EOF && c != '\n') {
                if (p < danger) 
                        *p++ = c;
                else if (p == danger)
                        error(WARN, "text string too long -- truncated");
        }
        CHECKEOF
        *p = '\0';
        if (quoted && *(--p) == '\"')
                *p = '\0';
}

lexrest(fp)             /* get rest of line into buf */
                        /* no error checking; error free from Pass 1 */
        FILE *fp;
{
        int c;
        char *p;

        p = buf;
        while ((c = getc(fp)) != EOF && c != '\n') {
                *p++ = c;
        }
        *p = '\0';
}

gobble(fp)              /* chew space til EOF; complain if nonwhite */
        FILE *fp;
{
        int c;

        while ((c = getc(fp)) == ' ' || c == '\t')
                ;
        CHECKEOF
        if (c != '\n') {
                error(WARN, "garbage at end of line");
                while ((c = getc(fp)) != EOF && c != '\n')
                        ;
                CHECKEOF
        }
}

gobble2(fp)             /* chew space til EOF, no complaints */
        FILE *fp;
{
        int c;

        while ((c = getc(fp)) != EOF && c != '\n')
                ;
        CHECKEOF
}

#define WANTPROF 0
#if WANTPROF
        int     hmallocinit;
        FILE    *hmallocfp;
#endif

char *emalloc(n)        /* check return from malloc */
        int n;
{
        char *p;

#if WANTPROF
        if (hmallocinit == 0) {
                hmallocinit = 1;
                if ((hmallocfp = fopen("/usr/tmp/malloc.hist", "w")) == NULL)
                        error(FATAL, "malloc history bug: can't open file");
        }
#endif
        p = malloc((size_t) n);
        if (p == NULL)
                error(FATAL, "out of memory");
#if WANTPROF
        fprintf(hmallocfp, "m\t%d\t%d\n", (int) p, n);
#endif
        return p;
}

efree(p)                /* personal version of free to match emalloc */
        char *p;
{
#if WANTPROF
        if (hmallocinit == 0)
                error(FATAL, "malloc history bug: first free before malloc");
        fprintf(hmallocfp, "f\t%d\n", (int) p);
#endif
        free(p);
}
END OF fdevelop.c
echo 'newer.c' 1>&2
cat >'newer.c' <<'END OF newer.c'
#include <sys/types.h>
#include <sys/stat.h>

/*
 *      newer x y
 *
 *      returns 0 if x exists and y does not, or if
 *      files x and y both exist and x was modified
 *      at least as recently as y, and nonzero otherwise.
 */

int
main (argc, argv)
        int argc;
        char *argv[];
{
        struct stat x, y;

        /* insist on exactly two args */
        if (argc != 3)
                return 1;
        
        /* does the first file exist? */
        if (stat(argv[1], &x) < 0)
                return 1;
        
        /* does the second file exist? */
        if (stat(argv[2], &y) < 0)
                return 0;
        
        /* fail if the first file is older than the second */
        if (x.st_mtime < y.st_mtime)
                return 1;
        
        /* otherwise, succeed */
        return 0;
}
END OF newer.c
echo 'libXg.bundle' 1>&2
cat >'libXg.bundle' <<'END OF libXg.bundle'
#!/bin/sh
# Self-unpacking archive format.  To unbundle, sh this file.
echo 'README' 1>&2
cat >'README' <<'END OF README'
This is an implementation of Plan 9's graphics library
under X using the Xt intrinsics. It should work for
X11 release 3 or higher.

The manual pages graphics.3, balloc.3, bitblt.3, event.3
and rgbpix.3 describe the libg interface, with the following
differences necessary to accommodate X:

- xtbinit is used to initialize the library, instead of
  binit

- getfont is used to read a font by name, instead of
  falloc, ffree, rdfontfile, wrfontfile

- divpt is the name of libg's div (which conflicts with ANSI)

- the event stuff is not optional (or bflush must be
  called every now and then)

END OF README
echo 'Make.aix' 1>&2
cat >'Make.aix' <<'END OF Make.aix'
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.
#
#       Prototype Aix Makefile for libXg
#       Courtesy of Dan McDonald
#
#       Define operating system type: -DAIX
#
#       Additionally, -D_POSIX_SOURCE (or its equivalent) may be specified
#       if your compiler supports posix-compatible compilation

OS=-DAIX -D_POSIX_SOURCE -D_ANSI_C_SOURCE

#       add -Iincludedir for any include directories that need to be searched
INCS=-I.

#       set this if your X libraries are in different locations
#       or if you need extra libraries to load with X11 applications
XLIBS=/usr/local/X11R5/lib/libXt.a /usr/local/X11R5/lib/libX11.a

#       add name of library orderer - use ":" if none
RANLIB=:

#       add name of librarian
AR=ar

#       the name of the library
LIB=libXg.a

CFLAGS=$(OS) -D_LIBXG_EXTENSION $(INCS) $(XCFLAGS)

###  AIX NOTE:  Normally, the way to invoke the RS/6000 C compiler for ANSI
###             C is to use "xlc".  The X include files here seem to not like
###             ANSI, so "cc" is used here, which compiles "EXTENDED" level
###             C.  (Kinda like gcc's default mode.)

CC=cc

OBJS=   arc.o arith.o balloc.o bitblt.o bitbltclip.o border.o bscreenrect.o\
        circle.o clipline.o clipr.o copymasked.o cursorset.o cursorswitch.o\
        disc.o ellipse.o font.o gcs.o getrect.o gwin.o latin1.o mkfont.o\
        menuhit.o point.o rdbitmap.o rdbitmapfile.o rdfontfile.o\
        rectclip.o rune.o segment.o string.o strwidth.o texture.o\
        wrbitmap.o wrbitmapfile.o xtbinit.o

all install:    $(LIB)
compile:        $(LIB)
test:   test.o
        $(CC) -o $@ $? $(LIB) $(XLIBS) -lm
        echo try running test
clean:
        rm -f *.o test

nuke:   clean
        rm -f $(LIB)

$(LIB): $(OBJS)
        $(AR) rv $(LIB) $(OBJS)
        $(RANLIB) $(LIB)

$(LIB)(%.o): %.o

$(OBJS):        libg.h libgint.h libc.h
END OF Make.aix
echo 'Make.apollo' 1>&2
cat >'Make.apollo' <<'END OF Make.apollo'
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.
#
#       Prototype Apollo Makefile for libXg 
#       Courtesy of Ed Kubaitis
#
#       Define operating system type: -DAPOLLO
#       
#       Additionally, -D_POSIX_SOURCE (or its equivalent) may be specified
#       if your compiler supports posix-compatible compilation
OS=-DAPOLLO -D_POSIX_SOURCE -A ansi

#       add -Iincludedir for any include directories that need to be searched
INCS=-I.

#       set this if your X libraries are in different locations
#       or if you need extra libraries to load with X11 applications
XLIBS=-lXt -lX11

#       add name of library orderer - use ":" if none
RANLIB=ranlib

#       add name of librarian
AR=ar

#       the name of the library
LIB=libXg.a

CFLAGS=$(OS)  -D_LIBXG_EXTENSION $(INCS) $(XCFLAGS)
CC=cc

OBJS=   arc.o arith.o balloc.o bitblt.o bitbltclip.o border.o bscreenrect.o\
        circle.o clipline.o clipr.o copymasked.o cursorset.o cursorswitch.o\
        disc.o ellipse.o font.o gcs.o getrect.o gwin.o latin1.o mkfont.o\
        menuhit.o point.o rdbitmap.o rdbitmapfile.o rdfontfile.o\
        rectclip.o rune.o segment.o string.o strwidth.o texture.o\
        wrbitmap.o wrbitmapfile.o xtbinit.o

all install:    $(LIB)
compile:        $(LIB)
test:   test.o
        $(CC) -o $@ $? $(LIB) $(XLIBS) -lm
        echo try running test
clean:
        rm -f *.o test

nuke:   clean
        rm -f $(LIB)

$(LIB): $(OBJS)
        $(AR) rv $(LIB) $(OBJS)
        $(RANLIB) $(LIB)

$(LIB)(%.o): %.o

$(OBJS):        libg.h libgint.h libc.h
END OF Make.apollo
echo 'Make.convex' 1>&2
cat >'Make.convex' <<'END OF Make.convex'
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.
#
#       Prototype Convex Makefile for libXg 
#       Courtesy of Ed Kubaitis
#
#       Define operating system type: -DCONVEX
#       
#       Additionally, -D_POSIX_SOURCE (or its equivalent) may be specified
#       if your compiler supports posix-compatible compilation
OS=-DCONVEX -D_POSIX_SOURCE

#       add -Iincludedir for any include directories that need to be searched
INCS=-I.

#       set this if your X libraries are in different locations
#       or if you need extra libraries to load with X11 applications
XLIBS=/usr/lib/libXt.a /usr/lib/libX11.a

#       add name of library orderer - use ":" if none
RANLIB=ranlib

#       add name of librarian
AR=ar

#       the name of the library
LIB=libXg.a

CFLAGS=$(OS) -D_LIBXG_EXTENSION $(INCS) $(XCFLAGS)
CC=cc

OBJS=   arc.o arith.o balloc.o bitblt.o bitbltclip.o border.o bscreenrect.o\
        circle.o clipline.o clipr.o copymasked.o cursorset.o cursorswitch.o\
        disc.o ellipse.o font.o gcs.o getrect.o gwin.o latin1.o mkfont.o\
        menuhit.o point.o rdbitmap.o rdbitmapfile.o rdfontfile.o\
        rectclip.o rune.o segment.o string.o strwidth.o texture.o\
        wrbitmap.o wrbitmapfile.o xtbinit.o

all install:    $(LIB)
compile:        $(LIB)
test:   test.o
        $(CC) -o $@ $? $(LIB) $(XLIBS) -lm
        echo try running test
clean:
        rm -f *.o test

nuke:   clean
        rm -f $(LIB)

$(LIB): $(OBJS)
        $(AR) rv $(LIB) $(OBJS)
        $(RANLIB) $(LIB)

$(LIB)(%.o): %.o

$(OBJS):        libg.h libgint.h libc.h
END OF Make.convex
echo 'Make.dec' 1>&2
cat >'Make.dec' <<'END OF Make.dec'
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.
#
#       Prototype Decstation 3100 Makefile for libXg
#       Courtesy of Alain Kagi
#
#       Define operating system type: -DUMIPS
#
#       Additionally, -D_POSIX_SOURCE (or its equivalent) may be specified
#       if your compiler supports posix-compatible compilation
OS=-DUMIPS -DMips

#       add -Iincludedir for any include directories that need to be searched
INCS=-I.

#       set this if your X libraries are in different locations
#       or if you need extra libraries to load with X11 applications
XLIBS=/usr/misc/X11/lib/libXt.a /usr/misc/X11/lib/libX11.a

#       add name of library orderer - use ":" if none
RANLIB=ranlib

#       add name of librarian
AR=ar

#       the name of the library
LIB=libXg.a

CFLAGS=$(OS) -D_LIBXG_EXTENSION $(INCS) $(XCFLAGS)
CC=cc

OBJS=   arc.o arith.o balloc.o bitblt.o bitbltclip.o border.o bscreenrect.o\
        circle.o clipline.o clipr.o copymasked.o cursorset.o cursorswitch.o\
        disc.o ellipse.o font.o gcs.o getrect.o gwin.o latin1.o mkfont.o\
        menuhit.o point.o rdbitmap.o rdbitmapfile.o rdfontfile.o\
        rectclip.o rune.o segment.o string.o strwidth.o texture.o\
        wrbitmap.o wrbitmapfile.o xtbinit.o

all install:    $(LIB)
compile:        $(LIB)
test:   test.o
        $(CC) -o $@ $? $(LIB) $(XLIBS)
        echo try running test
clean:
        rm -f *.o test

nuke:   clean
        rm -f $(LIB)

$(LIB): $(OBJS)
        $(AR) rv $(LIB) $(OBJS)
        $(RANLIB) $(LIB)

$(LIB)(%.o): %.o

$(OBJS):        libg.h libgint.h libc.h
END OF Make.dec
echo 'Make.dynix' 1>&2
cat >'Make.dynix' <<'END OF Make.dynix'
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.
#
#       Prototype Dynix Makefile for libXg 
#       Courtesy of Ed Kubaitis
#
#       Define operating system type: -DDYNIX
#       
#       Additionally, -D_POSIX_SOURCE (or its equivalent) may be specified
#       if your compiler supports posix-compatible compilation
OS=-DDYNIX -D_POSIX_SOURCE

#       add -Iincludedir for any include directories that need to be searched
INCS=-I.

#       set this if your X libraries are in different locations
#       or if you need extra libraries to load with X11 applications
XLIBS=/usr/lib/libXt.a /usr/lib/libX11.a

#       add name of library orderer - use ":" if none
RANLIB=ranlib

#       add name of librarian
AR=ar

#       the name of the library
LIB=libXg.a

CFLAGS=$(OS) -D_LIBXG_EXTENSION $(INCS) $(XCFLAGS)
CC=gcc

OBJS=   arc.o arith.o balloc.o bitblt.o bitbltclip.o border.o bscreenrect.o\
        circle.o clipline.o clipr.o copymasked.o cursorset.o cursorswitch.o\
        disc.o ellipse.o font.o gcs.o getrect.o gwin.o latin1.o mkfont.o\
        menuhit.o point.o rdbitmap.o rdbitmapfile.o rdfontfile.o\
        rectclip.o rune.o segment.o string.o strwidth.o texture.o\
        wrbitmap.o wrbitmapfile.o xtbinit.o

all install:    $(LIB)
compile:        $(LIB)
test:   test.o
        $(CC) -o $@ $? $(LIB) $(XLIBS) -lm
        echo try running test
clean:
        rm -f *.o test

nuke:   clean
        rm -f $(LIB)

$(LIB): $(OBJS)
        $(AR) rv $(LIB) $(OBJS)
        $(RANLIB) $(LIB)

$(LIB)(%.o): %.o

$(OBJS):        libg.h libgint.h libc.h
END OF Make.dynix
echo 'Make.hpux' 1>&2
cat >'Make.hpux' <<'END OF Make.hpux'
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.
#
#       Prototype HP-UX Makefile for libXg 
#       Courtesy of Ed Kubaitis
#
#       Define operating system type: -DHPUX
#       
#       Additionally, -D_POSIX_SOURCE (or its equivalent) may be specified
#       if your compiler supports posix-compatible compilation
OS=-DHPUX -D_POSIX_SOURCE -A a 

#       add -Iincludedir for any include directories that need to be searched
INCS=-I/usr/include/X11R4 -I.

#       set this if your X libraries are in different locations
#       or if you need extra libraries to load with X11 applications
XLIBS=

#       add name of library orderer - use ":" if none
RANLIB=ranlib

#       add name of librarian
AR=ar

#       the name of the library
LIB=libXg.a

CFLAGS=$(OS)  -D_LIBXG_EXTENSION $(INCS) $(XCFLAGS)
CC=cc

OBJS=   arc.o arith.o balloc.o bitblt.o bitbltclip.o border.o bscreenrect.o\
        circle.o clipline.o clipr.o copymasked.o cursorset.o cursorswitch.o\
        disc.o ellipse.o font.o gcs.o getrect.o gwin.o latin1.o mkfont.o\
        menuhit.o point.o rdbitmap.o rdbitmapfile.o rdfontfile.o\
        rectclip.o rune.o segment.o string.o strwidth.o texture.o\
        wrbitmap.o wrbitmapfile.o xtbinit.o

all install:    $(LIB)
compile:        $(LIB)
test:   test.o
        $(CC) -o $@ $? $(LIB) $(XLIBS) -lm
        echo try running test
clean:
        rm -f *.o test

nuke:   clean
        rm -f $(LIB)

$(LIB): $(OBJS)
        $(AR) rv $(LIB) $(OBJS)
        $(RANLIB) $(LIB)

$(LIB)(%.o): %.o

$(OBJS):        libg.h libgint.h libc.h
END OF Make.hpux
echo 'Make.irix' 1>&2
cat >'Make.irix' <<'END OF Make.irix'
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.
#
#       Prototype Silicon Graphics Makefile for libXg
#
#       Define operating system type: -DIRIX
#
#       Additionally, -D_POSIX_SOURCE (or its equivalent) may be specified
#       if your compiler supports posix-compatible compilation
OS=-DIRIX -ansiposix

#       add -Iincludedir for any include directories that need to be searched
INCS=-I.

#       set this if your X libraries are in different locations
#       or if you need extra libraries to load with X11 applications
XLIBS=/usr/local/X11R5/lib/libXt.a /usr/local/X11R5/lib/libX11.a

#       add name of library orderer - use ":" if none
RANLIB=:

#       add name of librarian
AR=ar

#       the name of the library
LIB=libXg.a

CFLAGS=$(OS) -D_LIBXG_EXTENSION $(INCS) $(XCFLAGS)
CC=cc

OBJS=   arc.o arith.o balloc.o bitblt.o bitbltclip.o border.o bscreenrect.o\
        circle.o clipline.o clipr.o copymasked.o cursorset.o cursorswitch.o\
        disc.o ellipse.o font.o gcs.o getrect.o gwin.o latin1.o mkfont.o\
        menuhit.o point.o rdbitmap.o rdbitmapfile.o rdfontfile.o\
        rectclip.o rune.o segment.o string.o strwidth.o texture.o\
        wrbitmap.o wrbitmapfile.o xtbinit.o

all install:    $(LIB)
compile:        $(LIB)
test:   test.o
        $(CC) -o $@ $? $(LIB) $(XLIBS) -lm
        echo try running test
clean:
        rm -f *.o test

nuke:   clean
        rm -f $(LIB)

$(LIB): $(OBJS)
        $(AR) rv $(LIB) $(OBJS)
        $(RANLIB) $(LIB)

$(LIB)(%.o): %.o

$(OBJS):        libg.h libgint.h libc.h
END OF Make.irix
echo 'Make.mips' 1>&2
cat >'Make.mips' <<'END OF Make.mips'
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.
#
#       Prototype Mips Makefile for libXg
#
#       Define operating system type: -DUMIPS
#
#       Additionally, -D_POSIX_SOURCE (or its equivalent) may be specified
#       if your compiler supports posix-compatible compilation
OS=-DUMIPS -DMips

#       add -Iincludedir for any include directories that need to be searched
INCS=-I.

#       set this if your X libraries are in different locations
#       or if you need extra libraries to load with X11 applications
XLIBS=/usr/local/X11R5/lib/libXt.a /usr/local/X11R5/lib/libX11.a

#       add name of library orderer - use ":" if none
RANLIB=:

#       add name of librarian
AR=ar

#       the name of the library
LIB=libXg.a

CFLAGS=$(OS) -D_LIBXG_EXTENSION $(INCS) $(XCFLAGS)
CC=cc

OBJS=   arc.o arith.o balloc.o bitblt.o bitbltclip.o border.o bscreenrect.o\
        circle.o clipline.o clipr.o copymasked.o cursorset.o cursorswitch.o\
        disc.o ellipse.o font.o gcs.o getrect.o gwin.o latin1.o mkfont.o\
        menuhit.o point.o rdbitmap.o rdbitmapfile.o rdfontfile.o\
        rectclip.o rune.o segment.o string.o strwidth.o texture.o\
        wrbitmap.o wrbitmapfile.o xtbinit.o

all install:    $(LIB)
compile:        $(LIB)
test:   test.o
        $(CC) -o $@ $? $(LIB) $(XLIBS)
        echo try running test
clean:
        rm -f *.o test

nuke:   clean
        rm -f $(LIB)

$(LIB): $(OBJS)
        $(AR) rv $(LIB) $(OBJS)
        $(RANLIB) $(LIB)

$(LIB)(%.o): %.o

$(OBJS):        libg.h libgint.h libc.h
END OF Make.mips
echo 'Make.osf' 1>&2
cat >'Make.osf' <<'END OF Make.osf'
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.
#
#       Prototype OSF/1 1.1 Makefile for libXg 
#       Courtesy of Rich Salz
#
#       Define operating system type: -DOSF1
#       
#       Additionally, -D_POSIX_SOURCE (or its equivalent) may be specified
#       if your compiler supports posix-compatible compilation
OS=-D_POSIX_SOURCE -DOSF1

#       add -Iincludedir for any include directories that need to be searched
INCS=-I.

#       set this if your X libraries are in different locations
#       or if you need extra libraries to load with X11 applications
XLIBS=/usr/X11/lib/libXt.a /usr/X11/lib/libX11.a

#       add name of library orderer - use ":" if none
RANLIB=ranlib

#       add name of librarian
AR=ar

#       the name of the library
LIB=libXg.a

CFLAGS=$(OS) -D_LIBXG_EXTENSION $(INCS) $(XCFLAGS)
CC=gcc

OBJS=   arc.o arith.o balloc.o bitblt.o bitbltclip.o border.o bscreenrect.o\
        circle.o clipline.o clipr.o copymasked.o cursorset.o cursorswitch.o\
        disc.o ellipse.o font.o gcs.o getrect.o gwin.o latin1.o mkfont.o\
        menuhit.o point.o rdbitmap.o rdbitmapfile.o rdfontfile.o\
        rectclip.o rune.o segment.o string.o strwidth.o texture.o\
        wrbitmap.o wrbitmapfile.o xtbinit.o

all compile:    $(LIB)
test:   test.o
        $(CC) -o $@ $? $(LIB) $(XLIBS) -lm
        @echo try running test
clean:
        rm -f *.o test

nuke:   clean
        rm -f $(LIB)

$(LIB): $(OBJS)
        $(AR) rv $(LIB) $(OBJS)
        $(RANLIB) $(LIB)

$(OBJS):        libg.h libgint.h libc.h
END OF Make.osf
echo 'Make.sun' 1>&2
cat >'Make.sun' <<'END OF Make.sun'
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.
#
#       Prototype Sun Makefile for libXg
#
#       Define operating system type: -DSUNOS
#       
#       Additionally, -D_POSIX_SOURCE (or its equivalent) may be specified
#       if your compiler supports posix-compatible compilation
OS=-D_POSIX_SOURCE -DSUNOS

#       add -Iincludedir for any include directories that need to be searched
INCS=-I/usr/openwin/include -I.

#       set this if your X libraries are in different locations
#       or if you need extra libraries to load with X11 applications
XLIBS=/usr/openwin/lib/libXt.a /usr/openwin/lib/libX11.a

#       add name of library orderer - use ":" if none
RANLIB=ranlib

#       add name of librarian
AR=ar

#       the name of the library
LIB=libXg.a

CFLAGS=$(OS) -fno-builtin -D_LIBXG_EXTENSION $(INCS) $(XCFLAGS)
CC=gcc

OBJS=   arc.o arith.o balloc.o bitblt.o bitbltclip.o border.o bscreenrect.o\
        circle.o clipline.o clipr.o copymasked.o cursorset.o cursorswitch.o\
        disc.o ellipse.o font.o gcs.o getrect.o gwin.o latin1.o mkfont.o\
        menuhit.o point.o rdbitmap.o rdbitmapfile.o rdfontfile.o\
        rectclip.o rune.o segment.o string.o strwidth.o texture.o\
        wrbitmap.o wrbitmapfile.o xtbinit.o

all install:    $(LIB)
compile:        $(LIB)
test:   test.o
        $(CC) -o $@ $? $(LIB) $(XLIBS) -lm
        echo try running test
clean:
        rm -f *.o test

nuke:   clean
        rm -f $(LIB)

$(LIB): $(OBJS)
        $(AR) rv $(LIB) $(OBJS)
        $(RANLIB) $(LIB)

$(LIB)(%.o): %.o

$(OBJS):        libg.h libgint.h libc.h
END OF Make.sun
echo 'Make.v10' 1>&2
cat >'Make.v10' <<'END OF Make.v10'
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.

#
#       Prototype V10 Makefile for libXg
#
#       Define operating system type: -Dv10
#       
#       Additionally, -D_POSIX_SOURCE (or its equivalent) may be specified
#       if your compiler supports posix-compatible compilation
OS=-D_POSIX_SOURCE -Dv10

#       add -Iincludedir for any include directories that need to be searched
INCS=-I../include

#       set this if your X libraries are in different locations
#       or if you need extra libraries to load with X11 applications
XLIBS=-lXt -lX11

#       add name of library orderer - use ":" if none
RANLIB=ranlib

#       add name of librarian
AR=ar

#       the name of the library
LIB=libXg.a

CFLAGS=$(OS) -D_LIBXG_EXTENSION $(INCS) $(XCFLAGS)
CC=pcc

OBJS=   arc.o arith.o balloc.o bitblt.o bitbltclip.o border.o bscreenrect.o\
        circle.o clipline.o clipr.o copymasked.o cursorset.o cursorswitch.o\
        disc.o ellipse.o font.o gcs.o getrect.o gwin.o latin1.o mkfont.o\
        menuhit.o point.o rdbitmap.o rdbitmapfile.o rdfontfile.o\
        rectclip.o rune.o segment.o string.o strwidth.o texture.o\
        wrbitmap.o wrbitmapfile.o xtbinit.o

all install:    $(LIB)
compile:        $(LIB)
test:   test.o
        $(CC) -o $@ $? $(LIB) $(XLIBS) -lm
        echo try running test
clean:
        rm -f *.o test

nuke:   clean
        rm -f $(LIB)

$(LIB): $(OBJS)
        $(AR) rv $(LIB) $(OBJS)
        $(RANLIB) $(LIB)

$(LIB)(%.o): %.o

$(OBJS):        ../include/libg.h libgint.h ../include/libc.h
END OF Make.v10
echo 'Makefile' 1>&2
cat >'Makefile' <<'END OF Makefile'
#       Copyright (c) 1992 AT&T - All rights reserved.
#       Copyright (c) 1992 AT&T - All rights reserved.
#
#       Prototype Makefile for libXg
#
#       define operating system.  ONE of:
#               -DIRIX -DSUNOS -DUMIPS -DSYSVR3 -DAIX -DOSF1
#               -DHPUX -DAPOLLO -DCONVEX -DDYNIX
#       
#       Additionally, -D_POSIX_SOURCE (or its equivalent) may be specified
#       if your compiler supports posix-compatible compilation
OS=-DIRIX -ansiposix

#       add -Iincludedir for any include directories that need to be searched
INCS=-I.

#       set this if your X libraries are in different locations
#       or if you need extra libraries to load with X11 applications
XLIBS=-L/usr/local/X11R5/lib -lXt -lX11

#       add name of library orderer - use ":" if none
RANLIB=:

#       add name of librarian
AR=ar

#       the name of the library
LIB=libXg.a

CFLAGS=$(OS) -D_LIBXG_EXTENSION $(INCS) $(XCFLAGS)
CC=cc

OBJS=   arc.o arith.o balloc.o bitblt.o bitbltclip.o border.o bscreenrect.o\
        circle.o clipline.o clipr.o copymasked.o cursorset.o cursorswitch.o\
        disc.o ellipse.o font.o gcs.o getrect.o gwin.o latin1.o mkfont.o\
        menuhit.o point.o rdbitmap.o rdbitmapfile.o rdfontfile.o\
        rectclip.o rune.o segment.o string.o strwidth.o texture.o\
        wrbitmap.o wrbitmapfile.o xtbinit.o

all install:    $(LIB)
compile:        $(LIB)
test:   test.o
        $(CC) -o $@ $? $(LIB) $(XLIBS) -lm
        echo try running test
clean:
        rm -f *.o test

clobber nuke:   clean
        rm -f $(LIB)

$(LIB): $(OBJS)
        $(AR) rv $(LIB) $(OBJS)
        $(RANLIB) $(LIB)

$(LIB)(%.o): %.o

$(OBJS):        libg.h libgint.h libc.h

bundle:
        @bundle README Make* *.h *.c *.3

END OF Makefile
echo 'Gwin.h' 1>&2
cat >'Gwin.h' <<'END OF Gwin.h'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#ifndef GWIN_H
#define GWIN_H

/* New resource names */

#define XtNscrollForwardR "scrollForwardR"
#define XtCScrollForwardR "ScrollForwardR"
#define XtNreshaped "reshaped"
#define XtCReshaped "Reshaped"
#define XtNgotchar "gotchar"
#define XtCGotchar "Gotchar"
#define XtNgotmouse "gotmouse"
#define XtCGotmouse "Gotmouse"
#define XtNp9font   "p9font"
#define XtCP9font   "P9font"

/* External reference to the class record pointer */
extern WidgetClass gwinWidgetClass;

/* Type definition for gwin widgets */
typedef struct _GwinRec *GwinWidget;

/* Type definition for gwin resources */
typedef struct {
                int buttons;
                struct {
                        int x;
                        int y;
                } xy;
                unsigned long msec;
        } Gwinmouse;

typedef void (*Reshapefunc)(int, int, int, int);
typedef void (*Charfunc)(int);
typedef void (*Mousefunc)(Gwinmouse*);

/* Method declarations */
extern String GwinSelectionSwap(Widget, String);

#endif /* GWIN_H */
END OF Gwin.h
echo 'GwinP.h' 1>&2
cat >'GwinP.h' <<'END OF GwinP.h'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#ifndef GWINP_H
#define GWINP_H

#include "Gwin.h"

/* Gwin is derived from Core */

/* Gwin instance part */
typedef struct {
        /* New resource fields */
        Pixel           foreground;
        Font            font;
        Boolean         forwardr;       /* does right button scroll forward? */
        Reshapefunc     reshaped;       /* Notify app of reshape */
        Charfunc        gotchar;        /* Notify app of char arrival */
        Mousefunc       gotmouse;       /* Notify app of mouse change */
        String          selection;      /* Current selection */
        String          p9font;
} GwinPart;

/* Full instance record */
typedef struct _GwinRec {
        CorePart        core;
        GwinPart        gwin;
} GwinRec;

/* New type for class methods */
typedef String (*SelSwapProc)(Widget, String);

/* Class part */
typedef struct {
        SelSwapProc     select_swap;
        XtPointer       extension;
} GwinClassPart;

/* Full class record */
typedef struct _GwinClassRec {
        CoreClassPart   core_class;
        GwinClassPart   gwin_class;
} GwinClassRec, *GwinWidgetClass;

/* External definition for class record */
extern GwinClassRec gwinClassRec;

#endif /* GWINP_H */
END OF GwinP.h
echo 'libc.h' 1>&2
cat >'libc.h' <<'END OF libc.h'
/* Copyright (c) 1992 AT&T - All rights reserved. */

        /* Plan 9 C library interface */


typedef unsigned char           uchar;
typedef unsigned short          Rune;

#include <stdio.h>      /* to properly declare sprintf */
#define sprint                          sprintf

enum
{
        OREAD   =       0,              /* open for read */
        OWRITE  =       1,              /* open for write */
        ORDWR   =       2,              /* open for read/write */
        ERRLEN  =       64              /* length of error message */
};

enum
{
        UTFmax          = 3,            /* maximum bytes per rune */
        Runesync        = 0x80,         /* cannot represent part of a utf 
sequence (<) */
        Runeself        = 0x80,         /* rune and utf sequences are the same 
(<) */
        Runeerror       = 0x80          /* decoding error in utf */
};

/*
 * new rune routines
 */
extern  int     runetochar(char*, Rune*);
extern  int     chartorune(Rune*, char*);
extern  int     runelen(long);
extern  int     fullrune(char*, int);

/*
 * rune routines from converted str routines
 */
extern  long    utflen(char*);          /* was countrune */
extern  char*   utfrune(char*, long);
extern  char*   utfrrune(char*, long);
extern  char*   utfutf(char*, char*);
/*
 *      Miscellaneous functions
 */
extern  void    fprint(int, char *, ...);
extern  int     notify (void(*)(void *, char *));
extern  int     errstr(char *);
extern  char*   getuser(void);
extern  void    exits(char*);
END OF libc.h
echo 'libg.h' 1>&2
cat >'libg.h' <<'END OF libg.h'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#ifndef _LIBG_H
#define _LIBG_H

#ifndef _LIBXG_EXTENSION
    This header file is not defined in pure ANSI/POSIX
#endif
/*
 *  Like Plan9's libg.h, but suitable for inclusion on non-Plan9 machines
 */

enum{ EMAXMSG = 128+8192 };     /* max event size */

/*
 * Types
 */

typedef struct  Bitmap          Bitmap;
typedef struct  Point           Point;
typedef struct  Rectangle       Rectangle;
typedef struct  Cursor          Cursor;
typedef struct  Mouse           Mouse;
typedef struct  Menu            Menu;
typedef struct  Font            Font;
typedef struct  Fontchar        Fontchar;
typedef struct  Subfont         Subfont;
typedef struct  Cachesubf       Cachesubf;
typedef struct  Event           Event;
typedef struct  RGB             RGB;

struct  Point
{
        int     x;
        int     y;
};

struct Rectangle
{
        Point min;
        Point max;
};

struct  Bitmap
{
        Rectangle r;            /* rectangle in data area, local coords */
        Rectangle clipr;        /* clipping region */
        int     ldepth;
        int     id;
        Bitmap  *cache;         /* zero; distinguishes bitmap from layer */
        int     flag;           /* flag used by X implementation of libg */
};

struct  Mouse
{
        int             buttons; /* bit array: LMR=124 */
        Point           xy;
        unsigned long   msec;
};

struct  Cursor
{
        Point           offset;
        unsigned char   clr[2*16];
        unsigned char   set[2*16];
        int             id;     /* init to zero; used by library */
};

struct Menu
{
        char    **item;
        char    *(*gen)(int);
        int     lasthit;
};

/*
 * Subfonts
 *
 * given char c, Subfont *f, Fontchar *i, and Point p, one says
 *      i = f->info+c;
 *      bitblt(b, Pt(p.x+i->left,p.y),
 *              bitmap, Rect(i->x,i->top,(i+1)->x,i->bottom),
 *              fc);
 *      p.x += i->width;
 * where bitmap is the repository of the glyphs.
 *
 */

struct  Fontchar
{
        short           x;              /* left edge of bits */
        unsigned char   top;            /* first non-zero scan-line */
        unsigned char   bottom;         /* last non-zero scan-line */
        char            left;           /* offset of baseline */
        unsigned char   width;          /* width of baseline */
};

struct  Subfont
{
        short           minrow; /* first character row in font (for X subfonts) 
*/
        short           mincol; /* first character col in font (for X subfonts) 
*/
        short           minchar; /* first char code in subfont */
        short           maxchar; /* last char code in subfont */
        short           width;  /* number of chars in row */
        short           n;      /* number of chars in font */
        unsigned char   height; /* height of bitmap */
        char            ascent; /* top of bitmap to baseline */
        Fontchar        *info;  /* n+1 character descriptors */
        int             id;     /* of font */
};

struct  Cachesubf
{
        Rune            min;    /* rune value of 0th char in subfont */
        Rune            max;    /* rune value+1 of last char in subfont */
        char            *name;
        Subfont         *f;     /* attached subfont */
};

struct Font
{
        char            *name;
        unsigned char   height; /* max height of bitmap, interline spacing */
        char            ascent; /* top of bitmap to baseline */
        char            width;  /* widest so far; used in caching only */
        char            ldepth; /* of images */
        short           id;     /* of font */
        short           nsubf;  /* number of subfonts */
        Cachesubf       *subf;  /* as read from file */
};

struct  Event
{
        int             kbdc;
        Mouse           mouse;
        int             n;              /* number of characters in mesage */
        unsigned char   data[EMAXMSG];  /* message from an arbitrary file 
descriptor */
};

struct RGB
{
        unsigned long   red;
        unsigned long   green;
        unsigned long   blue;
};

/*
 * Codes for bitblt etc.
 *
 *             D
 *           0   1
 *         ---------
 *       0 | 1 | 2 |
 *     S   |---|---|
 *       1 | 4 | 8 |
 *         ---------
 *
 *      Usually used as D|S; DorS is so tracebacks are readable.
 */
typedef
enum    Fcode
{
        Zero            = 0x0,
        DnorS           = 0x1,
        DandnotS        = 0x2,
        notS            = 0x3,
        notDandS        = 0x4,
        notD            = 0x5,
        DxorS           = 0x6,
        DnandS          = 0x7,
        DandS           = 0x8,
        DxnorS          = 0x9,
        D               = 0xA,
        DornotS         = 0xB,
        S               = 0xC,
        notDorS         = 0xD,
        DorS            = 0xE,
        F               = 0xF
} Fcode;

/*
 * Miscellany
 */

typedef void     (*Errfunc)(char *);

extern Point     add(Point, Point);
extern Point     sub(Point, Point);
extern Point     mul(Point, int);
extern Point     divpt(Point, int);
extern Rectangle rsubp(Rectangle, Point);
extern Rectangle raddp(Rectangle, Point);
extern Rectangle inset(Rectangle, int);
extern Rectangle rmul(Rectangle, int);
extern Rectangle rdiv(Rectangle, int);
extern Rectangle rshift(Rectangle, int);
extern Rectangle rcanon(Rectangle);
extern Bitmap*   balloc(Rectangle, int);
extern void      bfree(Bitmap*);
extern int       rectclip(Rectangle*, Rectangle);
extern void      xtbinit(Errfunc, char*, int*, char**);
extern void      bclose(void);
extern void      berror(char*);
extern void      bitblt(Bitmap*, Point, Bitmap*, Rectangle, Fcode);
extern void      copymasked(Bitmap*, Point, Bitmap*, Bitmap*, Rectangle);
extern int       bitbltclip(void*);
extern Subfont*  getfont(char*);
extern Font     *rdfontfile(char*, int);
extern void      ffree(Font*);
extern Font     *mkfont(Subfont*);
extern void      subffree(Subfont*);
extern int       cachechars(Font*, char**, void*, int, int*, unsigned short*);
extern Point     string(Bitmap*, Point, Font*, char*, Fcode);
extern void      segment(Bitmap*, Point, Point, int, Fcode);
extern void      point(Bitmap*, Point, int, Fcode);
extern void      arc(Bitmap*, Point, Point, Point, int, Fcode);
extern void      circle(Bitmap*, Point, int, int, Fcode);
extern void      disc(Bitmap*, Point, int, int, Fcode);
extern void      ellipse(Bitmap*, Point, int, int, int, Fcode);
extern long      strwidth(Font*, char*);
extern Point     strsize(Font*, char*);
extern long      charwidth(Font*, Rune);
extern void      texture(Bitmap*, Rectangle, Bitmap*, Fcode);
extern void      wrbitmap(Bitmap*, int, int, unsigned char*);
extern void      rdbitmap(Bitmap*, int, int, unsigned char*);
extern void      wrbitmapfile(int, Bitmap*);
extern Bitmap*   rdbitmapfile(int);
extern int       ptinrect(Point, Rectangle);
extern int       rectXrect(Rectangle, Rectangle);
extern int       eqpt(Point, Point);
extern int       eqrect(Rectangle, Rectangle);
extern void      border(Bitmap*, Rectangle, int, Fcode);
extern void      cursorswitch(Cursor*);
extern void      cursorset(Point);
extern Rectangle bscreenrect(Rectangle*);
extern void      bflush(void);
extern int       clipline(Rectangle, Point*, Point*);
extern int       clipr(Bitmap*, Rectangle);

extern void      einit(unsigned long);
extern unsigned long estart(unsigned long, int, int);
extern unsigned long etimer(unsigned long, int);
extern unsigned long event(Event*);
extern unsigned long eread(unsigned long, Event*);
extern Mouse     emouse(void);
extern int       ekbd(void);
extern int       ecanread(unsigned long);
extern int       ecanmouse(void);
extern int       ecankbd(void);
extern void      ereshaped(Rectangle);  /* supplied by user */
extern int       menuhit(int, Mouse*, Menu*);
extern Rectangle getrect(int, Mouse*);
extern unsigned long rgbpix(Bitmap*, RGB);
extern void      rdcolmap(Bitmap*, RGB*);
extern void      wrcolmap(Bitmap*, RGB*);

/* Extra functions supplied by libXg */
extern int      snarfswap(char*, int, char**);
extern int      scrollfwdbut(void);

enum{
        Emouse          = 1,
        Ekeyboard       = 2
};

extern Point     Pt(int, int);
extern Rectangle Rect(int, int, int, int);
extern Rectangle Rpt(Point, Point);


#define Dx(r)   ((r).max.x-(r).min.x)
#define Dy(r)   ((r).max.y-(r).min.y)

extern  Bitmap  screen;
extern  Font    *font;

#define BGSHORT(p)              (((p)[0]<<0) | ((p)[1]<<8))
#define BGLONG(p)               ((BGSHORT(p)<<0) | (BGSHORT(p+2)<<16))
#define BPSHORT(p, v)           ((p)[0]=(v), (p)[1]=((v)>>8))
#define BPLONG(p, v)            (BPSHORT(p, (v)), BPSHORT(p+2, (v)>>16))

#endif
END OF libg.h
echo 'libgint.h' 1>&2
cat >'libgint.h' <<'END OF libgint.h'
/* Copyright (c) 1992 AT&T - All rights reserved. */
/* internal libg implementation file - include after libg */

/*
 * include defs of standard library routines, if possible,
 * and string routines
 */
#ifdef _POSIX_SOURCE
#include <stdlib.h>
#include <string.h>
#endif /* _POSIX_SOURCE */

/*
 * use defines to rename X11 types Cursor, Font, Event
 */

#define Cursor xCursor
#define Font xFont
#define Event xEvent

#if     defined(v10) || defined(HPUX)
typedef char*   caddr_t;
#endif

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>

#undef Cursor
#undef Font
#undef Event

/* Return a GCs for solid filling/strings/etc., segments/points, and tiling */
extern GC       _getfillgc(Fcode, Bitmap*, unsigned long);
extern GC       _getcopygc(Fcode, Bitmap*, Bitmap*, int*);
extern GC       _getgc(Bitmap*, unsigned long, XGCValues *);

/* balloc without zero init (which uses a gc!) */
extern Bitmap   *_balloc(Rectangle, int);

/* X Display for this application's connection */
extern Display  *_dpy;

/* screen depth foreground and background for this application */
extern unsigned long    _fgpixel, _bgpixel;
extern XColor           _fgcolor, _bgcolor;

/* indexed by log depth (0 <= ld <= 5), to give depth and planemask */
extern int              _ld2d[];
extern unsigned long    _ld2dmask[];

/* libg.h defines:
 *   extern Bitmap screen;   -- Bitmap for application Window after xbinit()
 *   extern Font *font;      -- Font for application default font after xbinit()
 */

/*
 * Conventions:
 *   The .id field of a Bitmap is an X Pixmap unless the Bitmap is screen,
 *   in which case it is a Window.
 *   The .id field of a Cursor is set to the X xCursor the first time the
 *   cursor is used.
 *   The .id field of a Font is set to the X xFont.
 *
 *   Coordinate conventions: libg bitmaps can have non (0,0) origins,
 *   but not X Pixmaps, so we have to subtract the min point of a Bitmap
 *   from coords in the Bitmap before using the point in the corresponding 
Pixmap.
 *   The screen Bitmap, however, contains the rectangle in X coords of the
 *   widget in which the application is started, relative to the window.
 *   The origin may or may not be (0,0), but in any case, coordinates should
 *   NOT be translated before using in X calls on the Window.
 */

/* values for bitmap flag field (see _getcopygc if change first two vals) */
enum {
        DP1=    0x1,    /* depth == 1 (ldepth == 0) */
        BL1=    0x2,    /* black == 1 model */
        SCR=    0x4,    /* on screen */
        ZORG=   0x8,    /* r.min == Pt(0,0) */
        SHIFT= 0x20,    /* !SCR & !ZORG */
        CLIP=  0x40     /* r != clipr */
};

/* values for return bltfunc arg of _getcopygc */
enum {
        UseCopyArea,
        UseCopyPlane,
        UseFillRectangle
};
END OF libgint.h
echo 'u.h' 1>&2
cat >'u.h' <<'END OF u.h'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <setjmp.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

        /* System configuration parameters */

#ifdef  SYSVR3
#include        <malloc.h>
typedef unsigned short  ushort;
typedef unsigned long   ulong;
#define remove(v)                       unlink(v)
#define WEXITSTATUS(s)                  (((s)>>8)&0xFF)
extern  char *getenv(char*);
extern  char *getlogin(void);
extern  char *strerror(int);
extern  void *memmove(void*, const void*, size_t);
#define NEEDMEMMOVE
#define NEEDSTRERROR
#define NEEDVARARG
#endif  /* SYSVR3 */

#ifdef  IRIX
extern  void *memmove(void*, const void*, size_t);
#define NEEDMEMMOVE
#endif  /* IRIX */

#ifdef  UMIPS
typedef unsigned long   ulong;
typedef unsigned short  ushort;
#define const                   /* mips compiler doesn't support const */
extern  char *strerror(int);
extern  void *memmove(void*, const void*, size_t);
#define NEEDMEMMOVE
#define NEEDSTRERROR
#define NEEDVARARG
#endif  /* UMIPS */

#ifdef  SUNOS
typedef unsigned short  ushort;
typedef unsigned long   ulong;
extern  char *strerror(int);
extern  void *memmove(void*, const void*, size_t);
extern  void *memcpy(void*, const void*, size_t);
#define NEEDMEMMOVE
#define NEEDSTRERROR
#endif  /* SUNOS */

#ifdef  AIX
typedef unsigned short  ushort;
typedef unsigned long   ulong;
#endif  /* AIX */

#ifdef  OSF1
typedef unsigned short  ushort;
typedef unsigned long   ulong;
extern  void *memmove(void*, const void*, size_t);
#endif  /* OSF1 */

#ifdef  HPUX
typedef unsigned short  ushort;
typedef unsigned long   ulong;
#define NEEDSTRERROR
#endif  /* HPUX */

#ifdef  APOLLO
typedef unsigned short  ushort;
typedef unsigned long   ulong;
#endif  /* APOLLO */

#ifdef  CONVEX
typedef unsigned long   ulong;
#endif  /* CONVEX */

#ifdef  DYNIX
#define SIG_ERR         BADSIG
#define NEEDMEMMOVE
#define remove(v)                       unlink(v)
#define WEXITSTATUS(s)                  (((s)>>8)&0xFF)
#define NEEDMEMMOVE
#endif  /* DYNIX */

#ifdef  PTX
typedef unsigned short  ushort;
typedef unsigned long   ulong;
#endif  /* PTX */

#ifdef  v10
typedef unsigned short  ushort;
typedef unsigned long   ulong;
#endif
END OF u.h
echo 'arc.c' 1>&2
cat >'arc.c' <<'END OF arc.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"
#include <math.h>

#define rad2deg(x) 180*((x)/3.1415926535897932384626433832795028841971693993751)

void
arc(Bitmap *b, Point p0, Point p1, Point p2, int v, Fcode f)
{
        unsigned int d;
        int x, y, r, start, end, delta;
        GC g;

        p1.x -= p0.x;
        p1.y -= p0.y;
        p2.x -= p0.x;
        p2.y -= p0.y;
        r = (int)sqrt((double)(p1.x*p1.x + p1.y*p1.y));
        start = (int)(64*rad2deg(atan2(-p2.y, p2.x)));
        end = (int)(64*rad2deg(atan2(-p1.y, p1.x)));
        if(start < 0)
                start += 64*360;
        if(end < 0)
                end += 64*360;
        delta = end - start;
        if(delta < 0)
                delta += 64*360;
        x = p0.x - r;
        y = p0.y - r;
        if(b->flag&SHIFT){
                x -= b->r.min.x;
                y -= b->r.min.y;
        }
        d = 2*r;
        g = _getfillgc(f, b, v);
        /*
         * delta is positive, so this draws counterclockwise arc
         * from start to start+delta
         */
        XDrawArc(_dpy, (Drawable)b->id, g, x, y, d, d, start, delta);
}

END OF arc.c
echo 'arith.c' 1>&2
cat >'arith.c' <<'END OF arith.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>

Point
add(Point a, Point b)
{
        a.x += b.x;
        a.y += b.y;
        return a;
}

Point
sub(Point a, Point b)
{
        a.x -= b.x;
        a.y -= b.y;
        return a;
}

Rectangle
inset(Rectangle r, int n)
{
        r.min.x += n;
        r.min.y += n;
        r.max.x -= n;
        r.max.y -= n;
        return r;
}

Point
divpt(Point a, int b)
{
        a.x /= b;
        a.y /= b;
        return a;
}

Point
mul(Point a, int b)
{
        a.x *= b;
        a.y *= b;
        return a;
}

Rectangle
rsubp(Rectangle r, Point p)
{
        r.min.x -= p.x;
        r.min.y -= p.y;
        r.max.x -= p.x;
        r.max.y -= p.y;
        return r;
}

Rectangle
raddp(Rectangle r, Point p)
{
        r.min.x += p.x;
        r.min.y += p.y;
        r.max.x += p.x;
        r.max.y += p.y;
        return r;
}

Rectangle
rmul(Rectangle r, int a)
{
        if (a != 1) {
                r.min.x *= a;
                r.min.y *= a;
                r.max.x *= a;
                r.max.y *= a;
        }
        return r;
}

Rectangle
rdiv(Rectangle r, int a)
{
        if (a != 1) {
                r.min.x /= a;
                r.min.y /= a;
                r.max.x /= a;
                r.max.y /= a;
        }
        return r;
}

Rectangle
rshift(Rectangle r, int a)
{
        if (a > 0) {
                r.min.x <<= a;
                r.min.y <<= a;
                r.max.x <<= a;
                r.max.y <<= a;
        }
        else if (a < 0) {
                a = -a;
                r.min.x >>= a;
                r.min.y >>= a;
                r.max.x >>= a;
                r.max.y >>= a;
        }
        return r;
}

eqpt(Point p, Point q)
{
        return p.x==q.x && p.y==q.y;
}

eqrect(Rectangle r, Rectangle s)
{
        return r.min.x==s.min.x && r.max.x==s.max.x &&
               r.min.y==s.min.y && r.max.y==s.max.y;
}

rectXrect(Rectangle r, Rectangle s)
{
        return r.min.x<s.max.x && s.min.x<r.max.x &&
               r.min.y<s.max.y && s.min.y<r.max.y;
}

ptinrect(Point p, Rectangle r)
{
        return p.x>=r.min.x && p.x<r.max.x &&
               p.y>=r.min.y && p.y<r.max.y;
}

Rectangle
rcanon(Rectangle r)
{
        int t;
        if (r.max.x < r.min.x) {
                t = r.min.x;
                r.min.x = r.max.x;
                r.max.x = t;
        }
        if (r.max.y < r.min.y) {
                t = r.min.y;
                r.min.y = r.max.y;
                r.max.y = t;
        }
        return r;
}

Rectangle
Rect(int x1, int y1, int x2, int y2)
{
        Rectangle r;

        r.min.x = x1;
        r.min.y = y1;
        r.max.x = x2;
        r.max.y = y2;
        return r;
}

Rectangle
Rpt(Point p1, Point p2)
{
        Rectangle r;

        r.min = p1;
        r.max = p2;
        return r;
}

Point
Pt(int x, int y)
{
        Point p;

        p.x = x;
        p.y = y;
        return p;
}
END OF arith.c
echo 'balloc.c' 1>&2
cat >'balloc.c' <<'END OF balloc.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

Bitmap*
balloc(Rectangle r, int ldepth)
{
        Bitmap *b;

        b = _balloc(r, ldepth);
        bitblt(b, r.min, b, r, Zero);
        return b;
}

Bitmap*
_balloc(Rectangle r, int ldepth)
{
        int id;
        Bitmap *b;
        int ld;
        Rectangle rx;

        b = (Bitmap *)malloc(sizeof(Bitmap));
        if(b == 0)
                berror("balloc malloc");
        if (ldepth == 0)
                ld = 0;
        else
                ld = screen.ldepth;
        rx = r;
        if (Dx(rx) == 0)
                rx.max.x++;
        if (Dy(rx) == 0)
                rx.max.y++;
        id = (int) XCreatePixmap(_dpy, (Drawable)screen.id,
                        Dx(rx), Dy(rx), _ld2d[ld]);
        b->ldepth = ldepth;
        b->r = r;
        b->clipr = r;
        b->id = id;
        b->cache = 0;
        if(ldepth == 0)
                b->flag = DP1|BL1;
        else
                b->flag = screen.flag&BL1;
        if(r.min.x==0 && r.min.y ==0)
                b->flag |= ZORG;
        else
                b->flag |= SHIFT;
        return b;
}

void
bfree(Bitmap *b)
{
        XFreePixmap(_dpy, (Pixmap)b->id);
        free(b);
}
END OF balloc.c
echo 'bitblt.c' 1>&2
cat >'bitblt.c' <<'END OF bitblt.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

void
bitblt(Bitmap *d, Point p, Bitmap *s, Rectangle r, Fcode f)
{
        int sx, sy, dx, dy, bfunc;
        GC g;
        unsigned long plane;
        Bitmap *btmp;

        if(Dx(r)<=0 || Dy(r)<=0)
                return;
        sx = r.min.x;
        sy = r.min.y;
        if(s->flag&SHIFT){
                sx -= s->r.min.x;
                sy -= s->r.min.y;
        }
        dx = p.x;
        dy = p.y;
        if(d->flag&SHIFT){
                dx -= d->r.min.x;
                dy -= d->r.min.y;
        }
        g = _getcopygc(f, d, s, &bfunc);
        if(bfunc == UseCopyArea)
                XCopyArea(_dpy, (Drawable)s->id, (Drawable)d->id, g,
                        sx, sy, Dx(r), Dy(r), dx, dy);
        else if(bfunc == UseFillRectangle){
                XFillRectangle(_dpy, (Drawable)s->id, g,
                        dx, dy, Dx(r), Dy(r));
        }else{
                /* bfunc == UseCopyPlane */
                plane = _ld2dmask[s->ldepth];
                plane &= ~(plane>>1);
                if(0/*f == S*/)
                        XCopyPlane(_dpy, (Drawable)s->id, (Drawable)d->id, g,
                                sx, sy, Dx(r), Dy(r), dx, dy, plane);
                else {
                        /*
                         * CopyPlane can only do func code S,
                         * so copy src rect into a bitmap with the same depth
                         * as the dest, then do the bitblt from the tmp.
                         * This won't recurse again because we only get
                         * UseCopyPlane with differing bitmap depths
                         */
                        btmp = _balloc(Rect(0,0,Dx(r),Dy(r)), d->ldepth);
                        XCopyPlane(_dpy, (Drawable)s->id, (Drawable)btmp->id, g,
                                sx, sy, Dx(r), Dy(r), 0, 0, plane);
                        bitblt(d, p, btmp, btmp->r, f);
                        bfree(btmp);
                }
        }

}
END OF bitblt.c
echo 'bitbltclip.c' 1>&2
cat >'bitbltclip.c' <<'END OF bitbltclip.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

int
bitbltclip(void *vp)
{
        int dx, dy;
        int i;
        struct bbcarg{
                Bitmap *dm;
                Point p;
                Bitmap *sm;
                Rectangle r;
                Fcode f;
        }*bp;

        bp = (struct bbcarg *)vp;
        dx = Dx(bp->r);
        dy = Dy(bp->r);
        if(bp->p.x < bp->dm->clipr.min.x){
                i = bp->dm->clipr.min.x-bp->p.x;
                bp->r.min.x += i;
                bp->p.x += i;
                dx -= i;
        }
        if(bp->p.y < bp->dm->clipr.min.y){
                i = bp->dm->clipr.min.y-bp->p.y;
                bp->r.min.y += i;
                bp->p.y += i;
                dy -= i;
        }
        if(bp->p.x+dx > bp->dm->clipr.max.x){
                i = bp->p.x+dx-bp->dm->clipr.max.x;
                bp->r.max.x -= i;
                dx -= i;
        }
        if(bp->p.y+dy > bp->dm->clipr.max.y){
                i = bp->p.y+dy-bp->dm->clipr.max.y;
                bp->r.max.y -= i;
                dy -= i;
        }
        if(bp->r.min.x < bp->sm->clipr.min.x){
                i = bp->sm->clipr.min.x-bp->r.min.x;
                bp->p.x += i;
                bp->r.min.x += i;
                dx -= i;
        }
        if(bp->r.min.y < bp->sm->clipr.min.y){
                i = bp->sm->clipr.min.y-bp->r.min.y;
                bp->p.y += i;
                bp->r.min.y += i;
                dy -= i;
        }
        if(bp->r.max.x > bp->sm->clipr.max.x){
                i = bp->r.max.x-bp->sm->clipr.max.x;
                bp->r.max.x -= i;
                dx -= i;
        }
        if(bp->r.max.y > bp->sm->clipr.max.y){
                i = bp->r.max.y-bp->sm->clipr.max.y;
                bp->r.max.y -= i;
                dy -= i;
        }
        return dx>0 && dy>0;
}
END OF bitbltclip.c
echo 'border.c' 1>&2
cat >'border.c' <<'END OF border.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>

void
border(Bitmap *l, Rectangle r, int i, Fcode c)
{
        if(i > 0){
                bitblt(l, r.min,
                        l, Rect(r.min.x, r.min.y, r.max.x, r.min.y+i), c);
                bitblt(l, Pt(r.min.x, r.max.y-i),
                        l, Rect(r.min.x, r.max.y-i, r.max.x, r.max.y), c);
                bitblt(l, Pt(r.min.x, r.min.y+i),
                        l, Rect(r.min.x, r.min.y+i, r.min.x+i, r.max.y-i), c);
                bitblt(l, Pt(r.max.x-i, r.min.y+i),
                        l, Rect(r.max.x-i, r.min.y+i, r.max.x, r.max.y-i), c);
        }else if(i < 0){
                bitblt(l, Pt(r.min.x, r.min.y+i),
                        l, Rect(r.min.x, r.min.y+i, r.max.x, r.min.y), c);
                bitblt(l, Pt(r.min.x, r.max.y),
                        l, Rect(r.min.x, r.max.y, r.max.x, r.max.y-i), c);
                bitblt(l, Pt(r.min.x+i, r.min.y+i),
                        l, Rect(r.min.x+i, r.min.y+i, r.min.x, r.max.y-i), c);
                bitblt(l, Pt(r.max.x, r.min.y+i),
                        l, Rect(r.max.x, r.min.y+i, r.max.x-i, r.max.y-i), c);
        }
}
END OF border.c
echo 'bscreenrect.c' 1>&2
cat >'bscreenrect.c' <<'END OF bscreenrect.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

/*
 * The screen data structure should always be up to date
 * (Not true in the Plan 9 library, which is why this
 * function exists).
 */
Rectangle
bscreenrect(Rectangle *clipr)
{
        if(clipr)
                *clipr = screen.clipr;
        return screen.r;
}
END OF bscreenrect.c
echo 'circle.c' 1>&2
cat >'circle.c' <<'END OF circle.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

void
circle(Bitmap *b, Point p, int r, int v, Fcode f)
{
        unsigned int d;
        int x, y;
        GC g;

        x = p.x - r;
        y = p.y - r;
        if (b->flag&SHIFT){
                x -= b->r.min.x;
                y -= b->r.min.y;
        }
        d = 2*r;
        g = _getfillgc(f, b, v);
        XDrawArc(_dpy, (Drawable)b->id, g, x, y, d, d, 0, 23040/* 360 deg */);
}
END OF circle.c
echo 'clipline.c' 1>&2
cat >'clipline.c' <<'END OF clipline.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

typedef struct Linedesc
{
        int     x0;
        int     y0;
        char    xmajor;
        char    slopeneg;
        long    dminor;
        long    dmajor;
} Linedesc;

int      _clipline(Rectangle, Point*, Point*, Linedesc*);

#define XYswap(p)       t=(p)->x, (p)->x=(p)->y, (p)->y=t
#define Swap(x, y)      t=x, x=y, y=t

static long
lfloor(long x, long y)  /* first integer <= x/y */
{
        if(y <= 0){
                if(y == 0)
                        return x;
                y = -y;
                x = -x;
        }
        if(x < 0){      /* be careful; C div. is undefined */
                x = -x;
                x += y-1;
                return -(x/y);
        }
        return x/y;
}

static long
lceil(long x, long y)   /* first integer >= x/y */
{
        if(y <= 0){
                if(y == 0)
                        return x;
                y = -y;
                x = -x;
        }
        if(x < 0){
                x = -x;
                return -(x/y);
        }
        x += y-1;
        return x/y;
}

int
_gminor(long x, Linedesc *l)
{
        long y;

        y = 2*(x-l->x0)*l->dminor + l->dmajor;
        y = lfloor(y, 2*l->dmajor) + l->y0;
        return l->slopeneg? -y : y;
}

int
_gmajor(long y, Linedesc *l)
{
        long x;

        x = 2*((l->slopeneg? -y : y)-l->y0)*l->dmajor - l->dminor;
        x = lceil(x, 2*l->dminor) + l->x0;
        if(l->dminor)
                while(_gminor(x-1, l) == y)
                        x--;
        return x;
}

void
gsetline(Point *pp0, Point *pp1, Linedesc *l)
{
        long dx, dy, t;
        Point endpt;
        int swapped;
        Point p0, p1;

        swapped = 0;
        p0 = *pp0;
        p1 = *pp1;
        l->xmajor = 1;
        l->slopeneg = 0;
        dx = p1.x - p0.x;
        dy = p1.y - p0.y;
        if(abs(dy) > abs(dx)){  /* Steep */
                l->xmajor = 0;
                XYswap(&p0);
                XYswap(&p1);
                Swap(dx, dy);
        }
        if(dx < 0){
                swapped++;
                Swap(p0.x, p1.x);
                Swap(p0.y, p1.y);
                dx = -dx;
                dy = -dy;
        }
        if(dy < 0){
                l->slopeneg = 1;
                dy = -dy;
                p0.y = -p0.y;
        }
        l->dminor = dy;
        l->dmajor = dx;
        l->x0 = p0.x;
        l->y0 = p0.y;
        p1.x = swapped? p0.x+1 : p1.x-1;
        p1.y = _gminor(p1.x, l);
        if(l->xmajor == 0){
                XYswap(&p0);
                XYswap(&p1);
        }
        if(pp0->x > pp1->x){
                *pp1 = *pp0;
                *pp0 = p1;
        }else
                *pp1 = p1;
}
/*
 * Modified clip-to-rectangle algorithm
 *      works in bitmaps
 *      Everything in SCREEN coordinates.
 *
 *      Newman & Sproull 124 (1st edition)
 */

static int
code(Point *p, Rectangle *r)
{
        return( (p->x<r->min.x? 1 : p->x>=r->max.x? 2 : 0) |
                (p->y<r->min.y? 4 : p->y>=r->max.y? 8 : 0));
}

int
clipline(Rectangle r, Point *p0, Point *p1)
{
        Linedesc l;

        return _clipline(r, p0, p1, &l);
}

int
_clipline(Rectangle r, Point *p0, Point *p1, Linedesc *l)
{
        int c0, c1, n;
        long t, ret;
        Point temp;
        int swapped;

        if(p0->x==p1->x && p0->y==p1->y)
                return 0;
        gsetline(p0, p1, l);
        /* line is now closed */
        if(l->xmajor == 0){
                XYswap(p0);
                XYswap(p1);
                XYswap(&r.min);
                XYswap(&r.max);
        }
        c0 = code(p0, &r);
        c1 = code(p1, &r);
        ret = 1;
        swapped = 0;
        n = 0;
        while(c0 | c1){
                if(c0 & c1){    /* no point of line in r */
                        ret = 0;
                        goto Return;
                }
                if(++n > 10){   /* horrible points; overflow etc. etc. */
                        ret = 0;
                        goto Return;
                }
                if(c0 == 0){    /* swap points */
                        temp = *p0;
                        *p0 = *p1;
                        *p1 = temp;
                        Swap(c0, c1);
                        swapped ^= 1;
                }
                if(c0 == 0)
                        break;
                if(c0 & 1){             /* push towards left edge */
                        p0->x = r.min.x;
                        p0->y = _gminor(p0->x, l);
                }else if(c0 & 2){       /* push towards right edge */
                        p0->x = r.max.x-1;
                        p0->y = _gminor(p0->x, l);
                }else if(c0 & 4){       /* push towards top edge */
                        p0->y = r.min.y;
                        if(l->slopeneg)
                                p0->x = _gmajor(p0->y-1, l)-1;
                        else
                                p0->x = _gmajor(p0->y, l);
                }else if(c0 & 8){       /* push towards bottom edge */
                        p0->y = r.max.y-1;
                        if(l->slopeneg)
                                p0->x = _gmajor(p0->y, l);
                        else
                                p0->x = _gmajor(p0->y+1, l)-1;
                }
                c0 = code(p0, &r);
        }

    Return:
        if(l->xmajor == 0){
                XYswap(p0);
                XYswap(p1);
        }
        if(swapped){
                temp = *p0;
                *p0 = *p1;
                *p1 = temp;
        }
        return ret;
}
END OF clipline.c
echo 'clipr.c' 1>&2
cat >'clipr.c' <<'END OF clipr.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

int
clipr(Bitmap *d, Rectangle r)
{
        if(rectclip(&r, d->r) == 0)
                return 0;
        d->clipr = r;
        if(r.min.x != d->r.min.x ||
           r.min.y != d->r.min.y ||
           r.max.x != d->r.max.x ||
           r.max.y != d->r.max.y)
                d->flag |= CLIP;
        else
                d->flag &= ~CLIP;
        return 1;
}
END OF clipr.c
echo 'copymasked.c' 1>&2
cat >'copymasked.c' <<'END OF copymasked.c'
#include <libc.h>
#include <libg.h>
#include "libgint.h"

/*
 * m should be a 1-bit-deep bitmap with origin (0,0) and the
 * same extents as r.  s should have the same depth as d.
 * Rectangle r of s is copied to d wherever corresponding
 * bits of m are 1
 */
void
copymasked(Bitmap *d, Point p, Bitmap *s, Bitmap *m, Rectangle r)
{
        int sx, sy, dx, dy;
        XGCValues gcv;
        GC g;

        if(Dx(r)<=0 || Dy(r)<=0)
                return;
        sx = r.min.x;
        sy = r.min.y;
        if(s->flag&SHIFT){
                sx -= s->r.min.x;
                sy -= s->r.min.y;
        }
        dx = p.x;
        dy = p.y;
        if(d->flag&SHIFT){
                dx -= d->r.min.x;
                dy -= d->r.min.y;
        }
        gcv.fill_style = FillStippled;
        gcv.stipple = (Pixmap)m->id;
        gcv.function = GXclear;
        gcv.ts_x_origin = dx;
        gcv.ts_y_origin = dy;
        gcv.fill_style = FillStippled;
        g = _getgc(d, GCFunction|GCStipple|GCTileStipXOrigin
                |GCTileStipYOrigin|GCFillStyle, &gcv);
        XFillRectangle(_dpy, (Drawable)d->id, g,
                        dx, dy, Dx(r), Dy(r));
        gcv.function = GXor;
        gcv.fill_style = FillSolid;
        g = _getgc(d, GCFunction|GCFillStyle, &gcv);
        XCopyArea(_dpy, (Drawable)s->id, (Drawable)d->id, g,
                        sx, sy, Dx(r), Dy(r), dx, dy);
}
END OF copymasked.c
echo 'cursorset.c' 1>&2
cat >'cursorset.c' <<'END OF cursorset.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

/*
 * Only allow cursor to move within screen Bitmap
 */
void
cursorset(Point p)
{
        /* motion will be relative to window origin */
        p = sub(p, screen.r.min);
        XWarpPointer(_dpy, None, (Window)screen.id, 0, 0, 0, 0, p.x, p.y);
}
END OF cursorset.c
echo 'cursorswitch.c' 1>&2
cat >'cursorswitch.c' <<'END OF cursorswitch.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

/*
 * Use the id field in Cursor to hold the X id corresponding
 * to the cursor, so that it doesn't have to be recreated on
 * each cursorswitch.  This doesn't quite match the semantics
 * of Plan9 libg, since the user could create a cursor (say
 * with malloc) with garbage in the id field; or the user
 * could change the contents of the other fields and we
 * wouldn't know about it.  Neither of these happen in
 * existing uses of libg.
 */
static Cursor arrow =
{
        {-1, -1},
        {0xFF, 0xE0, 0xFF, 0xE0, 0xFF, 0xC0, 0xFF, 0x00,
         0xFF, 0x00, 0xFF, 0x80, 0xFF, 0xC0, 0xFF, 0xE0,
         0xE7, 0xF0, 0xE3, 0xF8, 0xC1, 0xFC, 0x00, 0xFE,
         0x00, 0x7F, 0x00, 0x3E, 0x00, 0x1C, 0x00, 0x08,
        },
        {0x00, 0x00, 0x7F, 0xC0, 0x7F, 0x00, 0x7C, 0x00,
         0x7E, 0x00, 0x7F, 0x00, 0x6F, 0x80, 0x67, 0xC0,
         0x43, 0xE0, 0x41, 0xF0, 0x00, 0xF8, 0x00, 0x7C,
         0x00, 0x3E, 0x00, 0x1C, 0x00, 0x08, 0x00, 0x00,
        }
};

static Bitmap *bsrc, *bmask;
static Rectangle crect = { 0, 0, 16, 16 };

void
cursorswitch(Cursor *c)
{
        if(c == 0)
                c = &arrow;
        if(c->id == 0){
                if(bsrc == 0){
                        bsrc = balloc(crect, 0);
                        bmask = balloc(crect, 0);
                }
                /*
                 * Cursor should have fg where "set" is 1,
                 * and bg where "clr" is 1 and "set" is 0,
                 * and should leave places alone where "set" and "clr" are both 0
                 */
                wrbitmap(bsrc, 0, 16, c->set);
#ifdef CURSORBUG
                /*
                 * Some X servers (e.g., Sun X-on-news for some color
                 * monitors) don't do XCreatePixmapCursor properly:
                 * only the mask gets displayed, all black
                 */
                wrbitmap(bmask, 0, 16, c->set);
#else
                wrbitmap(bmask, 0, 16, c->clr);
                bitblt(bmask, Pt(0,0), bsrc, crect, S|D);
#endif
                c->id = (int) XCreatePixmapCursor(_dpy, (Pixmap)bsrc->id, 
(Pixmap)bmask->id,
                        &_fgcolor, &_bgcolor, -c->offset.x, -c->offset.y);
        }
        XDefineCursor(_dpy, (Window)screen.id, (xCursor)c->id);
}
END OF cursorswitch.c
echo 'disc.c' 1>&2
cat >'disc.c' <<'END OF disc.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

void
disc(Bitmap *b, Point p, int r, int v, Fcode f)
{
        unsigned int d;
        int x, y;
        GC g;

        x = p.x - r;
        y = p.y - r;
        if (b->flag&SHIFT){
                x -= b->r.min.x;
                y -= b->r.min.y;
        }
        d = 2*r;
        g = _getfillgc(f, b, v);
        XFillArc(_dpy, (Drawable)b->id, g, x, y, d, d, 0, 23040/* 360 deg */);
}
END OF disc.c
echo 'ellipse.c' 1>&2
cat >'ellipse.c' <<'END OF ellipse.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

/* e(x,y) = b*b*x*x + a*a*y*y - a*a*b*b */

void
ellipse(Bitmap *bp, Point p, int a, int b, int v, Fcode f)
{
        int x, y;
        GC g;

        x = p.x - a;
        y = p.y - b;
        if (bp->flag&SHIFT){
                x -= bp->r.min.x;
                y -= bp->r.min.y;
        }
        g = _getfillgc(f, bp, v);
        XDrawArc(_dpy, (Drawable)bp->id, g, x, y, 2*a, 2*b, 0, 23040/* 360 deg 
*/);
}
END OF ellipse.c
echo 'font.c' 1>&2
cat >'font.c' <<'END OF font.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

#define PJW     0       /* use NUL==pjw for invisible characters */

static Cachesubf
*findsubfont(Font *f, Rune r, int *cn)
{
        int n, i, c;
        Rune rx;
        Cachesubf *csf;

        for (i = 0, rx = r; i < 2; i++, rx = PJW)
                for (n=0, csf=f->subf; n < f->nsubf; n++, csf++)
                        if (csf->min <= rx && rx <= csf->max) {
                                if (!csf->f) {
                                        csf->f = getfont(csf->name);
                                        if (!csf->f)
                                                return 0;
                                }
                                c = rx-csf->min+csf->f->minchar;
                                c = 
((c>>8)-csf->f->minrow)*csf->f->width+(c&0xff)-csf->f->mincol;
                                if (c < 0)
                                        break;
                                        /* ignore zero width characters */
                                if (csf->f->info[c].width == 0)
                                        break;
                                *cn = c;
                                return csf;
                        }
        return 0;
}

int
cachechars(Font *f, char **s, void *cp, int max, int *wp, unsigned short *fp)
{
        int i, w, wid, charnum;
        Rune r;
        char *sp;
        Cachesubf *csf;

        sp = *s;
        wid = 0;

        for (i=0; *sp && i<max; sp+=w) {
                r = *(unsigned char *)sp;
                if (r < Runeself)
                        w = 1;
                else
                        w = chartorune(&r, sp);
                csf = findsubfont(f, r, &charnum);
                if (!csf)
                        break;
                wid += csf->f->info[charnum].width;
                fp[i] = csf-f->subf;            /* subfont number */
                ((XChar2b*)cp)[i].byte1 = charnum/csf->f->width+csf->f->minrow;
                ((XChar2b*)cp)[i].byte2 = charnum%csf->f->width+csf->f->mincol;
                i++;
        }
        *s = sp;
        *wp = wid;
        return i;
}

long
charwidth(Font *f, Rune r)
{
        Cachesubf *csf;
        int charnum;

        if (r == 0)
                berror("NUL in charwidth");     /* difficult BUG */

        csf = findsubfont(f, r, &charnum);
        if (!csf)
                return 0;
        else
                return csf->f->info[charnum].width;
}

void
subffree(Subfont *f)
{
        if (f->info)
                free(f->info);  /* note: f->info must have been malloc'ed! */
        free(f);
}
END OF font.c
echo 'gcs.c' 1>&2
cat >'gcs.c' <<'END OF gcs.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

/*
 * Libg applications are written assuming that black is ~0
 * and white is 0.  Some screens use the reverse convention.
 * We get the effect the application desired by seeing what
 * happens if both the source and dest are converted to the
 * black==~0 convention, and then converting the dest back
 * to whatever convention it uses.
 *
 * Offscreen bitmaps of depth 1 use the black==~0 convention.
 *
 * Bitmaps of depth > 1 are probably in color.  Libg operations that
 * would produce a 1 should produce the foreground color, and
 * libg operations that would produce a 0 should produce the background
 * color.  Operations that use bitmaps of depth > 1 as source
 * should interpret the foreground pixel as "black" (1) and the
 * background pixel as "white" (0).  It is hard to make this work,
 * but the important cases are Fcodes Zero, F, S, and S^D, so
 * we make sure that those work.  When a fill value is given for
 * a bitmap of depth > 1, assume ~0 means foreground, but otherwise
 * take any other value literally (assume it came from rgbpix).
 * This may be wrong for the case of 0, but libg programmers
 * usually use Fcode Zero instead of passing 0 with Fcode S.
 *
 * We assume there are at most two depths of bitmaps: depth 1
 * and depth of the screen.
 */

/*
 * gx func code corresponding to libg func code when both
 * source and dest use 1 for black.  This is a straight translation.
 */
static int gx[16] = {
        GXclear,                /* Zero */
        GXnor,                  /* DnorS */
        GXandInverted,          /* DandnotS */
        GXcopyInverted,         /* notS */
        GXandReverse,           /* notDandS */
        GXinvert,               /* notD */
        GXxor,                  /* DxorS */
        GXnand,                 /* DnandS */
        GXand,                  /* DandS */
        GXequiv,                /* DxnorS */
        GXnoop,                 /* D */
        GXorInverted,           /* DornotS */
        GXcopy,                 /* S */
        GXorReverse,            /* notDorS */
        GXor,                   /* DorS */
        GXset,                  /* F */
};

/*
 * gx func code corresponding to libg func code when 0 means black
 * in dst and 1 means black in src. These means the table has op'
 * where dst <- dst op' src == not ( not(dst)  op  src ).
 * The comment on each line is op, in Fcode terms.
 */
static int d0s1gx[16] = {
        GXset,                  /* Zero */
        GXorReverse,            /* DnorS */
        GXor,                   /* DandnotS */
        GXcopy,                 /* notS */
        GXnand,                 /* notDandS */
        GXinvert,               /* notD */
        GXxor,                  /* DxorS */
        GXandReverse,           /* DnandS */
        GXorInverted,           /* DandS */
        GXequiv,                /* DxnorS */
        GXnoop,                 /* D */
        GXand,                  /* DornotS */
        GXcopyInverted,         /* S */
        GXnor,                  /* notDorS */
        GXandInverted,          /* DorS */
        GXclear,                /* F */
};
/*
 * gx func code corresponding to libg func code when 1 means black
 * in dst and 0 means black in src. These means the table has op'
 * where dst <- dst op' src == dst  op  not(src) )
 * The comment on each line is op, in Fcode terms.
 */
static int d1s0gx[16] = {
        GXclear,                /* Zero */
        GXandReverse,           /* DnorS */
        GXand,                  /* DandnotS */
        GXcopy,                 /* notS */
        GXnor,                  /* notDandS */
        GXinvert,               /* notD */
        GXequiv,                /* DxorS */
        GXorReverse,            /* DnandS */
        GXandInverted,          /* DandS */
        GXxor,                  /* DxnorS */
        GXnoop,                 /* D */
        GXor,                   /* DornotS */
        GXcopyInverted,         /* S */
        GXnand,                 /* notDorS */
        GXorInverted,           /* DorS */
        GXset,                  /* F */
};

/*
 * gx func code corresponding to libg func code when 0 means black
 * in both the src and the dst. These means the table has op'
 * where dst <- dst op' src == not (not(dst)  op  not(src)) )
 * The comment on each line is op, in Fcode terms.
 */
static int d0s0gx[16] = {
        GXset,                  /* Zero */
        GXnand,                 /* DnorS */
        GXorInverted,           /* DandnotS */
        GXcopyInverted,         /* notS */
        GXorReverse,            /* notDandS */
        GXinvert,               /* notD */
        GXequiv,                /* DxorS */
        GXnor,                  /* DnandS */
        GXor,                   /* DandS */
        GXxor,                  /* DxnorS */
        GXnoop,                 /* D */
        GXandInverted,          /* DornotS */
        GXcopy,                 /* S */
        GXandReverse,           /* notDorS */
        GXand,                  /* DorS */
        GXclear,                /* F */
};

/*
 * 1 for those Fcodes that are degenerate (don't involve src)
 */
static int degengc[16] = {
        1,                      /* Zero */
        0,                      /* DnorS */
        0,                      /* DandnotS */
        0,                      /* notS */
        0,                      /* notDandS */
        1,                      /* notD */
        0,                      /* DxorS */
        0,                      /* DnandS */
        0,                      /* DandS */
        0,                      /* DxnorS */
        1,                      /* D */
        0,                      /* DornotS */
        0,                      /* S */
        0,                      /* notDorS */
        0,                      /* DorS */
        1,                      /* F */
};

/*
 * GCs are all for same screen, and depth is either 1 or screen depth.
 * Return a GC for the depth of b, with values as specified by gcv.
 *
 * Also, set (or unset) the clip rectangle if necessary.
 * (This implementation should be improved if setting a clip rectangle is not 
rare).
 */
GC
_getgc(Bitmap *b, unsigned long gcvm, XGCValues *pgcv)
{
        static GC gc0, gcn;
        static int clipset = 0;
        GC g;
        XRectangle xr;

        g = (b->ldepth==0)? gc0 : gcn;
        if(!g){
                g = XCreateGC(_dpy, (Drawable)b->id, gcvm, pgcv);
                if(b->ldepth==0)
                        gc0 = g;
                else
                        gcn = g;
        } else
                XChangeGC(_dpy, g, gcvm, pgcv);
        if(b->flag&CLIP){
                xr.x = b->clipr.min.x;
                xr.y = b->clipr.min.y;
                xr.width = Dx(b->clipr);
                xr.height = Dy(b->clipr);
                if(b->flag&SHIFT){
                        xr.x -= b->r.min.x;
                        xr.y -= b->r.min.y;
                }
                XSetClipRectangles(_dpy, g, 0, 0, &xr, 1, YXBanded);
                clipset = 1;
        }else if(clipset){
                pgcv->clip_mask = None;
                XChangeGC(_dpy, g, GCClipMask, pgcv);
                clipset = 0;
        }
        return g;
}

/*
 * Return a GC that will fill bitmap b using a pixel value v and Fcode f.
 * Pixel value v is according to libg convention, so 0 means
 * white (or background) and ~0 means black (or foreground).
 */
GC
_getfillgc(Fcode f, Bitmap *b, unsigned long val)
{
        int xf, m;
        unsigned long v, fg, bg, spix, vmax;
        XGCValues gcv;

        f &= F;
        vmax = _ld2dmask[b->ldepth];
        v = val & vmax;
        spix = v;
        xf = GXcopy;
        m = b->flag;
        if(m & DP1){
                xf = (m&BL1)? gx[f] : d0s1gx[f];
        }else{
                fg = _fgpixel;
                bg = _bgpixel;
                switch(f){
                case Zero:
            labZero:
                        spix = bg;
                        break;
                case F:
            labF:
                        spix = fg;
                        break;
                case D:
            labD:
                        xf = GXnoop;
                        break;
                case notD:
            labnotD:
                        xf = GXxor;
                        spix = fg^bg;
                        break;
                case S:
                        if(val == ~0)
                                spix = fg;
                        else
                                spix = v;
                        break;
                case notS:
                        if(val == ~0)
                                spix = bg;
                        else
                                spix = v;
                        break;
                case DxorS:
                        xf = GXxor;
                        if(val == ~0)
                                spix = fg^bg;
                        else
                                spix = v;
                        break;
                case DxnorS:
                        xf = GXxor;
                        if(val == 0)
                                spix = fg^bg;
                        else
                                spix = v;
                        break;
                default:
                        /* hard to do anything other than v==0 or v==~0 case */
                        if(v < vmax-v){
                                /* v is closer to 0 than vmax */
                                switch(f&~S){
                                case D&~S:      goto labD;
                                case notD&~S:   goto labnotD;
                                case Zero&~S:   goto labZero;
                                case F&~S:      goto labF;
                                }
                        }else{
                                /* v is closer to vmax than 0 */
                                switch(f&S){
                                case D&S:       goto labD;
                                case notD&S:    goto labnotD;
                                case Zero&S:    goto labZero;
                                case F&S:       goto labF;
                                }
                        }
                        
                }
        }
        gcv.foreground = spix;
        gcv.function = xf;
        return _getgc(b, GCForeground|GCFunction, &gcv);
}

/*
 * Return a GC to be used to copy an area from bitmap sb to
 * bitmap db.  Sometimes the calling function shouldn't use
 * XCopyArea, but instead should use XCopyPlane or XFillRectangle.
 * The *bltfunc arg is set to one of UseCopyArea, UseCopyPlane,
 * UseFillRectangle.
 */
GC
_getcopygc(Fcode f, Bitmap *db, Bitmap *sb, int *bltfunc)
{
        unsigned long spix, bg, fg, df, sf;
        int xf, c;
        XGCValues gcv;
        unsigned long gcvm;

        f &= F;
        gcvm = 0;
        df = db->flag;
        if(degengc[f]){
                *bltfunc = UseFillRectangle;
                if(df&SCR || !(df&DP1)){
                        fg = _fgpixel;
                        bg = _bgpixel;
                }else{
                        /* must be DP1 and BL1 */
                        fg = 1;
                        bg = 0;
                }
                switch(f){
                case Zero:
                        xf = GXcopy;
                        spix = bg;
                        break;
                case F:
                        xf = GXcopy;
                        spix = fg;
                        break;
                case D:
                        xf = GXnoop;
                        spix = fg;
                        break;
                case notD:
                        xf = GXxor;
                        spix = fg^bg;
                        break;
                }
                gcv.function = xf;
                gcv.foreground = spix;
                gcvm = GCFunction|GCForeground;
        }else{
                /* src is involved in f */

#define code(f1,f2) ((((f1)&(DP1|BL1))<<2)|((f2)&(DP1|BL1)))

                sf = sb->flag;
                c = code(df,sf);
                *bltfunc = UseCopyArea;
                switch(code(df,sf)){
                case code(DP1|BL1,DP1|BL1):
                case code(BL1,BL1):
                        xf = gx[f];
                        break;
                case code(DP1|BL1,DP1):
                        xf = d1s0gx[f];
                        break;
                case code(DP1,DP1|BL1):
                        xf = d0s1gx[f];
                        break;
                case code(DP1,DP1):
                case code(0,0):
                        xf = d0s0gx[f];
                        break;
                default:
                        /*
                         * One bitmap has depth 1, the other has screen depth.
                         * We know the bitmap must have BL1.
                         * CopyPlane must be used; it won't really work
                         * for more than fcode==S.
                         */

                        *bltfunc = UseCopyPlane;
                        xf = GXcopy;
                        switch(c){

                        case code(0,DP1|BL1):
                        case code(BL1,DP1|BL1):
                                fg = _fgpixel;
                                bg = _bgpixel;
                                break;
                        case code(DP1|BL1,0):
                                fg = 0;
                                bg = 1;
                                break;
                        case code(DP1|BL1,BL1):
                                fg = 1;
                                bg = 0;
                                break;
                        default:
                                berror("bad combination of copy bitmaps");
                        }
                        gcv.foreground = fg;
                        gcv.background = bg;
                        gcvm |= GCForeground|GCBackground;
                }
                gcv.function = xf;
                gcvm |= GCFunction;
        
#undef code
        }

        return _getgc(db, gcvm, &gcv);
}
END OF gcs.c
echo 'getrect.c' 1>&2
cat >'getrect.c' <<'END OF getrect.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

static Cursor sweep={
        {-7, -7},
        {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x07,
         0xE0, 0x07, 0xE0, 0x07, 0xE3, 0xF7, 0xE3, 0xF7,
         0xE3, 0xE7, 0xE3, 0xF7, 0xE3, 0xFF, 0xE3, 0x7F,
         0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,},
        {0x00, 0x00, 0x7F, 0xFE, 0x40, 0x02, 0x40, 0x02,
         0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x41, 0xE2,
         0x41, 0xC2, 0x41, 0xE2, 0x41, 0x72, 0x40, 0x38,
         0x40, 0x1C, 0x40, 0x0E, 0x7F, 0xE6, 0x00, 0x00,}
};

static void
grabcursor(void)
{
        /* Grab X server with an limp wrist. */
        while (XGrabPointer(_dpy, screen.id, False,
                        ButtonPressMask|ButtonReleaseMask|
                        ButtonMotionMask|StructureNotifyMask,
                GrabModeAsync, GrabModeAsync, None, None, CurrentTime)
                        != GrabSuccess)
                sleep(2);
}

static void
ungrabcursor(void)
{
        XUngrabPointer(_dpy, CurrentTime);
}

Rectangle
getrect(int but, Mouse *m){
        Rectangle r, rc;

        but = 1<<(but-1);
        cursorswitch(&sweep);
        while(m->buttons)
                *m = emouse();
        grabcursor();
        while(!(m->buttons & but)){
                *m = emouse();
                if(m->buttons & (7^but))
                        goto Return;
        }
        r.min = m->xy;
        r.max = m->xy;
        do{
                rc = rcanon(r);
                border(&screen, rc, 2, F&~D);
                *m = emouse();
                border(&screen, rc, 2, F&~D);
                r.max = m->xy;
        }while(m->buttons & but);

    Return:
        cursorswitch((Cursor *)0);
        if(m->buttons & (7^but)){
                rc.min.x = rc.max.x = 0;
                while(m->buttons)
                        *m = emouse();
        }
        ungrabcursor();
        return rc;
}
END OF getrect.c
echo 'gwin.c' 1>&2
cat >'gwin.c' <<'END OF gwin.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <stdio.h>
#if     defined(v10) || defined(HPUX)
typedef char*   caddr_t;
#endif
#include <X11/Xos.h>
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>

#ifndef XtSpecificationRelease
#define R3
#define XtPointer caddr_t
#define XtOffsetOf(s_type,field) XtOffset(s_type*,field)
#define XtExposeCompressMultiple TRUE
#endif

#include "GwinP.h"

/* Forward declarations */
static void Realize(Widget, XtValueMask *, XSetWindowAttributes *);
static void Resize(Widget);
static void Redraw(Widget, XEvent *, Region);
static void Keyaction(Widget, XEvent *, String *, Cardinal*);
static void Mouseaction(Widget, XEvent *, String *, Cardinal*);
static String SelectSwap(Widget, String);

/* Data */

#define Offset(field) XtOffsetOf(GwinRec, gwin.field)

static XtResource resources[] = {
        {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
                Offset(foreground), XtRString, (XtPointer)XtDefaultForeground},
        {XtNfont,  XtCFont, XtRFontStruct, sizeof(XFontStruct *),
                Offset(font),XtRString, (XtPointer)XtDefaultFont},
        {XtNscrollForwardR, XtCScrollForwardR, XtRBoolean, sizeof(Boolean),
                Offset(forwardr), XtRImmediate, (XtPointer)TRUE},
        {XtNreshaped, XtCReshaped, XtRFunction, sizeof(Reshapefunc),
                Offset(reshaped), XtRFunction, (XtPointer) NULL},
        {XtNgotchar, XtCGotchar, XtRFunction, sizeof(Charfunc),
                Offset(gotchar), XtRFunction, (XtPointer) NULL},
        {XtNgotmouse, XtCGotmouse, XtRFunction, sizeof(Mousefunc),
                Offset(gotmouse), XtRFunction, (XtPointer) NULL},
        {XtNselection, XtCSelection, XtRString, sizeof(String),
                Offset(selection), XtRString, (XtPointer) NULL},
        {XtNp9font, XtCP9font, XtRString, sizeof(String),
                Offset(p9font), XtRString, (XtPointer) NULL}
};
#undef Offset


static XtActionsRec actions[] = {
        {"key", Keyaction},
        {"mouse", Mouseaction}
};

static char tms[] =
        "<Key> : key() \n\
        <Motion> : mouse() \n\
        <BtnDown> : mouse() \n\
        <BtnUp> : mouse() \n";

/* Class record declaration */

GwinClassRec gwinClassRec = {
  /* Core class part */
   {
    /* superclass         */    (WidgetClass)&widgetClassRec,
    /* class_name         */    "Gwin",
    /* widget_size        */    sizeof(GwinRec),
    /* class_initialize   */    NULL,
    /* class_part_initialize*/  NULL,
    /* class_inited       */    FALSE,
    /* initialize         */    NULL,
    /* initialize_hook    */    NULL,
    /* realize            */    Realize,
    /* actions            */    actions,
    /* num_actions        */    XtNumber(actions),
    /* resources          */    resources,
    /* num_resources      */    XtNumber(resources),
    /* xrm_class          */    NULLQUARK,
    /* compress_motion    */    TRUE,
    /* compress_exposure  */    XtExposeCompressMultiple,
    /* compress_enterleave*/    TRUE,
    /* visible_interest   */    FALSE,
    /* destroy            */    NULL,
    /* resize             */    Resize,
    /* expose             */    Redraw,
    /* set_values         */    NULL,
    /* set_values_hook    */    NULL,
    /* set_values_almost  */    XtInheritSetValuesAlmost,
    /* get_values_hook    */    NULL,
    /* accept_focus       */    XtInheritAcceptFocus,
    /* version            */    XtVersion,
    /* callback_offsets   */    NULL,
    /* tm_table           */    tms,
    /* query_geometry       */  XtInheritQueryGeometry,
    /* display_accelerator  */  NULL,
    /* extension            */  NULL
   },
  /* Gwin class part */
   {
    /* select_swap        */    SelectSwap,
   }
};

/* Class record pointer */
WidgetClass gwinWidgetClass = (WidgetClass) &gwinClassRec;

static void
Realize(Widget w, XtValueMask *valueMask, XSetWindowAttributes *attrs)
{
        XtValueMask             mask;

        *valueMask |= CWBackingStore;
        attrs->backing_store = Always;

        XtCreateWindow(w, InputOutput, (Visual *)0, *valueMask, attrs);
        XtSetKeyboardFocus(w->core.parent, w);

        Resize(w);
}

static void
Resize(Widget w)
{
        if(XtIsRealized(w))
                (*(XtClass(w)->core_class.expose))(w, (XEvent *)NULL, 
(Region)NULL);
}

static void
Redraw(Widget w, XEvent *e, Region r)
{
        Reshapefunc f;

        f = ((GwinWidget)w)->gwin.reshaped;
        if(f)
                (*f)(w->core.x, w->core.y,
                        w->core.x+w->core.width, w->core.y+w->core.height);
}

#define STUFFCOMPOSE() \
                                f = ((GwinWidget)w)->gwin.gotchar; \
                                if (f) \
                                        for (c = 0; c < composing; c++) \
                                                (*f)(compose[c])

static void
Keyaction(Widget w, XEvent *e, String *p, Cardinal *np)
{
        static unsigned char compose[5];
        static int composing = -1;

        int c;
        KeySym k;
        Charfunc f;
        Modifiers md;

        /*
         * I tried using XtGetActionKeysym, but it didn't seem to
         * do case conversion properly
         * (at least, with Xterminal servers and R4 intrinsics)
         */
        if(e->xany.type != KeyPress)
                return;
        XtTranslateKeycode(e->xany.display, (KeyCode)e->xkey.keycode,
                        e->xkey.state, &md, &k);
        if(k == NoSymbol)
                return;
        if(k&0xFF00){
                switch(k){
                case XK_BackSpace:
                case XK_Tab:
                case XK_Escape:
                case XK_Delete:
                case XK_KP_0:
                case XK_KP_1:
                case XK_KP_2:
                case XK_KP_3:
                case XK_KP_4:
                case XK_KP_5:
                case XK_KP_6:
                case XK_KP_7:
                case XK_KP_8:
                case XK_KP_9:
                case XK_KP_Divide:
                case XK_KP_Multiply:
                case XK_KP_Subtract:
                case XK_KP_Add:
                case XK_KP_Decimal:
                        k &= 0x7F;
                        break;
                case XK_Linefeed:
                        k = '\r';
                        break;
                case XK_KP_Enter:
                case XK_Return:
                        k = '\n';
                        break;
                case XK_Left:
                case XK_Down:
                case XK_Right:
                case XK_Next:
                        k = 0x80; /* "Scroll" */
                        break;
                default:
                        return; /* not ISO-1 or tty control */
                }
        }
        /* Compensate for servers that call a minus a hyphen */
        if(k == XK_hyphen)
                k = XK_minus;
        /* Do control mapping ourselves if translator doesn't */
        if((e->xkey.state&ControlMask) && !(md&ControlMask))
                k &= 0x9f;
        if ((e->xkey.state & Mod1Mask) || (composing > -1))
        {
                compose[++composing] = k;
                if ((*compose == 'X') && (composing > 0))
                {
                        if ((k < '0') || (k > 'f') ||
                                        ((k > '9') && (k < 'a')))
                        {
                                STUFFCOMPOSE();
                                c = (unsigned short)k;
                                composing = -1;
                        }
                        else if (composing == 4)
                        {
                                c = (int)unicode(compose);
                                if (c == -1)
                                {
                                        STUFFCOMPOSE();
                                        c = (unsigned short)compose[4];
                                }
                                composing = -1;
                        }
                }
                else if (composing == 1)
                {
                        c = (int)latin1(compose);
                        if (c == -1)
                        {
                                STUFFCOMPOSE();
                                c = (unsigned short)compose[1];
                        }
                        composing = -1;
                }
        }
        else
        {
                if (composing >= 0)
                {
                        composing++;
                        STUFFCOMPOSE();
                }
                c = (unsigned short)k;
                composing = -1;
        }

        if (composing >= 0)
                return;

        f = ((GwinWidget)w)->gwin.gotchar;
        if(f)
                (*f)(c);
}

static void
Mouseaction(Widget w, XEvent *e, String *p, Cardinal *np)
{
        int s;
        XButtonEvent *be;
        XMotionEvent *me;
        Gwinmouse m;
        Mousefunc f;

        switch(e->type){
        case ButtonPress:
                be = (XButtonEvent *)e;
                m.xy.x = be->x;
                m.xy.y = be->y;
                m.msec = be->time;
                s = be->state;  /* the previous state */
                switch(be->button){
                case 1: s |= Button1Mask; break;
                case 2: s |= Button2Mask; break;
                case 3: s |= Button3Mask; break;
                }
                break;
        case ButtonRelease:
                be = (XButtonEvent *)e;
                m.xy.x = be->x;
                m.xy.y = be->y;
                m.msec = be->time;
                s = be->state;
                switch(be->button){
                case 1: s &= ~Button1Mask; break;
                case 2: s &= ~Button2Mask; break;
                case 3: s &= ~Button3Mask; break;
                }
                break;
        case MotionNotify:
                me = (XMotionEvent *)e;
                s = me->state;
                m.xy.x = me->x;
                m.xy.y = me->y;
                m.msec = me->time;
                break;
        default:
                return;
        }
        m.buttons = 0;
        if(s & Button1Mask) m.buttons |= 1;
        if(s & Button2Mask) m.buttons |= 2;
        if(s & Button3Mask) m.buttons |= 4;
        f = ((GwinWidget)w)->gwin.gotmouse;
        if(f)
                (*f)(&m);
}

static void
SelCallback(Widget w, XtPointer cldata, Atom *sel, Atom *seltype,
        XtPointer val, unsigned long *len, int *fmt)
{
        String s;
        int n;
        GwinWidget gw = (GwinWidget)w;

        if(gw->gwin.selection)
                XtFree(gw->gwin.selection);
        if(*seltype != XA_STRING)
                n = 0;
        else
                n = (*len) * (*fmt/8);
        s = (String)XtMalloc(n+1);
        if(n > 0)
                memcpy(s, (char *)val, n);
        s[n] = 0;
        gw->gwin.selection = s;
        XtFree(val);
}

static Boolean
SendSel(Widget w, Atom *sel, Atom *target, Atom *rtype, XtPointer *ans,
                unsigned long *anslen, int *ansfmt)
{
        GwinWidget gw = (GwinWidget)w;
        static Atom targets = 0;
        XrmValue src, dst;
        char *s;

        if(*target == XA_STRING){
                s = gw->gwin.selection;
                if(!s)
                        s = "";
                *rtype = XA_STRING;
                *ans = (XtPointer) XtNewString(s);
                *anslen = strlen(*ans);
                *ansfmt = 8;
                return TRUE;
        }
#ifndef R3
        if(targets == 0){
                src.addr = "TARGETS";
                src.size = strlen(src.addr)+1;
                dst.size = sizeof(Atom);
                dst.addr = (XtPointer) &targets;
                XtConvertAndStore(w, XtRString, &src, XtRAtom, &dst);
        }
        if(*target == targets){
                *rtype = XA_ATOM;
                *ans = (XtPointer) XtNew(Atom);
                *(Atom*) *ans = XA_STRING;
                *anslen = 1;
                *ansfmt = 32;
                return TRUE;
        }
#endif
        return FALSE;
}

static String
SelectSwap(Widget w, String s)
{
        GwinWidget gw;
        String ans;

        gw = (GwinWidget)w;
        if(gw->gwin.selection){
                XtFree(gw->gwin.selection);
                gw->gwin.selection = 0;
        }
#ifdef R3
        XtGetSelectionValue(w, XA_PRIMARY, XA_STRING, SelCallback, 0,
                        CurrentTime);
#else
        XtGetSelectionValue(w, XA_PRIMARY, XA_STRING, SelCallback, 0,
                        XtLastTimestampProcessed(XtDisplay(w)));
#endif
        while(gw->gwin.selection == 0)
                XtAppProcessEvent(XtWidgetToApplicationContext(w) , XtIMAll);
        ans = gw->gwin.selection;
        gw->gwin.selection = XtMalloc(strlen(s)+1);
        strcpy(gw->gwin.selection, s);
#ifdef R3
        XtOwnSelection(w, XA_PRIMARY, CurrentTime, SendSel, NULL, NULL);
#else
        XtOwnSelection(w, XA_PRIMARY, XtLastTimestampProcessed(XtDisplay(w)),
                        SendSel, NULL, NULL);
#endif
        return ans;
}

/* The returned answer should be free()ed when no longer needed */
String
GwinSelectionSwap(Widget w, String s)
{
        XtCheckSubclass(w, gwinWidgetClass, NULL);
        return (*((GwinWidgetClass) XtClass(w))->gwin_class.select_swap)(w, s);
}

END OF gwin.c
echo 'latin1.c' 1>&2
cat >'latin1.c' <<'END OF latin1.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */

struct latin
{
        unsigned short  l;
        unsigned char   c[2];
}latintab[] = {
        0x00a1, '!','!',        /* spanish initial ! */
        0x00a2, 'c','$',        /* cent */
        0x00a3, 'l','$',        /* pound sterling */
        0x00a4, 'g','$',        /* general currency */
        0x00a5, 'y','$',        /* yen */
        0x00a6, '|','|',        /* broken vertical bar */
        0x00a7, 'S','S',        /* section symbol */
        0x00a8, '\"','\"',      /* dieresis */
        0x00a9, 'c','O',        /* copyright */
        0x00aa, 's','a',        /* super a, feminine ordinal */
        0x00ab, '<','<',        /* left angle quotation */
        0x00ac, 'n','o',        /* not sign, hooked overbar */
        0x00ad, '-','-',        /* soft hyphen */
        0x00ae, 'r','O',        /* registered trademark */
        0x00af, '_','_',        /* macron */
        0x00b0, 'd','e',        /* degree */
        0x00b1, '+','-',        /* plus-minus */
        0x00b2, 's','2',        /* sup 2 */
        0x00b3, 's','3',        /* sup 3 */
        0x00b4, '\'','\'',      /* acute accent */
        0x00b5, 'm','i',        /* micron */
        0x00b6, 'p','g',        /* paragraph (pilcrow) */
        0x00b7, '.','.',        /* centered . */
        0x00b8, ',',',',        /* cedilla */
        0x00b9, 's','1',        /* sup 1 */
        0x00ba, 's','o',        /* super o, masculine ordinal */
        0x00bb, '>','>',        /* right angle quotation */
        0x00bc, '1','4',        /* 1/4 */
        0x00bd, '1','2',        /* 1/2 */
        0x00be, '3','4',        /* 3/4 */
        0x00bf, '?','?',        /* spanish initial ? */
        0x00c0, '`','A',        /* A grave */
        0x00c1, '\'','A',       /* A acute */
        0x00c2, '^','A',        /* A circumflex */
        0x00c3, '~','A',        /* A tilde */
        0x00c4, '\"','A',       /* A dieresis */
        0x00c5, 'o','A',        /* A circle */
        0x00c6, 'A','E',        /* AE ligature */
        0x00c7, ',','C',        /* C cedilla */
        0x00c8, '`','E',        /* E grave */
        0x00c9, '\'','E',       /* E acute */
        0x00ca, '^','E',        /* E circumflex */
        0x00cb, '\"','E',       /* E dieresis */
        0x00cc, '`','I',        /* I grave */
        0x00cd, '\'','I',       /* I acute */
        0x00ce, '^','I',        /* I circumflex */
        0x00cf, '\"','I',       /* I dieresis */
        0x00d0, 'D','-',        /* Eth */
        0x00d1, '~','N',        /* N tilde */
        0x00d2, '`','O',        /* O grave */
        0x00d3, '\'','O',       /* O acute */
        0x00d4, '^','O',        /* O circumflex */
        0x00d5, '~','O',        /* O tilde */
        0x00d6, '\"','O',       /* O dieresis */
        0x00d7, 'm','u',        /* times sign */
        0x00d8, '/','O',        /* O slash */
        0x00d9, '`','U',        /* U grave */
        0x00da, '\'','U',       /* U acute */
        0x00db, '^','U',        /* U circumflex */
        0x00dc, '\"','U',       /* U dieresis */
        0x00dd, '\'','Y',       /* Y acute */
        0x00de, '|','P',        /* Thorn */
        0x00df, 's','s',        /* sharp s */
        0x00e0, '`','a',        /* a grave */
        0x00e1, '\'','a',       /* a acute */
        0x00e2, '^','a',        /* a circumflex */
        0x00e3, '~','a',        /* a tilde */
        0x00e4, '\"','a',       /* a dieresis */
        0x00e5, 'o','a',        /* a circle */
        0x00e6, 'a','e',        /* ae ligature */
        0x00e7, ',','c',        /* c cedilla */
        0x00e8, '`','e',        /* e grave */
        0x00e9, '\'','e',       /* e acute */
        0x00ea, '^','e',        /* e circumflex */
        0x00eb, '\"','e',       /* e dieresis */
        0x00ec, '`','i',        /* i grave */
        0x00ed, '\'','i',       /* i acute */
        0x00ee, '^','i',        /* i circumflex */
        0x00ef, '\"','i',       /* i dieresis */
        0x00f0, 'd','-',        /* eth */
        0x00f1, '~','n',        /* n tilde */
        0x00f2, '`','o',        /* o grave */
        0x00f3, '\'','o',       /* o acute */
        0x00f4, '^','o',        /* o circumflex */
        0x00f5, '~','o',        /* o tilde */
        0x00f6, '\"','o',       /* o dieresis */
        0x00f7, '-',':',        /* divide sign */
        0x00f8, '/','o',        /* o slash */
        0x00f9, '`','u',        /* u grave */
        0x00fa, '\'','u',       /* u acute */
        0x00fb, '^','u',        /* u circumflex */
        0x00fc, '\"','u',       /* u dieresis */
        0x00fd, '\'','y',       /* y acute */
        0x00fe, '|','p',        /* thorn */
        0x00ff, '\"','y',       /* y dieresis */
        0x2654, 'w','k',        /* chess white king */
        0x2655, 'w','q',        /* chess white queen */
        0x2656, 'w','r',        /* chess white rook */
        0x2657, 'w','b',        /* chess white bishop */
        0x2658, 'w','n',        /* chess white knight */
        0x2659, 'w','p',        /* chess white pawn */
        0x265a, 'b','k',        /* chess black king */
        0x265b, 'b','q',        /* chess black queen */
        0x265c, 'b','r',        /* chess black rook */
        0x265d, 'b','b',        /* chess black bishop */
        0x265e, 'b','n',        /* chess black knight */
        0x265f, 'b','p',        /* chess black pawn */
        0x03b1, '*','a',        /* alpha */
        0x03b2, '*','b',        /* beta */
        0x03b3, '*','g',        /* gamma */
        0x03b4, '*','d',        /* delta */
        0x03b5, '*','e',        /* epsilon */
        0x03b6, '*','z',        /* zeta */
        0x03b7, '*','y',        /* eta */
        0x03b8, '*','h',        /* theta */
        0x03b9, '*','i',        /* iota */
        0x03ba, '*','k',        /* kappa */
        0x03bb, '*','l',        /* lambda */
        0x03bc, '*','m',        /* mu */
        0x03bd, '*','n',        /* nu */
        0x03be, '*','c',        /* xsi */
        0x03bf, '*','o',        /* omicron */
        0x03c0, '*','p',        /* pi */
        0x03c1, '*','r',        /* rho */
        0x03c2, 't','s',        /* terminal sigma */
        0x03c3, '*','s',        /* sigma */
        0x03c4, '*','t',        /* tau */
        0x03c5, '*','u',        /* upsilon */
        0x03c6, '*','f',        /* phi */
        0x03c7, '*','x',        /* chi */
        0x03c8, '*','q',        /* psi */
        0x03c9, '*','w',        /* omega */     
        0x0391, '*','A',        /* Alpha */
        0x0392, '*','B',        /* Beta */
        0x0393, '*','G',        /* Gamma */
        0x0394, '*','D',        /* Delta */
        0x0395, '*','E',        /* Epsilon */
        0x0396, '*','Z',        /* Zeta */
        0x0397, '*','Y',        /* Eta */
        0x0398, '*','H',        /* Theta */
        0x0399, '*','I',        /* Iota */
        0x039a, '*','K',        /* Kappa */
        0x039b, '*','L',        /* Lambda */
        0x039c, '*','M',        /* Mu */
        0x039d, '*','N',        /* Nu */
        0x039e, '*','C',        /* Xsi */
        0x039f, '*','O',        /* Omicron */
        0x03a0, '*','P',        /* Pi */
        0x03a1, '*','R',        /* Rho */
        0x03a3, '*','S',        /* Sigma */
        0x03a4, '*','T',        /* Tau */
        0x03a5, '*','U',        /* Upsilon */
        0x03a6, '*','F',        /* Phi */
        0x03a7, '*','X',        /* Chi */
        0x03a8, '*','Q',        /* Psi */
        0x03a9, '*','W',        /* Omega */
        0x2190, '<','-',        /* left arrow */
        0x2191, 'u','a',        /* up arrow */
        0x2192, '-','>',        /* right arrow */
        0x2193, 'd','a',        /* down arrow */
        0x2194, 'a','b',        /* arrow both */
        0x21d0, 'V','=',        /* left double-line arrow */
        0x21d2, '=','V',        /* right double-line arrow */
        0x2200, 'f','a',        /* forall */
        0x2203, 't','e',        /* there exists */
        0x2202, 'p','d',        /* partial differential */
        0x2205, 'e','s',        /* empty set */
        0x2206, 'D','e',        /* delta */
        0x2207, 'g','r',        /* gradient */
        0x2208, 'm','o',        /* element of */
        0x2209, '!','m',        /* not element of */
        0x220d, 's','t',        /* such that */
        0x2217, '*','*',        /* math asterisk */
        0x2219, 'b','u',        /* bullet */
        0x221a, 's','r',        /* radical */
        0x221d, 'p','t',        /* proportional */
        0x221e, 'i','f',        /* infinity */
        0x2220, 'a','n',        /* angle */
        0x2227, 'l','&',        /* logical and */
        0x2228, 'l','|',        /* logical or */
        0x2229, 'c','a',        /* intersection */
        0x222a, 'c','u',        /* union */
        0x222b, 'i','s',        /* integral */
        0x2234, 't','f',        /* therefore */
        0x2243, '~','=',        /* asymptotically equal */
        0x2245, 'c','g',        /* congruent */
        0x2248, '~','~',        /* almost equal */
        0x2260, '!','=',        /* not equal */
        0x2261, '=','=',        /* equivalent */
        0x2266, '<','=',        /* less than or equal */
        0x2267, '>','=',        /* greater than or equal */
        0x2282, 's','b',        /* proper subset */
        0x2283, 's','p',        /* proper superset */
        0x2284, '!','b',        /* not subset */
        0x2286, 'i','b',        /* reflexive subset */
        0x2287, 'i','p',        /* reflexive superset */
        0x2295, 'O','+',        /* circle plus */
        0x2296, 'O','-',        /* circle minus */
        0x2297, 'O','x',        /* circle multiply */
        0x22a2, 't','u',        /* turnstile */
        0x22a8, 'T','u',        /* valid */
        0x22c4, 'l','z',        /* lozenge */
        0x22ef, 'e','l',        /* ellipses */
        0,      0,
};

long
latin1(unsigned char *k)
{
        struct latin *l;

        for(l=latintab; l->l; l++)
                if(k[0]==l->c[0] && k[1]==l->c[1])
                        return l->l;
        return -1;
}

long
unicode(unsigned char *k)
{
        long i, c;

        k++;    /* skip 'X' */
        c = 0;
        for(i=0; i<4; i++,k++){
                c <<= 4;
                if('0'<=*k && *k<='9')
                        c += *k-'0';
                else if('a'<=*k && *k<='f')
                        c += 10 + *k-'a';
                else if('A'<=*k && *k<='F')
                        c += 10 + *k-'A';
                else
                        return -1;
        }
        return c;
}
END OF latin1.c
echo 'menuhit.c' 1>&2
cat >'menuhit.c' <<'END OF menuhit.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

enum
{
        Margin = 3,             /* outside to text */
        Border = 2,             /* outside to selection boxes */
        Blackborder = 1,        /* width of outlining border */
        Vspacing = 1            /* extra spacing between lines of text */
};

Rectangle
menurect(Rectangle r, int i)
{
        if(i < 0)
                return Rect(0, 0, 0, 0);
        r = inset(r, Margin);
        r.min.y += (font->height+Vspacing)*i;
        r.max.y = r.min.y+font->height+Vspacing;
        return inset(r, Border-Margin);
}

int
menusel(Rectangle r, Point p)
{
        r = inset(r, Margin);
        if(!ptinrect(p, r))
                return -1;
        return (p.y-r.min.y)/(font->height+Vspacing);
}

int
menuhit(int but, Mouse *m, Menu *menu)
{
        int i, nitem, maxwid = 0, lasti;
        Rectangle r, menur;
        Point pt;
        Bitmap *b;
        char *item;

        for(nitem = 0;
            item = menu->item? menu->item[nitem] : (*menu->gen)(nitem);
            nitem++){
                i = strwidth(font, item);
                if(i > maxwid)
                        maxwid = i;
        }
        if(menu->lasthit<0 || menu->lasthit>=nitem)
                menu->lasthit = 0;
        r = inset(Rect(0, 0, maxwid, nitem*(font->height+Vspacing)), -Margin);
        r = rsubp(r,
            Pt(maxwid/2, menu->lasthit*(font->height+Vspacing)+font->height/2));
        r = raddp(r, m->xy);
        pt = Pt(0, 0);
        if(r.max.x>screen.r.max.x)
                pt.x = screen.r.max.x-r.max.x;
        if(r.max.y>screen.r.max.y)
                pt.y = screen.r.max.y-r.max.y;
        if(r.min.x<screen.r.min.x)
                pt.x = screen.r.min.x-r.min.x;
        if(r.min.y<screen.r.min.y)
                pt.y = screen.r.min.y-r.min.y;
        menur = raddp(r, pt);
        b = balloc(menur, screen.ldepth);
        if(b == 0)
                b = &screen;
        bitblt(b, menur.min, &screen, menur, S);
        bitblt(&screen, menur.min, &screen, menur, 0);
        border(&screen, menur, Blackborder, F);
        pt = Pt(menur.min.x+menur.max.x, menur.min.y+Margin);
        for(i = 0; i<nitem; i++, pt.y += font->height+Vspacing){
                item = menu->item? menu->item[i] : (*menu->gen)(i);
                string(&screen,
                        Pt((pt.x-strwidth(font, item))/2, pt.y),
                        font, item, S);
        }
        bflush();
        lasti = menusel(menur, m->xy);
        r = menurect(menur, menu->lasthit);
        cursorset(divpt(add(r.min, sub(r.max, Pt(0,Vspacing))), 2));
        bitblt(&screen, r.min, &screen, r, F&~D);
        for(;;){
                *m = emouse();
                if(!(m->buttons & (1<<(but-1))))
                        break;
                i = menusel(menur, m->xy);
                if(i == lasti)
                        continue;
                bitblt(&screen, r.min, &screen, r, F&~D);
                r = menurect(menur, i);
                bitblt(&screen, r.min, &screen, r, F&~D);
                lasti = i;
        }
        bitblt(&screen, menur.min, b, menur, S);
        if(b != &screen)
                bfree(b);
        if(lasti >= 0)
                menu->lasthit = lasti;
        return lasti;
}
END OF menuhit.c
echo 'mkfont.c' 1>&2
cat >'mkfont.c' <<'END OF mkfont.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include <string.h>
#include <stdlib.h>
extern char *strdup(const char *);

/*
 * Cobble fake font using existing subfont
 */
Font*
mkfont(Subfont *subfont)
{
        Font *font;
        unsigned char *gbuf;
        Cachesubf *c;

        font = (Font *)malloc(sizeof(Font));
        if(font == 0)
                return 0;
        memset(font, 0, sizeof(Font));
        font->name = strdup("<synthetic>");
        if (font->name==0) {
                free(font);
                return 0;
        }
        font->nsubf = 1;
        font->subf = (Cachesubf *)malloc(font->nsubf * sizeof(Cachesubf));
        if(font->subf == 0)
        {
                free(font->name);
                free(font);
                return 0;
        }
        memset(font->subf, 0, font->nsubf*sizeof(Cachesubf));
        font->height = subfont->height;
        font->ascent = subfont->ascent;
        font->ldepth = screen.ldepth;
        c = font->subf;
        subfont->minchar = subfont->mincol;     /* base font at first char */
        c->min = subfont->minchar;
        c->max = subfont->maxchar;
        c->name = 0;    /* noticed by freeup() */
        font->subf[0].f = subfont;
        return font;
}
END OF mkfont.c
echo 'point.c' 1>&2
cat >'point.c' <<'END OF point.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

void
point(Bitmap *b, Point p, int v, Fcode f)
{
        int x, y;
        GC g;

        x = p.x;
        y = p.y;
        if(b->flag&SHIFT){
                x -= b->r.min.x;
                y -= b->r.min.y;
        }
        g = _getfillgc(f, b, v);
        XDrawPoint(_dpy, (Drawable)b->id, g, x, y);
}
END OF point.c
echo 'rdbitmap.c' 1>&2
cat >'rdbitmap.c' <<'END OF rdbitmap.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

void
rdbitmap(Bitmap *b, int miny, int maxy, unsigned char *data)
{
        XImage *gim, *eim;
        int x, y, w, h, pix, n, offset;
        char *tdata;

        /*
         * The XGetImage returned image may be wrong in a number of ways:
         * wrong bit order, byte order, bit pad, scanline pad,
         * and constant shift.
         * So use a SLOW loop, for now
         */
        w = Dx(b->r);
        h = maxy - miny;
        gim = XGetImage(_dpy, (Drawable)b->id, 0, miny - b->r.min.y,
                        w, h, ~0, ZPixmap);
        n = (w * _ld2d[b->ldepth] + 7) / 8 * h;
        if(n <= 0)
                return;
        tdata = (char *)malloc(n);
        if (!tdata)
                berror("rdbitmap malloc");
        memcpy(tdata, (char *)data, n);
        eim = XCreateImage(_dpy, 0, _ld2d[b->ldepth], ZPixmap, 0, tdata,
                        w, h, 8, 0);
        eim->bitmap_pad = 8;
        eim->bitmap_bit_order = MSBFirst;
        eim->byte_order = MSBFirst;

        offset = b->r.min.x%8;
        for(y = 0; y < h; y++)
                for(x = 0; x < w; x++) {
                        pix = XGetPixel(gim, x, y);
                        XPutPixel(eim, x+offset, y, pix);
                }
        memcpy((char *)data, tdata, n);
        XDestroyImage(gim);
        XDestroyImage(eim);
}
END OF rdbitmap.c
echo 'rdbitmapfile.c' 1>&2
cat >'rdbitmapfile.c' <<'END OF rdbitmapfile.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

#define CHUNK 6000

Bitmap*
rdbitmapfile(int fd)
{
        char hdr[5*12+1];
        unsigned char *data;
        long dy, px;
        unsigned long l, t, n;
        long miny, maxy;
        Rectangle r;
        int ld;
        Bitmap *b;

        if(read(fd, hdr, 5*12)!=5*12)
                berror("rdbitmapfile read");
        ld = atoi(hdr+0*12);
        r.min.x = atoi(hdr+1*12);
        r.min.y = atoi(hdr+2*12);
        r.max.x = atoi(hdr+3*12);
        r.max.y = atoi(hdr+4*12);
        if(ld<0 || ld>1)
                berror("rdbitmapfile ldepth");
        if(r.min.x>r.max.x || r.min.y>r.max.y)
                berror("rdbitmapfile rectangle");

        miny = r.min.y;
        maxy = r.max.y;
        px = 1<<(3-ld); /* pixels per byte */
        /* set l to number of bytes of data per scan line */
        if(r.min.x >= 0)
                l = (r.max.x+px-1)/px - r.min.x/px;
        else{   /* make positive before divide */
                t = (-r.min.x)+px-1;
                t = (t/px)*px;
                l = (t+r.max.x+px-1)/px;
        }
        b = balloc(r, ld);
        if(b == 0)
                return 0;
        data = (unsigned char *)malloc(CHUNK);
        if(data == 0)
                berror("rdbitmapfile malloc");
        while(maxy > miny){
                dy = maxy - miny;
                if(dy*l > CHUNK)
                        dy = CHUNK/l;
                n = dy*l;
                if(read(fd, data, n) != n){
                        free(data);
                        bfree(b);
                        berror("rdbitmapfile read");
                }
                wrbitmap(b, miny, miny+dy, data);
                miny += dy;
        }
        free(data);
        return b;
}
END OF rdbitmapfile.c
echo 'rdfontfile.c' 1>&2
cat >'rdfontfile.c' <<'END OF rdfontfile.c'
#include <libc.h>
#include <libg.h>
#include "libgint.h"
#include <string.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <stdlib.h>
extern char *strdup(const char *);

static char*
skip(char *s)
{
        while (*s==' ' || *s=='\n' || *s=='\t')
                s++;
        return s;
}

Font *
rdfontfile(char *name, int ldepth)
{
        Font *fnt;
        Cachesubf *c;
        int fd, i;
        char *buf, *s, *t;
        struct stat sbuf;
        unsigned long min, max;

        fd = open(name, O_RDONLY);
        if (fd < 0)
                return 0;
        if (fstat(fd, &sbuf) < 0)
        {
    Err0:
                close(fd);
                return 0;
        }
        buf = (char *)malloc(sbuf.st_size+1);
        if (buf == 0)
                goto Err0;
        buf[sbuf.st_size] = 0;
        i = read(fd, buf, sbuf.st_size);
        close(fd);
        if (i != sbuf.st_size)
        {
    Err1:
                free(buf);
                return 0;
        }

        s = buf;
        fnt = (Font *)malloc(sizeof(Font));
        if (fnt == 0)
                goto Err1;
        memset(fnt, 0, sizeof(Font));
        fnt->name = strdup(name);
        if (fnt->name==0)
        {
    Err2:
                free(fnt->name);
                free(fnt);
                goto Err1;
        }
        fnt->height = strtol(s, &s, 0);
        s = skip(s);
        fnt->ascent = strtol(s, &s, 0);
        s = skip(s);
        if (fnt->height<=0 || fnt->ascent<=0)
                goto Err2;
        fnt->width = 0;
        fnt->ldepth = ldepth;

        fnt->id = 0;
        fnt->nsubf = 0;
        fnt->subf = 0;

        do {
                min = strtol(s, &s, 0);
                s = skip(s);
                max = strtol(s, &s, 0);
                s = skip(s);
                if(*s==0 || min>=65536 || max>=65536 || min>max)
                {
    Err3:
                        ffree(fnt);
                        return 0;
                }
                if (fnt->subf)
                        fnt->subf = (Cachesubf *)realloc(fnt->subf, 
(fnt->nsubf+1)*sizeof(Cachesubf));
                else
                        fnt->subf = (Cachesubf *)malloc(sizeof(Cachesubf));
                if (fnt->subf == 0)
                {
                        /* realloc manual says fnt->subf may have been 
destroyed */
                        fnt->nsubf = 0;
                        goto Err3;
                }
                c = &fnt->subf[fnt->nsubf];
                c->min = min;
                c->max = max;
                t = s;
                while (*s && *s!=' ' && *s!='\n' && *s!='\t')
                        s++;
                *s++ = 0;
                c->f = (Subfont *)0;
                c->name = strdup(t);
                if (c->name == 0)
                {
                        free(c);
                        goto Err3;
                }
                s = skip(s);
                fnt->nsubf++;
        } while(*s);
        free(buf);
        return fnt;
}

void
ffree(Font *f)
{
        int i;
        Cachesubf *c;
        unsigned char *b;

        for (i=0; i<f->nsubf; i++){
                c = f->subf+i;
                if (c->f)
                        subffree(c->f);
                free(c->name);
                free(c);
        }
        free(f->subf);
        free(f);
}
END OF rdfontfile.c
echo 'rectclip.c' 1>&2
cat >'rectclip.c' <<'END OF rectclip.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>

rectclip(Rectangle *rp, Rectangle b)            /* first by reference, second 
by value */
{
        Rectangle *bp = &b;
        /*
         * Expand rectXrect() in line for speed
         */
        if((rp->min.x<bp->max.x && bp->min.x<rp->max.x &&
            rp->min.y<bp->max.y && bp->min.y<rp->max.y)==0)
                return 0;
        /* They must overlap */
        if(rp->min.x < bp->min.x)
                rp->min.x = bp->min.x;
        if(rp->min.y < bp->min.y)
                rp->min.y = bp->min.y;
        if(rp->max.x > bp->max.x)
                rp->max.x = bp->max.x;
        if(rp->max.y > bp->max.y)
                rp->max.y = bp->max.y;
        return 1;
}
END OF rectclip.c
echo 'rune.c' 1>&2
cat >'rune.c' <<'END OF rune.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include        <string.h>
#include        <libc.h>

enum
{
        Bit1    = 7,
        Bitx    = 6,
        Bit2    = 5,
        Bit3    = 4,
        Bit4    = 3,

        T1      = ((1<<(Bit1+1))-1) ^ 0xFF,     /* 0000 0000 */
        Tx      = ((1<<(Bitx+1))-1) ^ 0xFF,     /* 1000 0000 */
        T2      = ((1<<(Bit2+1))-1) ^ 0xFF,     /* 1100 0000 */
        T3      = ((1<<(Bit3+1))-1) ^ 0xFF,     /* 1110 0000 */
        T4      = ((1<<(Bit4+1))-1) ^ 0xFF,     /* 1111 0000 */

        Rune1   = (1<<(Bit1+0*Bitx))-1,         /* 0000 0000 0111 1111 */
        Rune2   = (1<<(Bit2+1*Bitx))-1,         /* 0000 0111 1111 1111 */
        Rune3   = (1<<(Bit3+2*Bitx))-1,         /* 1111 1111 1111 1111 */

        Maskx   = (1<<Bitx)-1,                  /* 0011 1111 */
        Testx   = Maskx ^ 0xFF,                 /* 1100 0000 */

        Bad     = Runeerror
};

int
chartorune(Rune *rune, char *str)
{
        int c, c1, c2;
        long l;

        /*
         * one character sequence
         *      00000-0007F => T1
         */
        c = *(uchar*)str;
        if(c < Tx) {
                *rune = c;
                return 1;
        }

        /*
         * two character sequence
         *      0080-07FF => T2 Tx
         */
        c1 = *(uchar*)(str+1) ^ Tx;
        if(c1 & Testx)
                goto bad;
        if(c < T3) {
                if(c < T2)
                        goto bad;
                l = ((c << Bitx) | c1) & Rune2;
                if(l <= Rune1)
                        goto bad;
                *rune = l;
                return 2;
        }

        /*
         * three character sequence
         *      0800-FFFF => T3 Tx Tx
         */
        c2 = *(uchar*)(str+2) ^ Tx;
        if(c2 & Testx)
                goto bad;
        if(c < T4) {
                l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3;
                if(l <= Rune2)
                        goto bad;
                *rune = l;
                return 3;
        }

        /*
         * bad decoding
         */
bad:
        *rune = Bad;
        return 1;
}

int
runetochar(char *str, Rune *rune)
{
        long c;

        /*
         * one character sequence
         *      00000-0007F => 00-7F
         */
        c = *rune;
        if(c <= Rune1) {
                str[0] = c;
                return 1;
        }

        /*
         * two character sequence
         *      0080-07FF => T2 Tx
         */
        if(c <= Rune2) {
                str[0] = T2 | (c >> 1*Bitx);
                str[1] = Tx | (c & Maskx);
                return 2;
        }

        /*
         * three character sequence
         *      0800-FFFF => T3 Tx Tx
         */
        str[0] = T3 |  (c >> 2*Bitx);
        str[1] = Tx | ((c >> 1*Bitx) & Maskx);
        str[2] = Tx |  (c & Maskx);
        return 3;
}

int
runelen(long c)
{
        Rune rune;
        char str[10];

        rune = c;
        return runetochar(str, &rune);
}

int
fullrune(char *str, int n)
{
        int c;

        if(n > 0) {
                c = *(uchar*)str;
                if(c < Tx)
                        return 1;
                if(n > 1)
                        if(c < T3 || n > 2)
                                return 1;
        }
        return 0;
}

char*
utfrune(char *s, long c)
{
        long c1;
        Rune r;
        int n;

        if(c < Runesync)                /* not part of utf sequence */
                return strchr(s, c);

        for(;;) {
                c1 = *(uchar*)s;
                if(c1 < Runeself) {     /* one byte rune */
                        if(c1 == 0)
                                return 0;
                        if(c1 == c)
                                return s;
                        s++;
                        continue;
                }
                n = chartorune(&r, s);
                if(r == c)
                        return s;
                s += n;
        }
}

long
utflen(char *s)
{
        int c;
        long n;
        Rune rune;

        n = 0;
        for(;;) {
                c = *(uchar*)s;
                if(c < Runeself) {
                        if(c == 0)
                                return n;
                        s++;
                } else
                        s += chartorune(&rune, s);
                n++;
        }
}
END OF rune.c
echo 'segment.c' 1>&2
cat >'segment.c' <<'END OF segment.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

void
segment(Bitmap *d, Point p1, Point p2, int v, Fcode f)
{
        int x1, y1, x2, y2;
        GC g;

        x1 = p1.x;
        y1 = p1.y;
        x2 = p2.x;
        y2 = p2.y;
        if(d->flag&SHIFT){
                x1 -= d->r.min.x;
                y1 -= d->r.min.y;
                x2 -= d->r.min.x;
                y2 -= d->r.min.y;
        }
        g = _getfillgc(f, d, v);
        XDrawLine(_dpy, (Drawable)d->id, g, x1, y1, x2, y2);
}
END OF segment.c
echo 'string.c' 1>&2
cat >'string.c' <<'END OF string.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

enum    { Max = 128 };

Point
string(Bitmap *b, Point p, Font *ft, char *s, Fcode f)
{
        int x, y, wid, i, j, n, nti, cf;
        XChar2b cbuf[Max];
        unsigned short fbuf[Max];
        XTextItem16 ti[Max];
        Rune r;
        GC g;

        x = p.x;
        y = p.y;
        if (b->flag&SHIFT){
                x -= b->r.min.x;
                y -= b->r.min.y;
        }
        y += ft->ascent;
        g = _getfillgc(f, b, ~0);

        while (*s) {
                n = cachechars(ft, &s, cbuf, Max, &wid, fbuf);
                if (n <= 0) {
                        s += chartorune(&r, s);
                        continue;
                }
                nti = 0;
                cf = fbuf[0];                   /* first font */
                ti[0].chars = cbuf;
                ti[0].delta = 0;
                ti[0].font = (xFont)ft->subf[cf].f->id;
                for (i = 1, j = 1; i < n; i++, j++) {
                        if (fbuf[i] != cf) {    /* font change */
                                cf = fbuf[i];
                                ti[nti++].nchars = j;
                                ti[nti].chars = &cbuf[i];
                                ti[nti].delta = 0;
                                ti[nti].font = (xFont)ft->subf[cf].f->id;
                                j = 0;
                        }
                }
                ti[nti++].nchars = j;
                XDrawText16(_dpy, (Drawable)b->id, g, x, y, ti, nti);
                x += wid;
        }
        p.x = (b->flag&SHIFT) ? x + b->r.min.x : x;
        return p;
}
END OF string.c
echo 'strwidth.c' 1>&2
cat >'strwidth.c' <<'END OF strwidth.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

long
strwidth(Font *f, char *s)
{
        int wid, twid;
        enum { Max = 128 };
        Rune cbuf[Max];
        unsigned short fbuf[Max];
        Rune r;

        twid = 0;
        while (*s)
        {
                if (cachechars(f, &s, cbuf, Max, &wid, fbuf) <= 0)
                        s += chartorune(&r, s);
                else
                        twid += wid;
        }
        return twid;
}

Point
strsize(Font *f, char *s)
{
        return Pt(strwidth(f, s), f->height);
}
END OF strwidth.c
echo 'test.c' 1>&2
cat >'test.c' <<'END OF test.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#ifdef __STDC__
#include <stdlib.h>
#endif
#include <libg.h>
#include <stdio.h>

void cont(char *);
void putstring(char *);
void colorinit(void);
void printcolmap(void);
void invertcolmap(void);

unsigned char arrowset[] =
        {0x00, 0x00, 0x7F, 0xC0, 0x7F, 0x00, 0x7C, 0x00,
         0x7E, 0x00, 0x7F, 0x00, 0x6F, 0x80, 0x67, 0xC0,
         0x43, 0xE0, 0x41, 0xF0, 0x00, 0xF8, 0x00, 0x7C,
         0x00, 0x3E, 0x00, 0x1C, 0x00, 0x08, 0x00, 0x00};

char *colors[] = { "Black", "Red", "Green", "Yellow",
                "Cyan", "Magenta", "Blue", "White" };
RGB colordefs[] = {
        { 0,0,0 },                                      /* black */
        {0xFFFFFFFF,    0x00000000,     0x00000000},    /* red */
        {0x00000000,    0xFFFFFFFF,     0x00000000},    /* green */
        {0xFFFFFFFF,    0xFFFFFFFF,     0x00000000},    /* yellow */
        {0x00000000,    0xFFFFFFFF,     0xFFFFFFFF},    /* cyan */
        {0xFFFFFFFF,    0x00000000,     0xFFFFFFFF},    /* magenta */
        {0x00000000,    0x00000000,     0xFFFFFFFF},    /* blue */
        {0xFFFFFFFF,    0xFFFFFFFF,     0xFFFFFFFF},    /* white */
};
#define Ncol (sizeof(colordefs)/sizeof(colordefs[0]))
unsigned long rgbval[Ncol];
Bitmap *rgbbitmap[Ncol];

main(int argc, char **argv)
{
        Point p1,p2,p3;
        Mouse m;
        int r,rx,ry;
        int n, i;
        char *m3gen(int);
        static Menu menu3 = { (char **) 0, m3gen, 0 };
        char *p, buf[200];
        Bitmap *bm, *bm2;
        RGB cmap[256];

        xtbinit(0,0,&argc,argv);
        einit(Ekeyboard|Emouse);
        p1 = add(screen.r.min, Pt(15,15));
        p2 = sub(screen.r.max, Pt(15,15));
        p3 = divpt(add(p1,p2),2);
        fprintf(stderr, "segment(&screen, (%d,%d), (%d,%d), ~0, S)\n",
                p1.x,p1.y,p2.x,p2.y);
        segment(&screen, p1, p2, ~0, S);
        cont("point");
        fprintf(stderr, "point(&screen, (%d,%d), ~0, S)\n", p1.x,p1.y);
        point(&screen, p1, ~0, S);
        cont("circle");
        rx = p3.x - p1.x;
        ry = p3.y - p1.y;
        r = (rx < ry)? rx : ry;
        fprintf(stderr, "circle(&screen, (%d,%d), %d, ~0, S)\n",
                p3.x,p3.y,r);
        circle(&screen, p3, r, ~0, S);
        cont("disc");
        fprintf(stderr, "disc(&screen, (%d,%d), %d, ~0, S)\n",
                p3.x,p3.y,r);
        disc(&screen, p3, r, ~0, S);
        cont("clipped disc");
        fprintf(stderr, "clipr(&screen, ((%d,%d)(%d,%d))\n",
                p1.x+30, p1.y+5, p3.x-30, p3.y-5);
        clipr(&screen, Rect(p1.x+30, p1.y+5, p3.x-30, p3.y-5));
        fprintf(stderr, "disc(&screen, (%d,%d), %d, ~0, S)\n",
                p3.x,p3.y,r);
        disc(&screen, p3, r, ~0, S);
        clipr(&screen, screen.r);
        cont("ellipse");
        fprintf(stderr, "ellipse(&screen, (%d,%d), %d, %d, ~0, S)\n",
                p3.x,p3.y,r,r/2);
        ellipse(&screen, p3, r, r/2, ~0, S);
        cont("arc");
        fprintf(stderr, "arc(&screen, (%d,%d), (%d,%d), (%d,%d), ~0, S)\n",
                p3.x,p3.y, p3.x+r,p3.y, p3.x+r/2,p3.x-(int)(r*.866));
        arc(&screen, p3, Pt(p3.x+r,p3.y), Pt(p3.x+r/2,p3.x-(int)(r*.866)), ~0, 
S);
        if(screen.ldepth > 1){
                cont("color");
                colorinit();
                p3 = p1;
                rx *= 2;
                ry *= 2;
                for(i = 0; i<Ncol; i++) {
                        texture(&screen, Rpt(p3,add(p3,Pt(rx,ry/Ncol))),
                                rgbbitmap[i], S);
                        string(&screen, add(p3,Pt(15,15)), font, colors[i], 
DxorS);
                        p3.y += ry/Ncol;
                }
                printcolmap();
                cont("invert colmap");
                invertcolmap();
                printcolmap();
                p3 = p1;
                for(i = 0; i<Ncol; i++) {
                        texture(&screen, Rpt(p3,add(p3,Pt(rx,ry/Ncol))),
                                rgbbitmap[i], S);
                        string(&screen, add(p3,Pt(15,15)), font, colors[i], 
DxorS);
                        p3.y += ry/Ncol;
                }
        }
/*
        cont("wrbitmap, border, and bitblt(S)");
        bm = balloc(Rect(0,0,16,16), 0);
        fprintf(stderr, "border (%d,%d,%d,%d), -2, F)\n",
                p1.x, p1.y, p1.x+16, p1.y+16);
        border(&screen, Rpt(p1, add(p1,Pt(16,16))), -2, F);
        wrbitmap(bm, 0, 16, arrowset);
        fprintf(stderr, "bitblt(&screen, (%d,%d), bm, (0,0,16,16), S)\n",
                p1.x,p1.y);
        bitblt(&screen, p1, bm, Rect(0,0,16,16), S);
        cont("mouse track (button 1)");
        do{
                m = emouse();
        } while(!(m.buttons&1));
        fprintf(stderr,"test tracking\n");
        while(m.buttons&1){
                point(&screen, m.xy, ~0, S);
                m = emouse();
        }
        cursorswitch(0);
        cont("menuhit (button 3)");
        do {
                do{
                        m = emouse();
                } while(!(m.buttons&4));
                n = menuhit(3, &m, &menu3);
                fprintf(stderr, "button %d\n", n);
        } while (n != 0);
        cont("keyboard (end with \\n)");
        fprintf(stderr, "type something\n");
        for (p = buf; (*p = ekbd()) != '\n' && *p != '\r'; p++) {
                fprintf(stderr, "%c", *p);
                if (*p == '\b')
                        p -= 2;
                if (p < buf-1)
                        p = buf-1;
                p[1] = 0;
                putstring(buf);
        }
*/
        cont("done");
        exit(0);
}

void colorinit(void)    /* set up color definitions */
{
        int i;

        for (i = 0; i < Ncol; i++) {
                rgbval[i] = rgbpix(&screen, colordefs[i]);
                rgbbitmap[i] = balloc(Rect(0,0,1,1), screen.ldepth);
                point(rgbbitmap[i], Pt(0,0), rgbval[i], S);
        }
}

void printcolmap(void)
{
        int i, n;
        RGB cmap[256];

        rdcolmap(&screen, cmap);
        n = 1 << (1 << screen.ldepth);
        fprintf(stderr, "colormap, %d entries\n", n);
        for(i = 0; i < n; i++)
                fprintf(stderr, "%d:\t%.8x\t%.8x\t%.8x\n",
                        i, cmap[i].red, cmap[i].green, cmap[i].blue);
}

void invertcolmap(void)
{
        int i, n;
        RGB cmap[256];

        rdcolmap(&screen, cmap);
        n = 1 << (1 << screen.ldepth);
        for(i = 0; i < n; i++) {
                cmap[i].red = ~cmap[i].red;
                cmap[i].green = ~cmap[i].green;
                cmap[i].blue = ~cmap[i].blue;
        }
        wrcolmap(&screen, cmap);
}

void
putstring(char *buf)
{
        Point p;
        static int jmax = 0, l;

        p = add(screen.r.min, Pt(20,20));
        bitblt(&screen, p, &screen, Rect(p.x, p.y, p.x+jmax, p.y+font->height), 
Zero);
        string(&screen, p, font, buf, F);
        if ((l = strwidth(font, buf)) > jmax)
                jmax = l;
}

void
cont(char *msg)
{
        Event ev;
        Point mp;

        while(event(&ev) != Ekeyboard)
                continue;
        bitblt(&screen, Pt(0,0), &screen, screen.r, Zero);
        mp = add(screen.r.min, Pt(20,20));
        string(&screen, mp, font, msg, S);
        while(event(&ev) != Ekeyboard)
                continue;
        bitblt(&screen, Pt(0,0), &screen, screen.r, Zero);
}

char *
m3gen(int n)
{
        static char *m3[] ={ "quit", "thing1", "thing2" };

        if (n < 0 || n > 2)
                return 0;
        else 
                return m3[n];
}

void
ereshaped(Rectangle r)
{
}
END OF test.c
echo 'texture.c' 1>&2
cat >'texture.c' <<'END OF texture.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

void
texture(Bitmap *d, Rectangle r, Bitmap *s, Fcode f)
{
        int x, y, w, h, bfunc;
        GC g;

        x = r.min.x;
        y = r.min.y;
        if(d->flag&SHIFT){
                x -= d->r.min.x;
                y -= d->r.min.y;
        }
        g = _getcopygc(f, d, s, &bfunc);
        if(d->flag&SHIFT){
                XSetTSOrigin(_dpy, g, -d->r.min.x, -d->r.min.y);
        }else
                XSetTSOrigin(_dpy, g, 0, 0);
        w = Dx(r);
        h = Dy(r);
        if(bfunc == UseFillRectangle){
                /* source isn't involved at all */
                XFillRectangle(_dpy, (Drawable)d->id, g, x, y, w, h);
        }else if(bfunc == UseCopyArea){
                XSetTile(_dpy, g, (Drawable)s->id);
                XSetFillStyle(_dpy, g, FillTiled);
                XFillRectangle(_dpy, (Drawable)d->id, g, x, y, w, h);
                XSetFillStyle(_dpy, g, FillSolid);
        }else{
                if(s->ldepth != 0)
                        berror("unsupported texture");
                XSetStipple(_dpy, g, (Drawable)s->id);
                XSetFillStyle(_dpy, g, FillOpaqueStippled);
                XFillRectangle(_dpy, (Drawable)d->id, g, x, y, w, h);
                XSetFillStyle(_dpy, g, FillSolid);
        }
}
END OF texture.c
echo 'wrbitmap.c' 1>&2
cat >'wrbitmap.c' <<'END OF wrbitmap.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"
#include <X11/Intrinsic.h>
#ifndef XtSpecificationRelease
#define R3
#endif

void
wrbitmap(Bitmap *b, int miny, int maxy, unsigned char *data)
{
        XImage *im;
        int w, h, n, dep;
        GC g;

        w = Dx(b->r);
        h = maxy - miny;
        dep = _ld2d[b->ldepth];
        im = XCreateImage(_dpy, 0, dep, ZPixmap, 0,
                        (char*)data, w, h, 8, (w*dep+7)/8);

        /* Botched interface to XCreateImage doesn't let you set these: */
        im->bitmap_bit_order = MSBFirst;
        im->byte_order = MSBFirst;

        g = _getfillgc(S, b, ~0);
        XSetBackground(_dpy, g, b->flag&DP1 ? 0 : _bgpixel);
        XPutImage(_dpy, (Drawable)b->id, g, im, 0, 0, 0, miny - b->r.min.y, w, 
h);
}
END OF wrbitmap.c
echo 'wrbitmapfile.c' 1>&2
cat >'wrbitmapfile.c' <<'END OF wrbitmapfile.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include "libgint.h"

#define CHUNK   4096

void
wrbitmapfile(int fd, Bitmap *b)
{
        char hdr[5*12+1];
        unsigned char *data;
        long dy, px;
        unsigned long l, t, n;
        long miny, maxy;

        sprint(hdr, "%11d %11d %11d %11d %11d ",
                b->ldepth, b->r.min.x, b->r.min.y, b->r.max.x, b->r.max.y);
        if(write(fd, hdr, 5*12) != 5*12)
                berror("wrbitmapfile write");

        px = 1<<(3-b->ldepth);  /* pixels per byte */
        /* set l to number of bytes of data per scan line */
        if(b->r.min.x >= 0)
                l = (b->r.max.x+px-1)/px - b->r.min.x/px;
        else{   /* make positive before divide */
                t = (-b->r.min.x)+px-1;
                t = (t/px)*px;
                l = (t+b->r.max.x+px-1)/px;
        }
        miny = b->r.min.y;
        maxy = b->r.max.y;
        data = (unsigned char *)malloc(CHUNK);
        if(data == 0)
                berror("wrbitmapfile malloc");
        while(maxy > miny){
                dy = maxy - miny;
                if(dy*l > CHUNK)
                        dy = CHUNK/l;
                rdbitmap(b, miny, miny+dy, data);
                n = dy*l;
                if(write(fd, data, n) != n){
                        free(data);
                        berror("wrbitmapfile write");
                }
                miny += dy;
        }
        free(data);
}
END OF wrbitmapfile.c
echo 'xtbinit.c' 1>&2
cat >'xtbinit.c' <<'END OF xtbinit.c'
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <libc.h>
#include <libg.h>
#include <stdio.h>
#include "libgint.h"

#define COMPRESSMOUSE

#define Cursor xCursor
#define Font xFont
#define Event xEvent

#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include "Gwin.h"

#ifndef XtSpecificationRelease
#define R3
#define XtAppInitialize(a,b,c,d,e,f,g,h,i) XtInitialize(0,b,c,d,e,f)
#define XtConvertAndStore(a,b,c,d,e) (XtConvert(a,b,c,d,e),1)
#define XtAppPending(a) XtPending()
#define XtAppProcessEvent(a,b) XtProcessEvent(b)
#define XtAppAddTimeOut(a,b,c,d) XtAddTimeOut(b,c,d)
#define XtAppAddInput(a,b,c,d,e) XtAddInput(b,c,d,e)
#define XtPointer caddr_t
#endif

#undef Cursor
#undef Font
#undef Event

/* libg globals */
Bitmap  screen;
Font    *font;

/* implementation globals */
Display *_dpy;
Widget  _toplevel;
unsigned long   _fgpixel, _bgpixel;
XColor  _fgcolor, _bgcolor;
int     _ld2d[6] = { 1, 2, 4, 8, 16, 32 };
unsigned long _ld2dmask[6] = { 0x1, 0x3, 0xF, 0xFF, 0xFFFF, 0xFFFFFFFF };

/* xbinit implementation globals */
#ifndef R3
static XtAppContext app;
#endif
static Widget widg;
static int exposed = 0;
static Atom wm_take_focus;
static Mouse lastmouse;

typedef struct Ebuf {
        struct Ebuf     *next;
        int             n;
        unsigned char   buf[2];
} Ebuf;

typedef struct Esrc {
        int     inuse;
        int     size;
        Ebuf    *head;
        Ebuf    *tail;
} Esrc;

#define MAXSRC 10

static Esrc     esrc[MAXSRC];
static int      nsrc;

/* Make sure Smouse = log2(Emouse) and Skeyboard == log2(Ekeyboard) */
#define Smouse    0
#define Skeyboard 1

static int einitcalled = 0;
static int Stimer = -1;


static void     reshaped(int, int, int, int);
static void     gotchar(int);
static void     gotmouse(Gwinmouse *);
static int      log2(int);
static void     pixtocolor(Pixel, XColor *);
static Subfont  *XFontStructtoSubfont(XFontStruct *);
static Ebuf     *ebread(Esrc *);
static Ebuf     *ebadd(Esrc *);
static void     focinit(Widget);
static void     wmproto(Widget, XEvent *, String *, Cardinal *);
static void     waitevent(void);

static Errfunc  onerr;

String fallbacks[] = {
        "*gwin.width: 400",
        "*gwin.height: 400",
        NULL
};

#ifndef R3
static char *shelltrans = 
        "<ClientMessage> WM_PROTOCOLS : WMProtocolAction()";
static XtActionsRec wmpactions[] = {
        {"WMProtocolAction", wmproto}
};
#endif

void
xtbinit(Errfunc f, char *class, int *pargc, char **argv)
{
        int n;
        unsigned int depth;
        XFontStruct *xf;
        Subfont *subfont;
        String fontname;
        Arg args[10];
        char *p;
        XSetWindowAttributes attr;

        if(!class && argv[0]){
                p = strrchr(argv[0], '/');
                if(p)
                        class = XtNewString(p+1);
                else
                        class = XtNewString(argv[0]);
                if(class[0] >= 'a' && class[0] <= 'z')
                        class[0] += 'A' - 'a';
        }
        onerr = f;
        n = 0;
        XtSetArg(args[n], XtNinput, TRUE);              n++;
        _toplevel = XtAppInitialize(&app, class, 0, 0,
                        pargc, argv, fallbacks, args, n);

        n = 0;
        XtSetArg(args[n], XtNreshaped, reshaped);       n++;
        XtSetArg(args[n], XtNgotchar, gotchar);         n++;
        XtSetArg(args[n], XtNgotmouse, gotmouse);       n++;
        widg = XtCreateManagedWidget("gwin", gwinWidgetClass, _toplevel, args, 
n);

        n = 0;
        XtSetArg(args[n], XtNforeground, &_fgpixel);    n++;
        XtSetArg(args[n], XtNbackground, &_bgpixel);    n++;
        XtSetArg(args[n], XtNdepth, &depth);            n++;
        XtSetArg(args[n], XtNfont, &xf);                n++;
        XtSetArg(args[n], XtNp9font, &fontname);        n++;
        XtGetValues(widg, args, n);

        _dpy = XtDisplay(widg);
        screen.id = 0;
        XtRealizeWidget(_toplevel);
        pixtocolor(_fgpixel, &_fgcolor);
        pixtocolor(_bgpixel, &_bgcolor);
        screen.id = (int) XtWindow(widg);
        screen.ldepth = log2(depth);
        screen.flag = SCR;
        if(_fgpixel != 0)
                screen.flag |= BL1;
        if(depth == 1)
                screen.flag |= DP1;
        font = 0;
        subfont = 0;
        if (fontname) {
                font = rdfontfile(fontname, screen.ldepth);
                if (!font || charwidth(font, (Rune) ' ') == 0) {
                        subfont = getfont(fontname);
                        if (!subfont)
                                subfont = XFontStructtoSubfont(xf);
                        font = mkfont(subfont);
                }
        } else {
                subfont = XFontStructtoSubfont(xf);
                font = mkfont(subfont);
        }
        /* leave screen rect at all zeros until reshaped() sets it */
        while(!exposed)
                bflush();
        XFlush(_dpy);
        focinit(_toplevel);
}

static void
focinit(Widget w)
{
#ifndef R3
        XrmValue src, dst;

        src.addr = "WM_TAKE_FOCUS";
        src.size = strlen((char *)src.addr)+1;
        dst.addr = (XtPointer) &wm_take_focus;
        dst.size = sizeof(Atom);
        XtConvertAndStore(w, XtRString, &src, XtRAtom, &dst);
        XSetWMProtocols(XtDisplay(w), XtWindow(w), &wm_take_focus, 1);
        XtAppAddActions(app, wmpactions, XtNumber(wmpactions));
        XtAugmentTranslations(w, XtParseTranslationTable(shelltrans));
#endif
}

#ifndef R3
static void
wmproto(Widget w, XEvent *e , String *p, Cardinal *np)
{
        Time t;

        if(e->type == ClientMessage &&
          (Atom)(e->xclient.data.l[0]) == wm_take_focus) {
                t = (Time) e->xclient.data.l[1];
                XtCallAcceptFocus(widg, &t);
        }
}
#endif

static void
reshaped(int minx, int miny, int maxx, int maxy)
{
        Ebuf *eb;
        Mouse m;

        screen.r = Rect(minx, miny, maxx, maxy);
        screen.clipr = screen.r;
        if (screen.id) {
                exposed = 1;
                ereshaped(screen.r);
        }
        if(einitcalled){
                /*
                 * Cause a mouse event, so programs like sam
                 * will get out of eread and REALLY do the reshape
                 */
                eb = ebadd(&esrc[Smouse]);
                memcpy(eb->buf, &lastmouse, sizeof lastmouse);
        }
}

static void
gotchar(int c)
{
        Ebuf *eb;

        if(!einitcalled || !esrc[Skeyboard].inuse)
                return;
        eb = ebadd(&esrc[Skeyboard]);
        if(c == '\r')
                c = '\n';
        BPSHORT(eb->buf, (unsigned short)(c & 0xffff));
}

static void
gotmouse(Gwinmouse *gm)
{
        Ebuf *eb;
        Mouse m;

        if(!einitcalled || !esrc[Smouse].inuse)
                return;
        m.buttons = gm->buttons;
        m.xy.x = gm->xy.x;
        m.xy.y = gm->xy.y;
        m.msec = gm->msec;
        lastmouse = m;
        eb = ebadd(&esrc[Smouse]);
        memcpy(eb->buf, &m, sizeof m);
}

static void
gotinput(XtPointer cldata, int *pfd, XtInputId *id)
{
        Ebuf *eb;
        Esrc *es;

        if(!einitcalled)
                return;
        es = (Esrc *)cldata;
        eb = ebadd(es);
        if(es->size){
                eb->n = read(*pfd, (char *)eb->buf, es->size);
                if(eb->n < 0)
                        eb->n = 0;
        }
}

static void
gottimeout(XtPointer cldata, XtIntervalId *id)
{
        if(!einitcalled || Stimer == -1)
                return;
        /*
         * Don't queue up timeouts, because there's
         * too big a danger that they might pile up
         * too quickly.
         */
        esrc[Stimer].head = (Ebuf *)1;
        XtAppAddTimeOut(app, (int)cldata, gottimeout, cldata);
}

static int
log2(int n)
{
        int i, v;

        for(i=0, v=1; i < 32; i++, v<<=1)
                if(n == v)
                        break;
        return i;
}

static void
pixtocolor(Pixel p, XColor *pc)
{
#ifdef R3
        Colormap cmap;
        Arg args[2];
        int n;

        n = 0;
        XtSetArg(args[n], XtNcolormap, &cmap);  n++;
        XtGetValues(widg, args, n);
        pc->pixel = p;
        XQueryColor(_dpy, cmap, pc);
#else
        XrmValue xvf, xvt;

        xvf.size = sizeof(Pixel);
        xvf.addr = (XtPointer)&p;
        xvt.size = sizeof(XColor);
        xvt.addr = (XtPointer)pc;
        if(!XtConvertAndStore(widg, XtRPixel, &xvf, XtRColor, &xvt))
                pc->pixel = p;  /* maybe that's enough */
#endif
}

unsigned long
rgbpix(Bitmap *b, RGB col)
{
        XColor c;
        Colormap cmap;
        Arg args[2];
        int n;


        n = 0;
        XtSetArg(args[n], XtNcolormap, &cmap);  n++;
        XtGetValues(widg, args, n);
        c.red = col.red>>16;
        c.green = col.green>>16;
        c.blue = col.blue>>16;
        c.flags = DoRed|DoGreen|DoBlue;
        if(!XAllocColor(_dpy, cmap, &c))
                return 0;       /* what to do? */
        return (unsigned long)(c.pixel);
}

void
rdcolmap(Bitmap *b, RGB *map)
{
        XColor cols[256];
        int i, n, depth;
        Colormap cmap;
        Arg args[2];

        i = 0;
        XtSetArg(args[i], XtNcolormap, &cmap);  i++;
        XtGetValues(widg, args, i);

        depth = 1 << screen.ldepth;
        n = 1 << depth;
        if (depth == 1) {
                map[0].red = map[0].green = map[0].blue = ~0;
                map[1].red = map[1].green = map[1].blue = 0;
        }
        else {
                if (n > 256) {
                        berror("rdcolmap bitmap too deep");
                        return;
                }
                for (i = 0; i < n; i++)
                        cols[i].pixel = i;
                XQueryColors(_dpy, cmap, cols, n);
                for (i = 0; i < n; i++) {
                        map[i].red = (cols[i].red << 16) | cols[i].red;
                        map[i].green = (cols[i].green << 16) | cols[i].green;
                        map[i].blue = (cols[i].blue << 16) | cols[i].blue;
                }
        }
}

void
wrcolmap(Bitmap *b, RGB *map)
{
        int i, n, depth;
        Colormap cmap;
        Visual *vis;
        Screen *scr;
        XColor cols[256];
        Arg args[2];
        XVisualInfo vi;
        Window w;

        i = 0;
        XtSetArg(args[i], XtNscreen, &scr);     i++;
        XtGetValues(widg, args, i);

        depth = 1 << screen.ldepth;
        n = 1 << depth;
        if (n > 256) {
                berror("wrcolmap bitmap too deep");
                return;
        } else if (depth > 1) {
                for (i = 0; i < n; i++) {
                        cols[i].red = map[i].red >> 16;
                        cols[i].green = map[i].green >> 16;
                        cols[i].blue = map[i].blue >> 16;
                        cols[i].pixel = i;
                        cols[i].flags = DoRed|DoGreen|DoBlue;
                }
                if (!XMatchVisualInfo(_dpy, XScreenNumberOfScreen(scr),
                                        depth, PseudoColor, &vi)) {
                        berror("wrcolmap can't get visual");
                        return;
                }
                w = XtWindow(widg);
                cmap = XCreateColormap(_dpy, w, vi.visual, AllocAll);
                XStoreColors(_dpy, cmap, cols, n);

                i = 0;
                XtSetArg(args[i], XtNcolormap, cmap);   i++;
                XtSetValues(widg, args, i);
                XtSetWMColormapWindows(_toplevel, &widg, 1);
        }
}

Subfont *
getfont(char *s)
{
        XFontStruct *fp;

        if(!s)
                return 0;
        fp = XLoadQueryFont(_dpy, s);
        if(!fp)
                return 0;
        return XFontStructtoSubfont(fp);
}

static Subfont *
XFontStructtoSubfont(XFontStruct *fp)
{
        XCharStruct *cp;
        Subfont *f;
        int min, max;
        int i;

        if(!fp)
                berror("no font");
        f = (Subfont *)malloc(sizeof(Subfont));
        if(!f)
                berror("XFontStructtoSubfont malloc");
        min = fp->min_byte1;
        max = fp->max_byte1;
        f->minrow = min;
        f->mincol = fp->min_char_or_byte2;
        f->width = fp->max_char_or_byte2-fp->min_char_or_byte2+1;
        f->n = f->width;
/*      f->minchar = fp->min_char_or_byte2;*/
        f->minchar = 0;                         /* hack - filled in mkfont */
        f->maxchar = fp->max_char_or_byte2;
        if (min || max) {
/*              f->minchar |= (min<<8);         /* adjust for multi-row fonts */
                f->maxchar |= (max<<8);
                f->n *= (max-min+1);
        }
        f->id = fp->fid;
        f->height = fp->max_bounds.ascent + fp->max_bounds.descent;
        f->ascent = fp->max_bounds.ascent;
        f->info = (Fontchar *)malloc((f->n+1)*sizeof(Fontchar));
        if(!f->info)
                berror("getfont malloc");
        memset(f->info, 0, (f->n+1)*sizeof(Fontchar));
        for(i = 0; i < f->n; i++){
                if(fp->per_char)
                        cp = fp->per_char + i;
                else
                        cp = &fp->max_bounds;
                f->info[i].left = cp->lbearing;
                f->info[i].width = cp->width;
                f->info[i].top = 0;
                f->info[i].bottom = f->height;
        }
        XFreeFontInfo(0, fp, 0);
        return f;
}

int
scrollfwdbut(void)
{
        Arg arg;
        Boolean v;

        XtSetArg(arg, XtNscrollForwardR, &v);
        XtGetValues(widg, &arg, 1);
        return v? 3 : 1;
}

void
einit(unsigned long keys)
{
        nsrc = 0;
        if(keys&Emouse){
                esrc[Smouse].inuse = 1;
                esrc[Smouse].size = sizeof(Mouse);
                nsrc = Smouse+1;
        }
        if(keys&Ekeyboard){
                esrc[Skeyboard].inuse = 1;
                esrc[Skeyboard].size = 1;
                if(Skeyboard >= nsrc)
                        nsrc = Skeyboard+1;
        }
        einitcalled = 1;
}

unsigned long
estart(unsigned long key, int fd, int n)
{
        int i;

        if(fd < 0)
                berror("bad fd to estart");
        if(n <= 0 || n > EMAXMSG)
                n = EMAXMSG;
        for(i=0; i<MAXSRC; i++)
                if((key & ~(1<<i)) == 0 && !esrc[i].inuse){
                        if(nsrc <= i)
                                nsrc = i+1;
                        esrc[i].inuse = 1;
                        esrc[i].size = n;
                        XtAppAddInput(app, fd, (XtPointer)XtInputReadMask,
                                gotinput, (XtPointer) &esrc[i]);
                        return 1<<i;
                }
        return 0;
}

unsigned long
etimer(unsigned long key, int n)
{
        int i;

        if(Stimer != -1)
                berror("timer started twice");
        if(n <= 0)
                n = 1000;
        for(i=0; i<MAXSRC; i++)
                if((key & ~(1<<i)) == 0 && !esrc[i].inuse){
                        if(nsrc <= i)
                                nsrc = i+1;
                        esrc[i].inuse = 1;
                        esrc[i].size = 0;
                        XtAppAddTimeOut(app, n, gottimeout, (XtPointer)n);
                        Stimer = i;
                        return 1<<i;
                }
        return 0;
}

unsigned long
event(Event *e)
{
        return eread(~0L, e);
}

unsigned long
eread(unsigned long keys, Event *e)
{
        Ebuf *eb;
        int i;

        if(keys == 0)
                return 0;
                /* Give Priority to X events */
        if (XtAppPending(app) & XtIMXEvent)
                XtAppProcessEvent(app, XtIMXEvent);

        for(;;){
                for(i=0; i<nsrc; i++)
                        if((keys & (1<<i)) && esrc[i].head){
                                if(i == Smouse)
                                        e->mouse = emouse();
                                else if(i == Skeyboard)
                                        e->kbdc = ekbd();
                                else if(i == Stimer)
                                        esrc[i].head = 0;
                                else{
                                        eb = ebread(&esrc[i]);
                                        e->n = eb->n;
                                        if(e->n > 0)
                                                memcpy(e->data, eb->buf, e->n);
                                        free(eb);
                                }
                                return 1<<i;
                        }
                waitevent();
        }
}

Mouse
emouse(void)
{
        Mouse m;
        Ebuf *eb;

        if(!esrc[Smouse].inuse)
                berror("mouse events not selected");
        eb = ebread(&esrc[Smouse]);
        memcpy(&m, eb->buf, sizeof(Mouse));
        free(eb);
        return m;
}

int
ekbd(void)
{
        Ebuf *eb;
        int c;

        if(!esrc[Skeyboard].inuse)
                berror("keyboard events not selected");
        eb = ebread(&esrc[Skeyboard]);
        c = BGSHORT(eb->buf);
        free(eb);
        return c;
}

int
ecanread(unsigned long keys)
{
        int i;

        for(;;){
                for(i=0; i<nsrc; i++){
                        if((keys & (1<<i)) && esrc[i].head)
                                return 1<<i;
                }
                if(XtAppPending(app))
                        waitevent();
                else
                        return 0;
        }
}

int
ecanmouse(void)
{
        if(!esrc[Smouse].inuse)
                berror("mouse events not selected");
        return ecanread(Emouse);
}

int
ecankbd(void)
{
        if(!esrc[Skeyboard].inuse)
                berror("keyboard events not selected");
        return ecanread(Ekeyboard);
}

static Ebuf*
ebread(Esrc *s)
{
        Ebuf *eb;

        while(s->head == 0)
                waitevent();
        eb = s->head;
#ifdef COMPRESSMOUSE
        if(s == &esrc[Smouse]) {
                while(eb->next) {
                        s->head = eb->next;
                        free(eb);
                        eb = s->head;
                }
        }
#endif
        s->head = s->head->next;
        if(s->head == 0)
                s->tail = 0;
        return eb;
}

static Ebuf*
ebadd(Esrc *s)
{
        Ebuf *eb;
        int m;

        m = sizeof(Ebuf);
        if(s->size > 1)
                m += (s->size-1);       /* overestimate, because of alignment */
        eb = (Ebuf *)malloc(m);
        if(!eb)
                berror("eballoc can't malloc");
        eb->next = 0;
        eb->n = s->size;
        if(s->tail){
                s->tail->next = eb;
                s->tail = eb;
        }else
                s->head = s->tail = eb;
        return eb;
}

void
berror(char *s)
{
        if(onerr)
                (*onerr)(s);
        else{
                fprintf(stderr, "libg error: %s:\n", s);
                exit(1);
        }
}

void
bflush(void)
{
        while(XtAppPending(app) & XtIMXEvent)
                waitevent();
}

static void
waitevent(void)
{
        XFlush(_dpy);
        if (XtAppPending(app) & XtIMXEvent)
                XtAppProcessEvent(app, XtIMXEvent);
        else
                XtAppProcessEvent(app, XtIMAll);
}
                
int
snarfswap(char *s, int n, char **t)
{
        *t = GwinSelectionSwap(widg, s);
        if (*t)
                return strlen(*t);
        return 0;
}

#ifdef DEBUG
/* for debugging */
printgc(char *msg, GC g)
{
        XGCValues v;

        XGetGCValues(_dpy, g, GCFunction|GCForeground|GCBackground|GCFont|
                        GCTile|GCFillStyle|GCStipple, &v);
        fprintf(stderr, "%s: gc %x\n", msg, g);
        fprintf(stderr, "  fg %d bg %d func %d fillstyle %d font %x tile %x 
stipple %x\n",
                v.foreground, v.background, v.function, v.fill_style,
                v.font, v.tile, v.stipple);
}
#endif

END OF xtbinit.c
echo 'add.3' 1>&2
cat >'add.3' <<'END OF add.3'
.TH ADD 3G
.SH NAME
add, sub, mul, divpt, raddp, rsubp, rmul, rdiv, rshift, inset, rcanon, eqpt, 
eqrect, ptinrect, rectXrect, rectclip, Dx, Dy, Pt, Rect, Rpt \- arithmetic on 
points and rectangles
.SH SYNOPSIS
.B #include "libg.h"
.PP
.B
.ta 12n +12n +12n +12n +12n
Point   add(Point p, Point q)
.PP
.B
Point   sub(Point p, Point q)
.PP
.B
Point   mul(Point p, int a)
.PP
.B
Point   divpt(Point p, int a)
.PP
.B
Rectangle       raddp(Rectangle r, Point p)
.PP
.B
Rectangle       rsubp(Rectangle r, Point p)
.PP
.B
Rectangle       rmul(Rectangle r, int a)
.PP
.B
Rectangle       rdiv(Rectangle r, int a)
.PP
.B
Rectangle       rshift(Rectangle r, int a)
.PP
.B
Rectangle       inset(Rectangle r, int n)
.PP
.B
Rectangle       rcanon(Rectangle r)
.PP
.B
int     eqpt(Point p, Point q)
.PP
.B
int     eqrect(Rectangle r, Rectangle s)
.PP
.B
int     ptinrect(Point p, Rectangle r)
.PP
.B
int     rectXrect(Rectangle r, Rectangle s)
.PP
.B
int     rectclip(Rectangle *rp, Rectangle b)
.PP
.B
int     Dx(Rectangle r);
.PP
.B
int     Dy(Rectangle r);
.PP
.B
Point   Pt(int x, int y)
.PP
.B
Rectangle       Rect(int x0, int y0, int x1, int y1)
.PP
.B
Rectangle       Rpt(Point p, Point q)
.SH DESCRIPTION
The functions
.IR Pt ,
.I Rect
and
.I Rpt
construct geometrical data types from their components.
These are implemented as macros.
.PP
.I Add
returns the Point
sum of its arguments:
.BI Pt( p .x+ q .x,
.IB p .y+ q .y).
.I Sub
returns the Point
difference of its arguments:
.BI Pt( p .x- q .x,
.IB p .y- q .y).
.I Mul
returns the Point
.BI Pt( p .x* a ,
.IB p .y* a ).
.I Divpt
returns the Point
.BI Pt( p .x/ a ,
.IB p .y/ a ).
.PP
.I Raddp
returns the Rectangle
.BI Rect(add( r .min,
.IB p ),
.BI add( r .max,
.IB p ))\fR;
.I rsubp
returns the Rectangle
.BI Rpt(sub( r .min,
.IB p ),
.BI sub( r .max,
.IB p ))\fR.
.I Rmul
returns the Rectangle
.BI Rpt(mul( r .min, a ),
.BI mul( r .max, a ))\fR;
.I Rdiv
returns the Rectangle
.BI Rpt(div( r .min, a ),
.BI div( r .max, a ))\fR.
.PP
.I Rshift
returns the rectangle
.I r
with all coordinates either left-shifted or right-shifted by
.IR a ,
depending on whether
.I a
is positive or negative, respectively.
.PP
.I Inset
returns the Rectangle
.BI Rect( r .min.x+ n ,
.IB r .min.y+ n ,
.IB r .max.x- n ,
.IB r .max.y- n ) .
.PP
.I Rcanon
returns a rectangle with the same extent as
.IR r ,
canonicalized so that
.B min.x
.if t \(<=
.if n <=
.BR max.x ,
and
.B min.y
.if t \(<=
.if n <=
.BR max.y .
.PP
.I Eqpt
compares its argument Points and returns
0 if unequal,
1 if equal.
.I Eqrect
does the same for its argument Rectangles.
.PP
.I Ptinrect
returns 1 if
.I p
is a point within
.IR r ,
and 0 otherwise.
.PP
.I RectXrect
returns 1 if
.I r
and
.I s
share any point, and 0 otherwise.
.PP
.I Rectclip
clips in place
the Rectangle pointed to by
.I rp
so that it is completely contained within
.IR b .
The return value is 1 if any part of
.RI * rp
is within
.IR b .
Otherwise, the return value is 0 and
.RI * rp
is unchanged.
.PP
The functions
.I Dx
and
.I Dy
give the width (delta x) and height (delta y) of a Rectangle.
They are implemented as macros.
.SH SEE ALSO
.IR graphics (3)
END OF add.3
echo 'balloc.3' 1>&2
cat >'balloc.3' <<'END OF balloc.3'
.TH BALLOC 3G
.SH NAME
balloc, bfree, rdbitmap, wrbitmap, rdbitmapfile, wrbitmapfile \- allocating, 
freeing, reading, writing bitmaps
.SH SYNOPSIS
.nf
.PP
.B
#include "libg.h"
.PP
.ta \w'\fLBitmap 'u
.B
Bitmap  *balloc(Rectangle r, int ldepth)
.PP
.B
void    bfree(Bitmap *b)
.PP
.B
void    rdbitmap(Bitmap *b, int miny, int maxy, uchar *data)
.PP
.B
void    wrbitmap(Bitmap *b, int miny, int maxy, uchar *data)
.PP
.B
Bitmap  *rdbitmapfile(int fd)
.PP
.B
void    wrbitmapfile(int fd, Bitmap *b)
.SH DESCRIPTION
A new bitmap is allocated with
.BR balloc ;
it will have the extent and depth given by its arguments,
and will be filled with zeros. The
.I id
field will have been set to the identifying number used by
.F /dev/bitblt
(see
.IR bit (5)),
and the
.I cache
field will be zero.
.I Balloc
returns 0 if the server has run out of bitmap resources.
.B Bfree
frees the resources used by its argument bitmap.
.PP
The remaining functions deal with moving groups of pixel
values between bitmaps and user space or external files.
There is a fixed format for the bitmap data in user space or on
external files.
A pixel with x-coordinate =
.I x
in a bitmap with
.B ldepth
=
.I l
will appear as
.if t \fIw\fP = 2\u\s8\fIl\fP\s10\d
.if n w = 2^l
contiguous bits in a byte, with the pixel's high order bit
starting at the byte's bit number
.if t \fIw\fP\(mu(\fIx\fP mod 8/\fIw\fP),
.if n w*(x mod 8/w),
where bits within a byte are numbered 0 to 7 from the
high order to the low order bit.
If
.I w
is greater than 8, it is a multiple of 8, so
pixel values take up an integral number of bytes.
A
.I row
of bitmap
.I b
consists of the byte containing pixel
.IB b .r.min.x
and all the bytes up to and including the byte containing pixel
.IB b .r.min.x\fR\(mi1.
.PP
.I Rdbitmap
reads rows of pixels from bitmap
.I b
into
.IR data .
The rows read have
.IR y = ymin , ymin "+1, ... "
.IR ymax \(mi1.
Those rows must be within the range allowed by
.IB b .r.
.PP
.B Wrbitmap
replaces the specified rows of pixels in bitmap
.I b
with
.IR data .
.PP
.I Rdbitmapfile
creates a bitmap from data contained an external file;
.I fd
should be a file descriptor obtained by opening such a file for reading.
The external file should start with 5 ASCII integers:
.BR ldepth ,
.BR r.min.x ,
.BR r.min.y ,
.BR r.max.x ,
and
.BR r.max.y .
Each number is right-justified in 11 characters, followed by a blank.
The rows of bitmap data, formatted as described above,
follow the header.
The returned bitmap is allocated using
.I balloc .
.I Rdbitmapfile
returns 0 if the server has run out of bitmap resources.
.PP
.I Wrbitmapfile
writes bitmap
.I b
onto file descriptor
.IR fd ,
which should be open for writing.
The format is as just described for
.IR rdbitmapfile .
.PP
.I Rdbitmapfile
and
.I wrbitmapfile
don't close
.IR fd .
.PP
.SH DIAGNOSTICS
Some errors can occur when accessing the internal bitmaps,
when trying to malloc, or when trying to read or write the
argument file descriptors;
the graphics error function (see
.IR graphics (2))
is called when this happens.
.SH "SEE ALSO"
.IR graphics (3),
.IR bitblt (3).
END OF balloc.3
echo 'bitblt.3' 1>&2
cat >'bitblt.3' <<'END OF bitblt.3'
.TH BITBLT 3G
.SH NAME
bitblt, bitbltclip, point, segment, circle, disc, ellipse, texture, border, 
string, strsize, strwidth, Fcode \- graphics functions
.SH SYNOPSIS
.nf
.B #include "libg.h"
.PP
.ta \w'\fLPoint 'u
.B
void    bitblt(Bitmap *db, Point dp, Bitmap *sb,
.B
            Rectangle sr, Fcode f)
.PP
.B
void    bitbltclip(void *)
.PP
.B
void    point(Bitmap *b, Point p, int v, Fcode f);
.PP
.B
void    segment(Bitmap *b, Point p, Point q, int v, Fcode f)
.PP
.B
void    circle(Bitmap *b, Point p, int r, int v, Fcode f);
.PP
.B
void    disc(Bitmap *b, Point p, int r, int v, Fcode);
.PP
.B
void    ellipse(Bitmap *b, Point p, int a, int b, int v, Fcode f);
.PP
.B
void    texture(Bitmap *b, Rectangle r, Bitmap *t, Fcode f)
.PP
.B
void    border(Bitmap *b, Rectangle r, int w, Fcode f)
.PP
.B
Point   string(Bitmap *b, Point p, Font *ft, char *s, Fcode f)
.PP
.B
Point   strsize(Font *ft, char *s)
.PP
.B
long    strwidth(Font *ft, char *s)
.PP
.ft L
.ta 8n +\w'xxxxxxxxxx'u +\w'xxxxxxxxxx'u +\w'xxxxxxxxxx'u +\w'xxxxxxxxxx'u
enum Fcode {
        Zero,   DnorS,  DandnotS,       notS,
        notDandS,       notD,   DxorS,  DnandS,
        DandS,  DxnorS, D,      DornotS,
        S,      notDorS,        DorS,   F
} Fcode;
.ft P
.fi
.SH DESCRIPTION
.I Bitblt
(bit-block transfer)
takes bits from rectangle
.I sr
in the
.I source
Bitmap,
.IR sb,
and overlays them on a congruent rectangle with the
.B min
corner at point
.B dp
in the
.I destination
bitmap,
.IR db .
The
.I f
parameter says how to compute each destination pixel
as a function of the source and destination pixels.
The first sixteen codes in 
.B Fcode
give all possible boolean operations
on the source,
.B S 
and destination
.BR D .
The code values have been arranged so that they may be expressed as
boolean operations on the values
.B S
and
.BR D.
So, for example,
.B D|S
computes the result as the logical
.I or
of the destination pixel's old value and the overlaying source pixel's value.
If pixels are more than one bit deep, the operations are bitwise.
The
.B Zero
and
.B F
codes result in new pixel values that are all zeros or all ones, respectively.
.PP
If the source and destination bitmaps have different depths,
the source rectangle is first converted to have the same depth as the
destination, as follows:
conversion to a smaller number of bits per pixel is accomplished by
taking the desired number of high order bits;
conversion to a larger number of bits per pixel is accomplished by
putting the small value into the high order bits, and replicating it as many 
times
as necessary to fill the lower order bits.
.PP
All of the drawing graphics functions clip the rectangle against the
source and destination bitmaps, so that only
pixels within the destination bitmap are changed, and none are changed
that would have come from areas outside the source bitmap.
.I Bitbltclip
takes a pointer to the first argument of a
.I bitblt
argument list, and modifies
.I dp
and
.I sr
so that no more clipping is needed.
.PP
.I Point
changes the value of the destination point
.I p
in bitmap
.I b
according to function code
.IR f .
The source is a pixel with
value
.IR v .
The constant
.B ONES
defined in
.B libg.h
is useful when the maximum pixel value is desired for the source.
.PP
.IR Segment ,
.IR circle ,
.IR disc ,
and
.I ellipse
all draw in bitmap
.I b
with function code
.I f
and a source pixel with value
.IR v.
.I Segment
draws a line segment in bitmap
.I b
from point
.I p
to
.IR q .
The segment is half-open:
.I p
is the first point of the segment and
.I q
is the first point beyond the segment,
so adjacent segments sharing endpoints abut.
.I Circle
draws a circle with radius
.I r
and center at point
.IR p .
.I Disc
is the same except that it fills the circle.
.I Ellipse
draws an ellipse with horizontal semi-axis
.I a
and vertical semi-axis
.IR b.
.PP
.I Border
draws, with function
.I f
in bitmap
.IR b ,
the rectangular outline with lines of width
.IR w ,
fitting just inside rectangle
.IR r .
.PP
.I Texture
draws, with function
.I f
in bitmap
.IR b ,
a texture using the
bitmap specified by
.IR t .
The texture bitmap is aligned on
.IR b 's
coordinate system so that (0,0) in both coordinate systems coincide,
and then
.I t
is replicated to form a tiling of
.IR b .
The tiling is clipped to rectangle
.I r
in
.IR b ,
and then transferred to
.I b
using the specified function.
.PP
.I String
draws the text characters given by the null-terminated string
.I s
into bitmap
.IR b ,
using font
.IR ft.
The upper left corner of the first character (i.e., a point
that is
.IB ft ->ascent
above the baseline) is placed at point
.IR p ,
and subsequent characters are placed on the same baseline, displaced to
the right by the previous character's
.BR width .
The individual characters are
.IR bitblt 'ed
into the destination, using drawing function
.IR f .
.I String
returns the point in the destination bitmap after the final character of
.I s
(or where the final character would be drawn, assuming no clipping;
the returned value might be outside the destination bitmap).
.PP
The bounding box for text to be drawn with
.I string
in font
.I ft
can be found with
.IR strsize ;
it returns the
.B max
point of the bounding box, assuming a
.B min
point of (0,0).
.I Strwidth
returns the
.IR x -component
of the
.B max
point.
.SH SEE ALSO
.IR graphics (3)
END OF bitblt.3
echo 'event.3' 1>&2
cat >'event.3' <<'END OF event.3'
.TH EVENT 3G
.SH NAME
event, einit, estart, eread, emouse, ekbd, ecanread, ecanmouse, ecankbd, 
ereshaped, getrect, menuhit, Event, Mouse, Menu \- graphics events
.SH SYNOPSIS
.nf
.PP
.B
#include        "libg.h"
.ta \w'\fLunsigned long 'u
.PP
.B
void    einit(ulong keys)
.PP
.B
unsigned long   event(Event *e)
.PP
.B
Mouse   emouse(void)
.PP
.B
int     ekbd(void)
.PP
.B
int     ecanmouse(void)
.PP
.B
int     ecankbd(void)
.PP
.B
unsigned long   estart(ulong key, int fd, int n)
.PP
.B
unsigned long   etimer(ulong key, int n)
.PP
.B
unsigned long   eread(ulong keys, Event *e)
.PP
.B
int     ecanread(ulong keys)
.PP
.B
void    ereshaped(Rectangle r)
.PP
.B
Rectangle       getrect(int but, Mouse *m)
.PP
.B
int     menuhit(int but, Mouse *m, Menu *menu)
.PP
.B
enum{
        Emouse = 1,
        Ekeyboard = 2,
}
.fi
.SH DESCRIPTION
These routines provide an interface to multiple sources of input.
To use them,
.I einit
must be called.
If the argument to
.I enit
has the Emouse and Ekeyboard bits set,
the mouse and keyboard events will be enabled;
in this case,
.IR xtbinit
(see
.IR graphics (3))
must have already been called.
The user must provide a function called
.IR ereshaped ,
which will be called whenever the window in which the process
is running has been reshaped; the argument will be the Rectangle
for the new window shape, including the border.
.PP
As characters are typed on the keyboard, they are read by the
event mechanism and put in a queue.
.I Ekbd
returns the next character from the queue, blocking until the
queue is non-empty.
The characters are read by the event mechanism from the keyboard
so they are available as soon as they are typed.
.PP
When the mouse moves or a mouse button is depressed or released,
a new mouse event is queued by the event mechanism.
.I Emouse
returns the next mouse event from the queue, blocking until the
queue is non-empty.
.I Emouse
returns a
.B Mouse
structure:
.IP
.EX
.ta 6n +\w'Point 'u
struct Mouse
{
        int     buttons;
        Point   xy;
};
.EE
.PP
.B Buttons
is a bit field;
.B buttons&1
is set when the left mouse button is depressed,
.B buttons&2
when the middle button is depressed,
and
.B buttons&4
when the right button is depressed.
The current mouse position is always returned in
.BR xy .
.PP
.I Ecankbd
and
.I ecanmouse
return non-zero when there are keyboard or mouse events to available
to be read.
.PP
.I Estart
can be used to register additional file descriptors.
It takes as arguments the file descriptor to register,
the maximum length of an event message on that descriptor,
and a key to be used in accessing the event.
The key must be a power of 2 and must not confilict with any previous keys.
If a zero key is given, one which is not used will be chosen and returned.
.B
Ekeyboard
and
.B Emouse
are the mouse and keyboard event keys.
.PP
.I Etimer
starts a timer with a period of n milliseconds (default 1 second).
Only one timer can be started.
Extra timer events are not queued and the timer channel has no associated data.
.PP
.I Eread
waits for the next event specified by the mask
.B keys
of event keys submitted to estart.
It fills in the appropriate field of the argument
.B Event
structure, which looks like:
.IP
.EX
struct Event
{
        int     kbdc;
        Mouse   mouse;
        int     n;
        uchar   data[EMAXMSG];
}
.EE
.PP
.B Data
is an array which is large enough to hold a plan 9 protocol message.
.I Eread
returns the key for the event which was chosen.
For example, if a mouse event was read,
.I Emouse
will be returned.
.PP
.I Event
waits for the next event of any kind.
The return is the same as for
.IR eread .
.PP
As described in
.IR graphics (3),
the graphics functions are buffered.
.IR Event ,
.IR eread ,
.IR emouse ,
and
.I ekbd
all cause a buffer flush unless there is an event of the
appropriate type ready to return.
.PP
.I Getrect
is used to prompt the user to sweep a rectangle.
It should be called with
.I m
holding the mouse event that triggered the
.I getrect
(or, if none, a
.B Mouse
with
.B buttons
set to 7).
It changes to the sweep cursor,
waits for the buttons to all go up,
and then waits for button number
.I but
to be depressed, marking the initial corner.
If another button is depressed instead,
.I getrect
returns a rectangle
with zero for both corners, after
waiting for all the buttons to be released.
Otherwise,
.I getrect
continually draws the swept rectangle
until the button is released again, and returns the swept rectangle.
The mouse structure pointed to by
.I m
will contain the final mouse event.
.PP
.I Menuhit
displays a menu and returns a seleced menu item number.
It should be called with
.I m
holding the mouse event that triggered the
.I menuhit .
A
.B Menu
is a structure:
.IP
.EX
struct Menu
{
        char    **item;
        char    *(*gen)(int);
        int     lasthit;
}
.EE
.PP
If
.B item
is nonzero, it should be a null-terminated array of the character strings
to be displayed as menu items.
Otherwise,
.B gen
should be a function that, given an item number, returns the character
string for that item, or zero if the number is past the end of the list.
Items are numbered starting at zero.
.I Menuhit
waits until
.I but
is released, and then returns the number of the selection,
or \(mi1 for no selection.
The
.I m
argument is filled in with the final mouse event.
.SH "SEE ALSO"
.IR graphics (3)
END OF event.3
echo 'graphics.3' 1>&2
cat >'graphics.3' <<'END OF graphics.3'
.TH GRAPHICS 3G
.SH NAME
Point, Rectangle, Bitmap, Font, Fontchar, Cursor, xtbinit, bclose, berror, 
bscreenrect, bflush, cursorswitch, cursorset, getfont \- graphics
.SH SYNOPSIS
.nf
.PP
.ft L
#include "libg.h"
.ft P
.PP
.ta \w'\fLextern Bitmap 'u
.B
void    xtbinit(void (*errfun)(char *), char *font, int *pargc, char **argv)
.PP
.B
void    bclose(void)
.PP
.B
void    berror(char *msg)
.PP
.B
Rectangle       bscreenrect(void)
.PP
.B
void    bflush(void)
.PP
.B
void    cursorswitch(Cursor *curs)
.PP
.B
void    cursorset(Point p)
.PP
.B
Font    getfont(char *name)
.PP
.B
extern Bitmap   screen
.PP
.B
extern Font     *font
.fi
.SH DESCRIPTION
A
.B Point
is a location in a bitmap
(see below),
such as the screen, and is defined as:
.IP
.EX
.ta 6n
typedef
struct Point {
        int x;
        int y;
} Point;
.EE
.PP
The coordinate system has
.I x
increasing to the right and
.I y
increasing down.
.PP
A
.B Rectangle
is a rectangular area in a bitmap.
.IP
.EX
.ta 6n
typedef
struct Rectangle {
        Point min;      /* upper left */
        Point max;      /* lower right */
} Rectangle;
.EE
.PP
By definition,
.B min.x <= max.x
and
.BR "min.y <= max.y" .
By convention, the right (maximum
.IR x )
and bottom (maximum
.IR y )
edges are
excluded from the represented rectangle, so abutting rectangles have no
points in common.
Thus,
.B max
contains the coordinates of the first point beyond the rectangle.
.PP
A 
.B Bitmap
holds a rectangular image.
.IP
.EX
.ta 6n +\w'Rectangle 'u +\w'ldepth;     'u
typedef
struct Bitmap {
        Rectangle       r;      /* rectangle in data area, local coords */
        int     ldepth; /* log base 2 of number of bits per pixel */
        int     id;     /* id as known in /dev/bitblt */
        Bitmap *        cache;  /* zero; distinguishes bitmap from layer */
} Bitmap;
.EE
.PP
.B R.min
is the location in the bitmap
of the upper-leftmost point in the image.
There are
.if t .I 2\u\s8ldepth\s10\d
.if n 2^ldepth
contiguous bits for each pixel of the image;
the bits form a binary number giving the pixel value.
.PP
A
.I Font
is  a character set, stored as a single
bitmap
with the characters
placed side-by-side on a common baseline.
It is described by the following data structures.
.IP
.EX
.ta 6n +\w'unsigned char 'u +\w'bottom;   'u
typedef
struct Fontchar {
        short   x;      /* left edge of bits */
        unsigned char   top;    /* first non-zero scan-line */
        unsigned char   bottom; /* last non-zero scan-line */
        char    left;   /* offset of baseline */
        uchar   width;  /* width of baseline */
} Fontchar;

typedef
struct Font {
        short   n;      /* number of chars in font */
        char    height; /* height of bitmap */
        char    ascent; /* top of bitmap to baseline */
        Fontchar        *info;  /* n+1 Fontchars */
        int     id;     /* id as known in /dev/bitblt */
}Font;
.EE
.PP
The bitmap fills the rectangle
\fL(0, 0, \fIw\fP, height)\fR,
where
.I w
is the sum of
.L width
for all characters.
The pixels to be displayed for character
.I c
are in the rectangle
\fL(\fIi\fP->x, \fIi\fP->top, (\fIi\fP+1)->x, \%\fIi\fP->bottom)\fR
where
.I i
is
.B
&font->info[\fIc\fP]\fR.
When a character is diplayed in a string,
.L left
blank columns should appear to the left of the character rectangle,
and the next character of a string should start
.L width
pixels to the right of where the leading blank columns start.
The baseline of the characters is
.L ascent
rows down from the top of the font bitmap.
The
.L info
array should have
.BR n +1
elements, for character numbers 0 to
.BR n \(mi1 ,
and an additional entry so that the bitmap width of the last character
can be calculated.
.PP
A
.I Cursor
is put in this structure:
.IP
.EX
.ta 6n +\w'unsigned char 'u
struct  Cursor
{
        Point   offset;
        unsigned char   clr[2*16];
        unsigned char   set[2*16];
};
.EE
.PP
The arrays are to be arranged in rows, two characters per row, to give 16 rows
of 16 bits each.
A cursor is displayed on the screen by adding
.B offset
to the current mouse position, using
.B clr
as a mask to zero the pixels where
.B clr
is 1, and then setting all pixels to ones where
.B set
is one.
.PP
The function
.I xtbinit
should be called before using any graphics operations.
The
.I errfun
argument is a function that will be called with an error message
argument when the graphics functions detect an error;
such an error function should not return.
A zero for the
.I errfun
argument means use
.IR berror ,
which prints the message and exits.
The
.I class
argument is the name of the class of X application, or zero for to
use the capitalized version of the program name.
The
.I pargc
and
.I argv
arguments should be a pointer to the main program's
.I argc
and
.IR argv ;
any standard toolkit options in the argument list will be used
to initialize the window's options, and after
.I xtbinit
returns, those options will have been removed fromthe argument list.
.B Xtbinit
sets up the global
.I screen
to be a bitmap describing the area of the screen that the program
can use.
.I Xtbinit
also initializes the global default
.IR font .
.PP
.I Bclose
releases the resources allocated by
.I xtbinit
and the other graphics functions.
It usually isn't necessary, since the resources will be released
on program exit.
.PP
The
.IB screen .r
field is not guaranteed to be always accurate; the
.I bscreenrect
function returns the current size
(see
.IR event (3)
to see how to get reshape notification).
.PP
The mouse cursor is always displayed.
The initial cursor is an arrow.
.I Cursorswitch
causes the argument cursor to be displayed instead.
A zero argument causes a switch back to the arrow cursor.
.I Cursorset
moves the mouse cursor to position
.I p ,
provided (if in a window) that the requesting program is
executing in the current window and the mouse is within
the window boundaries; otherwise
.I cursorset
is a no-op.
.PP
The graphics functions described in
.IR bitblt (3)
and
.IR balloc (3)
are implemented by writing commands to the X server;
the writes are buffered, so the functions may not take effect immediately.
.I Bflush
flushes the buffer, doing all pending graphics operations.
.I Xtbinit
arranges that
.I bflush
will be called on exit,
and the following graphics functions all cause a flush:
.IR balloc ,
.IR bfree ,
.IR bscreenrect ,
.IR cursorset ,
.IR cursorswitch ,
.IR ecankbd ,
.IR ecanmouse ,
.IR ekbd ,
.IR emouse ,
.IR event ,
.IR rdbitmap ,
and
.IR wrbitmap .
.PP
.I Getfont
attempts to load the X font given by
.IR name ;
it returns a pointer to a
.B Font
struct if it succeeds, zero otherwise.
.SH "SEE ALSO"
.IR add (3),
.IR balloc (3),
.IR bitblt (3),
.IR event (3)
END OF graphics.3
echo 'rgbpix.3' 1>&2
cat >'rgbpix.3' <<'END OF rgbpix.3'
.TH RGBPIX 3G
.SH NAME
RGB, rgbpix, rdcolmap, wrcolmap
.SH SYNOPSIS
.nf
.PP
.ft L
#include "libg.h"
.ft P
.PP
.ta \w'\fLunsigned long 'u
.B
unsigned long   rgbpix(Bitmap *b, RGB rgb)
.PP
.B
void    rdcolmap(Bitmap *b, RGB *map)
.PP
.B
void    wrcolmap(Bitmap *b, RGB *map)
.fi
.SH DESCRIPTION
Colors are described by the red, green, and blue
light intensities, in an
.B RGB
datum:
.IP
.EX
.ta 6n
typedef
struct RGB {
        unsigned long red;
        unsigned long green;
        unsigned long blue;
} RGB;
.EE
.PP
Zero intensity means there is no component of the given color;
hence, black is represented by zero in all three positions and
white has the maximum unsigned long value in all three positions.
.PP
Some of the graphics functions, such as
.I point
(see
.IR bitblt (3)),
take a
.I pixel value
argument, which is a single unsigned long.
For a given bitmap,
.I rgbpix
returns the pixel value with a color closest to
the color represented by the
.I rgb
argument.
.PP
There is a
.I colormap
associated with each Bitmap.  A colormap is an array of
.BR RGB s,
of length
.if t 2\u\s82\u\s6\fIldepth\fP\d\d\s10,
.if n 2^(2^\fIldepth\fP),
giving the colors for pixels 0, 1, 2, etc.
.PP
.I Rdcolormap
reads the colormap for the given bitmap into the provided
.IR map ,
which must have enough space to hold it.
.I Wrcolormap
associates the given colormap with the given bitmap, if possible.
(The hardware might not allow this.)
.SH BUGS
These functions only work for the screen bitmap.
This interface will have to be refined for screens with
ldepth > 3.
.SH "SEE ALSO"
.IR graphics (3)
END OF rgbpix.3
END OF libXg.bundle



----- End forwarded message -----

-- 
 Mike Bianchi
 Foveal Systems

 973 822-2085   call to arrange Fax

 address@hidden
 http://www.AutoAuditorium.com
 http://www.FovealMounts.com




reply via email to

[Prev in Thread] Current Thread [Next in Thread]