Blob


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