]> git.lizzy.rs Git - plan9front.git/commitdiff
- use the double-buffer buffer to allow redrawing on resize events.
authorcinap_lenrek <cinap_lenrek@gmx.de>
Mon, 22 Apr 2013 17:10:09 +0000 (19:10 +0200)
committercinap_lenrek <cinap_lenrek@gmx.de>
Mon, 22 Apr 2013 17:10:09 +0000 (19:10 +0200)
specifing -d on the command line now only disables synchronous
drawing events.

- use threaded mouse and keyboard to allow for asynchronous
receoption of quit messages.  this allows plot to exit before drawing
is completed.  for programs like mapdemo, this is important.

there were two things that needed to get fixed as a result
- replace fprint(2, ...); exits("bad"); with sysfatal.  also get rid
of stdio.

- dpoint needed a mach-dependentent (sic) version.  otherwise
points on a resized screen will not be properly placed.

sys/src/cmd/plot/libplot/dpoint.c
sys/src/cmd/plot/libplot/fill.c
sys/src/cmd/plot/libplot/machdep.c
sys/src/cmd/plot/libplot/mplot.h
sys/src/cmd/plot/libplot/ppause.c
sys/src/cmd/plot/libplot/pprompt.c
sys/src/cmd/plot/plot.c

index 7d5b6ff877f35842aca769446e3c670eb699cc3e..1e93b8113f7dd544b4e7c95eacf76438441dcdd1 100644 (file)
@@ -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);
 }
index a33294e50a991ac26519c727710835d33627b324..12eff993193fb5d277bf212564785abda88e86c2 100644 (file)
@@ -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;
index cc7027438fe5f5043e68b5632491882b75e08fb8..64a2d7f9199fa07737cdd7ff82e18bb2dabe7373 100644 (file)
 #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;
 }
index 99e27efd1951de61725d0af92abfd068f413313b..6137a62c49da1541cd765e2107e6be3b4c64867b 100644 (file)
@@ -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);
index 9fb8863d28ca60f812462d1a08182a19f59f2910..6f0e22e20fbdcd00809f78cc48f5e78c72ee0646 100644 (file)
@@ -1,7 +1,6 @@
 #include "mplot.h"
 void ppause(void){ 
        char    aa[4]; 
-       fflush(stdout); 
        read(0, aa, 4);  
        erase(); 
 }
index 2678ead5f0a0e67d3f7db2cb4c1c866fc112b634..1e730abf391fc6448076cc39e47b42e7a3758e61 100644 (file)
@@ -1,5 +1,5 @@
 #include "mplot.h"
 void
 pprompt(void){
-       fprintf(stderr, ":");
+       fprint(2, ":");
 }
index a4cd59e2f309b7bb2666860f758606ec73b1dbd3..3633750ae5819652630dbe58481f91d7c8a056fc 100644 (file)
@@ -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;