]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/aux/statusbar.c
exec(2): fix prototypes
[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 #include <keyboard.h>
7
8 int newwin(char*);
9
10 int nokill;
11 int textmode;
12 char *title;
13
14 Image *light;
15 Image *dark;
16 Image *text;
17
18 void
19 initcolor(void)
20 {
21         text = display->black;
22         light = allocimagemix(display, DPalegreen, DWhite);
23         dark = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DDarkgreen);
24 }
25
26 Rectangle rbar;
27 Point ptext;
28 vlong n, d;
29 int last;
30 int lastp = -1;
31
32 char backup[80];
33
34 void
35 drawbar(void)
36 {
37         int i, j;
38         int p;
39         char buf[400], bar[200];
40         static char lastbar[200];
41
42         if(n > d || n < 0 || d <= 0)
43                 return;
44
45         i = (Dx(rbar)*n)/d;
46         p = (n*100LL)/d;
47
48         if(textmode){
49                 if(Dx(rbar) > 150){
50                         rbar.min.x = 0;
51                         rbar.max.x = 150;
52                         return;
53                 }
54                 bar[0] = '|';
55                 for(j=0; j<i; j++)
56                         bar[j+1] = '#';
57                 for(; j<Dx(rbar); j++)
58                         bar[j+1] = '-';
59                 bar[j++] = '|';
60                 bar[j++] = ' ';
61                 sprint(bar+j, "%3d%% ", p);
62                 for(i=0; bar[i]==lastbar[i] && bar[i]; i++)
63                         ;
64                 memset(buf, '\b', strlen(lastbar)-i);
65                 strcpy(buf+strlen(lastbar)-i, bar+i);
66                 if(buf[0])
67                         write(1, buf, strlen(buf));
68                 strcpy(lastbar, bar);
69                 return;
70         }
71
72         if(lastp == p && last == i)
73                 return;
74
75         if(lastp != p){
76                 sprint(buf, "%3d%%", p);
77                 
78                 stringbg(screen, addpt(screen->r.min, Pt(Dx(rbar)-30, 4)), text, ZP, display->defaultfont, buf, light, ZP);
79                 lastp = p;
80         }
81
82         if(last != i){
83                 if(i > last)
84                         draw(screen, Rect(rbar.min.x+last, rbar.min.y, rbar.min.x+i, rbar.max.y),
85                                 dark, nil, ZP);
86                 else
87                         draw(screen, Rect(rbar.min.x+i, rbar.min.y, rbar.min.x+last, rbar.max.y),
88                                 light, nil, ZP);
89                 last = i;
90         }
91         flushimage(display, 1);
92 }
93
94 void
95 eresized(int new)
96 {
97         Point p, q;
98         Rectangle r;
99
100         if(new && getwindow(display, Refnone) < 0)
101                 fprint(2,"can't reattach to window");
102
103         r = screen->r;
104         draw(screen, r, light, nil, ZP);
105         p = string(screen, addpt(r.min, Pt(4,4)), text, ZP,
106                 display->defaultfont, title);
107
108         p.x = r.min.x+4;
109         p.y += display->defaultfont->height+4;
110
111         q = subpt(r.max, Pt(4,4));
112         rbar = Rpt(p, q);
113
114         ptext = Pt(r.max.x-4-stringwidth(display->defaultfont, "100%"), r.min.x+4);
115         border(screen, rbar, -2, dark, ZP);
116         last = 0;
117         lastp = -1;
118
119         drawbar();
120 }
121
122 void
123 bar(Biobuf *b)
124 {
125         char *p, *f[2];
126         Event e;
127         int k, die, parent, child;
128
129         parent = getpid();
130
131         die = 0;
132         if(textmode)
133                 child = -1;
134         else
135         switch(child = rfork(RFMEM|RFPROC)) {
136         case 0:
137                 sleep(1000);
138                 while(!die && (k = eread(Ekeyboard|Emouse, &e))) {
139                         if(nokill==0 && k == Ekeyboard && (e.kbdc == Kdel || e.kbdc == Ketx)) {
140                                 die = 1;
141                                 postnote(PNPROC, parent, "interrupt");
142                                 _exits("interrupt");
143                         }
144                 }
145                 _exits(0);
146         }
147
148         while(!die && (p = Brdline(b, '\n'))) {
149                 p[Blinelen(b)-1] = '\0';
150                 if(tokenize(p, f, 2) != 2)
151                         continue;
152                 n = strtoll(f[0], 0, 0);
153                 d = strtoll(f[1], 0, 0);
154                 drawbar();
155         }
156         if(textmode)
157                 write(1, "\n", 1);
158         else
159                 postnote(PNPROC, 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 int
219 newwin(char *win)
220 {
221         char spec[100];
222         int cons;
223
224         if(win != nil){
225                 snprint(spec, sizeof(spec), "-r %s", win);
226                 win = spec;
227         }
228         if(newwindow(win) < 0){
229                 fprint(2, "%s: newwindow: %r", argv0);
230                 return -1;
231         }
232         if((cons = open("/dev/cons", OREAD)) < 0){
233         NoCons:
234                 fprint(2, "%s: can't open /dev/cons: %r", argv0);
235                 return -1;
236         }
237         dup(cons, 0);
238         close(cons);
239         if((cons = open("/dev/cons", OWRITE)) < 0)
240                 goto NoCons;
241         dup(cons, 1);
242         dup(cons, 2);
243         close(cons);
244         return 0;
245 }