13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier #include <thread.h>
57dd7cddfSDavid du Colombier #include <mouse.h>
67dd7cddfSDavid du Colombier #include <keyboard.h>
73e12c5d1SDavid du Colombier #include <frame.h>
83e12c5d1SDavid du Colombier #include "flayer.h"
93e12c5d1SDavid du Colombier #include "samterm.h"
103e12c5d1SDavid du Colombier
113e12c5d1SDavid du Colombier int cursorfd;
127dd7cddfSDavid du Colombier int plumbfd = -1;
133e12c5d1SDavid du Colombier int input;
143e12c5d1SDavid du Colombier int got;
153e12c5d1SDavid du Colombier int block;
163e12c5d1SDavid du Colombier int kbdc;
177dd7cddfSDavid du Colombier int resized;
183e12c5d1SDavid du Colombier uchar *hostp;
193e12c5d1SDavid du Colombier uchar *hoststop;
207dd7cddfSDavid du Colombier uchar *plumbbase;
217dd7cddfSDavid du Colombier uchar *plumbp;
227dd7cddfSDavid du Colombier uchar *plumbstop;
237dd7cddfSDavid du Colombier Channel *plumbc;
247dd7cddfSDavid du Colombier Channel *hostc;
257dd7cddfSDavid du Colombier Mousectl *mousectl;
267dd7cddfSDavid du Colombier Mouse *mousep;
277dd7cddfSDavid du Colombier Keyboardctl *keyboardctl;
283e12c5d1SDavid du Colombier void panic(char*);
293e12c5d1SDavid du Colombier
303e12c5d1SDavid du Colombier void
initio(void)31*e7d29567SDavid du Colombier initio(void)
32*e7d29567SDavid du Colombier {
337dd7cddfSDavid du Colombier threadsetname("main");
347dd7cddfSDavid du Colombier mousectl = initmouse(nil, display->image);
357dd7cddfSDavid du Colombier if(mousectl == nil){
367dd7cddfSDavid du Colombier fprint(2, "samterm: mouse init failed: %r\n");
377dd7cddfSDavid du Colombier threadexitsall("mouse");
387dd7cddfSDavid du Colombier }
397dd7cddfSDavid du Colombier mousep = mousectl;
407dd7cddfSDavid du Colombier keyboardctl = initkeyboard(nil);
417dd7cddfSDavid du Colombier if(keyboardctl == nil){
427dd7cddfSDavid du Colombier fprint(2, "samterm: keyboard init failed: %r\n");
437dd7cddfSDavid du Colombier threadexitsall("kbd");
447dd7cddfSDavid du Colombier }
457dd7cddfSDavid du Colombier hoststart();
467dd7cddfSDavid du Colombier if(plumbstart() < 0)
47bd389b36SDavid du Colombier extstart();
483e12c5d1SDavid du Colombier }
493e12c5d1SDavid du Colombier
503e12c5d1SDavid du Colombier void
getmouse(void)517dd7cddfSDavid du Colombier getmouse(void)
523e12c5d1SDavid du Colombier {
537dd7cddfSDavid du Colombier if(readmouse(mousectl) < 0)
547dd7cddfSDavid du Colombier panic("mouse");
553e12c5d1SDavid du Colombier }
563e12c5d1SDavid du Colombier
573e12c5d1SDavid du Colombier void
mouseunblock(void)583e12c5d1SDavid du Colombier mouseunblock(void)
593e12c5d1SDavid du Colombier {
607dd7cddfSDavid du Colombier got &= ~(1<<RMouse);
613e12c5d1SDavid du Colombier }
623e12c5d1SDavid du Colombier
633e12c5d1SDavid du Colombier void
kbdblock(void)643e12c5d1SDavid du Colombier kbdblock(void)
653e12c5d1SDavid du Colombier { /* ca suffit */
667dd7cddfSDavid du Colombier block = (1<<RKeyboard)|(1<<RPlumb);
673e12c5d1SDavid du Colombier }
683e12c5d1SDavid du Colombier
693e12c5d1SDavid du Colombier int
button(int but)703e12c5d1SDavid du Colombier button(int but)
713e12c5d1SDavid du Colombier {
727dd7cddfSDavid du Colombier getmouse();
737dd7cddfSDavid du Colombier return mousep->buttons&(1<<(but-1));
743e12c5d1SDavid du Colombier }
753e12c5d1SDavid du Colombier
76bd389b36SDavid du Colombier void
externload(int i)777dd7cddfSDavid du Colombier externload(int i)
78bd389b36SDavid du Colombier {
797dd7cddfSDavid du Colombier plumbbase = malloc(plumbbuf[i].n);
807dd7cddfSDavid du Colombier if(plumbbase == 0)
81bd389b36SDavid du Colombier return;
827dd7cddfSDavid du Colombier memmove(plumbbase, plumbbuf[i].data, plumbbuf[i].n);
837dd7cddfSDavid du Colombier plumbp = plumbbase;
847dd7cddfSDavid du Colombier plumbstop = plumbbase + plumbbuf[i].n;
857dd7cddfSDavid du Colombier got |= 1<<RPlumb;
86bd389b36SDavid du Colombier }
87bd389b36SDavid du Colombier
883e12c5d1SDavid du Colombier int
waitforio(void)893e12c5d1SDavid du Colombier waitforio(void)
903e12c5d1SDavid du Colombier {
917dd7cddfSDavid du Colombier Alt alts[NRes+1];
927dd7cddfSDavid du Colombier Rune r;
937dd7cddfSDavid du Colombier int i;
943e12c5d1SDavid du Colombier ulong type;
957dd7cddfSDavid du Colombier
967dd7cddfSDavid du Colombier again:
977dd7cddfSDavid du Colombier
987dd7cddfSDavid du Colombier alts[RPlumb].c = plumbc;
997dd7cddfSDavid du Colombier alts[RPlumb].v = &i;
1007dd7cddfSDavid du Colombier alts[RPlumb].op = CHANRCV;
1017dd7cddfSDavid du Colombier if((block & (1<<RPlumb)) || plumbc == nil)
1027dd7cddfSDavid du Colombier alts[RPlumb].op = CHANNOP;
1037dd7cddfSDavid du Colombier
1047dd7cddfSDavid du Colombier alts[RHost].c = hostc;
1057dd7cddfSDavid du Colombier alts[RHost].v = &i;
1067dd7cddfSDavid du Colombier alts[RHost].op = CHANRCV;
1077dd7cddfSDavid du Colombier if(block & (1<<RHost))
1087dd7cddfSDavid du Colombier alts[RHost].op = CHANNOP;
1097dd7cddfSDavid du Colombier
1107dd7cddfSDavid du Colombier alts[RKeyboard].c = keyboardctl->c;
1117dd7cddfSDavid du Colombier alts[RKeyboard].v = &r;
1127dd7cddfSDavid du Colombier alts[RKeyboard].op = CHANRCV;
1137dd7cddfSDavid du Colombier if(block & (1<<RKeyboard))
1147dd7cddfSDavid du Colombier alts[RKeyboard].op = CHANNOP;
1157dd7cddfSDavid du Colombier
1167dd7cddfSDavid du Colombier alts[RMouse].c = mousectl->c;
1177dd7cddfSDavid du Colombier alts[RMouse].v = &mousectl->Mouse;
1187dd7cddfSDavid du Colombier alts[RMouse].op = CHANRCV;
1197dd7cddfSDavid du Colombier if(block & (1<<RMouse))
1207dd7cddfSDavid du Colombier alts[RMouse].op = CHANNOP;
1217dd7cddfSDavid du Colombier
1227dd7cddfSDavid du Colombier alts[RResize].c = mousectl->resizec;
1237dd7cddfSDavid du Colombier alts[RResize].v = nil;
1247dd7cddfSDavid du Colombier alts[RResize].op = CHANRCV;
1257dd7cddfSDavid du Colombier if(block & (1<<RResize))
1267dd7cddfSDavid du Colombier alts[RResize].op = CHANNOP;
1277dd7cddfSDavid du Colombier
1287dd7cddfSDavid du Colombier alts[NRes].op = CHANEND;
1293e12c5d1SDavid du Colombier
1303e12c5d1SDavid du Colombier if(got & ~block)
1313e12c5d1SDavid du Colombier return got & ~block;
1327dd7cddfSDavid du Colombier flushimage(display, 1);
1337dd7cddfSDavid du Colombier type = alt(alts);
1343e12c5d1SDavid du Colombier switch(type){
1357dd7cddfSDavid du Colombier case RHost:
1367dd7cddfSDavid du Colombier hostp = hostbuf[i].data;
1377dd7cddfSDavid du Colombier hoststop = hostbuf[i].data + hostbuf[i].n;
1383e12c5d1SDavid du Colombier block = 0;
1393e12c5d1SDavid du Colombier break;
1407dd7cddfSDavid du Colombier case RPlumb:
1417dd7cddfSDavid du Colombier externload(i);
142bd389b36SDavid du Colombier break;
1437dd7cddfSDavid du Colombier case RKeyboard:
1447dd7cddfSDavid du Colombier kbdc = r;
1453e12c5d1SDavid du Colombier break;
1467dd7cddfSDavid du Colombier case RMouse:
1473e12c5d1SDavid du Colombier break;
1487dd7cddfSDavid du Colombier case RResize:
1497dd7cddfSDavid du Colombier resized = 1;
1507dd7cddfSDavid du Colombier /* do the resize in line if we've finished initializing and we're not in a blocking state */
1517dd7cddfSDavid du Colombier if(hasunlocked && block==0 && RESIZED())
1527dd7cddfSDavid du Colombier resize();
1537dd7cddfSDavid du Colombier goto again;
1543e12c5d1SDavid du Colombier }
1557dd7cddfSDavid du Colombier got |= 1<<type;
1563e12c5d1SDavid du Colombier return got;
1573e12c5d1SDavid du Colombier }
1583e12c5d1SDavid du Colombier
1593e12c5d1SDavid du Colombier int
rcvchar(void)1603e12c5d1SDavid du Colombier rcvchar(void)
1613e12c5d1SDavid du Colombier {
1623e12c5d1SDavid du Colombier int c;
1633e12c5d1SDavid du Colombier
1647dd7cddfSDavid du Colombier if(!(got & (1<<RHost)))
1653e12c5d1SDavid du Colombier return -1;
1663e12c5d1SDavid du Colombier c = *hostp++;
1673e12c5d1SDavid du Colombier if(hostp == hoststop)
1687dd7cddfSDavid du Colombier got &= ~(1<<RHost);
1693e12c5d1SDavid du Colombier return c;
1703e12c5d1SDavid du Colombier }
1713e12c5d1SDavid du Colombier
1723e12c5d1SDavid du Colombier char*
rcvstring(void)1733e12c5d1SDavid du Colombier rcvstring(void)
1743e12c5d1SDavid du Colombier {
1753e12c5d1SDavid du Colombier *hoststop = 0;
1767dd7cddfSDavid du Colombier got &= ~(1<<RHost);
1773e12c5d1SDavid du Colombier return (char*)hostp;
1783e12c5d1SDavid du Colombier }
1793e12c5d1SDavid du Colombier
1803e12c5d1SDavid du Colombier int
getch(void)1813e12c5d1SDavid du Colombier getch(void)
1823e12c5d1SDavid du Colombier {
1833e12c5d1SDavid du Colombier int c;
1843e12c5d1SDavid du Colombier
1853e12c5d1SDavid du Colombier while((c = rcvchar()) == -1){
1867dd7cddfSDavid du Colombier block = ~(1<<RHost);
1873e12c5d1SDavid du Colombier waitforio();
1883e12c5d1SDavid du Colombier block = 0;
1893e12c5d1SDavid du Colombier }
1903e12c5d1SDavid du Colombier return c;
1913e12c5d1SDavid du Colombier }
1923e12c5d1SDavid du Colombier
1933e12c5d1SDavid du Colombier int
externchar(void)194bd389b36SDavid du Colombier externchar(void)
195bd389b36SDavid du Colombier {
196bd389b36SDavid du Colombier Rune r;
197bd389b36SDavid du Colombier
198bd389b36SDavid du Colombier loop:
1997dd7cddfSDavid du Colombier if(got & ((1<<RPlumb) & ~block)){
2007dd7cddfSDavid du Colombier plumbp += chartorune(&r, (char*)plumbp);
2017dd7cddfSDavid du Colombier if(plumbp >= plumbstop){
2027dd7cddfSDavid du Colombier got &= ~(1<<RPlumb);
2037dd7cddfSDavid du Colombier free(plumbbase);
204bd389b36SDavid du Colombier }
205bd389b36SDavid du Colombier if(r == 0)
206bd389b36SDavid du Colombier goto loop;
207bd389b36SDavid du Colombier return r;
208bd389b36SDavid du Colombier }
209bd389b36SDavid du Colombier return -1;
210bd389b36SDavid du Colombier }
211bd389b36SDavid du Colombier
2127dd7cddfSDavid du Colombier int kpeekc = -1;
2137dd7cddfSDavid du Colombier int
ecankbd(void)2147dd7cddfSDavid du Colombier ecankbd(void)
2157dd7cddfSDavid du Colombier {
2167dd7cddfSDavid du Colombier Rune r;
2177dd7cddfSDavid du Colombier
2187dd7cddfSDavid du Colombier if(kpeekc >= 0)
2197dd7cddfSDavid du Colombier return 1;
2207dd7cddfSDavid du Colombier if(nbrecv(keyboardctl->c, &r) > 0){
2217dd7cddfSDavid du Colombier kpeekc = r;
2227dd7cddfSDavid du Colombier return 1;
2237dd7cddfSDavid du Colombier }
2247dd7cddfSDavid du Colombier return 0;
2257dd7cddfSDavid du Colombier }
2267dd7cddfSDavid du Colombier
2277dd7cddfSDavid du Colombier int
ekbd(void)2287dd7cddfSDavid du Colombier ekbd(void)
2297dd7cddfSDavid du Colombier {
2307dd7cddfSDavid du Colombier int c;
2317dd7cddfSDavid du Colombier Rune r;
2327dd7cddfSDavid du Colombier
2337dd7cddfSDavid du Colombier if(kpeekc >= 0){
2347dd7cddfSDavid du Colombier c = kpeekc;
2357dd7cddfSDavid du Colombier kpeekc = -1;
2367dd7cddfSDavid du Colombier return c;
2377dd7cddfSDavid du Colombier }
2387dd7cddfSDavid du Colombier if(recv(keyboardctl->c, &r) < 0){
2397dd7cddfSDavid du Colombier fprint(2, "samterm: keybard recv error: %r\n");
2407dd7cddfSDavid du Colombier panic("kbd");
2417dd7cddfSDavid du Colombier }
2427dd7cddfSDavid du Colombier return r;
2437dd7cddfSDavid du Colombier }
2447dd7cddfSDavid du Colombier
245bd389b36SDavid du Colombier int
kbdchar(void)2463e12c5d1SDavid du Colombier kbdchar(void)
2473e12c5d1SDavid du Colombier {
2487dd7cddfSDavid du Colombier int c, i;
2493e12c5d1SDavid du Colombier
250bd389b36SDavid du Colombier c = externchar();
251bd389b36SDavid du Colombier if(c > 0)
252bd389b36SDavid du Colombier return c;
2537dd7cddfSDavid du Colombier if(got & (1<<RKeyboard)){
2543e12c5d1SDavid du Colombier c = kbdc;
2553e12c5d1SDavid du Colombier kbdc = -1;
2567dd7cddfSDavid du Colombier got &= ~(1<<RKeyboard);
2573e12c5d1SDavid du Colombier return c;
2583e12c5d1SDavid du Colombier }
2597dd7cddfSDavid du Colombier while(plumbc!=nil && nbrecv(plumbc, &i)>0){
2607dd7cddfSDavid du Colombier externload(i);
261bd389b36SDavid du Colombier c = externchar();
262bd389b36SDavid du Colombier if(c > 0)
263bd389b36SDavid du Colombier return c;
264bd389b36SDavid du Colombier }
2653e12c5d1SDavid du Colombier if(!ecankbd())
2663e12c5d1SDavid du Colombier return -1;
2673e12c5d1SDavid du Colombier return ekbd();
2683e12c5d1SDavid du Colombier }
2693e12c5d1SDavid du Colombier
2703e12c5d1SDavid du Colombier int
qpeekc(void)2713e12c5d1SDavid du Colombier qpeekc(void)
2723e12c5d1SDavid du Colombier {
2733e12c5d1SDavid du Colombier return kbdc;
2743e12c5d1SDavid du Colombier }
2753e12c5d1SDavid du Colombier
2763e12c5d1SDavid du Colombier int
RESIZED(void)2777dd7cddfSDavid du Colombier RESIZED(void)
2783e12c5d1SDavid du Colombier {
2797dd7cddfSDavid du Colombier if(resized){
2807dd7cddfSDavid du Colombier if(getwindow(display, Refnone) < 0)
2817dd7cddfSDavid du Colombier panic("can't reattach to window");
2827dd7cddfSDavid du Colombier resized = 0;
2833e12c5d1SDavid du Colombier return 1;
2843e12c5d1SDavid du Colombier }
2853e12c5d1SDavid du Colombier return 0;
2863e12c5d1SDavid du Colombier }
287