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 /*78 void79 externload(int i)80 {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 }89 */91 int92 waitforio(void)93 {94 Alt alts[NRes+1];95 Rune r;96 int i;97 ulong type;99 again:101 alts[RPlumb].c = plumbc;102 alts[RPlumb].v = &i;103 alts[RPlumb].op = CHANRCV;104 if((block & (1<<RPlumb)) || plumbc == nil)105 alts[RPlumb].op = CHANNOP;107 alts[RHost].c = hostc;108 alts[RHost].v = &i;109 alts[RHost].op = CHANRCV;110 if(block & (1<<RHost))111 alts[RHost].op = CHANNOP;113 alts[RKeyboard].c = keyboardctl->c;114 alts[RKeyboard].v = &r;115 alts[RKeyboard].op = CHANRCV;116 if(block & (1<<RKeyboard))117 alts[RKeyboard].op = CHANNOP;119 alts[RMouse].c = mousectl->c;120 alts[RMouse].v = &mousectl->m;121 alts[RMouse].op = CHANRCV;122 if(block & (1<<RMouse))123 alts[RMouse].op = CHANNOP;125 alts[RResize].c = mousectl->resizec;126 alts[RResize].v = nil;127 alts[RResize].op = CHANRCV;128 if(block & (1<<RResize))129 alts[RResize].op = CHANNOP;131 alts[NRes].op = CHANEND;133 if(got & ~block)134 return got & ~block;135 flushimage(display, 1);136 type = alt(alts);137 switch(type){138 case RHost:139 hostp = hostbuf[i].data;140 hoststop = hostbuf[i].data + hostbuf[i].n;141 block = 0;142 break;143 /*144 case RPlumb:145 externload(i);146 break;147 */148 case RKeyboard:149 kbdc = r;150 break;151 case RMouse:152 break;153 case RResize:154 resized = 1;155 /* do the resize in line if we've finished initializing and we're not in a blocking state */156 if(hasunlocked && block==0 && RESIZED())157 resize();158 goto again;159 }160 got |= 1<<type;161 return got;162 }164 int165 rcvchar(void)166 {167 int c;169 if(!(got & (1<<RHost)))170 return -1;171 c = *hostp++;172 if(hostp == hoststop)173 got &= ~(1<<RHost);174 return c;175 }177 char*178 rcvstring(void)179 {180 *hoststop = 0;181 got &= ~(1<<RHost);182 return (char*)hostp;183 }185 int186 getch(void)187 {188 int c;190 while((c = rcvchar()) == -1){191 block = ~(1<<RHost);192 waitforio();193 block = 0;194 }195 return c;196 }198 int199 externchar(void)200 {201 Rune r;203 loop:204 if(got & ((1<<RPlumb) & ~block)){205 plumbp += chartorune(&r, (char*)plumbp);206 if(plumbp >= plumbstop){207 got &= ~(1<<RPlumb);208 free(plumbbase);209 }210 if(r == 0)211 goto loop;212 return r;213 }214 return -1;215 }217 int kpeekc = -1;218 int219 ecankbd(void)220 {221 Rune r;223 if(kpeekc >= 0)224 return 1;225 if(nbrecv(keyboardctl->c, &r) > 0){226 kpeekc = r;227 return 1;228 }229 return 0;230 }232 int233 ekbd(void)234 {235 int c;236 Rune r;238 if(kpeekc >= 0){239 c = kpeekc;240 kpeekc = -1;241 return c;242 }243 if(recv(keyboardctl->c, &r) < 0){244 fprint(2, "samterm: keybard recv error: %r\n");245 panic("kbd");246 }247 return r;248 }250 int251 kbdchar(void)252 {253 int c, i;255 c = externchar();256 if(c > 0)257 return c;258 if(got & (1<<RKeyboard)){259 c = kbdc;260 kbdc = -1;261 got &= ~(1<<RKeyboard);262 return c;263 }264 #if 0265 while(plumbc!=nil && nbrecv(plumbc, &i)>0){266 externload(i);267 c = externchar();268 if(c > 0)269 return c;270 }271 #endif272 if(!ecankbd())273 return -1;274 return ekbd();275 }277 int278 qpeekc(void)279 {280 return kbdc;281 }283 int284 RESIZED(void)285 {286 if(resized){287 if(getwindow(display, Refnone) < 0)288 panic("can't reattach to window");289 resized = 0;290 return 1;291 }292 return 0;293 }