19a747e4fSDavid du Colombier #include <u.h>
29a747e4fSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <draw.h>
49a747e4fSDavid du Colombier #include <bio.h>
59a747e4fSDavid du Colombier #include <event.h>
69a747e4fSDavid du Colombier
79a747e4fSDavid du Colombier enum {PNCTL=3};
89a747e4fSDavid du Colombier
99a747e4fSDavid du Colombier static char* rdenv(char*);
1067031067SDavid du Colombier int newwin(char*);
119a747e4fSDavid du Colombier Rectangle screenrect(void);
129a747e4fSDavid du Colombier
139a747e4fSDavid du Colombier int nokill;
1467031067SDavid du Colombier int textmode;
159a747e4fSDavid du Colombier char *title;
169a747e4fSDavid du Colombier
179a747e4fSDavid du Colombier Image *light;
189a747e4fSDavid du Colombier Image *dark;
199a747e4fSDavid du Colombier Image *text;
209a747e4fSDavid du Colombier
219a747e4fSDavid du Colombier void
initcolor(void)229a747e4fSDavid du Colombier initcolor(void)
239a747e4fSDavid du Colombier {
249a747e4fSDavid du Colombier text = display->black;
259a747e4fSDavid du Colombier light = allocimagemix(display, DPalegreen, DWhite);
269a747e4fSDavid du Colombier dark = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DDarkgreen);
279a747e4fSDavid du Colombier }
289a747e4fSDavid du Colombier
299a747e4fSDavid du Colombier Rectangle rbar;
309a747e4fSDavid du Colombier Point ptext;
3167031067SDavid du Colombier vlong n, d;
329a747e4fSDavid du Colombier int last;
33cf835aecSDavid du Colombier int lastp = -1;
3467031067SDavid du Colombier int first = 1;
3567031067SDavid du Colombier
3667031067SDavid du Colombier char backup[80];
379a747e4fSDavid du Colombier
389a747e4fSDavid du Colombier void
drawbar(void)399a747e4fSDavid du Colombier drawbar(void)
409a747e4fSDavid du Colombier {
4167031067SDavid du Colombier int i, j;
429a747e4fSDavid du Colombier int p;
43*9b7bf7dfSDavid du Colombier char buf[200], bar[100];
44cf835aecSDavid du Colombier static char lastbar[100];
459a747e4fSDavid du Colombier
469a747e4fSDavid du Colombier if(n > d || n < 0 || d <= 0)
479a747e4fSDavid du Colombier return;
489a747e4fSDavid du Colombier
4967031067SDavid du Colombier i = (Dx(rbar)*n)/d;
509a747e4fSDavid du Colombier p = (n*100LL)/d;
519a747e4fSDavid du Colombier
5267031067SDavid du Colombier if(textmode){
5367031067SDavid du Colombier bar[0] = '|';
5467031067SDavid du Colombier for(j=0; j<i; j++)
5567031067SDavid du Colombier bar[j+1] = '#';
5667031067SDavid du Colombier for(; j<60; j++)
5767031067SDavid du Colombier bar[j+1] = '-';
5867031067SDavid du Colombier bar[61] = '|';
5967031067SDavid du Colombier bar[62] = ' ';
6067031067SDavid du Colombier sprint(bar+63, "%3d%% ", p);
61cf835aecSDavid du Colombier for(i=0; bar[i]==lastbar[i] && bar[i]; i++)
62cf835aecSDavid du Colombier ;
63cf835aecSDavid du Colombier memset(buf, '\b', strlen(lastbar)-i);
64cf835aecSDavid du Colombier strcpy(buf+strlen(lastbar)-i, bar+i);
65cf835aecSDavid du Colombier if(buf[0])
66cf835aecSDavid du Colombier write(1, buf, strlen(buf));
67cf835aecSDavid du Colombier strcpy(lastbar, bar);
6867031067SDavid du Colombier return;
6967031067SDavid du Colombier }
7067031067SDavid du Colombier
71cf835aecSDavid du Colombier if(lastp == p && last == i)
72cf835aecSDavid du Colombier return;
73cf835aecSDavid du Colombier
749a747e4fSDavid du Colombier if(lastp != p){
759a747e4fSDavid du Colombier sprint(buf, "%d%%", p);
769a747e4fSDavid du Colombier
779a747e4fSDavid du Colombier stringbg(screen, addpt(screen->r.min, Pt(Dx(rbar)-30, 4)), text, ZP, display->defaultfont, buf, light, ZP);
789a747e4fSDavid du Colombier lastp = p;
799a747e4fSDavid du Colombier }
809a747e4fSDavid du Colombier
819a747e4fSDavid du Colombier if(last != i){
829a747e4fSDavid du Colombier draw(screen, Rect(rbar.min.x+last, rbar.min.y, rbar.min.x+i, rbar.max.y),
839a747e4fSDavid du Colombier dark, nil, ZP);
849a747e4fSDavid du Colombier last = i;
859a747e4fSDavid du Colombier }
869a747e4fSDavid du Colombier flushimage(display, 1);
879a747e4fSDavid du Colombier }
889a747e4fSDavid du Colombier
899a747e4fSDavid du Colombier void
eresized(int new)909a747e4fSDavid du Colombier eresized(int new)
919a747e4fSDavid du Colombier {
929a747e4fSDavid du Colombier Point p, q;
939a747e4fSDavid du Colombier Rectangle r;
949a747e4fSDavid du Colombier
959a747e4fSDavid du Colombier if(new && getwindow(display, Refnone) < 0)
969a747e4fSDavid du Colombier fprint(2,"can't reattach to window");
979a747e4fSDavid du Colombier
989a747e4fSDavid du Colombier r = screen->r;
999a747e4fSDavid du Colombier draw(screen, r, light, nil, ZP);
1009a747e4fSDavid du Colombier p = string(screen, addpt(r.min, Pt(4,4)), text, ZP,
1019a747e4fSDavid du Colombier display->defaultfont, title);
1029a747e4fSDavid du Colombier
1039a747e4fSDavid du Colombier p.x = r.min.x+4;
1049a747e4fSDavid du Colombier p.y += display->defaultfont->height+4;
1059a747e4fSDavid du Colombier
1069a747e4fSDavid du Colombier q = subpt(r.max, Pt(4,4));
1079a747e4fSDavid du Colombier rbar = Rpt(p, q);
1089a747e4fSDavid du Colombier
1099a747e4fSDavid du Colombier ptext = Pt(r.max.x-4-stringwidth(display->defaultfont, "100%"), r.min.x+4);
1109a747e4fSDavid du Colombier border(screen, rbar, -2, dark, ZP);
1119a747e4fSDavid du Colombier last = 0;
1129a747e4fSDavid du Colombier lastp = -1;
1139a747e4fSDavid du Colombier
1149a747e4fSDavid du Colombier drawbar();
1159a747e4fSDavid du Colombier }
1169a747e4fSDavid du Colombier
1179a747e4fSDavid du Colombier void
bar(Biobuf * b)1189a747e4fSDavid du Colombier bar(Biobuf *b)
1199a747e4fSDavid du Colombier {
1209a747e4fSDavid du Colombier char *p, *f[2];
1219a747e4fSDavid du Colombier Event e;
1229a747e4fSDavid du Colombier int k, die, parent, child;
1239a747e4fSDavid du Colombier
1249a747e4fSDavid du Colombier parent = getpid();
1259a747e4fSDavid du Colombier
1269a747e4fSDavid du Colombier die = 0;
1270d81f006SDavid du Colombier if(textmode)
1280d81f006SDavid du Colombier child = -1;
1290d81f006SDavid du Colombier else
1300d81f006SDavid du Colombier switch(child = rfork(RFMEM|RFPROC)) {
1319a747e4fSDavid du Colombier case 0:
1329a747e4fSDavid du Colombier sleep(1000);
1339a747e4fSDavid du Colombier while(!die && (k = eread(Ekeyboard|Emouse, &e))) {
1349a747e4fSDavid du Colombier if(nokill==0 && k == Ekeyboard && (e.kbdc == 0x7F || e.kbdc == 0x03)) { /* del, ctl-c */
1359a747e4fSDavid du Colombier die = 1;
1369a747e4fSDavid du Colombier postnote(PNPROC, parent, "interrupt");
1379a747e4fSDavid du Colombier _exits("interrupt");
1389a747e4fSDavid du Colombier }
1399a747e4fSDavid du Colombier }
1409a747e4fSDavid du Colombier _exits(0);
1419a747e4fSDavid du Colombier }
1429a747e4fSDavid du Colombier
1439a747e4fSDavid du Colombier while(!die && (p = Brdline(b, '\n'))) {
1449a747e4fSDavid du Colombier p[Blinelen(b)-1] = '\0';
1459a747e4fSDavid du Colombier if(tokenize(p, f, 2) != 2)
1469a747e4fSDavid du Colombier continue;
14767031067SDavid du Colombier n = strtoll(f[0], 0, 0);
14867031067SDavid du Colombier d = strtoll(f[1], 0, 0);
1499a747e4fSDavid du Colombier drawbar();
1509a747e4fSDavid du Colombier }
1519a747e4fSDavid du Colombier postnote(PNCTL, child, "kill");
1529a747e4fSDavid du Colombier }
1539a747e4fSDavid du Colombier
1549a747e4fSDavid du Colombier
1559a747e4fSDavid du Colombier void
usage(void)1569a747e4fSDavid du Colombier usage(void)
1579a747e4fSDavid du Colombier {
15867031067SDavid du Colombier fprint(2, "usage: bargraph [-kt] [-w minx,miny,maxx,maxy] 'title'\n");
1599a747e4fSDavid du Colombier exits("usage");
1609a747e4fSDavid du Colombier }
1619a747e4fSDavid du Colombier
1629a747e4fSDavid du Colombier void
main(int argc,char ** argv)1639a747e4fSDavid du Colombier main(int argc, char **argv)
1649a747e4fSDavid du Colombier {
1659a747e4fSDavid du Colombier Biobuf b;
1669a747e4fSDavid du Colombier char *p, *q;
1679a747e4fSDavid du Colombier int lfd;
1689a747e4fSDavid du Colombier
16967031067SDavid du Colombier p = "0,0,200,60";
1709a747e4fSDavid du Colombier
1719a747e4fSDavid du Colombier ARGBEGIN{
1729a747e4fSDavid du Colombier case 'w':
1739a747e4fSDavid du Colombier p = ARGF();
1749a747e4fSDavid du Colombier break;
17567031067SDavid du Colombier case 't':
17667031067SDavid du Colombier textmode = 1;
17767031067SDavid du Colombier break;
1789a747e4fSDavid du Colombier case 'k':
1799a747e4fSDavid du Colombier nokill = 1;
1809a747e4fSDavid du Colombier break;
1819a747e4fSDavid du Colombier default:
1829a747e4fSDavid du Colombier usage();
1839a747e4fSDavid du Colombier }ARGEND;
1849a747e4fSDavid du Colombier
1859a747e4fSDavid du Colombier if(argc != 1)
1869a747e4fSDavid du Colombier usage();
1879a747e4fSDavid du Colombier
1889a747e4fSDavid du Colombier title = argv[0];
1899a747e4fSDavid du Colombier
1909a747e4fSDavid du Colombier lfd = dup(0, -1);
1919a747e4fSDavid du Colombier
1929a747e4fSDavid du Colombier while(q = strchr(p, ','))
1939a747e4fSDavid du Colombier *q = ' ';
19467031067SDavid du Colombier Binit(&b, lfd, OREAD);
19567031067SDavid du Colombier if(textmode || newwin(p) < 0){
19667031067SDavid du Colombier textmode = 1;
19767031067SDavid du Colombier rbar = Rect(0, 0, 60, 1);
19867031067SDavid du Colombier }else{
1999a747e4fSDavid du Colombier initdraw(0, 0, "bar");
2009a747e4fSDavid du Colombier initcolor();
2019a747e4fSDavid du Colombier einit(Emouse|Ekeyboard);
2029a747e4fSDavid du Colombier eresized(0);
20367031067SDavid du Colombier }
2049a747e4fSDavid du Colombier bar(&b);
2059a747e4fSDavid du Colombier }
2069a747e4fSDavid du Colombier
2079a747e4fSDavid du Colombier
2089a747e4fSDavid du Colombier /* all code below this line should be in the library, but is stolen from colors instead */
2099a747e4fSDavid du Colombier static char*
rdenv(char * name)2109a747e4fSDavid du Colombier rdenv(char *name)
2119a747e4fSDavid du Colombier {
2129a747e4fSDavid du Colombier char *v;
2139a747e4fSDavid du Colombier int fd, size;
2149a747e4fSDavid du Colombier
2159a747e4fSDavid du Colombier fd = open(name, OREAD);
2169a747e4fSDavid du Colombier if(fd < 0)
2179a747e4fSDavid du Colombier return 0;
2189a747e4fSDavid du Colombier size = seek(fd, 0, 2);
2199a747e4fSDavid du Colombier v = malloc(size+1);
2209a747e4fSDavid du Colombier if(v == 0){
221cf835aecSDavid du Colombier fprint(2, "%s: can't malloc: %r\n", argv0);
2229a747e4fSDavid du Colombier exits("no mem");
2239a747e4fSDavid du Colombier }
2249a747e4fSDavid du Colombier seek(fd, 0, 0);
2259a747e4fSDavid du Colombier read(fd, v, size);
2269a747e4fSDavid du Colombier v[size] = 0;
2279a747e4fSDavid du Colombier close(fd);
2289a747e4fSDavid du Colombier return v;
2299a747e4fSDavid du Colombier }
2309a747e4fSDavid du Colombier
23167031067SDavid du Colombier int
newwin(char * win)2329a747e4fSDavid du Colombier newwin(char *win)
2339a747e4fSDavid du Colombier {
2349a747e4fSDavid du Colombier char *srv, *mntsrv;
2359a747e4fSDavid du Colombier char spec[100];
2369a747e4fSDavid du Colombier int srvfd, cons, pid;
2379a747e4fSDavid du Colombier
2389a747e4fSDavid du Colombier switch(rfork(RFFDG|RFPROC|RFNAMEG|RFENVG|RFNOTEG|RFNOWAIT)){
2399a747e4fSDavid du Colombier case -1:
24067031067SDavid du Colombier fprint(2, "bargraph: can't fork: %r\n");
24167031067SDavid du Colombier return -1;
2429a747e4fSDavid du Colombier case 0:
2439a747e4fSDavid du Colombier break;
2449a747e4fSDavid du Colombier default:
2459a747e4fSDavid du Colombier exits(0);
2469a747e4fSDavid du Colombier }
2479a747e4fSDavid du Colombier
2489a747e4fSDavid du Colombier srv = rdenv("/env/wsys");
2499a747e4fSDavid du Colombier if(srv == 0){
2509a747e4fSDavid du Colombier mntsrv = rdenv("/mnt/term/env/wsys");
2519a747e4fSDavid du Colombier if(mntsrv == 0){
25267031067SDavid du Colombier fprint(2, "bargraph: can't find $wsys\n");
25367031067SDavid du Colombier return -1;
2549a747e4fSDavid du Colombier }
2559a747e4fSDavid du Colombier srv = malloc(strlen(mntsrv)+10);
2569a747e4fSDavid du Colombier sprint(srv, "/mnt/term%s", mntsrv);
2579a747e4fSDavid du Colombier free(mntsrv);
2589a747e4fSDavid du Colombier pid = 0; /* can't send notes to remote processes! */
2599a747e4fSDavid du Colombier }else
2609a747e4fSDavid du Colombier pid = getpid();
2610d81f006SDavid du Colombier USED(pid);
2629a747e4fSDavid du Colombier srvfd = open(srv, ORDWR);
2639a747e4fSDavid du Colombier free(srv);
2649a747e4fSDavid du Colombier if(srvfd == -1){
26567031067SDavid du Colombier fprint(2, "bargraph: can't open %s: %r\n", srv);
26667031067SDavid du Colombier return -1;
2679a747e4fSDavid du Colombier }
2689a747e4fSDavid du Colombier sprint(spec, "new -r %s", win);
2699a747e4fSDavid du Colombier if(mount(srvfd, -1, "/mnt/wsys", 0, spec) == -1){
27067031067SDavid du Colombier fprint(2, "bargraph: can't mount /mnt/wsys: %r (spec=%s)\n", spec);
27167031067SDavid du Colombier return -1;
2729a747e4fSDavid du Colombier }
2739a747e4fSDavid du Colombier close(srvfd);
2749a747e4fSDavid du Colombier unmount("/mnt/acme", "/dev");
2759a747e4fSDavid du Colombier bind("/mnt/wsys", "/dev", MBEFORE);
2769a747e4fSDavid du Colombier cons = open("/dev/cons", OREAD);
2779a747e4fSDavid du Colombier if(cons==-1){
2789a747e4fSDavid du Colombier NoCons:
27967031067SDavid du Colombier fprint(2, "bargraph: can't open /dev/cons: %r");
28067031067SDavid du Colombier return -1;
2819a747e4fSDavid du Colombier }
2829a747e4fSDavid du Colombier dup(cons, 0);
2839a747e4fSDavid du Colombier close(cons);
2849a747e4fSDavid du Colombier cons = open("/dev/cons", OWRITE);
2859a747e4fSDavid du Colombier if(cons==-1)
2869a747e4fSDavid du Colombier goto NoCons;
2879a747e4fSDavid du Colombier dup(cons, 1);
2889a747e4fSDavid du Colombier dup(cons, 2);
2899a747e4fSDavid du Colombier close(cons);
2909a747e4fSDavid du Colombier // wctlfd = open("/dev/wctl", OWRITE);
29167031067SDavid du Colombier return 0;
2929a747e4fSDavid du Colombier }
2939a747e4fSDavid du Colombier
2949a747e4fSDavid du Colombier Rectangle
screenrect(void)2959a747e4fSDavid du Colombier screenrect(void)
2969a747e4fSDavid du Colombier {
2979a747e4fSDavid du Colombier int fd;
2989a747e4fSDavid du Colombier char buf[12*5];
2999a747e4fSDavid du Colombier
3009a747e4fSDavid du Colombier fd = open("/dev/screen", OREAD);
3019a747e4fSDavid du Colombier if(fd == -1)
3029a747e4fSDavid du Colombier fd=open("/mnt/term/dev/screen", OREAD);
3039a747e4fSDavid du Colombier if(fd == -1){
304cf835aecSDavid du Colombier fprint(2, "%s: can't open /dev/screen: %r\n", argv0);
3059a747e4fSDavid du Colombier exits("window read");
3069a747e4fSDavid du Colombier }
3079a747e4fSDavid du Colombier if(read(fd, buf, sizeof buf) != sizeof buf){
308cf835aecSDavid du Colombier fprint(2, "%s: can't read /dev/screen: %r\n", argv0);
3099a747e4fSDavid du Colombier exits("screen read");
3109a747e4fSDavid du Colombier }
3119a747e4fSDavid du Colombier close(fd);
3129a747e4fSDavid du Colombier return Rect(atoi(buf+12), atoi(buf+24), atoi(buf+36), atoi(buf+48));
3139a747e4fSDavid du Colombier }
3149a747e4fSDavid du Colombier
3159a747e4fSDavid du Colombier int
postnote(int group,int pid,char * note)3169a747e4fSDavid du Colombier postnote(int group, int pid, char *note)
3179a747e4fSDavid du Colombier {
3189a747e4fSDavid du Colombier char file[128];
3199a747e4fSDavid du Colombier int f, r;
3209a747e4fSDavid du Colombier
3219a747e4fSDavid du Colombier switch(group) {
3229a747e4fSDavid du Colombier case PNPROC:
3239a747e4fSDavid du Colombier sprint(file, "/proc/%d/note", pid);
3249a747e4fSDavid du Colombier break;
3259a747e4fSDavid du Colombier case PNGROUP:
3269a747e4fSDavid du Colombier sprint(file, "/proc/%d/notepg", pid);
3279a747e4fSDavid du Colombier break;
3289a747e4fSDavid du Colombier case PNCTL:
3299a747e4fSDavid du Colombier sprint(file, "/proc/%d/ctl", pid);
3309a747e4fSDavid du Colombier break;
3319a747e4fSDavid du Colombier default:
3329a747e4fSDavid du Colombier return -1;
3339a747e4fSDavid du Colombier }
3349a747e4fSDavid du Colombier
3359a747e4fSDavid du Colombier f = open(file, OWRITE);
3369a747e4fSDavid du Colombier if(f < 0)
3379a747e4fSDavid du Colombier return -1;
3389a747e4fSDavid du Colombier
3399a747e4fSDavid du Colombier r = strlen(note);
3409a747e4fSDavid du Colombier if(write(f, note, r) != r) {
3419a747e4fSDavid du Colombier close(f);
3429a747e4fSDavid du Colombier return -1;
3439a747e4fSDavid du Colombier }
3449a747e4fSDavid du Colombier close(f);
3459a747e4fSDavid du Colombier return 0;
3469a747e4fSDavid du Colombier }
347