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