xref: /csrg-svn/usr.bin/tn3270/ascii/termin.c (revision 30725)
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 
3030331Sminshall #include <stdio.h>
3130330Sminshall #include <ctype.h>
3230330Sminshall 
3330331Sminshall #include "../general.h"
3430330Sminshall #include "m4.out"		/* output of termcodes.m4 */
3530330Sminshall #include "state.h"
3630330Sminshall 
3730331Sminshall #include "../system/globals.h"
3830331Sminshall #include "../ctlr/function.h"
3930331Sminshall #include "../ctlr/inbound.ext"
4030331Sminshall #include "../ctlr/outbound.ext"
4130331Sminshall #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 
5230331Sminshall #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 
5930331Sminshall static int InControl;
6030331Sminshall static int WaitingForSynch;
6130331Sminshall 
6230330Sminshall static state
6330330Sminshall 	*headOfControl = 0;	/* where we enter code state table */
6430330Sminshall 
6530331Sminshall #define FullChar	((ourPTail+5) >= ourBuffer+sizeof ourBuffer)
6630330Sminshall #define EmptyChar	(ourPTail == ourPHead)
6730330Sminshall 
6830330Sminshall 
6930331Sminshall /*
70*30725Sminshall  * init_keyboard()
71*30725Sminshall  *
72*30725Sminshall  * Initialize the keyboard variables.
73*30725Sminshall  */
74*30725Sminshall 
75*30725Sminshall void
76*30725Sminshall init_keyboard()
77*30725Sminshall {
78*30725Sminshall     ourPHead = ourPTail = ourBuffer;
79*30725Sminshall     InControl = 0;
80*30725Sminshall     WaitingForSynch = 0;
81*30725Sminshall }
82*30725Sminshall 
83*30725Sminshall 
84*30725Sminshall /*
8530331Sminshall  * Initialize the keyboard mapping file.
8630331Sminshall  */
8730331Sminshall 
8830331Sminshall void
8930331Sminshall InitMapping()
9030331Sminshall {
9130331Sminshall     extern state *InitControl();
9230331Sminshall 
9330331Sminshall     if (!headOfControl) {
9430331Sminshall 	/* need to initialize */
9530331Sminshall 	headOfControl = InitControl((char *)0, 0);
9630331Sminshall 	if (!headOfControl) {		/* should not occur */
9730331Sminshall 	    quit();
9830331Sminshall 	}
9930331Sminshall     }
10030331Sminshall }
10130331Sminshall 
10230331Sminshall 
10330330Sminshall /* AddChar - put a character in our buffer */
10430330Sminshall 
10530330Sminshall static void
10630330Sminshall AddChar(c)
10730330Sminshall int	c;
10830330Sminshall {
10930330Sminshall     if (!FullChar) {
11030331Sminshall 	if ((c >= numberof(asctosc)) || (c < 0)) {
11130331Sminshall 	    ExitString(stderr,
11230331Sminshall 		    "Unable to locate function in termout.c, AddChar()\n", 1);
11330331Sminshall 	    /*NOTREACHED*/
11430331Sminshall 	} else {
11530331Sminshall 	    switch (asctosc[c].shift) {
11630331Sminshall 	    case cantdo:
11730331Sminshall 		if (c == ' ') {
11830331Sminshall 		    *ourPTail++ = asctosc[TC_SPACE].scancode;
11930331Sminshall 		} else {
12030331Sminshall 		    RingBell("Keyboard not capable of function.");
12130331Sminshall 		}
12230331Sminshall 		break;
12330331Sminshall 	    case normal:
12430331Sminshall 		*ourPTail++ = asctosc[c].scancode;
12530331Sminshall 		break;
12630331Sminshall 	    case shifted:
12730331Sminshall 		*ourPTail++ = asctosc[TC_MAKE_SHIFT].scancode;
12830331Sminshall 		*ourPTail++ = asctosc[c].scancode;
12930331Sminshall 		*ourPTail++ = asctosc[TC_BREAK_SHIFT].scancode;
13030331Sminshall 		break;
13130331Sminshall 	    case alted:
13230331Sminshall 		*ourPTail++ = asctosc[TC_MAKE_ALT].scancode;
13330331Sminshall 		*ourPTail++ = asctosc[c].scancode;
13430331Sminshall 		*ourPTail++ = asctosc[TC_BREAK_ALT].scancode;
13530331Sminshall 		break;
13630331Sminshall 	    case shiftalted:
13730331Sminshall 		*ourPTail++ = asctosc[TC_MAKE_SHIFT].scancode;
13830331Sminshall 		*ourPTail++ = asctosc[TC_MAKE_ALT].scancode;
13930331Sminshall 		*ourPTail++ = asctosc[c].scancode;
14030331Sminshall 		*ourPTail++ = asctosc[TC_BREAK_ALT].scancode;
14130331Sminshall 		*ourPTail++ = asctosc[TC_BREAK_SHIFT].scancode;
14230331Sminshall 		break;
14330331Sminshall 	    default:
14430331Sminshall 		ExitString(stderr,
14530331Sminshall 			    "Illegal 'shift' to AddChar() in termin.c\n", 1);
14630331Sminshall 	    }
14730331Sminshall 	}
14830330Sminshall     } else {
14930331Sminshall 	RingBell("Typeahead buffer full");
15030330Sminshall     }
15130330Sminshall }
15230330Sminshall 
15330330Sminshall /* FlushChar - put everything where it belongs */
15430330Sminshall 
15530330Sminshall static void
15630330Sminshall FlushChar()
15730330Sminshall {
15830330Sminshall     ourPTail = ourBuffer;
15930330Sminshall     ourPHead = ourBuffer;
16030330Sminshall }
16130330Sminshall 
16230330Sminshall int
16330330Sminshall TerminalIn()
16430330Sminshall {
16530330Sminshall     /* send data from us to next link in stream */
16630330Sminshall     int count;
16730330Sminshall 
16830330Sminshall     count = 0;
16930330Sminshall 
17030330Sminshall     if (!EmptyChar) {			/* send up the link */
17130330Sminshall 	count += DataFrom3270(ourPHead, ourPTail-ourPHead);
17230330Sminshall 	ourPHead += count;
17330330Sminshall 	if (EmptyChar) {
17430330Sminshall 	    FlushChar();
17530330Sminshall 	}
17630330Sminshall     }
17730330Sminshall 	/* return value answers question: "did we do anything useful?" */
17830330Sminshall     return(count? 1:0);
17930330Sminshall }
18030330Sminshall 
18130330Sminshall int
18230330Sminshall DataFromTerminal(buffer, count)
18330330Sminshall register char	*buffer;		/* the data read in */
18430330Sminshall register int	count;			/* how many bytes in this buffer */
18530330Sminshall {
18630330Sminshall     register state *regControlPointer;
18730330Sminshall     register char c;
18830330Sminshall     register int result;
18930330Sminshall     int origCount;
19030331Sminshall     extern int bellwinup;
19130330Sminshall     static state *controlPointer;
19230330Sminshall 
19330331Sminshall     if (bellwinup) {
19430331Sminshall 	BellOff();
19530330Sminshall     }
19630330Sminshall 
19730330Sminshall     origCount = count;
19830330Sminshall 
19930330Sminshall     while (count) {
20030330Sminshall 	c = *buffer++&0x7f;
20130330Sminshall 	count--;
20230330Sminshall 
20330330Sminshall 	if (!InControl && !IsControl(c)) {
20430330Sminshall 	    AddChar(c);			/* add ascii character */
20530330Sminshall 	} else {
20630330Sminshall 	    if (!InControl) {		/* first character of sequence */
20730330Sminshall 		InControl = 1;
20830330Sminshall 		controlPointer = headOfControl;
20930330Sminshall 	    }
21030330Sminshall 	    /* control pointer points to current position in state table */
21130330Sminshall 	    for (regControlPointer = controlPointer; ;
21230330Sminshall 			regControlPointer = NextState(regControlPointer)) {
21330330Sminshall 		if (!regControlPointer) {	/* ran off end */
21430331Sminshall 		    RingBell("Invalid control sequence");
21530330Sminshall 		    regControlPointer = headOfControl;
21630330Sminshall 		    InControl = 0;
21730330Sminshall 		    break;
21830330Sminshall 		}
21930330Sminshall 		if ((regControlPointer->match == c) /* hit this character */
22030330Sminshall 			|| (regControlPointer->match == MATCH_ANY)) {
22130330Sminshall 		    result = regControlPointer->result;
22230330Sminshall 		    if (result == TC_GOTO) {
22330330Sminshall 			regControlPointer = regControlPointer->address;
22430330Sminshall 			break;			/* go to next character */
22530330Sminshall 		    }
22630330Sminshall 		    if (WaitingForSynch) {
22730330Sminshall 			if (result == TC_SYNCH) {
22830330Sminshall 			    WaitingForSynch = 0;
22930330Sminshall 			} else {
23030331Sminshall 			    RingBell("Need to type synch character");
23130330Sminshall 			}
23230330Sminshall 		    }
23330330Sminshall 		    else if (result == TC_FLINP) {
23430330Sminshall 			FlushChar();		/* Don't add FLINP */
23530330Sminshall 		    } else {
23630330Sminshall 			if (result == TC_MASTER_RESET) {
23730330Sminshall 			    FlushChar();
23830330Sminshall 			}
23930330Sminshall 			AddChar(result);		/* add this code */
24030330Sminshall 		    }
24130330Sminshall 		    InControl = 0;	/* out of control now */
24230330Sminshall 		    break;
24330330Sminshall 		}
24430330Sminshall 	    }
24530330Sminshall 	    controlPointer = regControlPointer;		/* save state */
24630330Sminshall 	}
24730330Sminshall     }
24830330Sminshall     (void) TerminalIn();			/* try to send data */
24930330Sminshall     return(origCount-count);
25030330Sminshall }
251