#include #include #include #include #include #include #include #include "flayer.h" #include "samterm.h" int cursorfd; int plumbfd = -1; int input; int got; int block; int kbdc; int resized; uchar *hostp; uchar *hoststop; uchar *plumbbase; uchar *plumbp; uchar *plumbstop; Channel *plumbc; Channel *hostc; Mousectl *mousectl; Mouse *mousep; Keyboardctl *keyboardctl; void panic(char*); void initio(void) { threadsetname("main"); mousectl = initmouse(nil, display->image); if(mousectl == nil){ fprint(2, "samterm: mouse init failed: %r\n"); threadexitsall("mouse"); } mousep = mousectl; keyboardctl = initkeyboard(nil); if(keyboardctl == nil){ fprint(2, "samterm: keyboard init failed: %r\n"); threadexitsall("kbd"); } hoststart(); plumbstart(); } void getmouse(void) { if(readmouse(mousectl) < 0) panic("mouse"); } void mouseunblock(void) { got &= ~(1<buttons&(1<<(but-1)); } void externload(int i) { plumbbase = malloc(plumbbuf[i].n); if(plumbbase == 0) return; memmove(plumbbase, plumbbuf[i].data, plumbbuf[i].n); plumbp = plumbbase; plumbstop = plumbbase + plumbbuf[i].n; got |= 1<c; alts[RKeyboard].v = &r; alts[RKeyboard].op = CHANRCV; if(block & (1<c; alts[RMouse].v = &mousectl->Mouse; alts[RMouse].op = CHANRCV; if(block & (1<resizec; alts[RResize].v = nil; alts[RResize].op = CHANRCV; if(block & (1<bufp > display->buf) flushimage(display, 1); type = alt(alts); switch(type){ case RHost: hostp = hostbuf[i].data; hoststop = hostbuf[i].data + hostbuf[i].n; block = 0; break; case RPlumb: externload(i); break; case RKeyboard: kbdc = r; break; case RMouse: break; case RResize: resized = 1; /* do the resize in line if we've finished initializing and we're not in a blocking state */ if(hasunlocked && block==0 && RESIZED()) resize(); goto again; } got |= 1<user1; long p; if(nbrecv(mousectl->c, &mousectl->Mouse) < 0) panic("mouse"); if(n < 0){ if(sel > l->origin+f->p0){ l->p0 = l->origin+f->p0; l->p1 = sel; }else{ l->p0 = sel; l->p1 = l->origin+f->p0; } scrorigin(l, 1, -n+1); }else if(n == 0){ sleep(25); return; }else{ if(sel >= l->origin+f->p1){ l->p0 = l->origin+f->p1; l->p1 = sel; }else{ l->p0 = sel; l->p1 = l->origin+f->p1; } p = l->origin; if(l->origin+f->nchars != t->rasp.nrunes) p += frcharofpt(f, Pt(l->scroll.max.x, l->scroll.min.y + n * f->font->height)); scrorigin(l, 2, p); } /* * we must pull io from host while we are in frame(2) */ do{ block = ~(1 << RHost); waitforio(); rcv(); }while(t->lock); } int getch(void) { int c; while((c = rcvchar()) == -1){ block = ~(1<= plumbstop){ got &= ~(1<= 0) return 1; if(nbrecv(keyboardctl->c, &r) > 0){ kpeekc = r; return 1; } return 0; } int ekbd(void) { int c; Rune r; if(kpeekc >= 0){ c = kpeekc; kpeekc = -1; return c; } if(recv(keyboardctl->c, &r) < 0){ fprint(2, "samterm: keybard recv error: %r\n"); panic("kbd"); } return r; } int kbdchar(void) { int c, i; c = externchar(); if(c > 0) return c; if(got & (1<0){ externload(i); c = externchar(); if(c > 0) return c; } if(!ecankbd()) return -1; return ekbd(); } int qpeekc(void) { return kbdc; } int RESIZED(void) { if(resized){ if(getwindow(display, Refnone) < 0) panic("can't reattach to window"); resized = 0; return 1; } return 0; }