xref: /csrg-svn/usr.bin/tn3270/ascii/termin.c (revision 31966)
130330Sminshall /*
231891Sminshall  *	Copyright (c) 1984-1987 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
23*31966Sminshall static	char	sccsid[] = "@(#)termin.c	1.13 (Berkeley) 07/29/87";
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 
4031870Sminshall #include "../api/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 */
5731865Sminshall 	*ourPTail = ourBuffer,	/* where next character goes */
5831865Sminshall 	*TransPointer = 0;	/* For transparent mode data */
5930330Sminshall 
6030331Sminshall static int InControl;
6130331Sminshall static int WaitingForSynch;
6230331Sminshall 
6331245Sminshall static struct astosc
6431245Sminshall 	*spacePTR = 0;		/* Space is hard to enter */
6531245Sminshall 
6630330Sminshall static state
6730330Sminshall 	*headOfControl = 0;	/* where we enter code state table */
6830330Sminshall 
6930331Sminshall #define FullChar	((ourPTail+5) >= ourBuffer+sizeof ourBuffer)
7030330Sminshall #define EmptyChar	(ourPTail == ourPHead)
7130330Sminshall 
7230330Sminshall 
7330331Sminshall /*
7430725Sminshall  * init_keyboard()
7530725Sminshall  *
7630725Sminshall  * Initialize the keyboard variables.
7730725Sminshall  */
7830725Sminshall 
7930725Sminshall void
8030725Sminshall init_keyboard()
8130725Sminshall {
8230725Sminshall     ourPHead = ourPTail = ourBuffer;
8330725Sminshall     InControl = 0;
8430725Sminshall     WaitingForSynch = 0;
8530725Sminshall }
8630725Sminshall 
8730725Sminshall 
8830725Sminshall /*
8930331Sminshall  * Initialize the keyboard mapping file.
9030331Sminshall  */
9130331Sminshall 
9230331Sminshall void
9330331Sminshall InitMapping()
9430331Sminshall {
9530331Sminshall     extern state *InitControl();
9631245Sminshall     register struct astosc *ptr;
9730331Sminshall 
9830331Sminshall     if (!headOfControl) {
9930331Sminshall 	/* need to initialize */
10031245Sminshall 	headOfControl = InitControl((char *)0, 0, ascii_to_index);
10130331Sminshall 	if (!headOfControl) {		/* should not occur */
10230331Sminshall 	    quit();
10330331Sminshall 	}
10431245Sminshall 	for (ptr = &astosc[0]; ptr <= &astosc[highestof(astosc)]; ptr++) {
10531245Sminshall 	    if (ptr->function == FCN_SPACE) {
10631245Sminshall 		spacePTR = ptr;
10731245Sminshall 	    }
10831245Sminshall 	}
10930331Sminshall     }
11030331Sminshall }
11130331Sminshall 
11230331Sminshall 
11331245Sminshall /* AddChar - put a function index in our buffer */
11430330Sminshall 
11530330Sminshall static void
11630330Sminshall AddChar(c)
11730330Sminshall int	c;
11830330Sminshall {
11930330Sminshall     if (!FullChar) {
12031245Sminshall 	*ourPTail++ = c;
12130330Sminshall     } else {
12230331Sminshall 	RingBell("Typeahead buffer full");
12330330Sminshall     }
12430330Sminshall }
12530330Sminshall 
12630330Sminshall /* FlushChar - put everything where it belongs */
12730330Sminshall 
12830330Sminshall static void
12930330Sminshall FlushChar()
13030330Sminshall {
13130330Sminshall     ourPTail = ourBuffer;
13230330Sminshall     ourPHead = ourBuffer;
13330330Sminshall }
13430330Sminshall 
13531865Sminshall void
13631865Sminshall TransInput(onoff, mode)
13731865Sminshall int	mode;			/* Which KIND of transparent input */
13831865Sminshall int	onoff;			/* Going in, or coming out */
13931865Sminshall {
14031865Sminshall     if (onoff) {
14131865Sminshall 	/* Flush pending input */
14231865Sminshall 	FlushChar();
14331865Sminshall 	TransPointer = ourBuffer;
14431865Sminshall     } else {
14531865Sminshall     }
14631865Sminshall }
14731865Sminshall 
14830330Sminshall int
14930330Sminshall TerminalIn()
15030330Sminshall {
15130330Sminshall     /* send data from us to next link in stream */
15231245Sminshall     int work = 0;
15331245Sminshall     register struct astosc *ptr;
15430330Sminshall 
15531245Sminshall     while (!EmptyChar) {			/* send up the link */
15631446Sminshall 	if (*ourPHead == ' ') {
15731446Sminshall 	    ptr = spacePTR;
15831446Sminshall 	} else {
15931446Sminshall 	    ptr = &astosc[*ourPHead];
16031446Sminshall 	}
16131245Sminshall 	if (AcceptKeystroke(ptr->scancode, ptr->shiftstate) == 1) {
16231245Sminshall 	    ourPHead++;
16331245Sminshall 	    work = 1;
16431446Sminshall 	} else {
16531446Sminshall 	    break;
16630330Sminshall 	}
16730330Sminshall     }
16831446Sminshall 
16931245Sminshall     if (EmptyChar) {
17031245Sminshall 	FlushChar();
17131245Sminshall     }
17230330Sminshall 	/* return value answers question: "did we do anything useful?" */
17331245Sminshall     return work;
17430330Sminshall }
17530330Sminshall 
17630330Sminshall int
17730330Sminshall DataFromTerminal(buffer, count)
17830330Sminshall register char	*buffer;		/* the data read in */
17930330Sminshall register int	count;			/* how many bytes in this buffer */
18030330Sminshall {
18130330Sminshall     register state *regControlPointer;
18230330Sminshall     register char c;
18330330Sminshall     register int result;
18430330Sminshall     int origCount;
18530331Sminshall     extern int bellwinup;
18630330Sminshall     static state *controlPointer;
18730330Sminshall 
18831865Sminshall     if (TransPointer) {
18931865Sminshall 	int i;
19031865Sminshall 
19131865Sminshall 	if ((count+TransPointer) >= (ourBuffer+sizeof ourBuffer)) {
19231865Sminshall 	    i = ourBuffer+sizeof ourBuffer-TransPointer;
19331865Sminshall 	} else {
19431865Sminshall 	    i = count;
19531865Sminshall 	}
19631865Sminshall 	while (i--) {
197*31966Sminshall 	    c = (*buffer++)&0x7f;
19831865Sminshall 	    *TransPointer++ = c|0x80;
19931865Sminshall 	    if (c == '\r') {
20031865Sminshall 		SendTransparent(ourBuffer, TransPointer-ourBuffer);
20131865Sminshall 		TransPointer = 0;		/* Done */
20231865Sminshall 		break;
20331865Sminshall 	    }
20431865Sminshall 	}
20531865Sminshall 	return count;
20631865Sminshall     }
20731865Sminshall 
20830331Sminshall     if (bellwinup) {
20930331Sminshall 	BellOff();
21030330Sminshall     }
21130330Sminshall 
21230330Sminshall     origCount = count;
21330330Sminshall 
21430330Sminshall     while (count) {
21530330Sminshall 	c = *buffer++&0x7f;
21630330Sminshall 	count--;
21730330Sminshall 
21830330Sminshall 	if (!InControl && !IsControl(c)) {
21930330Sminshall 	    AddChar(c);			/* add ascii character */
22030330Sminshall 	} else {
22130330Sminshall 	    if (!InControl) {		/* first character of sequence */
22230330Sminshall 		InControl = 1;
22330330Sminshall 		controlPointer = headOfControl;
22430330Sminshall 	    }
22530330Sminshall 	    /* control pointer points to current position in state table */
22630330Sminshall 	    for (regControlPointer = controlPointer; ;
22730330Sminshall 			regControlPointer = NextState(regControlPointer)) {
22830330Sminshall 		if (!regControlPointer) {	/* ran off end */
22930331Sminshall 		    RingBell("Invalid control sequence");
23030330Sminshall 		    regControlPointer = headOfControl;
23130330Sminshall 		    InControl = 0;
23231447Sminshall 		    count = 0;		/* Flush current input */
23331550Sminshall 		    break;
23430330Sminshall 		}
23530330Sminshall 		if ((regControlPointer->match == c) /* hit this character */
23630330Sminshall 			|| (regControlPointer->match == MATCH_ANY)) {
23730330Sminshall 		    result = regControlPointer->result;
23831245Sminshall 		    if (result == STATE_GOTO) {
23930330Sminshall 			regControlPointer = regControlPointer->address;
24030330Sminshall 			break;			/* go to next character */
24130330Sminshall 		    }
24230330Sminshall 		    if (WaitingForSynch) {
24331245Sminshall 			if (astosc[result].function == FCN_SYNCH) {
24430330Sminshall 			    WaitingForSynch = 0;
24530330Sminshall 			} else {
24630331Sminshall 			    RingBell("Need to type synch character");
24730330Sminshall 			}
24830330Sminshall 		    }
24931245Sminshall 		    else if (astosc[result].function == FCN_FLINP) {
25030330Sminshall 			FlushChar();		/* Don't add FLINP */
25130330Sminshall 		    } else {
25231245Sminshall 			if (astosc[result].function == FCN_MASTER_RESET) {
25330330Sminshall 			    FlushChar();
25430330Sminshall 			}
25530330Sminshall 			AddChar(result);		/* add this code */
25630330Sminshall 		    }
25730330Sminshall 		    InControl = 0;	/* out of control now */
25830330Sminshall 		    break;
25930330Sminshall 		}
26030330Sminshall 	    }
26130330Sminshall 	    controlPointer = regControlPointer;		/* save state */
26230330Sminshall 	}
26330330Sminshall     }
26430330Sminshall     (void) TerminalIn();			/* try to send data */
26530330Sminshall     return(origCount-count);
26630330Sminshall }
267