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 protodebug;13 int cursorfd;14 int plumbfd = -1;15 int input;16 int got;17 int block;18 int kbdc;19 int resized;20 uchar *hostp;21 uchar *hoststop;22 uchar *plumbbase;23 uchar *plumbp;24 uchar *plumbstop;25 Channel *plumbc;26 Channel *hostc;27 Mousectl *mousectl;28 Mouse *mousep;29 Keyboardctl *keyboardctl;30 void panic(char*);32 void33 initio(void)34 {35 threadsetname("main");36 if(protodebug) print("mouse\n");37 mousectl = initmouse(nil, display->image);38 if(mousectl == nil){39 fprint(2, "samterm: mouse init failed: %r\n");40 threadexitsall("mouse");41 }42 mousep = &mousectl->m;43 if(protodebug) print("kbd\n");44 keyboardctl = initkeyboard(nil);45 if(keyboardctl == nil){46 fprint(2, "samterm: keyboard init failed: %r\n");47 threadexitsall("kbd");48 }49 if(protodebug) print("hoststart\n");50 hoststart();51 if(protodebug) print("plumbstart\n");52 if(plumbstart() < 0){53 if(protodebug) print("extstart\n");54 extstart();55 }56 if(protodebug) print("initio done\n");57 }59 void60 getmouse(void)61 {62 if(readmouse(mousectl) < 0)63 panic("mouse");64 }66 void67 mouseunblock(void)68 {69 got &= ~(1<<RMouse);70 }72 void73 kbdblock(void)74 { /* ca suffit */75 block = (1<<RKeyboard)|(1<<RPlumb);76 }78 int79 button(int but)80 {81 getmouse();82 return mousep->buttons&(1<<(but-1));83 }85 void86 externload(int i)87 {88 drawtopwindow();89 plumbbase = malloc(plumbbuf[i].n);90 if(plumbbase == 0)91 return;92 memmove(plumbbase, plumbbuf[i].data, plumbbuf[i].n);93 plumbp = plumbbase;94 plumbstop = plumbbase + plumbbuf[i].n;95 got |= 1<<RPlumb;96 }98 int99 waitforio(void)100 {101 Alt alts[NRes+1];102 Rune r;103 int i;104 ulong type;106 again:107 alts[RPlumb].c = plumbc;108 alts[RPlumb].v = &i;109 alts[RPlumb].op = CHANRCV;110 if((block & (1<<RPlumb)) || plumbc == nil)111 alts[RPlumb].op = CHANNOP;113 alts[RHost].c = hostc;114 alts[RHost].v = &i;115 alts[RHost].op = CHANRCV;116 if(block & (1<<RHost))117 alts[RHost].op = CHANNOP;119 alts[RKeyboard].c = keyboardctl->c;120 alts[RKeyboard].v = &r;121 alts[RKeyboard].op = CHANRCV;122 if(block & (1<<RKeyboard))123 alts[RKeyboard].op = CHANNOP;125 alts[RMouse].c = mousectl->c;126 alts[RMouse].v = &mousectl->m;127 alts[RMouse].op = CHANRCV;128 if(block & (1<<RMouse))129 alts[RMouse].op = CHANNOP;131 alts[RResize].c = mousectl->resizec;132 alts[RResize].v = nil;133 alts[RResize].op = CHANRCV;134 if(block & (1<<RResize))135 alts[RResize].op = CHANNOP;137 if(protodebug) print("waitforio %c%c%c%c%c\n",138 "h-"[alts[RHost].op == CHANNOP],139 "k-"[alts[RKeyboard].op == CHANNOP],140 "m-"[alts[RMouse].op == CHANNOP],141 "p-"[alts[RPlumb].op == CHANNOP],142 "R-"[alts[RResize].op == CHANNOP]);144 alts[NRes].op = CHANEND;146 if(got & ~block)147 return got & ~block;148 flushimage(display, 1);149 type = alt(alts);150 switch(type){151 case RHost:152 if(0) print("hostalt recv %d %d\n", i, hostbuf[i].n);153 hostp = hostbuf[i].data;154 hoststop = hostbuf[i].data + hostbuf[i].n;155 block = 0;156 break;157 case RPlumb:158 externload(i);159 break;160 case RKeyboard:161 kbdc = r;162 break;163 case RMouse:164 break;165 case RResize:166 resized = 1;167 /* do the resize in line if we've finished initializing and we're not in a blocking state */168 if(hasunlocked && block==0 && RESIZED())169 resize();170 goto again;171 }172 got |= 1<<type;173 return got;174 }176 int177 rcvchar(void)178 {179 int c;181 if(!(got & (1<<RHost)))182 return -1;183 c = *hostp++;184 if(hostp == hoststop)185 got &= ~(1<<RHost);186 return c;187 }189 char*190 rcvstring(void)191 {192 *hoststop = 0;193 got &= ~(1<<RHost);194 return (char*)hostp;195 }197 int198 getch(void)199 {200 int c;202 while((c = rcvchar()) == -1){203 block = ~(1<<RHost);204 waitforio();205 block = 0;206 }207 return c;208 }210 int211 externchar(void)212 {213 Rune r;215 loop:216 if(got & ((1<<RPlumb) & ~block)){217 plumbp += chartorune(&r, (char*)plumbp);218 if(plumbp >= plumbstop){219 got &= ~(1<<RPlumb);220 free(plumbbase);221 }222 if(r == 0)223 goto loop;224 return r;225 }226 return -1;227 }229 int kpeekc = -1;230 int231 ecankbd(void)232 {233 Rune r;235 if(kpeekc >= 0)236 return 1;237 if(nbrecv(keyboardctl->c, &r) > 0){238 kpeekc = r;239 return 1;240 }241 return 0;242 }244 int245 ekbd(void)246 {247 int c;248 Rune r;250 if(kpeekc >= 0){251 c = kpeekc;252 kpeekc = -1;253 return c;254 }255 if(recv(keyboardctl->c, &r) < 0){256 fprint(2, "samterm: keybard recv error: %r\n");257 panic("kbd");258 }259 return r;260 }262 int263 kbdchar(void)264 {265 int c, i;267 c = externchar();268 if(c > 0)269 return c;270 if(got & (1<<RKeyboard)){271 c = kbdc;272 kbdc = -1;273 got &= ~(1<<RKeyboard);274 return c;275 }276 while(plumbc!=nil && nbrecv(plumbc, &i)>0){277 externload(i);278 c = externchar();279 if(c > 0)280 return c;281 }282 if(!ecankbd())283 return -1;284 return ekbd();285 }287 int288 qpeekc(void)289 {290 return kbdc;291 }293 int294 RESIZED(void)295 {296 if(resized){297 if(getwindow(display, Refnone) < 0)298 panic("can't reattach to window");299 resized = 0;300 return 1;301 }302 return 0;303 }