Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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, "%d%%", 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
}