1 |
/* |
2 |
* Interface Implementation - terminal setup |
3 |
* Tom Epperly |
4 |
* Created: 1/17/90 |
5 |
* Version: $Revision: 1.10 $ |
6 |
* Version control file: $RCSfile: termsetup.c,v $ |
7 |
* Date last modified: $Date: 1997/07/18 12:35:28 $ |
8 |
* Last modified by: $Author: mthomas $ |
9 |
* |
10 |
* This file is part of the Ascend Language Interpreter. |
11 |
* |
12 |
* Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly |
13 |
* |
14 |
* The Ascend Language Interpreter is free software; you can redistribute |
15 |
* it and/or modify it under the terms of the GNU General Public License as |
16 |
* published by the Free Software Foundation; either version 2 of the |
17 |
* License, or (at your option) any later version. |
18 |
* |
19 |
* The Ascend Language Interpreter is distributed in hope that it will be |
20 |
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
21 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
22 |
* General Public License for more details. |
23 |
* |
24 |
* You should have received a copy of the GNU General Public License |
25 |
* along with the program; if not, write to the Free Software Foundation, |
26 |
* Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named |
27 |
* COPYING. |
28 |
* |
29 |
*/ |
30 |
#include <stdlib.h> |
31 |
#include <stdio.h> |
32 |
#include <assert.h> |
33 |
#include <string.h> |
34 |
#include <limits.h> |
35 |
#include <signal.h> |
36 |
#include "utilities\ascConfig.h" |
37 |
|
38 |
#ifndef __WIN32__ |
39 |
|
40 |
#include<unistd.h> |
41 |
#ifndef linux |
42 |
#include<sgtty.h> |
43 |
#endif |
44 |
#ifdef linux |
45 |
#include<bsd/sgtty.h> |
46 |
#endif |
47 |
#if defined(sun) || defined(__sun) /* sun */ |
48 |
#include<curses.h> |
49 |
#if defined(__SVR4) /* solaris */ |
50 |
#include<term.h> |
51 |
#endif /*solaris */ |
52 |
#endif /* sun */ |
53 |
#include<sys/ioctl.h> |
54 |
|
55 |
#ifdef _SGI_SOURCE |
56 |
#define _HPUX_SOURCE 1 |
57 |
#include <sys/ttold.h> |
58 |
#define RAW O_RAW |
59 |
#define CBREAK O_CBREAK |
60 |
#endif |
61 |
|
62 |
#define TERMBUF 1024 |
63 |
|
64 |
/* if the term is unknown, then try to use the following as |
65 |
the terminal type before exiting */ |
66 |
#define UNKNOWN_TERM_DEFAULT "dumb" |
67 |
|
68 |
/* global variables */ |
69 |
struct sgttyb g_old_terminal_settings,g_new_terminal_settings; |
70 |
unsigned g_terminal_inited=0; |
71 |
int g_filenum=0; |
72 |
char code_buf[TERMBUF],termcap_buffer[2048]; |
73 |
char *g_backspace=NULL,*g_clear=NULL,*g_clear_eol=NULL,*g_bell=NULL; |
74 |
|
75 |
|
76 |
int OutputChar(c) |
77 |
char c; |
78 |
{ |
79 |
return putchar(c); |
80 |
} |
81 |
|
82 |
void DeleteBackOne() |
83 |
{ |
84 |
tputs(g_backspace,1,OutputChar); |
85 |
putchar(' '); |
86 |
tputs(g_backspace,1,OutputChar); |
87 |
} |
88 |
|
89 |
void ClearScreen() |
90 |
{ |
91 |
tputs(g_clear,1,OutputChar); |
92 |
} |
93 |
|
94 |
void Bell() |
95 |
{ |
96 |
tputs(g_bell,1,OutputChar); |
97 |
} |
98 |
|
99 |
void ClearLine() |
100 |
{ |
101 |
putchar('\r'); |
102 |
tputs(g_clear_eol,1,OutputChar); |
103 |
} |
104 |
|
105 |
void SetupTermcapStuff() |
106 |
{ |
107 |
#ifndef __STDC__ |
108 |
int tgetent(); |
109 |
int tgetnum(); |
110 |
int tgetflag(); |
111 |
char *tgetstr(); |
112 |
#else |
113 |
int tgetent(char *, char *); |
114 |
int tgetnum(char *); |
115 |
int tgetflag(char *); |
116 |
char *tgetstr(char *, char **); |
117 |
#endif |
118 |
char *buffer = code_buf; |
119 |
|
120 |
switch(tgetent(termcap_buffer,getenv("TERM"))){ |
121 |
case -1: |
122 |
fprintf(stderr,"Unable to open termcap file.\n"); |
123 |
exit(2);/*NOTREACHED*/ |
124 |
case 0: |
125 |
fprintf(stderr,"There is no definition for %s in the termcap.\n", |
126 |
getenv("TERM")); |
127 |
/* try to use the default term type */ |
128 |
if (tgetent(termcap_buffer,UNKNOWN_TERM_DEFAULT) == 1) { |
129 |
/* successful...set the TERM envar to this and tell user */ |
130 |
putenv("TERM=" UNKNOWN_TERM_DEFAULT); |
131 |
fprintf(stderr,"Using \"%s\" terminal type.\n\n", UNKNOWN_TERM_DEFAULT); |
132 |
} |
133 |
else { |
134 |
/* the alternate term type failed also */ |
135 |
exit(2); /*NOTREACHED*/ |
136 |
} |
137 |
} |
138 |
/* bell */ |
139 |
if (!(g_bell = tgetstr("bl",&buffer))) |
140 |
if (!(g_bell = tgetstr("vb",&buffer))){ |
141 |
fprintf(stderr,"Terminal doesn't support a bell.\n"); |
142 |
fprintf(stderr,"Continuing on without bell.\n"); |
143 |
g_bell = "\007"; |
144 |
} |
145 |
assert(buffer < (code_buf + TERMBUF)); |
146 |
/* backspacing */ |
147 |
if (tgetflag("bs")){ |
148 |
g_backspace = "\010"; |
149 |
} |
150 |
else{ |
151 |
if (!(g_backspace = tgetstr("bc",&buffer))){ |
152 |
fprintf(stderr,"Terminal doesn't support backspacing.\n"); |
153 |
fprintf(stderr,"ASCEND needs backspacking.\n"); |
154 |
/*exit(2) NOTREACHED*/ |
155 |
} |
156 |
} |
157 |
assert(buffer < (code_buf + TERMBUF)); |
158 |
/* clear to end of line */ |
159 |
if (!(g_clear_eol = tgetstr("ce",&buffer))){ |
160 |
fprintf(stderr,"Terminal doesn't support clearing to end of line.\n"); |
161 |
fprintf(stderr,"ASCEND needs clearing to end of line.\n"); |
162 |
/*exit(2) NOTREACHED*/ |
163 |
} |
164 |
assert(buffer < (code_buf + TERMBUF)); |
165 |
/* clear screen */ |
166 |
if (!(g_clear = tgetstr("cl",&buffer))){ |
167 |
fprintf(stderr,"Terminal doesn't support clear screen.\n"); |
168 |
fprintf(stderr,"Continuing on without screen clearing.\n"); |
169 |
} |
170 |
assert(buffer < (code_buf + TERMBUF)); |
171 |
} |
172 |
|
173 |
void InterfaceError() |
174 |
{ |
175 |
fprintf(stderr,"Error changing terminal characteristics\n"); |
176 |
/* exit(2); NOTREACHED*/ |
177 |
} |
178 |
|
179 |
|
180 |
#ifdef _HPUX_SOURCE |
181 |
#define CBREAK 8 |
182 |
# ifndef TIOCGETP |
183 |
# define TIOCGETP _IOR('t', 8,struct sgttyb) |
184 |
# endif |
185 |
#define TIOCSETN _IOW('t', 9,struct sgttyb) |
186 |
#endif |
187 |
|
188 |
void SetupTerminal() |
189 |
{ |
190 |
#ifndef _HPUX_SOURCE |
191 |
g_filenum = fileno(stdin); |
192 |
if (ioctl(g_filenum,TIOCGETP,&g_old_terminal_settings)==-1) InterfaceError(); |
193 |
g_new_terminal_settings = g_old_terminal_settings; |
194 |
g_new_terminal_settings.sg_flags = |
195 |
(g_new_terminal_settings.sg_flags|CBREAK)&(~ECHO); |
196 |
if (ioctl(g_filenum,TIOCSETN,&g_new_terminal_settings)==-1) InterfaceError(); |
197 |
g_terminal_inited = 1; |
198 |
#endif |
199 |
} |
200 |
|
201 |
void RestoreTerminal() |
202 |
{ |
203 |
#ifndef _HPUX_SOURCE |
204 |
if (g_terminal_inited){ |
205 |
if (ioctl(g_filenum,TIOCSETN,&g_old_terminal_settings)==-1) |
206 |
InterfaceError(); |
207 |
g_terminal_inited = 0; |
208 |
} |
209 |
#endif |
210 |
} |
211 |
|
212 |
|
213 |
void TermSetup_ResetTerminal() |
214 |
{ |
215 |
#ifndef _HPUX_SOURCE |
216 |
if (g_terminal_inited){ |
217 |
if (ioctl(g_filenum,TIOCSETN,&g_new_terminal_settings)==-1) |
218 |
InterfaceError(); |
219 |
} |
220 |
else |
221 |
SetupTerminal(); |
222 |
ClearScreen(); |
223 |
#endif /* ! _HPUX_SOURCE */ |
224 |
} |
225 |
|
226 |
void ReadString(str,len) |
227 |
char *str; |
228 |
int *len; |
229 |
{ |
230 |
struct sgttyb old,new; |
231 |
int filenum; |
232 |
filenum = fileno(stdin); |
233 |
if (ioctl(filenum,TIOCGETP,&old)==-1) InterfaceError(); |
234 |
new = old; |
235 |
new.sg_flags = (new.sg_flags|ECHO)&(~CBREAK)&(~RAW); |
236 |
if (ioctl(filenum,TIOCSETN,&new)==-1) InterfaceError(); |
237 |
str = gets(str); |
238 |
*len = strlen(str); |
239 |
if (ioctl(filenum,TIOCSETN,&old)==-1) InterfaceError(); |
240 |
} |
241 |
|
242 |
#else /* __WIN32__ */ |
243 |
|
244 |
int OutputChar(char c) |
245 |
{ |
246 |
fprintf(stderr,"OutputChar() not implemented in Windows.\n"); |
247 |
return 0; |
248 |
} |
249 |
|
250 |
void DeleteBackOne(void) |
251 |
{ |
252 |
fprintf(stderr,"DeleteBackOne() not implemented in Windows.\n"); |
253 |
} |
254 |
|
255 |
void ClearScreen(void) |
256 |
{ |
257 |
fprintf(stderr,"ClearScreen() not implemented in Windows.\n"); |
258 |
} |
259 |
|
260 |
void Bell(void) |
261 |
{ |
262 |
fprintf(stderr,"Bell() not implemented in Windows.\n"); |
263 |
} |
264 |
|
265 |
void ClearLine(void) |
266 |
{ |
267 |
fprintf(stderr,"ClearLine() not implemented in Windows.\n"); |
268 |
} |
269 |
|
270 |
void SetupTermcapStuff(void) |
271 |
{ |
272 |
fprintf(stderr,"SetupTermcapStuff() not implemented in Windows.\n"); |
273 |
} |
274 |
|
275 |
void InterfaceError(void) |
276 |
{ |
277 |
fprintf(stderr,"InterfaceError() not implemented in Windows.\n"); |
278 |
} |
279 |
|
280 |
void SetupTerminal(void) |
281 |
{ |
282 |
fprintf(stderr,"SetupTerminal() not implemented in Windows.\n"); |
283 |
} |
284 |
|
285 |
void RestoreTerminal(void) |
286 |
{ |
287 |
fprintf(stderr,"RestoreTerminal() not implemented in Windows.\n"); |
288 |
} |
289 |
|
290 |
void TermSetup_ResetTerminal(void) |
291 |
{ |
292 |
fprintf(stderr,"TermSetup_ResetTerminal() not implemented in Windows.\n"); |
293 |
} |
294 |
|
295 |
void ReadString(char *str, int *len) |
296 |
{ |
297 |
fprintf(stderr,"ReadString() not implemented in Windows.\n"); |
298 |
} |
299 |
|
300 |
|
301 |
#endif /* __WIN32__ */ |
302 |
|