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