xref: /csrg-svn/usr.bin/tn3270/ascii/termin.c (revision 33817)
130330Sminshall /*
2*33817Sbostic  * Copyright (c) 1988 Regents of the University of California.
3*33817Sbostic  * All rights reserved.
430330Sminshall  *
5*33817Sbostic  * Redistribution and use in source and binary forms are permitted
6*33817Sbostic  * provided that this notice is preserved and that due credit is given
7*33817Sbostic  * to the University of California at Berkeley. The name of the University
8*33817Sbostic  * may not be used to endorse or promote products derived from this
9*33817Sbostic  * software without specific prior written permission. This software
10*33817Sbostic  * is provided ``as is'' without express or implied warranty.
1130330Sminshall  */
1230330Sminshall 
13*33817Sbostic #ifndef lint
14*33817Sbostic static char sccsid[] = "@(#)termin.c	3.2 (Berkeley) 03/28/88";
15*33817Sbostic #endif /* not lint */
1630330Sminshall 
1730330Sminshall /* this takes characters from the keyboard, and produces 3270 keystroke
1830330Sminshall 	codes
1930330Sminshall  */
2030330Sminshall 
2130331Sminshall #include <stdio.h>
2230330Sminshall #include <ctype.h>
2330330Sminshall 
2431176Sminshall #include "../general/general.h"
2530331Sminshall #include "../ctlr/function.h"
2630331Sminshall #include "../ctlr/inbound.ext"
2730331Sminshall #include "../ctlr/outbound.ext"
2830331Sminshall #include "../telnet.ext"
2930330Sminshall #include "termin.ext"
3030330Sminshall 
3131870Sminshall #include "../api/astosc.h"
3231245Sminshall #include "state.h"
3331245Sminshall 
3431245Sminshall #include "../general/globals.h"
3531245Sminshall 
3630330Sminshall #define IsControl(c)	(!isprint(c) || (isspace(c) && ((c) != ' ')))
3730330Sminshall 
3830330Sminshall #define NextState(x)	(x->next)
3930330Sminshall 
4030330Sminshall /* XXX temporary - hard code in the state table */
4130330Sminshall 
4230330Sminshall #define MATCH_ANY 0xff			/* actually, match any character */
4330330Sminshall 
4430330Sminshall 
4531245Sminshall static unsigned char
4630330Sminshall 	ourBuffer[100],		/* where we store stuff */
4730330Sminshall 	*ourPHead = ourBuffer,	/* first character in buffer */
4831865Sminshall 	*ourPTail = ourBuffer,	/* where next character goes */
4931865Sminshall 	*TransPointer = 0;	/* For transparent mode data */
5030330Sminshall 
5130331Sminshall static int InControl;
5230331Sminshall static int WaitingForSynch;
5330331Sminshall 
5431245Sminshall static struct astosc
5531245Sminshall 	*spacePTR = 0;		/* Space is hard to enter */
5631245Sminshall 
5730330Sminshall static state
5830330Sminshall 	*headOfControl = 0;	/* where we enter code state table */
5930330Sminshall 
6030331Sminshall #define FullChar	((ourPTail+5) >= ourBuffer+sizeof ourBuffer)
6130330Sminshall #define EmptyChar	(ourPTail == ourPHead)
6230330Sminshall 
6330330Sminshall 
6430331Sminshall /*
6530725Sminshall  * init_keyboard()
6630725Sminshall  *
6730725Sminshall  * Initialize the keyboard variables.
6830725Sminshall  */
6930725Sminshall 
7030725Sminshall void
7130725Sminshall init_keyboard()
7230725Sminshall {
7330725Sminshall     ourPHead = ourPTail = ourBuffer;
7430725Sminshall     InControl = 0;
7530725Sminshall     WaitingForSynch = 0;
7630725Sminshall }
7730725Sminshall 
7830725Sminshall 
7930725Sminshall /*
8030331Sminshall  * Initialize the keyboard mapping file.
8130331Sminshall  */
8230331Sminshall 
8330331Sminshall void
8430331Sminshall InitMapping()
8530331Sminshall {
8630331Sminshall     extern state *InitControl();
8731245Sminshall     register struct astosc *ptr;
8830331Sminshall 
8930331Sminshall     if (!headOfControl) {
9030331Sminshall 	/* need to initialize */
9131245Sminshall 	headOfControl = InitControl((char *)0, 0, ascii_to_index);
9230331Sminshall 	if (!headOfControl) {		/* should not occur */
9330331Sminshall 	    quit();
9430331Sminshall 	}
9531245Sminshall 	for (ptr = &astosc[0]; ptr <= &astosc[highestof(astosc)]; ptr++) {
9631245Sminshall 	    if (ptr->function == FCN_SPACE) {
9731245Sminshall 		spacePTR = ptr;
9831245Sminshall 	    }
9931245Sminshall 	}
10030331Sminshall     }
10130331Sminshall }
10230331Sminshall 
10330331Sminshall 
10431245Sminshall /* AddChar - put a function index in our buffer */
10530330Sminshall 
10630330Sminshall static void
10730330Sminshall AddChar(c)
10830330Sminshall int	c;
10930330Sminshall {
11030330Sminshall     if (!FullChar) {
11131245Sminshall 	*ourPTail++ = c;
11230330Sminshall     } else {
11330331Sminshall 	RingBell("Typeahead buffer full");
11430330Sminshall     }
11530330Sminshall }
11630330Sminshall 
11730330Sminshall /* FlushChar - put everything where it belongs */
11830330Sminshall 
11930330Sminshall static void
12030330Sminshall FlushChar()
12130330Sminshall {
12230330Sminshall     ourPTail = ourBuffer;
12330330Sminshall     ourPHead = ourBuffer;
12430330Sminshall }
12530330Sminshall 
12631865Sminshall void
12731865Sminshall TransInput(onoff, mode)
12831865Sminshall int	mode;			/* Which KIND of transparent input */
12931865Sminshall int	onoff;			/* Going in, or coming out */
13031865Sminshall {
13131865Sminshall     if (onoff) {
13231865Sminshall 	/* Flush pending input */
13331865Sminshall 	FlushChar();
13431865Sminshall 	TransPointer = ourBuffer;
13531865Sminshall     } else {
13631865Sminshall     }
13731865Sminshall }
13831865Sminshall 
13930330Sminshall int
14030330Sminshall TerminalIn()
14130330Sminshall {
14230330Sminshall     /* send data from us to next link in stream */
14331245Sminshall     int work = 0;
14431245Sminshall     register struct astosc *ptr;
14530330Sminshall 
14631245Sminshall     while (!EmptyChar) {			/* send up the link */
14731446Sminshall 	if (*ourPHead == ' ') {
14831446Sminshall 	    ptr = spacePTR;
14931446Sminshall 	} else {
15031446Sminshall 	    ptr = &astosc[*ourPHead];
15131446Sminshall 	}
15231245Sminshall 	if (AcceptKeystroke(ptr->scancode, ptr->shiftstate) == 1) {
15331245Sminshall 	    ourPHead++;
15431245Sminshall 	    work = 1;
15531446Sminshall 	} else {
15631446Sminshall 	    break;
15730330Sminshall 	}
15830330Sminshall     }
15931446Sminshall 
16031245Sminshall     if (EmptyChar) {
16131245Sminshall 	FlushChar();
16231245Sminshall     }
16330330Sminshall 	/* return value answers question: "did we do anything useful?" */
16431245Sminshall     return work;
16530330Sminshall }
16630330Sminshall 
16730330Sminshall int
16830330Sminshall DataFromTerminal(buffer, count)
16930330Sminshall register char	*buffer;		/* the data read in */
17030330Sminshall register int	count;			/* how many bytes in this buffer */
17130330Sminshall {
17230330Sminshall     register state *regControlPointer;
17330330Sminshall     register char c;
17430330Sminshall     register int result;
17530330Sminshall     int origCount;
17630331Sminshall     extern int bellwinup;
17730330Sminshall     static state *controlPointer;
17830330Sminshall 
17931865Sminshall     if (TransPointer) {
18031865Sminshall 	int i;
18131865Sminshall 
18231865Sminshall 	if ((count+TransPointer) >= (ourBuffer+sizeof ourBuffer)) {
18331865Sminshall 	    i = ourBuffer+sizeof ourBuffer-TransPointer;
18431865Sminshall 	} else {
18531865Sminshall 	    i = count;
18631865Sminshall 	}
18731865Sminshall 	while (i--) {
18831966Sminshall 	    c = (*buffer++)&0x7f;
18931865Sminshall 	    *TransPointer++ = c|0x80;
19031865Sminshall 	    if (c == '\r') {
19131865Sminshall 		SendTransparent(ourBuffer, TransPointer-ourBuffer);
19231865Sminshall 		TransPointer = 0;		/* Done */
19331865Sminshall 		break;
19431865Sminshall 	    }
19531865Sminshall 	}
19631865Sminshall 	return count;
19731865Sminshall     }
19831865Sminshall 
19930331Sminshall     if (bellwinup) {
20030331Sminshall 	BellOff();
20130330Sminshall     }
20230330Sminshall 
20330330Sminshall     origCount = count;
20430330Sminshall 
20530330Sminshall     while (count) {
20630330Sminshall 	c = *buffer++&0x7f;
20730330Sminshall 	count--;
20830330Sminshall 
20930330Sminshall 	if (!InControl && !IsControl(c)) {
21030330Sminshall 	    AddChar(c);			/* add ascii character */
21130330Sminshall 	} else {
21230330Sminshall 	    if (!InControl) {		/* first character of sequence */
21330330Sminshall 		InControl = 1;
21430330Sminshall 		controlPointer = headOfControl;
21530330Sminshall 	    }
21630330Sminshall 	    /* control pointer points to current position in state table */
21730330Sminshall 	    for (regControlPointer = controlPointer; ;
21830330Sminshall 			regControlPointer = NextState(regControlPointer)) {
21930330Sminshall 		if (!regControlPointer) {	/* ran off end */
22030331Sminshall 		    RingBell("Invalid control sequence");
22130330Sminshall 		    regControlPointer = headOfControl;
22230330Sminshall 		    InControl = 0;
22331447Sminshall 		    count = 0;		/* Flush current input */
22431550Sminshall 		    break;
22530330Sminshall 		}
22630330Sminshall 		if ((regControlPointer->match == c) /* hit this character */
22730330Sminshall 			|| (regControlPointer->match == MATCH_ANY)) {
22830330Sminshall 		    result = regControlPointer->result;
22931245Sminshall 		    if (result == STATE_GOTO) {
23030330Sminshall 			regControlPointer = regControlPointer->address;
23130330Sminshall 			break;			/* go to next character */
23230330Sminshall 		    }
23330330Sminshall 		    if (WaitingForSynch) {
23431245Sminshall 			if (astosc[result].function == FCN_SYNCH) {
23530330Sminshall 			    WaitingForSynch = 0;
23630330Sminshall 			} else {
23730331Sminshall 			    RingBell("Need to type synch character");
23830330Sminshall 			}
23930330Sminshall 		    }
24031245Sminshall 		    else if (astosc[result].function == FCN_FLINP) {
24130330Sminshall 			FlushChar();		/* Don't add FLINP */
24230330Sminshall 		    } else {
24331245Sminshall 			if (astosc[result].function == FCN_MASTER_RESET) {
24430330Sminshall 			    FlushChar();
24530330Sminshall 			}
24630330Sminshall 			AddChar(result);		/* add this code */
24730330Sminshall 		    }
24830330Sminshall 		    InControl = 0;	/* out of control now */
24930330Sminshall 		    break;
25030330Sminshall 		}
25130330Sminshall 	    }
25230330Sminshall 	    controlPointer = regControlPointer;		/* save state */
25330330Sminshall 	}
25430330Sminshall     }
25530330Sminshall     (void) TerminalIn();			/* try to send data */
25630330Sminshall     return(origCount-count);
25730330Sminshall }
258