1 |
|
|
/* $OpenBSD: lib_setup.c,v 1.12 2010/01/12 23:22:06 nicm Exp $ */ |
2 |
|
|
|
3 |
|
|
/**************************************************************************** |
4 |
|
|
* Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. * |
5 |
|
|
* * |
6 |
|
|
* Permission is hereby granted, free of charge, to any person obtaining a * |
7 |
|
|
* copy of this software and associated documentation files (the * |
8 |
|
|
* "Software"), to deal in the Software without restriction, including * |
9 |
|
|
* without limitation the rights to use, copy, modify, merge, publish, * |
10 |
|
|
* distribute, distribute with modifications, sublicense, and/or sell * |
11 |
|
|
* copies of the Software, and to permit persons to whom the Software is * |
12 |
|
|
* furnished to do so, subject to the following conditions: * |
13 |
|
|
* * |
14 |
|
|
* The above copyright notice and this permission notice shall be included * |
15 |
|
|
* in all copies or substantial portions of the Software. * |
16 |
|
|
* * |
17 |
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * |
18 |
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * |
19 |
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * |
20 |
|
|
* IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * |
21 |
|
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * |
22 |
|
|
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * |
23 |
|
|
* THE USE OR OTHER DEALINGS IN THE SOFTWARE. * |
24 |
|
|
* * |
25 |
|
|
* Except as contained in this notice, the name(s) of the above copyright * |
26 |
|
|
* holders shall not be used in advertising or otherwise to promote the * |
27 |
|
|
* sale, use or other dealings in this Software without prior written * |
28 |
|
|
* authorization. * |
29 |
|
|
****************************************************************************/ |
30 |
|
|
|
31 |
|
|
/**************************************************************************** |
32 |
|
|
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * |
33 |
|
|
* and: Eric S. Raymond <esr@snark.thyrsus.com> * |
34 |
|
|
* and: Thomas E. Dickey 1996-on * |
35 |
|
|
****************************************************************************/ |
36 |
|
|
|
37 |
|
|
/* |
38 |
|
|
* Terminal setup routines common to termcap and terminfo: |
39 |
|
|
* |
40 |
|
|
* use_env(bool) |
41 |
|
|
* setupterm(char *, int, int *) |
42 |
|
|
*/ |
43 |
|
|
|
44 |
|
|
#include <curses.priv.h> |
45 |
|
|
#include <tic.h> /* for MAX_NAME_SIZE */ |
46 |
|
|
#include <term_entry.h> |
47 |
|
|
|
48 |
|
|
#if SVR4_TERMIO && !defined(_POSIX_SOURCE) |
49 |
|
|
#define _POSIX_SOURCE |
50 |
|
|
#endif |
51 |
|
|
|
52 |
|
|
#if HAVE_LOCALE_H |
53 |
|
|
#include <locale.h> |
54 |
|
|
#endif |
55 |
|
|
|
56 |
|
|
#include <term.h> /* lines, columns, cur_term */ |
57 |
|
|
|
58 |
|
|
MODULE_ID("$Id: lib_setup.c,v 1.12 2010/01/12 23:22:06 nicm Exp $") |
59 |
|
|
|
60 |
|
|
/**************************************************************************** |
61 |
|
|
* |
62 |
|
|
* Terminal size computation |
63 |
|
|
* |
64 |
|
|
****************************************************************************/ |
65 |
|
|
|
66 |
|
|
#if HAVE_SIZECHANGE |
67 |
|
|
# if !defined(sun) || !TERMIOS |
68 |
|
|
# if HAVE_SYS_IOCTL_H |
69 |
|
|
# include <sys/ioctl.h> |
70 |
|
|
# endif |
71 |
|
|
# endif |
72 |
|
|
#endif |
73 |
|
|
|
74 |
|
|
#if NEED_PTEM_H |
75 |
|
|
/* On SCO, they neglected to define struct winsize in termios.h -- it's only |
76 |
|
|
* in termio.h and ptem.h (the former conflicts with other definitions). |
77 |
|
|
*/ |
78 |
|
|
# include <sys/stream.h> |
79 |
|
|
# include <sys/ptem.h> |
80 |
|
|
#endif |
81 |
|
|
|
82 |
|
|
#if HAVE_LANGINFO_CODESET |
83 |
|
|
#include <langinfo.h> |
84 |
|
|
#endif |
85 |
|
|
|
86 |
|
|
/* |
87 |
|
|
* SCO defines TIOCGSIZE and the corresponding struct. Other systems (SunOS, |
88 |
|
|
* Solaris, IRIX) define TIOCGWINSZ and struct winsize. |
89 |
|
|
*/ |
90 |
|
|
#ifdef TIOCGSIZE |
91 |
|
|
# define IOCTL_WINSIZE TIOCGSIZE |
92 |
|
|
# define STRUCT_WINSIZE struct ttysize |
93 |
|
|
# define WINSIZE_ROWS(n) (int)n.ts_lines |
94 |
|
|
# define WINSIZE_COLS(n) (int)n.ts_cols |
95 |
|
|
#else |
96 |
|
|
# ifdef TIOCGWINSZ |
97 |
|
|
# define IOCTL_WINSIZE TIOCGWINSZ |
98 |
|
|
# define STRUCT_WINSIZE struct winsize |
99 |
|
|
# define WINSIZE_ROWS(n) (int)n.ws_row |
100 |
|
|
# define WINSIZE_COLS(n) (int)n.ws_col |
101 |
|
|
# endif |
102 |
|
|
#endif |
103 |
|
|
|
104 |
|
|
/* |
105 |
|
|
* Reduce explicit use of "cur_term" global variable. |
106 |
|
|
*/ |
107 |
|
|
#undef CUR |
108 |
|
|
#define CUR termp->type. |
109 |
|
|
|
110 |
|
|
/* |
111 |
|
|
* Wrap global variables in this module. |
112 |
|
|
*/ |
113 |
|
|
#if USE_REENTRANT |
114 |
|
|
NCURSES_EXPORT(char *) |
115 |
|
|
NCURSES_PUBLIC_VAR(ttytype) (void) |
116 |
|
|
{ |
117 |
|
|
static char empty[] = ""; |
118 |
|
|
return cur_term ? cur_term->type.term_names : empty; |
119 |
|
|
} |
120 |
|
|
NCURSES_EXPORT(int *) |
121 |
|
|
_nc_ptr_Lines(void) |
122 |
|
|
{ |
123 |
|
|
return ptrLines(); |
124 |
|
|
} |
125 |
|
|
NCURSES_EXPORT(int) |
126 |
|
|
NCURSES_PUBLIC_VAR(LINES) (void) |
127 |
|
|
{ |
128 |
|
|
return *_nc_ptr_Lines(); |
129 |
|
|
} |
130 |
|
|
NCURSES_EXPORT(int *) |
131 |
|
|
_nc_ptr_Cols(void) |
132 |
|
|
{ |
133 |
|
|
return ptrCols(); |
134 |
|
|
} |
135 |
|
|
NCURSES_EXPORT(int) |
136 |
|
|
NCURSES_PUBLIC_VAR(COLS) (void) |
137 |
|
|
{ |
138 |
|
|
return *_nc_ptr_Cols(); |
139 |
|
|
} |
140 |
|
|
NCURSES_EXPORT(int) |
141 |
|
|
NCURSES_PUBLIC_VAR(TABSIZE) (void) |
142 |
|
|
{ |
143 |
|
|
return SP ? SP->_TABSIZE : 8; |
144 |
|
|
} |
145 |
|
|
#else |
146 |
|
|
NCURSES_EXPORT_VAR(char) ttytype[NAMESIZE] = ""; |
147 |
|
|
NCURSES_EXPORT_VAR(int) LINES = 0; |
148 |
|
|
NCURSES_EXPORT_VAR(int) COLS = 0; |
149 |
|
|
NCURSES_EXPORT_VAR(int) TABSIZE = 0; |
150 |
|
|
#endif |
151 |
|
|
|
152 |
|
|
#if NCURSES_EXT_FUNCS |
153 |
|
|
NCURSES_EXPORT(int) |
154 |
|
|
set_tabsize(int value) |
155 |
|
|
{ |
156 |
|
|
int code = OK; |
157 |
|
|
#if USE_REENTRANT |
158 |
|
|
if (SP) { |
159 |
|
|
SP->_TABSIZE = value; |
160 |
|
|
} else { |
161 |
|
|
code = ERR; |
162 |
|
|
} |
163 |
|
|
#else |
164 |
|
|
TABSIZE = value; |
165 |
|
|
#endif |
166 |
|
|
return code; |
167 |
|
|
} |
168 |
|
|
#endif |
169 |
|
|
|
170 |
|
|
#if USE_SIGWINCH |
171 |
|
|
/* |
172 |
|
|
* If we have a pending SIGWINCH, set the flag in each screen. |
173 |
|
|
*/ |
174 |
|
|
NCURSES_EXPORT(int) |
175 |
|
|
_nc_handle_sigwinch(SCREEN *sp) |
176 |
|
|
{ |
177 |
|
|
SCREEN *scan; |
178 |
|
|
|
179 |
|
|
if (_nc_globals.have_sigwinch) { |
180 |
|
|
_nc_globals.have_sigwinch = 0; |
181 |
|
|
|
182 |
|
|
for (each_screen(scan)) { |
183 |
|
|
scan->_sig_winch = TRUE; |
184 |
|
|
} |
185 |
|
|
} |
186 |
|
|
|
187 |
|
|
return (sp ? sp->_sig_winch : 0); |
188 |
|
|
} |
189 |
|
|
|
190 |
|
|
#endif |
191 |
|
|
|
192 |
|
|
NCURSES_EXPORT(void) |
193 |
|
|
use_env(bool f) |
194 |
|
|
{ |
195 |
|
|
T((T_CALLED("use_env()"))); |
196 |
|
|
_nc_prescreen.use_env = f; |
197 |
|
|
returnVoid; |
198 |
|
|
} |
199 |
|
|
|
200 |
|
|
NCURSES_EXPORT(void) |
201 |
|
|
_nc_get_screensize(SCREEN *sp, int *linep, int *colp) |
202 |
|
|
/* Obtain lines/columns values from the environment and/or terminfo entry */ |
203 |
|
|
{ |
204 |
|
6 |
TERMINAL *termp = cur_term; |
205 |
|
|
int my_tabsize; |
206 |
|
|
|
207 |
|
|
/* figure out the size of the screen */ |
208 |
|
|
T(("screen size: terminfo lines = %d columns = %d", lines, columns)); |
209 |
|
|
|
210 |
✗✓ |
3 |
if (!_nc_prescreen.use_env) { |
211 |
|
|
*linep = (int) lines; |
212 |
|
|
*colp = (int) columns; |
213 |
|
|
} else { /* usually want to query LINES and COLUMNS from environment */ |
214 |
|
|
int value; |
215 |
|
|
|
216 |
|
3 |
*linep = *colp = 0; |
217 |
|
|
|
218 |
|
|
/* first, look for environment variables */ |
219 |
✗✓ |
3 |
if ((value = _nc_getenv_num("LINES")) > 0) { |
220 |
|
|
*linep = value; |
221 |
|
|
} |
222 |
✗✓ |
3 |
if ((value = _nc_getenv_num("COLUMNS")) > 0) { |
223 |
|
|
*colp = value; |
224 |
|
|
} |
225 |
|
|
T(("screen size: environment LINES = %d COLUMNS = %d", *linep, *colp)); |
226 |
|
|
|
227 |
|
|
#ifdef __EMX__ |
228 |
|
|
if (*linep <= 0 || *colp <= 0) { |
229 |
|
|
int screendata[2]; |
230 |
|
|
_scrsize(screendata); |
231 |
|
|
*colp = screendata[0]; |
232 |
|
|
*linep = screendata[1]; |
233 |
|
|
T(("EMX screen size: environment LINES = %d COLUMNS = %d", |
234 |
|
|
*linep, *colp)); |
235 |
|
|
} |
236 |
|
|
#endif |
237 |
|
|
#if HAVE_SIZECHANGE |
238 |
|
|
/* if that didn't work, maybe we can try asking the OS */ |
239 |
✗✓✗✗
|
3 |
if (*linep <= 0 || *colp <= 0) { |
240 |
✓✓ |
3 |
if (isatty(cur_term->Filedes)) { |
241 |
|
2 |
STRUCT_WINSIZE size; |
242 |
|
|
|
243 |
|
2 |
errno = 0; |
244 |
|
2 |
do { |
245 |
✗✗ |
2 |
if (ioctl(cur_term->Filedes, IOCTL_WINSIZE, &size) < 0 |
246 |
✗✓ |
2 |
&& errno != EINTR) |
247 |
|
|
goto failure; |
248 |
✗✓ |
2 |
} while |
249 |
|
2 |
(errno == EINTR); |
250 |
|
|
|
251 |
|
|
/* |
252 |
|
|
* Solaris lets users override either dimension with an |
253 |
|
|
* environment variable. |
254 |
|
|
*/ |
255 |
✓✗ |
2 |
if (*linep <= 0) |
256 |
✗✓✗✗
|
6 |
*linep = (sp != 0 && sp->_filtered) ? 1 : WINSIZE_ROWS(size); |
257 |
✓✗ |
2 |
if (*colp <= 0) |
258 |
|
2 |
*colp = WINSIZE_COLS(size); |
259 |
|
4 |
} |
260 |
|
|
/* FALLTHRU */ |
261 |
|
|
failure:; |
262 |
|
|
} |
263 |
|
|
#endif /* HAVE_SIZECHANGE */ |
264 |
|
|
|
265 |
|
|
/* if we can't get dynamic info about the size, use static */ |
266 |
✓✓ |
3 |
if (*linep <= 0) { |
267 |
|
1 |
*linep = (int) lines; |
268 |
|
1 |
} |
269 |
✓✓ |
3 |
if (*colp <= 0) { |
270 |
|
1 |
*colp = (int) columns; |
271 |
|
1 |
} |
272 |
|
|
|
273 |
|
|
/* the ultimate fallback, assume fixed 24x80 size */ |
274 |
✗✓ |
3 |
if (*linep <= 0) { |
275 |
|
|
*linep = 24; |
276 |
|
|
} |
277 |
✗✓ |
3 |
if (*colp <= 0) { |
278 |
|
|
*colp = 80; |
279 |
|
|
} |
280 |
|
|
|
281 |
|
|
/* |
282 |
|
|
* Put the derived values back in the screen-size caps, so |
283 |
|
|
* tigetnum() and tgetnum() will do the right thing. |
284 |
|
|
*/ |
285 |
|
3 |
lines = (short) (*linep); |
286 |
|
3 |
columns = (short) (*colp); |
287 |
|
|
} |
288 |
|
|
|
289 |
|
|
T(("screen size is %dx%d", *linep, *colp)); |
290 |
|
|
|
291 |
✓✗ |
3 |
if (VALID_NUMERIC(init_tabs)) |
292 |
|
3 |
my_tabsize = (int) init_tabs; |
293 |
|
|
else |
294 |
|
|
my_tabsize = 8; |
295 |
|
|
|
296 |
|
|
#if USE_REENTRANT |
297 |
|
|
if (sp != 0) |
298 |
|
|
sp->_TABSIZE = my_tabsize; |
299 |
|
|
#else |
300 |
|
3 |
TABSIZE = my_tabsize; |
301 |
|
|
#endif |
302 |
|
|
T(("TABSIZE = %d", TABSIZE)); |
303 |
|
3 |
} |
304 |
|
|
|
305 |
|
|
#if USE_SIZECHANGE |
306 |
|
|
NCURSES_EXPORT(void) |
307 |
|
|
_nc_update_screensize(SCREEN *sp) |
308 |
|
|
{ |
309 |
|
|
TERMINAL *termp = cur_term; |
310 |
|
|
int old_lines = lines; |
311 |
|
|
int new_lines; |
312 |
|
|
int old_cols = columns; |
313 |
|
|
int new_cols; |
314 |
|
|
|
315 |
|
|
_nc_get_screensize(sp, &new_lines, &new_cols); |
316 |
|
|
|
317 |
|
|
/* |
318 |
|
|
* See is_term_resized() and resizeterm(). |
319 |
|
|
* We're doing it this way because those functions belong to the upper |
320 |
|
|
* ncurses library, while this resides in the lower terminfo library. |
321 |
|
|
*/ |
322 |
|
|
if (sp != 0 |
323 |
|
|
&& sp->_resize != 0) { |
324 |
|
|
if ((new_lines != old_lines) || (new_cols != old_cols)) |
325 |
|
|
sp->_resize(new_lines, new_cols); |
326 |
|
|
sp->_sig_winch = FALSE; |
327 |
|
|
} |
328 |
|
|
} |
329 |
|
|
#endif |
330 |
|
|
|
331 |
|
|
/**************************************************************************** |
332 |
|
|
* |
333 |
|
|
* Terminal setup |
334 |
|
|
* |
335 |
|
|
****************************************************************************/ |
336 |
|
|
|
337 |
|
|
#define ret_error(code, fmt, arg) if (errret) {\ |
338 |
|
|
*errret = code;\ |
339 |
|
|
returnCode(ERR);\ |
340 |
|
|
} else {\ |
341 |
|
|
fprintf(stderr, fmt, arg);\ |
342 |
|
|
exit(EXIT_FAILURE);\ |
343 |
|
|
} |
344 |
|
|
|
345 |
|
|
#define ret_error0(code, msg) if (errret) {\ |
346 |
|
|
*errret = code;\ |
347 |
|
|
returnCode(ERR);\ |
348 |
|
|
} else {\ |
349 |
|
|
fprintf(stderr, msg);\ |
350 |
|
|
exit(EXIT_FAILURE);\ |
351 |
|
|
} |
352 |
|
|
|
353 |
|
|
#if USE_DATABASE || USE_TERMCAP |
354 |
|
|
/* |
355 |
|
|
* Return 1 if entry found, 0 if not found, -1 if database not accessible, |
356 |
|
|
* just like tgetent(). |
357 |
|
|
*/ |
358 |
|
|
static int |
359 |
|
|
grab_entry(const char *const tn, TERMTYPE *const tp) |
360 |
|
|
{ |
361 |
|
6 |
char filename[PATH_MAX]; |
362 |
|
3 |
int status = _nc_read_entry(tn, filename, tp); |
363 |
|
|
|
364 |
|
|
/* |
365 |
|
|
* If we have an entry, force all of the cancelled strings to null |
366 |
|
|
* pointers so we don't have to test them in the rest of the library. |
367 |
|
|
* (The terminfo compiler bypasses this logic, since it must know if |
368 |
|
|
* a string is cancelled, for merging entries). |
369 |
|
|
*/ |
370 |
✓✗ |
3 |
if (status == TGETENT_YES) { |
371 |
|
|
unsigned n; |
372 |
✓✓ |
288 |
for_each_boolean(n, tp) { |
373 |
✗✓ |
141 |
if (!VALID_BOOLEAN(tp->Booleans[n])) |
374 |
|
|
tp->Booleans[n] = FALSE; |
375 |
|
|
} |
376 |
✓✓ |
2532 |
for_each_string(n, tp) { |
377 |
✗✓ |
1263 |
if (tp->Strings[n] == CANCELLED_STRING) |
378 |
|
|
tp->Strings[n] = ABSENT_STRING; |
379 |
|
|
} |
380 |
|
3 |
} |
381 |
|
3 |
return (status); |
382 |
|
3 |
} |
383 |
|
|
#endif |
384 |
|
|
|
385 |
|
|
/* |
386 |
|
|
** do_prototype() |
387 |
|
|
** |
388 |
|
|
** Take the real command character out of the CC environment variable |
389 |
|
|
** and substitute it in for the prototype given in 'command_character'. |
390 |
|
|
*/ |
391 |
|
|
static void |
392 |
|
|
do_prototype(TERMINAL * termp) |
393 |
|
|
{ |
394 |
|
|
unsigned i; |
395 |
|
|
char CC; |
396 |
|
|
char proto; |
397 |
|
|
char *tmp; |
398 |
|
|
|
399 |
|
|
if ((tmp = getenv("CC")) != 0) { |
400 |
|
|
if ((CC = *tmp) != 0) { |
401 |
|
|
proto = *command_character; |
402 |
|
|
|
403 |
|
|
for_each_string(i, &(termp->type)) { |
404 |
|
|
for (tmp = termp->type.Strings[i]; *tmp; tmp++) { |
405 |
|
|
if (*tmp == proto) |
406 |
|
|
*tmp = CC; |
407 |
|
|
} |
408 |
|
|
} |
409 |
|
|
} |
410 |
|
|
} |
411 |
|
|
} |
412 |
|
|
|
413 |
|
|
/* |
414 |
|
|
* Find the locale which is in effect. |
415 |
|
|
*/ |
416 |
|
|
NCURSES_EXPORT(char *) |
417 |
|
|
_nc_get_locale(void) |
418 |
|
|
{ |
419 |
|
|
char *env; |
420 |
|
|
#if HAVE_LOCALE_H |
421 |
|
|
/* |
422 |
|
|
* This is preferable to using getenv() since it ensures that we are using |
423 |
|
|
* the locale which was actually initialized by the application. |
424 |
|
|
*/ |
425 |
|
|
env = setlocale(LC_CTYPE, 0); |
426 |
|
|
#else |
427 |
|
|
if (((env = getenv("LC_ALL")) != 0 && *env != '\0') |
428 |
|
|
|| ((env = getenv("LC_CTYPE")) != 0 && *env != '\0') |
429 |
|
|
|| ((env = getenv("LANG")) != 0 && *env != '\0')) { |
430 |
|
|
; |
431 |
|
|
} |
432 |
|
|
#endif |
433 |
|
|
T(("_nc_get_locale %s", _nc_visbuf(env))); |
434 |
|
|
return env; |
435 |
|
|
} |
436 |
|
|
|
437 |
|
|
/* |
438 |
|
|
* Check if we are running in a UTF-8 locale. |
439 |
|
|
*/ |
440 |
|
|
NCURSES_EXPORT(int) |
441 |
|
|
_nc_unicode_locale(void) |
442 |
|
|
{ |
443 |
|
|
int result = 0; |
444 |
|
|
#if HAVE_LANGINFO_CODESET |
445 |
|
|
char *env = nl_langinfo(CODESET); |
446 |
|
|
result = !strcmp(env, "UTF-8"); |
447 |
|
|
T(("_nc_unicode_locale(%s) ->%d", env, result)); |
448 |
|
|
#else |
449 |
|
|
char *env = _nc_get_locale(); |
450 |
|
|
if (env != 0) { |
451 |
|
|
if (strstr(env, ".UTF-8") != 0) { |
452 |
|
|
result = 1; |
453 |
|
|
T(("_nc_unicode_locale(%s) ->%d", env, result)); |
454 |
|
|
} |
455 |
|
|
} |
456 |
|
|
#endif |
457 |
|
|
return result; |
458 |
|
|
} |
459 |
|
|
|
460 |
|
|
#define CONTROL_N(s) ((s) != 0 && strstr(s, "\016") != 0) |
461 |
|
|
#define CONTROL_O(s) ((s) != 0 && strstr(s, "\017") != 0) |
462 |
|
|
|
463 |
|
|
/* |
464 |
|
|
* Check for known broken cases where a UTF-8 locale breaks the alternate |
465 |
|
|
* character set. |
466 |
|
|
*/ |
467 |
|
|
NCURSES_EXPORT(int) |
468 |
|
|
_nc_locale_breaks_acs(TERMINAL * termp) |
469 |
|
|
{ |
470 |
|
|
char *env; |
471 |
|
|
|
472 |
|
|
if ((env = getenv("NCURSES_NO_UTF8_ACS")) != 0) { |
473 |
|
|
return atoi(env); |
474 |
|
|
} else if ((env = getenv("TERM")) != 0) { |
475 |
|
|
if (strstr(env, "linux")) |
476 |
|
|
return 1; /* always broken */ |
477 |
|
|
if (strstr(env, "screen") != 0 |
478 |
|
|
&& ((env = getenv("TERMCAP")) != 0 |
479 |
|
|
&& strstr(env, "screen") != 0) |
480 |
|
|
&& strstr(env, "hhII00") != 0) { |
481 |
|
|
if (CONTROL_N(enter_alt_charset_mode) || |
482 |
|
|
CONTROL_O(enter_alt_charset_mode) || |
483 |
|
|
CONTROL_N(set_attributes) || |
484 |
|
|
CONTROL_O(set_attributes)) |
485 |
|
|
return 1; |
486 |
|
|
} |
487 |
|
|
} |
488 |
|
|
return 0; |
489 |
|
|
} |
490 |
|
|
|
491 |
|
|
/* |
492 |
|
|
* This entrypoint is called from tgetent() to allow a special case of reusing |
493 |
|
|
* the same TERMINAL data (see comment). |
494 |
|
|
*/ |
495 |
|
|
NCURSES_EXPORT(int) |
496 |
|
|
_nc_setupterm(NCURSES_CONST char *tname, int Filedes, int *errret, bool reuse) |
497 |
|
|
{ |
498 |
|
|
TERMINAL *termp; |
499 |
|
|
int status; |
500 |
|
|
|
501 |
|
|
START_TRACE(); |
502 |
|
|
T((T_CALLED("setupterm(%s,%d,%p)"), _nc_visbuf(tname), Filedes, errret)); |
503 |
|
|
|
504 |
✗✓ |
3 |
if (tname == 0) { |
505 |
|
|
tname = getenv("TERM"); |
506 |
|
|
if (tname == 0 || *tname == '\0') { |
507 |
|
|
ret_error0(TGETENT_ERR, "TERM environment variable not set.\n"); |
508 |
|
|
} |
509 |
|
|
} |
510 |
|
|
|
511 |
✗✓ |
3 |
if (strlen(tname) > MAX_NAME_SIZE) { |
512 |
|
|
ret_error(TGETENT_ERR, |
513 |
|
|
"TERM environment must be <= %d characters.\n", |
514 |
|
|
MAX_NAME_SIZE); |
515 |
|
|
} |
516 |
|
|
|
517 |
|
|
T(("your terminal name is %s", tname)); |
518 |
|
|
|
519 |
|
|
/* |
520 |
|
|
* Allow output redirection. This is what SVr3 does. If stdout is |
521 |
|
|
* directed to a file, screen updates go to standard error. |
522 |
|
|
*/ |
523 |
✓✗✓✓
|
6 |
if (Filedes == STDOUT_FILENO && !isatty(Filedes)) |
524 |
|
1 |
Filedes = STDERR_FILENO; |
525 |
|
|
|
526 |
|
|
/* |
527 |
|
|
* Check if we have already initialized to use this terminal. If so, we |
528 |
|
|
* do not need to re-read the terminfo entry, or obtain TTY settings. |
529 |
|
|
* |
530 |
|
|
* This is an improvement on SVr4 curses. If an application mixes curses |
531 |
|
|
* and termcap calls, it may call both initscr and tgetent. This is not |
532 |
|
|
* really a good thing to do, but can happen if someone tries using ncurses |
533 |
|
|
* with the readline library. The problem we are fixing is that when |
534 |
|
|
* tgetent calls setupterm, the resulting Ottyb struct in cur_term is |
535 |
|
|
* zeroed. A subsequent call to endwin uses the zeroed terminal settings |
536 |
|
|
* rather than the ones saved in initscr. So we check if cur_term appears |
537 |
|
|
* to contain terminal settings for the same output file as our current |
538 |
|
|
* call - and copy those terminal settings. (SVr4 curses does not do this, |
539 |
|
|
* however applications that are working around the problem will still work |
540 |
|
|
* properly with this feature). |
541 |
|
|
*/ |
542 |
|
|
if (reuse |
543 |
✓✗ |
6 |
&& (termp = cur_term) != 0 |
544 |
✗✓ |
3 |
&& termp->Filedes == Filedes |
545 |
|
|
&& termp->_termname != 0 |
546 |
|
|
&& !strcmp(termp->_termname, tname) |
547 |
|
|
&& _nc_name_match(termp->type.term_names, tname, "|")) { |
548 |
|
|
T(("reusing existing terminal information and mode-settings")); |
549 |
|
|
} else { |
550 |
|
|
|
551 |
|
3 |
termp = typeCalloc(TERMINAL, 1); |
552 |
|
|
|
553 |
✗✓ |
3 |
if (termp == 0) { |
554 |
|
|
ret_error0(TGETENT_ERR, |
555 |
|
|
"Not enough memory to create terminal structure.\n"); |
556 |
|
|
} |
557 |
|
|
#if USE_DATABASE || USE_TERMCAP |
558 |
|
3 |
status = grab_entry(tname, &termp->type); |
559 |
|
|
#else |
560 |
|
|
status = TGETENT_NO; |
561 |
|
|
#endif |
562 |
|
|
|
563 |
|
|
/* try fallback list if entry on disk */ |
564 |
✗✓ |
3 |
if (status != TGETENT_YES) { |
565 |
|
|
const TERMTYPE *fallback = _nc_fallback(tname); |
566 |
|
|
|
567 |
|
|
if (fallback) { |
568 |
|
|
termp->type = *fallback; |
569 |
|
|
status = TGETENT_YES; |
570 |
|
|
} |
571 |
|
|
} |
572 |
|
|
|
573 |
✗✓ |
3 |
if (status != TGETENT_YES) { |
574 |
|
|
del_curterm(termp); |
575 |
|
|
if (status == TGETENT_ERR) { |
576 |
|
|
ret_error0(status, "terminals database is inaccessible\n"); |
577 |
|
|
} else if (status == TGETENT_NO) { |
578 |
|
|
ret_error(status, "'%s': unknown terminal type.\n", tname); |
579 |
|
|
} |
580 |
|
|
} |
581 |
|
|
#if !USE_REENTRANT |
582 |
|
3 |
strncpy(ttytype, termp->type.term_names, NAMESIZE - 1); |
583 |
|
3 |
ttytype[NAMESIZE - 1] = '\0'; |
584 |
|
|
#endif |
585 |
|
|
|
586 |
|
3 |
termp->Filedes = Filedes; |
587 |
|
3 |
termp->_termname = strdup(tname); |
588 |
|
|
|
589 |
|
3 |
set_curterm(termp); |
590 |
|
|
|
591 |
✗✓✗✗
|
3 |
if (command_character && getenv("CC")) |
592 |
|
|
do_prototype(termp); |
593 |
|
|
|
594 |
|
|
/* |
595 |
|
|
* If an application calls setupterm() rather than initscr() or |
596 |
|
|
* newterm(), we will not have the def_prog_mode() call in |
597 |
|
|
* _nc_setupscreen(). Do it now anyway, so we can initialize the |
598 |
|
|
* baudrate. |
599 |
|
|
*/ |
600 |
✓✓ |
3 |
if (isatty(Filedes)) { |
601 |
|
2 |
def_prog_mode(); |
602 |
|
2 |
baudrate(); |
603 |
|
2 |
} |
604 |
|
|
} |
605 |
|
|
|
606 |
|
|
/* |
607 |
|
|
* We should always check the screensize, just in case. |
608 |
|
|
*/ |
609 |
|
3 |
_nc_get_screensize(SP, ptrLines(), ptrCols()); |
610 |
|
|
|
611 |
✓✗ |
3 |
if (errret) |
612 |
|
3 |
*errret = TGETENT_YES; |
613 |
|
|
|
614 |
✗✓ |
3 |
if (generic_type) { |
615 |
|
|
ret_error(TGETENT_NO, "'%s': I need something more specific.\n", tname); |
616 |
|
|
} |
617 |
✗✓ |
3 |
if (hard_copy) { |
618 |
|
|
ret_error(TGETENT_YES, "'%s': I can't handle hardcopy terminals.\n", tname); |
619 |
|
|
} |
620 |
|
3 |
returnCode(OK); |
621 |
|
3 |
} |
622 |
|
|
|
623 |
|
|
/* |
624 |
|
|
* setupterm(termname, Filedes, errret) |
625 |
|
|
* |
626 |
|
|
* Find and read the appropriate object file for the terminal |
627 |
|
|
* Make cur_term point to the structure. |
628 |
|
|
*/ |
629 |
|
|
NCURSES_EXPORT(int) |
630 |
|
|
setupterm(NCURSES_CONST char *tname, int Filedes, int *errret) |
631 |
|
|
{ |
632 |
|
|
return _nc_setupterm(tname, Filedes, errret, FALSE); |
633 |
|
|
} |