timport statusbar, converted to libthread (Lou Kamenov) - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 1e987f65a1e11a49f3b0200083b8f619554fb9fc
 (DIR) parent 7eddb1da6f6634d3b6b58413cf367585daf70a9f
 (HTM) Author: rsc <devnull@localhost>
       Date:   Sun, 25 Mar 2007 17:19:30 +0000
       
       import statusbar, converted to libthread (Lou Kamenov)
       
       Diffstat:
         A src/cmd/draw/statusbar.c            |     234 +++++++++++++++++++++++++++++++
       
       1 file changed, 234 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/draw/statusbar.c b/src/cmd/draw/statusbar.c
       t@@ -0,0 +1,234 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <draw.h>
       +#include <thread.h>
       +#include <bio.h>
       +#include <mouse.h>
       +#include <keyboard.h>
       +
       +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; j<i; j++)
       +                        bar[j+1] = '#';
       +                for(; j<Dx(rbar); j++)
       +                        bar[j+1] = '-';
       +                bar[j++] = '|';
       +                bar[j++] = ' ';
       +                sprint(bar+j, "%3d%% ", p);
       +                for(i=0; bar[i]==lastbar[i] && bar[i]; i++)
       +                        ;
       +                memset(buf, '\b', strlen(lastbar)-i);
       +                strcpy(buf+strlen(lastbar)-i, bar+i);
       +                if(buf[0])
       +                        write(1, buf, strlen(buf));
       +                strcpy(lastbar, bar);
       +                return;
       +        }
       +
       +        if(lastp == p && last == i)
       +                return;
       +
       +        if(lastp != p){
       +                sprint(buf, "%d%%", p);
       +                stringbg(screen, addpt(screen->r.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);
       +}
       +