xref: /csrg-svn/usr.bin/tn3270/ascii/termin.c (revision 30331)
130330Sminshall /*
230330Sminshall  *	Copyright (c) 1984, 1985, 1986 by the Regents of the
330330Sminshall  *	University of California and by Gregory Glenn Minshall.
430330Sminshall  *
530330Sminshall  *	Permission to use, copy, modify, and distribute these
630330Sminshall  *	programs and their documentation for any purpose and
730330Sminshall  *	without fee is hereby granted, provided that this
830330Sminshall  *	copyright and permission appear on all copies and
930330Sminshall  *	supporting documentation, the name of the Regents of
1030330Sminshall  *	the University of California not be used in advertising
1130330Sminshall  *	or publicity pertaining to distribution of the programs
1230330Sminshall  *	without specific prior permission, and notice be given in
1330330Sminshall  *	supporting documentation that copying and distribution is
1430330Sminshall  *	by permission of the Regents of the University of California
1530330Sminshall  *	and by Gregory Glenn Minshall.  Neither the Regents of the
1630330Sminshall  *	University of California nor Gregory Glenn Minshall make
1730330Sminshall  *	representations about the suitability of this software
1830330Sminshall  *	for any purpose.  It is provided "as is" without
1930330Sminshall  *	express or implied warranty.
2030330Sminshall  */
2130330Sminshall 
2230330Sminshall #ifndef	lint
2330330Sminshall static	char	sccsid[] = "@(#)termin.c	3.1  10/29/86";
2430330Sminshall #endif	/* ndef lint */
2530330Sminshall 
2630330Sminshall /* this takes characters from the keyboard, and produces 3270 keystroke
2730330Sminshall 	codes
2830330Sminshall  */
2930330Sminshall 
30*30331Sminshall #include <stdio.h>
3130330Sminshall #include <ctype.h>
3230330Sminshall 
33*30331Sminshall #include "../general.h"
3430330Sminshall #include "m4.out"		/* output of termcodes.m4 */
3530330Sminshall #include "state.h"
3630330Sminshall 
37*30331Sminshall #include "../system/globals.h"
38*30331Sminshall #include "../ctlr/function.h"
39*30331Sminshall #include "../ctlr/inbound.ext"
40*30331Sminshall #include "../ctlr/outbound.ext"
41*30331Sminshall #include "../telnet.ext"
4230330Sminshall #include "termin.ext"
4330330Sminshall 
4430330Sminshall #define IsControl(c)	(!isprint(c) || (isspace(c) && ((c) != ' ')))
4530330Sminshall 
4630330Sminshall #define NextState(x)	(x->next)
4730330Sminshall 
4830330Sminshall /* XXX temporary - hard code in the state table */
4930330Sminshall 
5030330Sminshall #define MATCH_ANY 0xff			/* actually, match any character */
5130330Sminshall 
52*30331Sminshall #include "astosc.out"
5330330Sminshall 
5430330Sminshall static char
5530330Sminshall 	ourBuffer[100],		/* where we store stuff */
5630330Sminshall 	*ourPHead = ourBuffer,	/* first character in buffer */
5730330Sminshall 	*ourPTail = ourBuffer;	/* where next character goes */
5830330Sminshall 
59*30331Sminshall static int InControl;
60*30331Sminshall static int WaitingForSynch;
61*30331Sminshall 
6230330Sminshall static state
6330330Sminshall 	*headOfControl = 0;	/* where we enter code state table */
6430330Sminshall 
65*30331Sminshall #define FullChar	((ourPTail+5) >= ourBuffer+sizeof ourBuffer)
6630330Sminshall #define EmptyChar	(ourPTail == ourPHead)
6730330Sminshall 
6830330Sminshall 
69*30331Sminshall /*
70*30331Sminshall  * Initialize the keyboard mapping file.
71*30331Sminshall  */
72*30331Sminshall 
73*30331Sminshall void
74*30331Sminshall InitMapping()
75*30331Sminshall {
76*30331Sminshall     extern state *InitControl();
77*30331Sminshall 
78*30331Sminshall     if (!headOfControl) {
79*30331Sminshall 	/* need to initialize */
80*30331Sminshall 	headOfControl = InitControl((char *)0, 0);
81*30331Sminshall 	if (!headOfControl) {		/* should not occur */
82*30331Sminshall 	    quit();
83*30331Sminshall 	}
84*30331Sminshall     }
85*30331Sminshall }
86*30331Sminshall 
87*30331Sminshall 
8830330Sminshall /* AddChar - put a character in our buffer */
8930330Sminshall 
9030330Sminshall static void
9130330Sminshall AddChar(c)
9230330Sminshall int	c;
9330330Sminshall {
9430330Sminshall     if (!FullChar) {
95*30331Sminshall 	if ((c >= numberof(asctosc)) || (c < 0)) {
96*30331Sminshall 	    ExitString(stderr,
97*30331Sminshall 		    "Unable to locate function in termout.c, AddChar()\n", 1);
98*30331Sminshall 	    /*NOTREACHED*/
99*30331Sminshall 	} else {
100*30331Sminshall 	    switch (asctosc[c].shift) {
101*30331Sminshall 	    case cantdo:
102*30331Sminshall 		if (c == ' ') {
103*30331Sminshall 		    *ourPTail++ = asctosc[TC_SPACE].scancode;
104*30331Sminshall 		} else {
105*30331Sminshall 		    RingBell("Keyboard not capable of function.");
106*30331Sminshall 		}
107*30331Sminshall 		break;
108*30331Sminshall 	    case normal:
109*30331Sminshall 		*ourPTail++ = asctosc[c].scancode;
110*30331Sminshall 		break;
111*30331Sminshall 	    case shifted:
112*30331Sminshall 		*ourPTail++ = asctosc[TC_MAKE_SHIFT].scancode;
113*30331Sminshall 		*ourPTail++ = asctosc[c].scancode;
114*30331Sminshall 		*ourPTail++ = asctosc[TC_BREAK_SHIFT].scancode;
115*30331Sminshall 		break;
116*30331Sminshall 	    case alted:
117*30331Sminshall 		*ourPTail++ = asctosc[TC_MAKE_ALT].scancode;
118*30331Sminshall 		*ourPTail++ = asctosc[c].scancode;
119*30331Sminshall 		*ourPTail++ = asctosc[TC_BREAK_ALT].scancode;
120*30331Sminshall 		break;
121*30331Sminshall 	    case shiftalted:
122*30331Sminshall 		*ourPTail++ = asctosc[TC_MAKE_SHIFT].scancode;
123*30331Sminshall 		*ourPTail++ = asctosc[TC_MAKE_ALT].scancode;
124*30331Sminshall 		*ourPTail++ = asctosc[c].scancode;
125*30331Sminshall 		*ourPTail++ = asctosc[TC_BREAK_ALT].scancode;
126*30331Sminshall 		*ourPTail++ = asctosc[TC_BREAK_SHIFT].scancode;
127*30331Sminshall 		break;
128*30331Sminshall 	    default:
129*30331Sminshall 		ExitString(stderr,
130*30331Sminshall 			    "Illegal 'shift' to AddChar() in termin.c\n", 1);
131*30331Sminshall 	    }
132*30331Sminshall 	}
13330330Sminshall     } else {
134*30331Sminshall 	RingBell("Typeahead buffer full");
13530330Sminshall     }
13630330Sminshall }
13730330Sminshall 
13830330Sminshall /* FlushChar - put everything where it belongs */
13930330Sminshall 
14030330Sminshall static void
14130330Sminshall FlushChar()
14230330Sminshall {
14330330Sminshall     ourPTail = ourBuffer;
14430330Sminshall     ourPHead = ourBuffer;
14530330Sminshall }
14630330Sminshall 
147*30331Sminshall terminit()
148*30331Sminshall {
149*30331Sminshall     FlushChar();
150*30331Sminshall     InControl = WaitingForSynch = 0;
151*30331Sminshall }
15230330Sminshall 
153*30331Sminshall 
15430330Sminshall int
15530330Sminshall TerminalIn()
15630330Sminshall {
15730330Sminshall     /* send data from us to next link in stream */
15830330Sminshall     int count;
15930330Sminshall 
16030330Sminshall     count = 0;
16130330Sminshall 
16230330Sminshall     if (!EmptyChar) {			/* send up the link */
16330330Sminshall 	count += DataFrom3270(ourPHead, ourPTail-ourPHead);
16430330Sminshall 	ourPHead += count;
16530330Sminshall 	if (EmptyChar) {
16630330Sminshall 	    FlushChar();
16730330Sminshall 	}
16830330Sminshall     }
16930330Sminshall 	/* return value answers question: "did we do anything useful?" */
17030330Sminshall     return(count? 1:0);
17130330Sminshall }
17230330Sminshall 
17330330Sminshall int
17430330Sminshall DataFromTerminal(buffer, count)
17530330Sminshall register char	*buffer;		/* the data read in */
17630330Sminshall register int	count;			/* how many bytes in this buffer */
17730330Sminshall {
17830330Sminshall     register state *regControlPointer;
17930330Sminshall     register char c;
18030330Sminshall     register int result;
18130330Sminshall     int origCount;
182*30331Sminshall     extern int bellwinup;
18330330Sminshall     static state *controlPointer;
18430330Sminshall 
185*30331Sminshall     if (bellwinup) {
186*30331Sminshall 	BellOff();
18730330Sminshall     }
18830330Sminshall 
18930330Sminshall     origCount = count;
19030330Sminshall 
19130330Sminshall     while (count) {
19230330Sminshall 	c = *buffer++&0x7f;
19330330Sminshall 	count--;
19430330Sminshall 
19530330Sminshall 	if (!InControl && !IsControl(c)) {
19630330Sminshall 	    AddChar(c);			/* add ascii character */
19730330Sminshall 	} else {
19830330Sminshall 	    if (!InControl) {		/* first character of sequence */
19930330Sminshall 		InControl = 1;
20030330Sminshall 		controlPointer = headOfControl;
20130330Sminshall 	    }
20230330Sminshall 	    /* control pointer points to current position in state table */
20330330Sminshall 	    for (regControlPointer = controlPointer; ;
20430330Sminshall 			regControlPointer = NextState(regControlPointer)) {
20530330Sminshall 		if (!regControlPointer) {	/* ran off end */
206*30331Sminshall 		    RingBell("Invalid control sequence");
20730330Sminshall 		    regControlPointer = headOfControl;
20830330Sminshall 		    InControl = 0;
20930330Sminshall 		    break;
21030330Sminshall 		}
21130330Sminshall 		if ((regControlPointer->match == c) /* hit this character */
21230330Sminshall 			|| (regControlPointer->match == MATCH_ANY)) {
21330330Sminshall 		    result = regControlPointer->result;
21430330Sminshall 		    if (result == TC_GOTO) {
21530330Sminshall 			regControlPointer = regControlPointer->address;
21630330Sminshall 			break;			/* go to next character */
21730330Sminshall 		    }
21830330Sminshall 		    if (WaitingForSynch) {
21930330Sminshall 			if (result == TC_SYNCH) {
22030330Sminshall 			    WaitingForSynch = 0;
22130330Sminshall 			} else {
222*30331Sminshall 			    RingBell("Need to type synch character");
22330330Sminshall 			}
22430330Sminshall 		    }
22530330Sminshall 		    else if (result == TC_FLINP) {
22630330Sminshall 			FlushChar();		/* Don't add FLINP */
22730330Sminshall 		    } else {
22830330Sminshall 			if (result == TC_MASTER_RESET) {
22930330Sminshall 			    FlushChar();
23030330Sminshall 			}
23130330Sminshall 			AddChar(result);		/* add this code */
23230330Sminshall 		    }
23330330Sminshall 		    InControl = 0;	/* out of control now */
23430330Sminshall 		    break;
23530330Sminshall 		}
23630330Sminshall 	    }
23730330Sminshall 	    controlPointer = regControlPointer;		/* save state */
23830330Sminshall 	}
23930330Sminshall     }
24030330Sminshall     (void) TerminalIn();			/* try to send data */
24130330Sminshall     return(origCount-count);
24230330Sminshall }
243