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