aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/draw
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2007-03-25 17:19:30 +0000
committerrsc <devnull@localhost>2007-03-25 17:19:30 +0000
commit1e987f65a1e11a49f3b0200083b8f619554fb9fc (patch)
tree0c5fa25813413f4b748b3312adeb51b41ec2d9bb /src/cmd/draw
parent7eddb1da6f6634d3b6b58413cf367585daf70a9f (diff)
downloadplan9port-1e987f65a1e11a49f3b0200083b8f619554fb9fc.tar.gz
plan9port-1e987f65a1e11a49f3b0200083b8f619554fb9fc.tar.bz2
plan9port-1e987f65a1e11a49f3b0200083b8f619554fb9fc.zip
import statusbar, converted to libthread (Lou Kamenov)
Diffstat (limited to 'src/cmd/draw')
-rw-r--r--src/cmd/draw/statusbar.c234
1 files changed, 234 insertions, 0 deletions
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 <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);
+}
+