git: 9front

Download patch

ref: 45ebfb3565a5e27c2af6758f95a372aea827b852
parent: 98f0addfd29bbad64956f04c7f1c89992dd837a1
author: cinap_lenrek <cinap_lenrek@rei2.9hal>
date: Fri Feb 10 20:51:38 EST 2012

add aux/statusmsg

--- a/sys/man/8/statusbar
+++ b/sys/man/8/statusbar
@@ -1,6 +1,6 @@
 .TH STATUSBAR 8
 .SH NAME
-statusbar \- display a bar graph status window
+statusbar, statusmsg \- display a bar graph or status message window
 .SH SYNOPSIS
 .B aux/statusbar
 [
@@ -11,20 +11,33 @@
 .I minx,miny,maxx,maxy
 ]
 .I title
+.br
+.B aux/statusmsg
+[
+.B -kt
+]
+[
+.B -w
+.I minx,miny,maxx,maxy
+] [
+.I title
+]
 .SH DESCRIPTION
-.I Aux/statusbar
-reads textual status lines
-from standard input, converting them into a
-continuously updated bar graph displayed in a new window
-on the screen.
+.I Statusbar
+and
+.I statusmsg
+read textual status lines from standard input into a
+continuously updated bar graph or text message displayed in
+a new window on the screen.
 The
 .I title
-is displayed on a line above the bar graph.
-Each input line is two space-separated decimal numbers:
+is displayed on a line above the bar graph or message.
+For
+.I statusbar,
+each input line is two space-separated decimal numbers:
 the numerator and denominator of a fraction.
 .PP
-.I Statusbar
-exits when it reaches end-of-file on standard input.
+The programs exit when it reaches end-of-file on standard input.
 Typing
 .SM DEL
 or control-C
@@ -33,39 +46,15 @@
 The options are:
 .TP
 .B -k
-do not allow typing to cause
-.I statusbar
-to exit
+do not allow typing to cause exit
 .TP
 .B -t
-print an ASCII status bar to standard output, using
-backspace to redraw it
+print an ASCII version of the bar or message to standard output, using
+backspace to redraw it. 
 .TP
 .B -w
-set the coordinates of the statusbar window created
+set the coordinates of the window created
 .PD
-.SH EXAMPLE
-The
-.B -v
-option to
-.IR hget (1)
-.\" and the 
-.\" .B -d
-.\" option to
-.\" .IR venti/fmtarenas
-.\" and
-.\" .I venti/fmtisect
-.\" (see
-.\" .IR venti-fmt (8))
-causes it to print status lines suitable for
-input to
-.IR statusbar .
-.PP
-Monitor a long download:
-.IP
-.EX
-hget -v -o bigfile http://server.com/bigfile |[2]
-  aux/statusbar 'big file download'
-.EE
 .SH SOURCE
 .B /sys/src/cmd/aux/statusbar.c
+.B /sys/src/cmd/aux/statusmsg.c
--- /dev/null
+++ b/sys/src/cmd/aux/statusmsg.c
@@ -1,0 +1,298 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <bio.h>
+#include <event.h>
+
+enum {PNCTL=3};
+
+static char* rdenv(char*);
+int newwin(char*);
+Rectangle screenrect(void);
+
+int nokill;
+int textmode;
+char *title = nil;
+char message[1024];
+
+Image *light;
+Image *text;
+Rectangle rtext;
+
+void
+initcolor(void)
+{
+	text = display->black;
+	light = allocimagemix(display, DPalegreen, DWhite);
+}
+
+void
+drawmsg(void)
+{
+	if(textmode){
+		static int last = 0;
+
+		while(last-- > 0)
+			write(1, "\b", 1);
+		write(1, message, strlen(message));
+		last = utflen(message);
+		return;
+	}
+	draw(screen, rtext, light, nil, ZP);
+	string(screen, rtext.min, text, ZP, display->defaultfont, message);
+	flushimage(display, 1);
+}
+
+void
+eresized(int new)
+{
+	if(new && getwindow(display, Refnone) < 0)
+		fprint(2,"can't reattach to window");
+	rtext = screen->r;
+	draw(screen, rtext, light, nil, ZP);
+	rtext.min.x += 4;
+	rtext.min.y += 4;
+	if(title){
+		string(screen, rtext.min, text, ZP, display->defaultfont, title);
+		rtext.min.y += 8+display->defaultfont->height;
+	}
+	rtext.max.y = rtext.min.y + display->defaultfont->height;
+	drawmsg();
+}
+
+void
+msg(Biobuf *b)
+{
+	char *p;
+	Event e;
+	int k, die, parent, child;
+
+	parent = getpid();
+
+	die = 0;
+	if(textmode){
+		child = -1;
+		if(title){
+			write(1, title, strlen(title));
+			write(1, ": ", 2);
+		}
+	} else
+	switch(child = rfork(RFMEM|RFPROC)) {
+	case 0:
+		sleep(1000);
+		while(!die && (k = eread(Ekeyboard|Emouse, &e))) {
+			if(nokill==0 && k == Ekeyboard && (e.kbdc == 0x7F || e.kbdc == 0x03)) { /* del, ctl-c */
+				die = 1;
+				postnote(PNPROC, parent, "interrupt");
+				_exits("interrupt");
+			}
+		}
+		_exits(0);
+	}
+	while(!die && (p = Brdline(b, '\n'))) {
+		snprint(message, sizeof(message), "%.*s", Blinelen(b)-1, p);
+		drawmsg();
+	}
+	if(textmode)
+		write(1, "\n", 1);
+	postnote(PNCTL, child, "kill");
+}
+
+
+void
+usage(void)
+{
+	fprint(2, "usage: %s [-kt] [-w minx,miny,maxx,maxy] [title]\n", argv0);
+	exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+	Biobuf b;
+	char *p, *q;
+	int lfd;
+
+	p = "0,0,200,60";
+	
+	ARGBEGIN{
+	case 'w':
+		p = ARGF();
+		break;
+	case 't':
+		textmode = 1;
+		break;
+	case 'k':
+		nokill = 1;
+		break;
+	default:
+		usage();
+	}ARGEND;
+
+	switch(argc){
+	default:
+		usage();
+	case 1:
+		title = argv[0];
+		break;
+	case 0:
+		break;
+	}
+	lfd = dup(0, -1);
+
+	while(q = strchr(p, ','))
+		*q = ' ';
+	Binit(&b, lfd, OREAD);
+	if(textmode || newwin(p) < 0){
+		textmode = 1;
+	}else{
+		if(initdraw(0, 0, title) < 0)
+			exits("initdraw");
+		initcolor();
+		einit(Emouse|Ekeyboard);
+		eresized(0);
+	}
+	msg(&b);
+
+	exits(0);
+}
+
+
+/* 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, "%s: can't malloc: %r\n", argv0);
+		exits("no mem");
+	}
+	seek(fd, 0, 0);
+	read(fd, v, size);
+	v[size] = 0;
+	close(fd);
+	return v;
+}
+
+int
+newwin(char *win)
+{
+	char *srv, *mntsrv;
+	char spec[100];
+	int srvfd, cons, pid;
+
+	switch(rfork(RFFDG|RFPROC|RFNAMEG|RFENVG|RFNOTEG|RFNOWAIT)){
+	case -1:
+		fprint(2, "%s: can't fork: %r\n", argv0);
+		return -1;
+	case 0:
+		break;
+	default:
+		exits(0);
+	}
+
+	srv = rdenv("/env/wsys");
+	if(srv == 0){
+		mntsrv = rdenv("/mnt/term/env/wsys");
+		if(mntsrv == 0){
+			fprint(2, "%s: can't find $wsys\n", argv0);
+			return -1;
+		}
+		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();
+	USED(pid);
+	srvfd = open(srv, ORDWR);
+	free(srv);
+	if(srvfd == -1){
+		fprint(2, "%s: can't open %s: %r\n", argv0, srv);
+		return -1;
+	}
+	sprint(spec, "new -r %s", win);
+	if(mount(srvfd, -1, "/mnt/wsys", 0, spec) == -1){
+		fprint(2, "%s: can't mount /mnt/wsys: %r (spec=%s)\n", argv0, spec);
+		return -1;
+	}
+	close(srvfd);
+	unmount("/mnt/acme", "/dev");
+	bind("/mnt/wsys", "/dev", MBEFORE);
+	cons = open("/dev/cons", OREAD);
+	if(cons==-1){
+	NoCons:
+		fprint(2, "%s: can't open /dev/cons: %r", argv0);
+		return -1;
+	}
+	dup(cons, 0);
+	close(cons);
+	cons = open("/dev/cons", OWRITE);
+	if(cons==-1)
+		goto NoCons;
+	dup(cons, 1);
+	dup(cons, 2);
+	close(cons);
+	return 0;
+}
+
+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, "%s: can't open /dev/screen: %r\n", argv0);
+		exits("window read");
+	}
+	if(read(fd, buf, sizeof buf) != sizeof buf){
+		fprint(2, "%s: can't read /dev/screen: %r\n", argv0);
+		exits("screen read");
+	}
+	close(fd);
+	return Rect(atoi(buf+12), atoi(buf+24), atoi(buf+36), atoi(buf+48));
+}
+
+int
+postnote(int group, int pid, char *note)
+{
+	char file[128];
+	int f, r;
+
+	switch(group) {
+	case PNPROC:
+		sprint(file, "/proc/%d/note", pid);
+		break;
+	case PNGROUP:
+		sprint(file, "/proc/%d/notepg", pid);
+		break;
+	case PNCTL:
+		sprint(file, "/proc/%d/ctl", pid);
+		break;
+	default:
+		return -1;
+	}
+
+	f = open(file, OWRITE);
+	if(f < 0)
+		return -1;
+
+	r = strlen(note);
+	if(write(f, note, r) != r) {
+		close(f);
+		return -1;
+	}
+	close(f);
+	return 0;
+}
--