int newwin;
int rotate;
int viewgen;
+int forward; /* read ahead direction: >= 0 forwards, < 0 backwards */
Point resize, pos;
Page *root, *current;
Page lru;
MiB = 1024*1024,
};
-ulong imemlimit = 8*MiB;
+ulong imemlimit = 16*MiB;
ulong imemsize;
Image *frame, *paper, *ground;
return;
/* add rio border */
size = addpt(size, Pt(Borderwidth*2, Borderwidth*2));
- if(display->image){
+ if(display->image != nil){
Point dsize = subpt(display->image->r.max, display->image->r.min);
if(size.x > dsize.x)
size.x = dsize.x;
char mnt[32], cmd[64], *argv[4];
seek(p->fd, 0, 0);
- snprint(mnt, sizeof(mnt), "/n/tapefs.%.12d%.8lux", getpid(), (ulong)p);
+ snprint(mnt, sizeof(mnt), "/n/tapefs.%.12d%.8lux", getpid(), (ulong)(uintptr)p);
snprint(cmd, sizeof(cmd), "exec %s -m %s /fd/0", (char*)p->data, mnt);
switch(rfork(RFPROC|RFMEM|RFFDG|RFREND)){
case -1:
while(n > 0 && s[n-1] == '\n')
n--;
s[n] = 0;
- addpage(p, buf, popenfile, strdup(buf), -1);
+ addpage(p, s, popenfile, strdup(buf), -1);
}
close(fd);
return -1;
Page*
nextpage(Page *p)
{
- if(p && p->down)
+ if(p != nil && p->down != nil)
return p->down;
- while(p){
- if(p->next)
+ while(p != nil){
+ if(p->next != nil)
return p->next;
p = p->up;
}
{
Page *p, *t;
- if(x){
- for(p = root->down; p; p = t)
+ if(x != nil){
+ for(p = root->down; p != nil; p = t)
if((t = nextpage(p)) == x)
return p;
}
p->lprev = nil;
}
-void
-loadpage(Page *p)
+static void
+llinkhead(Page *p)
{
- int fd;
-
- qlock(&lru);
lunlink(p);
p->lnext = lru.lnext;
p->lprev = &lru;
p->lnext->lprev = p;
p->lprev->lnext = p;
+}
+
+void
+loadpage(Page *p)
+{
+ int fd;
+
+ qlock(&lru);
+ llinkhead(p);
qunlock(&lru);
- if(p->open && p->image == nil){
+ if(p->open != nil && p->image == nil){
fd = openpage(p);
if(fd >= 0){
if((p->image = readimage(display, fd, 1)) == nil)
void
loadpages(Page *p, int oviewgen)
{
- while(p && viewgen == oviewgen){
+ while(p != nil && viewgen == oviewgen){
qlock(p);
loadpage(p);
if(viewgen != oviewgen){
unlockdisplay(display);
}
qunlock(p);
- if(p != current || imemsize >= imemlimit)
- break;
- p = nextpage(p);
+ if(p != current && imemsize >= imemlimit)
+ break; /* only one page ahead once we reach the limit */
+ if(forward < 0){
+ if(p->up == nil || p->up->down == p)
+ break;
+ p = prevpage(p);
+ } else {
+ if(p->next == nil)
+ break;
+ p = nextpage(p);
+ }
}
}
dr = r;
for(sp=dr.min; dr.min.x < r.max.x; sp.x++){
dr.max.x = dr.min.x+1;
- if(b) gendrawdiff(d, dr, top, b, sp, nil, ZP, SoverD);
+ if(b != nil) gendrawdiff(d, dr, top, b, sp, nil, ZP, SoverD);
gendrawdiff(d, dr, top, t, sp, nil, ZP, SoverD);
for(dr.min.x++; ++a.x < f && dr.min.x < r.max.x; dr.min.x++){
dr.max.x = dr.min.x+1;
Point
pagesize(Page *p)
{
- return p->image ? mulpt(subpt(p->image->r.max, p->image->r.min), zoom) : ZP;
+ return p->image != nil ? mulpt(subpt(p->image->r.max, p->image->r.min), zoom) : ZP;
}
void
Rectangle r;
Image *i;
- if(i = p->image){
+ if((i = p->image) != nil){
r = rectaddpt(Rpt(ZP, pagesize(p)), addpt(pos, screen->r.min));
zoomdraw(screen, r, ZR, paper, i, i->r.min, zoom);
} else {
Image *i;
i = p->image;
- if(i==0 || d.x==0 && d.y==0)
+ if(i==nil || d.x==0 && d.y==0)
return;
r = rectaddpt(Rpt(ZP, pagesize(p)), addpt(pos, screen->r.min));
pos = addpt(pos, d);
nr = rectaddpt(r, d);
- rectclip(&r, screen->r);
- draw(screen, rectaddpt(r, d), screen, nil, r.min);
+ if(rectclip(&r, screen->r))
+ draw(screen, rectaddpt(r, d), screen, nil, r.min);
+ else
+ r = ZR;
zoomdraw(screen, nr, rectaddpt(r, d), paper, i, i->r.min, zoom);
drawframe(nr);
}
pagewalk = nil;
memset(buf, 0, sizeof(buf));
snprint(buf, sizeof(buf), "%s%s%s",
- name ? name : "",
- (name && addr) ? "!" : "",
- addr ? addr : "");
+ name != nil ? name : "",
+ (name != nil && addr != nil) ? "!" : "",
+ addr != nil ? addr : "");
pagewalk = buf;
a = nil;
- if(root){
+ if(root != nil){
p = root->down;
Loop:
- for(; p; p = p->next)
+ for(; p != nil; p = p->next)
if(pagewalk1(p)){
a = p;
p = p->down;
Page*
findpage(char *name)
{
- static char buf[NPATH], *f[32];
Page *p;
int n;
n = strlen(name);
/* look in current document */
- if(current && current->up){
- for(p = current->up->down; p; p = p->next)
+ if(current != nil && current->up != nil){
+ for(p = current->up->down; p != nil; p = p->next)
if(cistrncmp(p->name, name, n) == 0)
return p;
}
/* look everywhere */
- if(root){
- for(p = root->down; p; p = nextpage(p))
+ if(root != nil){
+ for(p = root->down; p != nil; p = nextpage(p))
if(cistrncmp(p->name, name, n) == 0)
return p;
}
return trywalk(name, nil);
}
+void
+writeaddr(Page *p, char *file)
+{
+ char buf[NPATH], *s;
+ int fd;
+
+ s = pageaddr(p, buf, sizeof(buf));
+ if((fd = open(file, OWRITE)) >= 0){
+ write(fd, s, strlen(s));
+ close(fd);
+ }
+}
+
Page*
pageat(int i)
{
Page *p;
- for(p = root->down; i > 0 && p; p = nextpage(p))
+ for(p = root->down; i > 0 && p != nil; p = nextpage(p))
i--;
return i ? nil : p;
}
Page *p;
int i;
- for(i = 0, p = root->down; p && p != x; p = nextpage(p))
+ for(i = 0, p = root->down; p != nil && p != x; p = nextpage(p))
i++;
return (p == x) ? i : -1;
}
{
Page *p;
- if(p = pageat(i))
+ if((p = pageat(i)) != nil)
return shortlabel(p->name);
return nil;
}
if(p == nil)
return;
esetcursor(&reading);
+ writeaddr(p, "/dev/label");
current = p;
oviewgen = viewgen;
switch(rfork(RFPROC|RFMEM)){
if(p == nil)
return;
drawlock(0);
- if(p->image == nil)
- unloadpages(imemlimit/2);
+ unloadpages(imemlimit);
showpage1(p);
drawlock(1);
}
-void
-shownext(void)
-{
- Page *p;
-
- for(p = nextpage(current); p; p = nextpage(p))
- if(p->image || p->open)
- break;
- showpage(p);
-}
-
-void
-showprev(void)
-{
- Page *p;
-
- for(p = prevpage(current); p; p = prevpage(p))
- if(p->image || p->open)
- break;
- showpage(p);
-}
-
void
zerox(Page *p)
{
return;
snprint(label, sizeof(label), "%s %s", p->ext, p->name);
ps = Pt(0, 0);
- if(p->image)
+ if(p->image != nil)
ps = addpt(subpt(p->image->r.max, p->image->r.min), Pt(24, 24));
drawlock(0);
if((fd = p->fd) < 0){
fd = dup(fd, -1);
seek(fd, 0, 0);
}
- if(rfork(RFPROC|RFMEM|RFFDG|RFNOTEG|RFNOWAIT) == 0){
+ if(rfork(RFPROC|RFMEM|RFFDG|RFNOTEG|RFREND|RFNOWAIT) == 0){
if(newwindow(nil) != -1){
dupfds(fd, open("/dev/cons", OWRITE), open("/dev/cons", OWRITE), -1);
if((fd = open("/dev/label", OWRITE)) >= 0){
drawlock(1);
}
-
-void
-snarfaddr(Page *p)
-{
- char buf[NPATH], *s;
- int fd;
-
- s = pageaddr(p, buf, sizeof(buf));
- if((fd = open("/dev/snarf", OWRITE)) >= 0){
- write(fd, s, strlen(s));
- close(fd);
- }
-}
-
void
eresized(int new)
{
drawlock(1);
if(new && getwindow(display, Refnone) == -1)
sysfatal("getwindow: %r");
- if(p = current){
+ if((p = current) != nil){
if(canqlock(p)){
drawpage(p);
qunlock(p);
case Cwrite:
if(current == nil || !canqlock(current))
break;
- if(current->image){
+ if(current->image != nil){
s = nil;
- if(current->up && current->up != root)
+ if(current->up != nil && current->up != root)
s = current->up->name;
snprint(buf, sizeof(buf), "%s%s%s.bit",
- s ? s : "",
- s ? "." : "",
+ s != nil ? s : "",
+ s != nil ? "." : "",
current->name);
if(eenter("Write", buf, sizeof(buf), m) > 0){
if((fd = create(buf, OWRITE, 0666)) < 0){
qunlock(current);
break;
case Csnarf:
- snarfaddr(current);
+ writeaddr(current, "/dev/snarf");
break;
case Cnext:
- shownext();
+ forward = 1;
+ showpage(nextpage(current));
break;
case Cprev:
- showprev();
+ forward = -1;
+ showpage(prevpage(current));
break;
case Czerox:
zerox(current);
}
}
+void
+scroll(int y)
+{
+ Point z;
+ Page *p;
+
+ if(current == nil || !canqlock(current))
+ return;
+ if(y < 0){
+ if(pos.y >= 0){
+ p = prevpage(current);
+ if(p != nil){
+ qunlock(current);
+ z = ZP;
+ if(canqlock(p)){
+ z = pagesize(p);
+ qunlock(p);
+ }
+ if(z.y == 0)
+ z.y = Dy(screen->r);
+ if(pos.y+z.y > Dy(screen->r))
+ pos.y = Dy(screen->r) - z.y;
+ forward = -1;
+ showpage(p);
+ return;
+ }
+ y = 0;
+ }
+ } else {
+ z = pagesize(current);
+ if(pos.y+z.y <= Dy(screen->r)){
+ p = nextpage(current);
+ if(p != nil){
+ qunlock(current);
+ if(pos.y < 0)
+ pos.y = 0;
+ forward = 1;
+ showpage(p);
+ return;
+ }
+ y = 0;
+ }
+ }
+ translate(current, Pt(0, -y));
+ qunlock(current);
+}
+
void
main(int argc, char *argv[])
{
ground = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x777777FF);
display->locking = 1;
unlockdisplay(display);
- drawlock(1);
einit(Ekeyboard|Emouse);
eplumb(Eplumb, "image");
for(; *argv; argv++)
addpage(root, *argv, popenfile, strdup(*argv), -1);
+ drawlock(1);
for(;;){
drawlock(0);
i=event(&e);
pagemenu.lasthit = pageindex(current);
x = pageat(emenuhit(3, &m, &pagemenu));
qunlock(&pagelock);
+ forward = 0;
showpage(x);
}
+ } else if(m.buttons & 8){
+ scroll(screen->r.min.y - m.xy.y);
+ } else if(m.buttons & 16){
+ scroll(m.xy.y - screen->r.min.y);
}
break;
case Ekeyboard:
switch(e.kbdc){
case Kup:
- if(current == nil || !canqlock(current))
- break;
- if(pos.y < 0){
- translate(current, Pt(0, Dy(screen->r)/2));
- qunlock(current);
- break;
- }
- if(prevpage(current))
- pos.y = 0;
- qunlock(current);
- docmd(Cprev, &m);
+ scroll(-Dy(screen->r)/3);
+ break;
+ case Kpgup:
+ scroll(-Dy(screen->r)/2);
break;
case Kdown:
- if(current == nil || !canqlock(current))
- break;
- o = addpt(pos, pagesize(current));
- if(o.y > Dy(screen->r)){
- translate(current, Pt(0, -Dy(screen->r)/2));
- qunlock(current);
- break;
- }
- if(nextpage(current))
- pos.y = 0;
- qunlock(current);
- docmd(Cnext, &m);
+ scroll(Dy(screen->r)/3);
+ break;
+ case Kpgdown:
+ scroll(Dy(screen->r)/2);
break;
default:
for(i = 0; i<nelem(cmds); i++)
(e.kbdc & 0xFF00) == Spec)
break;
snprint(buf, sizeof(buf), "%C", (Rune)e.kbdc);
- if(eenter("Go to", buf, sizeof(buf), &m) > 0)
+ if(eenter("Go to", buf, sizeof(buf), &m) > 0){
+ forward = 0;
showpage(findpage(buf));
+ }
}
break;
case Eplumb:
j = trywalk(s, plumblookup(pm->attr, "addr"));
if(j == nil){
current = root;
+ drawlock(0);
j = addpage(root, s, popenfile, s, fd);
+ drawlock(1);
}
+ forward = 0;
showpage(j);
}
Plumbfree: