xref: /csrg-svn/usr.bin/tn3270/ascii/termin.c (revision 62321)
148755Sbostic /*-
2*62321Sbostic  * Copyright (c) 1988, 1993
3*62321Sbostic  *	The Regents of the University of California.  All rights reserved.
430330Sminshall  *
548755Sbostic  * %sccs.include.redist.c%
630330Sminshall  */
730330Sminshall 
833817Sbostic #ifndef lint
9*62321Sbostic static char sccsid[] = "@(#)termin.c	8.1 (Berkeley) 06/06/93";
1033817Sbostic #endif /* not lint */
1130330Sminshall 
1230330Sminshall /* this takes characters from the keyboard, and produces 3270 keystroke
1330330Sminshall 	codes
1430330Sminshall  */
1530330Sminshall 
1630331Sminshall #include <stdio.h>
1730330Sminshall #include <ctype.h>
1830330Sminshall 
1931176Sminshall #include "../general/general.h"
2030331Sminshall #include "../ctlr/function.h"
2135419Sminshall #include "../ctlr/externs.h"
2235419Sminshall #include "../ctlr/declare.h"
2330330Sminshall 
2431870Sminshall #include "../api/astosc.h"
2531245Sminshall #include "state.h"
2631245Sminshall 
2731245Sminshall #include "../general/globals.h"
2831245Sminshall 
2930330Sminshall #define IsControl(c)	(!isprint(c) || (isspace(c) && ((c) != ' ')))
3030330Sminshall 
3130330Sminshall #define NextState(x)	(x->next)
3230330Sminshall 
3330330Sminshall /* XXX temporary - hard code in the state table */
3430330Sminshall 
3530330Sminshall #define MATCH_ANY 0xff			/* actually, match any character */
3630330Sminshall 
3730330Sminshall 
3831245Sminshall static unsigned char
3930330Sminshall 	ourBuffer[100],		/* where we store stuff */
4030330Sminshall 	*ourPHead = ourBuffer,	/* first character in buffer */
4131865Sminshall 	*ourPTail = ourBuffer,	/* where next character goes */
4231865Sminshall 	*TransPointer = 0;	/* For transparent mode data */
4330330Sminshall 
4430331Sminshall static int InControl;
4530331Sminshall static int WaitingForSynch;
4630331Sminshall 
4731245Sminshall static struct astosc
4831245Sminshall 	*spacePTR = 0;		/* Space is hard to enter */
4931245Sminshall 
5030330Sminshall static state
5130330Sminshall 	*headOfControl = 0;	/* where we enter code state table */
5230330Sminshall 
5330331Sminshall #define FullChar	((ourPTail+5) >= ourBuffer+sizeof ourBuffer)
5430330Sminshall #define EmptyChar	(ourPTail == ourPHead)
5530330Sminshall 
5630330Sminshall 
5730331Sminshall /*
5830725Sminshall  * init_keyboard()
5930725Sminshall  *
6030725Sminshall  * Initialize the keyboard variables.
6130725Sminshall  */
6230725Sminshall 
6330725Sminshall void
init_keyboard()6430725Sminshall init_keyboard()
6530725Sminshall {
6630725Sminshall     ourPHead = ourPTail = ourBuffer;
6730725Sminshall     InControl = 0;
6830725Sminshall     WaitingForSynch = 0;
6930725Sminshall }
7030725Sminshall 
7130725Sminshall 
7230725Sminshall /*
7330331Sminshall  * Initialize the keyboard mapping file.
7430331Sminshall  */
7530331Sminshall 
7630331Sminshall void
InitMapping()7730331Sminshall InitMapping()
7830331Sminshall {
7930331Sminshall     extern state *InitControl();
8031245Sminshall     register struct astosc *ptr;
8130331Sminshall 
8230331Sminshall     if (!headOfControl) {
8330331Sminshall 	/* need to initialize */
8431245Sminshall 	headOfControl = InitControl((char *)0, 0, ascii_to_index);
8530331Sminshall 	if (!headOfControl) {		/* should not occur */
8630331Sminshall 	    quit();
8730331Sminshall 	}
8831245Sminshall 	for (ptr = &astosc[0]; ptr <= &astosc[highestof(astosc)]; ptr++) {
8931245Sminshall 	    if (ptr->function == FCN_SPACE) {
9031245Sminshall 		spacePTR = ptr;
9131245Sminshall 	    }
9231245Sminshall 	}
9330331Sminshall     }
9430331Sminshall }
9530331Sminshall 
9630331Sminshall 
9731245Sminshall /* AddChar - put a function index in our buffer */
9830330Sminshall 
9930330Sminshall static void
AddChar(c)10030330Sminshall AddChar(c)
10130330Sminshall int	c;
10230330Sminshall {
10330330Sminshall     if (!FullChar) {
10431245Sminshall 	*ourPTail++ = c;
10530330Sminshall     } else {
10630331Sminshall 	RingBell("Typeahead buffer full");
10730330Sminshall     }
10830330Sminshall }
10930330Sminshall 
11030330Sminshall /* FlushChar - put everything where it belongs */
11130330Sminshall 
11230330Sminshall static void
FlushChar()11330330Sminshall FlushChar()
11430330Sminshall {
11530330Sminshall     ourPTail = ourBuffer;
11630330Sminshall     ourPHead = ourBuffer;
11730330Sminshall }
11830330Sminshall 
11935419Sminshall /*ARGSUSED*/
12031865Sminshall void
TransInput(onoff,mode)12131865Sminshall TransInput(onoff, mode)
12231865Sminshall int	mode;			/* Which KIND of transparent input */
12331865Sminshall int	onoff;			/* Going in, or coming out */
12431865Sminshall {
12531865Sminshall     if (onoff) {
12631865Sminshall 	/* Flush pending input */
12731865Sminshall 	FlushChar();
12831865Sminshall 	TransPointer = ourBuffer;
12931865Sminshall     } else {
13031865Sminshall     }
13131865Sminshall }
13231865Sminshall 
13330330Sminshall int
TerminalIn()13430330Sminshall TerminalIn()
13530330Sminshall {
13630330Sminshall     /* send data from us to next link in stream */
13731245Sminshall     int work = 0;
13831245Sminshall     register struct astosc *ptr;
13930330Sminshall 
14031245Sminshall     while (!EmptyChar) {			/* send up the link */
14131446Sminshall 	if (*ourPHead == ' ') {
14231446Sminshall 	    ptr = spacePTR;
14331446Sminshall 	} else {
14431446Sminshall 	    ptr = &astosc[*ourPHead];
14531446Sminshall 	}
14631245Sminshall 	if (AcceptKeystroke(ptr->scancode, ptr->shiftstate) == 1) {
14731245Sminshall 	    ourPHead++;
14831245Sminshall 	    work = 1;
14931446Sminshall 	} else {
15031446Sminshall 	    break;
15130330Sminshall 	}
15230330Sminshall     }
15331446Sminshall 
15431245Sminshall     if (EmptyChar) {
15531245Sminshall 	FlushChar();
15631245Sminshall     }
15730330Sminshall 	/* return value answers question: "did we do anything useful?" */
15831245Sminshall     return work;
15930330Sminshall }
16030330Sminshall 
16130330Sminshall int
DataFromTerminal(buffer,count)16230330Sminshall DataFromTerminal(buffer, count)
16330330Sminshall register char	*buffer;		/* the data read in */
16430330Sminshall register int	count;			/* how many bytes in this buffer */
16530330Sminshall {
16630330Sminshall     register state *regControlPointer;
16730330Sminshall     register char c;
16830330Sminshall     register int result;
16930330Sminshall     int origCount;
17030331Sminshall     extern int bellwinup;
17130330Sminshall     static state *controlPointer;
17230330Sminshall 
17331865Sminshall     if (TransPointer) {
17431865Sminshall 	int i;
17531865Sminshall 
17631865Sminshall 	if ((count+TransPointer) >= (ourBuffer+sizeof ourBuffer)) {
17731865Sminshall 	    i = ourBuffer+sizeof ourBuffer-TransPointer;
17831865Sminshall 	} else {
17931865Sminshall 	    i = count;
18031865Sminshall 	}
18131865Sminshall 	while (i--) {
18231966Sminshall 	    c = (*buffer++)&0x7f;
18331865Sminshall 	    *TransPointer++ = c|0x80;
18431865Sminshall 	    if (c == '\r') {
18535419Sminshall 		SendTransparent((char *)ourBuffer, TransPointer-ourBuffer);
18631865Sminshall 		TransPointer = 0;		/* Done */
18731865Sminshall 		break;
18831865Sminshall 	    }
18931865Sminshall 	}
19031865Sminshall 	return count;
19131865Sminshall     }
19231865Sminshall 
19330331Sminshall     if (bellwinup) {
19435419Sminshall 	void BellOff();
19535419Sminshall 
19630331Sminshall 	BellOff();
19730330Sminshall     }
19830330Sminshall 
19930330Sminshall     origCount = count;
20030330Sminshall 
20130330Sminshall     while (count) {
20230330Sminshall 	c = *buffer++&0x7f;
20330330Sminshall 	count--;
20430330Sminshall 
20530330Sminshall 	if (!InControl && !IsControl(c)) {
20630330Sminshall 	    AddChar(c);			/* add ascii character */
20730330Sminshall 	} else {
20830330Sminshall 	    if (!InControl) {		/* first character of sequence */
20930330Sminshall 		InControl = 1;
21030330Sminshall 		controlPointer = headOfControl;
21130330Sminshall 	    }
21230330Sminshall 	    /* control pointer points to current position in state table */
21330330Sminshall 	    for (regControlPointer = controlPointer; ;
21430330Sminshall 			regControlPointer = NextState(regControlPointer)) {
21530330Sminshall 		if (!regControlPointer) {	/* ran off end */
21630331Sminshall 		    RingBell("Invalid control sequence");
21730330Sminshall 		    regControlPointer = headOfControl;
21830330Sminshall 		    InControl = 0;
21931447Sminshall 		    count = 0;		/* Flush current input */
22031550Sminshall 		    break;
22130330Sminshall 		}
22230330Sminshall 		if ((regControlPointer->match == c) /* hit this character */
22330330Sminshall 			|| (regControlPointer->match == MATCH_ANY)) {
22430330Sminshall 		    result = regControlPointer->result;
22531245Sminshall 		    if (result == STATE_GOTO) {
22630330Sminshall 			regControlPointer = regControlPointer->address;
22730330Sminshall 			break;			/* go to next character */
22830330Sminshall 		    }
22930330Sminshall 		    if (WaitingForSynch) {
23031245Sminshall 			if (astosc[result].function == FCN_SYNCH) {
23130330Sminshall 			    WaitingForSynch = 0;
23230330Sminshall 			} else {
23335419Sminshall 			    void RingBell();
23435419Sminshall 
23530331Sminshall 			    RingBell("Need to type synch character");
23630330Sminshall 			}
23730330Sminshall 		    }
23831245Sminshall 		    else if (astosc[result].function == FCN_FLINP) {
23930330Sminshall 			FlushChar();		/* Don't add FLINP */
24030330Sminshall 		    } else {
24131245Sminshall 			if (astosc[result].function == FCN_MASTER_RESET) {
24230330Sminshall 			    FlushChar();
24330330Sminshall 			}
24430330Sminshall 			AddChar(result);		/* add this code */
24530330Sminshall 		    }
24630330Sminshall 		    InControl = 0;	/* out of control now */
24730330Sminshall 		    break;
24830330Sminshall 		}
24930330Sminshall 	    }
25030330Sminshall 	    controlPointer = regControlPointer;		/* save state */
25130330Sminshall 	}
25230330Sminshall     }
25330330Sminshall     (void) TerminalIn();			/* try to send data */
25430330Sminshall     return(origCount-count);
25530330Sminshall }
256