xref: /plan9/sys/src/cmd/samterm/io.c (revision e7d295677b9ada08eb7a196a06047fdf5d8dfea2)
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