|
|
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.