add aux/statusmsg

front
cinap_lenrek 2012-02-11 01:51:38 +01:00
parent 1d58cb8832
commit e283619ecb
2 changed files with 326 additions and 39 deletions

View File

@ -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 @@ statusbar \- display a bar graph status window
.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 @@ will also cause it to exit.
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

298
sys/src/cmd/aux/statusmsg.c Normal file
View File

@ -0,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;
}