From mboxrd@z Thu Jan 1 00:00:00 1970 From: erik quanstrom Date: Sun, 21 Apr 2013 23:58:08 -0400 To: 9fans@9fans.net Message-ID: In-Reply-To: <5C36A3EB-D065-4AAD-98D0-D53503ABAC32@corpus-callosum.com> References: <51724B16.6020703@yahoo.fr> <5C36A3EB-D065-4AAD-98D0-D53503ABAC32@corpus-callosum.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="upas-gklqhbppfjhljxtiyiuzsuafwn" Subject: Re: [9fans] Plot(1) broken on p9p OSX? Topicbox-Message-UUID: 458ef190-ead8-11e9-9d60-3106f5b1d025 This is a multi-part message in MIME format. --upas-gklqhbppfjhljxtiyiuzsuafwn Content-Disposition: inline Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit On Sat Apr 20 14:25:53 EDT 2013, jas@corpus-callosum.com wrote: > Plot doesn't have any redraw in eresized(). It would need to redraw > the screen and reprocess the data for the new size. yes. this is a problem for plan 9. you cannot move or hide the plot window. imho this is pretty antisocial. i've attached a version that always uses the double-buffer buffer to allow for resize events. double-buffering now only prevents the draw from going directly to the screen. it is also possible to select exit from the menu before the input is exhausted. for programs like mapdemo, this is important. a better solution would be to additionally save all the draw commands (between clears) and if the screen size has changed, recompute. otherwise if redrawing is necessary, the double-buffer buffer can be reused. unfortunately, i'm too lazy for that. > Fixing this > would probably fix devdraw cocoa versions as well and enable the > server option. > > This could be why devdraw on Mountain Lion also ends up with a > blank screen. it would seem that mountain lion devdraw has a bug. devdraw should not send a resize event until there is a, er, resize event. this spurious event is an error. - erik --upas-gklqhbppfjhljxtiyiuzsuafwn Content-Disposition: attachment; filename=plotdiff Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit diff -c /n/dump/2013/0421/sys/src/cmd/plot/plot.c plot.c /n/dump/2013/0421/sys/src/cmd/plot/plot.c:3,9 - plot.c:3,11 #include #include "plot.h" #include - #include + #include + #include + #include void define(char*); void call(char*); /n/dump/2013/0421/sys/src/cmd/plot/plot.c:106,111 - plot.c:108,114 #define NFSTACK 50 struct fstack{ + char name[128]; int peekc; int lineno; char *corebuf; /n/dump/2013/0421/sys/src/cmd/plot/plot.c:124,146 - plot.c:127,228 int cnt[NPTS]; /* control-polygon vertex counts */ double *pts[NPTS]; /* control-polygon vertex pointers */ - extern void m_swapbuf(void); + extern void m_swapbuf(void); /* reaching into implementation. ick. */ + extern Image *offscreen; void - eresized(int new){ - if(new && getwindow(display, Refnone) < 0){ - fprint(2, "Can't reattach to window: %r\n"); - exits("resize"); + 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 - main(int arc, char *arv[]){ + 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 + threadmain(int arc, char *arv[]){ char *ap; Biobuf *bp; int fd; /n/dump/2013/0421/sys/src/cmd/plot/plot.c:147,157 - plot.c:229,240 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; /n/dump/2013/0421/sys/src/cmd/plot/plot.c:158,164 - plot.c:241,249 case 's': fd=server(); break; } openpl(oflag); - if(1||dflag) doublebuffer(); + proccreate(mouseproc, nil, 32*1024); + if(dflag) + doublebuffer(); for (; arc > 1; arc--, arv++) { if (arv[1][0] == '-') { ap = arv[1]; /n/dump/2013/0421/sys/src/cmd/plot/plot.c:196,205 - plot.c:281,288 } 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) { /n/dump/2013/0421/sys/src/cmd/plot/plot.c:324,333 - plot.c:407,414 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; } } /n/dump/2013/0421/sys/src/cmd/plot/plot.c:358,374 - plot.c:439,449 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; } /n/dump/2013/0421/sys/src/cmd/plot/plot.c:383,396 - plot.c:458,467 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; /n/dump/2013/0421/sys/src/cmd/plot/plot.c:447,465 - plot.c:518,531 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; /n/dump/2013/0421/sys/src/cmd/plot/plot.c:498,505 - plot.c:564,570 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; /n/dump/2013/0421/sys/src/cmd/plot/plot.c:516,525 - plot.c:581,588 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); /n/dump/2013/0421/sys/src/cmd/plot/plot.c:536,545 - plot.c:599,606 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){ /n/dump/2013/0421/sys/src/cmd/plot/plot.c:553,566 - plot.c:614,627 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; /n/dump/2013/0421/sys/src/cmd/plot/plot.c:575,584 - plot.c:636,643 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++; /n/dump/2013/0421/sys/src/cmd/plot/plot.c:585,594 - plot.c:644,652 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; /n/dump/2013/0421/sys/src/cmd/plot/plot.c:598,611 - plot.c:656,666 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; diff -c /n/dump/2013/0421/sys/src/cmd/plot/libplot/machdep.c libplot/machdep.c /n/dump/2013/0421/sys/src/cmd/plot/libplot/machdep.c:1,10 - libplot/machdep.c:1,38 #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. /n/dump/2013/0421/sys/src/cmd/plot/libplot/machdep.c:11,114 - libplot/machdep.c:39,135 * 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); + if(offscreen != screen && !buffer) + line(screen, xlp(Pt(x0, y0)), xlp(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; - } /* * 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){ - fprint(2, "Can't double buffer\n"); - offscreen=screen; - } - } + void m_dblbuf(void) + { + buffer = 1; } - /* Assume colormap entry because + + /* * Use cache to avoid repeated allocation. */ struct{ /n/dump/2013/0421/sys/src/cmd/plot/libplot/machdep.c:127,136 - libplot/machdep.c:148,155 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 #include - //#include #include #include #define SCX(A) ((((A) - e1->xmin)*e1->scalex + e1->left)+.5) --upas-gklqhbppfjhljxtiyiuzsuafwn--