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 33*31176Sminshall #include "../general/general.h" 3430330Sminshall #include "m4.out" /* output of termcodes.m4 */ 3530330Sminshall #include "state.h" 3630330Sminshall 37*31176Sminshall #include "../general/globals.h" 3830331Sminshall #include "../ctlr/function.h" 3930331Sminshall #include "../ctlr/inbound.ext" 4030331Sminshall #include "../ctlr/outbound.ext" 4130331Sminshall #include "../telnet.ext" 4230330Sminshall #include "termin.ext" 4330330Sminshall 4430330Sminshall #define IsControl(c) (!isprint(c) || (isspace(c) && ((c) != ' '))) 4530330Sminshall 4630330Sminshall #define NextState(x) (x->next) 4730330Sminshall 4830330Sminshall /* XXX temporary - hard code in the state table */ 4930330Sminshall 5030330Sminshall #define MATCH_ANY 0xff /* actually, match any character */ 5130330Sminshall 5230331Sminshall #include "astosc.out" 5330330Sminshall 5430330Sminshall static 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 6230330Sminshall static state 6330330Sminshall *headOfControl = 0; /* where we enter code state table */ 6430330Sminshall 6530331Sminshall #define FullChar ((ourPTail+5) >= ourBuffer+sizeof ourBuffer) 6630330Sminshall #define EmptyChar (ourPTail == ourPHead) 6730330Sminshall 6830330Sminshall 6930331Sminshall /* 7030725Sminshall * init_keyboard() 7130725Sminshall * 7230725Sminshall * Initialize the keyboard variables. 7330725Sminshall */ 7430725Sminshall 7530725Sminshall void 7630725Sminshall init_keyboard() 7730725Sminshall { 7830725Sminshall ourPHead = ourPTail = ourBuffer; 7930725Sminshall InControl = 0; 8030725Sminshall WaitingForSynch = 0; 8130725Sminshall } 8230725Sminshall 8330725Sminshall 8430725Sminshall /* 8530331Sminshall * Initialize the keyboard mapping file. 8630331Sminshall */ 8730331Sminshall 8830331Sminshall void 8930331Sminshall InitMapping() 9030331Sminshall { 9130331Sminshall extern state *InitControl(); 9230331Sminshall 9330331Sminshall if (!headOfControl) { 9430331Sminshall /* need to initialize */ 9530331Sminshall headOfControl = InitControl((char *)0, 0); 9630331Sminshall if (!headOfControl) { /* should not occur */ 9730331Sminshall quit(); 9830331Sminshall } 9930331Sminshall } 10030331Sminshall } 10130331Sminshall 10230331Sminshall 10330330Sminshall /* AddChar - put a character in our buffer */ 10430330Sminshall 10530330Sminshall static void 10630330Sminshall AddChar(c) 10730330Sminshall int c; 10830330Sminshall { 10930330Sminshall if (!FullChar) { 11030331Sminshall if ((c >= numberof(asctosc)) || (c < 0)) { 11130331Sminshall ExitString(stderr, 11230331Sminshall "Unable to locate function in termout.c, AddChar()\n", 1); 11330331Sminshall /*NOTREACHED*/ 11430331Sminshall } else { 11530331Sminshall switch (asctosc[c].shift) { 11630331Sminshall case cantdo: 11730331Sminshall if (c == ' ') { 11830331Sminshall *ourPTail++ = asctosc[TC_SPACE].scancode; 11930331Sminshall } else { 12030331Sminshall RingBell("Keyboard not capable of function."); 12130331Sminshall } 12230331Sminshall break; 12330331Sminshall case normal: 12430331Sminshall *ourPTail++ = asctosc[c].scancode; 12530331Sminshall break; 12630331Sminshall case shifted: 12730331Sminshall *ourPTail++ = asctosc[TC_MAKE_SHIFT].scancode; 12830331Sminshall *ourPTail++ = asctosc[c].scancode; 12930331Sminshall *ourPTail++ = asctosc[TC_BREAK_SHIFT].scancode; 13030331Sminshall break; 13130331Sminshall case alted: 13230331Sminshall *ourPTail++ = asctosc[TC_MAKE_ALT].scancode; 13330331Sminshall *ourPTail++ = asctosc[c].scancode; 13430331Sminshall *ourPTail++ = asctosc[TC_BREAK_ALT].scancode; 13530331Sminshall break; 13630331Sminshall case shiftalted: 13730331Sminshall *ourPTail++ = asctosc[TC_MAKE_SHIFT].scancode; 13830331Sminshall *ourPTail++ = asctosc[TC_MAKE_ALT].scancode; 13930331Sminshall *ourPTail++ = asctosc[c].scancode; 14030331Sminshall *ourPTail++ = asctosc[TC_BREAK_ALT].scancode; 14130331Sminshall *ourPTail++ = asctosc[TC_BREAK_SHIFT].scancode; 14230331Sminshall break; 14330331Sminshall default: 14430331Sminshall ExitString(stderr, 14530331Sminshall "Illegal 'shift' to AddChar() in termin.c\n", 1); 14630331Sminshall } 14730331Sminshall } 14830330Sminshall } else { 14930331Sminshall RingBell("Typeahead buffer full"); 15030330Sminshall } 15130330Sminshall } 15230330Sminshall 15330330Sminshall /* FlushChar - put everything where it belongs */ 15430330Sminshall 15530330Sminshall static void 15630330Sminshall FlushChar() 15730330Sminshall { 15830330Sminshall ourPTail = ourBuffer; 15930330Sminshall ourPHead = ourBuffer; 16030330Sminshall } 16130330Sminshall 16230330Sminshall int 16330330Sminshall TerminalIn() 16430330Sminshall { 16530330Sminshall /* send data from us to next link in stream */ 16630330Sminshall int count; 16730330Sminshall 16830330Sminshall count = 0; 16930330Sminshall 17030330Sminshall if (!EmptyChar) { /* send up the link */ 17130330Sminshall count += DataFrom3270(ourPHead, ourPTail-ourPHead); 17230330Sminshall ourPHead += count; 17330330Sminshall if (EmptyChar) { 17430330Sminshall FlushChar(); 17530330Sminshall } 17630330Sminshall } 17730330Sminshall /* return value answers question: "did we do anything useful?" */ 17830330Sminshall return(count? 1:0); 17930330Sminshall } 18030330Sminshall 18130330Sminshall int 18230330Sminshall DataFromTerminal(buffer, count) 18330330Sminshall register char *buffer; /* the data read in */ 18430330Sminshall register int count; /* how many bytes in this buffer */ 18530330Sminshall { 18630330Sminshall register state *regControlPointer; 18730330Sminshall register char c; 18830330Sminshall register int result; 18930330Sminshall int origCount; 19030331Sminshall extern int bellwinup; 19130330Sminshall static state *controlPointer; 19230330Sminshall 19330331Sminshall if (bellwinup) { 19430331Sminshall BellOff(); 19530330Sminshall } 19630330Sminshall 19730330Sminshall origCount = count; 19830330Sminshall 19930330Sminshall while (count) { 20030330Sminshall c = *buffer++&0x7f; 20130330Sminshall count--; 20230330Sminshall 20330330Sminshall if (!InControl && !IsControl(c)) { 20430330Sminshall AddChar(c); /* add ascii character */ 20530330Sminshall } else { 20630330Sminshall if (!InControl) { /* first character of sequence */ 20730330Sminshall InControl = 1; 20830330Sminshall controlPointer = headOfControl; 20930330Sminshall } 21030330Sminshall /* control pointer points to current position in state table */ 21130330Sminshall for (regControlPointer = controlPointer; ; 21230330Sminshall regControlPointer = NextState(regControlPointer)) { 21330330Sminshall if (!regControlPointer) { /* ran off end */ 21430331Sminshall RingBell("Invalid control sequence"); 21530330Sminshall regControlPointer = headOfControl; 21630330Sminshall InControl = 0; 21730330Sminshall break; 21830330Sminshall } 21930330Sminshall if ((regControlPointer->match == c) /* hit this character */ 22030330Sminshall || (regControlPointer->match == MATCH_ANY)) { 22130330Sminshall result = regControlPointer->result; 22230330Sminshall if (result == TC_GOTO) { 22330330Sminshall regControlPointer = regControlPointer->address; 22430330Sminshall break; /* go to next character */ 22530330Sminshall } 22630330Sminshall if (WaitingForSynch) { 22730330Sminshall if (result == TC_SYNCH) { 22830330Sminshall WaitingForSynch = 0; 22930330Sminshall } else { 23030331Sminshall RingBell("Need to type synch character"); 23130330Sminshall } 23230330Sminshall } 23330330Sminshall else if (result == TC_FLINP) { 23430330Sminshall FlushChar(); /* Don't add FLINP */ 23530330Sminshall } else { 23630330Sminshall if (result == TC_MASTER_RESET) { 23730330Sminshall FlushChar(); 23830330Sminshall } 23930330Sminshall AddChar(result); /* add this code */ 24030330Sminshall } 24130330Sminshall InControl = 0; /* out of control now */ 24230330Sminshall break; 24330330Sminshall } 24430330Sminshall } 24530330Sminshall controlPointer = regControlPointer; /* save state */ 24630330Sminshall } 24730330Sminshall } 24830330Sminshall (void) TerminalIn(); /* try to send data */ 24930330Sminshall return(origCount-count); 25030330Sminshall } 251