#include <plumb.h>
#include <cursor.h>
#include <panel.h>
+#include <regexp.h>
#include "mothra.h"
#include "rtext.h"
-int debug=0; /* -d flag causes debug messages to appear in mothra.err */
-int verbose=0; /* -v flag causes html errors to appear in mothra.err */
+int debug=0;
+int verbose=0; /* -v flag causes html errors to be written to file-descriptor 2 */
int defdisplay=1; /* is the default (initial) display visible? */
Panel *root; /* the whole display */
Panel *alt; /* the alternate display */
Panel *alttext; /* the alternate text window */
Panel *cmd; /* command entry */
-Panel *curttl; /* label giving the title of the visible text */
Panel *cururl; /* label giving the url of the visible text */
Panel *list; /* list of previously acquired www pages */
Panel *msg; /* message display */
"moth mode",
"snarf",
"paste",
+ "search",
"save hit",
"hit list",
"exit",
}
void mkpanels(void){
- Panel *p, *bar;
+ Panel *p, *bar, *swap;
+
menu3=plmenu(0, 0, buttons, PACKN|FILLX, hit3);
root=plpopup(root, EXPAND, 0, 0, menu3);
p=plgroup(root, PACKN|FILLX);
bar=plscrollbar(p, PACKW);
list=pllist(p, PACKN|FILLX, genwww, 8, doprev);
plscroll(list, 0, bar);
- p=plgroup(root, PACKN|FILLX);
- pllabel(p, PACKW, "Title:");
- curttl=pllabel(p, PACKE|EXPAND, "---");
- plplacelabel(curttl, PLACEW);
p=plgroup(root, PACKN|FILLX);
pllabel(p, PACKW, "Url:");
cururl=pllabel(p, PACKE|EXPAND, "---");
bar=plscrollbar(alt, PACKW|USERFL);
alttext=pltextview(alt, PACKE|EXPAND, Pt(0, 0), 0, dolink);
plscroll(alttext, 0, bar);
+
+ if(!defdisplay){
+ swap=root;
+ root=alt;
+ alt=swap;
+ swap=text;
+ text=alttext;
+ alttext=swap;
+ }
}
int cohort = -1;
void killcohort(void){
void dienow(void*, char*){
noted(NDFLT);
}
-int mkmfile(char *stem, int mode){
- char *henv;
- char filename[NNAME];
+
+char* mkhome(void){
+ static char *home; /* where to put files */
+ char *henv, *tmp;
int f;
- if(home[0]=='\0'){
+
+ if(home == nil){
henv=getenv("home");
if(henv){
- sprint(home, "%s/lib", henv);
- f=create(home, OREAD, DMDIR|0777);
+ tmp = smprint("%s/lib", henv);
+ f=create(tmp, OREAD, DMDIR|0777);
if(f!=-1) close(f);
- sprint(home, "%s/lib/mothra", henv);
+ free(tmp);
+
+ home = smprint("%s/lib/mothra", henv);
f=create(home, OREAD, DMDIR|0777);
if(f!=-1) close(f);
free(henv);
}
else
- strcpy(home, "/tmp");
+ home = strdup("/tmp");
}
- snprint(filename, sizeof(filename), "%s/%s", home, stem);
- f=create(filename, OWRITE, mode);
- if(f==-1)
- f=create(stem, OWRITE, mode);
- return f;
+ return home;
}
void donecurs(void){
}
void scrollto(char *tag);
+void search(void);
+
extern char *mtpt; /* url */
void main(int argc, char *argv[]){
Www *new;
Action *a;
char *url;
- int errfile;
int i;
quotefmtinstall();
case 'm':
if(mtpt = ARGF())
break;
+ case 'a': defdisplay=0; break;
default: goto Usage;
}ARGEND
switch(argc){
default:
Usage:
- fprint(2, "Usage: %s [-d] [-m mtpt] [url]\n", argv[0]);
+ fprint(2, "Usage: %s [-dva] [-m mtpt] [url]\n", argv0);
exits("usage");
case 0:
url=getenv("url");
break;
case 1: url=argv[0]; break;
}
- errfile=mkmfile("mothra.err", 0666);
- if(errfile!=-1){
- dup(errfile, 2);
- close(errfile);
- }
if(initdraw(0, 0, mothra) < 0)
sysfatal("initdraw: %r");
display->locking = 1;
bullet=allocimage(display, Rect(0,0,25, 8), screen->chan, 0, DWhite);
fillellipse(bullet, Pt(4,4), 3, 3, display->black, ZP);
mkpanels();
-
unlockdisplay(display);
eresized(0);
drawlock(1);
case Kend:
scrolltext(-text->size.y, 2);
break;
+ case Kack:
+ search();
+ break;
}
break;
case Emouse:
mouse=e.mouse;
- if(mouse.buttons & (8|16)){
+ if(mouse.buttons & (8|16) && ptinrect(mouse.xy, text->r)){
if(mouse.buttons & 8)
- scrolltext(-text->size.y/24, 1);
+ scrolltext(text->r.min.y - mouse.xy.y, 1);
else
- scrolltext(text->size.y/24, 1);
+ scrolltext(mouse.xy.y - text->r.min.y, 1);
break;
}
plmouse(root, &mouse);
r=screen->r;
plpack(root, r);
plpack(alt, r);
- draw(screen, r, display->white, 0, ZP);
+ pldraw(cmd, screen); /* put cmd box on screen for alt display */
pldraw(root, screen);
flushimage(display, 1);
drawlock(0);
char *genwww(Panel *, int index){
static char buf[1024];
+ Www *w;
int i;
if(index >= nwww())
return 0;
i = wwwtop-index-1;
- snprint(buf, sizeof(buf), "%2d %s", i+1, www(i)->title);
+ w = www(i);
+ if(!w->url)
+ return 0;
+ if(w->title[0]!='\0'){
+ w->gottitle=1;
+ snprint(buf, sizeof(buf), "%2d %s", i+1, w->title);
+ } else
+ snprint(buf, sizeof(buf), "%2d %s", i+1, urlstr(w->url));
return buf;
}
if(current)
current->yoffs=plgetpostextview(text);
current=new;
- plinitlabel(curttl, PACKE|EXPAND, current->title);
- if(defdisplay) pldraw(curttl, screen);
plinitlabel(cururl, PACKE|EXPAND, current->url->fullname);
if(defdisplay) pldraw(cururl, screen);
plinittextview(text, PACKE|EXPAND, Pt(0, 0), current->text, dolink);
exits(0);
}
plinitentry(cmd, EXPAND, 0, "", docmd);
- if(defdisplay) pldraw(cmd, screen);
+ pldraw(root, screen);
+}
+
+void search(void){
+ static char last[256];
+ char buf[256];
+ Reprog *re;
+ Rtext *tp;
+
+ for(;;){
+ if(current == nil || current->text == nil || text == nil)
+ return;
+ strncpy(buf, last, sizeof(buf)-1);
+ if(eenter("Search for", buf, sizeof(buf), &mouse) <= 0)
+ return;
+ re = regcompnl(buf);
+ if(re == nil)
+ return;
+ strncpy(last, buf, sizeof(buf)-1);
+ for(tp=current->text;tp;tp=tp->next)
+ if(tp->flags & PL_SEL)
+ break;
+ if(tp == nil)
+ tp = current->text;
+ else {
+ tp->flags &= ~PL_SEL;
+ tp = tp->next;
+ }
+ while(tp != nil){
+ tp->flags &= ~PL_SEL;
+ if(tp->text && *tp->text)
+ if(regexec(re, tp->text, nil, 0)){
+ tp->flags |= PL_SEL;
+ plsetpostextview(text, tp->topy);
+ break;
+ }
+ tp = tp->next;
+ }
+ free(re);
+ updtext(current);
+ }
}
void hiturl(int buttons, char *url, int map){
int yoffs;
Action *a;
+ /* really a button, hit it */
+ if(word->p != nil && word->p != p && strcmp(word->p->kind, "button") == 0){
+ extern void pl_buttonhit(Panel *p, int buttons, int check);
+ pl_buttonhit(word->p, buttons, 0);
+ return;
+ }
+
a=word->user;
- if(a == nil || a->image == nil && a->link == nil)
+ if(a == nil || (a->link == nil && a->image == nil))
return;
if(mothmode)
hiturl(buttons, a->image ? a->image : a->link, 0);
- else if(a->ismap){
- yoffs=plgetpostextview(p);
- coord=subpt(subpt(mouse.xy, word->r.min), p->r.min);
- snprint(mapurl, sizeof(mapurl), "%s?%d,%d", a->link, coord.x, coord.y+yoffs);
- hiturl(buttons, mapurl, 1);
- } else
- hiturl(buttons, a->link ? a->link : a->image, 0);
+ else if(a->link){
+ if(a->ismap){
+ yoffs=plgetpostextview(p);
+ coord=subpt(subpt(mouse.xy, word->r.min), p->r.min);
+ snprint(mapurl, sizeof(mapurl), "%s?%d,%d", a->link, coord.x, coord.y+yoffs);
+ hiturl(buttons, mapurl, 1);
+ } else
+ hiturl(buttons, a->link, 0);
+ }
}
-void filter(char *cmd, int fd){
- switch(rfork(RFFDG|RFPROC|RFMEM|RFNOWAIT)){
+void filter(int fd, char *cmd){
+ switch(rfork(RFFDG|RFPROC|RFMEM|RFREND|RFNOWAIT|RFNOTEG)){
case -1:
message("Can't fork!");
break;
case 0:
- close(0);
- dup(fd, 0);
- close(fd);
+ dupfds(fd, 1, 2, -1);
execl("/bin/rc", "rc", "-c", cmd, 0);
_exits(0);
}
plrtfree(tt);
}
-int pipeline(char *cmd, int fd)
+void
+dupfds(int fd, ...)
+{
+ int mfd, n, i;
+ va_list arg;
+ Dir *dir;
+
+ va_start(arg, fd);
+ for(mfd = 0; fd >= 0; fd = va_arg(arg, int), mfd++)
+ if(fd != mfd)
+ if(dup(fd, mfd) < 0)
+ sysfatal("dup: %r");
+ va_end(arg);
+ if((fd = open("/fd", OREAD)) < 0)
+ sysfatal("open: %r");
+ n = dirreadall(fd, &dir);
+ for(i=0; i<n; i++){
+ if(strstr(dir[i].name, "ctl"))
+ continue;
+ fd = atoi(dir[i].name);
+ if(fd >= mfd)
+ close(fd);
+ }
+ free(dir);
+}
+
+int pipeline(int fd, char *fmt, ...)
{
+ char buf[80], *argv[4];
+ va_list arg;
int pfd[2];
- if(pipe(pfd)==-1){
-Err:
+ va_start(arg, fmt);
+ vsnprint(buf, sizeof buf, fmt, arg);
+ va_end(arg);
+
+ if(pipe(pfd) < 0){
+ Err:
close(fd);
- werrstr("pipeline for %s failed: %r", cmd);
+ werrstr("pipeline for %s failed: %r", buf);
return -1;
}
- switch(fork()){
+ switch(rfork(RFPROC|RFMEM|RFFDG|RFREND|RFNOWAIT)){
case -1:
close(pfd[0]);
close(pfd[1]);
goto Err;
case 0:
- dup(fd, 0);
- dup(pfd[0], 1);
- close(pfd[0]);
- close(pfd[1]);
- execl("/bin/rc", "rc", "-c", cmd, 0);
+ dupfds(fd, pfd[1], 2, -1);
+ argv[0] = "rc";
+ argv[1] = "-c";
+ argv[2] = buf;
+ argv[3] = nil;
+ exec("/bin/rc", argv);
_exits(0);
}
- close(pfd[0]);
close(fd);
- return pfd[1];
+ close(pfd[1]);
+ return pfd[0];
}
char*
seturl(&url, urlname, current ? current->url->fullname : "");
selection=&url;
message("selected: %s", urlstr(selection));
+ plgrabkb(cmd); /* for snarf */
return selection;
}
void seturl(Url *url, char *urlname, char *base){
save(fd, cmd);
break;
case HTML:
- fd = pipeline("/bin/uhtml", fd);
+ fd = pipeline(fd, "exec uhtml");
case PLAIN:
n=0;
for(i=wwwtop-1; i>=0 && i!=(wwwtop-NWWW-1); i--){
case PNG:
case BMP:
case PAGE:
- filter("page -w", fd);
+ filter(fd, "exec page -w");
break;
}
break;
void updtext(Www *w){
Rtext *t;
Action *a;
+ if(defdisplay && w->gottitle==0 && w->title[0]!='\0')
+ pldraw(list, screen);
for(t=w->text;t;t=t->next){
a=t->user;
if(a){
w->yoffs=plgetpostextview(text);
plinittextview(text, PACKE|EXPAND, Pt(0, 0), w->text, dolink);
plsetpostextview(text, w->yoffs);
- pldraw(root, screen);
+ pldraw(text, screen);
}
void finish(Www *w){
*/
for(t=w->text;t;t=t->next){
a=t->user;
- if(a == nil || a->image == nil || a->link == nil)
+ if(a == nil || a->image == nil)
continue;
+ if(a->link == nil){
+ if(on)
+ t->flags |= PL_HOT;
+ else
+ t->flags &= ~PL_HOT;
+ continue;
+ }
x = t->next;
if(on){
t->next = nil;
plrtstr(&t->next, 0, 0, t->font, strdup("->"), PL_HOT, ap);
t->next->next = x;
} else {
- t->next = x->next;
- x->next = nil;
- freetext(x);
+ if(x) {
+ t->next = x->next;
+ x->next = nil;
+ freetext(x);
+ }
}
}
updtext(w);
updtext(w);
}
void snarf(Panel *p){
- if(p==0) p=cmd;
- plputsnarf(urlstr(selection));
- /* non-ops if nothing selected */
- plsnarf(p);
- plsnarf(text);
+ if(p==0 || p==cmd){
+ if(selection){
+ plputsnarf(urlstr(selection));
+ plsnarf(text);
+ }else
+ message("no url selected");
+ }else
+ plsnarf(p);
}
void paste(Panel *p){
if(p==0) p=cmd;
paste(plkbfocus);
break;
case 4:
- snprint(name, sizeof(name), "%s/hit.html", home);
+ search();
+ break;
+ case 5:
+ if(!selection){
+ message("no url selected");
+ break;
+ }
+ snprint(name, sizeof(name), "%s/hit.html", mkhome());
fd=open(name, OWRITE);
if(fd==-1){
fd=create(name, OWRITE, 0666);
fprint(fd, "<p><a href=\"%s\">%s</a>\n", urlstr(selection), urlstr(selection));
close(fd);
break;
- case 5:
- snprint(name, sizeof(name), "file:%s/hit.html", home);
+ case 6:
+ snprint(name, sizeof(name), "file:%s/hit.html", mkhome());
geturl(name, -1, 1, 0);
break;
- case 6:
+ case 7:
if(confirm(3))
exits(0);
break;