npage: implement page options

This commit is contained in:
cinap_lenrek 2011-09-11 01:01:50 +02:00
parent 441a33970d
commit f2c136f903
2 changed files with 155 additions and 59 deletions

View file

@ -25,9 +25,12 @@ struct Page {
Page *tail;
};
int rotate = 0;
int viewgen = 0;
int pagegen = 0;
int ppi = 100;
int imode;
int newwin;
int rotate;
int viewgen;
int pagegen;
Point resize, pos;
Page *root, *current;
QLock pagelock;
@ -45,15 +48,16 @@ enum {
char *pagemenugen(int i);
char *menuitems[] = {
"orig size",
"rotate 90",
"rotate 180",
"upside down",
"",
"fit to width",
"fit to height",
"original size",
"fit width",
"fit height",
"",
"next",
"prev",
"zerox",
"",
"quit",
nil
@ -125,7 +129,7 @@ createtmp(ulong id, char *pfx)
{
char nam[64];
sprint(nam, "%s%s%.12d%.8lux", pagespool, pfx, getpid(), id ^ 0xcafebabe);
snprint(nam, sizeof nam, "%s%s%.12d%.8lux", pagespool, pfx, getpid(), id ^ 0xcafebabe);
return create(nam, OEXCL|ORCLOSE|ORDWR, 0600);
}
@ -141,7 +145,7 @@ pipeline(int fd, char *fmt, ...)
dup(nullfd, fd);
return;
}
switch(rfork(RFPROC|RFFDG|RFNOWAIT)){
switch(rfork(RFPROC|RFFDG|RFREND|RFNOWAIT)){
case -1:
close(pfd[0]);
close(pfd[1]);
@ -162,7 +166,7 @@ pipeline(int fd, char *fmt, ...)
argv[2] = buf;
argv[3] = nil;
exec("/bin/rc", argv);
exits(nil);
sysfatal("exec: %r");
}
close(pfd[1]);
dup(pfd[0], fd);
@ -282,7 +286,7 @@ popengs(Page *p)
goto Err1;
}
switch(rfork(RFPROC|RFFDG)){
switch(rfork(RFREND|RFPROC|RFFDG|RFNOWAIT)){
case -1:
goto Err2;
case 0:
@ -324,11 +328,12 @@ popengs(Page *p)
argv[6] = "-dQUIET";
argv[7] = "-dTextAlphaBits=4";
argv[8] = "-dGraphicsAlphaBits=4";
argv[9] = "-r100";
snprint(buf, sizeof buf, "-r%d", ppi);
argv[9] = buf;
argv[10] = pdf ? "-" : "/fd/4";
argv[11] = nil;
exec("/bin/gs", argv);
exits("exec");
sysfatal("exec: %r");
}
close(pin[1]);
@ -401,7 +406,6 @@ Out:
close(pin[0]);
close(pout[0]);
close(pdat[0]);
waitpid();
return -1;
}
@ -563,9 +567,7 @@ loadpage(Page *p)
pagegen++;
if(rotate)
pipeline(fd, "rotate -r %d", rotate);
if(resize.x && resize.y)
pipeline(fd, "resize -x %d -y %d", resize.x, resize.y);
else if(resize.x)
if(resize.x)
pipeline(fd, "resize -x %d", resize.x);
else if(resize.y)
pipeline(fd, "resize -y %d", resize.y);
@ -610,9 +612,13 @@ unloadpages(int age)
}
}
void
resizewin(Point);
void
loadpages(Page *p, int ahead, int oviewgen)
{
Point size;
int i;
unloadpages(NAHEAD*2);
@ -628,10 +634,17 @@ loadpages(Page *p, int ahead, int oviewgen)
qunlock(p);
break;
}
size = p->image ? subpt(p->image->r.max, p->image->r.min) : ZP;
qunlock(p);
if(p == current)
eresized(0);
i++;
if(p == current){
if(size.x && size.y && newwin){
newwin = 0;
resizewin(size);
}
eresized(0);
}
}
}
}
@ -698,7 +711,21 @@ gendrawdiff(Image *dst, Rectangle bot, Rectangle top,
}
}
void eresized(int new)
void
resizewin(Point size)
{
int wctl;
if((wctl = open("/dev/wctl", OWRITE)) < 0)
return;
/* add rio border */
size = addpt(size, Pt(Borderwidth, Borderwidth));
fprint(wctl, "resize -dx %d -dy %d\n", size.x, size.y);
close(wctl);
}
void
eresized(int new)
{
Rectangle r;
Image *i;
@ -730,7 +757,7 @@ void eresized(int new)
r = rectaddpt(rectaddpt(Rpt(ZP, subpt(i->r.max, i->r.min)), screen->r.min), pos);
draw(screen, r, i, nil, i->r.min);
gendrawdiff(screen, screen->r, r, display->white, ZP, nil, ZP, S);
border(screen, r, -4, display->black, ZP);
border(screen, r, -Borderwidth, display->black, ZP);
flushimage(display, 1);
esetcursor(nil);
Out:
@ -738,7 +765,8 @@ Out:
qunlock(p);
}
void translate(Page *p, Point d)
void
translate(Page *p, Point d)
{
Rectangle r, or, nr;
Image *i;
@ -756,7 +784,7 @@ void translate(Page *p, Point d)
draw(screen, rectaddpt(or, d), screen, nil, or.min);
gendrawdiff(screen, nr, rectaddpt(or, d), i, i->r.min, nil, ZP, S);
gendrawdiff(screen, screen->r, nr, display->white, ZP, nil, ZP, S);
border(screen, nr, -4, display->black, ZP);
border(screen, nr, -Borderwidth, display->black, ZP);
flushimage(display, 1);
}
qunlock(p);
@ -812,9 +840,9 @@ showpage(Page *p)
if(p == nil)
return;
esetcursor(&reading);
current = p;
oviewgen = viewgen;
esetcursor(&reading);
if(++nproc > NPROC)
if(waitpid() > 0)
nproc--;
@ -850,6 +878,44 @@ shortname(char *s)
return s;
}
void
zerox(Page *p)
{
char nam[64], *argv[4];
int fd;
if(p == nil)
return;
esetcursor(&reading);
qlock(p);
if(p->open == nil || (fd = p->open(p)) < 0){
p->open = nil;
goto Out;
}
if(rfork(RFREND|RFFDG|RFPROC|RFENVG|RFNOTEG|RFNOWAIT) == 0){
dup(fd, 0);
close(fd);
snprint(nam, sizeof nam, "/bin/%s", argv0);
argv[0] = argv0;
argv[1] = "-w";
argv[2] = nil;
exec(nam, argv);
sysfatal("exec: %r");
}
close(fd);
Out:
qunlock(p);
esetcursor(nil);
}
void
usage(void)
{
fprint(2, "usage: %s [ -iRw ] [ -p ppi ] [ file ... ]\n", argv0);
exits("usage");
}
void
main(int argc, char *argv[])
{
@ -861,27 +927,50 @@ main(int argc, char *argv[])
char *s;
int i;
ARGBEGIN {
case 'a':
case 'v':
case 'V':
case 'P':
break;
case 'R':
newwin = -1;
break;
case 'w':
newwin = 1;
break;
case 'i':
imode = 1;
break;
case 'p':
ppi = atoi(EARGF(usage()));
break;
default:
usage();
} ARGEND;
/*
* so that we can stop all subprocesses with a note,
* and to isolate rendezvous from other processes
*/
rfork(RFNOTEG|RFNAMEG|RFREND);
atexit(killcohort);
ARGBEGIN {
} ARGEND;
nullfd = open("/dev/null", ORDWR);
initdraw(drawerr, nil, "npage");
if(newwin > 0){
s = smprint("-pid %d", getpid());
if(newwindow(s) < 0)
sysfatal("newwindow: %r");
free(s);
}
initdraw(drawerr, nil, argv0);
display->locking = 1;
unlockdisplay(display);
einit(Ekeyboard|Emouse);
eplumb(Eplumb, "image");
nullfd = open("/dev/null", ORDWR);
current = root = addpage(nil, "root", nil, nil, -1);
if(*argv == nil)
addpage(root, "-", popenfile, strdup("/fd/0"), -1);
if(*argv == nil && !imode)
addpage(root, "stdin", popenfile, strdup("/fd/0"), -1);
for(; *argv; argv++)
addpage(root, shortname(*argv), popenfile, strdup(*argv), -1);
@ -899,61 +988,68 @@ main(int argc, char *argv[])
break;
translate(current, subpt(m.xy, o));
}
unlockdisplay(display);
continue;
goto Unlock;
}
if(m.buttons & 2){
i = emenuhit(2, &m, &menu);
unlockdisplay(display);
if(i < 0 || i >= nelem(menuitems) || menuitems[i]==nil)
continue;
goto Unlock;
s = menuitems[i];
if(strncmp(s, "rotate ", 7)==0){
rotate += atoi(s+7);
rotate %= 360;
goto Unload;
}
if(strcmp(s, "fit to width")==0){
pos = ZP;
resize = subpt(screen->r.max, screen->r.min);
resize.y = 0;
goto Unload;
}
if(strcmp(s, "fit to height")==0){
pos = ZP;
resize = subpt(screen->r.max, screen->r.min);
resize.x = 0;
goto Unload;
}
if(strcmp(s, "original size")==0){
if(strcmp(s, "orig size")==0){
pos = ZP;
resize = ZP;
rotate = 0;
Unload:
viewgen++;
unlockdisplay(display);
esetcursor(&reading);
unloadpages(0);
showpage(current);
continue;
}
if(strncmp(s, "rotate ", 7)==0){
rotate += atoi(s+7);
rotate %= 360;
goto Unload;
}
if(strcmp(s, "upside down")==0){
rotate += 180;
goto Unload;
}
if(strcmp(s, "fit width")==0){
pos = ZP;
resize = subpt(screen->r.max, screen->r.min);
resize.y = 0;
goto Unload;
}
if(strcmp(s, "fit height")==0){
pos = ZP;
resize = subpt(screen->r.max, screen->r.min);
resize.x = 0;
goto Unload;
}
unlockdisplay(display);
if(strcmp(s, "next")==0)
showpage(nextpage(current));
if(strcmp(s, "prev")==0)
showpage(prevpage(current));
if(strcmp(s, "zerox")==0)
zerox(current);
if(strcmp(s, "quit")==0)
exits(0);
continue;
}
if(m.buttons & 4){
if(root->down == nil)
goto Unlock;
pagemenu.lasthit = pageindex(current);
i = emenuhit(3, &m, &pagemenu);
unlockdisplay(display);
if(i != -1)
showpage(pageat(i));
continue;
}
Unlock:
unlockdisplay(display);
break;
case Ekeyboard:

View file

@ -97,7 +97,7 @@ upsidedown(Memimage *m)
void
usage(void)
{
fprint(2, "usage: %s -r degree [ file ]\n", argv0);
fprint(2, "usage: %s [ -r degree ] [ -u | -l ] [ file ]\n", argv0);
exits("usage");
}