xref: /csrg-svn/usr.bin/tn3270/ascii/termin.c (revision 30330)
1*30330Sminshall /*
2*30330Sminshall  *	Copyright (c) 1984, 1985, 1986 by the Regents of the
3*30330Sminshall  *	University of California and by Gregory Glenn Minshall.
4*30330Sminshall  *
5*30330Sminshall  *	Permission to use, copy, modify, and distribute these
6*30330Sminshall  *	programs and their documentation for any purpose and
7*30330Sminshall  *	without fee is hereby granted, provided that this
8*30330Sminshall  *	copyright and permission appear on all copies and
9*30330Sminshall  *	supporting documentation, the name of the Regents of
10*30330Sminshall  *	the University of California not be used in advertising
11*30330Sminshall  *	or publicity pertaining to distribution of the programs
12*30330Sminshall  *	without specific prior permission, and notice be given in
13*30330Sminshall  *	supporting documentation that copying and distribution is
14*30330Sminshall  *	by permission of the Regents of the University of California
15*30330Sminshall  *	and by Gregory Glenn Minshall.  Neither the Regents of the
16*30330Sminshall  *	University of California nor Gregory Glenn Minshall make
17*30330Sminshall  *	representations about the suitability of this software
18*30330Sminshall  *	for any purpose.  It is provided "as is" without
19*30330Sminshall  *	express or implied warranty.
20*30330Sminshall  */
21*30330Sminshall 
22*30330Sminshall #ifndef	lint
23*30330Sminshall static	char	sccsid[] = "@(#)termin.c	3.1  10/29/86";
24*30330Sminshall #endif	/* ndef lint */
25*30330Sminshall 
26*30330Sminshall /* this takes characters from the keyboard, and produces 3270 keystroke
27*30330Sminshall 	codes
28*30330Sminshall  */
29*30330Sminshall 
30*30330Sminshall #include <ctype.h>
31*30330Sminshall 
32*30330Sminshall #include "m4.out"		/* output of termcodes.m4 */
33*30330Sminshall #include "state.h"
34*30330Sminshall 
35*30330Sminshall #include "globals.h"
36*30330Sminshall #include "inbound.ext"
37*30330Sminshall #include "outbound.ext"
38*30330Sminshall #include "telnet.ext"
39*30330Sminshall #include "termin.ext"
40*30330Sminshall 
41*30330Sminshall #define IsControl(c)	(!isprint(c) || (isspace(c) && ((c) != ' ')))
42*30330Sminshall 
43*30330Sminshall #define NextState(x)	(x->next)
44*30330Sminshall 
45*30330Sminshall /* XXX temporary - hard code in the state table */
46*30330Sminshall 
47*30330Sminshall #define MATCH_ANY 0xff			/* actually, match any character */
48*30330Sminshall 
49*30330Sminshall 
50*30330Sminshall static char
51*30330Sminshall 	ourBuffer[100],		/* where we store stuff */
52*30330Sminshall 	*ourPHead = ourBuffer,	/* first character in buffer */
53*30330Sminshall 	*ourPTail = ourBuffer;	/* where next character goes */
54*30330Sminshall 
55*30330Sminshall static state
56*30330Sminshall 	*headOfControl = 0;	/* where we enter code state table */
57*30330Sminshall 
58*30330Sminshall #define FullChar	(ourPTail == ourBuffer+sizeof ourBuffer)
59*30330Sminshall #define EmptyChar	(ourPTail == ourPHead)
60*30330Sminshall 
61*30330Sminshall 
62*30330Sminshall /* AddChar - put a character in our buffer */
63*30330Sminshall 
64*30330Sminshall static void
65*30330Sminshall AddChar(c)
66*30330Sminshall int	c;
67*30330Sminshall {
68*30330Sminshall     if (!FullChar) {
69*30330Sminshall 	*ourPTail++ = (char) c;
70*30330Sminshall     } else {
71*30330Sminshall 	RingBell();
72*30330Sminshall     }
73*30330Sminshall }
74*30330Sminshall 
75*30330Sminshall /* FlushChar - put everything where it belongs */
76*30330Sminshall 
77*30330Sminshall static void
78*30330Sminshall FlushChar()
79*30330Sminshall {
80*30330Sminshall     ourPTail = ourBuffer;
81*30330Sminshall     ourPHead = ourBuffer;
82*30330Sminshall }
83*30330Sminshall 
84*30330Sminshall 
85*30330Sminshall int
86*30330Sminshall TerminalIn()
87*30330Sminshall {
88*30330Sminshall     /* send data from us to next link in stream */
89*30330Sminshall     int count;
90*30330Sminshall 
91*30330Sminshall     count = 0;
92*30330Sminshall 
93*30330Sminshall     if (!EmptyChar) {			/* send up the link */
94*30330Sminshall 	count += DataFrom3270(ourPHead, ourPTail-ourPHead);
95*30330Sminshall 	ourPHead += count;
96*30330Sminshall 	if (EmptyChar) {
97*30330Sminshall 	    FlushChar();
98*30330Sminshall 	}
99*30330Sminshall     }
100*30330Sminshall 	/* return value answers question: "did we do anything useful?" */
101*30330Sminshall     return(count? 1:0);
102*30330Sminshall }
103*30330Sminshall 
104*30330Sminshall int
105*30330Sminshall DataFromTerminal(buffer, count)
106*30330Sminshall register char	*buffer;		/* the data read in */
107*30330Sminshall register int	count;			/* how many bytes in this buffer */
108*30330Sminshall {
109*30330Sminshall     register state *regControlPointer;
110*30330Sminshall     register char c;
111*30330Sminshall     register int result;
112*30330Sminshall     int origCount;
113*30330Sminshall 
114*30330Sminshall     static int InControl = 0;
115*30330Sminshall     static int WaitingForSynch = 0;
116*30330Sminshall     static state *controlPointer;
117*30330Sminshall     extern state *InitControl();
118*30330Sminshall 
119*30330Sminshall     if (!headOfControl) {
120*30330Sminshall 	/* need to initialize */
121*30330Sminshall 	headOfControl = InitControl((char *)0, 0);
122*30330Sminshall 	if (!headOfControl) {		/* should not occur */
123*30330Sminshall 	    quit();
124*30330Sminshall 	}
125*30330Sminshall     }
126*30330Sminshall 
127*30330Sminshall 
128*30330Sminshall     origCount = count;
129*30330Sminshall 
130*30330Sminshall     while (count) {
131*30330Sminshall 	c = *buffer++&0x7f;
132*30330Sminshall 	count--;
133*30330Sminshall 
134*30330Sminshall 	if (!InControl && !IsControl(c)) {
135*30330Sminshall 	    AddChar(c);			/* add ascii character */
136*30330Sminshall 	} else {
137*30330Sminshall 	    if (!InControl) {		/* first character of sequence */
138*30330Sminshall 		InControl = 1;
139*30330Sminshall 		controlPointer = headOfControl;
140*30330Sminshall 	    }
141*30330Sminshall 	    /* control pointer points to current position in state table */
142*30330Sminshall 	    for (regControlPointer = controlPointer; ;
143*30330Sminshall 			regControlPointer = NextState(regControlPointer)) {
144*30330Sminshall 		if (!regControlPointer) {	/* ran off end */
145*30330Sminshall 		    RingBell();
146*30330Sminshall 		    regControlPointer = headOfControl;
147*30330Sminshall 		    InControl = 0;
148*30330Sminshall 		    break;
149*30330Sminshall 		}
150*30330Sminshall 		if ((regControlPointer->match == c) /* hit this character */
151*30330Sminshall 			|| (regControlPointer->match == MATCH_ANY)) {
152*30330Sminshall 		    result = regControlPointer->result;
153*30330Sminshall 		    if (result == TC_GOTO) {
154*30330Sminshall 			regControlPointer = regControlPointer->address;
155*30330Sminshall 			break;			/* go to next character */
156*30330Sminshall 		    }
157*30330Sminshall 		    if (WaitingForSynch) {
158*30330Sminshall 			if (result == TC_SYNCH) {
159*30330Sminshall 			    WaitingForSynch = 0;
160*30330Sminshall 			} else {
161*30330Sminshall 			    RingBell();
162*30330Sminshall 			}
163*30330Sminshall 		    }
164*30330Sminshall 		    else if (result == TC_FLINP) {
165*30330Sminshall 			FlushChar();		/* Don't add FLINP */
166*30330Sminshall 		    } else {
167*30330Sminshall 			if (result == TC_MASTER_RESET) {
168*30330Sminshall 			    FlushChar();
169*30330Sminshall 			}
170*30330Sminshall 			AddChar(result);		/* add this code */
171*30330Sminshall 		    }
172*30330Sminshall 		    InControl = 0;	/* out of control now */
173*30330Sminshall 		    break;
174*30330Sminshall 		}
175*30330Sminshall 	    }
176*30330Sminshall 	    controlPointer = regControlPointer;		/* save state */
177*30330Sminshall 	}
178*30330Sminshall     }
179*30330Sminshall     (void) TerminalIn();			/* try to send data */
180*30330Sminshall     return(origCount-count);
181*30330Sminshall }
182