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 /*
78 void
79 externload(int i)
80 {
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 }
89 */
91 int
92 waitforio(void)
93 {
94 Alt alts[NRes+1];
95 Rune r;
96 int i;
97 ulong type;
99 again:
101 alts[RPlumb].c = plumbc;
102 alts[RPlumb].v = &i;
103 alts[RPlumb].op = CHANRCV;
104 if((block & (1<<RPlumb)) || plumbc == nil)
105 alts[RPlumb].op = CHANNOP;
107 alts[RHost].c = hostc;
108 alts[RHost].v = &i;
109 alts[RHost].op = CHANRCV;
110 if(block & (1<<RHost))
111 alts[RHost].op = CHANNOP;
113 alts[RKeyboard].c = keyboardctl->c;
114 alts[RKeyboard].v = &r;
115 alts[RKeyboard].op = CHANRCV;
116 if(block & (1<<RKeyboard))
117 alts[RKeyboard].op = CHANNOP;
119 alts[RMouse].c = mousectl->c;
120 alts[RMouse].v = &mousectl->m;
121 alts[RMouse].op = CHANRCV;
122 if(block & (1<<RMouse))
123 alts[RMouse].op = CHANNOP;
125 alts[RResize].c = mousectl->resizec;
126 alts[RResize].v = nil;
127 alts[RResize].op = CHANRCV;
128 if(block & (1<<RResize))
129 alts[RResize].op = CHANNOP;
131 alts[NRes].op = CHANEND;
133 if(got & ~block)
134 return got & ~block;
135 flushimage(display, 1);
136 type = alt(alts);
137 switch(type){
138 case RHost:
139 hostp = hostbuf[i].data;
140 hoststop = hostbuf[i].data + hostbuf[i].n;
141 block = 0;
142 break;
143 /*
144 case RPlumb:
145 externload(i);
146 break;
147 */
148 case RKeyboard:
149 kbdc = r;
150 break;
151 case RMouse:
152 break;
153 case RResize:
154 resized = 1;
155 /* do the resize in line if we've finished initializing and we're not in a blocking state */
156 if(hasunlocked && block==0 && RESIZED())
157 resize();
158 goto again;
160 got |= 1<<type;
161 return got;
164 int
165 rcvchar(void)
167 int c;
169 if(!(got & (1<<RHost)))
170 return -1;
171 c = *hostp++;
172 if(hostp == hoststop)
173 got &= ~(1<<RHost);
174 return c;
177 char*
178 rcvstring(void)
180 *hoststop = 0;
181 got &= ~(1<<RHost);
182 return (char*)hostp;
185 int
186 getch(void)
188 int c;
190 while((c = rcvchar()) == -1){
191 block = ~(1<<RHost);
192 waitforio();
193 block = 0;
195 return c;
198 int
199 externchar(void)
201 Rune r;
203 loop:
204 if(got & ((1<<RPlumb) & ~block)){
205 plumbp += chartorune(&r, (char*)plumbp);
206 if(plumbp >= plumbstop){
207 got &= ~(1<<RPlumb);
208 free(plumbbase);
210 if(r == 0)
211 goto loop;
212 return r;
214 return -1;
217 int kpeekc = -1;
218 int
219 ecankbd(void)
221 Rune r;
223 if(kpeekc >= 0)
224 return 1;
225 if(nbrecv(keyboardctl->c, &r) > 0){
226 kpeekc = r;
227 return 1;
229 return 0;
232 int
233 ekbd(void)
235 int c;
236 Rune r;
238 if(kpeekc >= 0){
239 c = kpeekc;
240 kpeekc = -1;
241 return c;
243 if(recv(keyboardctl->c, &r) < 0){
244 fprint(2, "samterm: keybard recv error: %r\n");
245 panic("kbd");
247 return r;
250 int
251 kbdchar(void)
253 int c, i;
255 c = externchar();
256 if(c > 0)
257 return c;
258 if(got & (1<<RKeyboard)){
259 c = kbdc;
260 kbdc = -1;
261 got &= ~(1<<RKeyboard);
262 return c;
264 #if 0
265 while(plumbc!=nil && nbrecv(plumbc, &i)>0){
266 externload(i);
267 c = externchar();
268 if(c > 0)
269 return c;
271 #endif
272 if(!ecankbd())
273 return -1;
274 return ekbd();
277 int
278 qpeekc(void)
280 return kbdc;
283 int
284 RESIZED(void)
286 if(resized){
287 if(getwindow(display, Refnone) < 0)
288 panic("can't reattach to window");
289 resized = 0;
290 return 1;
292 return 0;