[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Groff] pic animation,
M Bianchi <=