diff options
Diffstat (limited to 'src/cmd/samterm/io.c')
-rw-r--r-- | src/cmd/samterm/io.c | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/src/cmd/samterm/io.c b/src/cmd/samterm/io.c new file mode 100644 index 00000000..dfdfd9ce --- /dev/null +++ b/src/cmd/samterm/io.c @@ -0,0 +1,293 @@ +#include <u.h> +#include <libc.h> +#include <draw.h> +#include <thread.h> +#include <mouse.h> +#include <cursor.h> +#include <keyboard.h> +#include <frame.h> +#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->m; + keyboardctl = initkeyboard(nil); + if(keyboardctl == nil){ + fprint(2, "samterm: keyboard init failed: %r\n"); + threadexitsall("kbd"); + } + hoststart(); + if(plumbstart() < 0) + extstart(); +} + +void +getmouse(void) +{ + if(readmouse(mousectl) < 0) + panic("mouse"); +} + +void +mouseunblock(void) +{ + got &= ~(1<<RMouse); +} + +void +kbdblock(void) +{ /* ca suffit */ + block = (1<<RKeyboard)|(1<<RPlumb); +} + +int +button(int but) +{ + getmouse(); + return mousep->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<<RPlumb; +} +*/ + +int +waitforio(void) +{ + Alt alts[NRes+1]; + Rune r; + int i; + ulong type; + +again: + + alts[RPlumb].c = plumbc; + alts[RPlumb].v = &i; + alts[RPlumb].op = CHANRCV; + if((block & (1<<RPlumb)) || plumbc == nil) + alts[RPlumb].op = CHANNOP; + + alts[RHost].c = hostc; + alts[RHost].v = &i; + alts[RHost].op = CHANRCV; + if(block & (1<<RHost)) + alts[RHost].op = CHANNOP; + + alts[RKeyboard].c = keyboardctl->c; + alts[RKeyboard].v = &r; + alts[RKeyboard].op = CHANRCV; + if(block & (1<<RKeyboard)) + alts[RKeyboard].op = CHANNOP; + + alts[RMouse].c = mousectl->c; + alts[RMouse].v = &mousectl->m; + alts[RMouse].op = CHANRCV; + if(block & (1<<RMouse)) + alts[RMouse].op = CHANNOP; + + alts[RResize].c = mousectl->resizec; + alts[RResize].v = nil; + alts[RResize].op = CHANRCV; + if(block & (1<<RResize)) + alts[RResize].op = CHANNOP; + + alts[NRes].op = CHANEND; + + if(got & ~block) + return got & ~block; + 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<<type; + return got; +} + +int +rcvchar(void) +{ + int c; + + if(!(got & (1<<RHost))) + return -1; + c = *hostp++; + if(hostp == hoststop) + got &= ~(1<<RHost); + return c; +} + +char* +rcvstring(void) +{ + *hoststop = 0; + got &= ~(1<<RHost); + return (char*)hostp; +} + +int +getch(void) +{ + int c; + + while((c = rcvchar()) == -1){ + block = ~(1<<RHost); + waitforio(); + block = 0; + } + return c; +} + +int +externchar(void) +{ + Rune r; + + loop: + if(got & ((1<<RPlumb) & ~block)){ + plumbp += chartorune(&r, (char*)plumbp); + if(plumbp >= plumbstop){ + got &= ~(1<<RPlumb); + free(plumbbase); + } + if(r == 0) + goto loop; + return r; + } + return -1; +} + +int kpeekc = -1; +int +ecankbd(void) +{ + Rune r; + + if(kpeekc >= 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<<RKeyboard)){ + c = kbdc; + kbdc = -1; + got &= ~(1<<RKeyboard); + return c; + } +#if 0 + while(plumbc!=nil && nbrecv(plumbc, &i)>0){ + externload(i); + c = externchar(); + if(c > 0) + return c; + } +#endif + 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; +} |