xref: /inferno-os/appl/cmd/wish.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1implement Test;
2
3include "sys.m";
4include "draw.m";
5draw: Draw;
6Screen, Display, Image: import draw;
7include "tk.m";
8
9Test: module
10{
11	init:	fn(ctxt: ref Draw->Context, argv: list of string);
12};
13
14tk: Tk;
15sys: Sys;
16
17init(nil: ref Draw->Context, argv: list of string)
18{
19	cmd: string;
20
21	sys = load Sys Sys->PATH;
22	draw = load Draw Draw->PATH;
23	tk = load Tk Tk->PATH;
24
25	display := Display.allocate(nil);
26	if(display == nil) {
27		sys->print("can't initialize display: %r\n");
28		return;
29	}
30
31	disp := display.image;
32	screen := Screen.allocate(disp, display.rgb(161, 195, 209), 1);
33	if(screen == nil) {
34		sys->print("can't allocate screen: %r\n");
35		return;
36	}
37	fd := sys->open("/dev/pointer", sys->OREAD);
38	if(fd == nil) {
39		sys->print("open: %s: %r\n", "/dev/pointer");
40		sys->print("run wm/wish instead\n");
41		return;
42	}
43
44	t := tk->toplevel(display, "");
45	spawn mouse(t, fd);
46	spawn keyboard(t);
47	disp.draw(disp.r, screen.fill, nil, disp.r.min);
48
49	input := array[8192] of byte;
50	stdin := sys->fildes(0);
51
52	if(argv != nil)
53		argv = tl argv;
54	while(argv != nil) {
55		exec(t, hd argv);
56		argv = tl argv;
57	}
58
59	for(;;) {
60		tk->cmd(t, "update");
61
62		prompt := '%';
63		if(cmd != nil)
64			prompt = '>';
65		sys->print("%c ", prompt);
66
67		n := sys->read(stdin, input, len input);
68		if(n <= 0)
69			break;
70		if(n == 1)
71			continue;
72		cmd += string input[0:n-1];
73		if(cmd[len cmd-1] != '\\') {
74			cmd = esc(cmd);
75			s := tk->cmd(t, cmd);
76			if(len s != 0)
77				sys->print("%s\n", s);
78			cmd = nil;
79			continue;
80		}
81		cmd = cmd[0:len cmd-1];
82	}
83}
84
85esc(s: string): string
86{
87	c: int;
88
89	for(i := 0; i < len s; i++) {
90		if(s[i] != '\\')
91			continue;
92		case s[i+1] {
93		'n'=>	c = '\n';
94		't'=>	c = '\t';
95		'b'=>	c = '\b';
96		'\\'=>	c = '\\';
97		* =>	c = 0;
98		}
99		if(c != 0) {
100			s[i] = c;
101			s = s[0:i+1]+s[i+2:len s];
102		}
103	}
104	return s;
105}
106
107exec(t: ref Tk->Toplevel, path: string)
108{
109	fd := sys->open(path, sys->OREAD);
110	if(fd == nil) {
111		sys->print("open: %s: %r\n", path);
112		return;
113	}
114	(ok, d) := sys->fstat(fd);
115	if(ok < 0) {
116		sys->print("fstat: %s: %r\n", path);
117		return;
118	}
119	buf := array[int d.length] of byte;
120	if(sys->read(fd, buf, len buf) < 0) {
121		sys->print("read: %s: %r\n", path);
122		return;
123	}
124	(n, l) := sys->tokenize(string buf, "\n");
125	buf = nil;
126	n = -1;
127	for(; l != nil; l = tl l) {
128		n++;
129		s := hd l;
130		if(len s == 0 || s[0] == '#')
131			continue;
132
133		while(s[len s-1] == '\\') {
134			s = s[0:len s-1];
135			if(tl l != nil) {
136				l = tl l;
137				s = s + hd l;
138			}
139			else
140				break;
141		}
142
143		s = tk->cmd(t, esc(s));
144
145		if(len s != 0 && s[0] == '!') {
146			sys->print("%s:%d %s\n", path, n, s);
147			sys->print("%s:%d %s\n", path, n, hd l);
148		}
149	}
150}
151
152mouse(t: ref Tk->Toplevel, fd: ref Sys->FD)
153{
154	n := 0;
155	buf := array[100] of byte;
156	for(;;) {
157		n = sys->read(fd, buf, len buf);
158		if(n <= 0)
159			break;
160
161		if(int buf[0] == 'm' && n >= 1+3*12) {
162			x := int(string buf[ 1:13]);
163			y := int(string buf[12:25]);
164			b := int(string buf[24:37]);
165			tk->pointer(t, Draw->Pointer(b, Draw->Point(x, y), sys->millisec()));
166		}
167	}
168}
169
170keyboard(t: ref Tk->Toplevel)
171{
172	dfd := sys->open("/dev/keyboard", sys->OREAD);
173	if(dfd == nil)
174		return;
175
176	b:= array[1] of byte;
177	buf := array[10] of byte;
178	i := 0;
179	for(;;) {
180		n := sys->read(dfd, buf[i:], len buf - i);
181		if(n < 1)
182			break;
183		i += n;
184		while(i >0 && (nutf := sys->utfbytes(buf, i)) > 0){
185			s := string buf[0:nutf];
186			tk->keyboard(t, int s[0]);
187			buf[0:] = buf[nutf:i];
188			i -= nutf;
189		}
190	}
191}
192