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 30*30331Sminshall #include <stdio.h> 3130330Sminshall #include <ctype.h> 3230330Sminshall 33*30331Sminshall #include "../general.h" 3430330Sminshall #include "m4.out" /* output of termcodes.m4 */ 3530330Sminshall #include "state.h" 3630330Sminshall 37*30331Sminshall #include "../system/globals.h" 38*30331Sminshall #include "../ctlr/function.h" 39*30331Sminshall #include "../ctlr/inbound.ext" 40*30331Sminshall #include "../ctlr/outbound.ext" 41*30331Sminshall #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 52*30331Sminshall #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 59*30331Sminshall static int InControl; 60*30331Sminshall static int WaitingForSynch; 61*30331Sminshall 6230330Sminshall static state 6330330Sminshall *headOfControl = 0; /* where we enter code state table */ 6430330Sminshall 65*30331Sminshall #define FullChar ((ourPTail+5) >= ourBuffer+sizeof ourBuffer) 6630330Sminshall #define EmptyChar (ourPTail == ourPHead) 6730330Sminshall 6830330Sminshall 69*30331Sminshall /* 70*30331Sminshall * Initialize the keyboard mapping file. 71*30331Sminshall */ 72*30331Sminshall 73*30331Sminshall void 74*30331Sminshall InitMapping() 75*30331Sminshall { 76*30331Sminshall extern state *InitControl(); 77*30331Sminshall 78*30331Sminshall if (!headOfControl) { 79*30331Sminshall /* need to initialize */ 80*30331Sminshall headOfControl = InitControl((char *)0, 0); 81*30331Sminshall if (!headOfControl) { /* should not occur */ 82*30331Sminshall quit(); 83*30331Sminshall } 84*30331Sminshall } 85*30331Sminshall } 86*30331Sminshall 87*30331Sminshall 8830330Sminshall /* AddChar - put a character in our buffer */ 8930330Sminshall 9030330Sminshall static void 9130330Sminshall AddChar(c) 9230330Sminshall int c; 9330330Sminshall { 9430330Sminshall if (!FullChar) { 95*30331Sminshall if ((c >= numberof(asctosc)) || (c < 0)) { 96*30331Sminshall ExitString(stderr, 97*30331Sminshall "Unable to locate function in termout.c, AddChar()\n", 1); 98*30331Sminshall /*NOTREACHED*/ 99*30331Sminshall } else { 100*30331Sminshall switch (asctosc[c].shift) { 101*30331Sminshall case cantdo: 102*30331Sminshall if (c == ' ') { 103*30331Sminshall *ourPTail++ = asctosc[TC_SPACE].scancode; 104*30331Sminshall } else { 105*30331Sminshall RingBell("Keyboard not capable of function."); 106*30331Sminshall } 107*30331Sminshall break; 108*30331Sminshall case normal: 109*30331Sminshall *ourPTail++ = asctosc[c].scancode; 110*30331Sminshall break; 111*30331Sminshall case shifted: 112*30331Sminshall *ourPTail++ = asctosc[TC_MAKE_SHIFT].scancode; 113*30331Sminshall *ourPTail++ = asctosc[c].scancode; 114*30331Sminshall *ourPTail++ = asctosc[TC_BREAK_SHIFT].scancode; 115*30331Sminshall break; 116*30331Sminshall case alted: 117*30331Sminshall *ourPTail++ = asctosc[TC_MAKE_ALT].scancode; 118*30331Sminshall *ourPTail++ = asctosc[c].scancode; 119*30331Sminshall *ourPTail++ = asctosc[TC_BREAK_ALT].scancode; 120*30331Sminshall break; 121*30331Sminshall case shiftalted: 122*30331Sminshall *ourPTail++ = asctosc[TC_MAKE_SHIFT].scancode; 123*30331Sminshall *ourPTail++ = asctosc[TC_MAKE_ALT].scancode; 124*30331Sminshall *ourPTail++ = asctosc[c].scancode; 125*30331Sminshall *ourPTail++ = asctosc[TC_BREAK_ALT].scancode; 126*30331Sminshall *ourPTail++ = asctosc[TC_BREAK_SHIFT].scancode; 127*30331Sminshall break; 128*30331Sminshall default: 129*30331Sminshall ExitString(stderr, 130*30331Sminshall "Illegal 'shift' to AddChar() in termin.c\n", 1); 131*30331Sminshall } 132*30331Sminshall } 13330330Sminshall } else { 134*30331Sminshall RingBell("Typeahead buffer full"); 13530330Sminshall } 13630330Sminshall } 13730330Sminshall 13830330Sminshall /* FlushChar - put everything where it belongs */ 13930330Sminshall 14030330Sminshall static void 14130330Sminshall FlushChar() 14230330Sminshall { 14330330Sminshall ourPTail = ourBuffer; 14430330Sminshall ourPHead = ourBuffer; 14530330Sminshall } 14630330Sminshall 147*30331Sminshall terminit() 148*30331Sminshall { 149*30331Sminshall FlushChar(); 150*30331Sminshall InControl = WaitingForSynch = 0; 151*30331Sminshall } 15230330Sminshall 153*30331Sminshall 15430330Sminshall int 15530330Sminshall TerminalIn() 15630330Sminshall { 15730330Sminshall /* send data from us to next link in stream */ 15830330Sminshall int count; 15930330Sminshall 16030330Sminshall count = 0; 16130330Sminshall 16230330Sminshall if (!EmptyChar) { /* send up the link */ 16330330Sminshall count += DataFrom3270(ourPHead, ourPTail-ourPHead); 16430330Sminshall ourPHead += count; 16530330Sminshall if (EmptyChar) { 16630330Sminshall FlushChar(); 16730330Sminshall } 16830330Sminshall } 16930330Sminshall /* return value answers question: "did we do anything useful?" */ 17030330Sminshall return(count? 1:0); 17130330Sminshall } 17230330Sminshall 17330330Sminshall int 17430330Sminshall DataFromTerminal(buffer, count) 17530330Sminshall register char *buffer; /* the data read in */ 17630330Sminshall register int count; /* how many bytes in this buffer */ 17730330Sminshall { 17830330Sminshall register state *regControlPointer; 17930330Sminshall register char c; 18030330Sminshall register int result; 18130330Sminshall int origCount; 182*30331Sminshall extern int bellwinup; 18330330Sminshall static state *controlPointer; 18430330Sminshall 185*30331Sminshall if (bellwinup) { 186*30331Sminshall BellOff(); 18730330Sminshall } 18830330Sminshall 18930330Sminshall origCount = count; 19030330Sminshall 19130330Sminshall while (count) { 19230330Sminshall c = *buffer++&0x7f; 19330330Sminshall count--; 19430330Sminshall 19530330Sminshall if (!InControl && !IsControl(c)) { 19630330Sminshall AddChar(c); /* add ascii character */ 19730330Sminshall } else { 19830330Sminshall if (!InControl) { /* first character of sequence */ 19930330Sminshall InControl = 1; 20030330Sminshall controlPointer = headOfControl; 20130330Sminshall } 20230330Sminshall /* control pointer points to current position in state table */ 20330330Sminshall for (regControlPointer = controlPointer; ; 20430330Sminshall regControlPointer = NextState(regControlPointer)) { 20530330Sminshall if (!regControlPointer) { /* ran off end */ 206*30331Sminshall RingBell("Invalid control sequence"); 20730330Sminshall regControlPointer = headOfControl; 20830330Sminshall InControl = 0; 20930330Sminshall break; 21030330Sminshall } 21130330Sminshall if ((regControlPointer->match == c) /* hit this character */ 21230330Sminshall || (regControlPointer->match == MATCH_ANY)) { 21330330Sminshall result = regControlPointer->result; 21430330Sminshall if (result == TC_GOTO) { 21530330Sminshall regControlPointer = regControlPointer->address; 21630330Sminshall break; /* go to next character */ 21730330Sminshall } 21830330Sminshall if (WaitingForSynch) { 21930330Sminshall if (result == TC_SYNCH) { 22030330Sminshall WaitingForSynch = 0; 22130330Sminshall } else { 222*30331Sminshall RingBell("Need to type synch character"); 22330330Sminshall } 22430330Sminshall } 22530330Sminshall else if (result == TC_FLINP) { 22630330Sminshall FlushChar(); /* Don't add FLINP */ 22730330Sminshall } else { 22830330Sminshall if (result == TC_MASTER_RESET) { 22930330Sminshall FlushChar(); 23030330Sminshall } 23130330Sminshall AddChar(result); /* add this code */ 23230330Sminshall } 23330330Sminshall InControl = 0; /* out of control now */ 23430330Sminshall break; 23530330Sminshall } 23630330Sminshall } 23730330Sminshall controlPointer = regControlPointer; /* save state */ 23830330Sminshall } 23930330Sminshall } 24030330Sminshall (void) TerminalIn(); /* try to send data */ 24130330Sminshall return(origCount-count); 24230330Sminshall } 243