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 void32 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 void52 getmouse(void)53 {54 if(readmouse(mousectl) < 0)55 panic("mouse");56 }58 void59 mouseunblock(void)60 {61 got &= ~(1<<RMouse);62 }64 void65 kbdblock(void)66 { /* ca suffit */67 block = (1<<RKeyboard)|(1<<RPlumb);68 }70 int71 button(int but)72 {73 getmouse();74 return mousep->buttons&(1<<(but-1));75 }77 void78 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 int91 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;163 }164 got |= 1<<type;165 return got;166 }168 int169 rcvchar(void)170 {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;179 }181 char*182 rcvstring(void)183 {184 *hoststop = 0;185 got &= ~(1<<RHost);186 return (char*)hostp;187 }189 int190 getch(void)191 {192 int c;194 while((c = rcvchar()) == -1){195 block = ~(1<<RHost);196 waitforio();197 block = 0;198 }199 return c;200 }202 int203 externchar(void)204 {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);213 }214 if(r == 0)215 goto loop;216 return r;217 }218 return -1;219 }221 int kpeekc = -1;222 int223 ecankbd(void)224 {225 Rune r;227 if(kpeekc >= 0)228 return 1;229 if(nbrecv(keyboardctl->c, &r) > 0){230 kpeekc = r;231 return 1;232 }233 return 0;234 }236 int237 ekbd(void)238 {239 int c;240 Rune r;242 if(kpeekc >= 0){243 c = kpeekc;244 kpeekc = -1;245 return c;246 }247 if(recv(keyboardctl->c, &r) < 0){248 fprint(2, "samterm: keybard recv error: %r\n");249 panic("kbd");250 }251 return r;252 }254 int255 kbdchar(void)256 {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;267 }268 while(plumbc!=nil && nbrecv(plumbc, &i)>0){269 externload(i);270 c = externchar();271 if(c > 0)272 return c;273 }274 if(!ecankbd())275 return -1;276 return ekbd();277 }279 int280 qpeekc(void)281 {282 return kbdc;283 }285 int286 RESIZED(void)287 {288 if(resized){289 if(getwindow(display, Refnone) < 0)290 panic("can't reattach to window");291 resized = 0;292 return 1;293 }294 return 0;295 }