130330Sminshall /* 230330Sminshall * Copyright (c) 1984, 1985, 1986 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 2330330Sminshall static char sccsid[] = "@(#)termin.c 3.1 10/29/86"; 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 40*31870Sminshall #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--) { 19731865Sminshall 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