ref: 3a0587ee001a5ae643695eca9033b29a24a17d4c
dir: /page-del/
diff 855cf4326f5a07d7142c2d8918f5fa856d912b85 uncommitted --- a/sys/src/cmd/page.c +++ b/sys/src/cmd/page.c @@ -74,7 +74,10 @@ Czerox, Cwrite, Cext, + Cpop, Cdummy2, + Cdelete, + Cdummy3, Cquit, }; @@ -98,7 +101,10 @@ [Czerox] "zerox", 'z', 0, 0, [Cwrite] "write", 'w', 0, 0, [Cext] "ext", 'x', 0, 0, + [Cpop] "pop", 'p', 0, 0, [Cdummy2] "", 0, 0, 0, + [Cdelete] "delete", 'D', 0, 0, + [Cdummy3] "", 0, 0, 0, [Cquit] "quit", 'q', Kdel, Keof, }; @@ -134,6 +140,7 @@ void showpage(Page *); void drawpage(Page *); Point pagesize(Page *); +void drawlock(int); Page* addpage(Page *up, char *name, int (*popen)(Page *), void *pdata, int fd) @@ -986,6 +993,71 @@ } } +/* page entries are never freed, there's no point + * and would break everything */ +Page* +poppage(Page *p) +{ + Page *t, *q; + + if(p == nil) + return nil; + if(p->up != root) + return p; + qlock(&pagelock); + for(t = p->down; t != nil && t->up != root; t = q){ + qlock(t); + drawlock(0); + unloadpage(t); + drawlock(1); + free(t->name); + free(t->data); + t->name = t->data = nil; + q = nextpage(t); + qunlock(t); + } + drawlock(0); + unloadpage(p); + drawlock(1); + free(p->name); + free(p->data); + p->name = p->data = nil; + t = prevpage(p); + if(root->tail == p) + root->tail = t; + if(root->down == p || t == nil) + root->down = p->next; + else + t->next = p->next; + qunlock(&pagelock); + qunlock(p); + if(p->next != nil){ + forward = 1; + return p->next; + } + forward = -1; + return t; +} + +Page* +delpage(Page *p) +{ + if(p == nil) + return nil; + /* to remove(2) subpages in documents makes no sense, and just + * removing a subentry doesn't seem like a feature worth the bother */ + if(p->up != root) + return p; + if(p->fd >= 0) + close(p->fd); + p->fd = -1; + if(remove(p->name) < 0){ + fprint(2, "remove %s: %r", p->name); + return p; + } + return poppage(p); +} + /* * A draw operation that touches only the area contained in bot but not in top. * mp and sp get aligned with bot.min. @@ -1461,6 +1533,7 @@ char buf[NPATH], *s; Point o; int fd; + Page *p; switch(i){ case Corigsize: @@ -1546,6 +1619,28 @@ case Csnarf: writeaddr(current, "/dev/snarf"); break; + case Cpop: + if(current == nil || !canqlock(current)) + break; + if((p = poppage(current)) == current) + break; + Reset: + current = p; + if(current == nil){ + drawlock(0); + draw(screen, screen->r, paper, nil, ZP); + drawframe(screen->r); + drawlock(1); + break; + } + showpage(current); + break; + case Cdelete: + if(current == nil || !canqlock(current)) + break; + if((p = delpage(current)) == current) + break; + goto Reset; case Cnext: forward = 1; showpage(nextpage(current));