tadd page (Kris Maglione) - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 05a4d855f167ae2d0d2c0ba0e386d933172b71ea | |
parent 6c4c5c5b959ec8a2e85510bdf85339582f638f36 | |
Author: rsc <devnull@localhost> | |
Date: Mon, 26 Mar 2007 20:55:26 +0000 | |
add page (Kris Maglione) | |
Diffstat: | |
M src/cmd/mkfile | 2 +- | |
M src/cmd/page/filter.c | 28 +++++++++++++++------------- | |
M src/cmd/page/gfx.c | 94 +++++++++--------------------… | |
M src/cmd/page/gs.c | 175 +++++++++++++----------------… | |
M src/cmd/page/mkfile | 10 ++++++++++ | |
M src/cmd/page/nrotate.c | 6 +++--- | |
M src/cmd/page/page.c | 76 +++++++++++++++++++++++++++--… | |
M src/cmd/page/page.h | 30 +++++++++++++++++++++++++++++- | |
M src/cmd/page/pdf.c | 8 ++++---- | |
M src/cmd/page/pdfprolog.c | 19 +++++-------------- | |
M src/cmd/page/pdfprolog.ps | 19 +++++-------------- | |
M src/cmd/page/ps.c | 10 +++++----- | |
M src/cmd/page/rotate.c | 30 +++++++++++++++--------------- | |
M src/cmd/page/util.c | 79 ++++++++++++++---------------… | |
M src/cmd/page/view.c | 342 ++++++++++++++---------------… | |
15 files changed, 448 insertions(+), 480 deletions(-) | |
--- | |
diff --git a/src/cmd/mkfile b/src/cmd/mkfile | |
t@@ -4,7 +4,7 @@ TARG=`ls *.[cy] *.lx | egrep -v "\.tab\.c$|^x\." | sed 's/\.[c… | |
<$PLAN9/src/mkmany | |
-BUGGERED='CVS|faces|factotum|lp|ip|mailfs|page|scat|upas|vncv|mnihongo|mpm|ind… | |
+BUGGERED='CVS|faces|factotum|lp|ip|mailfs|scat|upas|vncv|mnihongo|mpm|index|u9… | |
DIRS=lex `ls -l |sed -n 's/^d.* //p' |egrep -v "^($BUGGERED)$"|egrep -v '^lex$… | |
<$PLAN9/src/mkdirs | |
diff --git a/src/cmd/page/filter.c b/src/cmd/page/filter.c | |
t@@ -1,9 +1,9 @@ | |
#include <u.h> | |
#include <libc.h> | |
#include <draw.h> | |
-#include <cursor.h> | |
-#include <event.h> | |
+#include <thread.h> | |
#include <bio.h> | |
+#include <cursor.h> | |
#include "page.h" | |
Document* | |
t@@ -24,7 +24,7 @@ initfilt(Biobuf *b, int argc, char **argv, uchar *buf, int n… | |
if(docopy){ | |
if(pipe(p) < 0){ | |
fprint(2, "pipe fails: %r\n"); | |
- exits("Epipe"); | |
+ threadexits("Epipe"); | |
} | |
}else{ | |
p[0] = open("/dev/null", ORDWR); | |
t@@ -35,27 +35,29 @@ initfilt(Biobuf *b, int argc, char **argv, uchar *buf, int… | |
switch(fork()){ | |
case -1: | |
fprint(2, "fork fails: %r\n"); | |
- exits("Efork"); | |
+ threadexits("Efork"); | |
default: | |
- close(p[1]); | |
+ close(p[0]); | |
if(docopy){ | |
- write(p[0], buf, nbuf); | |
+ write(p[1], buf, nbuf); | |
if(b) | |
while((n = Bread(b, xbuf, sizeof xbuf)) > 0) | |
- write(p[0], xbuf, n); | |
+ write(p[1], xbuf, n); | |
else | |
while((n = read(stdinfd, xbuf, sizeof xbuf)) >… | |
- write(p[0], xbuf, n); | |
+ write(p[1], xbuf, n); | |
} | |
- close(p[0]); | |
+ close(p[1]); | |
waitpid(); | |
break; | |
case 0: | |
- close(p[0]); | |
- dup(p[1], 0); | |
+ close(p[1]); | |
+ dup(p[0], 0); | |
dup(ofd, 1); | |
/* stderr shines through */ | |
- execl("/bin/rc", "rc", "-c", cmd, nil); | |
+ if(chatty) | |
+ fprint(2, "Execing '%s'\n", cmd); | |
+ execlp("rc", "rc", "-c", cmd, nil); | |
break; | |
} | |
t@@ -81,7 +83,7 @@ initdvi(Biobuf *b, int argc, char **argv, uchar *buf, int nb… | |
*/ | |
if(b == nil){ /* standard input; spool to disk (ouch) */ | |
fd = spooltodisk(buf, nbuf, &name); | |
- sprint(fdbuf, "/fd/%d", fd); | |
+ sprint(fdbuf, "/dev/fd/%d", fd); | |
b = Bopen(fdbuf, OREAD); | |
if(b == nil){ | |
fprint(2, "cannot open disk spool file\n"); | |
diff --git a/src/cmd/page/gfx.c b/src/cmd/page/gfx.c | |
t@@ -5,14 +5,13 @@ | |
#include <u.h> | |
#include <libc.h> | |
#include <draw.h> | |
-#include <cursor.h> | |
-#include <event.h> | |
+#include <thread.h> | |
#include <bio.h> | |
+#include <cursor.h> | |
#include "page.h" | |
typedef struct Convert Convert; | |
typedef struct GfxInfo GfxInfo; | |
-typedef struct Graphic Graphic; | |
struct Convert { | |
char *name; | |
t@@ -24,29 +23,6 @@ struct GfxInfo { | |
Graphic *g; | |
}; | |
-struct Graphic { | |
- int type; | |
- char *name; | |
- uchar *buf; /* if stdin */ | |
- int nbuf; | |
-}; | |
- | |
-enum { | |
- Ipic, | |
- Itiff, | |
- Ijpeg, | |
- Igif, | |
- Iinferno, | |
- Ifax, | |
- Icvt2pic, | |
- Iplan9bm, | |
- Iccittg4, | |
- Ippm, | |
- Ipng, | |
- Iyuv, | |
- Ibmp | |
-}; | |
- | |
/* | |
* N.B. These commands need to read stdin if %a is replaced | |
* with an empty string. | |
t@@ -65,15 +41,14 @@ Convert cvt[] = { | |
[Iccittg4] { "ccitt-g4", "cat %a|rx nslocum /usr/lib/ocr/bin/bcp… | |
[Ipng] { "png", "png -9 %a", "png -t9 %a" }, | |
[Iyuv] { "yuv", "yuv -9 %a", "yuv -t9 %a" }, | |
-[Ibmp] { "bmp", "bmp -9 %a", "bmp -t9 %a" } | |
+[Ibmp] { "bmp", "bmp -9 %a", "bmp -t9 %a" }, | |
}; | |
-static Image* convert(Graphic*); | |
static Image* gfxdrawpage(Document *d, int page); | |
static char* gfxpagename(Document*, int); | |
-static int spawnrc(char*, uchar*, int); | |
-static void waitrc(void); | |
-static int spawnpost(int); | |
+static int spawnrc(char*, Graphic*); | |
+//static void waitrc(void); | |
+//static int spawnpost(int); | |
static int addpage(Document*, char*); | |
static int rmpage(Document*, int); | |
static int genaddpage(Document*, char*, uchar*, int); | |
t@@ -202,12 +177,12 @@ genaddpage(Document *doc, char *name, uchar *buf, int nb… | |
else | |
g->type = Icvt2pic; | |
- if(name) | |
+ if(name){ | |
g->name = estrdup(name); | |
- else{ | |
+ g->fd = -1; | |
+ }else{ | |
g->name = estrdup("stdin"); /* so it can be freed */ | |
- g->buf = buf; | |
- g->nbuf = nbuf; | |
+ g->fd = stdinpipe(buf, nbuf); | |
} | |
if(chatty) fprint(2, "classified \"%s\" as \"%s\"\n", g->name, cvt[g->… | |
t@@ -244,7 +219,7 @@ rmpage(Document *doc, int n) | |
} | |
-static Image* | |
+Image* | |
convert(Graphic *g) | |
{ | |
int fd; | |
t@@ -253,25 +228,24 @@ convert(Graphic *g) | |
char *name, buf[1000]; | |
Image *im; | |
int rcspawned = 0; | |
- Waitmsg *w; | |
c = cvt[g->type]; | |
if(c.cmd == nil) { | |
if(chatty) fprint(2, "no conversion for bitmap \"%s\"...\n", g… | |
- if(g->buf == nil){ /* not stdin */ | |
+ if(g->fd < 0){ /* not stdin */ | |
fd = open(g->name, OREAD); | |
if(fd < 0) { | |
fprint(2, "cannot open file: %r\n"); | |
wexits("open"); | |
} | |
}else | |
- fd = stdinpipe(g->buf, g->nbuf); | |
+ fd = g->fd; | |
} else { | |
cmd = c.cmd; | |
if(truecolor && c.truecmd) | |
cmd = c.truecmd; | |
- if(g->buf != nil) /* is stdin */ | |
+ if(g->fd >= 0) /* is pipe */ | |
name = ""; | |
else | |
name = g->name; | |
t@@ -281,7 +255,7 @@ convert(Graphic *g) | |
} | |
snprint(buf, sizeof buf, cmd, name); | |
if(chatty) fprint(2, "using \"%s\" to convert \"%s\"...\n", bu… | |
- fd = spawnrc(buf, g->buf, g->nbuf); | |
+ fd = spawnrc(buf, g); | |
rcspawned++; | |
if(fd < 0) { | |
fprint(2, "cannot spawn converter: %r\n"); | |
t@@ -293,43 +267,31 @@ convert(Graphic *g) | |
if(im == nil) { | |
fprint(2, "warning: couldn't read image: %r\n"); | |
} | |
- close(fd); | |
- /* for some reason rx doesn't work well with wait */ | |
- /* for some reason 3to1 exits on success with a non-null status of |3t… | |
- if(rcspawned && g->type != Iccittg4) { | |
- if((w=wait())!=nil && w->msg[0] && !strstr(w->msg, "3to1")) | |
- fprint(2, "slave wait error: %s\n", w->msg); | |
- free(w); | |
- } | |
+ close(fd); | |
return im; | |
} | |
static int | |
-spawnrc(char *cmd, uchar *stdinbuf, int nstdinbuf) | |
+spawnrc(char *cmd, Graphic *g) | |
{ | |
int pfd[2]; | |
- int pid; | |
+ int fd[3]; | |
if(chatty) fprint(2, "spawning(%s)...", cmd); | |
if(pipe(pfd) < 0) | |
return -1; | |
- if((pid = fork()) < 0) | |
+ | |
+ if(g->fd > 0) | |
+ fd[0] = dup(g->fd, -1); | |
+ else | |
+ fd[0] = open("/dev/null", OREAD); | |
+ fd[1] = pfd[1]; | |
+ fd[2] = dup(2, -1); | |
+ | |
+ if(threadspawnl(fd, "rc", "rc", "-c", cmd, nil) == -1) | |
return -1; | |
- if(pid == 0) { | |
- close(pfd[1]); | |
- if(stdinbuf) | |
- dup(stdinpipe(stdinbuf, nstdinbuf), 0); | |
- else | |
- dup(open("/dev/null", OREAD), 0); | |
- dup(pfd[0], 1); | |
- /*dup(pfd[0], 2); */ | |
- execl("/bin/rc", "rc", "-c", cmd, nil); | |
- wexits("exec"); | |
- } | |
- close(pfd[0]); | |
- return pfd[1]; | |
+ return pfd[0]; | |
} | |
- | |
diff --git a/src/cmd/page/gs.c b/src/cmd/page/gs.c | |
t@@ -7,9 +7,9 @@ | |
#include <u.h> | |
#include <libc.h> | |
#include <draw.h> | |
-#include <cursor.h> | |
-#include <event.h> | |
+#include <thread.h> | |
#include <bio.h> | |
+#include <cursor.h> | |
#include "page.h" | |
static int gspid; /* globals for atexit */ | |
t@@ -37,87 +37,41 @@ killgs(void) | |
postnote(PNPROC, gspid, "die yankee pig dog"); | |
} | |
-int | |
-spawnwriter(GSInfo *g, Biobuf *b) | |
+void | |
+spawnreader(void *cp) | |
{ | |
- char buf[4096]; | |
- int n; | |
- int fd; | |
+ int n, fd, pfd[2]; | |
+ char buf[1024]; | |
- switch(fork()){ | |
- case -1: return -1; | |
- case 0: break; | |
- default: return 0; | |
- } | |
+ recv(cp, &fd); | |
- Bseek(b, 0, 0); | |
- fd = g->gsfd; | |
- while((n = Bread(b, buf, sizeof buf)) > 0) | |
- write(fd, buf, n); | |
- fprint(fd, "(/fd/3) (w) file dup (THIS IS NOT AN INFERNO BITMAP\\n) wr… | |
- _exits(0); | |
- return -1; | |
-} | |
+ if(pipe(pfd)<0) | |
+ wexits("pipe failed"); | |
-int | |
-spawnreader(int fd) | |
-{ | |
- int n, pfd[2]; | |
- char buf[1024]; | |
+ send(cp, &pfd[1]); | |
- if(pipe(pfd)<0) | |
- return -1; | |
- switch(fork()){ | |
- case -1: | |
- return -1; | |
- case 0: | |
- break; | |
- default: | |
- close(pfd[0]); | |
- return pfd[1]; | |
+ while((n=read(pfd[0], buf, sizeof buf)) > 0) { | |
+ write(1, buf, n); | |
+ write(fd, buf, n); | |
} | |
- close(pfd[1]); | |
- switch(fork()){ | |
- case -1: | |
- wexits("fork failed"); | |
- case 0: | |
- while((n=read(fd, buf, sizeof buf)) > 0) { | |
- write(1, buf, n); | |
- write(pfd[0], buf, n); | |
- } | |
- break; | |
- default: | |
- while((n=read(pfd[0], buf, sizeof buf)) > 0) { | |
- write(1, buf, n); | |
- write(fd, buf, n); | |
- } | |
- break; | |
- } | |
- postnote(PNGROUP, getpid(), "i'm die-ing"); | |
- _exits(0); | |
- return -1; | |
+ close(pfd[0]); | |
+ threadexits(0); | |
} | |
void | |
-spawnmonitor(int fd) | |
+spawnmonitor(void *cp) | |
{ | |
char buf[4096]; | |
char *xbuf; | |
+ int fd; | |
int n; | |
int out; | |
int first; | |
- switch(rfork(RFFDG|RFNOTEG|RFPROC)){ | |
- case -1: | |
- default: | |
- return; | |
- | |
- case 0: | |
- break; | |
- } | |
+ recv(cp, &fd); | |
- out = open("/dev/cons", OWRITE); | |
+ out = open("/dev/tty", OWRITE); | |
if(out < 0) | |
out = 2; | |
t@@ -131,17 +85,19 @@ spawnmonitor(int fd) | |
write(out, xbuf, n); | |
alarm(500); | |
} | |
- _exits(0); | |
+ threadexits(0); | |
} | |
int | |
spawngs(GSInfo *g, char *safer) | |
{ | |
+ Channel *cp; | |
char *args[16]; | |
char tb[32], gb[32]; | |
int i, nargs; | |
int devnull; | |
- int stdinout[2]; | |
+ int stdinp[2]; | |
+ int stdoutp[2]; | |
int dataout[2]; | |
int errout[2]; | |
t@@ -153,15 +109,15 @@ spawngs(GSInfo *g, char *safer) | |
* gs output written to fd 1 (i.e. ouptut gs generates on error) is fe… | |
* gs data output is written to fd 3, which is dataout. | |
*/ | |
- if(pipe(stdinout) < 0 || pipe(dataout)<0 || pipe(errout)<0) | |
+ if(pipe(stdinp)<0 || pipe(stdoutp)<0 || pipe(dataout)<0 || pipe(errout… | |
return -1; | |
nargs = 0; | |
args[nargs++] = "gs"; | |
args[nargs++] = "-dNOPAUSE"; | |
- args[nargs++] = safer; | |
- args[nargs++] = "-sDEVICE=plan9"; | |
- args[nargs++] = "-sOutputFile=/fd/3"; | |
+ args[nargs++] = "-dDELAYSAFER"; | |
+ args[nargs++] = "-sDEVICE=bmp16m"; | |
+ args[nargs++] = "-sOutputFile=/dev/fd/3"; | |
args[nargs++] = "-dQUIET"; | |
args[nargs++] = "-r100"; | |
sprint(tb, "-dTextAlphaBits=%d", textbits); | |
t@@ -175,9 +131,10 @@ spawngs(GSInfo *g, char *safer) | |
gspid = fork(); | |
if(gspid == 0) { | |
- close(stdinout[1]); | |
- close(dataout[1]); | |
- close(errout[1]); | |
+ close(stdinp[1]); | |
+ close(stdoutp[0]); | |
+ close(dataout[0]); | |
+ close(errout[0]); | |
/* | |
* Horrible problem: we want to dup fd's 0-4 below, | |
t@@ -189,36 +146,49 @@ spawngs(GSInfo *g, char *safer) | |
while((devnull = open("/dev/null", ORDWR)) < 5) | |
; | |
- stdinout[0] = dup(stdinout[0], -1); | |
- errout[0] = dup(errout[0], -1); | |
- dataout[0] = dup(dataout[0], -1); | |
+ stdinp[0] = dup(stdinp[0], -1); | |
+ stdoutp[1] = dup(stdoutp[1], -1); | |
+ errout[1] = dup(errout[1], -1); | |
+ dataout[1] = dup(dataout[1], -1); | |
- dup(stdinout[0], 0); | |
- dup(errout[0], 1); | |
- dup(devnull, 2); /* never anything useful */ | |
- dup(dataout[0], 3); | |
- dup(stdinout[0], 4); | |
+ dup(stdinp[0], 0); | |
+ dup(errout[1], 1); | |
+ dup(errout[1], devnull); /* never anything useful */ | |
+ dup(dataout[1], 3); | |
+ dup(stdoutp[1], 4); | |
for(i=5; i<20; i++) | |
close(i); | |
- exec("/bin/gs", args); | |
+ execvp("gs", args); | |
wexits("exec"); | |
} | |
- close(stdinout[0]); | |
- close(errout[0]); | |
- close(dataout[0]); | |
+ close(stdinp[0]); | |
+ close(stdoutp[1]); | |
+ close(errout[1]); | |
+ close(dataout[1]); | |
atexit(killgs); | |
- if(teegs) | |
- stdinout[1] = spawnreader(stdinout[1]); | |
+ cp = chancreate(sizeof(int), 0); | |
+ if(teegs) { | |
+ proccreate(spawnreader, cp, mainstacksize); | |
+ send(cp, &stdoutp[0]); | |
+ recv(cp, &stdoutp[0]); | |
+ } | |
- gsfd = g->gsfd = stdinout[1]; | |
- g->gsdfd = dataout[1]; | |
+ gsfd = g->gsfd = stdinp[1]; | |
g->gspid = gspid; | |
+ g->g.fd = dataout[0]; | |
+ g->g.name = "gs pipe"; | |
+ g->g.type = Ibmp; | |
+ | |
+ proccreate(spawnmonitor, cp, mainstacksize); | |
+ send(cp, &errout[0]); | |
+ chanfree(cp); | |
- spawnmonitor(errout[1]); | |
- Binit(&g->gsrd, g->gsfd, OREAD); | |
+ Binit(&g->gsrd, stdoutp[0], OREAD); | |
- gscmd(g, "/PAGEOUT (/fd/4) (w) file def\n"); | |
+ gscmd(g, "/PAGEOUT (/dev/fd/4) (w) file def\n"); | |
+ if(!strcmp(safer, "-dSAFER")) | |
+ gscmd(g, ".setsafe\n"); | |
gscmd(g, "/PAGE== { PAGEOUT exch write==only PAGEOUT (\\n) writestring… | |
waitgs(g); | |
t@@ -269,11 +239,14 @@ setdim(GSInfo *gs, Rectangle bbox, int ppi, int landscap… | |
if(!Dx(bbox)) | |
bbox = Rect(0, 0, 612, 792); /* 8½×11 */ | |
- if(landscape) | |
- pbox = Rect(bbox.min.y, bbox.min.x, bbox.max.y, bbox.max.x); | |
- else | |
+ switch(landscape){ | |
+ case 0: | |
pbox = bbox; | |
- | |
+ break; | |
+ default: | |
+ pbox = Rect(bbox.min.y, bbox.min.x, bbox.max.y, bbox.max.x); | |
+ break; | |
+ } | |
gscmd(gs, "/PageSize [%d %d]\n", Dx(pbox), Dy(pbox)); | |
gscmd(gs, "/Margins [%d %d]\n", -pbox.min.x, -pbox.min.y); | |
gscmd(gs, "currentdevice putdeviceprops pop\n"); | |
t@@ -305,10 +278,10 @@ waitgs(GSInfo *gs) | |
uchar buf[1024]; | |
int n; | |
-/* gscmd(gs, "(\\n**bstack\\n) print flush\n"); */ | |
-/* gscmd(gs, "stack flush\n"); */ | |
-/* gscmd(gs, "(**estack\\n) print flush\n"); */ | |
- gscmd(gs, "(\\n/*GO.SYSIN DD\\n) PAGE==\n"); */ | |
+// gscmd(gs, "(\\n**bstack\\n) print flush\n"); | |
+// gscmd(gs, "stack flush\n"); | |
+// gscmd(gs, "(**estack\\n) print flush\n"); | |
+ gscmd(gs, "(\\n//GO.SYSIN DD\\n) PAGE==\n"); | |
alarm(300*1000); | |
for(;;) { | |
diff --git a/src/cmd/page/mkfile b/src/cmd/page/mkfile | |
t@@ -14,8 +14,18 @@ OFILES=\ | |
util.$O\ | |
view.$O\ | |
+LIB=$PLAN9/lib/libdraw.a | |
+ | |
+UPDATE=\ | |
+ mkfile\ | |
+ ${OFILES:%.$O=%.c}\ | |
+ pdfprolog.ps\ | |
+ $HFILES\ | |
+ | |
<$PLAN9/src/mkone | |
+BIN=$PLAN9/bin | |
+ | |
pdfprolog.c: pdfprolog.ps | |
cat pdfprolog.ps | sed 's/.*/"&\\n"/g' >pdfprolog.c | |
diff --git a/src/cmd/page/nrotate.c b/src/cmd/page/nrotate.c | |
t@@ -15,15 +15,15 @@ | |
#include <libc.h> | |
#include <bio.h> | |
#include <draw.h> | |
+#include <thread.h> | |
#include <cursor.h> | |
-#include <event.h> | |
#include "page.h" | |
int ndraw = 0; | |
enum { | |
Xaxis, | |
- Yaxis | |
+ Yaxis, | |
}; | |
static void reverse(Image*, Image*, int); | |
t@@ -229,7 +229,7 @@ swapadjacent(Image *img, Image *tmp, int axis, int imgdim,… | |
/* | |
* r0 is the lower rectangle, while r1 is the upper one. | |
*/ | |
- draw(tmp, tmp->r, img, nil | |
+ draw(tmp, tmp->r, img, nil, | |
} | |
void | |
diff --git a/src/cmd/page/page.c b/src/cmd/page/page.c | |
t@@ -1,9 +1,10 @@ | |
#include <u.h> | |
#include <libc.h> | |
#include <draw.h> | |
-#include <cursor.h> | |
-#include <event.h> | |
+#include <thread.h> | |
+#include <thread.h> | |
#include <bio.h> | |
+#include <cursor.h> | |
#include "page.h" | |
int resizing; | |
t@@ -16,10 +17,45 @@ int ppi = 100; | |
int teegs = 0; | |
int truetoboundingbox; | |
int textbits=4, gfxbits=4; | |
-int wctlfd = -1; | |
int stdinfd; | |
int truecolor; | |
int imagemode; | |
+int notewatcher; | |
+int notegp; | |
+ | |
+int | |
+watcher(void *v, char *x) | |
+{ | |
+ USED(v); | |
+ if(strcmp(x, "die") != 0) | |
+ postnote(PNGROUP, notegp, x); | |
+ threadexitsall(0); | |
+ return 0; | |
+} | |
+ | |
+int | |
+bell(void *u, char *x) | |
+{ | |
+ if(x && strcmp(x, "hangup") == 0) | |
+ threadexitsall(0); | |
+ | |
+ if(x && strstr(x, "die") == nil) | |
+ fprint(2, "postnote %d: %s\n", getpid(), x); | |
+ | |
+ /* alarms come from the gs monitor */ | |
+ if(x && strstr(x, "alarm")){ | |
+ postnote(PNGROUP, getpid(), "die (gs error)"); | |
+ postnote(PNPROC, notewatcher, "die (gs error)"); | |
+ } | |
+ | |
+ /* function mentions u so that it's in the stack trace */ | |
+ if((u == nil || u != x) && doabort) | |
+ abort(); | |
+ | |
+/* fprint(2, "exiting %d\n", getpid()); */ | |
+ wexits("note"); | |
+ return 0; | |
+} | |
static int | |
afmt(Fmt *fmt) | |
t@@ -37,14 +73,15 @@ void | |
usage(void) | |
{ | |
fprint(2, "usage: page [-biRrw] [-p ppi] file...\n"); | |
- exits("usage"); | |
+ wexits("usage"); | |
} | |
void | |
-main(int argc, char **argv) | |
+threadmain(int argc, char **argv) | |
{ | |
Document *doc; | |
Biobuf *b; | |
+ char *basename = argv[0]; | |
enum { Ninput = 16 }; | |
uchar buf[Ninput+1]; | |
int readstdin; | |
t@@ -82,7 +119,7 @@ main(int argc, char **argv) | |
truetoboundingbox = 1; | |
break; | |
case 'w': | |
- mknewwindow = 1; | |
+ fprint(2, "%s: -w has only the effect of -R X11 systems\n", ba… | |
resizing = 1; | |
break; | |
case 'i': | |
t@@ -92,14 +129,30 @@ main(int argc, char **argv) | |
usage(); | |
}ARGEND; | |
+ notegp = getpid(); | |
+ | |
+ switch(notewatcher = fork()){ | |
+ case -1: | |
+ sysfatal("fork\n"); | |
+ threadexitsall(0); | |
+ default: | |
+ break; | |
+ case 0: | |
+ atnotify(watcher, 1); | |
+ for(;;) | |
+ sleep(1000); | |
+ /* not reached */ | |
+ } | |
+ | |
rfork(RFNOTEG); | |
+ atnotify(bell, 1); | |
readstdin = 0; | |
if(imagemode == 0 && argc == 0){ | |
readstdin = 1; | |
stdinfd = dup(0, -1); | |
close(0); | |
- open("/dev/cons", OREAD); | |
+ open("/dev/tty", OREAD); | |
} | |
quotefmtinstall(); | |
t@@ -107,8 +160,9 @@ main(int argc, char **argv) | |
fmtinstall('R', Rfmt); | |
fmtinstall('P', Pfmt); | |
+ /* | |
if(mknewwindow) | |
- newwin(); | |
+ newwin(); */ | |
if(readstdin){ | |
b = nil; | |
t@@ -179,5 +233,9 @@ main(int argc, char **argv) | |
void | |
wexits(char *s) | |
{ | |
- exits(s); | |
+ if(s && *s && strcmp(s, "note") != 0 && mknewwindow) | |
+ sleep(10*1000); | |
+ postnote(PNPROC, notewatcher, "die"); | |
+ postnote(PNGROUP, getpid(), "die"); | |
+ threadexitsall(s); | |
} | |
diff --git a/src/cmd/page/page.h b/src/cmd/page/page.h | |
t@@ -1,3 +1,5 @@ | |
+#undef pipe | |
+ | |
typedef struct Document Document; | |
struct Document { | |
t@@ -12,6 +14,31 @@ struct Document { | |
void *extra; | |
}; | |
+typedef struct Graphic Graphic; | |
+ | |
+struct Graphic { | |
+ int type; | |
+ int fd; | |
+ char *name; | |
+}; | |
+ | |
+enum { | |
+ Ipic, | |
+ Itiff, | |
+ Ijpeg, | |
+ Igif, | |
+ Iinferno, | |
+ Ifax, | |
+ Icvt2pic, | |
+ Iplan9bm, | |
+ Iccittg4, | |
+ Ippm, | |
+ Ipng, | |
+ Iyuv, | |
+ Ibmp, | |
+}; | |
+ | |
+ | |
void *emalloc(int); | |
void *erealloc(void*, int); | |
char *estrdup(char*); | |
t@@ -48,10 +75,10 @@ Image *resample(Image*, Image*); | |
/* ghostscript interface shared by ps, pdf */ | |
typedef struct GSInfo GSInfo; | |
struct GSInfo { | |
+ Graphic g; | |
int gsfd; | |
Biobuf gsrd; | |
int gspid; | |
- int gsdfd; | |
int ppi; | |
}; | |
void waitgs(GSInfo*); | |
t@@ -70,6 +97,7 @@ void wexits(char*); | |
Image* xallocimage(Display*, Rectangle, ulong, int, ulong); | |
int bell(void*, char*); | |
int opentemp(char *template); | |
+Image* convert(Graphic *g); | |
extern int stdinfd; | |
extern int truecolor; | |
diff --git a/src/cmd/page/pdf.c b/src/cmd/page/pdf.c | |
t@@ -8,7 +8,7 @@ | |
#include <libc.h> | |
#include <draw.h> | |
#include <cursor.h> | |
-#include <event.h> | |
+#include <thread.h> | |
#include <bio.h> | |
#include "page.h" | |
t@@ -66,7 +66,7 @@ initpdf(Biobuf *b, int argc, char **argv, uchar *buf, int nb… | |
fprint(2, "reading through pdf...\n"); | |
if(b == nil){ /* standard input; spool to disk (ouch) */ | |
fd = spooltodisk(buf, nbuf, &fn); | |
- sprint(fdbuf, "/fd/%d", fd); | |
+ sprint(fdbuf, "/dev/fd/%d", fd); | |
b = Bopen(fdbuf, OREAD); | |
if(b == nil){ | |
fprint(2, "cannot open disk spool file\n"); | |
t@@ -122,7 +122,7 @@ initpdf(Biobuf *b, int argc, char **argv, uchar *buf, int … | |
pdf->pagebbox = emalloc(sizeof(Rectangle)*npage); | |
for(i=0; i<npage; i++) { | |
gscmd(&pdf->gs, "%d pdfgetpage\n", i+1); | |
- pdf->pagebbox[i] = pdfbbox(pdf); | |
+ pdf->pagebbox[i] = pdfbbox(&pdf->gs); | |
if(Dx(pdf->pagebbox[i]) <= 0) | |
pdf->pagebbox[i] = bbox; | |
} | |
t@@ -136,7 +136,7 @@ pdfdrawpage(Document *doc, int page) | |
Image *im; | |
gscmd(&pdf->gs, "%d DoPDFPage\n", page+1); | |
- im = readimage(display, pdf->gs.gsdfd, 0); | |
+ im = convert(&pdf->gs.g); | |
if(im == nil) { | |
fprint(2, "fatal: readimage error %r\n"); | |
wexits("readimage"); | |
diff --git a/src/cmd/page/pdfprolog.c b/src/cmd/page/pdfprolog.c | |
t@@ -2,28 +2,19 @@ | |
"/Page# 0 def\n" | |
"/PDFSave null def\n" | |
"/DSCPageCount 0 def\n" | |
-"/DoPDFPage {dup /Page# exch store pdfgetpage mypdfshowpage } def\n" | |
+"/DoPDFPage {dup /Page# exch store pdfgetpage pdfshowpage } def\n" | |
"\n" | |
"/pdfshowpage_mysetpage { % <pagedict> pdfshowpage_mysetpage <pagedict>… | |
" dup /CropBox pget {\n" | |
" boxrect\n" | |
" 2 array astore /PageSize exch 4 2 roll\n" | |
-" neg exch neg exch 2 array astore /PageOffset exch\n" | |
+" 4 index /Rotate pget {\n" | |
+" dup 0 lt {360 add} if 90 idiv {exch neg} repeat\n" | |
+" } if\n" | |
+" exch neg exch 2 array astore /PageOffset exch\n" | |
" << 5 1 roll >> setpagedevice\n" | |
" } if\n" | |
"} bind def\n" | |
"\n" | |
-"/mypdfshowpage % <pagedict> pdfshowpage -\n" | |
-" { dup /Page exch store\n" | |
-" pdfshowpage_init \n" | |
-" pdfshowpage_setpage \n" | |
-" pdfshowpage_mysetpage\n" | |
-" save /PDFSave exch store\n" | |
-" (before exec) VMDEBUG\n" | |
-" pdfshowpage_finish\n" | |
-" (after exec) VMDEBUG\n" | |
-" PDFSave restore\n" | |
-" } bind def\n" | |
-"\n" | |
"GS_PDF_ProcSet begin\n" | |
"pdfdict begin\n" | |
diff --git a/src/cmd/page/pdfprolog.ps b/src/cmd/page/pdfprolog.ps | |
t@@ -2,28 +2,19 @@ | |
/Page# 0 def | |
/PDFSave null def | |
/DSCPageCount 0 def | |
-/DoPDFPage {dup /Page# exch store pdfgetpage mypdfshowpage } def | |
+/DoPDFPage {dup /Page# exch store pdfgetpage pdfshowpage } def | |
/pdfshowpage_mysetpage { % <pagedict> pdfshowpage_mysetpage <pagedict> | |
dup /CropBox pget { | |
boxrect | |
2 array astore /PageSize exch 4 2 roll | |
- neg exch neg exch 2 array astore /PageOffset exch | |
+ 4 index /Rotate pget { | |
+ dup 0 lt {360 add} if 90 idiv {exch neg} repeat | |
+ } if | |
+ exch neg exch 2 array astore /PageOffset exch | |
<< 5 1 roll >> setpagedevice | |
} if | |
} bind def | |
-/mypdfshowpage % <pagedict> pdfshowpage - | |
- { dup /Page exch store | |
- pdfshowpage_init | |
- pdfshowpage_setpage | |
- pdfshowpage_mysetpage | |
- save /PDFSave exch store | |
- (before exec) VMDEBUG | |
- pdfshowpage_finish | |
- (after exec) VMDEBUG | |
- PDFSave restore | |
- } bind def | |
- | |
GS_PDF_ProcSet begin | |
pdfdict begin | |
diff --git a/src/cmd/page/ps.c b/src/cmd/page/ps.c | |
t@@ -8,7 +8,7 @@ | |
#include <libc.h> | |
#include <draw.h> | |
#include <cursor.h> | |
-#include <event.h> | |
+#include <thread.h> | |
#include <bio.h> | |
#include <ctype.h> | |
#include "page.h" | |
t@@ -158,7 +158,7 @@ initps(Biobuf *b, int argc, char **argv, uchar *buf, int n… | |
fprint(2, "reading through postscript...\n"); | |
if(b == nil){ /* standard input; spool to disk (ouch) */ | |
fd = spooltodisk(buf, nbuf, nil); | |
- sprint(fdbuf, "/fd/%d", fd); | |
+ sprint(fdbuf, "/dev/fd/%d", fd); | |
b = Bopen(fdbuf, OREAD); | |
if(b == nil){ | |
fprint(2, "cannot open disk spool file\n"); | |
t@@ -367,7 +367,7 @@ Keepreading: | |
if(dumb) { | |
fprint(ps->gs.gsfd, "(%s) run\n", argv[0]); | |
- fprint(ps->gs.gsfd, "(/fd/3) (w) file dup (THIS IS NOT A PLAN9… | |
+ fprint(ps->gs.gsfd, "(/dev/fd/3) (w) file dup (THIS IS NOT A P… | |
} | |
ps->bbox = bbox; | |
t@@ -417,7 +417,7 @@ psdrawpage(Document *d, int page) | |
Image *im; | |
if(ps->clueless) | |
- return readimage(display, ps->gs.gsdfd, 0); | |
+ return convert(&ps->gs.g); | |
waitgs(&ps->gs); | |
t@@ -433,7 +433,7 @@ psdrawpage(Document *d, int page) | |
* so send one to avoid deadlock. | |
*/ | |
write(ps->gs.gsfd, "\n", 1); | |
- im = readimage(display, ps->gs.gsdfd, 0); | |
+ im = convert(&ps->gs.g); | |
if(im == nil) { | |
fprint(2, "fatal: readimage error %r\n"); | |
wexits("readimage"); | |
diff --git a/src/cmd/page/rotate.c b/src/cmd/page/rotate.c | |
t@@ -15,14 +15,14 @@ | |
#include <libc.h> | |
#include <bio.h> | |
#include <draw.h> | |
+#include <thread.h> | |
#include <cursor.h> | |
-#include <event.h> | |
#include "page.h" | |
int ndraw = 0; | |
enum { | |
Xaxis = 0, | |
- Yaxis = 1 | |
+ Yaxis = 1, | |
}; | |
Image *mtmp; | |
t@@ -55,7 +55,6 @@ moveup(Image *im, Image *tmp, int a, int b, int c, int axis) | |
drawop(tmp, tmp->r, im, nil, im->r.min, S); | |
switch(axis){ | |
- default: | |
case Xaxis: | |
range = Rect(a, im->r.min.y, c, im->r.max.y); | |
dr0 = range; | |
t@@ -67,6 +66,7 @@ moveup(Image *im, Image *tmp, int a, int b, int c, int axis) | |
p1 = Pt(a, im->r.min.y); | |
break; | |
case Yaxis: | |
+ default: | |
range = Rect(im->r.min.x, a, im->r.max.x, c); | |
dr0 = range; | |
dr0.max.y = dr0.min.y+(c-b); | |
t@@ -90,7 +90,6 @@ interlace(Image *im, Image *tmp, int axis, int n, Image *mas… | |
r0 = im->r; | |
r1 = im->r; | |
switch(axis) { | |
- default: | |
case Xaxis: | |
r0.max.x = n; | |
r1.min.x = n; | |
t@@ -98,6 +97,7 @@ interlace(Image *im, Image *tmp, int axis, int n, Image *mas… | |
p1 = (Point){-gran, 0}; | |
break; | |
case Yaxis: | |
+ default: | |
r0.max.y = n; | |
r1.min.y = n; | |
p0 = (Point){0, gran}; | |
t@@ -132,12 +132,12 @@ interlace(Image *im, Image *tmp, int axis, int n, Image … | |
int | |
nextmask(Image *mask, int axis, int maskdim) | |
{ | |
- Point delta; | |
+ Point o; | |
- delta = axis==Xaxis ? Pt(maskdim,0) : Pt(0,maskdim); | |
+ o = axis==Xaxis ? Pt(maskdim,0) : Pt(0,maskdim); | |
drawop(mtmp, mtmp->r, mask, nil, mask->r.min, S); | |
- gendrawop(mask, mask->r, mtmp, delta, mtmp, divpt(delta,-2), S); | |
-/* writefile("mask", mask, maskdim/2); */ | |
+ gendrawop(mask, mask->r, mtmp, o, mtmp, divpt(o,-2), S); | |
+// writefile("mask", mask, maskdim/2); | |
return maskdim/2; | |
} | |
t@@ -153,13 +153,13 @@ shuffle(Image *im, Image *tmp, int axis, int n, Image *m… | |
nn = n - left; | |
interlace(im, tmp, axis, nn, mask, gran); | |
-/* writefile("interlace", im, gran); */ | |
+// writefile("interlace", im, gran); | |
gran = nextmask(mask, axis, gran); | |
shuffle(im, tmp, axis, n, mask, gran, nn); | |
-/* writefile("shuffle", im, gran); */ | |
+// writefile("shuffle", im, gran); | |
moveup(im, tmp, lastnn, nn, n, axis); | |
-/* writefile("move", im, gran); */ | |
+// writefile("move", im, gran); | |
} | |
void | |
t@@ -198,7 +198,7 @@ rot180(Image *im) | |
} | |
rmask.max.x = gran; | |
drawop(mask, rmask, display->opaque, nil, ZP, S); | |
-/* writefile("mask", mask, gran); */ | |
+// writefile("mask", mask, gran); | |
shuffle(im, tmp, Xaxis, Dx(im->r), mask, gran, 0); | |
freeimage(mask); | |
freeimage(mtmp); | |
t@@ -309,11 +309,11 @@ i0(double x) | |
} | |
double | |
-kaiser(double x, double tau, double alpha) | |
+kaiser(double x, double t, double a) | |
{ | |
- if(fabs(x) > tau) | |
+ if(fabs(x) > t) | |
return 0.; | |
- return i0(alpha*sqrt(1-(x*x/(tau*tau))))/i0(alpha); | |
+ return i0(a*sqrt(1-(x*x/(t*t))))/i0(a); | |
} | |
diff --git a/src/cmd/page/util.c b/src/cmd/page/util.c | |
t@@ -1,9 +1,9 @@ | |
#include <u.h> | |
#include <libc.h> | |
#include <draw.h> | |
-#include <cursor.h> | |
-#include <event.h> | |
+#include <thread.h> | |
#include <bio.h> | |
+#include <cursor.h> | |
#include "page.h" | |
void* | |
t@@ -41,30 +41,6 @@ estrdup(char *s) | |
return t; | |
} | |
-int | |
-opentemp(char *template) | |
-{ | |
- int fd, i; | |
- char *p; | |
- | |
- p = estrdup(template); | |
- fd = -1; | |
- for(i=0; i<10; i++){ | |
- mktemp(p); | |
- if(access(p, 0) < 0 && (fd=create(p, ORDWR|ORCLOSE, 0400)) >= … | |
- break; | |
- strcpy(p, template); | |
- } | |
- if(fd < 0){ | |
- fprint(2, "couldn't make temporary file\n"); | |
- wexits("Ecreat"); | |
- } | |
- strcpy(template, p); | |
- free(p); | |
- | |
- return fd; | |
-} | |
- | |
/* | |
* spool standard input to /tmp. | |
* we've already read the initial in bytes into ibuf. | |
t@@ -96,37 +72,54 @@ spooltodisk(uchar *ibuf, int in, char **name) | |
return fd; | |
} | |
+typedef struct StdinArg StdinArg; | |
+ | |
+struct StdinArg { | |
+ Channel *cp; | |
+ uchar *ibuf; | |
+ int in; | |
+}; | |
+ | |
/* | |
* spool standard input into a pipe. | |
* we've already ready the first in bytes into ibuf | |
*/ | |
-int | |
-stdinpipe(uchar *ibuf, int in) | |
+static void | |
+_stdinpipe(void *a) | |
{ | |
uchar buf[8192]; | |
- int n; | |
+ StdinArg *arg; | |
int p[2]; | |
+ int n; | |
+ | |
+ arg = a; | |
+ | |
if(pipe(p) < 0){ | |
fprint(2, "pipe fails: %r\n"); | |
wexits("pipe"); | |
} | |
- switch(rfork(RFPROC|RFFDG)){ | |
- case -1: | |
- fprint(2, "fork fails: %r\n"); | |
- wexits("fork"); | |
- default: | |
- close(p[1]); | |
- return p[0]; | |
- case 0: | |
- break; | |
- } | |
+ send(arg->cp, &p[0]); | |
- close(p[0]); | |
- write(p[1], ibuf, in); | |
+ write(p[1], arg->ibuf, arg->in); | |
while((n = read(stdinfd, buf, sizeof buf)) > 0) | |
write(p[1], buf, n); | |
+ | |
+ close(p[1]); | |
+ threadexits(0); | |
+} | |
+ | |
+int | |
+stdinpipe(uchar *ibuf, int in) { | |
+ StdinArg arg; | |
+ int fd; | |
- _exits(0); | |
- return -1; /* not reached */ | |
+ arg.ibuf = ibuf; | |
+ arg.in = in; | |
+ arg.cp = chancreate(sizeof(int), 0); | |
+ proccreate(_stdinpipe, &arg, mainstacksize); | |
+ recv(arg.cp, &fd); | |
+ chanfree(arg.cp); | |
+ | |
+ return fd; | |
} | |
diff --git a/src/cmd/page/view.c b/src/cmd/page/view.c | |
t@@ -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; | |
t@@ -26,6 +28,7 @@ Point ul; /* the upper left corner of… | |
Point pclip(Point, Rectangle); | |
Rectangle mkrange(Rectangle screenr, Rectangle imr); | |
void redraw(Image*); | |
+void plumbproc(void*); | |
Cursor reading={ | |
{-1, -1}, | |
t@@ -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 | |
t@@ -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; | |
t@@ -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; | |
t@@ -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"; | |
t@@ -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; | |
} | |
t@@ -265,7 +261,7 @@ enum{ | |
Del, | |
Write, | |
Empty3, | |
- Exit | |
+ Exit, | |
}; | |
void | |
t@@ -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[] = { | |
t@@ -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 = ± | |
+ 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; | |
/* | |
t@@ -336,7 +363,7 @@ viewer(Document *dd) | |
midmenu.lasthit = Next; | |
showpage(page, &menu); | |
- esetcursor(nil); | |
+ setcursor(mc, nil); | |
nxt = 0; | |
for(;;) { | |
t@@ -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; | |
t@@ -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… | |
display->defaultfont, s); | |
- esetcursor(nil); | |
+ setcursor(mc, nil); | |
flushimage(display, 1); | |
break; | |
case 'd': /* remove image from working set */ | |
t@@ -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); | |
t@@ -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; | |
t@@ -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); | |
t@@ -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){ | |
t@@ -543,7 +569,7 @@ viewer(Document *dd) | |
double delta; | |
Rectangle r; | |
- r = egetrect(Middle, &m); | |
+ r = getrect(Middle, mc); | |
if((rectclip(&r, rectaddpt(im-… | |
Dx(r) == 0 || Dy(r) ==… | |
break; | |
t@@ -553,7 +579,7 @@ viewer(Document *dd) | |
else | |
delta = (double)Dy(im-… | |
- esetcursor(&reading); | |
+ setcursor(mc, &reading); | |
tmp = xallocimage(display, | |
Rect(0, 0, (in… | |
im->chan, 0, D… | |
t@@ -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); | |
t@@ -580,7 +606,7 @@ viewer(Document *dd) | |
delta = (double)Dy(scr… | |
r = Rect(0, 0, (int)((double)D… | |
- esetcursor(&reading); | |
+ setcursor(mc, &reading); | |
tmp = xallocimage(display, r, … | |
if(tmp == nil) { | |
fprint(2, "out of memo… | |
t@@ -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); | |
t@@ -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); | |
t@@ -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… | |
display->defaultfont, … | |
- esetcursor(nil); | |
+ setcursor(mc, nil); | |
flushimage(display, 1); | |
break; | |
case Del: /* delete */ | |
t@@ -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; | |
t@@ -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; | |
t@@ -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 */ | |
t@@ -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); | |
t@@ -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); | |
} | |
/* | |
t@@ -966,129 +982,73 @@ xallocimage(Display *d, Rectangle r, ulong chan, int re… | |
return allocimage(d, r, chan, repl, val); | |
} | |
-/* all code below this line should be in the library, but is stolen from color… | |
-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… | |
- }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:'",… | |
+ 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]); | |
} |