Sync usage with man page.
[netbsd-mini2440.git] / usr.bin / tn3270 / ascii / termin.c
blob1bdcff5165c18c6409a885bee8bce102a9494aab
1 /* $NetBSD: termin.c,v 1.7 2002/06/13 23:41:18 wiz Exp $ */
3 /*-
4 * Copyright (c) 1988 The Regents of the University of California.
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)termin.c 4.2 (Berkeley) 4/26/91";
36 #else
37 __RCSID("$NetBSD: termin.c,v 1.7 2002/06/13 23:41:18 wiz Exp $");
38 #endif
39 #endif /* not lint */
41 /* this takes characters from the keyboard, and produces 3270 keystroke
42 codes
45 #include <stdio.h>
46 #include <ctype.h>
48 #include "../general/general.h"
49 #include "../ctlr/function.h"
50 #include "../ctlr/declare.h"
51 #include "../sys_curses/telextrn.h"
53 #include "../api/astosc.h"
54 #include "state.h"
55 #include "externs.h"
56 #include "map3270.h"
58 #include "../general/globals.h"
60 extern cc_t escape; /* Escape to command mode */
62 #define IsControl(c) (!isprint((unsigned char)c) || (isspace((unsigned char)c) && ((c) != ' ')))
64 #define NextState(x) (x->next)
66 /* XXX temporary - hard code in the state table */
68 #define MATCH_ANY 0xff /* actually, match any character */
71 static unsigned char
72 ourBuffer[100], /* where we store stuff */
73 *ourPHead = ourBuffer, /* first character in buffer */
74 *ourPTail = ourBuffer, /* where next character goes */
75 *TransPointer = 0; /* For transparent mode data */
77 static int InControl;
78 static int WaitingForSynch;
80 static struct astosc
81 *spacePTR = 0; /* Space is hard to enter */
83 static state
84 *headOfControl = 0; /* where we enter code state table */
86 #define FullChar ((ourPTail+5) >= ourBuffer+sizeof ourBuffer)
87 #define EmptyChar (ourPTail == ourPHead)
90 static void AddChar(int);
91 static void FlushChar(void);
95 * init_keyboard()
97 * Initialize the keyboard variables.
100 void
101 init_keyboard()
103 ourPHead = ourPTail = ourBuffer;
104 InControl = 0;
105 WaitingForSynch = 0;
110 * Initialize the keyboard mapping file.
113 void
114 InitMapping()
116 struct astosc *ptr;
118 if (!headOfControl) {
119 /* need to initialize */
120 headOfControl = InitControl((char *)0, 0, ascii_to_index);
121 if (!headOfControl) { /* should not occur */
122 quit(0, NULL);
124 for (ptr = &astosc[0]; ptr <= &astosc[highestof(astosc)]; ptr++) {
125 if (ptr->function == FCN_SPACE) {
126 spacePTR = ptr;
133 /* AddChar - put a function index in our buffer */
135 static void
136 AddChar(c)
137 int c;
139 if (!FullChar) {
140 *ourPTail++ = c;
141 } else {
142 RingBell("Typeahead buffer full");
146 /* FlushChar - put everything where it belongs */
148 static void
149 FlushChar()
151 ourPTail = ourBuffer;
152 ourPHead = ourBuffer;
155 /*ARGSUSED*/
156 void
157 TransInput(onoff, mode)
158 int mode; /* Which KIND of transparent input */
159 int onoff; /* Going in, or coming out */
161 if (onoff) {
162 /* Flush pending input */
163 FlushChar();
164 TransPointer = ourBuffer;
165 } else {
170 TerminalIn()
172 /* send data from us to next link in stream */
173 int work = 0;
174 struct astosc *ptr;
176 while (!EmptyChar) { /* send up the link */
177 if (*ourPHead == ' ') {
178 ptr = spacePTR;
179 } else {
180 ptr = &astosc[*ourPHead];
182 if (AcceptKeystroke(ptr->scancode, ptr->shiftstate) == 1) {
183 ourPHead++;
184 work = 1;
185 } else {
186 break;
190 if (EmptyChar) {
191 FlushChar();
193 /* return value answers question: "did we do anything useful?" */
194 return work;
198 DataFromTerminal(buffer, count)
199 char *buffer; /* the data read in */
200 int count; /* how many bytes in this buffer */
202 state *regControlPointer;
203 int c;
204 int result;
205 int origCount;
206 extern int bellwinup;
207 static state *controlPointer;
209 if (TransPointer) {
210 int i;
212 if ((count+TransPointer) >= (ourBuffer+sizeof ourBuffer)) {
213 i = ourBuffer+sizeof ourBuffer-TransPointer;
214 } else {
215 i = count;
217 while (i--) {
218 c = (*buffer++)&0x7f;
219 *TransPointer++ = c|0x80;
220 if (c == '\r') {
221 SendTransparent((char *)ourBuffer, TransPointer-ourBuffer);
222 TransPointer = 0; /* Done */
223 break;
226 return count;
229 if (bellwinup) {
230 BellOff();
233 origCount = count;
235 while (count) {
236 c = *buffer++&0x7f;
237 count--;
239 if (c == escape) {
240 if (count && (*buffer&0x7f) == escape) {
241 buffer++;
242 count--;
243 } else {
244 command(0, (char *)0, 0);
245 RefreshScreen();
246 continue;
250 if (!InControl && !IsControl(c)) {
251 AddChar(c); /* add ascii character */
252 } else {
253 if (!InControl) { /* first character of sequence */
254 InControl = 1;
255 controlPointer = headOfControl;
257 /* control pointer points to current position in state table */
258 for (regControlPointer = controlPointer; ;
259 regControlPointer = NextState(regControlPointer)) {
260 if (!regControlPointer) { /* ran off end */
261 RingBell("Invalid control sequence");
262 regControlPointer = headOfControl;
263 InControl = 0;
264 count = 0; /* Flush current input */
265 break;
267 if ((regControlPointer->match == c) /* hit this character */
268 || (regControlPointer->match == MATCH_ANY)) {
269 result = regControlPointer->result;
270 if (result == STATE_GOTO) {
271 regControlPointer = regControlPointer->address;
272 break; /* go to next character */
274 if (WaitingForSynch) {
275 if (astosc[result].function == FCN_SYNCH) {
276 WaitingForSynch = 0;
277 } else {
278 RingBell("Need to type synch character");
281 else if (astosc[result].function == FCN_FLINP) {
282 FlushChar(); /* Don't add FLINP */
283 } else {
284 if (astosc[result].function == FCN_MASTER_RESET) {
285 FlushChar();
287 AddChar(result); /* add this code */
289 InControl = 0; /* out of control now */
290 break;
293 controlPointer = regControlPointer; /* save state */
296 (void) TerminalIn(); /* try to send data */
297 return(origCount-count);