118027f8cSDavid du Colombier #include <u.h>
218027f8cSDavid du Colombier #include <libc.h>
318027f8cSDavid du Colombier #include <draw.h>
418027f8cSDavid du Colombier #include <bio.h>
518027f8cSDavid du Colombier #include <event.h>
618027f8cSDavid du Colombier
718027f8cSDavid du Colombier enum {PNCTL=3};
818027f8cSDavid du Colombier
918027f8cSDavid du Colombier static char* rdenv(char*);
1018027f8cSDavid du Colombier int newwin(char*);
1118027f8cSDavid du Colombier Rectangle screenrect(void);
1218027f8cSDavid du Colombier
1318027f8cSDavid du Colombier int nokill;
1418027f8cSDavid du Colombier int textmode;
1518027f8cSDavid du Colombier char *title;
1618027f8cSDavid du Colombier
1718027f8cSDavid du Colombier Image *light;
1818027f8cSDavid du Colombier Image *dark;
1918027f8cSDavid du Colombier Image *text;
2018027f8cSDavid du Colombier
2118027f8cSDavid du Colombier void
initcolor(void)2218027f8cSDavid du Colombier initcolor(void)
2318027f8cSDavid du Colombier {
2418027f8cSDavid du Colombier text = display->black;
2518027f8cSDavid du Colombier light = allocimagemix(display, DPalegreen, DWhite);
2618027f8cSDavid du Colombier dark = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DDarkgreen);
2718027f8cSDavid du Colombier }
2818027f8cSDavid du Colombier
2918027f8cSDavid du Colombier Rectangle rbar;
3018027f8cSDavid du Colombier Point ptext;
3118027f8cSDavid du Colombier vlong n, d;
3218027f8cSDavid du Colombier int last;
3318027f8cSDavid du Colombier int lastp = -1;
3418027f8cSDavid du Colombier
3518027f8cSDavid du Colombier char backup[80];
3618027f8cSDavid du Colombier
3718027f8cSDavid du Colombier void
drawbar(void)3818027f8cSDavid du Colombier drawbar(void)
3918027f8cSDavid du Colombier {
4018027f8cSDavid du Colombier int i, j;
4118027f8cSDavid du Colombier int p;
4218027f8cSDavid du Colombier char buf[400], bar[200];
4318027f8cSDavid du Colombier static char lastbar[200];
4418027f8cSDavid du Colombier
4518027f8cSDavid du Colombier if(n > d || n < 0 || d <= 0)
4618027f8cSDavid du Colombier return;
4718027f8cSDavid du Colombier
4818027f8cSDavid du Colombier i = (Dx(rbar)*n)/d;
4918027f8cSDavid du Colombier p = (n*100LL)/d;
5018027f8cSDavid du Colombier
5118027f8cSDavid du Colombier if(textmode){
5218027f8cSDavid du Colombier if(Dx(rbar) > 150){
5318027f8cSDavid du Colombier rbar.min.x = 0;
5418027f8cSDavid du Colombier rbar.max.x = 150;
5518027f8cSDavid du Colombier return;
5618027f8cSDavid du Colombier }
5718027f8cSDavid du Colombier bar[0] = '|';
5818027f8cSDavid du Colombier for(j=0; j<i; j++)
5918027f8cSDavid du Colombier bar[j+1] = '#';
6018027f8cSDavid du Colombier for(; j<Dx(rbar); j++)
6118027f8cSDavid du Colombier bar[j+1] = '-';
6218027f8cSDavid du Colombier bar[j++] = '|';
6318027f8cSDavid du Colombier bar[j++] = ' ';
6418027f8cSDavid du Colombier sprint(bar+j, "%3d%% ", p);
6518027f8cSDavid du Colombier for(i=0; bar[i]==lastbar[i] && bar[i]; i++)
6618027f8cSDavid du Colombier ;
6718027f8cSDavid du Colombier memset(buf, '\b', strlen(lastbar)-i);
6818027f8cSDavid du Colombier strcpy(buf+strlen(lastbar)-i, bar+i);
6918027f8cSDavid du Colombier if(buf[0])
7018027f8cSDavid du Colombier write(1, buf, strlen(buf));
7118027f8cSDavid du Colombier strcpy(lastbar, bar);
7218027f8cSDavid du Colombier return;
7318027f8cSDavid du Colombier }
7418027f8cSDavid du Colombier
7518027f8cSDavid du Colombier if(lastp == p && last == i)
7618027f8cSDavid du Colombier return;
7718027f8cSDavid du Colombier
7818027f8cSDavid du Colombier if(lastp != p){
7918027f8cSDavid du Colombier sprint(buf, "%d%%", p);
8018027f8cSDavid du Colombier
8118027f8cSDavid du Colombier stringbg(screen, addpt(screen->r.min, Pt(Dx(rbar)-30, 4)), text, ZP, display->defaultfont, buf, light, ZP);
8218027f8cSDavid du Colombier lastp = p;
8318027f8cSDavid du Colombier }
8418027f8cSDavid du Colombier
8518027f8cSDavid du Colombier if(last != i){
86*360053c8SDavid du Colombier if(i > last)
8718027f8cSDavid du Colombier draw(screen, Rect(rbar.min.x+last, rbar.min.y, rbar.min.x+i, rbar.max.y),
8818027f8cSDavid du Colombier dark, nil, ZP);
89*360053c8SDavid du Colombier else
90*360053c8SDavid du Colombier draw(screen, Rect(rbar.min.x+i, rbar.min.y, rbar.min.x+last, rbar.max.y),
91*360053c8SDavid du Colombier light, nil, ZP);
9218027f8cSDavid du Colombier last = i;
9318027f8cSDavid du Colombier }
9418027f8cSDavid du Colombier flushimage(display, 1);
9518027f8cSDavid du Colombier }
9618027f8cSDavid du Colombier
9718027f8cSDavid du Colombier void
eresized(int new)9818027f8cSDavid du Colombier eresized(int new)
9918027f8cSDavid du Colombier {
10018027f8cSDavid du Colombier Point p, q;
10118027f8cSDavid du Colombier Rectangle r;
10218027f8cSDavid du Colombier
10318027f8cSDavid du Colombier if(new && getwindow(display, Refnone) < 0)
10418027f8cSDavid du Colombier fprint(2,"can't reattach to window");
10518027f8cSDavid du Colombier
10618027f8cSDavid du Colombier r = screen->r;
10718027f8cSDavid du Colombier draw(screen, r, light, nil, ZP);
10818027f8cSDavid du Colombier p = string(screen, addpt(r.min, Pt(4,4)), text, ZP,
10918027f8cSDavid du Colombier display->defaultfont, title);
11018027f8cSDavid du Colombier
11118027f8cSDavid du Colombier p.x = r.min.x+4;
11218027f8cSDavid du Colombier p.y += display->defaultfont->height+4;
11318027f8cSDavid du Colombier
11418027f8cSDavid du Colombier q = subpt(r.max, Pt(4,4));
11518027f8cSDavid du Colombier rbar = Rpt(p, q);
11618027f8cSDavid du Colombier
11718027f8cSDavid du Colombier ptext = Pt(r.max.x-4-stringwidth(display->defaultfont, "100%"), r.min.x+4);
11818027f8cSDavid du Colombier border(screen, rbar, -2, dark, ZP);
11918027f8cSDavid du Colombier last = 0;
12018027f8cSDavid du Colombier lastp = -1;
12118027f8cSDavid du Colombier
12218027f8cSDavid du Colombier drawbar();
12318027f8cSDavid du Colombier }
12418027f8cSDavid du Colombier
12518027f8cSDavid du Colombier void
bar(Biobuf * b)12618027f8cSDavid du Colombier bar(Biobuf *b)
12718027f8cSDavid du Colombier {
12818027f8cSDavid du Colombier char *p, *f[2];
12918027f8cSDavid du Colombier Event e;
13018027f8cSDavid du Colombier int k, die, parent, child;
13118027f8cSDavid du Colombier
13218027f8cSDavid du Colombier parent = getpid();
13318027f8cSDavid du Colombier
13418027f8cSDavid du Colombier die = 0;
13518027f8cSDavid du Colombier if(textmode)
13618027f8cSDavid du Colombier child = -1;
13718027f8cSDavid du Colombier else
13818027f8cSDavid du Colombier switch(child = rfork(RFMEM|RFPROC)) {
13918027f8cSDavid du Colombier case 0:
14018027f8cSDavid du Colombier sleep(1000);
14118027f8cSDavid du Colombier while(!die && (k = eread(Ekeyboard|Emouse, &e))) {
14218027f8cSDavid du Colombier if(nokill==0 && k == Ekeyboard && (e.kbdc == 0x7F || e.kbdc == 0x03)) { /* del, ctl-c */
14318027f8cSDavid du Colombier die = 1;
14418027f8cSDavid du Colombier postnote(PNPROC, parent, "interrupt");
14518027f8cSDavid du Colombier _exits("interrupt");
14618027f8cSDavid du Colombier }
14718027f8cSDavid du Colombier }
14818027f8cSDavid du Colombier _exits(0);
14918027f8cSDavid du Colombier }
15018027f8cSDavid du Colombier
15118027f8cSDavid du Colombier while(!die && (p = Brdline(b, '\n'))) {
15218027f8cSDavid du Colombier p[Blinelen(b)-1] = '\0';
15318027f8cSDavid du Colombier if(tokenize(p, f, 2) != 2)
15418027f8cSDavid du Colombier continue;
15518027f8cSDavid du Colombier n = strtoll(f[0], 0, 0);
15618027f8cSDavid du Colombier d = strtoll(f[1], 0, 0);
15718027f8cSDavid du Colombier drawbar();
15818027f8cSDavid du Colombier }
15918027f8cSDavid du Colombier postnote(PNCTL, child, "kill");
16018027f8cSDavid du Colombier }
16118027f8cSDavid du Colombier
16218027f8cSDavid du Colombier
16318027f8cSDavid du Colombier void
usage(void)16418027f8cSDavid du Colombier usage(void)
16518027f8cSDavid du Colombier {
166a4162ed5SDavid du Colombier fprint(2, "usage: aux/statusbar [-kt] [-w minx,miny,maxx,maxy] 'title'\n");
16718027f8cSDavid du Colombier exits("usage");
16818027f8cSDavid du Colombier }
16918027f8cSDavid du Colombier
17018027f8cSDavid du Colombier void
main(int argc,char ** argv)17118027f8cSDavid du Colombier main(int argc, char **argv)
17218027f8cSDavid du Colombier {
17318027f8cSDavid du Colombier Biobuf b;
17418027f8cSDavid du Colombier char *p, *q;
17518027f8cSDavid du Colombier int lfd;
17618027f8cSDavid du Colombier
17718027f8cSDavid du Colombier p = "0,0,200,60";
17818027f8cSDavid du Colombier
17918027f8cSDavid du Colombier ARGBEGIN{
18018027f8cSDavid du Colombier case 'w':
18118027f8cSDavid du Colombier p = ARGF();
18218027f8cSDavid du Colombier break;
18318027f8cSDavid du Colombier case 't':
18418027f8cSDavid du Colombier textmode = 1;
18518027f8cSDavid du Colombier break;
18618027f8cSDavid du Colombier case 'k':
18718027f8cSDavid du Colombier nokill = 1;
18818027f8cSDavid du Colombier break;
18918027f8cSDavid du Colombier default:
19018027f8cSDavid du Colombier usage();
19118027f8cSDavid du Colombier }ARGEND;
19218027f8cSDavid du Colombier
19318027f8cSDavid du Colombier if(argc != 1)
19418027f8cSDavid du Colombier usage();
19518027f8cSDavid du Colombier
19618027f8cSDavid du Colombier title = argv[0];
19718027f8cSDavid du Colombier
19818027f8cSDavid du Colombier lfd = dup(0, -1);
19918027f8cSDavid du Colombier
20018027f8cSDavid du Colombier while(q = strchr(p, ','))
20118027f8cSDavid du Colombier *q = ' ';
20218027f8cSDavid du Colombier Binit(&b, lfd, OREAD);
20318027f8cSDavid du Colombier if(textmode || newwin(p) < 0){
20418027f8cSDavid du Colombier textmode = 1;
20518027f8cSDavid du Colombier rbar = Rect(0, 0, 60, 1);
20618027f8cSDavid du Colombier }else{
2072cca75a1SDavid du Colombier if(initdraw(0, 0, "bar") < 0)
2082cca75a1SDavid du Colombier exits("initdraw");
20918027f8cSDavid du Colombier initcolor();
21018027f8cSDavid du Colombier einit(Emouse|Ekeyboard);
21118027f8cSDavid du Colombier eresized(0);
21218027f8cSDavid du Colombier }
21318027f8cSDavid du Colombier bar(&b);
2142cca75a1SDavid du Colombier
2152cca75a1SDavid du Colombier exits(0);
21618027f8cSDavid du Colombier }
21718027f8cSDavid du Colombier
21818027f8cSDavid du Colombier
21918027f8cSDavid du Colombier /* all code below this line should be in the library, but is stolen from colors instead */
22018027f8cSDavid du Colombier static char*
rdenv(char * name)22118027f8cSDavid du Colombier rdenv(char *name)
22218027f8cSDavid du Colombier {
22318027f8cSDavid du Colombier char *v;
22418027f8cSDavid du Colombier int fd, size;
22518027f8cSDavid du Colombier
22618027f8cSDavid du Colombier fd = open(name, OREAD);
22718027f8cSDavid du Colombier if(fd < 0)
22818027f8cSDavid du Colombier return 0;
22918027f8cSDavid du Colombier size = seek(fd, 0, 2);
23018027f8cSDavid du Colombier v = malloc(size+1);
23118027f8cSDavid du Colombier if(v == 0){
23218027f8cSDavid du Colombier fprint(2, "%s: can't malloc: %r\n", argv0);
23318027f8cSDavid du Colombier exits("no mem");
23418027f8cSDavid du Colombier }
23518027f8cSDavid du Colombier seek(fd, 0, 0);
23618027f8cSDavid du Colombier read(fd, v, size);
23718027f8cSDavid du Colombier v[size] = 0;
23818027f8cSDavid du Colombier close(fd);
23918027f8cSDavid du Colombier return v;
24018027f8cSDavid du Colombier }
24118027f8cSDavid du Colombier
24218027f8cSDavid du Colombier int
newwin(char * win)24318027f8cSDavid du Colombier newwin(char *win)
24418027f8cSDavid du Colombier {
24518027f8cSDavid du Colombier char *srv, *mntsrv;
24618027f8cSDavid du Colombier char spec[100];
24718027f8cSDavid du Colombier int srvfd, cons, pid;
24818027f8cSDavid du Colombier
24918027f8cSDavid du Colombier switch(rfork(RFFDG|RFPROC|RFNAMEG|RFENVG|RFNOTEG|RFNOWAIT)){
25018027f8cSDavid du Colombier case -1:
251a4162ed5SDavid du Colombier fprint(2, "statusbar: can't fork: %r\n");
25218027f8cSDavid du Colombier return -1;
25318027f8cSDavid du Colombier case 0:
25418027f8cSDavid du Colombier break;
25518027f8cSDavid du Colombier default:
25618027f8cSDavid du Colombier exits(0);
25718027f8cSDavid du Colombier }
25818027f8cSDavid du Colombier
25918027f8cSDavid du Colombier srv = rdenv("/env/wsys");
26018027f8cSDavid du Colombier if(srv == 0){
26118027f8cSDavid du Colombier mntsrv = rdenv("/mnt/term/env/wsys");
26218027f8cSDavid du Colombier if(mntsrv == 0){
263a4162ed5SDavid du Colombier fprint(2, "statusbar: can't find $wsys\n");
26418027f8cSDavid du Colombier return -1;
26518027f8cSDavid du Colombier }
26618027f8cSDavid du Colombier srv = malloc(strlen(mntsrv)+10);
26718027f8cSDavid du Colombier sprint(srv, "/mnt/term%s", mntsrv);
26818027f8cSDavid du Colombier free(mntsrv);
26918027f8cSDavid du Colombier pid = 0; /* can't send notes to remote processes! */
27018027f8cSDavid du Colombier }else
27118027f8cSDavid du Colombier pid = getpid();
27218027f8cSDavid du Colombier USED(pid);
27318027f8cSDavid du Colombier srvfd = open(srv, ORDWR);
27418027f8cSDavid du Colombier free(srv);
27518027f8cSDavid du Colombier if(srvfd == -1){
276a4162ed5SDavid du Colombier fprint(2, "statusbar: can't open %s: %r\n", srv);
27718027f8cSDavid du Colombier return -1;
27818027f8cSDavid du Colombier }
27918027f8cSDavid du Colombier sprint(spec, "new -r %s", win);
28018027f8cSDavid du Colombier if(mount(srvfd, -1, "/mnt/wsys", 0, spec) == -1){
281a4162ed5SDavid du Colombier fprint(2, "statusbar: can't mount /mnt/wsys: %r (spec=%s)\n", spec);
28218027f8cSDavid du Colombier return -1;
28318027f8cSDavid du Colombier }
28418027f8cSDavid du Colombier close(srvfd);
28518027f8cSDavid du Colombier unmount("/mnt/acme", "/dev");
28618027f8cSDavid du Colombier bind("/mnt/wsys", "/dev", MBEFORE);
28718027f8cSDavid du Colombier cons = open("/dev/cons", OREAD);
28818027f8cSDavid du Colombier if(cons==-1){
28918027f8cSDavid du Colombier NoCons:
290a4162ed5SDavid du Colombier fprint(2, "statusbar: can't open /dev/cons: %r");
29118027f8cSDavid du Colombier return -1;
29218027f8cSDavid du Colombier }
29318027f8cSDavid du Colombier dup(cons, 0);
29418027f8cSDavid du Colombier close(cons);
29518027f8cSDavid du Colombier cons = open("/dev/cons", OWRITE);
29618027f8cSDavid du Colombier if(cons==-1)
29718027f8cSDavid du Colombier goto NoCons;
29818027f8cSDavid du Colombier dup(cons, 1);
29918027f8cSDavid du Colombier dup(cons, 2);
30018027f8cSDavid du Colombier close(cons);
30118027f8cSDavid du Colombier // wctlfd = open("/dev/wctl", OWRITE);
30218027f8cSDavid du Colombier return 0;
30318027f8cSDavid du Colombier }
30418027f8cSDavid du Colombier
30518027f8cSDavid du Colombier Rectangle
screenrect(void)30618027f8cSDavid du Colombier screenrect(void)
30718027f8cSDavid du Colombier {
30818027f8cSDavid du Colombier int fd;
30918027f8cSDavid du Colombier char buf[12*5];
31018027f8cSDavid du Colombier
31118027f8cSDavid du Colombier fd = open("/dev/screen", OREAD);
31218027f8cSDavid du Colombier if(fd == -1)
31318027f8cSDavid du Colombier fd=open("/mnt/term/dev/screen", OREAD);
31418027f8cSDavid du Colombier if(fd == -1){
31518027f8cSDavid du Colombier fprint(2, "%s: can't open /dev/screen: %r\n", argv0);
31618027f8cSDavid du Colombier exits("window read");
31718027f8cSDavid du Colombier }
31818027f8cSDavid du Colombier if(read(fd, buf, sizeof buf) != sizeof buf){
31918027f8cSDavid du Colombier fprint(2, "%s: can't read /dev/screen: %r\n", argv0);
32018027f8cSDavid du Colombier exits("screen read");
32118027f8cSDavid du Colombier }
32218027f8cSDavid du Colombier close(fd);
32318027f8cSDavid du Colombier return Rect(atoi(buf+12), atoi(buf+24), atoi(buf+36), atoi(buf+48));
32418027f8cSDavid du Colombier }
32518027f8cSDavid du Colombier
32618027f8cSDavid du Colombier int
postnote(int group,int pid,char * note)32718027f8cSDavid du Colombier postnote(int group, int pid, char *note)
32818027f8cSDavid du Colombier {
32918027f8cSDavid du Colombier char file[128];
33018027f8cSDavid du Colombier int f, r;
33118027f8cSDavid du Colombier
33218027f8cSDavid du Colombier switch(group) {
33318027f8cSDavid du Colombier case PNPROC:
33418027f8cSDavid du Colombier sprint(file, "/proc/%d/note", pid);
33518027f8cSDavid du Colombier break;
33618027f8cSDavid du Colombier case PNGROUP:
33718027f8cSDavid du Colombier sprint(file, "/proc/%d/notepg", pid);
33818027f8cSDavid du Colombier break;
33918027f8cSDavid du Colombier case PNCTL:
34018027f8cSDavid du Colombier sprint(file, "/proc/%d/ctl", pid);
34118027f8cSDavid du Colombier break;
34218027f8cSDavid du Colombier default:
34318027f8cSDavid du Colombier return -1;
34418027f8cSDavid du Colombier }
34518027f8cSDavid du Colombier
34618027f8cSDavid du Colombier f = open(file, OWRITE);
34718027f8cSDavid du Colombier if(f < 0)
34818027f8cSDavid du Colombier return -1;
34918027f8cSDavid du Colombier
35018027f8cSDavid du Colombier r = strlen(note);
35118027f8cSDavid du Colombier if(write(f, note, r) != r) {
35218027f8cSDavid du Colombier close(f);
35318027f8cSDavid du Colombier return -1;
35418027f8cSDavid du Colombier }
35518027f8cSDavid du Colombier close(f);
35618027f8cSDavid du Colombier return 0;
35718027f8cSDavid du Colombier }
358