Subversion Repositories planix.SVN

Rev

Details | 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 <thread.h>
5
#include <mouse.h>
6
#include <keyboard.h>
7
#include <frame.h>
8
#include "flayer.h"
9
#include "samterm.h"
10
 
11
int	cursorfd;
12
int	plumbfd = -1;
13
int	input;
14
int	got;
15
int	block;
16
int	kbdc;
17
int	resized;
18
uchar	*hostp;
19
uchar	*hoststop;
20
uchar	*plumbbase;
21
uchar	*plumbp;
22
uchar	*plumbstop;
23
Channel	*plumbc;
24
Channel	*hostc;
25
Mousectl	*mousectl;
26
Mouse	*mousep;
27
Keyboardctl *keyboardctl;
28
void	panic(char*);
29
 
30
void
31
initio(void)
32
{
33
	threadsetname("main");
34
	mousectl = initmouse(nil, display->image);
35
	if(mousectl == nil){
36
		fprint(2, "samterm: mouse init failed: %r\n");
37
		threadexitsall("mouse");
38
	}
39
	mousep = mousectl;
40
	keyboardctl = initkeyboard(nil);
41
	if(keyboardctl == nil){
42
		fprint(2, "samterm: keyboard init failed: %r\n");
43
		threadexitsall("kbd");
44
	}
45
	hoststart();
46
	if(plumbstart() < 0)
47
		extstart();
48
}
49
 
50
void
51
getmouse(void)
52
{
53
	if(readmouse(mousectl) < 0)
54
		panic("mouse");
55
}
56
 
57
void
58
mouseunblock(void)
59
{
60
	got &= ~(1<<RMouse);
61
}
62
 
63
void
64
kbdblock(void)
65
{		/* ca suffit */
66
	block = (1<<RKeyboard)|(1<<RPlumb);
67
}
68
 
69
int
70
button(int but)
71
{
72
	getmouse();
73
	return mousep->buttons&(1<<(but-1));
74
}
75
 
76
void
77
externload(int i)
78
{
79
	plumbbase = malloc(plumbbuf[i].n);
80
	if(plumbbase == 0)
81
		return;
82
	memmove(plumbbase, plumbbuf[i].data, plumbbuf[i].n);
83
	plumbp = plumbbase;
84
	plumbstop = plumbbase + plumbbuf[i].n;
85
	got |= 1<<RPlumb;
86
}
87
 
88
int
89
waitforio(void)
90
{
91
	Alt alts[NRes+1];
92
	Rune r;
93
	int i;
94
	ulong type;
95
 
96
again:
97
 
98
	alts[RPlumb].c = plumbc;
99
	alts[RPlumb].v = &i;
100
	alts[RPlumb].op = CHANRCV;
101
	if((block & (1<<RPlumb)) || plumbc == nil)
102
		alts[RPlumb].op = CHANNOP;
103
 
104
	alts[RHost].c = hostc;
105
	alts[RHost].v = &i;
106
	alts[RHost].op = CHANRCV;
107
	if(block & (1<<RHost))
108
		alts[RHost].op = CHANNOP;
109
 
110
	alts[RKeyboard].c = keyboardctl->c;
111
	alts[RKeyboard].v = &r;
112
	alts[RKeyboard].op = CHANRCV;
113
	if(block & (1<<RKeyboard))
114
		alts[RKeyboard].op = CHANNOP;
115
 
116
	alts[RMouse].c = mousectl->c;
117
	alts[RMouse].v = &mousectl->Mouse;
118
	alts[RMouse].op = CHANRCV;
119
	if(block & (1<<RMouse))
120
		alts[RMouse].op = CHANNOP;
121
 
122
	alts[RResize].c = mousectl->resizec;
123
	alts[RResize].v = nil;
124
	alts[RResize].op = CHANRCV;
125
	if(block & (1<<RResize))
126
		alts[RResize].op = CHANNOP;
127
 
128
	alts[NRes].op = CHANEND;
129
 
130
	if(got & ~block)
131
		return got & ~block;
132
	flushimage(display, 1);
133
	type = alt(alts);
134
	switch(type){
135
	case RHost:
136
		hostp = hostbuf[i].data;
137
		hoststop = hostbuf[i].data + hostbuf[i].n;
138
		block = 0;
139
		break;
140
	case RPlumb:
141
		externload(i);
142
		break;
143
	case RKeyboard:
144
		kbdc = r;
145
		break;
146
	case RMouse:
147
		break;
148
	case RResize:
149
		resized = 1;
150
		/* do the resize in line if we've finished initializing and we're not in a blocking state */
151
		if(hasunlocked && block==0 && RESIZED())
152
			resize();
153
		goto again;
154
	}
155
	got |= 1<<type;
156
	return got; 
157
}
158
 
159
int
160
rcvchar(void)
161
{
162
	int c;
163
 
164
	if(!(got & (1<<RHost)))
165
		return -1;
166
	c = *hostp++;
167
	if(hostp == hoststop)
168
		got &= ~(1<<RHost);
169
	return c;
170
}
171
 
172
char*
173
rcvstring(void)
174
{
175
	*hoststop = 0;
176
	got &= ~(1<<RHost);
177
	return (char*)hostp;
178
}
179
 
180
int
181
getch(void)
182
{
183
	int c;
184
 
185
	while((c = rcvchar()) == -1){
186
		block = ~(1<<RHost);
187
		waitforio();
188
		block = 0;
189
	}
190
	return c;
191
}
192
 
193
int
194
externchar(void)
195
{
196
	Rune r;
197
 
198
    loop:
199
	if(got & ((1<<RPlumb) & ~block)){
200
		plumbp += chartorune(&r, (char*)plumbp);
201
		if(plumbp >= plumbstop){
202
			got &= ~(1<<RPlumb);
203
			free(plumbbase);
204
		}
205
		if(r == 0)
206
			goto loop;
207
		return r;
208
	}
209
	return -1;
210
}
211
 
212
int kpeekc = -1;
213
int
214
ecankbd(void)
215
{
216
	Rune r;
217
 
218
	if(kpeekc >= 0)
219
		return 1;
220
	if(nbrecv(keyboardctl->c, &r) > 0){
221
		kpeekc = r;
222
		return 1;
223
	}
224
	return 0;
225
}
226
 
227
int
228
ekbd(void)
229
{
230
	int c;
231
	Rune r;
232
 
233
	if(kpeekc >= 0){
234
		c = kpeekc;
235
		kpeekc = -1;
236
		return c;
237
	}
238
	if(recv(keyboardctl->c, &r) < 0){
239
		fprint(2, "samterm: keybard recv error: %r\n");
240
		panic("kbd");
241
	}
242
	return r;
243
}
244
 
245
int
246
kbdchar(void)
247
{
248
	int c, i;
249
 
250
	c = externchar();
251
	if(c > 0)
252
		return c;
253
	if(got & (1<<RKeyboard)){
254
		c = kbdc;
255
		kbdc = -1;
256
		got &= ~(1<<RKeyboard);
257
		return c;
258
	}
259
	while(plumbc!=nil && nbrecv(plumbc, &i)>0){
260
		externload(i);
261
		c = externchar();
262
		if(c > 0)
263
			return c;
264
	}
265
	if(!ecankbd())
266
		return -1;
267
	return ekbd();
268
}
269
 
270
int
271
qpeekc(void)
272
{
273
	return kbdc;
274
}
275
 
276
int
277
RESIZED(void)
278
{
279
	if(resized){
280
		if(getwindow(display, Refnone) < 0)
281
			panic("can't reattach to window");
282
		resized = 0;
283
		return 1;
284
	}
285
	return 0;
286
}