diff -r 5ecb69a3c1a0 sys/src/cmd/mothra/forms.c --- a/sys/src/cmd/mothra/forms.c Mon Mar 06 03:07:03 2017 +0100 +++ b/sys/src/cmd/mothra/forms.c Wed Mar 08 14:36:42 2017 -0800 @@ -485,7 +485,7 @@ o->selected=o->def; break; } - pldraw(text, screen); + pldraw(root, screen); } void h_buttoninput(Panel *p, int){ diff -r 5ecb69a3c1a0 sys/src/cmd/mothra/mothra.c --- a/sys/src/cmd/mothra/mothra.c Mon Mar 06 03:07:03 2017 +0100 +++ b/sys/src/cmd/mothra/mothra.c Wed Mar 08 14:36:42 2017 -0800 @@ -18,13 +18,18 @@ int visxbar=0; /* horizontal scrollbar visible? */ int topxbar=0; /* horizontal scrollbar at top? */ Panel *root; /* the whole display */ -Panel *alt; /* the alternate display */ -Panel *alttext; /* the alternate text window */ +Panel *tablist; +Panel *holder; /* of current tab view */ + +int taballoc=0; +int ntabs=0; +Tab *tabs; +Tab *curtab; + Panel *cmd; /* command entry */ -Panel *cururl; /* label giving the url of the visible text */ -Panel *list; /* list of previously acquired www pages */ Panel *msg; /* message display */ Panel *menu3; /* button 3 menu */ + char mothra[] = "mothra!"; Cursor patientcurs={ 0, 0, @@ -74,9 +79,6 @@ 0x0c, 0x30, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, } }; -Www *current=0; -Url *selection=0; -int mothmode; int kickpipe[2]; void docmd(Panel *, char *); @@ -101,13 +103,14 @@ 0 }; -int wwwtop=0; Www *www(int index){ - static Www a[NWWW]; - return &a[index % NWWW]; + return &curtab->a[index % NWWW]; } int nwww(void){ - return wwwtopwwwtopwwwtop : NWWW; + + return 0; } int subpanel(Panel *obj, Panel *subj){ @@ -124,11 +127,11 @@ int adjkb(void){ Rtext *t; int yoffs; - if(current){ - yoffs=text->r.min.y-plgetpostextview(text); - for(t=current->text;t;t=t->next) if(!eqrect(t->r, Rect(0,0,0,0))){ - if(t->r.max.y+yoffs>=text->r.min.y - && t->r.min.y+yoffsr.max.y + if(curtab->current){ + yoffs=curtab->text->r.min.y-plgetpostextview(curtab->text); + for(t=curtab->current->text;t;t=t->next) if(!eqrect(t->r, Rect(0,0,0,0))){ + if(t->r.max.y+yoffs>=curtab->text->r.min.y + && t->r.min.y+yoffstext->r.max.y && t->b==0 && subpanel(t->p, plkbfocus)) return 1; @@ -142,7 +145,7 @@ { Scroll s; - s = plgetscroll(text); + s = plgetscroll(curtab->text); switch(whence){ case 0: s.pos.y = dy; @@ -158,14 +161,13 @@ s.pos.y = s.size.y; if(s.pos.y < 0) s.pos.y = 0; - plsetscroll(text, s); } void sidescroll(int dx, int whence) { Scroll s; - s = plgetscroll(text); + s = plgetscroll(curtab->text); switch(whence){ case 0: s.pos.x = dx; @@ -177,11 +179,152 @@ s.pos.x = s.size.x+dx; break; } - if(s.pos.x > s.size.x - text->size.x + 5) - s.pos.x = s.size.x - text->size.x + 5; + if(s.pos.x > s.size.x - curtab->text->size.x + 5) + s.pos.x = s.size.x - curtab->text->size.x + 5; if(s.pos.x < 0) s.pos.x = 0; - plsetscroll(text, s); + plsetscroll(curtab->text, s); +} + +Tab* newtab(void){ + Panel *p, *bar; + Tab *t; + t = mallocz(sizeof(Tab), 1); + assert(t); + + t->id = taballoc++; + + t->view = plgroup(0, EXPAND); + p=plgroup(t->view, PACKN|FILLX); + bar=plscrollbar(p, PACKW); + t->list=pllist(p, PACKN|FILLX, genwww, 4, doprev); + plscroll(t->list, 0, bar); + p=plgroup(t->view, PACKN|FILLX); + pllabel(p, PACKW, "Url:"); + t->cururl=pllabel(p, PACKE|EXPAND, "---"); + plplacelabel(t->cururl, PLACEW); + p=plgroup(t->view, PACKN|FILLX|EXPAND); + bar=plscrollbar(p, PACKW|USERFL); + t->text=pltextview(p, PACKE|EXPAND, Pt(0, 0), nil, dolink); + plscroll(t->text, 0, bar); + plplacelabel(t->cururl, PLACEW); + + t->alt=plpopup(0, PACKE|EXPAND, 0, 0, menu3); + bar=plscrollbar(t->alt, PACKW|USERFL); + t->alttext=pltextview(t->alt, PACKE|EXPAND, Pt(0, 0), 0, dolink); + plscroll(t->alttext, 0, bar); + + return t; +} + +Tab *gettab(int index){ + int i; + Tab *tb; + + if(index < 0 || index > ntabs) + return nil; + + i = 0; + tb = tabs; + while(i < index){ + i++; + tb = tb->next; + } + + return tb; +} + +// tab functions +static char* +gentab(Panel*, int index) +{ + static char buf[256]; + Tab *tb; + + if(index >= ntabs) + return nil; + + tb=gettab(index); + + if(!tb->current || !tb->current->url) + snprint(buf, sizeof(buf), "%2d", tb->id+1); + else if(tb->current->title[0]!='\0'){ + //w->gottitle=1; + snprint(buf, sizeof(buf), "%2d %s", tb->id+1, tb->current->title); + } else + snprint(buf, sizeof(buf), "%2d %s", tb->id+1, urlstr(tb->current->url)); + + return buf; +} + +void pll(Tab *t){ + fprint(2, "tab %d\n ", t->id+1); + if(t->next) + pll(t->next); +} + +void dotab(Panel *, int buttons, int index){ + int i; + Tab *tb, *prev; + + if(index < 0 || index > ntabs) + return; + + i = 0; + tb = tabs; + prev = nil; + while(i < index){ + i++; + prev = tb; + tb = tb->next; + } + + switch(buttons){ + case 1: + holder->child = tb->view; + curtab = tb; + + break; + case 2: + /* no deleting the first tab */ + if(tb->id == 0) + break; + + if(prev){ + //current = prev; + holder->child = prev->view; + curtab = prev; + } + prev->next = tb->next; + + plfree(tb->view); + free(tb); + ntabs--; + break; + } + + plinitlist(tablist, PACKW|FILLX|EXPAND, gentab, ntabs < 5 ? ntabs : 4, dotab); + + eresized(0); +} + +void donewtab(Panel *, int buttons){ + Tab *new, *tb; + + new = newtab(); + ntabs++; + + tb = tabs; + + while(tb->next != nil){ + tb = tb->next; + } + + tb->next = new; + + plinitlist(tablist, PACKW|FILLX|EXPAND, gentab, ntabs < 5 ? ntabs : 4, dotab); + + eresized(0); } void mkpanels(void){ @@ -197,10 +340,17 @@ menu3=plmenu(0, 0, buttons, PACKN|FILLX, hit3); root=plpopup(root, EXPAND, 0, 0, menu3); p=plgroup(root, PACKN|FILLX); + xbar=plscrollbar(p, PACKW); + tablist=pllist(p, PACKW|FILLX|EXPAND, gentab, 1, dotab); + plscroll(tablist, 0, xbar); + plbutton(p, PACKW|FILLY, "+", donewtab); + p=plgroup(root, PACKN|FILLX); msg=pllabel(p, PACKN|FILLX, mothra); plplacelabel(msg, PLACEW); pllabel(p, PACKW, "Go:"); cmd=plentry(p, PACKN|FILLX, 0, "", docmd); + holder=plgroup(root, EXPAND); + /* p=plgroup(root, PACKN|FILLX); ybar=plscrollbar(p, PACKW); list=pllist(p, PACKN|FILLX, genwww, 8, doprev); @@ -214,12 +364,10 @@ xbar=plscrollbar(p, xflags); text=pltextview(p, PACKE|EXPAND, Pt(0, 0), 0, dolink); plscroll(text, xbar, ybar); +*/ plgrabkb(cmd); - alt=plpopup(0, PACKE|EXPAND, 0, 0, menu3); - ybar=plscrollbar(alt, PACKW|USERFL); - xbar=plscrollbar(alt, xflags); - alttext=pltextview(alt, PACKE|EXPAND, Pt(0, 0), 0, dolink); - plscroll(alttext, xbar, ybar); + +/* if(!defdisplay){ swap=root; root=alt; @@ -228,7 +376,10 @@ text=alttext; alttext=swap; } + */ + } + int cohort = -1; void killcohort(void){ int i; @@ -269,9 +420,9 @@ } void donecurs(void){ - if(current && current->alldone==0) + if(curtab->current && curtab->current->alldone==0) esetcursor(&readingcurs); - else if(mothmode) + else if(curtab->mothmode) esetcursor(&mothcurs); else esetcursor(0); @@ -297,6 +448,7 @@ Event e; enum { Eplumb = 128, Ekick = 256 }; Plumbmsg *pm; + Www *current; char *url; int i; @@ -358,7 +510,10 @@ sysfatal("can't allocimage!"); bullet=allocimage(display, Rect(0,0,25, 8), screen->chan, 0, DWhite); fillellipse(bullet, Pt(4,4), 3, 3, display->black, ZP); + curtab = tabs = newtab(); + ntabs++; mkpanels(); + holder->child = tabs->view; unlockdisplay(display); eresized(0); drawlock(1); @@ -368,6 +523,7 @@ mouse.buttons=0; for(;;){ + current = curtab->current; if(mouse.buttons==0 && current){ if(current->finished){ updtext(current); @@ -403,38 +559,38 @@ scrolltext(0, 0); break; case Kup: - scrolltext(-text->size.y/4, 1); + scrolltext(-curtab->text->size.y/4, 1); break; case Kpgup: - scrolltext(-text->size.y/2, 1); + scrolltext(-curtab->text->size.y/2, 1); break; case Kdown: - scrolltext(text->size.y/4, 1); + scrolltext(curtab->text->size.y/4, 1); break; case Kpgdown: - scrolltext(text->size.y/2, 1); + scrolltext(curtab->text->size.y/2, 1); break; case Kend: - scrolltext(-text->size.y, 2); + scrolltext(-curtab->text->size.y, 2); break; case Kack: search(); break; case Kright: - sidescroll(text->size.x/4, 1); + sidescroll(curtab->text->size.x/4, 1); break; case Kleft: - sidescroll(-text->size.x/4, 1); + sidescroll(-curtab->text->size.x/4, 1); break; } break; case Emouse: mouse=e.mouse; - if(mouse.buttons & (8|16) && ptinrect(mouse.xy, text->r)){ + if(mouse.buttons & (8|16) && ptinrect(mouse.xy, curtab->text->r)){ if(mouse.buttons & 8) - scrolltext(text->r.min.y - mouse.xy.y, 1); + scrolltext(curtab->text->r.min.y - mouse.xy.y, 1); else - scrolltext(mouse.xy.y - text->r.min.y, 1); + scrolltext(mouse.xy.y - curtab->text->r.min.y, 1); break; } plmouse(root, &mouse); @@ -442,6 +598,9 @@ case Eplumb: pm=e.v; if(pm->ndata > 0) + /* XXX: donewtab here? */ + donewtab(nil, 0); + dotab(nil, 1, ntabs-1); geturl(pm->data, -1, 1, 0); plumbfree(pm); break; @@ -490,7 +649,7 @@ } r=screen->r; plpack(root, r); - plpack(alt, r); + plpack(curtab->alt, r); pldraw(cmd, screen); /* put cmd box on screen for alt display */ pldraw(root, screen); flushimage(display, 1); @@ -517,7 +676,7 @@ if(index >= nwww()) return 0; - i = wwwtop-index-1; + i = curtab->wwwtop-index-1; w = www(i); if(!w->url) return 0; @@ -532,18 +691,18 @@ void scrollto(char *tag){ Rtext *tp; Action *ap; - if(current == nil || text == nil) + if(curtab->current == nil || curtab->text == nil) return; if(tag && tag[0]){ - for(tp=current->text;tp;tp=tp->next){ + for(tp=curtab->current->text;tp;tp=tp->next){ ap=tp->user; if(ap && ap->name && strcmp(ap->name, tag)==0){ - current->yoffs=tp->topy; + curtab->current->yoffs=tp->topy; break; } } } - plsetpostextview(text, current->yoffs); + plsetpostextview(curtab->text, curtab->current->yoffs); } /* @@ -553,16 +712,16 @@ Www *new; int i; new=www(index); - if(new==current && (tag==0 || tag[0]==0)) return; - if(current) - current->yoffs=plgetpostextview(text); - current=new; - plinitlabel(cururl, PACKE|EXPAND, current->url->fullname); - if(defdisplay) pldraw(cururl, screen); - plinittextview(text, PACKE|EXPAND, Pt(0, 0), current->text, dolink); + if(new==curtab->current && (tag==0 || tag[0]==0)) return; + if(curtab->current) + curtab->current->yoffs=plgetpostextview(curtab->text); + curtab->current=new; + plinitlabel(curtab->cururl, PACKE|EXPAND, curtab->current->url->fullname); + if(defdisplay) pldraw(curtab->cururl, screen); + plinittextview(curtab->text, PACKE|EXPAND, Pt(0, 0), curtab->current->text, dolink); scrollto(tag); if((i = open("/dev/label", OWRITE)) >= 0){ - fprint(i, "%s %s", mothra, current->url->fullname); + fprint(i, "%s %s", mothra, curtab->current->url->fullname); close(i); } donecurs(); @@ -613,7 +772,7 @@ if(full){ writeimage(fd, screen, 0); } else { - if((b=allocimage(display, text->r, screen->chan, 0, DNofill)) == nil){ + if((b=allocimage(display, curtab->text->r, screen->chan, 0, DNofill)) == nil){ message("can't allocate image"); close(fd); return; @@ -662,15 +821,15 @@ break; case 'a': s = arg(s); - if(*s=='\0' && selection) + if(*s=='\0' && curtab->selection) hit3(3, 0); break; case 'g': s = arg(s); if(*s=='\0'){ case 'r': - if(selection) - s = urlstr(selection); + if(curtab->selection) + s = urlstr(curtab->selection); else message("no url selected"); } @@ -679,15 +838,15 @@ case 'j': s = arg(s); if(*s) - doprev(nil, 1, wwwtop-atoi(s)); + doprev(nil, 1, curtab->wwwtop-atoi(s)); else message("Usage: j index"); break; case 'm': - mothon(current, !mothmode); + mothon(curtab->current, !curtab->mothmode); break; case 'k': - killpix(current); + killpix(curtab->current); break; case 'w': case 'W': @@ -702,17 +861,17 @@ break; case 's': s = arg(s); - if(!selection){ + if(!curtab->selection){ message("no url selected"); break; } if(s==0 || *s=='\0'){ - snprint(buf, sizeof(buf), "%s", urltofile(selection)); + snprint(buf, sizeof(buf), "%s", urltofile(curtab->selection)); if(eenter("Save to", buf, sizeof(buf), &mouse) <= 0) break; s = buf; } - save(urlget(selection, -1), s); + save(urlget(curtab->selection, -1), s); break; case 'q': exits(0); @@ -733,7 +892,7 @@ Rtext *tp; for(;;){ - if(current == nil || current->text == nil || text == nil) + if(curtab->current == nil || curtab->current->text == nil || curtab->text == nil) return; strncpy(buf, last, sizeof(buf)-1); if(eenter("Search for", buf, sizeof(buf), &mouse) <= 0) @@ -744,11 +903,11 @@ message("%r"); continue; } - for(tp=current->text;tp;tp=tp->next) + for(tp=curtab->current->text;tp;tp=tp->next) if(tp->flags & PL_SEL) break; if(tp == nil) - tp = current->text; + tp = curtab->current->text; else { tp->flags &= ~PL_SEL; tp = tp->next; @@ -758,13 +917,13 @@ if(tp->text && *tp->text) if(regexec(re, tp->text, nil, 0)){ tp->flags |= PL_SEL; - plsetpostextview(text, tp->topy); + plsetpostextview(curtab->text, tp->topy); break; } tp = tp->next; } free(re); - updtext(current); + updtext(curtab->current); } } @@ -784,7 +943,7 @@ USED(p); if(index < 0 || index >= nwww()) return; - i = wwwtop-index-1; + i = curtab->wwwtop-index-1; switch(buttons){ case 1: setcurrent(i, 0); /* no break ... */ case 2: selurl(www(i)->url->fullname); break; @@ -801,7 +960,7 @@ a=word->user; if(a == nil || (a->link == nil && a->image == nil)) return; - if(mothmode) + if(curtab->mothmode) hiturl(buttons, a->image ? a->image : a->link, 0); else if(a->link){ if(a->ismap){ @@ -955,13 +1114,13 @@ Url* selurl(char *urlname){ Url *last; - last=selection; - selection=emalloc(sizeof(Url)); - seturl(selection, urlname, current ? current->url->fullname : ""); + last=curtab->selection; + curtab->selection=emalloc(sizeof(Url)); + seturl(curtab->selection, urlname, curtab->current ? curtab->current->url->fullname : ""); if(last) freeurl(last); - message("selected: %s", urlstr(selection)); + message("selected: %s", urlstr(curtab->selection)); plgrabkb(cmd); /* for snarf */ - return selection; + return curtab->selection; } /* @@ -979,17 +1138,17 @@ } selurl(urlname); - selection->map=map; + curtab->selection->map=map; - message("getting %s", urlstr(selection)); + message("getting %s", urlstr(curtab->selection)); esetcursor(&patientcurs); for(;;){ - if((fd=urlget(selection, post)) < 0){ + if((fd=urlget(curtab->selection, post)) < 0){ message("%r"); break; } - message("getting %s", selection->fullname); - if(mothmode && !plumb) + message("getting %s", curtab->selection->fullname); + if(curtab->mothmode && !plumb) typ = -1; else typ = snooptype(fd); @@ -1000,7 +1159,7 @@ close(fd); break; } - snprint(cmd, sizeof(cmd), "%s", urltofile(selection)); + snprint(cmd, sizeof(cmd), "%s", urltofile(curtab->selection)); if(eenter("Save to", cmd, sizeof(cmd), &mouse) <= 0){ close(fd); break; @@ -1011,13 +1170,13 @@ fd = pipeline(fd, "exec uhtml"); case PLAIN: n=0; - for(i=wwwtop-1; i>=0 && i!=(wwwtop-NWWW-1); i--){ + for(i=curtab->wwwtop-1; i>=0 && i!=(curtab->wwwtop-NWWW-1); i--){ w = www(i); n += countpix(w->pix); if(n >= NPIXMB*1024*1024) killpix(w); } - w = www(i = wwwtop++); + w = www(i = curtab->wwwtop++); if(i >= NWWW){ /* wait for the reader to finish the document */ while(!w->finished && !w->alldone){ @@ -1031,10 +1190,10 @@ freeurl(w->url); memset(w, 0, sizeof(*w)); } - if(selection->map) - w->url=copyurl(current->url); + if(curtab->selection->map) + w->url=copyurl(curtab->current->url); else - w->url=copyurl(selection); + w->url=copyurl(curtab->selection); w->finished = 0; w->alldone = 0; gettext(w, fd, typ); @@ -1048,9 +1207,9 @@ } _exits(0); } - plinitlist(list, PACKN|FILLX, genwww, 8, doprev); - if(defdisplay) pldraw(list, screen); - setcurrent(i, selection->tag); + plinitlist(curtab->list, PACKN|FILLX, genwww, 4, doprev); + if(defdisplay) pldraw(curtab->list, screen); + setcurrent(i, curtab->selection->tag); break; case GIF: case JPEG: @@ -1068,7 +1227,7 @@ Rtext *t; Action *a; if(defdisplay && w->gottitle==0 && w->title[0]!='\0') - pldraw(list, screen); + pldraw(curtab->list, screen); for(t=w->text;t;t=t->next){ a=t->user; if(a){ @@ -1077,12 +1236,12 @@ a->field=0; } } - if(w != current) + if(w != curtab->current) return; - w->yoffs=plgetpostextview(text); - plinittextview(text, PACKE|EXPAND, Pt(0, 0), w->text, dolink); - plsetpostextview(text, w->yoffs); - pldraw(text, screen); + w->yoffs=plgetpostextview(curtab->text); + plinittextview(curtab->text, PACKE|EXPAND, Pt(0, 0), w->text, dolink); + plsetpostextview(curtab->text, w->yoffs); + pldraw(curtab->text, screen); } void finish(Www *w){ @@ -1096,9 +1255,9 @@ Rtext *t, *x; Action *a, *ap; - if(w==0 || mothmode==on) + if(w==0 || curtab->mothmode==on) return; - if(mothmode = on) + if(curtab->mothmode = on) message("moth mode!"); else message(mothra); @@ -1150,9 +1309,9 @@ } void snarf(Panel *p){ if(p==0 || p==cmd){ - if(selection){ - plputsnarf(urlstr(selection)); - plsnarf(text); + if(curtab->selection){ + plputsnarf(urlstr(curtab->selection)); + plsnarf(curtab->text); }else message("no url selected"); }else @@ -1169,24 +1328,24 @@ USED(button); switch(item){ case 0: - swap=root; - root=alt; - alt=swap; - if(current) - current->yoffs=plgetpostextview(text); - swap=text; - text=alttext; - alttext=swap; + swap=holder->child; + holder->child=curtab->alt; + curtab->alt=swap; + if(curtab->current) + curtab->current->yoffs=plgetpostextview(curtab->text); + swap=curtab->text; + curtab->text=curtab->alttext; + curtab->alttext=swap; defdisplay=!defdisplay; plpack(root, screen->r); - if(current){ - plinittextview(text, PACKE|EXPAND, Pt(0, 0), current->text, dolink); - plsetpostextview(text, current->yoffs); + if(curtab->current){ + plinittextview(curtab->text, PACKE|EXPAND, Pt(0, 0), curtab->current->text, dolink); + plsetpostextview(curtab->text, curtab->current->yoffs); } pldraw(root, screen); break; case 1: - mothon(current, !mothmode); + mothon(curtab->current, !curtab->mothmode); break; case 2: snarf(plkbfocus); @@ -1198,7 +1357,7 @@ search(); break; case 5: - if(!selection){ + if(!curtab->selection){ message("no url selected"); break; } @@ -1214,7 +1373,7 @@ fprint(fd, "

Hit list

\n"); } seek(fd, 0, 2); - fprint(fd, "

%s\n", urlstr(selection), urlstr(selection)); + fprint(fd, "

%s\n", urlstr(curtab->selection), urlstr(curtab->selection)); close(fd); break; case 6: diff -r 5ecb69a3c1a0 sys/src/cmd/mothra/mothra.h --- a/sys/src/cmd/mothra/mothra.h Mon Mar 06 03:07:03 2017 +0100 +++ b/sys/src/cmd/mothra/mothra.h Wed Mar 08 14:36:42 2017 -0800 @@ -1,7 +1,7 @@ enum{ - NWWW=64, /* # of pages we hold in the log */ - NXPROC=5, /* # of parallel procs loading the pix */ - NPIXMB=8, /* megabytes of image data to keep arround */ + NWWW=32, /* # of pages we hold in the log */ + NXPROC=2, /* # of parallel procs loading the pix */ + NPIXMB=32, /* megabytes of image data to keep arround */ NNAME=512, NLINE=256, NAUTH=128, @@ -10,6 +10,7 @@ NREDIR=10, /* # of redirections we'll tolerate before declaring a loop */ }; +typedef struct Tab Tab; typedef struct Action Action; typedef struct Url Url; typedef struct Www Www; @@ -43,6 +44,27 @@ int alldone; /* page will not change further -- used to adjust cursor */ }; +struct Tab{ + Panel *view; + + Panel *alt; + Panel *alttext; + Panel *list; + Panel *cururl; + Panel *text; /* Panel displaying the current www page */ + + Rtext *rtext; + + Www *current; + Url *selection; + int mothmode; + int wwwtop; + Www a[NWWW]; + + int id; + Tab *next; +}; + enum{ PLAIN, HTML, @@ -66,7 +88,7 @@ Image *hrule, *bullet, *linespace; int chrwidth; /* nominal width of characters in font */ -Panel *text; /* Panel displaying the current www page */ +extern Panel *root; int debug; /* command line flag */ /*