1 /*- 2 * Copyright (c) 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)termin.c 8.1 (Berkeley) 06/06/93"; 10 #endif /* not lint */ 11 12 /* this takes characters from the keyboard, and produces 3270 keystroke 13 codes 14 */ 15 16 #include <stdio.h> 17 #include <ctype.h> 18 19 #include "../general/general.h" 20 #include "../ctlr/function.h" 21 #include "../ctlr/externs.h" 22 #include "../ctlr/declare.h" 23 24 #include "../api/astosc.h" 25 #include "state.h" 26 27 #include "../general/globals.h" 28 29 #define IsControl(c) (!isprint(c) || (isspace(c) && ((c) != ' '))) 30 31 #define NextState(x) (x->next) 32 33 /* XXX temporary - hard code in the state table */ 34 35 #define MATCH_ANY 0xff /* actually, match any character */ 36 37 38 static unsigned char 39 ourBuffer[100], /* where we store stuff */ 40 *ourPHead = ourBuffer, /* first character in buffer */ 41 *ourPTail = ourBuffer, /* where next character goes */ 42 *TransPointer = 0; /* For transparent mode data */ 43 44 static int InControl; 45 static int WaitingForSynch; 46 47 static struct astosc 48 *spacePTR = 0; /* Space is hard to enter */ 49 50 static state 51 *headOfControl = 0; /* where we enter code state table */ 52 53 #define FullChar ((ourPTail+5) >= ourBuffer+sizeof ourBuffer) 54 #define EmptyChar (ourPTail == ourPHead) 55 56 57 /* 58 * init_keyboard() 59 * 60 * Initialize the keyboard variables. 61 */ 62 63 void 64 init_keyboard() 65 { 66 ourPHead = ourPTail = ourBuffer; 67 InControl = 0; 68 WaitingForSynch = 0; 69 } 70 71 72 /* 73 * Initialize the keyboard mapping file. 74 */ 75 76 void 77 InitMapping() 78 { 79 extern state *InitControl(); 80 register struct astosc *ptr; 81 82 if (!headOfControl) { 83 /* need to initialize */ 84 headOfControl = InitControl((char *)0, 0, ascii_to_index); 85 if (!headOfControl) { /* should not occur */ 86 quit(); 87 } 88 for (ptr = &astosc[0]; ptr <= &astosc[highestof(astosc)]; ptr++) { 89 if (ptr->function == FCN_SPACE) { 90 spacePTR = ptr; 91 } 92 } 93 } 94 } 95 96 97 /* AddChar - put a function index in our buffer */ 98 99 static void 100 AddChar(c) 101 int c; 102 { 103 if (!FullChar) { 104 *ourPTail++ = c; 105 } else { 106 RingBell("Typeahead buffer full"); 107 } 108 } 109 110 /* FlushChar - put everything where it belongs */ 111 112 static void 113 FlushChar() 114 { 115 ourPTail = ourBuffer; 116 ourPHead = ourBuffer; 117 } 118 119 /*ARGSUSED*/ 120 void 121 TransInput(onoff, mode) 122 int mode; /* Which KIND of transparent input */ 123 int onoff; /* Going in, or coming out */ 124 { 125 if (onoff) { 126 /* Flush pending input */ 127 FlushChar(); 128 TransPointer = ourBuffer; 129 } else { 130 } 131 } 132 133 int 134 TerminalIn() 135 { 136 /* send data from us to next link in stream */ 137 int work = 0; 138 register struct astosc *ptr; 139 140 while (!EmptyChar) { /* send up the link */ 141 if (*ourPHead == ' ') { 142 ptr = spacePTR; 143 } else { 144 ptr = &astosc[*ourPHead]; 145 } 146 if (AcceptKeystroke(ptr->scancode, ptr->shiftstate) == 1) { 147 ourPHead++; 148 work = 1; 149 } else { 150 break; 151 } 152 } 153 154 if (EmptyChar) { 155 FlushChar(); 156 } 157 /* return value answers question: "did we do anything useful?" */ 158 return work; 159 } 160 161 int 162 DataFromTerminal(buffer, count) 163 register char *buffer; /* the data read in */ 164 register int count; /* how many bytes in this buffer */ 165 { 166 register state *regControlPointer; 167 register char c; 168 register int result; 169 int origCount; 170 extern int bellwinup; 171 static state *controlPointer; 172 173 if (TransPointer) { 174 int i; 175 176 if ((count+TransPointer) >= (ourBuffer+sizeof ourBuffer)) { 177 i = ourBuffer+sizeof ourBuffer-TransPointer; 178 } else { 179 i = count; 180 } 181 while (i--) { 182 c = (*buffer++)&0x7f; 183 *TransPointer++ = c|0x80; 184 if (c == '\r') { 185 SendTransparent((char *)ourBuffer, TransPointer-ourBuffer); 186 TransPointer = 0; /* Done */ 187 break; 188 } 189 } 190 return count; 191 } 192 193 if (bellwinup) { 194 void BellOff(); 195 196 BellOff(); 197 } 198 199 origCount = count; 200 201 while (count) { 202 c = *buffer++&0x7f; 203 count--; 204 205 if (!InControl && !IsControl(c)) { 206 AddChar(c); /* add ascii character */ 207 } else { 208 if (!InControl) { /* first character of sequence */ 209 InControl = 1; 210 controlPointer = headOfControl; 211 } 212 /* control pointer points to current position in state table */ 213 for (regControlPointer = controlPointer; ; 214 regControlPointer = NextState(regControlPointer)) { 215 if (!regControlPointer) { /* ran off end */ 216 RingBell("Invalid control sequence"); 217 regControlPointer = headOfControl; 218 InControl = 0; 219 count = 0; /* Flush current input */ 220 break; 221 } 222 if ((regControlPointer->match == c) /* hit this character */ 223 || (regControlPointer->match == MATCH_ANY)) { 224 result = regControlPointer->result; 225 if (result == STATE_GOTO) { 226 regControlPointer = regControlPointer->address; 227 break; /* go to next character */ 228 } 229 if (WaitingForSynch) { 230 if (astosc[result].function == FCN_SYNCH) { 231 WaitingForSynch = 0; 232 } else { 233 void RingBell(); 234 235 RingBell("Need to type synch character"); 236 } 237 } 238 else if (astosc[result].function == FCN_FLINP) { 239 FlushChar(); /* Don't add FLINP */ 240 } else { 241 if (astosc[result].function == FCN_MASTER_RESET) { 242 FlushChar(); 243 } 244 AddChar(result); /* add this code */ 245 } 246 InControl = 0; /* out of control now */ 247 break; 248 } 249 } 250 controlPointer = regControlPointer; /* save state */ 251 } 252 } 253 (void) TerminalIn(); /* try to send data */ 254 return(origCount-count); 255 } 256