xref: /csrg-svn/usr.bin/tn3270/ascii/termin.c (revision 35419)
130330Sminshall /*
233817Sbostic  * Copyright (c) 1988 Regents of the University of California.
333817Sbostic  * All rights reserved.
430330Sminshall  *
533817Sbostic  * Redistribution and use in source and binary forms are permitted
6*35419Sminshall  * provided that the above copyright notice and this paragraph are
7*35419Sminshall  * duplicated in all such forms and that any documentation,
8*35419Sminshall  * advertising materials, and other materials related to such
9*35419Sminshall  * distribution and use acknowledge that the software was developed
10*35419Sminshall  * by the University of California, Berkeley.  The name of the
11*35419Sminshall  * University may not be used to endorse or promote products derived
12*35419Sminshall  * from this software without specific prior written permission.
13*35419Sminshall  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*35419Sminshall  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*35419Sminshall  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1630330Sminshall  */
1730330Sminshall 
1833817Sbostic #ifndef lint
19*35419Sminshall static char sccsid[] = "@(#)termin.c	3.3 (Berkeley) 08/28/88";
2033817Sbostic #endif /* not lint */
2130330Sminshall 
2230330Sminshall /* this takes characters from the keyboard, and produces 3270 keystroke
2330330Sminshall 	codes
2430330Sminshall  */
2530330Sminshall 
2630331Sminshall #include <stdio.h>
2730330Sminshall #include <ctype.h>
2830330Sminshall 
2931176Sminshall #include "../general/general.h"
3030331Sminshall #include "../ctlr/function.h"
31*35419Sminshall #include "../ctlr/externs.h"
32*35419Sminshall #include "../ctlr/declare.h"
3330330Sminshall 
3431870Sminshall #include "../api/astosc.h"
3531245Sminshall #include "state.h"
3631245Sminshall 
3731245Sminshall #include "../general/globals.h"
3831245Sminshall 
3930330Sminshall #define IsControl(c)	(!isprint(c) || (isspace(c) && ((c) != ' ')))
4030330Sminshall 
4130330Sminshall #define NextState(x)	(x->next)
4230330Sminshall 
4330330Sminshall /* XXX temporary - hard code in the state table */
4430330Sminshall 
4530330Sminshall #define MATCH_ANY 0xff			/* actually, match any character */
4630330Sminshall 
4730330Sminshall 
4831245Sminshall static unsigned char
4930330Sminshall 	ourBuffer[100],		/* where we store stuff */
5030330Sminshall 	*ourPHead = ourBuffer,	/* first character in buffer */
5131865Sminshall 	*ourPTail = ourBuffer,	/* where next character goes */
5231865Sminshall 	*TransPointer = 0;	/* For transparent mode data */
5330330Sminshall 
5430331Sminshall static int InControl;
5530331Sminshall static int WaitingForSynch;
5630331Sminshall 
5731245Sminshall static struct astosc
5831245Sminshall 	*spacePTR = 0;		/* Space is hard to enter */
5931245Sminshall 
6030330Sminshall static state
6130330Sminshall 	*headOfControl = 0;	/* where we enter code state table */
6230330Sminshall 
6330331Sminshall #define FullChar	((ourPTail+5) >= ourBuffer+sizeof ourBuffer)
6430330Sminshall #define EmptyChar	(ourPTail == ourPHead)
6530330Sminshall 
6630330Sminshall 
6730331Sminshall /*
6830725Sminshall  * init_keyboard()
6930725Sminshall  *
7030725Sminshall  * Initialize the keyboard variables.
7130725Sminshall  */
7230725Sminshall 
7330725Sminshall void
7430725Sminshall init_keyboard()
7530725Sminshall {
7630725Sminshall     ourPHead = ourPTail = ourBuffer;
7730725Sminshall     InControl = 0;
7830725Sminshall     WaitingForSynch = 0;
7930725Sminshall }
8030725Sminshall 
8130725Sminshall 
8230725Sminshall /*
8330331Sminshall  * Initialize the keyboard mapping file.
8430331Sminshall  */
8530331Sminshall 
8630331Sminshall void
8730331Sminshall InitMapping()
8830331Sminshall {
8930331Sminshall     extern state *InitControl();
9031245Sminshall     register struct astosc *ptr;
9130331Sminshall 
9230331Sminshall     if (!headOfControl) {
9330331Sminshall 	/* need to initialize */
9431245Sminshall 	headOfControl = InitControl((char *)0, 0, ascii_to_index);
9530331Sminshall 	if (!headOfControl) {		/* should not occur */
9630331Sminshall 	    quit();
9730331Sminshall 	}
9831245Sminshall 	for (ptr = &astosc[0]; ptr <= &astosc[highestof(astosc)]; ptr++) {
9931245Sminshall 	    if (ptr->function == FCN_SPACE) {
10031245Sminshall 		spacePTR = ptr;
10131245Sminshall 	    }
10231245Sminshall 	}
10330331Sminshall     }
10430331Sminshall }
10530331Sminshall 
10630331Sminshall 
10731245Sminshall /* AddChar - put a function index in our buffer */
10830330Sminshall 
10930330Sminshall static void
11030330Sminshall AddChar(c)
11130330Sminshall int	c;
11230330Sminshall {
11330330Sminshall     if (!FullChar) {
11431245Sminshall 	*ourPTail++ = c;
11530330Sminshall     } else {
11630331Sminshall 	RingBell("Typeahead buffer full");
11730330Sminshall     }
11830330Sminshall }
11930330Sminshall 
12030330Sminshall /* FlushChar - put everything where it belongs */
12130330Sminshall 
12230330Sminshall static void
12330330Sminshall FlushChar()
12430330Sminshall {
12530330Sminshall     ourPTail = ourBuffer;
12630330Sminshall     ourPHead = ourBuffer;
12730330Sminshall }
12830330Sminshall 
129*35419Sminshall /*ARGSUSED*/
13031865Sminshall void
13131865Sminshall TransInput(onoff, mode)
13231865Sminshall int	mode;			/* Which KIND of transparent input */
13331865Sminshall int	onoff;			/* Going in, or coming out */
13431865Sminshall {
13531865Sminshall     if (onoff) {
13631865Sminshall 	/* Flush pending input */
13731865Sminshall 	FlushChar();
13831865Sminshall 	TransPointer = ourBuffer;
13931865Sminshall     } else {
14031865Sminshall     }
14131865Sminshall }
14231865Sminshall 
14330330Sminshall int
14430330Sminshall TerminalIn()
14530330Sminshall {
14630330Sminshall     /* send data from us to next link in stream */
14731245Sminshall     int work = 0;
14831245Sminshall     register struct astosc *ptr;
14930330Sminshall 
15031245Sminshall     while (!EmptyChar) {			/* send up the link */
15131446Sminshall 	if (*ourPHead == ' ') {
15231446Sminshall 	    ptr = spacePTR;
15331446Sminshall 	} else {
15431446Sminshall 	    ptr = &astosc[*ourPHead];
15531446Sminshall 	}
15631245Sminshall 	if (AcceptKeystroke(ptr->scancode, ptr->shiftstate) == 1) {
15731245Sminshall 	    ourPHead++;
15831245Sminshall 	    work = 1;
15931446Sminshall 	} else {
16031446Sminshall 	    break;
16130330Sminshall 	}
16230330Sminshall     }
16331446Sminshall 
16431245Sminshall     if (EmptyChar) {
16531245Sminshall 	FlushChar();
16631245Sminshall     }
16730330Sminshall 	/* return value answers question: "did we do anything useful?" */
16831245Sminshall     return work;
16930330Sminshall }
17030330Sminshall 
17130330Sminshall int
17230330Sminshall DataFromTerminal(buffer, count)
17330330Sminshall register char	*buffer;		/* the data read in */
17430330Sminshall register int	count;			/* how many bytes in this buffer */
17530330Sminshall {
17630330Sminshall     register state *regControlPointer;
17730330Sminshall     register char c;
17830330Sminshall     register int result;
17930330Sminshall     int origCount;
18030331Sminshall     extern int bellwinup;
18130330Sminshall     static state *controlPointer;
18230330Sminshall 
18331865Sminshall     if (TransPointer) {
18431865Sminshall 	int i;
18531865Sminshall 
18631865Sminshall 	if ((count+TransPointer) >= (ourBuffer+sizeof ourBuffer)) {
18731865Sminshall 	    i = ourBuffer+sizeof ourBuffer-TransPointer;
18831865Sminshall 	} else {
18931865Sminshall 	    i = count;
19031865Sminshall 	}
19131865Sminshall 	while (i--) {
19231966Sminshall 	    c = (*buffer++)&0x7f;
19331865Sminshall 	    *TransPointer++ = c|0x80;
19431865Sminshall 	    if (c == '\r') {
195*35419Sminshall 		SendTransparent((char *)ourBuffer, TransPointer-ourBuffer);
19631865Sminshall 		TransPointer = 0;		/* Done */
19731865Sminshall 		break;
19831865Sminshall 	    }
19931865Sminshall 	}
20031865Sminshall 	return count;
20131865Sminshall     }
20231865Sminshall 
20330331Sminshall     if (bellwinup) {
204*35419Sminshall 	void BellOff();
205*35419Sminshall 
20630331Sminshall 	BellOff();
20730330Sminshall     }
20830330Sminshall 
20930330Sminshall     origCount = count;
21030330Sminshall 
21130330Sminshall     while (count) {
21230330Sminshall 	c = *buffer++&0x7f;
21330330Sminshall 	count--;
21430330Sminshall 
21530330Sminshall 	if (!InControl && !IsControl(c)) {
21630330Sminshall 	    AddChar(c);			/* add ascii character */
21730330Sminshall 	} else {
21830330Sminshall 	    if (!InControl) {		/* first character of sequence */
21930330Sminshall 		InControl = 1;
22030330Sminshall 		controlPointer = headOfControl;
22130330Sminshall 	    }
22230330Sminshall 	    /* control pointer points to current position in state table */
22330330Sminshall 	    for (regControlPointer = controlPointer; ;
22430330Sminshall 			regControlPointer = NextState(regControlPointer)) {
22530330Sminshall 		if (!regControlPointer) {	/* ran off end */
22630331Sminshall 		    RingBell("Invalid control sequence");
22730330Sminshall 		    regControlPointer = headOfControl;
22830330Sminshall 		    InControl = 0;
22931447Sminshall 		    count = 0;		/* Flush current input */
23031550Sminshall 		    break;
23130330Sminshall 		}
23230330Sminshall 		if ((regControlPointer->match == c) /* hit this character */
23330330Sminshall 			|| (regControlPointer->match == MATCH_ANY)) {
23430330Sminshall 		    result = regControlPointer->result;
23531245Sminshall 		    if (result == STATE_GOTO) {
23630330Sminshall 			regControlPointer = regControlPointer->address;
23730330Sminshall 			break;			/* go to next character */
23830330Sminshall 		    }
23930330Sminshall 		    if (WaitingForSynch) {
24031245Sminshall 			if (astosc[result].function == FCN_SYNCH) {
24130330Sminshall 			    WaitingForSynch = 0;
24230330Sminshall 			} else {
243*35419Sminshall 			    void RingBell();
244*35419Sminshall 
24530331Sminshall 			    RingBell("Need to type synch character");
24630330Sminshall 			}
24730330Sminshall 		    }
24831245Sminshall 		    else if (astosc[result].function == FCN_FLINP) {
24930330Sminshall 			FlushChar();		/* Don't add FLINP */
25030330Sminshall 		    } else {
25131245Sminshall 			if (astosc[result].function == FCN_MASTER_RESET) {
25230330Sminshall 			    FlushChar();
25330330Sminshall 			}
25430330Sminshall 			AddChar(result);		/* add this code */
25530330Sminshall 		    }
25630330Sminshall 		    InControl = 0;	/* out of control now */
25730330Sminshall 		    break;
25830330Sminshall 		}
25930330Sminshall 	    }
26030330Sminshall 	    controlPointer = regControlPointer;		/* save state */
26130330Sminshall 	}
26230330Sminshall     }
26330330Sminshall     (void) TerminalIn();			/* try to send data */
26430330Sminshall     return(origCount-count);
26530330Sminshall }
266