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