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 4031245Sminshall #include "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 */ 5730330Sminshall *ourPTail = ourBuffer; /* where next character goes */ 5830330Sminshall 5930331Sminshall static int InControl; 6030331Sminshall static int WaitingForSynch; 6130331Sminshall 6231245Sminshall static struct astosc 6331245Sminshall *spacePTR = 0; /* Space is hard to enter */ 6431245Sminshall 6530330Sminshall static state 6630330Sminshall *headOfControl = 0; /* where we enter code state table */ 6730330Sminshall 6830331Sminshall #define FullChar ((ourPTail+5) >= ourBuffer+sizeof ourBuffer) 6930330Sminshall #define EmptyChar (ourPTail == ourPHead) 7030330Sminshall 7130330Sminshall 7230331Sminshall /* 7330725Sminshall * init_keyboard() 7430725Sminshall * 7530725Sminshall * Initialize the keyboard variables. 7630725Sminshall */ 7730725Sminshall 7830725Sminshall void 7930725Sminshall init_keyboard() 8030725Sminshall { 8130725Sminshall ourPHead = ourPTail = ourBuffer; 8230725Sminshall InControl = 0; 8330725Sminshall WaitingForSynch = 0; 8430725Sminshall } 8530725Sminshall 8630725Sminshall 8730725Sminshall /* 8830331Sminshall * Initialize the keyboard mapping file. 8930331Sminshall */ 9030331Sminshall 9130331Sminshall void 9230331Sminshall InitMapping() 9330331Sminshall { 9430331Sminshall extern state *InitControl(); 9531245Sminshall register struct astosc *ptr; 9630331Sminshall 9730331Sminshall if (!headOfControl) { 9830331Sminshall /* need to initialize */ 9931245Sminshall headOfControl = InitControl((char *)0, 0, ascii_to_index); 10030331Sminshall if (!headOfControl) { /* should not occur */ 10130331Sminshall quit(); 10230331Sminshall } 10331245Sminshall for (ptr = &astosc[0]; ptr <= &astosc[highestof(astosc)]; ptr++) { 10431245Sminshall if (ptr->function == FCN_SPACE) { 10531245Sminshall spacePTR = ptr; 10631245Sminshall } 10731245Sminshall } 10830331Sminshall } 10930331Sminshall } 11030331Sminshall 11130331Sminshall 11231245Sminshall /* AddChar - put a function index in our buffer */ 11330330Sminshall 11430330Sminshall static void 11530330Sminshall AddChar(c) 11630330Sminshall int c; 11730330Sminshall { 11830330Sminshall if (!FullChar) { 11931245Sminshall *ourPTail++ = c; 12030330Sminshall } else { 12130331Sminshall RingBell("Typeahead buffer full"); 12230330Sminshall } 12330330Sminshall } 12430330Sminshall 12530330Sminshall /* FlushChar - put everything where it belongs */ 12630330Sminshall 12730330Sminshall static void 12830330Sminshall FlushChar() 12930330Sminshall { 13030330Sminshall ourPTail = ourBuffer; 13130330Sminshall ourPHead = ourBuffer; 13230330Sminshall } 13330330Sminshall 13430330Sminshall int 13530330Sminshall TerminalIn() 13630330Sminshall { 13730330Sminshall /* send data from us to next link in stream */ 13831245Sminshall int work = 0; 13931245Sminshall register struct astosc *ptr; 14030330Sminshall 14131245Sminshall while (!EmptyChar) { /* send up the link */ 142*31446Sminshall if (*ourPHead == ' ') { 143*31446Sminshall ptr = spacePTR; 144*31446Sminshall } else { 145*31446Sminshall ptr = &astosc[*ourPHead]; 146*31446Sminshall } 14731245Sminshall if (AcceptKeystroke(ptr->scancode, ptr->shiftstate) == 1) { 14831245Sminshall ourPHead++; 14931245Sminshall work = 1; 150*31446Sminshall } else { 151*31446Sminshall break; 15230330Sminshall } 15330330Sminshall } 154*31446Sminshall 15531245Sminshall if (EmptyChar) { 15631245Sminshall FlushChar(); 15731245Sminshall } 15830330Sminshall /* return value answers question: "did we do anything useful?" */ 15931245Sminshall return work; 16030330Sminshall } 16130330Sminshall 16230330Sminshall int 16330330Sminshall DataFromTerminal(buffer, count) 16430330Sminshall register char *buffer; /* the data read in */ 16530330Sminshall register int count; /* how many bytes in this buffer */ 16630330Sminshall { 16730330Sminshall register state *regControlPointer; 16830330Sminshall register char c; 16930330Sminshall register int result; 17030330Sminshall int origCount; 17130331Sminshall extern int bellwinup; 17230330Sminshall static state *controlPointer; 17330330Sminshall 17430331Sminshall if (bellwinup) { 17530331Sminshall BellOff(); 17630330Sminshall } 17730330Sminshall 17830330Sminshall origCount = count; 17930330Sminshall 18030330Sminshall while (count) { 18130330Sminshall c = *buffer++&0x7f; 18230330Sminshall count--; 18330330Sminshall 18430330Sminshall if (!InControl && !IsControl(c)) { 18530330Sminshall AddChar(c); /* add ascii character */ 18630330Sminshall } else { 18730330Sminshall if (!InControl) { /* first character of sequence */ 18830330Sminshall InControl = 1; 18930330Sminshall controlPointer = headOfControl; 19030330Sminshall } 19130330Sminshall /* control pointer points to current position in state table */ 19230330Sminshall for (regControlPointer = controlPointer; ; 19330330Sminshall regControlPointer = NextState(regControlPointer)) { 19430330Sminshall if (!regControlPointer) { /* ran off end */ 19530331Sminshall RingBell("Invalid control sequence"); 19630330Sminshall regControlPointer = headOfControl; 19730330Sminshall InControl = 0; 19830330Sminshall break; 19930330Sminshall } 20030330Sminshall if ((regControlPointer->match == c) /* hit this character */ 20130330Sminshall || (regControlPointer->match == MATCH_ANY)) { 20230330Sminshall result = regControlPointer->result; 20331245Sminshall if (result == STATE_GOTO) { 20430330Sminshall regControlPointer = regControlPointer->address; 20530330Sminshall break; /* go to next character */ 20630330Sminshall } 20730330Sminshall if (WaitingForSynch) { 20831245Sminshall if (astosc[result].function == FCN_SYNCH) { 20930330Sminshall WaitingForSynch = 0; 21030330Sminshall } else { 21130331Sminshall RingBell("Need to type synch character"); 21230330Sminshall } 21330330Sminshall } 21431245Sminshall else if (astosc[result].function == FCN_FLINP) { 21530330Sminshall FlushChar(); /* Don't add FLINP */ 21630330Sminshall } else { 21731245Sminshall if (astosc[result].function == FCN_MASTER_RESET) { 21830330Sminshall FlushChar(); 21930330Sminshall } 22030330Sminshall AddChar(result); /* add this code */ 22130330Sminshall } 22230330Sminshall InControl = 0; /* out of control now */ 22330330Sminshall break; 22430330Sminshall } 22530330Sminshall } 22630330Sminshall controlPointer = regControlPointer; /* save state */ 22730330Sminshall } 22830330Sminshall } 22930330Sminshall (void) TerminalIn(); /* try to send data */ 23030330Sminshall return(origCount-count); 23130330Sminshall } 232