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