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