diff options
| -rw-r--r-- | sys/src/cmd/plot/libplot/dpoint.c | 3 | ||||
| -rw-r--r-- | sys/src/cmd/plot/libplot/fill.c | 3 | ||||
| -rw-r--r-- | sys/src/cmd/plot/libplot/machdep.c | 179 | ||||
| -rw-r--r-- | sys/src/cmd/plot/libplot/mplot.h | 3 | ||||
| -rw-r--r-- | sys/src/cmd/plot/libplot/ppause.c | 1 | ||||
| -rw-r--r-- | sys/src/cmd/plot/libplot/pprompt.c | 2 | ||||
| -rw-r--r-- | sys/src/cmd/plot/plot.c | 205 |
7 files changed, 236 insertions, 160 deletions
diff --git a/sys/src/cmd/plot/libplot/dpoint.c b/sys/src/cmd/plot/libplot/dpoint.c index 7d5b6ff87..1e93b8113 100644 --- a/sys/src/cmd/plot/libplot/dpoint.c +++ b/sys/src/cmd/plot/libplot/dpoint.c @@ -1,6 +1,5 @@ #include "mplot.h" void dpoint(double x, double y){ - draw(screen, Rect(SCX(x), SCY(y), SCX(x)+1, SCY(y)+1), getcolor(e1->foregr), - nil, ZP); + m_dpt(x, y); move(x, y); } diff --git a/sys/src/cmd/plot/libplot/fill.c b/sys/src/cmd/plot/libplot/fill.c index a33294e50..12eff9931 100644 --- a/sys/src/cmd/plot/libplot/fill.c +++ b/sys/src/cmd/plot/libplot/fill.c @@ -47,8 +47,7 @@ static void polygon(int cnt[], double *pts[], Windrule w, int v){ edges=(Edge *)malloc(nvert*sizeof(Edge)); if(edges==0){ NoSpace: - fprintf(stderr, "polygon: no space\n"); - exits("malloc failed"); + sysfatal("polygon: no space"); } ylist=(Edge **)malloc(Dy(screen->r)*sizeof(Edge *)); if(ylist==0) goto NoSpace; diff --git a/sys/src/cmd/plot/libplot/machdep.c b/sys/src/cmd/plot/libplot/machdep.c index cc7027438..64a2d7f91 100644 --- a/sys/src/cmd/plot/libplot/machdep.c +++ b/sys/src/cmd/plot/libplot/machdep.c @@ -1,114 +1,135 @@ #include "mplot.h" Image *offscreen; +static int buffer; + +static Point +xlp(Point p) +{ + p.x += screen->r.min.x + 4 - offscreen->r.min.x; + p.y += screen->r.min.y + 4 - offscreen->r.min.y; + return p; +} + +static Rectangle +xlr(Rectangle r) +{ + int dx, dy; + + dx = screen->r.min.x + 4 - offscreen->r.min.x; + dy = screen->r.min.y + 4 - offscreen->r.min.y; + r.min.x += dx; + r.min.y += dy; + r.max.x += dx; + r.max.y += dy; + return r; +} + /* * Clear the window from x0, y0 to x1, y1 (inclusive) to color c */ -void m_clrwin(int x0, int y0, int x1, int y1, int c){ +void +m_clrwin(int x0, int y0, int x1, int y1, int c) +{ draw(offscreen, Rect(x0, y0, x1+1, y1+1), getcolor(c), nil, ZP); + if(offscreen != screen && !buffer) + draw(screen, xlr(Rect(x0, y0, x1+1, y1+1)), getcolor(c), nil, ZP); } /* * Draw text between pointers p and q with first character centered at x, y. * Use color c. Centered if cen is non-zero, right-justified if right is non-zero. * Returns the y coordinate for any following line of text. */ -int m_text(int x, int y, char *p, char *q, int c, int cen, int right){ +int +m_text(int x, int y, char *p, char *q, int c, int cen, int right) +{ Point tsize; - USED(c); - tsize=stringsize(font, p); - if(cen) x -= tsize.x/2; - else if(right) x -= tsize.x; + + tsize = stringsize(font, p); + if(cen) + x -= tsize.x/2; + else if(right) + x -= tsize.x; stringn(offscreen, Pt(x, y-tsize.y/2), getcolor(c), ZP, font, p, q-p); + if(offscreen != screen && !buffer) + stringn(screen, xlp(Pt(x, y-tsize.y/2)), getcolor(c), ZP, font, p, q-p); return y+tsize.y; } /* + * draw point x, y + */ +void +m_dpt(double x, double y) +{ + Image *c; + + c = getcolor(e1->foregr); + draw(offscreen, Rect(SCX(x), SCY(y), SCX(x)+1, SCY(y)+1), c, nil, ZP); + if(offscreen != screen && !buffer) + draw(screen, xlr(Rect(SCX(x), SCY(y), SCX(x)+1, SCY(y)+1)), c, nil, ZP); +} + +/* * Draw the vector from x0, y0 to x1, y1 in color c. * Clipped by caller */ -void m_vector(int x0, int y0, int x1, int y1, int c){ +void +m_vector(int x0, int y0, int x1, int y1, int c) +{ line(offscreen, Pt(x0, y0), Pt(x1, y1), Endsquare, Endsquare, 0, getcolor(c), ZP); -} -char *scanint(char *s, int *n){ - while(*s<'0' || '9'<*s){ - if(*s=='\0'){ - fprint(2, "plot: bad -Wxmin,ymin,xmax,ymax\n"); - exits("bad arg"); - } - s++; - } - *n=0; - while('0'<=*s && *s<='9'){ - *n=*n*10+*s-'0'; - s++; - } - return s; -} -char *rdenv(char *name){ - char *v; - int fd, size; - fd=open(name, OREAD); - if(fd<0) return 0; - size=seek(fd, 0, 2); - v=malloc(size+1); - if(v==0){ - fprint(2, "Can't malloc: %r\n"); - exits("no mem"); - } - seek(fd, 0, 0); - read(fd, v, size); - v[size]=0; - close(fd); - return v; + if(offscreen != screen && !buffer) + line(screen, xlp(Pt(x0, y0)), xlp(Pt(x1, y1)), Endsquare, Endsquare, 0, getcolor(c), ZP); } /* * Startup initialization */ -void m_initialize(char *s){ - static int first=1; +void m_initialize(char*) +{ + static int once; int dx, dy; - USED(s); - if(first){ - if(initdraw(0,0,"plot") < 0) - sysfatal("initdraw: %r"); - einit(Emouse); - clipminx=mapminx=screen->r.min.x+4; - clipminy=mapminy=screen->r.min.y+4; - clipmaxx=mapmaxx=screen->r.max.x-5; - clipmaxy=mapmaxy=screen->r.max.y-5; - dx=clipmaxx-clipminx; - dy=clipmaxy-clipminy; - if(dx>dy){ - mapminx+=(dx-dy)/2; - mapmaxx=mapminx+dy; - } - else{ - mapminy+=(dy-dx)/2; - mapmaxy=mapminy+dx; - } - first=0; - offscreen = screen; + + if(once) + return; + once = 1; + + if(initdraw(nil, nil, "plot") < 0) + sysfatal("initdraw: %r"); +///// einit(Emouse); + offscreen = allocimage(display, insetrect(screen->r, 4), screen->chan, 0, -1); + if(offscreen == nil) + sysfatal("Can't double buffer\n"); + clipminx = mapminx = screen->r.min.x+4; + clipminy = mapminy = screen->r.min.y+4; + clipmaxx = mapmaxx = screen->r.max.x-5; + clipmaxy = mapmaxy = screen->r.max.y-5; + dx = clipmaxx-clipminx; + dy = clipmaxy-clipminy; + if(dx>dy){ + mapminx += (dx-dy)/2; + mapmaxx = mapminx+dy; + } + else{ + mapminy += (dy-dx)/2; + mapmaxy = mapminy+dx; } } /* * Clean up when finished */ -void m_finish(void){ +void m_finish(void) +{ m_swapbuf(); } -void m_swapbuf(void){ - if(offscreen!=screen) - draw(screen, offscreen->r, offscreen, nil, offscreen->r.min); +void m_swapbuf(void) +{ + draw(screen, insetrect(screen->r, 4), offscreen, nil, offscreen->r.min); flushimage(display, 1); } -void m_dblbuf(void){ - if(offscreen==screen){ - offscreen=allocimage(display, insetrect(screen->r, 4), screen->chan, 0, -1); - if(offscreen==0){ - fprintf(stderr, "Can't double buffer\n"); - offscreen=screen; - } - } +void m_dblbuf(void) +{ + buffer = 1; } -/* Assume colormap entry because + +/* * Use cache to avoid repeated allocation. */ struct{ @@ -127,16 +148,14 @@ getcolor(int v) return icache[j].i; i = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1, v); - if(i == nil){ - fprint(2, "plot: can't allocate image for color: %r\n"); - exits("allocimage"); - } + if(i == nil) + sysfatal("plot: can't allocate image for color: %r"); for(j=0; j<nelem(icache); j++) if(icache[j].i == nil){ icache[j].v = v; icache[j].i = i; break; } - +if(j == nelem(icache))sysfatal("icache: too small"); return i; } diff --git a/sys/src/cmd/plot/libplot/mplot.h b/sys/src/cmd/plot/libplot/mplot.h index 99e27efd1..6137a62c4 100644 --- a/sys/src/cmd/plot/libplot/mplot.h +++ b/sys/src/cmd/plot/libplot/mplot.h @@ -1,6 +1,6 @@ #include <u.h> #include <libc.h> -#include <stdio.h> +//#include <stdio.h> #include <draw.h> #include <event.h> #define SCX(A) ((((A) - e1->xmin)*e1->scalex + e1->left)+.5) @@ -39,6 +39,7 @@ void m_clrwin(int, int, int, int, int); void m_finish(void); void m_initialize(char *); int m_text(int, int, char *, char *, int, int, int); +void m_dpt(double, double); void m_vector(int, int, int, int, int); void m_swapbuf(void); void m_dblbuf(void); diff --git a/sys/src/cmd/plot/libplot/ppause.c b/sys/src/cmd/plot/libplot/ppause.c index 9fb8863d2..6f0e22e20 100644 --- a/sys/src/cmd/plot/libplot/ppause.c +++ b/sys/src/cmd/plot/libplot/ppause.c @@ -1,7 +1,6 @@ #include "mplot.h" void ppause(void){ char aa[4]; - fflush(stdout); read(0, aa, 4); erase(); } diff --git a/sys/src/cmd/plot/libplot/pprompt.c b/sys/src/cmd/plot/libplot/pprompt.c index 2678ead5f..1e730abf3 100644 --- a/sys/src/cmd/plot/libplot/pprompt.c +++ b/sys/src/cmd/plot/libplot/pprompt.c @@ -1,5 +1,5 @@ #include "mplot.h" void pprompt(void){ - fprintf(stderr, ":"); + fprint(2, ":"); } diff --git a/sys/src/cmd/plot/plot.c b/sys/src/cmd/plot/plot.c index a4cd59e2f..3633750ae 100644 --- a/sys/src/cmd/plot/plot.c +++ b/sys/src/cmd/plot/plot.c @@ -3,7 +3,9 @@ #include <bio.h> #include "plot.h" #include <draw.h> -#include <event.h> +#include <thread.h> +#include <mouse.h> +#include <keyboard.h> void define(char*); void call(char*); @@ -106,6 +108,7 @@ struct fcall *fptr = flibr; #define NFSTACK 50 struct fstack{ + char name[128]; int peekc; int lineno; char *corebuf; @@ -124,37 +127,123 @@ double x[NX]; /* numeric arguments */ int cnt[NPTS]; /* control-polygon vertex counts */ double *pts[NPTS]; /* control-polygon vertex pointers */ -void eresized(int new){ - if(new && getwindow(display, Refnone) < 0){ - fprint(2, "Can't reattach to window: %r\n"); - exits("resize"); +extern void m_swapbuf(void); /* reaching into implementation. ick. */ +extern Image *offscreen; + +void +resize(Point p) +{ + int fd; + + fd = open("/dev/wctl", OWRITE); + if(fd >= 0){ + fprint(fd, "resize -dx %d -dy %d", p.x+4*2, p.y+4*2); + close(fd); } } + +void +resizeto(Point p) +{ + Point s; + + s = (Point){Dx(screen->r), Dy(screen->r)}; + if(eqpt(p, s)) + return; + resize(p); +} + +void +eresized(int new) +{ + if(new && getwindow(display, Refnone) < 0) + sysfatal("plot: can't reattach to window: %r\n"); +// resizeto((Point){Dx(offscreen->r)+4, Dy(offscreen->r)+4}); + m_swapbuf(); +} + char *items[]={ "exit", 0 }; Menu menu={items}; + +void +mouseproc(void*) +{ + void *v; + Rune r; + Alt alts[4]; + Keyboardctl *k; + Mousectl *m; + Mouse mc; + enum{Amouse, Akbd, Aresize, Aend}; + + m = initmouse(nil, screen); + k = initkeyboard(nil); + + memset(alts, 0, sizeof alts); + alts[Amouse].c = m->c; + alts[Amouse].v = &mc; + alts[Amouse].op = CHANRCV; + + alts[Akbd].c = k->c; + alts[Akbd].v = &r; + alts[Akbd].op = CHANRCV; + + alts[Aresize].c = m->resizec; + alts[Aresize].v = &v; + alts[Aresize].op = CHANRCV; + + alts[Aend].op = CHANEND; + + for(;;) + switch(alt(alts)){ + default: + sysfatal("mouse!"); + case Amouse: + if(mc.buttons & 4) { + if(menuhit(3, m, &menu, nil) == 0) + threadexitsall(""); + } + break; + case Akbd: + switch(r){ + case 'q': + case 0x7f: + case 0x04: + threadexitsall(""); + } + break; + case Aresize: + eresized(1); + ; + } +} + void -main(int arc, char *arv[]){ +threadmain(int arc, char *arv[]){ char *ap; Biobuf *bp; int fd; int i; int dflag; char *oflag; - Mouse m; + bp = 0; fd = dup(0, -1); /* because openpl will close 0! */ dflag=0; oflag=""; + argv0 = arv[0]; for(i=1;i!=arc;i++) if(arv[i][0]=='-') switch(arv[i][1]){ case 'd': dflag=1; break; case 'o': oflag=arv[i]+2; break; case 's': fd=server(); break; } openpl(oflag); - if(dflag) doublebuffer(); + proccreate(mouseproc, nil, 32*1024); + if(dflag) + doublebuffer(); for (; arc > 1; arc--, arv++) { if (arv[1][0] == '-') { ap = arv[1]; @@ -192,10 +281,8 @@ main(int arc, char *arv[]){ } closepl(); flushimage(display, 1); - for(;;){ - m=emouse(); - if(m.buttons&4 && emenuhit(3, &m, &menu)==0) exits(0); - } + for(;;) + sleep(1000); } int isalpha(int c) { @@ -320,10 +407,8 @@ numargs(int n){ c=nextc(); }while(strchr(" \t\n", c) || c!='.' && c!='+' && c!='-' && ispunct(c)); fsp->peekc=c; - if(!numstring()){ - fprint(2, "line %d: number expected\n", fsp->lineno); - exits("input error"); - } + if(!numstring()) + sysfatal("%s:%d: number expected\n", fsp->name, fsp->lineno); x[i]=atof(argstr)*fsp->scale; } } @@ -354,17 +439,11 @@ polyarg(void){ c=nextc(); if(c==r){ if(*cntp){ - if(*cntp&1){ - fprint(2, "line %d: phase error\n", - fsp->lineno); - exits("bad input"); - } + if(*cntp&1) + sysfatal("%s:%d: phase error", fsp->name, fsp->lineno); *cntp/=2; - if(ptsp==&pts[NPTS]){ - fprint(2, "line %d: out of polygons\n", - fsp->lineno); - exits("exceeded limit"); - } + if(ptsp==&pts[NPTS]) + sysfatal("%s:%d: out of polygons", fsp->name, fsp->lineno); *++ptsp=xp; *++cntp=0; } @@ -379,14 +458,10 @@ polyarg(void){ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': fsp->peekc=c; - if(!numstring()){ - fprint(2, "line %d: expected number\n", fsp->lineno); - exits("bad input"); - } - if(xp==&x[NX]){ - fprint(2, "line %d: out of space\n", fsp->lineno); - exits("exceeded limit"); - } + if(!numstring()) + sysfatal("%s:%d: expected number", fsp->name, fsp->lineno); + if(xp==&x[NX]) + sysfatal("%s:%d: out of space", fsp->name, fsp->lineno); *xp++=atof(argstr); ++*cntp; break; @@ -443,19 +518,14 @@ process(Biobuf *fd){ for(pplots=plots;pplots->cc;pplots++) if(strncmp(argstr, pplots->cc, pplots->numc)==0) break; - if(pplots->cc==0){ - fprint(2, "line %d, %s unknown\n", fsp->lineno, - argstr); - exits("bad command"); - } + if(pplots->cc==0) + sysfatal("%s:%d: %s unknown", fsp->name, fsp->lineno, argstr); } else{ fsp->peekc=c; } - if(!pplots){ - fprint(2, "line %d, no command!\n", fsp->lineno); - exits("no command"); - } + if(!pplots) + sysfatal("%s:%d: no command\n", fsp->name, fsp->lineno); switch(pplots-plots){ case ARC: numargs(7); rarc(x[0],x[1],x[2],x[3],x[4],x[5],x[6]); break; case BOX: numargs(4); box(x[0], x[1], x[2], x[3]); break; @@ -494,8 +564,7 @@ process(Biobuf *fd){ case TEXT: strarg(); text(argstr); pplots=0; break; case VEC: numargs(2); vec(x[0], x[1]); break; default: - fprint(2, "plot: missing case %ld\n", pplots-plots); - exits("internal error"); + sysfatal("%s:%d: plot: missing case %ld\n", fsp->name, fsp->lineno, pplots-plots); } } return 1; @@ -512,10 +581,8 @@ void define(char *a){ int curly = 0; ap = a; while(isalpha(*ap))ap++; - if(ap == a){ - fprint(2,"no name with define\n"); - exits("define"); - } + if(ap == a) + sysfatal("plot: no name with define\n"); i = ap - a; if(names+i+1 > enames){ names = malloc((unsigned)512); @@ -532,10 +599,8 @@ void define(char *a){ fptr->stash = nstash; while(*ap != '{') if(*ap == '\n'){ - if((ap=Brdline(fsp->fd, '\n'))==0){ - fprint(2,"unexpected end of file\n"); - exits("eof"); - } + if((ap=Brdline(fsp->fd, '\n'))==0) + sysfatal("plot: unexpected eof"); } else ap++; while((j=Bgetc(fsp->fd))!= Beof){ @@ -549,14 +614,14 @@ void define(char *a){ free(bstash); size += 1024; bstash = realloc(bstash,size); + if(bstash == nil) + sysfatal("plot: realloc: %r"); estash = bstash+size; } } *nstash++ = '\0'; - if(fptr++ >= &flibr[MAXL]){ - fprint(2,"Too many objects\n"); - exits("too many objects"); - } + if(fptr++ >= &flibr[MAXL]) + sysfatal("too many objects"); } void call(char *a){ char *ap; @@ -571,20 +636,17 @@ void call(char *a){ if (!(strcmp(a, f->name))) break; } - if(f == fptr){ - fprint(2, "object %s not defined\n",a); - exits("undefined"); - } + if(f == fptr) + sysfatal("plot: object %s not defined",a); *ap = sav; while (isspace(*ap) || *ap == ',') ap++; if (*ap != '\0') SC = atof(ap); else SC = 1.; - if(++fsp==&fstack[NFSTACK]){ - fprint(2, "input stack overflow\n"); - exits("blew stack"); - } + if(++fsp==&fstack[NFSTACK]) + sysfatal("plot: input stack overflow"); + snprint(fsp->name, sizeof fsp->name, "call %s", f->name); fsp->peekc=Beof; fsp->lineno=1; fsp->corebuf=f->stash; @@ -594,14 +656,11 @@ void call(char *a){ void include(char *a){ Biobuf *fd; fd=Bopen(a, OREAD); - if(fd==0){ - perror(a); - exits("can't include"); - } - if(++fsp==&fstack[NFSTACK]){ - fprint(2, "input stack overflow\n"); - exits("blew stack"); - } + if(fd==0) + sysfatal("plot: cant include %s: %r", a); + if(++fsp==&fstack[NFSTACK]) + sysfatal("plot: input stack overflow"); + snprint(fsp->name, sizeof fsp->name, "%s", a); fsp->peekc=Beof; fsp->lineno=1; fsp->corebuf=0; |
