1 /* 2 * Copyright (c) 1984, 1985, 1986 by the Regents of the 3 * University of California and by Gregory Glenn Minshall. 4 * 5 * Permission to use, copy, modify, and distribute these 6 * programs and their documentation for any purpose and 7 * without fee is hereby granted, provided that this 8 * copyright and permission appear on all copies and 9 * supporting documentation, the name of the Regents of 10 * the University of California not be used in advertising 11 * or publicity pertaining to distribution of the programs 12 * without specific prior permission, and notice be given in 13 * supporting documentation that copying and distribution is 14 * by permission of the Regents of the University of California 15 * and by Gregory Glenn Minshall. Neither the Regents of the 16 * University of California nor Gregory Glenn Minshall make 17 * representations about the suitability of this software 18 * for any purpose. It is provided "as is" without 19 * express or implied warranty. 20 */ 21 22 #ifndef lint 23 static char sccsid[] = "@(#)termin.c 3.1 10/29/86"; 24 #endif /* ndef lint */ 25 26 /* this takes characters from the keyboard, and produces 3270 keystroke 27 codes 28 */ 29 30 #include <stdio.h> 31 #include <ctype.h> 32 33 #include "../general/general.h" 34 #include "../ctlr/function.h" 35 #include "../ctlr/inbound.ext" 36 #include "../ctlr/outbound.ext" 37 #include "../telnet.ext" 38 #include "termin.ext" 39 40 #include "../apilib/astosc.h" 41 #include "state.h" 42 43 #include "../general/globals.h" 44 45 #define IsControl(c) (!isprint(c) || (isspace(c) && ((c) != ' '))) 46 47 #define NextState(x) (x->next) 48 49 /* XXX temporary - hard code in the state table */ 50 51 #define MATCH_ANY 0xff /* actually, match any character */ 52 53 54 static unsigned char 55 ourBuffer[100], /* where we store stuff */ 56 *ourPHead = ourBuffer, /* first character in buffer */ 57 *ourPTail = ourBuffer; /* where next character goes */ 58 59 static int InControl; 60 static int WaitingForSynch; 61 62 static struct astosc 63 *spacePTR = 0; /* Space is hard to enter */ 64 65 static state 66 *headOfControl = 0; /* where we enter code state table */ 67 68 #define FullChar ((ourPTail+5) >= ourBuffer+sizeof ourBuffer) 69 #define EmptyChar (ourPTail == ourPHead) 70 71 72 /* 73 * init_keyboard() 74 * 75 * Initialize the keyboard variables. 76 */ 77 78 void 79 init_keyboard() 80 { 81 ourPHead = ourPTail = ourBuffer; 82 InControl = 0; 83 WaitingForSynch = 0; 84 } 85 86 87 /* 88 * Initialize the keyboard mapping file. 89 */ 90 91 void 92 InitMapping() 93 { 94 extern state *InitControl(); 95 register struct astosc *ptr; 96 97 if (!headOfControl) { 98 /* need to initialize */ 99 headOfControl = InitControl((char *)0, 0, ascii_to_index); 100 if (!headOfControl) { /* should not occur */ 101 quit(); 102 } 103 for (ptr = &astosc[0]; ptr <= &astosc[highestof(astosc)]; ptr++) { 104 if (ptr->function == FCN_SPACE) { 105 spacePTR = ptr; 106 } 107 } 108 } 109 } 110 111 112 /* AddChar - put a function index in our buffer */ 113 114 static void 115 AddChar(c) 116 int c; 117 { 118 if (!FullChar) { 119 *ourPTail++ = c; 120 } else { 121 RingBell("Typeahead buffer full"); 122 } 123 } 124 125 /* FlushChar - put everything where it belongs */ 126 127 static void 128 FlushChar() 129 { 130 ourPTail = ourBuffer; 131 ourPHead = ourBuffer; 132 } 133 134 int 135 TerminalIn() 136 { 137 /* send data from us to next link in stream */ 138 int work = 0; 139 register struct astosc *ptr; 140 141 while (!EmptyChar) { /* send up the link */ 142 if (*ourPHead == ' ') { 143 ptr = spacePTR; 144 } else { 145 ptr = &astosc[*ourPHead]; 146 } 147 if (AcceptKeystroke(ptr->scancode, ptr->shiftstate) == 1) { 148 ourPHead++; 149 work = 1; 150 } else { 151 break; 152 } 153 } 154 155 if (EmptyChar) { 156 FlushChar(); 157 } 158 /* return value answers question: "did we do anything useful?" */ 159 return work; 160 } 161 162 int 163 DataFromTerminal(buffer, count) 164 register char *buffer; /* the data read in */ 165 register int count; /* how many bytes in this buffer */ 166 { 167 register state *regControlPointer; 168 register char c; 169 register int result; 170 int origCount; 171 extern int bellwinup; 172 static state *controlPointer; 173 174 if (bellwinup) { 175 BellOff(); 176 } 177 178 origCount = count; 179 180 while (count) { 181 c = *buffer++&0x7f; 182 count--; 183 184 if (!InControl && !IsControl(c)) { 185 AddChar(c); /* add ascii character */ 186 } else { 187 if (!InControl) { /* first character of sequence */ 188 InControl = 1; 189 controlPointer = headOfControl; 190 } 191 /* control pointer points to current position in state table */ 192 for (regControlPointer = controlPointer; ; 193 regControlPointer = NextState(regControlPointer)) { 194 if (!regControlPointer) { /* ran off end */ 195 RingBell("Invalid control sequence"); 196 regControlPointer = headOfControl; 197 InControl = 0; 198 count = 0; /* Flush current input */ 199 break; 200 } 201 if ((regControlPointer->match == c) /* hit this character */ 202 || (regControlPointer->match == MATCH_ANY)) { 203 result = regControlPointer->result; 204 if (result == STATE_GOTO) { 205 regControlPointer = regControlPointer->address; 206 break; /* go to next character */ 207 } 208 if (WaitingForSynch) { 209 if (astosc[result].function == FCN_SYNCH) { 210 WaitingForSynch = 0; 211 } else { 212 RingBell("Need to type synch character"); 213 } 214 } 215 else if (astosc[result].function == FCN_FLINP) { 216 FlushChar(); /* Don't add FLINP */ 217 } else { 218 if (astosc[result].function == FCN_MASTER_RESET) { 219 FlushChar(); 220 } 221 AddChar(result); /* add this code */ 222 } 223 InControl = 0; /* out of control now */ 224 break; 225 } 226 } 227 controlPointer = regControlPointer; /* save state */ 228 } 229 } 230 (void) TerminalIn(); /* try to send data */ 231 return(origCount-count); 232 } 233