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 }