]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/aux/statusbar.c
python: update python build configuration to new ape capabilities like getaddrinfo...
[plan9front.git] / sys / src / cmd / aux / statusbar.c
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <bio.h>
5 #include <event.h>
6
7 enum {PNCTL=3};
8
9 static char* rdenv(char*);
10 int newwin(char*);
11 Rectangle screenrect(void);
12
13 int nokill;
14 int textmode;
15 char *title;
16
17 Image *light;
18 Image *dark;
19 Image *text;
20
21 void
22 initcolor(void)
23 {
24         text = display->black;
25         light = allocimagemix(display, DPalegreen, DWhite);
26         dark = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DDarkgreen);
27 }
28
29 Rectangle rbar;
30 Point ptext;
31 vlong n, d;
32 int last;
33 int lastp = -1;
34
35 char backup[80];
36
37 void
38 drawbar(void)
39 {
40         int i, j;
41         int p;
42         char buf[400], bar[200];
43         static char lastbar[200];
44
45         if(n > d || n < 0 || d <= 0)
46                 return;
47
48         i = (Dx(rbar)*n)/d;
49         p = (n*100LL)/d;
50
51         if(textmode){
52                 if(Dx(rbar) > 150){
53                         rbar.min.x = 0;
54                         rbar.max.x = 150;
55                         return;
56                 }
57                 bar[0] = '|';
58                 for(j=0; j<i; j++)
59                         bar[j+1] = '#';
60                 for(; j<Dx(rbar); j++)
61                         bar[j+1] = '-';
62                 bar[j++] = '|';
63                 bar[j++] = ' ';
64                 sprint(bar+j, "%3d%% ", p);
65                 for(i=0; bar[i]==lastbar[i] && bar[i]; i++)
66                         ;
67                 memset(buf, '\b', strlen(lastbar)-i);
68                 strcpy(buf+strlen(lastbar)-i, bar+i);
69                 if(buf[0])
70                         write(1, buf, strlen(buf));
71                 strcpy(lastbar, bar);
72                 return;
73         }
74
75         if(lastp == p && last == i)
76                 return;
77
78         if(lastp != p){
79                 sprint(buf, "%3d%%", p);
80                 
81                 stringbg(screen, addpt(screen->r.min, Pt(Dx(rbar)-30, 4)), text, ZP, display->defaultfont, buf, light, ZP);
82                 lastp = p;
83         }
84
85         if(last != i){
86                 if(i > last)
87                         draw(screen, Rect(rbar.min.x+last, rbar.min.y, rbar.min.x+i, rbar.max.y),
88                                 dark, nil, ZP);
89                 else
90                         draw(screen, Rect(rbar.min.x+i, rbar.min.y, rbar.min.x+last, rbar.max.y),
91                                 light, nil, ZP);
92                 last = i;
93         }
94         flushimage(display, 1);
95 }
96
97 void
98 eresized(int new)
99 {
100         Point p, q;
101         Rectangle r;
102
103         if(new && getwindow(display, Refnone) < 0)
104                 fprint(2,"can't reattach to window");
105
106         r = screen->r;
107         draw(screen, r, light, nil, ZP);
108         p = string(screen, addpt(r.min, Pt(4,4)), text, ZP,
109                 display->defaultfont, title);
110
111         p.x = r.min.x+4;
112         p.y += display->defaultfont->height+4;
113
114         q = subpt(r.max, Pt(4,4));
115         rbar = Rpt(p, q);
116
117         ptext = Pt(r.max.x-4-stringwidth(display->defaultfont, "100%"), r.min.x+4);
118         border(screen, rbar, -2, dark, ZP);
119         last = 0;
120         lastp = -1;
121
122         drawbar();
123 }
124
125 void
126 bar(Biobuf *b)
127 {
128         char *p, *f[2];
129         Event e;
130         int k, die, parent, child;
131
132         parent = getpid();
133
134         die = 0;
135         if(textmode)
136                 child = -1;
137         else
138         switch(child = rfork(RFMEM|RFPROC)) {
139         case 0:
140                 sleep(1000);
141                 while(!die && (k = eread(Ekeyboard|Emouse, &e))) {
142                         if(nokill==0 && k == Ekeyboard && (e.kbdc == 0x7F || e.kbdc == 0x03)) { /* del, ctl-c */
143                                 die = 1;
144                                 postnote(PNPROC, parent, "interrupt");
145                                 _exits("interrupt");
146                         }
147                 }
148                 _exits(0);
149         }
150
151         while(!die && (p = Brdline(b, '\n'))) {
152                 p[Blinelen(b)-1] = '\0';
153                 if(tokenize(p, f, 2) != 2)
154                         continue;
155                 n = strtoll(f[0], 0, 0);
156                 d = strtoll(f[1], 0, 0);
157                 drawbar();
158         }
159         postnote(PNCTL, child, "kill");
160 }
161
162
163 void
164 usage(void)
165 {
166         fprint(2, "usage: aux/statusbar [-kt] [-w minx,miny,maxx,maxy] 'title'\n");
167         exits("usage");
168 }
169
170 void
171 main(int argc, char **argv)
172 {
173         Biobuf b;
174         char *p, *q;
175         int lfd;
176
177         p = "0,0,200,60";
178         
179         ARGBEGIN{
180         case 'w':
181                 p = ARGF();
182                 break;
183         case 't':
184                 textmode = 1;
185                 break;
186         case 'k':
187                 nokill = 1;
188                 break;
189         default:
190                 usage();
191         }ARGEND;
192
193         if(argc != 1)
194                 usage();
195
196         title = argv[0];
197
198         lfd = dup(0, -1);
199
200         while(q = strchr(p, ','))
201                 *q = ' ';
202         Binit(&b, lfd, OREAD);
203         if(textmode || newwin(p) < 0){
204                 textmode = 1;
205                 rbar = Rect(0, 0, 60, 1);
206         }else{
207                 if(initdraw(0, 0, "bar") < 0)
208                         exits("initdraw");
209                 initcolor();
210                 einit(Emouse|Ekeyboard);
211                 eresized(0);
212         }
213         bar(&b);
214
215         exits(0);
216 }
217
218
219 /* all code below this line should be in the library, but is stolen from colors instead */
220 static char*
221 rdenv(char *name)
222 {
223         char *v;
224         int fd, size;
225
226         fd = open(name, OREAD);
227         if(fd < 0)
228                 return 0;
229         size = seek(fd, 0, 2);
230         v = malloc(size+1);
231         if(v == 0){
232                 fprint(2, "%s: can't malloc: %r\n", argv0);
233                 exits("no mem");
234         }
235         seek(fd, 0, 0);
236         read(fd, v, size);
237         v[size] = 0;
238         close(fd);
239         return v;
240 }
241
242 int
243 newwin(char *win)
244 {
245         char *srv, *mntsrv;
246         char spec[100];
247         int srvfd, cons, pid;
248
249         switch(rfork(RFFDG|RFPROC|RFNAMEG|RFENVG|RFNOTEG|RFNOWAIT)){
250         case -1:
251                 fprint(2, "statusbar: can't fork: %r\n");
252                 return -1;
253         case 0:
254                 break;
255         default:
256                 exits(0);
257         }
258
259         srv = rdenv("/env/wsys");
260         if(srv == 0){
261                 mntsrv = rdenv("/mnt/term/env/wsys");
262                 if(mntsrv == 0){
263                         fprint(2, "statusbar: can't find $wsys\n");
264                         return -1;
265                 }
266                 srv = malloc(strlen(mntsrv)+10);
267                 sprint(srv, "/mnt/term%s", mntsrv);
268                 free(mntsrv);
269                 pid  = 0;                       /* can't send notes to remote processes! */
270         }else
271                 pid = getpid();
272         USED(pid);
273         srvfd = open(srv, ORDWR);
274         free(srv);
275         if(srvfd == -1){
276                 fprint(2, "statusbar: can't open %s: %r\n", srv);
277                 return -1;
278         }
279         sprint(spec, "new -r %s", win);
280         if(mount(srvfd, -1, "/mnt/wsys", 0, spec) == -1){
281                 fprint(2, "statusbar: can't mount /mnt/wsys: %r (spec=%s)\n", spec);
282                 return -1;
283         }
284         close(srvfd);
285         unmount("/mnt/acme", "/dev");
286         bind("/mnt/wsys", "/dev", MBEFORE);
287         cons = open("/dev/cons", OREAD);
288         if(cons==-1){
289         NoCons:
290                 fprint(2, "statusbar: can't open /dev/cons: %r");
291                 return -1;
292         }
293         dup(cons, 0);
294         close(cons);
295         cons = open("/dev/cons", OWRITE);
296         if(cons==-1)
297                 goto NoCons;
298         dup(cons, 1);
299         dup(cons, 2);
300         close(cons);
301 //      wctlfd = open("/dev/wctl", OWRITE);
302         return 0;
303 }
304
305 Rectangle
306 screenrect(void)
307 {
308         int fd;
309         char buf[12*5];
310
311         fd = open("/dev/screen", OREAD);
312         if(fd == -1)
313                 fd=open("/mnt/term/dev/screen", OREAD);
314         if(fd == -1){
315                 fprint(2, "%s: can't open /dev/screen: %r\n", argv0);
316                 exits("window read");
317         }
318         if(read(fd, buf, sizeof buf) != sizeof buf){
319                 fprint(2, "%s: can't read /dev/screen: %r\n", argv0);
320                 exits("screen read");
321         }
322         close(fd);
323         return Rect(atoi(buf+12), atoi(buf+24), atoi(buf+36), atoi(buf+48));
324 }
325
326 int
327 postnote(int group, int pid, char *note)
328 {
329         char file[128];
330         int f, r;
331
332         switch(group) {
333         case PNPROC:
334                 sprint(file, "/proc/%d/note", pid);
335                 break;
336         case PNGROUP:
337                 sprint(file, "/proc/%d/notepg", pid);
338                 break;
339         case PNCTL:
340                 sprint(file, "/proc/%d/ctl", pid);
341                 break;
342         default:
343                 return -1;
344         }
345
346         f = open(file, OWRITE);
347         if(f < 0)
348                 return -1;
349
350         r = strlen(note);
351         if(write(f, note, r) != r) {
352                 close(f);
353                 return -1;
354         }
355         close(f);
356         return 0;
357 }