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