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:
100 alts[RPlumb].c = plumbc;
101 alts[RPlumb].v = &i;
102 alts[RPlumb].op = CHANRCV;
103 if((block & (1<<RPlumb)) || plumbc == nil)
104 alts[RPlumb].op = CHANNOP;
106 alts[RHost].c = hostc;
107 alts[RHost].v = &i;
108 alts[RHost].op = CHANRCV;
109 if(block & (1<<RHost))
110 alts[RHost].op = CHANNOP;
112 alts[RKeyboard].c = keyboardctl->c;
113 alts[RKeyboard].v = &r;
114 alts[RKeyboard].op = CHANRCV;
115 if(block & (1<<RKeyboard))
116 alts[RKeyboard].op = CHANNOP;
118 alts[RMouse].c = mousectl->c;
119 alts[RMouse].v = &mousectl->m;
120 alts[RMouse].op = CHANRCV;
121 if(block & (1<<RMouse))
122 alts[RMouse].op = CHANNOP;
124 alts[RResize].c = mousectl->resizec;
125 alts[RResize].v = nil;
126 alts[RResize].op = CHANRCV;
127 if(block & (1<<RResize))
128 alts[RResize].op = CHANNOP;
130 alts[NRes].op = CHANEND;
132 if(got & ~block)
133 return got & ~block;
134 flushimage(display, 1);
135 type = alt(alts);
136 switch(type){
137 case RHost:
138 hostp = hostbuf[i].data;
139 hoststop = hostbuf[i].data + hostbuf[i].n;
140 block = 0;
141 break;
142 case RPlumb:
143 externload(i);
144 break;
145 case RKeyboard:
146 kbdc = r;
147 break;
148 case RMouse:
149 break;
150 case RResize:
151 resized = 1;
152 /* do the resize in line if we've finished initializing and we're not in a blocking state */
153 if(hasunlocked && block==0 && RESIZED())
154 resize();
155 goto again;
157 got |= 1<<type;
158 return got;
161 int
162 rcvchar(void)
164 int c;
166 if(!(got & (1<<RHost)))
167 return -1;
168 c = *hostp++;
169 if(hostp == hoststop)
170 got &= ~(1<<RHost);
171 return c;
174 char*
175 rcvstring(void)
177 *hoststop = 0;
178 got &= ~(1<<RHost);
179 return (char*)hostp;
182 int
183 getch(void)
185 int c;
187 while((c = rcvchar()) == -1){
188 block = ~(1<<RHost);
189 waitforio();
190 block = 0;
192 return c;
195 int
196 externchar(void)
198 Rune r;
200 loop:
201 if(got & ((1<<RPlumb) & ~block)){
202 plumbp += chartorune(&r, (char*)plumbp);
203 if(plumbp >= plumbstop){
204 got &= ~(1<<RPlumb);
205 free(plumbbase);
207 if(r == 0)
208 goto loop;
209 return r;
211 return -1;
214 int kpeekc = -1;
215 int
216 ecankbd(void)
218 Rune r;
220 if(kpeekc >= 0)
221 return 1;
222 if(nbrecv(keyboardctl->c, &r) > 0){
223 kpeekc = r;
224 return 1;
226 return 0;
229 int
230 ekbd(void)
232 int c;
233 Rune r;
235 if(kpeekc >= 0){
236 c = kpeekc;
237 kpeekc = -1;
238 return c;
240 if(recv(keyboardctl->c, &r) < 0){
241 fprint(2, "samterm: keybard recv error: %r\n");
242 panic("kbd");
244 return r;
247 int
248 kbdchar(void)
250 int i, c;
252 c = externchar();
253 if(c > 0)
254 return c;
255 if(got & (1<<RKeyboard)){
256 c = kbdc;
257 kbdc = -1;
258 got &= ~(1<<RKeyboard);
259 return c;
261 while(plumbc!=nil && nbrecv(plumbc, &i)>0){
262 externload(i);
263 c = externchar();
264 if(c > 0)
265 return c;
267 if(!ecankbd())
268 return -1;
269 return ekbd();
272 int
273 qpeekc(void)
275 return kbdc;
278 int
279 RESIZED(void)
281 if(resized){
282 if(getwindow(display, Refnone) < 0)
283 panic("can't reattach to window");
284 resized = 0;
285 return 1;
287 return 0;