1*48755Sbostic /*- 2*48755Sbostic * Copyright (c) 1988 The Regents of the University of California. 333817Sbostic * All rights reserved. 430330Sminshall * 5*48755Sbostic * %sccs.include.redist.c% 630330Sminshall */ 730330Sminshall 833817Sbostic #ifndef lint 9*48755Sbostic static char sccsid[] = "@(#)termin.c 4.2 (Berkeley) 04/26/91"; 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 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 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 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 11330330Sminshall FlushChar() 11430330Sminshall { 11530330Sminshall ourPTail = ourBuffer; 11630330Sminshall ourPHead = ourBuffer; 11730330Sminshall } 11830330Sminshall 11935419Sminshall /*ARGSUSED*/ 12031865Sminshall void 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 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 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