xref: /csrg-svn/usr.bin/window/wwiomux.c (revision 16124)
113923Sedward #ifndef lint
2*16124Sedward static	char *sccsid = "@(#)wwiomux.c	3.8 84/03/03";
313923Sedward #endif
413923Sedward 
513923Sedward #include "ww.h"
615872Sedward #include <sys/time.h>
713923Sedward 
815872Sedward /*
9*16124Sedward  * Multiple window output handler.
10*16124Sedward  * The idea is to copy window outputs to the terminal, via the
11*16124Sedward  * display package.  We try to give the top most window highest
12*16124Sedward  * priority.  The only return condition is when there is keyboard
13*16124Sedward  * input, which is serviced asynchronously by wwrint().
14*16124Sedward  * When there's nothing to do, we sleep in a select().
15*16124Sedward  * This can be done better with interrupt driven io.  But that's
16*16124Sedward  * not supported on ptys, yet.
17*16124Sedward  * The history of this routine is interesting.
1815872Sedward  */
1915872Sedward wwiomux()
2013923Sedward {
2115872Sedward 	register struct ww *w;
2215872Sedward 	int imask;
23*16124Sedward 	register n;
2415872Sedward 	register char *p;
2515872Sedward 	char c;
2615872Sedward 	static struct timeval tv = { 0, 0 };
27*16124Sedward 	char noblock;
2813923Sedward 
2915872Sedward loop:
30*16124Sedward 	if (wwinterrupt())
31*16124Sedward 		return;
32*16124Sedward 
33*16124Sedward 	imask = 0;
34*16124Sedward 	noblock = 0;
3515872Sedward 	for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) {
3615872Sedward 		if (w->ww_pty < 0)
3715872Sedward 			continue;
38*16124Sedward 		imask |= 1 << w->ww_pty;
39*16124Sedward 		if (w->ww_obc > 0 && !w->ww_stopped)
40*16124Sedward 			noblock = 1;
4115872Sedward 	}
42*16124Sedward 
43*16124Sedward 	if (!noblock) {
44*16124Sedward 		if (wwcurwin != 0)
45*16124Sedward 			wwcurtowin(wwcurwin);
4615872Sedward 		wwupdate();
4715872Sedward 		wwflush();
48*16124Sedward 		if (setjmp(wwjmpbuf))
49*16124Sedward 			return;
50*16124Sedward 		wwsetjmp = 1;
51*16124Sedward 		if (wwinterrupt()) {
52*16124Sedward 			wwsetjmp = 0;
53*16124Sedward 			return;
54*16124Sedward 		}
5515872Sedward 	}
5615872Sedward 	wwnselect++;
5715872Sedward 	n = select(wwdtablesize, &imask, (int *)0, (int *)0,
58*16124Sedward 		noblock ? &tv : (struct timeval *)0);
59*16124Sedward 	wwsetjmp = 0;
60*16124Sedward 
6115872Sedward 	if (n < 0)
6215872Sedward 		wwnselecte++;
63*16124Sedward 	else if (n == 0)
64*16124Sedward 		wwnselectz++;
65*16124Sedward 	else {
6615872Sedward 		char first_time = 1;
6715872Sedward 		for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) {
6815872Sedward 			if (w->ww_pty < 0)
6915872Sedward 				continue;
7015872Sedward 			if (imask & 1 << w->ww_pty) {
7115872Sedward 				wwnwread++;
7215872Sedward 				p = w->ww_obp + w->ww_obc;
7315872Sedward 				if (p == w->ww_ob)
7415872Sedward 					w->ww_obp++;
7515872Sedward 				else
7615872Sedward 					p--;
7715872Sedward 				c = *p;
7815872Sedward 				n = read(w->ww_pty, p, w->ww_obe - p);
7915872Sedward 				if (n < 0) {
8015872Sedward 					wwnwreade++;
8115872Sedward 					(void) close(w->ww_pty);
8215872Sedward 					w->ww_pty = -1;
8315872Sedward 					continue;
8415872Sedward 				} else if (n == 0) {
8515872Sedward 					wwnwreadz++;
8615872Sedward 				} else if (*p == TIOCPKT_DATA) {
87*16124Sedward 					n--;
8815872Sedward 					wwnwreadd++;
89*16124Sedward 					wwnwreadc += n;
90*16124Sedward 					w->ww_obc += n;
9115872Sedward 				} else {
9215872Sedward 					wwnwreadp++;
9315872Sedward 					if (*p & TIOCPKT_STOP)
9415872Sedward 						w->ww_stopped = 1;
9515872Sedward 					if (*p & TIOCPKT_START)
9615872Sedward 						w->ww_stopped = 0;
9715872Sedward 					if (*p & TIOCPKT_FLUSHWRITE) {
98*16124Sedward 						w->ww_stopped = 0;
9915872Sedward 						w->ww_obp = w->ww_ob;
10015872Sedward 						w->ww_obc = 0;
10115872Sedward 					}
10215872Sedward 				}
10315872Sedward 				*p = c;
10415872Sedward 			}
10515872Sedward 			if (first_time && w->ww_obc != 0 && !w->ww_stopped) {
10615872Sedward 				first_time = 0;
107*16124Sedward 				n = wwwrite(w, w->ww_obp, w->ww_obc);
10815872Sedward 				if (w->ww_obc -= n)
10915872Sedward 					w->ww_obp += n;
11015872Sedward 				else
11115872Sedward 					w->ww_obp = w->ww_ob;
112*16124Sedward 				if (wwinterrupt())
113*16124Sedward 					return;
11415872Sedward 			}
11513923Sedward 		}
11615872Sedward 	}
117*16124Sedward 	goto loop;
11813923Sedward }
119