git: 9front

Download patch

ref: 4e437e7f173d8a8104c4efa6803086bc32ab62fb
parent: 9ae3ae651b358ad1fd435e27e86d3458c45dca8b
author: cinap_lenrek <cinap_lenrek@centraldogma>
date: Sat Sep 10 21:01:50 EDT 2011

npage: implement page options

--- a/sys/src/cmd/npage.c
+++ b/sys/src/cmd/npage.c
@@ -25,9 +25,12 @@
 	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 @@
 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 @@
 {
 	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 @@
 		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 @@
 		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 @@
 		goto Err1;
 	}
 
-	switch(rfork(RFPROC|RFFDG)){
+	switch(rfork(RFREND|RFPROC|RFFDG|RFNOWAIT)){
 	case -1:
 		goto Err2;
 	case 0:
@@ -324,11 +328,12 @@
 		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 @@
 	close(pin[0]);
 	close(pout[0]);
 	close(pdat[0]);
-	waitpid();
 	return -1;
 }
 
@@ -563,9 +567,7 @@
 			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);
@@ -611,8 +613,12 @@
 }
 
 void
+resizewin(Point);
+
+void
 loadpages(Page *p, int ahead, int oviewgen)
 {
+	Point size;
 	int i;
 
 	unloadpages(NAHEAD*2);
@@ -628,10 +634,17 @@
 				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,8 +711,22 @@
 	}
 }
 
-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;
 	Page *p;
@@ -730,7 +757,7 @@
 	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 @@
 	qunlock(p);
 }
 
-void translate(Page *p, Point d)
+void
+translate(Page *p, Point d)
 {
 	Rectangle r, or, nr;
 	Image *i;
@@ -756,7 +784,7 @@
 		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 @@
 
 	if(p == nil)
 		return;
+	esetcursor(&reading);
 	current = p;
 	oviewgen = viewgen;
-	esetcursor(&reading);
 	if(++nproc > NPROC)
 		if(waitpid() > 0)
 			nproc--;
@@ -851,6 +879,44 @@
 }
 
 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[])
 {
 	enum { Eplumb = 4 };
@@ -861,6 +927,28 @@
 	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
@@ -867,21 +955,22 @@
 	 */
 	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 @@
 						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(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, "fit to width")==0){
+				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 to height")==0){
+				if(strcmp(s, "fit height")==0){
 					pos = ZP;
 					resize = subpt(screen->r.max, screen->r.min);
 					resize.x = 0;
 					goto Unload;
 				}
-				if(strcmp(s, "original size")==0){
-					pos = ZP;
-					resize = ZP;
-					rotate = 0;
-				Unload:
-					viewgen++;
-					esetcursor(&reading);
-					unloadpages(0);
-					showpage(current);
-					continue;
-				}
+				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:
--- a/sys/src/cmd/rotate.c
+++ b/sys/src/cmd/rotate.c
@@ -97,7 +97,7 @@
 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");
 }
 
--