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: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;156 }157 got |= 1<<type;158 return got;159 }161 int162 rcvchar(void)163 {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;172 }174 char*175 rcvstring(void)176 {177 *hoststop = 0;178 got &= ~(1<<RHost);179 return (char*)hostp;180 }182 int183 getch(void)184 {185 int c;187 while((c = rcvchar()) == -1){188 block = ~(1<<RHost);189 waitforio();190 block = 0;191 }192 return c;193 }195 int196 externchar(void)197 {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);206 }207 if(r == 0)208 goto loop;209 return r;210 }211 return -1;212 }214 int kpeekc = -1;215 int216 ecankbd(void)217 {218 Rune r;220 if(kpeekc >= 0)221 return 1;222 if(nbrecv(keyboardctl->c, &r) > 0){223 kpeekc = r;224 return 1;225 }226 return 0;227 }229 int230 ekbd(void)231 {232 int c;233 Rune r;235 if(kpeekc >= 0){236 c = kpeekc;237 kpeekc = -1;238 return c;239 }240 if(recv(keyboardctl->c, &r) < 0){241 fprint(2, "samterm: keybard recv error: %r\n");242 panic("kbd");243 }244 return r;245 }247 int248 kbdchar(void)249 {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;260 }261 while(plumbc!=nil && nbrecv(plumbc, &i)>0){262 externload(i);263 c = externchar();264 if(c > 0)265 return c;266 }267 if(!ecankbd())268 return -1;269 return ekbd();270 }272 int273 qpeekc(void)274 {275 return kbdc;276 }278 int279 RESIZED(void)280 {281 if(resized){282 if(getwindow(display, Refnone) < 0)283 panic("can't reattach to window");284 resized = 0;285 return 1;286 }287 return 0;288 }