aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/page
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
parent6c4c5c5b959ec8a2e85510bdf85339582f638f36 (diff)
downloadplan9port-05a4d855f167ae2d0d2c0ba0e386d933172b71ea.tar.gz
plan9port-05a4d855f167ae2d0d2c0ba0e386d933172b71ea.tar.bz2
plan9port-05a4d855f167ae2d0d2c0ba0e386d933172b71ea.zip
add page (Kris Maglione)
Diffstat (limited to 'src/cmd/page')
-rw-r--r--src/cmd/page/filter.c28
-rw-r--r--src/cmd/page/gfx.c94
-rw-r--r--src/cmd/page/gs.c175
-rw-r--r--src/cmd/page/mkfile10
-rw-r--r--src/cmd/page/nrotate.c6
-rw-r--r--src/cmd/page/page.c76
-rw-r--r--src/cmd/page/page.h30
-rw-r--r--src/cmd/page/pdf.c8
-rw-r--r--src/cmd/page/pdfprolog.c19
-rw-r--r--src/cmd/page/pdfprolog.ps19
-rw-r--r--src/cmd/page/ps.c10
-rw-r--r--src/cmd/page/rotate.c30
-rw-r--r--src/cmd/page/util.c79
-rw-r--r--src/cmd/page/view.c342
14 files changed, 447 insertions, 479 deletions
diff --git a/src/cmd/page/filter.c b/src/cmd/page/filter.c
index 319cfb68..415db038 100644
--- a/src/cmd/page/filter.c
+++ b/src/cmd/page/filter.c
@@ -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*
@@ -24,7 +24,7 @@ initfilt(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf, char *type, cha
if(docopy){
if(pipe(p) < 0){
fprint(2, "pipe fails: %r\n");
- exits("Epipe");
+ threadexits("Epipe");
}
}else{
p[0] = open("/dev/null", ORDWR);
@@ -35,27 +35,29 @@ initfilt(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf, char *type, cha
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)) > 0)
- 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;
}
@@ -81,7 +83,7 @@ initdvi(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf)
*/
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
index 9ce6f74c..e8b40d03 100644
--- a/src/cmd/page/gfx.c
+++ b/src/cmd/page/gfx.c
@@ -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;
@@ -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.
@@ -65,15 +41,14 @@ Convert cvt[] = {
[Iccittg4] { "ccitt-g4", "cat %a|rx nslocum /usr/lib/ocr/bin/bcp -M|fb/pcp -tcompressed -l0" },
[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);
@@ -202,12 +177,12 @@ genaddpage(Document *doc, char *name, uchar *buf, int nbuf)
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->type].name);
@@ -244,7 +219,7 @@ rmpage(Document *doc, int n)
}
-static Image*
+Image*
convert(Graphic *g)
{
int fd;
@@ -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->name);
- 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;
@@ -281,7 +255,7 @@ convert(Graphic *g)
}
snprint(buf, sizeof buf, cmd, name);
if(chatty) fprint(2, "using \"%s\" to convert \"%s\"...\n", buf, g->name);
- fd = spawnrc(buf, g->buf, g->nbuf);
+ fd = spawnrc(buf, g);
rcspawned++;
if(fd < 0) {
fprint(2, "cannot spawn converter: %r\n");
@@ -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 |3to1 */
- 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
index fd7337ec..8c0e1b59 100644
--- a/src/cmd/page/gs.c
+++ b/src/cmd/page/gs.c
@@ -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 */
@@ -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) writestring flushfile\n");
- _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;
@@ -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];
@@ -153,15 +109,15 @@ spawngs(GSInfo *g, char *safer)
* gs output written to fd 1 (i.e. ouptut gs generates on error) is fed to errout.
* 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)<0)
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);
@@ -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,
@@ -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 PAGEOUT flushfile } def\n");
waitgs(g);
@@ -269,11 +239,14 @@ setdim(GSInfo *gs, Rectangle bbox, int ppi, int landscape)
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");
@@ -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
index 0c4163ad..bcd02a8d 100644
--- a/src/cmd/page/mkfile
+++ b/src/cmd/page/mkfile
@@ -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
index 9f6816e2..96563c3d 100644
--- a/src/cmd/page/nrotate.c
+++ b/src/cmd/page/nrotate.c
@@ -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);
@@ -229,7 +229,7 @@ swapadjacent(Image *img, Image *tmp, int axis, int imgdim, Image *mask, int mask
/*
* 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
index 4c76e033..52c6eee3 100644
--- a/src/cmd/page/page.c
+++ b/src/cmd/page/page.c
@@ -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;
@@ -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)
@@ -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;
@@ -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", basename);
resizing = 1;
break;
case 'i':
@@ -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();
@@ -107,8 +160,9 @@ main(int argc, char **argv)
fmtinstall('R', Rfmt);
fmtinstall('P', Pfmt);
+ /*
if(mknewwindow)
- newwin();
+ newwin(); */
if(readstdin){
b = nil;
@@ -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
index be54e386..7e6c526e 100644
--- a/src/cmd/page/page.h
+++ b/src/cmd/page/page.h
@@ -1,3 +1,5 @@
+#undef pipe
+
typedef struct Document Document;
struct Document {
@@ -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*);
@@ -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*);
@@ -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
index d723ad8c..77c88852 100644
--- a/src/cmd/page/pdf.c
+++ b/src/cmd/page/pdf.c
@@ -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"
@@ -66,7 +66,7 @@ initpdf(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf)
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");
@@ -122,7 +122,7 @@ initpdf(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf)
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;
}
@@ -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
index 8493e6d2..de51c062 100644
--- a/src/cmd/page/pdfprolog.c
+++ b/src/cmd/page/pdfprolog.c
@@ -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>\n"
" 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
index c4c31c92..681e0587 100644
--- a/src/cmd/page/pdfprolog.ps
+++ b/src/cmd/page/pdfprolog.ps
@@ -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
index cc6f3c51..4b678dc3 100644
--- a/src/cmd/page/ps.c
+++ b/src/cmd/page/ps.c
@@ -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"
@@ -158,7 +158,7 @@ initps(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf)
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");
@@ -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 BITMAP 01234567890123456789012345678901234567890123456789\\n) writestring flushfile\n");
+ fprint(ps->gs.gsfd, "(/dev/fd/3) (w) file dup (THIS IS NOT A PLAN9 BITMAP 01234567890123456789012345678901234567890123456789\\n) writestring flushfile\n");
}
ps->bbox = bbox;
@@ -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);
@@ -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
index fc13059b..48087348 100644
--- a/src/cmd/page/rotate.c
+++ b/src/cmd/page/rotate.c
@@ -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;
@@ -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;
@@ -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);
@@ -90,7 +90,6 @@ interlace(Image *im, Image *tmp, int axis, int n, Image *mask, int gran)
r0 = im->r;
r1 = im->r;
switch(axis) {
- default:
case Xaxis:
r0.max.x = n;
r1.min.x = n;
@@ -98,6 +97,7 @@ interlace(Image *im, Image *tmp, int axis, int n, Image *mask, int gran)
p1 = (Point){-gran, 0};
break;
case Yaxis:
+ default:
r0.max.y = n;
r1.min.y = n;
p0 = (Point){0, gran};
@@ -132,12 +132,12 @@ interlace(Image *im, Image *tmp, int axis, int n, Image *mask, int gran)
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;
}
@@ -153,13 +153,13 @@ shuffle(Image *im, Image *tmp, int axis, int n, Image *mask, int gran,
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
@@ -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);
@@ -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
index 2669df84..1f6fdeff 100644
--- a/src/cmd/page/util.c
+++ b/src/cmd/page/util.c
@@ -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*
@@ -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)) >= 0)
- 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.
@@ -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
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]);
}