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;
+}
--
⑨