aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/samterm/io.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/samterm/io.c')
-rw-r--r--src/cmd/samterm/io.c293
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;
+}