aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/page/view.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2007-03-26 20:55:26 +0000
committerrsc <devnull@localhost>2007-03-26 20:55:26 +0000
commit05a4d855f167ae2d0d2c0ba0e386d933172b71ea (patch)
tree8a1c64cf67479d8cab98b70fd25a12929f566634 /src/cmd/page/view.c
parent6c4c5c5b959ec8a2e85510bdf85339582f638f36 (diff)
downloadplan9port-05a4d855f167ae2d0d2c0ba0e386d933172b71ea.tar.gz
plan9port-05a4d855f167ae2d0d2c0ba0e386d933172b71ea.tar.bz2
plan9port-05a4d855f167ae2d0d2c0ba0e386d933172b71ea.zip
add page (Kris Maglione)
Diffstat (limited to 'src/cmd/page/view.c')
-rw-r--r--src/cmd/page/view.c342
1 files changed, 151 insertions, 191 deletions
diff --git a/src/cmd/page/view.c b/src/cmd/page/view.c
index 1cdb2541..ab409cc7 100644
--- a/src/cmd/page/view.c
+++ b/src/cmd/page/view.c
@@ -4,17 +4,19 @@
#include <u.h>
#include <libc.h>
+#include <9pclient.h>
#include <draw.h>
#include <cursor.h>
-#include <cursor.h>
-#include <event.h>
+#include <mouse.h>
+#include <keyboard.h>
+#include <thread.h>
#include <bio.h>
#include <plumb.h>
#include <ctype.h>
-#include <keyboard.h>
#include "page.h"
Document *doc;
+Mousectl *mc;
Image *im;
int page;
int angle = 0;
@@ -26,6 +28,7 @@ Point ul; /* the upper left corner of the image is at this point on the screen
Point pclip(Point, Rectangle);
Rectangle mkrange(Rectangle screenr, Rectangle imr);
void redraw(Image*);
+void plumbproc(void*);
Cursor reading={
{-1, -1},
@@ -56,20 +59,13 @@ enum {
Middle = 2,
Right = 4,
- RMenu = 3
+ RMenu = 3,
};
void
unhide(void)
{
- static int wctl = -1;
-
- if(wctl < 0)
- wctl = open("/dev/wctl", OWRITE);
- if(wctl < 0)
- return;
-
- write(wctl, "unhide", 6);
+ USED(nil);
}
int
@@ -126,7 +122,7 @@ showpage(int page, Menu *m)
else
m->lasthit = reverse ? doc->npage-1-page : page;
- esetcursor(&reading);
+ setcursor(mc, &reading);
freeimage(im);
if((page < 0 || page >= doc->npage) && !doc->fwdonly){
im = nil;
@@ -169,7 +165,7 @@ showpage(int page, Menu *m)
break;
}
- esetcursor(nil);
+ setcursor(mc, nil);
if(showbottom){
ul.y = screen->r.max.y - Dy(im->r);
showbottom = 0;
@@ -186,7 +182,7 @@ writebitmap(void)
char name[64+30];
static char result[200];
char *p, *q;
- int fd;
+ int fd = -1;
if(im == nil)
return "no image";
@@ -209,18 +205,18 @@ writebitmap(void)
snprint(name, sizeof(name)-1, "%s.%d.bit", q, page+1);
if(access(name, 0) >= 0) {
strcat(name, "XXXX");
- mktemp(name);
+ fd = mkstemp(name);
}
- if(access(name, 0) >= 0)
+ if(fd < 0)
return "couldn't think of a name for bitmap";
} else {
strcpy(name, "bitXXXX");
- mktemp(name);
- if(access(name, 0) >= 0)
+ mkstemp(name);
+ if(fd < 0)
return "couldn't think of a name for bitmap";
}
- if((fd = create(name, OWRITE, 0666)) < 0) {
+ if(fd < 0) {
snprint(result, sizeof result, "cannot create %s: %r", name);
return result;
}
@@ -265,7 +261,7 @@ enum{
Del,
Write,
Empty3,
- Exit
+ Exit,
};
void
@@ -273,11 +269,14 @@ viewer(Document *dd)
{
int i, fd, n, oldpage;
int nxt;
+ Channel *cp;
Menu menu, midmenu;
Mouse m;
- Event e;
+ Keyboardctl *kc;
Point dxy, oxy, xy0;
+ Rune run;
Rectangle r;
+ int size[2];
Image *tmp;
static char *fwditems[] = { "this page", "next page", "exit", 0 };
static char *miditems[] = {
@@ -299,16 +298,44 @@ viewer(Document *dd)
0
};
char *s;
- enum { Eplumb = 4 };
+ enum {
+ CMouse,
+ CResize,
+ CKeyboard,
+ CPlumb,
+ CN
+ };
+ Alt alts[CN+1];
Plumbmsg *pm;
+ cp = chancreate(sizeof pm, 0);
+ assert(cp);
+
doc = dd; /* save global for menuhit */
ul = screen->r.min;
- einit(Emouse|Ekeyboard);
- if(doc->addpage != nil)
- eplumb(Eplumb, "image");
+ mc = initmouse(nil, screen);
+ kc = initkeyboard(nil);
+ alts[CMouse].c = mc->c;
+ alts[CMouse].v = &m;
+ alts[CMouse].op = CHANRCV;
+ alts[CResize].c = mc->resizec;
+ alts[CResize].v = &size;
+ alts[CResize].op = CHANRCV;
+ alts[CKeyboard].c = kc->c;
+ alts[CKeyboard].v = &run;
+ alts[CKeyboard].op = CHANRCV;
+ alts[CPlumb].c = cp;
+ alts[CPlumb].v = &pm;
+ alts[CPlumb].op = CHANNOP;
+ alts[CN].op = CHANEND;
+
+ /* XXX: Event */
+ if(doc->addpage != nil) {
+ alts[CPlumb].op = CHANRCV;
+ proccreate(plumbproc, cp, 16384);
+ }
- esetcursor(&reading);
+ setcursor(mc, &reading);
r.min = ZP;
/*
@@ -336,7 +363,7 @@ viewer(Document *dd)
midmenu.lasthit = Next;
showpage(page, &menu);
- esetcursor(nil);
+ setcursor(mc, nil);
nxt = 0;
for(;;) {
@@ -345,14 +372,14 @@ viewer(Document *dd)
* a fair amount. we don't care about doc->npage anymore, and
* all that can be done is select the next page.
*/
- switch(eread(Emouse|Ekeyboard|Eplumb, &e)){
- case Ekeyboard:
- if(e.kbdc <= 0xFF && isdigit(e.kbdc)) {
- nxt = nxt*10+e.kbdc-'0';
+ switch(alt(alts)) {
+ case CKeyboard:
+ if(run <= 0xFF && isdigit(run)) {
+ nxt = nxt*10+run-'0';
break;
- } else if(e.kbdc != '\n')
+ } else if(run != '\n')
nxt = 0;
- switch(e.kbdc) {
+ switch(run) {
case 'r': /* reverse page order */
if(doc->fwdonly)
break;
@@ -372,12 +399,12 @@ viewer(Document *dd)
}
break;
case 'w': /* write bitmap of current screen */
- esetcursor(&reading);
+ setcursor(mc, &reading);
s = writebitmap();
if(s)
string(screen, addpt(screen->r.min, Pt(5,5)), display->black, ZP,
display->defaultfont, s);
- esetcursor(nil);
+ setcursor(mc, nil);
flushimage(display, 1);
break;
case 'd': /* remove image from working set */
@@ -397,9 +424,9 @@ viewer(Document *dd)
case 'u':
if(im==nil)
break;
- esetcursor(&reading);
+ setcursor(mc, &reading);
rot180(im);
- esetcursor(nil);
+ setcursor(mc, nil);
angle = (angle+180) % 360;
redraw(screen);
flushimage(display, 1);
@@ -470,15 +497,14 @@ viewer(Document *dd)
}
break;
default:
- esetcursor(&query);
+ setcursor(mc, &query);
sleep(1000);
- esetcursor(nil);
+ setcursor(mc, nil);
break;
}
break;
- case Emouse:
- m = e.mouse;
+ case CMouse:
switch(m.buttons){
case Left:
oxy = m.xy;
@@ -487,7 +513,7 @@ viewer(Document *dd)
dxy = subpt(m.xy, oxy);
oxy = m.xy;
translate(dxy);
- m = emouse();
+ recv(mc->c, &m);
} while(m.buttons == Left);
if(m.buttons) {
dxy = subpt(xy0, oxy);
@@ -499,7 +525,7 @@ viewer(Document *dd)
if(doc->npage == 0)
break;
- n = emenuhit(Middle, &m, &midmenu);
+ n = menuhit(Middle, mc, &midmenu, nil);
if(n == -1)
break;
switch(n){
@@ -543,7 +569,7 @@ viewer(Document *dd)
double delta;
Rectangle r;
- r = egetrect(Middle, &m);
+ r = getrect(Middle, mc);
if((rectclip(&r, rectaddpt(im->r, ul)) == 0) ||
Dx(r) == 0 || Dy(r) == 0)
break;
@@ -553,7 +579,7 @@ viewer(Document *dd)
else
delta = (double)Dy(im->r)/(double)Dy(r);
- esetcursor(&reading);
+ setcursor(mc, &reading);
tmp = xallocimage(display,
Rect(0, 0, (int)((double)Dx(im->r)*delta), (int)((double)Dy(im->r)*delta)),
im->chan, 0, DBlack);
@@ -564,7 +590,7 @@ viewer(Document *dd)
resample(im, tmp);
freeimage(im);
im = tmp;
- esetcursor(nil);
+ setcursor(mc, nil);
ul = screen->r.min;
redraw(screen);
flushimage(display, 1);
@@ -580,7 +606,7 @@ viewer(Document *dd)
delta = (double)Dy(screen->r)/(double)Dy(im->r);
r = Rect(0, 0, (int)((double)Dx(im->r)*delta), (int)((double)Dy(im->r)*delta));
- esetcursor(&reading);
+ setcursor(mc, &reading);
tmp = xallocimage(display, r, im->chan, 0, DBlack);
if(tmp == nil) {
fprint(2, "out of memory during fit: %r\n");
@@ -589,16 +615,16 @@ viewer(Document *dd)
resample(im, tmp);
freeimage(im);
im = tmp;
- esetcursor(nil);
+ setcursor(mc, nil);
ul = screen->r.min;
redraw(screen);
flushimage(display, 1);
break;
}
case Rot: /* rotate 90 */
- esetcursor(&reading);
+ setcursor(mc, &reading);
im = rot90(im);
- esetcursor(nil);
+ setcursor(mc, nil);
angle = (angle+90) % 360;
redraw(screen);
flushimage(display, 1);
@@ -606,9 +632,9 @@ viewer(Document *dd)
case Upside: /* upside-down */
if(im==nil)
break;
- esetcursor(&reading);
+ setcursor(mc, &reading);
rot180(im);
- esetcursor(nil);
+ setcursor(mc, nil);
angle = (angle+180) % 360;
redraw(screen);
flushimage(display, 1);
@@ -628,12 +654,12 @@ viewer(Document *dd)
}
break;
case Write: /* write */
- esetcursor(&reading);
+ setcursor(mc, &reading);
s = writebitmap();
if(s)
string(screen, addpt(screen->r.min, Pt(5,5)), display->black, ZP,
display->defaultfont, s);
- esetcursor(nil);
+ setcursor(mc, nil);
flushimage(display, 1);
break;
case Del: /* delete */
@@ -663,7 +689,7 @@ viewer(Document *dd)
break;
oldpage = page;
- n = emenuhit(RMenu, &m, &menu);
+ n = menuhit(RMenu, mc, &menu, nil);
if(n == -1)
break;
@@ -691,9 +717,15 @@ viewer(Document *dd)
break;
}
break;
-
- case Eplumb:
- pm = e.v;
+ case CResize:
+ r = screen->r;
+ if(getwindow(display, Refnone) < 0)
+ fprint(2,"can't reattach to window");
+ ul = addpt(ul, subpt(screen->r.min, r.min));
+ redraw(screen);
+ flushimage(display, 1);
+ break;
+ case CPlumb:
if(pm->ndata <= 0){
plumbfree(pm);
break;
@@ -866,18 +898,7 @@ redraw(Image *screen)
}
}
border(screen, r, -4000, gray, ZP);
-/* flushimage(display, 0); */
-}
-
-void
-eresized(int new)
-{
- Rectangle r;
- r = screen->r;
- if(new && getwindow(display, Refnone) < 0)
- fprint(2,"can't reattach to window");
- ul = addpt(ul, subpt(screen->r.min, r.min));
- redraw(screen);
+// flushimage(display, 0);
}
/* clip p to be in r */
@@ -909,21 +930,17 @@ resize(int dx, int dy)
static Rectangle sr;
Rectangle r, or;
- dx += 2*Borderwidth;
- dy += 2*Borderwidth;
- if(wctlfd < 0){
- wctlfd = open("/dev/wctl", OWRITE);
- if(wctlfd < 0)
- return;
+ r = screen->r;
+ if(Dx(sr)*Dy(sr) == 0) {
+ sr = screenrect();
+ /* Start with the size of the first image */
+ r.max.x = r.min.x;
+ r.max.y = r.min.y;
}
- r = insetrect(screen->r, -Borderwidth);
if(Dx(r) >= dx && Dy(r) >= dy)
return;
- if(Dx(sr)*Dy(sr) == 0)
- sr = screenrect();
-
or = r;
r.max.x = max(r.min.x+dx, r.max.x);
@@ -950,8 +967,7 @@ resize(int dx, int dy)
if(Dx(r) == Dx(or) && Dy(r) == Dy(or))
return;
- fprint(wctlfd, "resize -minx %d -miny %d -maxx %d -maxy %d\n",
- r.min.x, r.min.y, r.max.x, r.max.y);
+ drawresizewindow(r);
}
/*
@@ -966,129 +982,73 @@ xallocimage(Display *d, Rectangle r, ulong chan, int repl, ulong val)
return allocimage(d, r, chan, repl, val);
}
-/* all code below this line should be in the library, but is stolen from colors instead */
-static 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, "page: can't malloc: %r\n");
- wexits("no mem");
- }
- seek(fd, 0, 0);
- read(fd, v, size);
- v[size] = 0;
- close(fd);
- return v;
-}
-
void
-newwin(void)
+plumbproc(void *c)
{
- char *srv, *mntsrv;
- char spec[100];
- int srvfd, cons, pid;
-
- switch(rfork(RFFDG|RFPROC|RFNAMEG|RFENVG|RFNOTEG|RFNOWAIT)){
- case -1:
- fprint(2, "page: can't fork: %r\n");
- wexits("no fork");
- case 0:
- break;
- default:
- wexits(0);
+ Channel *cp;
+ CFid *fd;
+
+ cp = c;
+ fd = plumbopenfid("image", OREAD|OCEXEC);
+ if(fd == nil) {
+ fprint(2, "Cannot connect to the plumber");
+ threadexits("plumber");
}
-
- srv = rdenv("/env/wsys");
- if(srv == 0){
- mntsrv = rdenv("/mnt/term/env/wsys");
- if(mntsrv == 0){
- fprint(2, "page: can't find $wsys\n");
- wexits("srv");
- }
- srv = malloc(strlen(mntsrv)+10);
- sprint(srv, "/mnt/term%s", mntsrv);
- free(mntsrv);
- pid = 0; /* can't send notes to remote processes! */
- }else
- pid = getpid();
- srvfd = open(srv, ORDWR);
- free(srv);
- if(srvfd == -1){
- fprint(2, "page: can't open %s: %r\n", srv);
- wexits("no srv");
- }
- sprint(spec, "new -pid %d", pid);
- if(mount(srvfd, -1, "/mnt/wsys", 0, spec) == -1){
- fprint(2, "page: can't mount /mnt/wsys: %r (spec=%s)\n", spec);
- wexits("no mount");
- }
- close(srvfd);
- unmount("/mnt/acme", "/dev");
- bind("/mnt/wsys", "/dev", MBEFORE);
- cons = open("/dev/cons", OREAD);
- if(cons==-1){
- NoCons:
- fprint(2, "page: can't open /dev/cons: %r");
- wexits("no cons");
+ for(;;) {
+ send(cp, plumbrecvfid(fd));
}
- dup(cons, 0);
- close(cons);
- cons = open("/dev/cons", OWRITE);
- if(cons==-1)
- goto NoCons;
- dup(cons, 1);
- dup(cons, 2);
- close(cons);
-/* wctlfd = open("/dev/wctl", OWRITE); */
}
+/* XXX: This function is ugly and hacky. There may be a better way... or not */
Rectangle
screenrect(void)
{
- int fd;
- char buf[12*5];
-
- fd = open("/dev/screen", OREAD);
- if(fd == -1)
- fd=open("/mnt/term/dev/screen", OREAD);
- if(fd == -1){
- fprint(2, "page: can't open /dev/screen: %r\n");
- wexits("window read");
- }
- if(read(fd, buf, sizeof buf) != sizeof buf){
- fprint(2, "page: can't read /dev/screen: %r\n");
- wexits("screen read");
- }
- close(fd);
- return Rect(atoi(buf+12), atoi(buf+24), atoi(buf+36), atoi(buf+48));
+ int fd[3], pfd[2];
+ int n, w, h;
+ char buf[64];
+ char *p, *pr;
+
+ if(pipe(pfd) < 0)
+ wexits("pipe failed");
+
+ fd[0] = open("/dev/null", OREAD);
+ fd[1] = pfd[1];
+ fd[2] = dup(2, -1);
+ if(threadspawnl(fd, "rc", "rc", "-c", "xdpyinfo | grep 'dimensions:'", nil) == -1)
+ wexits("threadspawnl failed");
+
+ if((n = read(pfd[0], buf, 63)) <= 0)
+ wexits("read xdpyinfo failed");
+ close(fd[0]);
+
+ buf[n] = '\0';
+ for(p = buf; *p; p++)
+ if(*p >= '0' && *p <= '9') break;
+ if(*p == '\0')
+ wexits("xdpyinfo parse failed");
+
+ w = strtoul(p, &pr, 10);
+ if(p == pr || *pr == '\0' || *(++pr) == '\0')
+ wexits("xdpyinfo parse failed");
+ h = strtoul(pr, &p, 10);
+ if(p == pr)
+ wexits("xdpyinfo parse failed");
+
+ return Rect(0, 0, w, h);
}
void
zerox(void)
{
int pfd[2];
+ int fd[3];
pipe(pfd);
- switch(rfork(RFFDG|RFPROC)) {
- case -1:
- wexits("cannot fork in zerox: %r");
- case 0:
- dup(pfd[1], 0);
- close(pfd[0]);
- execl("/bin/page", "page", "-w", nil);
- wexits("cannot exec in zerox: %r\n");
- default:
- close(pfd[1]);
- writeimage(pfd[0], im, 0);
- close(pfd[0]);
- break;
- }
+ fd[0] = pfd[0];
+ fd[1] = dup(1, -1);
+ fd[2] = dup(2, -1);
+ threadspawnl(fd, "page", "page", "-R", nil);
+
+ writeimage(pfd[1], im, 0);
+ close(pfd[1]);
}