Fix for a crash which happened when a document couldn't be opened.
[AROS-Contrib.git] / fish / microemacs / termio.c
blob73120c422bdc4b83e688053999f20a519793049c
1 /*
2 * The functions in this file negotiate with the operating system for
3 * characters, and write characters in a barely buffered fashion on the display.
4 * All operating systems.
5 */
6 #include <stdio.h>
8 #include <proto/dos.h>
10 #include "ed.h"
12 #if AMIGA
13 #define AMG_MAXBUF 1024
14 static BPTR terminal;
15 static char scrn_tmp[AMG_MAXBUF+1];
16 static int scrn_tmp_p = 0;
17 #endif
19 #if VMS
20 #include <stsdef.h>
21 #include <ssdef.h>
22 #include <descrip.h>
23 #include <iodef.h>
24 #include <ttdef.h>
26 #define NIBUF 128 /* Input buffer size */
27 #define NOBUF 1024 /* MM says bug buffers win! */
28 #define EFN 0 /* Event flag */
30 char obuf[NOBUF]; /* Output buffer */
31 int nobuf; /* # of bytes in above */
32 char ibuf[NIBUF]; /* Input buffer */
33 int nibuf; /* # of bytes in above */
34 int ibufi; /* Read index */
35 int oldmode[2]; /* Old TTY mode bits */
36 int newmode[2]; /* New TTY mode bits */
37 short iochan; /* TTY I/O channel */
38 #endif
40 #if CPM
41 #include <bdos.h>
42 #endif
44 #if MSDOS
45 #undef LATTICE
46 #include <dos.h>
47 #endif
49 #if RAINBOW
50 #include "rainbow.h"
51 #endif
53 #if V7
54 #include <sgtty.h> /* for stty/gtty functions */
55 struct sgttyb ostate; /* saved tty state */
56 struct sgttyb nstate; /* values for editor mode */
57 #endif
60 * This function is called once to set up the terminal device streams.
61 * On VMS, it translates SYS$INPUT until it finds the terminal, then assigns
62 * a channel to it and sets it raw. On CPM it is a no-op.
64 int ttopen(void)
66 #if AMIGA
67 terminal = Open("RAW:1/1/639/399/MicroEmacs", MODE_NEWFILE);
68 return (terminal != 0);
70 #endif
71 #if VMS
72 struct dsc$descriptor idsc;
73 struct dsc$descriptor odsc;
74 char oname[40];
75 int iosb[2];
76 int status;
78 odsc.dsc$a_pointer = "SYS$INPUT";
79 odsc.dsc$w_length = strlen(odsc.dsc$a_pointer);
80 odsc.dsc$b_dtype = DSC$K_DTYPE_T;
81 odsc.dsc$b_class = DSC$K_CLASS_S;
82 idsc.dsc$b_dtype = DSC$K_DTYPE_T;
83 idsc.dsc$b_class = DSC$K_CLASS_S;
84 do {
85 idsc.dsc$a_pointer = odsc.dsc$a_pointer;
86 idsc.dsc$w_length = odsc.dsc$w_length;
87 odsc.dsc$a_pointer = &oname[0];
88 odsc.dsc$w_length = sizeof(oname);
89 status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc);
90 if (status!=SS$_NORMAL && status!=SS$_NOTRAN)
91 exit(status);
92 if (oname[0] == 0x1B) {
93 odsc.dsc$a_pointer += 4;
94 odsc.dsc$w_length -= 4;
96 } while (status == SS$_NORMAL);
97 status = SYS$ASSIGN(&odsc, &iochan, 0, 0);
98 if (status != SS$_NORMAL)
99 exit(status);
100 status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
101 oldmode, sizeof(oldmode), 0, 0, 0, 0);
102 if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
103 exit(status);
104 newmode[0] = oldmode[0];
105 newmode[1] = oldmode[1] | TT$M_PASSALL | TT$M_NOECHO;
106 status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
107 newmode, sizeof(newmode), 0, 0, 0, 0);
108 if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
109 exit(status);
110 #endif
111 #if CPM
112 #endif
113 #if MSDOS
114 #endif
115 #if V7
116 gtty(1, &ostate); /* save old state */
117 gtty(1, &nstate); /* get base of new state */
118 nstate.sg_flags |= RAW;
119 nstate.sg_flags &= ~(ECHO|CRMOD); /* no echo for now... */
120 stty(1, &nstate); /* set mode */
121 #endif
125 * This function gets called just before we go back home to the command
126 * interpreter. On VMS it puts the terminal back in a reasonable state.
127 * Another no-operation on CPM.
129 void ttclose()
131 #if AMIGA
132 amg_flush();
133 Close(terminal);
134 #endif
135 #if VMS
136 int status;
137 int iosb[1];
139 ttflush();
140 status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
141 oldmode, sizeof(oldmode), 0, 0, 0, 0);
142 if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
143 exit(status);
144 status = SYS$DASSGN(iochan);
145 if (status != SS$_NORMAL)
146 exit(status);
147 #endif
148 #if CPM
149 #endif
150 #if MSDOS
151 #endif
152 #if V7
153 stty(1, &ostate);
154 #endif
158 * Write a character to the display. On VMS, terminal output is buffered, and
159 * we just put the characters in the big array, after checking for overflow.
160 * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
161 * MS-DOS (use the very very raw console output routine).
163 void ttputc(c)
164 #if AMIGA
165 char c;
166 #endif
168 #if AMIGA
169 scrn_tmp[scrn_tmp_p++] = c;
170 if(scrn_tmp_p>=AMG_MAXBUF)
171 amg_flush();
172 #endif
173 #if VMS
174 if (nobuf >= NOBUF)
175 ttflush();
176 obuf[nobuf++] = c;
177 #endif
179 #if CPM
180 bios(BCONOUT, c, 0);
181 #endif
183 #if MSDOS && CWC86
184 dosb(CONDIO, c, 0);
185 #endif
187 #if RAINBOW
188 Put_Char(c); /* fast video */
189 #endif
191 #if V7
192 fputc(c, stdout);
193 #endif
196 void amg_flush()
198 if(scrn_tmp_p)
199 Write(terminal,scrn_tmp,scrn_tmp_p);
200 scrn_tmp_p = 0;
204 * Flush terminal buffer. Does real work where the terminal output is buffered
205 * up. A no-operation on systems where byte at a time terminal I/O is done.
207 int ttflush()
209 #if AMIGA
210 amg_flush();
211 return 0;
212 #endif
213 #if VMS
214 int status;
215 int iosb[2];
217 status = SS$_NORMAL;
218 if (nobuf != 0) {
219 status = SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT,
220 iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0);
221 if (status == SS$_NORMAL)
222 status = iosb[0] & 0xFFFF;
223 nobuf = 0;
225 return (status);
226 #endif
227 #if CPM
228 return 0;
229 #endif
230 #if MSDOS
231 return 0;
232 #endif
233 #if V7
234 fflush(stdout);
235 return 0;
236 #endif
240 * Read a character from the terminal, performing no editing and doing no echo
241 * at all. More complex in VMS that almost anyplace else, which figures. Very
242 * simple on CPM, because the system can do exactly what you want.
244 int ttgetc()
246 #if AMIGA
247 char ch;
248 amg_flush();
249 Read(terminal, &ch, 1);
250 return (int) ch;
251 #endif
252 #if VMS
253 int status;
254 int iosb[2];
255 int term[2];
257 while (ibufi >= nibuf) {
258 ibufi = 0;
259 term[0] = 0;
260 term[1] = 0;
261 status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED,
262 iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0);
263 if (status != SS$_NORMAL)
264 exit(status);
265 status = iosb[0] & 0xFFFF;
266 if (status!=SS$_NORMAL && status!=SS$_TIMEOUT)
267 exit(status);
268 nibuf = (iosb[0]>>16) + (iosb[1]>>16);
269 if (nibuf == 0) {
270 status = SYS$QIOW(EFN, iochan, IO$_READLBLK,
271 iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
272 if (status != SS$_NORMAL
273 || (status = (iosb[0]&0xFFFF)) != SS$_NORMAL)
274 exit(status);
275 nibuf = (iosb[0]>>16) + (iosb[1]>>16);
278 return (ibuf[ibufi++] & 0xFF); /* Allow multinational */
279 #endif
281 #if CPM
282 return (biosb(BCONIN, 0, 0));
283 #endif
285 #if RAINBOW
286 int Ch;
288 while ((Ch = Read_Keyboard()) < 0);
290 if ((Ch & Function_Key) == 0)
291 if (!((Ch & 0xFF) == 015 || (Ch & 0xFF) == 0177))
292 Ch &= 0xFF;
294 return Ch;
295 #endif
297 #if MSDOS && MWC86
298 return (dosb(CONRAW, 0, 0));
299 #endif
301 #if V7
302 return(fgetc(stdin));
303 #endif