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