From 1e987f65a1e11a49f3b0200083b8f619554fb9fc Mon Sep 17 00:00:00 2001 From: rsc Date: Sun, 25 Mar 2007 17:19:30 +0000 Subject: import statusbar, converted to libthread (Lou Kamenov) --- src/cmd/draw/statusbar.c | 234 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 src/cmd/draw/statusbar.c (limited to 'src/cmd/draw') diff --git a/src/cmd/draw/statusbar.c b/src/cmd/draw/statusbar.c new file mode 100644 index 00000000..fef6d2dd --- /dev/null +++ b/src/cmd/draw/statusbar.c @@ -0,0 +1,234 @@ +#include +#include +#include +#include +#include +#include +#include + +void keyboardthread(void *v); +void mousethread(void *v); +void resizethread(void *v); +void updateproc(void *v); + +enum { + STACK = 8196, +}; + +int nokill; +int textmode; +char *title; + +Biobuf b; +Image *light; +Image *dark; +Image *text; +Keyboardctl *kc; +Mousectl *mc; + +void +initcolor(void) +{ + text = display->black; + light = allocimagemix(display, DPalegreen, DWhite); + dark = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DDarkgreen); +} + +Rectangle rbar; +vlong n, d; +int last; +int lastp = -1; + +char backup[80]; + +void +drawbar(void) +{ + int i, j; + int p; + char buf[400], bar[200]; + static char lastbar[200]; + + if(n > d || n < 0 || d <= 0) + return; + + i = (Dx(rbar)*n)/d; + p = (n*100LL)/d; + if(textmode){ + if(Dx(rbar) > 150){ + rbar.min.x = 0; + rbar.max.x = 150; + return; + } + bar[0] = '|'; + for(j=0; jr.min, Pt(Dx(rbar)-30, 4)), text, ZP, display->defaultfont, buf, light, ZP); + lastp = p; + } + + if(last != i){ + draw(screen, Rect(rbar.min.x+last, rbar.min.y, rbar.min.x+i, rbar.max.y), + dark, nil, ZP); + last = i; + } + flushimage(display, 1); +} + +void +resize() +{ + Point p, q; + Rectangle r; + + r = screen->r; + draw(screen, r, light, nil, ZP); + p = string(screen, addpt(r.min, Pt(4,4)), text, ZP, + display->defaultfont, title); + + p.x = r.min.x+4; + p.y += display->defaultfont->height+4; + + q = subpt(r.max, Pt(4,4)); + rbar = Rpt(p, q); + border(screen, rbar, -2, dark, ZP); + last = 0; + lastp = -1; + + flushimage(display, 1); + drawbar(); +} + +void +keyboardthread(void *v) +{ + Rune r; + + while(recv(kc->c , &r) == 1){ + if ((r == 0x7F || r == 0x03 || r == 'q') && !nokill) + threadexitsall("interrupt"); + } +} + +void +mousethread(void *v) +{ + USED(v); + + while(recv(mc->c, 0) == 1); /* to unblock mc->c */ +} + +void +resizethread(void *v) +{ + USED(v); + + while(recv(mc->resizec, 0) == 1){ + lockdisplay(display); + if(getwindow(display, Refnone) < 0) + sysfatal("attach to window: %r"); + resize(); + unlockdisplay(display); + } +} + +void +updateproc(void *v) +{ + char *p, *f[2]; + + sleep(1000); + while((p = Brdline(&b, '\n'))){ + p[Blinelen(&b)-1] = '\0'; + if(tokenize(p, f, 2) != 2) + continue; + n = strtoll(f[0], 0, 0); + d = strtoll(f[1], 0, 0); + if(!textmode){ + lockdisplay(display); + drawbar(); + unlockdisplay(display); + } else + drawbar(); + } + threadexitsall("success"); +} + +void +usage(void) +{ + fprint(2, "usage: statusbar [-kt] [-W winsize] 'title'\n"); + threadexitsall("usage"); +} + +void +threadmain(int argc, char **argv) +{ + char *p; + int lfd; + + p = "300x40@100,100"; + + ARGBEGIN{ + case 'W': + p = ARGF(); + break; + case 't': + textmode = 1; + break; + case 'k': + nokill = 1; + break; + default: + usage(); + }ARGEND; + + if(argc != 1) + usage(); + + winsize = p; + + title = argv[0]; + + lfd = dup(0, -1); + Binit(&b, lfd, OREAD); + + rbar = Rect(0, 0, 60, 1); + if (!textmode){ + if(initdraw(0, nil, "bar") < 0) + sysfatal("initdraw: %r"); + initcolor(); + if((mc = initmouse(nil, screen)) == nil) + sysfatal("initmouse: %r"); + if((kc = initkeyboard(nil)) == nil) + sysfatal("initkeyboard: %r"); + display->locking = 1; + threadcreate(resizethread, nil, STACK); + threadcreate(keyboardthread, nil, STACK); + threadcreate(mousethread, nil, STACK); + resize(); + unlockdisplay(display); + } + proccreate(updateproc, nil, STACK); +} + -- cgit v1.2.3