xref: /csrg-svn/usr.bin/tn3270/ascii/termin.c (revision 31447)
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 
3331176Sminshall #include "../general/general.h"
3430331Sminshall #include "../ctlr/function.h"
3530331Sminshall #include "../ctlr/inbound.ext"
3630331Sminshall #include "../ctlr/outbound.ext"
3730331Sminshall #include "../telnet.ext"
3830330Sminshall #include "termin.ext"
3930330Sminshall 
4031245Sminshall #include "astosc.h"
4131245Sminshall #include "state.h"
4231245Sminshall 
4331245Sminshall #include "../general/globals.h"
4431245Sminshall 
4530330Sminshall #define IsControl(c)	(!isprint(c) || (isspace(c) && ((c) != ' ')))
4630330Sminshall 
4730330Sminshall #define NextState(x)	(x->next)
4830330Sminshall 
4930330Sminshall /* XXX temporary - hard code in the state table */
5030330Sminshall 
5130330Sminshall #define MATCH_ANY 0xff			/* actually, match any character */
5230330Sminshall 
5330330Sminshall 
5431245Sminshall static unsigned 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 
6231245Sminshall static struct astosc
6331245Sminshall 	*spacePTR = 0;		/* Space is hard to enter */
6431245Sminshall 
6530330Sminshall static state
6630330Sminshall 	*headOfControl = 0;	/* where we enter code state table */
6730330Sminshall 
6830331Sminshall #define FullChar	((ourPTail+5) >= ourBuffer+sizeof ourBuffer)
6930330Sminshall #define EmptyChar	(ourPTail == ourPHead)
7030330Sminshall 
7130330Sminshall 
7230331Sminshall /*
7330725Sminshall  * init_keyboard()
7430725Sminshall  *
7530725Sminshall  * Initialize the keyboard variables.
7630725Sminshall  */
7730725Sminshall 
7830725Sminshall void
7930725Sminshall init_keyboard()
8030725Sminshall {
8130725Sminshall     ourPHead = ourPTail = ourBuffer;
8230725Sminshall     InControl = 0;
8330725Sminshall     WaitingForSynch = 0;
8430725Sminshall }
8530725Sminshall 
8630725Sminshall 
8730725Sminshall /*
8830331Sminshall  * Initialize the keyboard mapping file.
8930331Sminshall  */
9030331Sminshall 
9130331Sminshall void
9230331Sminshall InitMapping()
9330331Sminshall {
9430331Sminshall     extern state *InitControl();
9531245Sminshall     register struct astosc *ptr;
9630331Sminshall 
9730331Sminshall     if (!headOfControl) {
9830331Sminshall 	/* need to initialize */
9931245Sminshall 	headOfControl = InitControl((char *)0, 0, ascii_to_index);
10030331Sminshall 	if (!headOfControl) {		/* should not occur */
10130331Sminshall 	    quit();
10230331Sminshall 	}
10331245Sminshall 	for (ptr = &astosc[0]; ptr <= &astosc[highestof(astosc)]; ptr++) {
10431245Sminshall 	    if (ptr->function == FCN_SPACE) {
10531245Sminshall 		spacePTR = ptr;
10631245Sminshall 	    }
10731245Sminshall 	}
10830331Sminshall     }
10930331Sminshall }
11030331Sminshall 
11130331Sminshall 
11231245Sminshall /* AddChar - put a function index in our buffer */
11330330Sminshall 
11430330Sminshall static void
11530330Sminshall AddChar(c)
11630330Sminshall int	c;
11730330Sminshall {
11830330Sminshall     if (!FullChar) {
11931245Sminshall 	*ourPTail++ = c;
12030330Sminshall     } else {
12130331Sminshall 	RingBell("Typeahead buffer full");
12230330Sminshall     }
12330330Sminshall }
12430330Sminshall 
12530330Sminshall /* FlushChar - put everything where it belongs */
12630330Sminshall 
12730330Sminshall static void
12830330Sminshall FlushChar()
12930330Sminshall {
13030330Sminshall     ourPTail = ourBuffer;
13130330Sminshall     ourPHead = ourBuffer;
13230330Sminshall }
13330330Sminshall 
13430330Sminshall int
13530330Sminshall TerminalIn()
13630330Sminshall {
13730330Sminshall     /* send data from us to next link in stream */
13831245Sminshall     int work = 0;
13931245Sminshall     register struct astosc *ptr;
14030330Sminshall 
14131245Sminshall     while (!EmptyChar) {			/* send up the link */
14231446Sminshall 	if (*ourPHead == ' ') {
14331446Sminshall 	    ptr = spacePTR;
14431446Sminshall 	} else {
14531446Sminshall 	    ptr = &astosc[*ourPHead];
14631446Sminshall 	}
14731245Sminshall 	if (AcceptKeystroke(ptr->scancode, ptr->shiftstate) == 1) {
14831245Sminshall 	    ourPHead++;
14931245Sminshall 	    work = 1;
15031446Sminshall 	} else {
15131446Sminshall 	    break;
15230330Sminshall 	}
15330330Sminshall     }
15431446Sminshall 
15531245Sminshall     if (EmptyChar) {
15631245Sminshall 	FlushChar();
15731245Sminshall     }
15830330Sminshall 	/* return value answers question: "did we do anything useful?" */
15931245Sminshall     return work;
16030330Sminshall }
16130330Sminshall 
16230330Sminshall int
16330330Sminshall DataFromTerminal(buffer, count)
16430330Sminshall register char	*buffer;		/* the data read in */
16530330Sminshall register int	count;			/* how many bytes in this buffer */
16630330Sminshall {
16730330Sminshall     register state *regControlPointer;
16830330Sminshall     register char c;
16930330Sminshall     register int result;
17030330Sminshall     int origCount;
17130331Sminshall     extern int bellwinup;
17230330Sminshall     static state *controlPointer;
17330330Sminshall 
17430331Sminshall     if (bellwinup) {
17530331Sminshall 	BellOff();
17630330Sminshall     }
17730330Sminshall 
17830330Sminshall     origCount = count;
17930330Sminshall 
18030330Sminshall     while (count) {
18130330Sminshall 	c = *buffer++&0x7f;
18230330Sminshall 	count--;
18330330Sminshall 
18430330Sminshall 	if (!InControl && !IsControl(c)) {
18530330Sminshall 	    AddChar(c);			/* add ascii character */
18630330Sminshall 	} else {
18730330Sminshall 	    if (!InControl) {		/* first character of sequence */
18830330Sminshall 		InControl = 1;
18930330Sminshall 		controlPointer = headOfControl;
19030330Sminshall 	    }
19130330Sminshall 	    /* control pointer points to current position in state table */
19230330Sminshall 	    for (regControlPointer = controlPointer; ;
19330330Sminshall 			regControlPointer = NextState(regControlPointer)) {
19430330Sminshall 		if (!regControlPointer) {	/* ran off end */
19530331Sminshall 		    RingBell("Invalid control sequence");
19630330Sminshall 		    regControlPointer = headOfControl;
19730330Sminshall 		    InControl = 0;
198*31447Sminshall 		    count = 0;		/* Flush current input */
199*31447Sminshall 		    continue;
20030330Sminshall 		}
20130330Sminshall 		if ((regControlPointer->match == c) /* hit this character */
20230330Sminshall 			|| (regControlPointer->match == MATCH_ANY)) {
20330330Sminshall 		    result = regControlPointer->result;
20431245Sminshall 		    if (result == STATE_GOTO) {
20530330Sminshall 			regControlPointer = regControlPointer->address;
20630330Sminshall 			break;			/* go to next character */
20730330Sminshall 		    }
20830330Sminshall 		    if (WaitingForSynch) {
20931245Sminshall 			if (astosc[result].function == FCN_SYNCH) {
21030330Sminshall 			    WaitingForSynch = 0;
21130330Sminshall 			} else {
21230331Sminshall 			    RingBell("Need to type synch character");
21330330Sminshall 			}
21430330Sminshall 		    }
21531245Sminshall 		    else if (astosc[result].function == FCN_FLINP) {
21630330Sminshall 			FlushChar();		/* Don't add FLINP */
21730330Sminshall 		    } else {
21831245Sminshall 			if (astosc[result].function == FCN_MASTER_RESET) {
21930330Sminshall 			    FlushChar();
22030330Sminshall 			}
22130330Sminshall 			AddChar(result);		/* add this code */
22230330Sminshall 		    }
22330330Sminshall 		    InControl = 0;	/* out of control now */
22430330Sminshall 		    break;
22530330Sminshall 		}
22630330Sminshall 	    }
22730330Sminshall 	    controlPointer = regControlPointer;		/* save state */
22830330Sminshall 	}
22930330Sminshall     }
23030330Sminshall     (void) TerminalIn();			/* try to send data */
23130330Sminshall     return(origCount-count);
23230330Sminshall }
233