URI:
       tstatusbar.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tstatusbar.c (3806B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <draw.h>
            4 #include <thread.h>
            5 #include <bio.h>
            6 #include <mouse.h>
            7 #include <keyboard.h>
            8 
            9 void keyboardthread(void *v);
           10 void mousethread(void *v);
           11 void resizethread(void *v);
           12 void updateproc(void *v);
           13 
           14 enum {
           15         STACK = 8196,
           16 };
           17 
           18 int nokill;
           19 int textmode;
           20 char *title;
           21 
           22 Biobuf b;
           23 Image *light;
           24 Image *dark;
           25 Image *text;
           26 Keyboardctl *kc;
           27 Mousectl *mc;
           28 
           29 void
           30 initcolor(void)
           31 {
           32         text = display->black;
           33         light = allocimagemix(display, DPalegreen, DWhite);
           34         dark = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DDarkgreen);
           35 }
           36 
           37 Rectangle rbar;
           38 vlong n, d;
           39 int last;
           40 int lastp = -1;
           41 
           42 char backup[80];
           43 
           44 void
           45 drawbar(void)
           46 {
           47         int i, j;
           48         int p;
           49         char buf[400], bar[200];
           50         static char lastbar[200];
           51 
           52         if(n > d || n < 0 || d <= 0)
           53                 return;
           54 
           55         i = (Dx(rbar)*n)/d;
           56         p = (n*100LL)/d;
           57         if(textmode){
           58                 if(Dx(rbar) > 150){
           59                         rbar.min.x = 0;
           60                         rbar.max.x = 150;
           61                         return;
           62                 }
           63                 bar[0] = '|';
           64                 for(j=0; j<i; j++)
           65                         bar[j+1] = '#';
           66                 for(; j<Dx(rbar); j++)
           67                         bar[j+1] = '-';
           68                 bar[j++] = '|';
           69                 bar[j++] = ' ';
           70                 sprint(bar+j, "%3d%% ", p);
           71                 for(i=0; bar[i]==lastbar[i] && bar[i]; i++)
           72                         ;
           73                 memset(buf, '\b', strlen(lastbar)-i);
           74                 strcpy(buf+strlen(lastbar)-i, bar+i);
           75                 if(buf[0])
           76                         write(1, buf, strlen(buf));
           77                 strcpy(lastbar, bar);
           78                 return;
           79         }
           80 
           81         if(lastp == p && last == i)
           82                 return;
           83 
           84         if(lastp != p){
           85                 sprint(buf, "%d%%", p);
           86                 stringbg(screen, addpt(screen->r.min, Pt(Dx(rbar)-30, 4)), text, ZP, display->defaultfont, buf, light, ZP);
           87                 lastp = p;
           88         }
           89 
           90         if(last != i){
           91                 draw(screen, Rect(rbar.min.x+last, rbar.min.y, rbar.min.x+i, rbar.max.y),
           92                         dark, nil, ZP);
           93                 last = i;
           94         }
           95         flushimage(display, 1);
           96 }
           97 
           98 void
           99 resize()
          100 {
          101         Point p, q;
          102         Rectangle r;
          103 
          104         r = screen->r;
          105         draw(screen, r, light, nil, ZP);
          106         p = string(screen, addpt(r.min, Pt(4,4)), text, ZP,
          107                 display->defaultfont, title);
          108 
          109         p.x = r.min.x+4;
          110         p.y += display->defaultfont->height+4;
          111 
          112         q = subpt(r.max, Pt(4,4));
          113         rbar = Rpt(p, q);
          114         border(screen, rbar, -2, dark, ZP);
          115         last = 0;
          116         lastp = -1;
          117 
          118         flushimage(display, 1);
          119         drawbar();
          120 }
          121 
          122 void
          123 keyboardthread(void *v)
          124 {
          125         Rune r;
          126 
          127         while(recv(kc->c , &r) == 1){
          128                 if ((r == 0x7F || r == 0x03 || r == 'q') && !nokill)
          129                         threadexitsall("interrupt");
          130         }
          131 }
          132 
          133 void
          134 mousethread(void *v)
          135 {
          136         USED(v);
          137 
          138         while(recv(mc->c, 0) == 1); /* to unblock mc->c */
          139 }
          140 
          141 void
          142 resizethread(void *v)
          143 {
          144         USED(v);
          145 
          146         while(recv(mc->resizec, 0) == 1){
          147                 lockdisplay(display);
          148                 if(getwindow(display, Refnone) < 0)
          149                         sysfatal("attach to window: %r");
          150                 resize();
          151                 unlockdisplay(display);
          152         }
          153 }
          154 
          155 void
          156 updateproc(void *v)
          157 {
          158         char *p, *f[2];
          159 
          160         sleep(1000);
          161         while((p = Brdline(&b, '\n'))){
          162                 p[Blinelen(&b)-1] = '\0';
          163                 if(tokenize(p, f, 2) != 2)
          164                         continue;
          165                 n = strtoll(f[0], 0, 0);
          166                 d = strtoll(f[1], 0, 0);
          167                 if(!textmode){
          168                         lockdisplay(display);
          169                         drawbar();
          170                         unlockdisplay(display);
          171                 } else
          172                         drawbar();
          173         }
          174         threadexitsall("success");
          175 }
          176 
          177 void
          178 usage(void)
          179 {
          180         fprint(2, "usage: statusbar [-kt] [-W winsize] 'title'\n");
          181         threadexitsall("usage");
          182 }
          183 
          184 void
          185 threadmain(int argc, char **argv)
          186 {
          187         char *p;
          188         int lfd;
          189 
          190         p = "300x40@100,100";
          191 
          192         ARGBEGIN{
          193         case 'W':
          194                 p = ARGF();
          195                 break;
          196         case 't':
          197                 textmode = 1;
          198                 break;
          199         case 'k':
          200                 nokill = 1;
          201                 break;
          202         default:
          203                 usage();
          204         }ARGEND;
          205 
          206         if(argc != 1)
          207                 usage();
          208 
          209         winsize = p;
          210 
          211         title = argv[0];
          212 
          213         lfd = dup(0, -1);
          214         Binit(&b, lfd, OREAD);
          215 
          216         rbar = Rect(0, 0, 60, 1);
          217         if (!textmode){
          218                 if(initdraw(0, nil, "bar") < 0)
          219                         sysfatal("initdraw: %r");
          220                 initcolor();
          221                 if((mc = initmouse(nil, screen)) == nil)
          222                         sysfatal("initmouse: %r");
          223                 if((kc = initkeyboard(nil)) == nil)
          224                         sysfatal("initkeyboard: %r");
          225                 display->locking = 1;
          226                 threadcreate(resizethread, nil, STACK);
          227                 threadcreate(keyboardthread, nil, STACK);
          228                 threadcreate(mousethread, nil, STACK);
          229                 resize();
          230                 unlockdisplay(display);
          231         }
          232         proccreate(updateproc, nil, STACK);
          233 }