13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
3*7dd7cddfSDavid du Colombier #include <draw.h>
4*7dd7cddfSDavid du Colombier #include <cursor.h>
5*7dd7cddfSDavid du Colombier #include <event.h>
63e12c5d1SDavid du Colombier #include <bio.h>
73e12c5d1SDavid du Colombier #include "proof.h"
83e12c5d1SDavid du Colombier
93e12c5d1SDavid du Colombier int res;
103e12c5d1SDavid du Colombier int hpos;
113e12c5d1SDavid du Colombier int vpos;
123e12c5d1SDavid du Colombier int DIV = 11;
133e12c5d1SDavid du Colombier
143e12c5d1SDavid du Colombier Point offset;
153e12c5d1SDavid du Colombier Point xyoffset = { 0,0 };
163e12c5d1SDavid du Colombier
173e12c5d1SDavid du Colombier Rectangle view[MAXVIEW];
183e12c5d1SDavid du Colombier Rectangle bound[MAXVIEW]; /* extreme points */
193e12c5d1SDavid du Colombier int nview = 1;
203e12c5d1SDavid du Colombier
213e12c5d1SDavid du Colombier int lastp; /* last page number we were on */
223e12c5d1SDavid du Colombier
233e12c5d1SDavid du Colombier #define NPAGENUMS 200
243e12c5d1SDavid du Colombier struct pagenum {
253e12c5d1SDavid du Colombier int num;
263e12c5d1SDavid du Colombier long adr;
273e12c5d1SDavid du Colombier } pagenums[NPAGENUMS];
283e12c5d1SDavid du Colombier int npagenums;
293e12c5d1SDavid du Colombier
303e12c5d1SDavid du Colombier int curfont, cursize;
313e12c5d1SDavid du Colombier
323e12c5d1SDavid du Colombier char *getcmdstr(void);
333e12c5d1SDavid du Colombier
343e12c5d1SDavid du Colombier static void initpage(void);
353e12c5d1SDavid du Colombier static void view_setup(int);
363e12c5d1SDavid du Colombier static Point scale(Point);
373e12c5d1SDavid du Colombier static void clearview(Rectangle);
383e12c5d1SDavid du Colombier static int addpage(int);
39*7dd7cddfSDavid du Colombier static void spline(Image *, int, Point *);
403e12c5d1SDavid du Colombier static int skipto(int, int);
413e12c5d1SDavid du Colombier static void wiggly(int);
423e12c5d1SDavid du Colombier static void devcntrl(void);
433e12c5d1SDavid du Colombier static void eatline(void);
443e12c5d1SDavid du Colombier static int getn(void);
453e12c5d1SDavid du Colombier static int botpage(int);
463e12c5d1SDavid du Colombier static void getstr(char *);
473e12c5d1SDavid du Colombier static void getutf(char *);
483e12c5d1SDavid du Colombier
49*7dd7cddfSDavid du Colombier #define Do screen->r.min
50*7dd7cddfSDavid du Colombier #define Dc screen->r.max
513e12c5d1SDavid du Colombier
523e12c5d1SDavid du Colombier /* declarations and definitions of font stuff are in font.c and main.c */
533e12c5d1SDavid du Colombier
543e12c5d1SDavid du Colombier static void
initpage(void)553e12c5d1SDavid du Colombier initpage(void)
563e12c5d1SDavid du Colombier {
573e12c5d1SDavid du Colombier int i;
583e12c5d1SDavid du Colombier
593e12c5d1SDavid du Colombier view_setup(nview);
603e12c5d1SDavid du Colombier for (i = 0; i < nview-1; i++)
61*7dd7cddfSDavid du Colombier draw(screen, view[i], screen, nil, view[i+1].min);
623e12c5d1SDavid du Colombier clearview(view[nview-1]);
633e12c5d1SDavid du Colombier offset = view[nview-1].min;
643e12c5d1SDavid du Colombier vpos = 0;
653e12c5d1SDavid du Colombier }
663e12c5d1SDavid du Colombier
673e12c5d1SDavid du Colombier static void
view_setup(int n)683e12c5d1SDavid du Colombier view_setup(int n)
693e12c5d1SDavid du Colombier {
703e12c5d1SDavid du Colombier int i, j, v, dx, dy, r, c;
713e12c5d1SDavid du Colombier
723e12c5d1SDavid du Colombier switch (n) {
733e12c5d1SDavid du Colombier case 1: r = 1; c = 1; break;
743e12c5d1SDavid du Colombier case 2: r = 1; c = 2; break;
753e12c5d1SDavid du Colombier case 3: r = 1; c = 3; break;
763e12c5d1SDavid du Colombier case 4: r = 2; c = 2; break;
773e12c5d1SDavid du Colombier case 5: case 6: r = 2; c = 3; break;
783e12c5d1SDavid du Colombier case 7: case 8: case 9: r = 3; c = 3; break;
793e12c5d1SDavid du Colombier default: r = (n+2)/3; c = 3; break; /* finking out */
803e12c5d1SDavid du Colombier }
813e12c5d1SDavid du Colombier dx = (Dc.x - Do.x) / c;
823e12c5d1SDavid du Colombier dy = (Dc.y - Do.y) / r;
833e12c5d1SDavid du Colombier v = 0;
843e12c5d1SDavid du Colombier for (i = 0; i < r && v < n; i++)
853e12c5d1SDavid du Colombier for (j = 0; j < c && v < n; j++) {
86*7dd7cddfSDavid du Colombier view[v] = screen->r;
873e12c5d1SDavid du Colombier view[v].min.x = Do.x + j * dx;
883e12c5d1SDavid du Colombier view[v].max.x = Do.x + (j+1) * dx;
893e12c5d1SDavid du Colombier view[v].min.y = Do.y + i * dy;
903e12c5d1SDavid du Colombier view[v].max.y = Do.y + (i+1) * dy;
913e12c5d1SDavid du Colombier v++;
923e12c5d1SDavid du Colombier }
933e12c5d1SDavid du Colombier }
943e12c5d1SDavid du Colombier
953e12c5d1SDavid du Colombier static void
clearview(Rectangle r)963e12c5d1SDavid du Colombier clearview(Rectangle r)
973e12c5d1SDavid du Colombier {
98*7dd7cddfSDavid du Colombier draw(screen, r, display->white, nil, r.min);
993e12c5d1SDavid du Colombier }
1003e12c5d1SDavid du Colombier
101*7dd7cddfSDavid du Colombier int resized;
eresized(int new)102*7dd7cddfSDavid du Colombier void eresized(int new)
1033e12c5d1SDavid du Colombier {
104*7dd7cddfSDavid du Colombier /* this is called if we are resized */
105*7dd7cddfSDavid du Colombier if(new && getwindow(display, Refnone) < 0)
106*7dd7cddfSDavid du Colombier drawerror(display, "can't reattach to window");
1073e12c5d1SDavid du Colombier initpage();
108*7dd7cddfSDavid du Colombier resized = 1;
1093e12c5d1SDavid du Colombier }
1103e12c5d1SDavid du Colombier
1113e12c5d1SDavid du Colombier static Point
scale(Point p)1123e12c5d1SDavid du Colombier scale(Point p)
1133e12c5d1SDavid du Colombier {
1143e12c5d1SDavid du Colombier p.x /= DIV;
1153e12c5d1SDavid du Colombier p.y /= DIV;
116*7dd7cddfSDavid du Colombier return addpt(xyoffset, addpt(offset,p));
1173e12c5d1SDavid du Colombier }
1183e12c5d1SDavid du Colombier
1193e12c5d1SDavid du Colombier static int
addpage(int n)1203e12c5d1SDavid du Colombier addpage(int n)
1213e12c5d1SDavid du Colombier {
1223e12c5d1SDavid du Colombier int i;
1233e12c5d1SDavid du Colombier
1243e12c5d1SDavid du Colombier for (i = 0; i < npagenums; i++)
1253e12c5d1SDavid du Colombier if (n == pagenums[i].num)
1263e12c5d1SDavid du Colombier return i;
1273e12c5d1SDavid du Colombier if (npagenums < NPAGENUMS-1) {
1283e12c5d1SDavid du Colombier pagenums[npagenums].num = n;
129*7dd7cddfSDavid du Colombier pagenums[npagenums].adr = offsetc();
1303e12c5d1SDavid du Colombier npagenums++;
1313e12c5d1SDavid du Colombier }
1323e12c5d1SDavid du Colombier return npagenums;
1333e12c5d1SDavid du Colombier }
1343e12c5d1SDavid du Colombier
1353e12c5d1SDavid du Colombier void
readpage(void)1363e12c5d1SDavid du Colombier readpage(void)
1373e12c5d1SDavid du Colombier {
138*7dd7cddfSDavid du Colombier int c, i, a, alpha, phi;
1393e12c5d1SDavid du Colombier static int first = 0;
1403e12c5d1SDavid du Colombier int m, n, gonow = 1;
141219b2ee8SDavid du Colombier Rune r[32], t;
1423e12c5d1SDavid du Colombier Point p,q,qq;
1433e12c5d1SDavid du Colombier
144*7dd7cddfSDavid du Colombier offset = screen->clipr.min;
145*7dd7cddfSDavid du Colombier esetcursor(&deadmouse);
1463e12c5d1SDavid du Colombier while (gonow)
1473e12c5d1SDavid du Colombier {
148*7dd7cddfSDavid du Colombier c = getc();
1493e12c5d1SDavid du Colombier switch (c)
1503e12c5d1SDavid du Colombier {
1513e12c5d1SDavid du Colombier case -1:
152*7dd7cddfSDavid du Colombier esetcursor(0);
1533e12c5d1SDavid du Colombier if (botpage(lastp+1)) {
1543e12c5d1SDavid du Colombier initpage();
1553e12c5d1SDavid du Colombier break;
1563e12c5d1SDavid du Colombier }
1573e12c5d1SDavid du Colombier exits(0);
1583e12c5d1SDavid du Colombier case 'p': /* new page */
1593e12c5d1SDavid du Colombier lastp = getn();
1603e12c5d1SDavid du Colombier addpage(lastp);
1613e12c5d1SDavid du Colombier if (first++ > 0) {
162*7dd7cddfSDavid du Colombier esetcursor(0);
1633e12c5d1SDavid du Colombier botpage(lastp);
164*7dd7cddfSDavid du Colombier esetcursor(&deadmouse);
1653e12c5d1SDavid du Colombier }
1663e12c5d1SDavid du Colombier initpage();
1673e12c5d1SDavid du Colombier break;
1683e12c5d1SDavid du Colombier case '\n': /* when input is text */
1693e12c5d1SDavid du Colombier case ' ':
1703e12c5d1SDavid du Colombier case 0: /* occasional noise creeps in */
1713e12c5d1SDavid du Colombier break;
1723e12c5d1SDavid du Colombier case '0': case '1': case '2': case '3': case '4':
1733e12c5d1SDavid du Colombier case '5': case '6': case '7': case '8': case '9':
1743e12c5d1SDavid du Colombier /* two motion digits plus a character */
175*7dd7cddfSDavid du Colombier hpos += (c-'0')*10 + getc()-'0';
1763e12c5d1SDavid du Colombier
1773e12c5d1SDavid du Colombier /* FALLS THROUGH */
1783e12c5d1SDavid du Colombier case 'c': /* single ascii character */
179*7dd7cddfSDavid du Colombier r[0] = getrune();
180219b2ee8SDavid du Colombier r[1] = 0;
181219b2ee8SDavid du Colombier dochar(r);
1823e12c5d1SDavid du Colombier break;
1833e12c5d1SDavid du Colombier
1843e12c5d1SDavid du Colombier case 'C':
185219b2ee8SDavid du Colombier for(i=0; ; i++){
186*7dd7cddfSDavid du Colombier t = getrune();
187219b2ee8SDavid du Colombier if(isspace(t))
1883e12c5d1SDavid du Colombier break;
189219b2ee8SDavid du Colombier r[i] = t;
190219b2ee8SDavid du Colombier }
191219b2ee8SDavid du Colombier r[i] = 0;
192219b2ee8SDavid du Colombier dochar(r);
193219b2ee8SDavid du Colombier break;
194219b2ee8SDavid du Colombier
1953e12c5d1SDavid du Colombier case 'N':
196219b2ee8SDavid du Colombier r[0] = getn();
197219b2ee8SDavid du Colombier r[1] = 0;
198219b2ee8SDavid du Colombier dochar(r);
1993e12c5d1SDavid du Colombier break;
200219b2ee8SDavid du Colombier
2013e12c5d1SDavid du Colombier case 'D': /* draw function */
202*7dd7cddfSDavid du Colombier switch (getc())
2033e12c5d1SDavid du Colombier {
2043e12c5d1SDavid du Colombier case 'l': /* draw a line */
2053e12c5d1SDavid du Colombier n = getn();
2063e12c5d1SDavid du Colombier m = getn();
2073e12c5d1SDavid du Colombier p = Pt(hpos,vpos);
208*7dd7cddfSDavid du Colombier q = addpt(p, Pt(n,m));
2093e12c5d1SDavid du Colombier hpos += n;
2103e12c5d1SDavid du Colombier vpos += m;
211*7dd7cddfSDavid du Colombier line(screen, scale(p), scale(q), 0, 0, 0, display->black, ZP);
2123e12c5d1SDavid du Colombier break;
2133e12c5d1SDavid du Colombier case 'c': /* circle */
2143e12c5d1SDavid du Colombier /*nop*/
2153e12c5d1SDavid du Colombier m = getn()/2;
2163e12c5d1SDavid du Colombier p = Pt(hpos+m,vpos);
2173e12c5d1SDavid du Colombier hpos += 2*m;
218*7dd7cddfSDavid du Colombier ellipse(screen, scale(p), m/DIV, m/DIV, 0, display->black, ZP);
2193e12c5d1SDavid du Colombier /* p=currentpt; p.x+=dmap(m/2);circle bp,p,a,ONES,Mode*/
2203e12c5d1SDavid du Colombier break;
2213e12c5d1SDavid du Colombier case 'e': /* ellipse */
2223e12c5d1SDavid du Colombier /*nop*/
2233e12c5d1SDavid du Colombier m = getn()/2;
2243e12c5d1SDavid du Colombier n = getn()/2;
2253e12c5d1SDavid du Colombier p = Pt(hpos+m,vpos);
2263e12c5d1SDavid du Colombier hpos += 2*m;
227*7dd7cddfSDavid du Colombier ellipse(screen, scale(p), m/DIV, n/DIV, 0, display->black, ZP);
2283e12c5d1SDavid du Colombier break;
2293e12c5d1SDavid du Colombier case 'a': /* arc */
2303e12c5d1SDavid du Colombier p = scale(Pt(hpos,vpos));
2313e12c5d1SDavid du Colombier n = getn();
2323e12c5d1SDavid du Colombier m = getn();
2333e12c5d1SDavid du Colombier hpos += n;
2343e12c5d1SDavid du Colombier vpos += m;
2353e12c5d1SDavid du Colombier q = scale(Pt(hpos,vpos));
2363e12c5d1SDavid du Colombier n = getn();
2373e12c5d1SDavid du Colombier m = getn();
2383e12c5d1SDavid du Colombier hpos += n;
2393e12c5d1SDavid du Colombier vpos += m;
2403e12c5d1SDavid du Colombier qq = scale(Pt(hpos,vpos));
241*7dd7cddfSDavid du Colombier /*
242*7dd7cddfSDavid du Colombier * tricky: convert from 3-point clockwise to
243*7dd7cddfSDavid du Colombier * center, angle1, delta-angle counterclockwise.
244*7dd7cddfSDavid du Colombier */
245*7dd7cddfSDavid du Colombier a = hypot(qq.x-q.x, qq.y-q.y);
246*7dd7cddfSDavid du Colombier phi = atan2(q.y-p.y, p.x-q.x)*180./PI;
247*7dd7cddfSDavid du Colombier alpha = atan2(q.y-qq.y, qq.x-q.x)*180./PI - phi;
248*7dd7cddfSDavid du Colombier if(alpha < 0)
249*7dd7cddfSDavid du Colombier alpha += 360;
250*7dd7cddfSDavid du Colombier arc(screen, q, a, a, 0, display->black, ZP, phi, alpha);
2513e12c5d1SDavid du Colombier break;
2523e12c5d1SDavid du Colombier case '~': /* wiggly line */
2533e12c5d1SDavid du Colombier wiggly(0);
2543e12c5d1SDavid du Colombier break;
2553e12c5d1SDavid du Colombier default:
2563e12c5d1SDavid du Colombier break;
2573e12c5d1SDavid du Colombier }
2583e12c5d1SDavid du Colombier eatline();
2593e12c5d1SDavid du Colombier break;
2603e12c5d1SDavid du Colombier case 's':
2613e12c5d1SDavid du Colombier n = getn(); /* ignore fractional sizes */
2623e12c5d1SDavid du Colombier if (cursize == n)
2633e12c5d1SDavid du Colombier break;
2643e12c5d1SDavid du Colombier cursize = n;
2653e12c5d1SDavid du Colombier if (cursize >= NFONT)
2663e12c5d1SDavid du Colombier cursize = NFONT-1;
2673e12c5d1SDavid du Colombier break;
2683e12c5d1SDavid du Colombier case 'f':
2693e12c5d1SDavid du Colombier curfont = getn();
2703e12c5d1SDavid du Colombier break;
2713e12c5d1SDavid du Colombier case 'H': /* absolute horizontal motion */
2723e12c5d1SDavid du Colombier hpos = getn();
2733e12c5d1SDavid du Colombier break;
2743e12c5d1SDavid du Colombier case 'h': /* relative horizontal motion */
2753e12c5d1SDavid du Colombier hpos += getn();
2763e12c5d1SDavid du Colombier break;
2773e12c5d1SDavid du Colombier case 'w': /* word space */
2783e12c5d1SDavid du Colombier break;
2793e12c5d1SDavid du Colombier case 'V':
2803e12c5d1SDavid du Colombier vpos = getn();
2813e12c5d1SDavid du Colombier break;
2823e12c5d1SDavid du Colombier case 'v':
2833e12c5d1SDavid du Colombier vpos += getn();
2843e12c5d1SDavid du Colombier break;
2853e12c5d1SDavid du Colombier case '#': /* comment */
2863e12c5d1SDavid du Colombier case 'n': /* end of line */
2873e12c5d1SDavid du Colombier eatline();
2883e12c5d1SDavid du Colombier break;
2893e12c5d1SDavid du Colombier case 'x': /* device control */
2903e12c5d1SDavid du Colombier devcntrl();
2913e12c5d1SDavid du Colombier break;
2923e12c5d1SDavid du Colombier default:
293*7dd7cddfSDavid du Colombier fprint(2, "unknown input character %o %c at offset %lud\n", c, c, offsetc());
2943e12c5d1SDavid du Colombier exits("bad char");
2953e12c5d1SDavid du Colombier }
2963e12c5d1SDavid du Colombier }
297*7dd7cddfSDavid du Colombier esetcursor(0);
2983e12c5d1SDavid du Colombier }
2993e12c5d1SDavid du Colombier
3003e12c5d1SDavid du Colombier static void
spline(Image * b,int n,Point * pp)301*7dd7cddfSDavid du Colombier spline(Image *b, int n, Point *pp)
3023e12c5d1SDavid du Colombier {
3033e12c5d1SDavid du Colombier long w, t1, t2, t3, fac=1000;
3043e12c5d1SDavid du Colombier int i, j, steps=10;
3053e12c5d1SDavid du Colombier Point p, q;
3063e12c5d1SDavid du Colombier
3073e12c5d1SDavid du Colombier for (i = n; i > 0; i--)
3083e12c5d1SDavid du Colombier pp[i] = pp[i-1];
3093e12c5d1SDavid du Colombier pp[n+1] = pp[n];
3103e12c5d1SDavid du Colombier n += 2;
3113e12c5d1SDavid du Colombier p = pp[0];
3123e12c5d1SDavid du Colombier for(i = 0; i < n-2; i++)
3133e12c5d1SDavid du Colombier {
3143e12c5d1SDavid du Colombier for(j = 0; j < steps; j++)
3153e12c5d1SDavid du Colombier {
3163e12c5d1SDavid du Colombier w = fac * j / steps;
3173e12c5d1SDavid du Colombier t1 = w * w / (2 * fac);
3183e12c5d1SDavid du Colombier w = w - fac/2;
3193e12c5d1SDavid du Colombier t2 = 3*fac/4 - w * w / fac;
3203e12c5d1SDavid du Colombier w = w - fac/2;
3213e12c5d1SDavid du Colombier t3 = w * w / (2*fac);
3223e12c5d1SDavid du Colombier q.x = (t1*pp[i+2].x + t2*pp[i+1].x +
3233e12c5d1SDavid du Colombier t3*pp[i].x + fac/2) / fac;
3243e12c5d1SDavid du Colombier q.y = (t1*pp[i+2].y + t2*pp[i+1].y +
3253e12c5d1SDavid du Colombier t3*pp[i].y + fac/2) / fac;
326*7dd7cddfSDavid du Colombier line(b, p, q, 0, 0, 0, display->black, ZP);
3273e12c5d1SDavid du Colombier p = q;
3283e12c5d1SDavid du Colombier }
3293e12c5d1SDavid du Colombier }
3303e12c5d1SDavid du Colombier }
3313e12c5d1SDavid du Colombier
3323e12c5d1SDavid du Colombier /* Have to parse skipped pages, to find out what fonts are loaded. */
3333e12c5d1SDavid du Colombier static int
skipto(int gotop,int curp)3343e12c5d1SDavid du Colombier skipto(int gotop, int curp)
3353e12c5d1SDavid du Colombier {
3363e12c5d1SDavid du Colombier char *p;
3373e12c5d1SDavid du Colombier int i;
3383e12c5d1SDavid du Colombier
3393e12c5d1SDavid du Colombier if (gotop == curp)
3403e12c5d1SDavid du Colombier return 1;
3413e12c5d1SDavid du Colombier for (i = 0; i < npagenums; i++)
3423e12c5d1SDavid du Colombier if (pagenums[i].num == gotop) {
343*7dd7cddfSDavid du Colombier if (seekc(pagenums[i].adr) == Beof) {
3443e12c5d1SDavid du Colombier fprint(2, "can't rewind input\n");
3453e12c5d1SDavid du Colombier return 0;
3463e12c5d1SDavid du Colombier }
3473e12c5d1SDavid du Colombier return 1;
3483e12c5d1SDavid du Colombier }
3493e12c5d1SDavid du Colombier if (gotop <= curp) {
3503e12c5d1SDavid du Colombier restart:
351*7dd7cddfSDavid du Colombier if (seekc(0) == Beof) {
3523e12c5d1SDavid du Colombier fprint(2, "can't rewind input\n");
3533e12c5d1SDavid du Colombier return 0;
3543e12c5d1SDavid du Colombier }
3553e12c5d1SDavid du Colombier }
3563e12c5d1SDavid du Colombier for(;;){
357*7dd7cddfSDavid du Colombier p = rdlinec();
3583e12c5d1SDavid du Colombier if (p == 0) {
3593e12c5d1SDavid du Colombier if(gotop>curp){
3603e12c5d1SDavid du Colombier gotop = curp;
3613e12c5d1SDavid du Colombier goto restart;
3623e12c5d1SDavid du Colombier }
3633e12c5d1SDavid du Colombier return 0;
3643e12c5d1SDavid du Colombier } else if (*p == 'p') {
3653e12c5d1SDavid du Colombier lastp = curp = atoi(p+1);
3663e12c5d1SDavid du Colombier addpage(lastp); /* maybe 1 too high */
3673e12c5d1SDavid du Colombier if (curp>=gotop)
3683e12c5d1SDavid du Colombier return 1;
3693e12c5d1SDavid du Colombier }
3703e12c5d1SDavid du Colombier }
3713e12c5d1SDavid du Colombier }
3723e12c5d1SDavid du Colombier
3733e12c5d1SDavid du Colombier static void
wiggly(int skip)3743e12c5d1SDavid du Colombier wiggly(int skip)
3753e12c5d1SDavid du Colombier {
3763e12c5d1SDavid du Colombier Point p[300];
3773e12c5d1SDavid du Colombier int c,i,n;
378*7dd7cddfSDavid du Colombier for (n = 1; (c = getc()) != '\n' && c>=0; n++) {
379*7dd7cddfSDavid du Colombier ungetc();
3803e12c5d1SDavid du Colombier p[n].x = getn();
3813e12c5d1SDavid du Colombier p[n].y = getn();
3823e12c5d1SDavid du Colombier }
3833e12c5d1SDavid du Colombier p[0] = Pt(hpos, vpos);
3843e12c5d1SDavid du Colombier for (i = 1; i < n; i++)
385*7dd7cddfSDavid du Colombier p[i] = addpt(p[i],p[i-1]);
3863e12c5d1SDavid du Colombier hpos = p[n-1].x;
3873e12c5d1SDavid du Colombier vpos = p[n-1].y;
3883e12c5d1SDavid du Colombier for (i = 0; i < n; i++)
3893e12c5d1SDavid du Colombier p[i] = scale(p[i]);
3903e12c5d1SDavid du Colombier if (!skip)
391*7dd7cddfSDavid du Colombier spline(screen,n,p);
3923e12c5d1SDavid du Colombier }
3933e12c5d1SDavid du Colombier
3943e12c5d1SDavid du Colombier static void
devcntrl(void)3953e12c5d1SDavid du Colombier devcntrl(void) /* interpret device control functions */
3963e12c5d1SDavid du Colombier {
3973e12c5d1SDavid du Colombier char str[80];
3983e12c5d1SDavid du Colombier int n;
3993e12c5d1SDavid du Colombier
4003e12c5d1SDavid du Colombier getstr(str);
4013e12c5d1SDavid du Colombier switch (str[0]) { /* crude for now */
4023e12c5d1SDavid du Colombier case 'i': /* initialize */
4033e12c5d1SDavid du Colombier break;
4043e12c5d1SDavid du Colombier case 'T': /* device name */
4053e12c5d1SDavid du Colombier getstr(devname);
4063e12c5d1SDavid du Colombier break;
4073e12c5d1SDavid du Colombier case 't': /* trailer */
4083e12c5d1SDavid du Colombier break;
4093e12c5d1SDavid du Colombier case 'p': /* pause -- can restart */
4103e12c5d1SDavid du Colombier break;
4113e12c5d1SDavid du Colombier case 's': /* stop */
4123e12c5d1SDavid du Colombier break;
4133e12c5d1SDavid du Colombier case 'r': /* resolution assumed when prepared */
4143e12c5d1SDavid du Colombier res=getn();
4153e12c5d1SDavid du Colombier DIV = floor(.5 + res/(100.0*mag));
4163e12c5d1SDavid du Colombier if (DIV < 1)
4173e12c5d1SDavid du Colombier DIV = 1;
4183e12c5d1SDavid du Colombier mag = res/(100.0*DIV); /* adjust mag according to DIV coarseness */
4193e12c5d1SDavid du Colombier break;
4203e12c5d1SDavid du Colombier case 'f': /* font used */
4213e12c5d1SDavid du Colombier n = getn();
4223e12c5d1SDavid du Colombier getstr(str);
4233e12c5d1SDavid du Colombier loadfontname(n, str);
4243e12c5d1SDavid du Colombier break;
4253e12c5d1SDavid du Colombier /* these don't belong here... */
4263e12c5d1SDavid du Colombier case 'H': /* char height */
4273e12c5d1SDavid du Colombier break;
4283e12c5d1SDavid du Colombier case 'S': /* slant */
4293e12c5d1SDavid du Colombier break;
4303e12c5d1SDavid du Colombier case 'X':
4313e12c5d1SDavid du Colombier break;
4323e12c5d1SDavid du Colombier }
4333e12c5d1SDavid du Colombier eatline();
4343e12c5d1SDavid du Colombier }
4353e12c5d1SDavid du Colombier
436219b2ee8SDavid du Colombier int
isspace(int c)437219b2ee8SDavid du Colombier isspace(int c)
438219b2ee8SDavid du Colombier {
439219b2ee8SDavid du Colombier return c==' ' || c=='\t' || c=='\n';
440219b2ee8SDavid du Colombier }
441219b2ee8SDavid du Colombier
4423e12c5d1SDavid du Colombier static void
getstr(char * is)4433e12c5d1SDavid du Colombier getstr(char *is)
4443e12c5d1SDavid du Colombier {
4453e12c5d1SDavid du Colombier uchar *s = (uchar *) is;
4463e12c5d1SDavid du Colombier
447*7dd7cddfSDavid du Colombier for (*s = getc(); isspace(*s); *s = getc())
4483e12c5d1SDavid du Colombier ;
449*7dd7cddfSDavid du Colombier for (; !isspace(*s); *++s = getc())
4503e12c5d1SDavid du Colombier ;
451*7dd7cddfSDavid du Colombier ungetc();
4523e12c5d1SDavid du Colombier *s = 0;
4533e12c5d1SDavid du Colombier }
4543e12c5d1SDavid du Colombier
4553e12c5d1SDavid du Colombier static void
getutf(char * s)4563e12c5d1SDavid du Colombier getutf(char *s) /* get next utf char, as bytes */
4573e12c5d1SDavid du Colombier {
4583e12c5d1SDavid du Colombier int c, i;
4593e12c5d1SDavid du Colombier
4603e12c5d1SDavid du Colombier for (i=0;;) {
461*7dd7cddfSDavid du Colombier c = getc();
4623e12c5d1SDavid du Colombier if (c < 0)
4633e12c5d1SDavid du Colombier return;
4643e12c5d1SDavid du Colombier s[i++] = c;
4653e12c5d1SDavid du Colombier
4663e12c5d1SDavid du Colombier if (fullrune(s, i)) {
4673e12c5d1SDavid du Colombier s[i] = 0;
4683e12c5d1SDavid du Colombier return;
4693e12c5d1SDavid du Colombier }
4703e12c5d1SDavid du Colombier }
4713e12c5d1SDavid du Colombier }
4723e12c5d1SDavid du Colombier
4733e12c5d1SDavid du Colombier static void
eatline(void)4743e12c5d1SDavid du Colombier eatline(void)
4753e12c5d1SDavid du Colombier {
4763e12c5d1SDavid du Colombier int c;
4773e12c5d1SDavid du Colombier
478*7dd7cddfSDavid du Colombier while ((c=getc()) != '\n' && c >= 0)
4793e12c5d1SDavid du Colombier ;
4803e12c5d1SDavid du Colombier }
4813e12c5d1SDavid du Colombier
4823e12c5d1SDavid du Colombier static int
getn(void)4833e12c5d1SDavid du Colombier getn(void)
4843e12c5d1SDavid du Colombier {
4853e12c5d1SDavid du Colombier int n, c, sign;
4863e12c5d1SDavid du Colombier
487*7dd7cddfSDavid du Colombier while (c = getc())
4883e12c5d1SDavid du Colombier if (!isspace(c))
4893e12c5d1SDavid du Colombier break;
490219b2ee8SDavid du Colombier if(c == '-'){
4913e12c5d1SDavid du Colombier sign = -1;
492*7dd7cddfSDavid du Colombier c = getc();
493219b2ee8SDavid du Colombier }else
4943e12c5d1SDavid du Colombier sign = 1;
495*7dd7cddfSDavid du Colombier for (n = 0; '0'<=c && c<='9'; c = getc())
4963e12c5d1SDavid du Colombier n = n*10 + c - '0';
4973e12c5d1SDavid du Colombier while (c == ' ')
498*7dd7cddfSDavid du Colombier c = getc();
499*7dd7cddfSDavid du Colombier ungetc();
5003e12c5d1SDavid du Colombier return(n*sign);
5013e12c5d1SDavid du Colombier }
5023e12c5d1SDavid du Colombier
5033e12c5d1SDavid du Colombier static int
botpage(int np)5043e12c5d1SDavid du Colombier botpage(int np) /* called at bottom of page np-1 == top of page np */
5053e12c5d1SDavid du Colombier {
5063e12c5d1SDavid du Colombier char *p;
5073e12c5d1SDavid du Colombier int n;
5083e12c5d1SDavid du Colombier
5093e12c5d1SDavid du Colombier while (p = getcmdstr()) {
5103e12c5d1SDavid du Colombier if (*p == '\0')
5113e12c5d1SDavid du Colombier return 0;
5123e12c5d1SDavid du Colombier if (*p == 'q')
5133e12c5d1SDavid du Colombier exits(p);
5143e12c5d1SDavid du Colombier if (*p == 'c') /* nop */
5153e12c5d1SDavid du Colombier continue;
5163e12c5d1SDavid du Colombier if (*p == 'm') {
5173e12c5d1SDavid du Colombier mag = atof(p+1);
5183e12c5d1SDavid du Colombier if (mag <= .1 || mag >= 10)
5193e12c5d1SDavid du Colombier mag = DEFMAG;
5203e12c5d1SDavid du Colombier allfree(); /* zap fonts */
5213e12c5d1SDavid du Colombier DIV = floor(.5 + res/(100.0*mag));
5223e12c5d1SDavid du Colombier if (DIV < 1)
5233e12c5d1SDavid du Colombier DIV = 1;
5243e12c5d1SDavid du Colombier mag = res/(100.0*DIV);
5253e12c5d1SDavid du Colombier return skipto(np-1, np); /* reprint the page */
5263e12c5d1SDavid du Colombier }
5273e12c5d1SDavid du Colombier if (*p == 'x') {
5283e12c5d1SDavid du Colombier xyoffset.x += atoi(p+1)*100;
5293e12c5d1SDavid du Colombier skipto(np-1, np);
5303e12c5d1SDavid du Colombier return 1;
5313e12c5d1SDavid du Colombier }
5323e12c5d1SDavid du Colombier if (*p == 'y') {
5333e12c5d1SDavid du Colombier xyoffset.y += atoi(p+1)*100;
5343e12c5d1SDavid du Colombier skipto(np-1, np);
5353e12c5d1SDavid du Colombier return 1;
5363e12c5d1SDavid du Colombier }
5373e12c5d1SDavid du Colombier if (*p == '/') { /* divide into n pieces */
5383e12c5d1SDavid du Colombier nview = atoi(p+1);
5393e12c5d1SDavid du Colombier if (nview < 1)
5403e12c5d1SDavid du Colombier nview = 1;
5413e12c5d1SDavid du Colombier else if (nview > MAXVIEW)
5423e12c5d1SDavid du Colombier nview = MAXVIEW;
5433e12c5d1SDavid du Colombier return skipto(np-1, np);
5443e12c5d1SDavid du Colombier }
5453e12c5d1SDavid du Colombier if (*p == 'p') {
546*7dd7cddfSDavid du Colombier if (p[1] == '\0'){ /* bare 'p' */
547*7dd7cddfSDavid du Colombier if(skipto(np-1, np))
548*7dd7cddfSDavid du Colombier return 1;
549*7dd7cddfSDavid du Colombier continue;
550*7dd7cddfSDavid du Colombier }
5513e12c5d1SDavid du Colombier p++;
5523e12c5d1SDavid du Colombier }
553219b2ee8SDavid du Colombier if ('0'<=*p && *p<='9') {
5543e12c5d1SDavid du Colombier n = atoi(p);
555*7dd7cddfSDavid du Colombier if(skipto(n, np))
556*7dd7cddfSDavid du Colombier return 1;
557*7dd7cddfSDavid du Colombier continue;
5583e12c5d1SDavid du Colombier }
5593e12c5d1SDavid du Colombier if (*p == '-' || *p == '+') {
5603e12c5d1SDavid du Colombier n = atoi(p);
5613e12c5d1SDavid du Colombier if (n == 0)
5623e12c5d1SDavid du Colombier n = *p == '-' ? -1 : 1;
563*7dd7cddfSDavid du Colombier if(skipto(np - 1 + n, np))
564*7dd7cddfSDavid du Colombier return 1;
565*7dd7cddfSDavid du Colombier continue;
5663e12c5d1SDavid du Colombier }
5673e12c5d1SDavid du Colombier if (*p == 'd') {
5683e12c5d1SDavid du Colombier dbg = 1 - dbg;
5693e12c5d1SDavid du Colombier continue;
5703e12c5d1SDavid du Colombier }
5713e12c5d1SDavid du Colombier
5723e12c5d1SDavid du Colombier fprint(2, "illegal; try q, 17, +2, -1, p, m.7, /2, x1, y-.5 or return\n");
5733e12c5d1SDavid du Colombier }
5743e12c5d1SDavid du Colombier return 0;
5753e12c5d1SDavid du Colombier }
576