1fdd4e1e0SJan Lentfer /****************************************************************************
2*32bb5217SDaniel Fojt * Copyright 2018-2019,2020 Thomas E. Dickey *
3*32bb5217SDaniel Fojt * Copyright 1998-2016,2017 Free Software Foundation, Inc. *
4fdd4e1e0SJan Lentfer * *
5fdd4e1e0SJan Lentfer * Permission is hereby granted, free of charge, to any person obtaining a *
6fdd4e1e0SJan Lentfer * copy of this software and associated documentation files (the *
7fdd4e1e0SJan Lentfer * "Software"), to deal in the Software without restriction, including *
8fdd4e1e0SJan Lentfer * without limitation the rights to use, copy, modify, merge, publish, *
9fdd4e1e0SJan Lentfer * distribute, distribute with modifications, sublicense, and/or sell *
10fdd4e1e0SJan Lentfer * copies of the Software, and to permit persons to whom the Software is *
11fdd4e1e0SJan Lentfer * furnished to do so, subject to the following conditions: *
12fdd4e1e0SJan Lentfer * *
13fdd4e1e0SJan Lentfer * The above copyright notice and this permission notice shall be included *
14fdd4e1e0SJan Lentfer * in all copies or substantial portions of the Software. *
15fdd4e1e0SJan Lentfer * *
16fdd4e1e0SJan Lentfer * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
17fdd4e1e0SJan Lentfer * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
18fdd4e1e0SJan Lentfer * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
19fdd4e1e0SJan Lentfer * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
20fdd4e1e0SJan Lentfer * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
21fdd4e1e0SJan Lentfer * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
22fdd4e1e0SJan Lentfer * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
23fdd4e1e0SJan Lentfer * *
24fdd4e1e0SJan Lentfer * Except as contained in this notice, the name(s) of the above copyright *
25fdd4e1e0SJan Lentfer * holders shall not be used in advertising or otherwise to promote the *
26fdd4e1e0SJan Lentfer * sale, use or other dealings in this Software without prior written *
27fdd4e1e0SJan Lentfer * authorization. *
28fdd4e1e0SJan Lentfer ****************************************************************************/
29fdd4e1e0SJan Lentfer
30fdd4e1e0SJan Lentfer /****************************************************************************
31fdd4e1e0SJan Lentfer * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
32fdd4e1e0SJan Lentfer * and: Eric S. Raymond <esr@snark.thyrsus.com> *
331d102085SJan Lentfer * and: Thomas E. Dickey 1996-on *
3400d8f3c4SJohn Marino * and: Juergen Pfeifer 2009 *
35fdd4e1e0SJan Lentfer ****************************************************************************/
36fdd4e1e0SJan Lentfer
37fdd4e1e0SJan Lentfer /*
38fdd4e1e0SJan Lentfer * Terminal setup routines common to termcap and terminfo:
39fdd4e1e0SJan Lentfer *
40fdd4e1e0SJan Lentfer * use_env(bool)
413468e90cSJohn Marino * use_tioctl(bool)
42fdd4e1e0SJan Lentfer * setupterm(char *, int, int *)
43fdd4e1e0SJan Lentfer */
44fdd4e1e0SJan Lentfer
45fdd4e1e0SJan Lentfer #include <curses.priv.h>
46fdd4e1e0SJan Lentfer #include <tic.h> /* for MAX_NAME_SIZE */
47fdd4e1e0SJan Lentfer
481d102085SJan Lentfer #if HAVE_LOCALE_H
491d102085SJan Lentfer #include <locale.h>
501d102085SJan Lentfer #endif
511d102085SJan Lentfer
52*32bb5217SDaniel Fojt MODULE_ID("$Id: lib_setup.c,v 1.207 2020/02/02 23:34:34 tom Exp $")
53fdd4e1e0SJan Lentfer
54fdd4e1e0SJan Lentfer /****************************************************************************
55fdd4e1e0SJan Lentfer *
56fdd4e1e0SJan Lentfer * Terminal size computation
57fdd4e1e0SJan Lentfer *
58fdd4e1e0SJan Lentfer ****************************************************************************/
59fdd4e1e0SJan Lentfer
60fdd4e1e0SJan Lentfer #if HAVE_SIZECHANGE
61fdd4e1e0SJan Lentfer # if !defined(sun) || !TERMIOS
62fdd4e1e0SJan Lentfer # if HAVE_SYS_IOCTL_H
63fdd4e1e0SJan Lentfer # include <sys/ioctl.h>
64fdd4e1e0SJan Lentfer # endif
65fdd4e1e0SJan Lentfer # endif
66fdd4e1e0SJan Lentfer #endif
67fdd4e1e0SJan Lentfer
68fdd4e1e0SJan Lentfer #if NEED_PTEM_H
69fdd4e1e0SJan Lentfer /* On SCO, they neglected to define struct winsize in termios.h -- it's only
70fdd4e1e0SJan Lentfer * in termio.h and ptem.h (the former conflicts with other definitions).
71fdd4e1e0SJan Lentfer */
72fdd4e1e0SJan Lentfer # include <sys/stream.h>
73fdd4e1e0SJan Lentfer # include <sys/ptem.h>
74fdd4e1e0SJan Lentfer #endif
75fdd4e1e0SJan Lentfer
761d102085SJan Lentfer #if HAVE_LANGINFO_CODESET
771d102085SJan Lentfer #include <langinfo.h>
781d102085SJan Lentfer #endif
791d102085SJan Lentfer
80fdd4e1e0SJan Lentfer /*
81fdd4e1e0SJan Lentfer * SCO defines TIOCGSIZE and the corresponding struct. Other systems (SunOS,
82fdd4e1e0SJan Lentfer * Solaris, IRIX) define TIOCGWINSZ and struct winsize.
83fdd4e1e0SJan Lentfer */
84fdd4e1e0SJan Lentfer #ifdef TIOCGSIZE
85fdd4e1e0SJan Lentfer # define IOCTL_WINSIZE TIOCGSIZE
86fdd4e1e0SJan Lentfer # define STRUCT_WINSIZE struct ttysize
87fdd4e1e0SJan Lentfer # define WINSIZE_ROWS(n) (int)n.ts_lines
88fdd4e1e0SJan Lentfer # define WINSIZE_COLS(n) (int)n.ts_cols
89fdd4e1e0SJan Lentfer #else
90fdd4e1e0SJan Lentfer # ifdef TIOCGWINSZ
91fdd4e1e0SJan Lentfer # define IOCTL_WINSIZE TIOCGWINSZ
92fdd4e1e0SJan Lentfer # define STRUCT_WINSIZE struct winsize
93fdd4e1e0SJan Lentfer # define WINSIZE_ROWS(n) (int)n.ws_row
94fdd4e1e0SJan Lentfer # define WINSIZE_COLS(n) (int)n.ws_col
95fdd4e1e0SJan Lentfer # endif
96fdd4e1e0SJan Lentfer #endif
97fdd4e1e0SJan Lentfer
981d102085SJan Lentfer /*
991d102085SJan Lentfer * Reduce explicit use of "cur_term" global variable.
1001d102085SJan Lentfer */
1011d102085SJan Lentfer #undef CUR
102*32bb5217SDaniel Fojt #define CUR TerminalType(termp).
1031d102085SJan Lentfer
1041d102085SJan Lentfer /*
1051d102085SJan Lentfer * Wrap global variables in this module.
1061d102085SJan Lentfer */
1071d102085SJan Lentfer #if USE_REENTRANT
10800d8f3c4SJohn Marino
NCURSES_EXPORT(char *)1091d102085SJan Lentfer NCURSES_EXPORT(char *)
1101d102085SJan Lentfer NCURSES_PUBLIC_VAR(ttytype) (void)
1111d102085SJan Lentfer {
1121d102085SJan Lentfer static char empty[] = "";
11300d8f3c4SJohn Marino char *result = empty;
11400d8f3c4SJohn Marino
11500d8f3c4SJohn Marino #if NCURSES_SP_FUNCS
11600d8f3c4SJohn Marino if (CURRENT_SCREEN) {
11700d8f3c4SJohn Marino TERMINAL *termp = TerminalOf(CURRENT_SCREEN);
11800d8f3c4SJohn Marino if (termp != 0) {
119*32bb5217SDaniel Fojt result = TerminalType(termp).term_names;
1201d102085SJan Lentfer }
12100d8f3c4SJohn Marino }
12200d8f3c4SJohn Marino #else
12300d8f3c4SJohn Marino if (cur_term != 0) {
124*32bb5217SDaniel Fojt result = TerminalType(cur_term).term_names;
12500d8f3c4SJohn Marino }
12600d8f3c4SJohn Marino #endif
12700d8f3c4SJohn Marino return result;
12800d8f3c4SJohn Marino }
12900d8f3c4SJohn Marino
1301d102085SJan Lentfer NCURSES_EXPORT(int *)
_nc_ptr_Lines(SCREEN * sp)13100d8f3c4SJohn Marino _nc_ptr_Lines(SCREEN *sp)
1321d102085SJan Lentfer {
13300d8f3c4SJohn Marino return ptrLines(sp);
1341d102085SJan Lentfer }
13500d8f3c4SJohn Marino
1361d102085SJan Lentfer NCURSES_EXPORT(int)
NCURSES_PUBLIC_VAR(LINES)1371d102085SJan Lentfer NCURSES_PUBLIC_VAR(LINES) (void)
1381d102085SJan Lentfer {
13900d8f3c4SJohn Marino return *_nc_ptr_Lines(CURRENT_SCREEN);
1401d102085SJan Lentfer }
14100d8f3c4SJohn Marino
1421d102085SJan Lentfer NCURSES_EXPORT(int *)
_nc_ptr_Cols(SCREEN * sp)14300d8f3c4SJohn Marino _nc_ptr_Cols(SCREEN *sp)
1441d102085SJan Lentfer {
14500d8f3c4SJohn Marino return ptrCols(sp);
1461d102085SJan Lentfer }
14700d8f3c4SJohn Marino
1481d102085SJan Lentfer NCURSES_EXPORT(int)
NCURSES_PUBLIC_VAR(COLS)1491d102085SJan Lentfer NCURSES_PUBLIC_VAR(COLS) (void)
1501d102085SJan Lentfer {
15100d8f3c4SJohn Marino return *_nc_ptr_Cols(CURRENT_SCREEN);
1521d102085SJan Lentfer }
15300d8f3c4SJohn Marino
15400d8f3c4SJohn Marino NCURSES_EXPORT(int *)
_nc_ptr_Tabsize(SCREEN * sp)15500d8f3c4SJohn Marino _nc_ptr_Tabsize(SCREEN *sp)
15600d8f3c4SJohn Marino {
15700d8f3c4SJohn Marino return ptrTabsize(sp);
15800d8f3c4SJohn Marino }
15900d8f3c4SJohn Marino
1601d102085SJan Lentfer NCURSES_EXPORT(int)
NCURSES_PUBLIC_VAR(TABSIZE)1611d102085SJan Lentfer NCURSES_PUBLIC_VAR(TABSIZE) (void)
1621d102085SJan Lentfer {
16300d8f3c4SJohn Marino return *_nc_ptr_Tabsize(CURRENT_SCREEN);
1641d102085SJan Lentfer }
1651d102085SJan Lentfer #else
166fdd4e1e0SJan Lentfer NCURSES_EXPORT_VAR(char) ttytype[NAMESIZE] = "";
167fdd4e1e0SJan Lentfer NCURSES_EXPORT_VAR(int) LINES = 0;
168fdd4e1e0SJan Lentfer NCURSES_EXPORT_VAR(int) COLS = 0;
16900d8f3c4SJohn Marino NCURSES_EXPORT_VAR(int) TABSIZE = 8;
1701d102085SJan Lentfer #endif
171fdd4e1e0SJan Lentfer
1721d102085SJan Lentfer #if NCURSES_EXT_FUNCS
1731d102085SJan Lentfer NCURSES_EXPORT(int)
NCURSES_SP_NAME(set_tabsize)17400d8f3c4SJohn Marino NCURSES_SP_NAME(set_tabsize) (NCURSES_SP_DCLx int value)
1751d102085SJan Lentfer {
1761d102085SJan Lentfer int code = OK;
177*32bb5217SDaniel Fojt if (value <= 0) {
178*32bb5217SDaniel Fojt code = ERR;
179*32bb5217SDaniel Fojt } else {
1801d102085SJan Lentfer #if USE_REENTRANT
18100d8f3c4SJohn Marino if (SP_PARM) {
18200d8f3c4SJohn Marino SP_PARM->_TABSIZE = value;
1831d102085SJan Lentfer } else {
1841d102085SJan Lentfer code = ERR;
1851d102085SJan Lentfer }
1861d102085SJan Lentfer #else
18700d8f3c4SJohn Marino (void) SP_PARM;
1881d102085SJan Lentfer TABSIZE = value;
1891d102085SJan Lentfer #endif
190*32bb5217SDaniel Fojt }
1911d102085SJan Lentfer return code;
1921d102085SJan Lentfer }
19300d8f3c4SJohn Marino
19400d8f3c4SJohn Marino #if NCURSES_SP_FUNCS
19500d8f3c4SJohn Marino NCURSES_EXPORT(int)
set_tabsize(int value)19600d8f3c4SJohn Marino set_tabsize(int value)
19700d8f3c4SJohn Marino {
19800d8f3c4SJohn Marino return NCURSES_SP_NAME(set_tabsize) (CURRENT_SCREEN, value);
19900d8f3c4SJohn Marino }
2001d102085SJan Lentfer #endif
20100d8f3c4SJohn Marino #endif /* NCURSES_EXT_FUNCS */
2021d102085SJan Lentfer
2031d102085SJan Lentfer #if USE_SIGWINCH
2041d102085SJan Lentfer /*
2051d102085SJan Lentfer * If we have a pending SIGWINCH, set the flag in each screen.
2061d102085SJan Lentfer */
2071d102085SJan Lentfer NCURSES_EXPORT(int)
_nc_handle_sigwinch(SCREEN * sp)2081d102085SJan Lentfer _nc_handle_sigwinch(SCREEN *sp)
2091d102085SJan Lentfer {
2101d102085SJan Lentfer SCREEN *scan;
2111d102085SJan Lentfer
2121d102085SJan Lentfer if (_nc_globals.have_sigwinch) {
2131d102085SJan Lentfer _nc_globals.have_sigwinch = 0;
2141d102085SJan Lentfer
2151d102085SJan Lentfer for (each_screen(scan)) {
2161d102085SJan Lentfer scan->_sig_winch = TRUE;
2171d102085SJan Lentfer }
2181d102085SJan Lentfer }
2191d102085SJan Lentfer
2201d102085SJan Lentfer return (sp ? sp->_sig_winch : 0);
2211d102085SJan Lentfer }
2221d102085SJan Lentfer
2231d102085SJan Lentfer #endif
224fdd4e1e0SJan Lentfer
225fdd4e1e0SJan Lentfer NCURSES_EXPORT(void)
NCURSES_SP_NAME(use_env)22600d8f3c4SJohn Marino NCURSES_SP_NAME(use_env) (NCURSES_SP_DCLx bool f)
227fdd4e1e0SJan Lentfer {
228*32bb5217SDaniel Fojt START_TRACE();
22900d8f3c4SJohn Marino T((T_CALLED("use_env(%p,%d)"), (void *) SP_PARM, (int) f));
23000d8f3c4SJohn Marino #if NCURSES_SP_FUNCS
23100d8f3c4SJohn Marino if (IsPreScreen(SP_PARM)) {
23200d8f3c4SJohn Marino SP_PARM->_use_env = f;
23300d8f3c4SJohn Marino }
23400d8f3c4SJohn Marino #else
2351d102085SJan Lentfer _nc_prescreen.use_env = f;
23600d8f3c4SJohn Marino #endif
237fdd4e1e0SJan Lentfer returnVoid;
238fdd4e1e0SJan Lentfer }
239fdd4e1e0SJan Lentfer
2403468e90cSJohn Marino NCURSES_EXPORT(void)
NCURSES_SP_NAME(use_tioctl)2413468e90cSJohn Marino NCURSES_SP_NAME(use_tioctl) (NCURSES_SP_DCLx bool f)
2423468e90cSJohn Marino {
243*32bb5217SDaniel Fojt START_TRACE();
2443468e90cSJohn Marino T((T_CALLED("use_tioctl(%p,%d)"), (void *) SP_PARM, (int) f));
2453468e90cSJohn Marino #if NCURSES_SP_FUNCS
2463468e90cSJohn Marino if (IsPreScreen(SP_PARM)) {
247*32bb5217SDaniel Fojt SP_PARM->use_tioctl = f;
2483468e90cSJohn Marino }
2493468e90cSJohn Marino #else
2503468e90cSJohn Marino _nc_prescreen.use_tioctl = f;
2513468e90cSJohn Marino #endif
2523468e90cSJohn Marino returnVoid;
2533468e90cSJohn Marino }
2543468e90cSJohn Marino
25500d8f3c4SJohn Marino #if NCURSES_SP_FUNCS
2561d102085SJan Lentfer NCURSES_EXPORT(void)
use_env(bool f)25700d8f3c4SJohn Marino use_env(bool f)
25800d8f3c4SJohn Marino {
2593468e90cSJohn Marino START_TRACE();
260*32bb5217SDaniel Fojt T((T_CALLED("use_env(%d)"), (int) f));
26100d8f3c4SJohn Marino _nc_prescreen.use_env = f;
26200d8f3c4SJohn Marino returnVoid;
26300d8f3c4SJohn Marino }
2643468e90cSJohn Marino
2653468e90cSJohn Marino NCURSES_EXPORT(void)
use_tioctl(bool f)2663468e90cSJohn Marino use_tioctl(bool f)
2673468e90cSJohn Marino {
2683468e90cSJohn Marino START_TRACE();
269*32bb5217SDaniel Fojt T((T_CALLED("use_tioctl(%d)"), (int) f));
2703468e90cSJohn Marino _nc_prescreen.use_tioctl = f;
2713468e90cSJohn Marino returnVoid;
2723468e90cSJohn Marino }
27300d8f3c4SJohn Marino #endif
27400d8f3c4SJohn Marino
27500d8f3c4SJohn Marino NCURSES_EXPORT(void)
_nc_get_screensize(SCREEN * sp,TERMINAL * termp,int * linep,int * colp)27600d8f3c4SJohn Marino _nc_get_screensize(SCREEN *sp,
27700d8f3c4SJohn Marino #ifdef USE_TERM_DRIVER
27800d8f3c4SJohn Marino TERMINAL *termp,
27900d8f3c4SJohn Marino #endif
28000d8f3c4SJohn Marino int *linep, int *colp)
281fdd4e1e0SJan Lentfer /* Obtain lines/columns values from the environment and/or terminfo entry */
282fdd4e1e0SJan Lentfer {
28300d8f3c4SJohn Marino #ifdef USE_TERM_DRIVER
28400d8f3c4SJohn Marino TERMINAL_CONTROL_BLOCK *TCB;
28500d8f3c4SJohn Marino int my_tabsize;
28600d8f3c4SJohn Marino
28700d8f3c4SJohn Marino assert(termp != 0 && linep != 0 && colp != 0);
28800d8f3c4SJohn Marino TCB = (TERMINAL_CONTROL_BLOCK *) termp;
28900d8f3c4SJohn Marino
29000d8f3c4SJohn Marino my_tabsize = TCB->info.tabsize;
2913468e90cSJohn Marino TCB->drv->td_size(TCB, linep, colp);
29200d8f3c4SJohn Marino
29300d8f3c4SJohn Marino #if USE_REENTRANT
29400d8f3c4SJohn Marino if (sp != 0) {
29500d8f3c4SJohn Marino sp->_TABSIZE = my_tabsize;
29600d8f3c4SJohn Marino }
29700d8f3c4SJohn Marino #else
29800d8f3c4SJohn Marino (void) sp;
29900d8f3c4SJohn Marino TABSIZE = my_tabsize;
30000d8f3c4SJohn Marino #endif
30100d8f3c4SJohn Marino T(("TABSIZE = %d", my_tabsize));
30200d8f3c4SJohn Marino #else /* !USE_TERM_DRIVER */
3031d102085SJan Lentfer TERMINAL *termp = cur_term;
3041d102085SJan Lentfer int my_tabsize;
305*32bb5217SDaniel Fojt bool useEnv = _nc_prescreen.use_env;
306*32bb5217SDaniel Fojt bool useTioctl = _nc_prescreen.use_tioctl;
3071d102085SJan Lentfer
308fdd4e1e0SJan Lentfer /* figure out the size of the screen */
309fdd4e1e0SJan Lentfer T(("screen size: terminfo lines = %d columns = %d", lines, columns));
310fdd4e1e0SJan Lentfer
311fdd4e1e0SJan Lentfer *linep = (int) lines;
312fdd4e1e0SJan Lentfer *colp = (int) columns;
31300d8f3c4SJohn Marino
314*32bb5217SDaniel Fojt #if NCURSES_SP_FUNCS
315*32bb5217SDaniel Fojt if (sp) {
316*32bb5217SDaniel Fojt useEnv = sp->_use_env;
317*32bb5217SDaniel Fojt useTioctl = sp->use_tioctl;
318*32bb5217SDaniel Fojt }
319*32bb5217SDaniel Fojt #endif
320fdd4e1e0SJan Lentfer
321*32bb5217SDaniel Fojt if (useEnv || useTioctl) {
322fdd4e1e0SJan Lentfer #ifdef __EMX__
32300d8f3c4SJohn Marino {
324fdd4e1e0SJan Lentfer int screendata[2];
325fdd4e1e0SJan Lentfer _scrsize(screendata);
326fdd4e1e0SJan Lentfer *colp = screendata[0];
3273468e90cSJohn Marino *linep = ((sp != 0 && sp->_filtered)
3283468e90cSJohn Marino ? 1
3293468e90cSJohn Marino : screendata[1]);
330fdd4e1e0SJan Lentfer T(("EMX screen size: environment LINES = %d COLUMNS = %d",
331fdd4e1e0SJan Lentfer *linep, *colp));
332fdd4e1e0SJan Lentfer }
333fdd4e1e0SJan Lentfer #endif
334fdd4e1e0SJan Lentfer #if HAVE_SIZECHANGE
33500d8f3c4SJohn Marino /* try asking the OS */
3363468e90cSJohn Marino if (NC_ISATTY(cur_term->Filedes)) {
337fdd4e1e0SJan Lentfer STRUCT_WINSIZE size;
338fdd4e1e0SJan Lentfer
339fdd4e1e0SJan Lentfer errno = 0;
340fdd4e1e0SJan Lentfer do {
34100d8f3c4SJohn Marino if (ioctl(cur_term->Filedes, IOCTL_WINSIZE, &size) >= 0) {
34200d8f3c4SJohn Marino *linep = ((sp != 0 && sp->_filtered)
34300d8f3c4SJohn Marino ? 1
34400d8f3c4SJohn Marino : WINSIZE_ROWS(size));
34500d8f3c4SJohn Marino *colp = WINSIZE_COLS(size);
34600d8f3c4SJohn Marino T(("SYS screen size: environment LINES = %d COLUMNS = %d",
34700d8f3c4SJohn Marino *linep, *colp));
34800d8f3c4SJohn Marino break;
34900d8f3c4SJohn Marino }
350fdd4e1e0SJan Lentfer } while
351fdd4e1e0SJan Lentfer (errno == EINTR);
352fdd4e1e0SJan Lentfer }
353fdd4e1e0SJan Lentfer #endif /* HAVE_SIZECHANGE */
354fdd4e1e0SJan Lentfer
355*32bb5217SDaniel Fojt if (useEnv) {
356*32bb5217SDaniel Fojt int value;
357*32bb5217SDaniel Fojt
358*32bb5217SDaniel Fojt if (useTioctl) {
3593468e90cSJohn Marino /*
3603468e90cSJohn Marino * If environment variables are used, update them.
3613468e90cSJohn Marino */
3623468e90cSJohn Marino if ((sp == 0 || !sp->_filtered) && _nc_getenv_num("LINES") > 0) {
3633468e90cSJohn Marino _nc_setenv_num("LINES", *linep);
3643468e90cSJohn Marino }
3653468e90cSJohn Marino if (_nc_getenv_num("COLUMNS") > 0) {
3663468e90cSJohn Marino _nc_setenv_num("COLUMNS", *colp);
3673468e90cSJohn Marino }
3683468e90cSJohn Marino }
3693468e90cSJohn Marino
37000d8f3c4SJohn Marino /*
37100d8f3c4SJohn Marino * Finally, look for environment variables.
37200d8f3c4SJohn Marino *
37300d8f3c4SJohn Marino * Solaris lets users override either dimension with an environment
37400d8f3c4SJohn Marino * variable.
37500d8f3c4SJohn Marino */
37600d8f3c4SJohn Marino if ((value = _nc_getenv_num("LINES")) > 0) {
37700d8f3c4SJohn Marino *linep = value;
37800d8f3c4SJohn Marino T(("screen size: environment LINES = %d", *linep));
37900d8f3c4SJohn Marino }
38000d8f3c4SJohn Marino if ((value = _nc_getenv_num("COLUMNS")) > 0) {
38100d8f3c4SJohn Marino *colp = value;
38200d8f3c4SJohn Marino T(("screen size: environment COLUMNS = %d", *colp));
38300d8f3c4SJohn Marino }
3843468e90cSJohn Marino }
38500d8f3c4SJohn Marino
386fdd4e1e0SJan Lentfer /* if we can't get dynamic info about the size, use static */
387fdd4e1e0SJan Lentfer if (*linep <= 0) {
388fdd4e1e0SJan Lentfer *linep = (int) lines;
389fdd4e1e0SJan Lentfer }
390fdd4e1e0SJan Lentfer if (*colp <= 0) {
391fdd4e1e0SJan Lentfer *colp = (int) columns;
392fdd4e1e0SJan Lentfer }
393fdd4e1e0SJan Lentfer
394fdd4e1e0SJan Lentfer /* the ultimate fallback, assume fixed 24x80 size */
395fdd4e1e0SJan Lentfer if (*linep <= 0) {
396fdd4e1e0SJan Lentfer *linep = 24;
397fdd4e1e0SJan Lentfer }
398fdd4e1e0SJan Lentfer if (*colp <= 0) {
399fdd4e1e0SJan Lentfer *colp = 80;
400fdd4e1e0SJan Lentfer }
401fdd4e1e0SJan Lentfer
402fdd4e1e0SJan Lentfer /*
403fdd4e1e0SJan Lentfer * Put the derived values back in the screen-size caps, so
404fdd4e1e0SJan Lentfer * tigetnum() and tgetnum() will do the right thing.
405fdd4e1e0SJan Lentfer */
406*32bb5217SDaniel Fojt lines = (NCURSES_INT2) (*linep);
407*32bb5217SDaniel Fojt columns = (NCURSES_INT2) (*colp);
408*32bb5217SDaniel Fojt #if NCURSES_EXT_NUMBERS
409*32bb5217SDaniel Fojt #define OldNumber(termp,name) \
410*32bb5217SDaniel Fojt (termp)->type.Numbers[(&name - (termp)->type2.Numbers)]
411*32bb5217SDaniel Fojt OldNumber(termp, lines) = (short) (*linep);
412*32bb5217SDaniel Fojt OldNumber(termp, columns) = (short) (*colp);
413*32bb5217SDaniel Fojt #endif
414fdd4e1e0SJan Lentfer }
415fdd4e1e0SJan Lentfer
416fdd4e1e0SJan Lentfer T(("screen size is %dx%d", *linep, *colp));
417fdd4e1e0SJan Lentfer
418fdd4e1e0SJan Lentfer if (VALID_NUMERIC(init_tabs))
4191d102085SJan Lentfer my_tabsize = (int) init_tabs;
420fdd4e1e0SJan Lentfer else
4211d102085SJan Lentfer my_tabsize = 8;
4221d102085SJan Lentfer
4231d102085SJan Lentfer #if USE_REENTRANT
4241d102085SJan Lentfer if (sp != 0)
4251d102085SJan Lentfer sp->_TABSIZE = my_tabsize;
4261d102085SJan Lentfer #else
4271d102085SJan Lentfer TABSIZE = my_tabsize;
4281d102085SJan Lentfer #endif
429fdd4e1e0SJan Lentfer T(("TABSIZE = %d", TABSIZE));
43000d8f3c4SJohn Marino #endif /* USE_TERM_DRIVER */
431fdd4e1e0SJan Lentfer }
432fdd4e1e0SJan Lentfer
433fdd4e1e0SJan Lentfer #if USE_SIZECHANGE
434fdd4e1e0SJan Lentfer NCURSES_EXPORT(void)
_nc_update_screensize(SCREEN * sp)4351d102085SJan Lentfer _nc_update_screensize(SCREEN *sp)
436fdd4e1e0SJan Lentfer {
4371d102085SJan Lentfer int new_lines;
4381d102085SJan Lentfer int new_cols;
439fdd4e1e0SJan Lentfer
44000d8f3c4SJohn Marino #ifdef USE_TERM_DRIVER
44100d8f3c4SJohn Marino int old_lines;
44200d8f3c4SJohn Marino int old_cols;
44300d8f3c4SJohn Marino
44400d8f3c4SJohn Marino assert(sp != 0);
44500d8f3c4SJohn Marino
4463468e90cSJohn Marino CallDriver_2(sp, td_getsize, &old_lines, &old_cols);
44700d8f3c4SJohn Marino
44800d8f3c4SJohn Marino #else
44900d8f3c4SJohn Marino TERMINAL *termp = cur_term;
45000d8f3c4SJohn Marino int old_lines = lines;
45100d8f3c4SJohn Marino int old_cols = columns;
45200d8f3c4SJohn Marino #endif
45300d8f3c4SJohn Marino
454*32bb5217SDaniel Fojt if (sp != 0) {
45500d8f3c4SJohn Marino TINFO_GET_SIZE(sp, sp->_term, &new_lines, &new_cols);
4561d102085SJan Lentfer /*
4571d102085SJan Lentfer * See is_term_resized() and resizeterm().
4581d102085SJan Lentfer * We're doing it this way because those functions belong to the upper
4591d102085SJan Lentfer * ncurses library, while this resides in the lower terminfo library.
4601d102085SJan Lentfer */
461*32bb5217SDaniel Fojt if (sp->_resize != 0) {
4623468e90cSJohn Marino if ((new_lines != old_lines) || (new_cols != old_cols)) {
46300d8f3c4SJohn Marino sp->_resize(NCURSES_SP_ARGx new_lines, new_cols);
4643468e90cSJohn Marino } else if (sp->_sig_winch && (sp->_ungetch != 0)) {
4653468e90cSJohn Marino sp->_ungetch(SP_PARM, KEY_RESIZE); /* so application can know this */
4663468e90cSJohn Marino }
4671d102085SJan Lentfer sp->_sig_winch = FALSE;
4681d102085SJan Lentfer }
469fdd4e1e0SJan Lentfer }
470*32bb5217SDaniel Fojt }
471*32bb5217SDaniel Fojt #endif /* USE_SIZECHANGE */
472fdd4e1e0SJan Lentfer
473fdd4e1e0SJan Lentfer /****************************************************************************
474fdd4e1e0SJan Lentfer *
475fdd4e1e0SJan Lentfer * Terminal setup
476fdd4e1e0SJan Lentfer *
477fdd4e1e0SJan Lentfer ****************************************************************************/
478fdd4e1e0SJan Lentfer
4793468e90cSJohn Marino #if NCURSES_USE_DATABASE || NCURSES_USE_TERMCAP
4801d102085SJan Lentfer /*
4811d102085SJan Lentfer * Return 1 if entry found, 0 if not found, -1 if database not accessible,
4821d102085SJan Lentfer * just like tgetent().
4831d102085SJan Lentfer */
48400d8f3c4SJohn Marino int
_nc_setup_tinfo(const char * const tn,TERMTYPE2 * const tp)485*32bb5217SDaniel Fojt _nc_setup_tinfo(const char *const tn, TERMTYPE2 *const tp)
486fdd4e1e0SJan Lentfer {
487fdd4e1e0SJan Lentfer char filename[PATH_MAX];
488*32bb5217SDaniel Fojt int status = _nc_read_entry2(tn, filename, tp);
489fdd4e1e0SJan Lentfer
490fdd4e1e0SJan Lentfer /*
491fdd4e1e0SJan Lentfer * If we have an entry, force all of the cancelled strings to null
492fdd4e1e0SJan Lentfer * pointers so we don't have to test them in the rest of the library.
493fdd4e1e0SJan Lentfer * (The terminfo compiler bypasses this logic, since it must know if
494fdd4e1e0SJan Lentfer * a string is cancelled, for merging entries).
495fdd4e1e0SJan Lentfer */
4961d102085SJan Lentfer if (status == TGETENT_YES) {
497fdd4e1e0SJan Lentfer unsigned n;
498fdd4e1e0SJan Lentfer for_each_boolean(n, tp) {
499fdd4e1e0SJan Lentfer if (!VALID_BOOLEAN(tp->Booleans[n]))
500fdd4e1e0SJan Lentfer tp->Booleans[n] = FALSE;
501fdd4e1e0SJan Lentfer }
502fdd4e1e0SJan Lentfer for_each_string(n, tp) {
503fdd4e1e0SJan Lentfer if (tp->Strings[n] == CANCELLED_STRING)
504fdd4e1e0SJan Lentfer tp->Strings[n] = ABSENT_STRING;
505fdd4e1e0SJan Lentfer }
506fdd4e1e0SJan Lentfer }
507fdd4e1e0SJan Lentfer return (status);
508fdd4e1e0SJan Lentfer }
509fdd4e1e0SJan Lentfer #endif
510fdd4e1e0SJan Lentfer
511fdd4e1e0SJan Lentfer /*
512fdd4e1e0SJan Lentfer ** Take the real command character out of the CC environment variable
513fdd4e1e0SJan Lentfer ** and substitute it in for the prototype given in 'command_character'.
514fdd4e1e0SJan Lentfer */
51500d8f3c4SJohn Marino void
_nc_tinfo_cmdch(TERMINAL * termp,int proto)5163468e90cSJohn Marino _nc_tinfo_cmdch(TERMINAL *termp, int proto)
517fdd4e1e0SJan Lentfer {
518fdd4e1e0SJan Lentfer char *tmp;
519fdd4e1e0SJan Lentfer
52000d8f3c4SJohn Marino /*
52100d8f3c4SJohn Marino * Only use the character if the string is a single character,
52200d8f3c4SJohn Marino * since it is fairly common for developers to set the C compiler
52300d8f3c4SJohn Marino * name as an environment variable - using the same symbol.
52400d8f3c4SJohn Marino */
52500d8f3c4SJohn Marino if ((tmp = getenv("CC")) != 0 && strlen(tmp) == 1) {
526*32bb5217SDaniel Fojt unsigned i;
527*32bb5217SDaniel Fojt char CC = *tmp;
528*32bb5217SDaniel Fojt
5291d102085SJan Lentfer for_each_string(i, &(termp->type)) {
5303468e90cSJohn Marino for (tmp = termp->type.Strings[i]; tmp && *tmp; tmp++) {
5313468e90cSJohn Marino if (UChar(*tmp) == proto)
532fdd4e1e0SJan Lentfer *tmp = CC;
533fdd4e1e0SJan Lentfer }
534fdd4e1e0SJan Lentfer }
535fdd4e1e0SJan Lentfer }
5361d102085SJan Lentfer }
537fdd4e1e0SJan Lentfer
538fdd4e1e0SJan Lentfer /*
5391d102085SJan Lentfer * Find the locale which is in effect.
540fdd4e1e0SJan Lentfer */
541fdd4e1e0SJan Lentfer NCURSES_EXPORT(char *)
_nc_get_locale(void)542fdd4e1e0SJan Lentfer _nc_get_locale(void)
543fdd4e1e0SJan Lentfer {
544fdd4e1e0SJan Lentfer char *env;
5451d102085SJan Lentfer #if HAVE_LOCALE_H
5461d102085SJan Lentfer /*
5471d102085SJan Lentfer * This is preferable to using getenv() since it ensures that we are using
5481d102085SJan Lentfer * the locale which was actually initialized by the application.
5491d102085SJan Lentfer */
5501d102085SJan Lentfer env = setlocale(LC_CTYPE, 0);
5511d102085SJan Lentfer #else
552*32bb5217SDaniel Fojt if (((env = getenv("LANG")) != 0 && *env != '\0')
553fdd4e1e0SJan Lentfer || ((env = getenv("LC_CTYPE")) != 0 && *env != '\0')
554*32bb5217SDaniel Fojt || ((env = getenv("LC_ALL")) != 0 && *env != '\0')) {
5551d102085SJan Lentfer ;
556fdd4e1e0SJan Lentfer }
5571d102085SJan Lentfer #endif
5581d102085SJan Lentfer T(("_nc_get_locale %s", _nc_visbuf(env)));
5591d102085SJan Lentfer return env;
560fdd4e1e0SJan Lentfer }
561fdd4e1e0SJan Lentfer
562fdd4e1e0SJan Lentfer /*
563fdd4e1e0SJan Lentfer * Check if we are running in a UTF-8 locale.
564fdd4e1e0SJan Lentfer */
565fdd4e1e0SJan Lentfer NCURSES_EXPORT(int)
_nc_unicode_locale(void)566fdd4e1e0SJan Lentfer _nc_unicode_locale(void)
567fdd4e1e0SJan Lentfer {
5681d102085SJan Lentfer int result = 0;
569*32bb5217SDaniel Fojt #if defined(_WIN32) && USE_WIDEC_SUPPORT
5703468e90cSJohn Marino result = 1;
5713468e90cSJohn Marino #elif HAVE_LANGINFO_CODESET
5721d102085SJan Lentfer char *env = nl_langinfo(CODESET);
5731d102085SJan Lentfer result = !strcmp(env, "UTF-8");
5741d102085SJan Lentfer T(("_nc_unicode_locale(%s) ->%d", env, result));
5751d102085SJan Lentfer #else
576fdd4e1e0SJan Lentfer char *env = _nc_get_locale();
577fdd4e1e0SJan Lentfer if (env != 0) {
5781d102085SJan Lentfer if (strstr(env, ".UTF-8") != 0) {
5791d102085SJan Lentfer result = 1;
5801d102085SJan Lentfer T(("_nc_unicode_locale(%s) ->%d", env, result));
581fdd4e1e0SJan Lentfer }
582fdd4e1e0SJan Lentfer }
5831d102085SJan Lentfer #endif
5841d102085SJan Lentfer return result;
5851d102085SJan Lentfer }
5861d102085SJan Lentfer
5871d102085SJan Lentfer #define CONTROL_N(s) ((s) != 0 && strstr(s, "\016") != 0)
5881d102085SJan Lentfer #define CONTROL_O(s) ((s) != 0 && strstr(s, "\017") != 0)
589fdd4e1e0SJan Lentfer
590fdd4e1e0SJan Lentfer /*
591fdd4e1e0SJan Lentfer * Check for known broken cases where a UTF-8 locale breaks the alternate
592fdd4e1e0SJan Lentfer * character set.
593fdd4e1e0SJan Lentfer */
594fdd4e1e0SJan Lentfer NCURSES_EXPORT(int)
_nc_locale_breaks_acs(TERMINAL * termp)5951d102085SJan Lentfer _nc_locale_breaks_acs(TERMINAL *termp)
596fdd4e1e0SJan Lentfer {
59700d8f3c4SJohn Marino const char *env_name = "NCURSES_NO_UTF8_ACS";
5983468e90cSJohn Marino const char *env;
59900d8f3c4SJohn Marino int value;
60000d8f3c4SJohn Marino int result = 0;
6011d102085SJan Lentfer
6023468e90cSJohn Marino T((T_CALLED("_nc_locale_breaks_acs:%d"), result));
6033468e90cSJohn Marino if (getenv(env_name) != 0) {
60400d8f3c4SJohn Marino result = _nc_getenv_num(env_name);
60500d8f3c4SJohn Marino } else if ((value = tigetnum("U8")) >= 0) {
60600d8f3c4SJohn Marino result = value; /* use extension feature */
6071d102085SJan Lentfer } else if ((env = getenv("TERM")) != 0) {
60800d8f3c4SJohn Marino if (strstr(env, "linux")) {
60900d8f3c4SJohn Marino result = 1; /* always broken */
61000d8f3c4SJohn Marino } else if (strstr(env, "screen") != 0
611fdd4e1e0SJan Lentfer && ((env = getenv("TERMCAP")) != 0
612fdd4e1e0SJan Lentfer && strstr(env, "screen") != 0)
613fdd4e1e0SJan Lentfer && strstr(env, "hhII00") != 0) {
6141d102085SJan Lentfer if (CONTROL_N(enter_alt_charset_mode) ||
6151d102085SJan Lentfer CONTROL_O(enter_alt_charset_mode) ||
6161d102085SJan Lentfer CONTROL_N(set_attributes) ||
61700d8f3c4SJohn Marino CONTROL_O(set_attributes)) {
61800d8f3c4SJohn Marino result = 1;
619fdd4e1e0SJan Lentfer }
620fdd4e1e0SJan Lentfer }
62100d8f3c4SJohn Marino }
6223468e90cSJohn Marino returnCode(result);
623fdd4e1e0SJan Lentfer }
624fdd4e1e0SJan Lentfer
625fdd4e1e0SJan Lentfer NCURSES_EXPORT(int)
TINFO_SETUP_TERM(TERMINAL ** tp,const char * tname,int Filedes,int * errret,int reuse)62600d8f3c4SJohn Marino TINFO_SETUP_TERM(TERMINAL **tp,
627*32bb5217SDaniel Fojt const char *tname,
62800d8f3c4SJohn Marino int Filedes,
62900d8f3c4SJohn Marino int *errret,
6303468e90cSJohn Marino int reuse)
631fdd4e1e0SJan Lentfer {
63200d8f3c4SJohn Marino #ifdef USE_TERM_DRIVER
63300d8f3c4SJohn Marino TERMINAL_CONTROL_BLOCK *TCB = 0;
63400d8f3c4SJohn Marino #endif
63500d8f3c4SJohn Marino TERMINAL *termp;
63600d8f3c4SJohn Marino SCREEN *sp = 0;
637*32bb5217SDaniel Fojt char *myname;
63800d8f3c4SJohn Marino int code = ERR;
639fdd4e1e0SJan Lentfer
640fdd4e1e0SJan Lentfer START_TRACE();
64100d8f3c4SJohn Marino
64200d8f3c4SJohn Marino #ifdef USE_TERM_DRIVER
64300d8f3c4SJohn Marino T((T_CALLED("_nc_setupterm_ex(%p,%s,%d,%p)"),
64400d8f3c4SJohn Marino (void *) tp, _nc_visbuf(tname), Filedes, (void *) errret));
64500d8f3c4SJohn Marino
64600d8f3c4SJohn Marino if (tp == 0) {
64700d8f3c4SJohn Marino ret_error0(TGETENT_ERR,
64800d8f3c4SJohn Marino "Invalid parameter, internal error.\n");
64900d8f3c4SJohn Marino } else
65000d8f3c4SJohn Marino termp = *tp;
65100d8f3c4SJohn Marino #else
65200d8f3c4SJohn Marino termp = cur_term;
65300d8f3c4SJohn Marino T((T_CALLED("setupterm(%s,%d,%p)"), _nc_visbuf(tname), Filedes, (void *) errret));
65400d8f3c4SJohn Marino #endif
655fdd4e1e0SJan Lentfer
656fdd4e1e0SJan Lentfer if (tname == 0) {
657fdd4e1e0SJan Lentfer tname = getenv("TERM");
658fdd4e1e0SJan Lentfer if (tname == 0 || *tname == '\0') {
6593468e90cSJohn Marino #ifdef USE_TERM_DRIVER
6603468e90cSJohn Marino tname = "unknown";
6613468e90cSJohn Marino #else
6621d102085SJan Lentfer ret_error0(TGETENT_ERR, "TERM environment variable not set.\n");
6633468e90cSJohn Marino #endif
664fdd4e1e0SJan Lentfer }
665fdd4e1e0SJan Lentfer }
666*32bb5217SDaniel Fojt myname = strdup(tname);
6671d102085SJan Lentfer
668*32bb5217SDaniel Fojt if (strlen(myname) > MAX_NAME_SIZE) {
6691d102085SJan Lentfer ret_error(TGETENT_ERR,
6701d102085SJan Lentfer "TERM environment must be <= %d characters.\n",
671*32bb5217SDaniel Fojt MAX_NAME_SIZE,
672*32bb5217SDaniel Fojt free(myname));
673fdd4e1e0SJan Lentfer }
674fdd4e1e0SJan Lentfer
675*32bb5217SDaniel Fojt T(("your terminal name is %s", myname));
676fdd4e1e0SJan Lentfer
677fdd4e1e0SJan Lentfer /*
678fdd4e1e0SJan Lentfer * Allow output redirection. This is what SVr3 does. If stdout is
679fdd4e1e0SJan Lentfer * directed to a file, screen updates go to standard error.
680fdd4e1e0SJan Lentfer */
6813468e90cSJohn Marino if (Filedes == STDOUT_FILENO && !NC_ISATTY(Filedes))
682fdd4e1e0SJan Lentfer Filedes = STDERR_FILENO;
683fdd4e1e0SJan Lentfer
684fdd4e1e0SJan Lentfer /*
685fdd4e1e0SJan Lentfer * Check if we have already initialized to use this terminal. If so, we
686fdd4e1e0SJan Lentfer * do not need to re-read the terminfo entry, or obtain TTY settings.
687fdd4e1e0SJan Lentfer *
688fdd4e1e0SJan Lentfer * This is an improvement on SVr4 curses. If an application mixes curses
689fdd4e1e0SJan Lentfer * and termcap calls, it may call both initscr and tgetent. This is not
690fdd4e1e0SJan Lentfer * really a good thing to do, but can happen if someone tries using ncurses
691fdd4e1e0SJan Lentfer * with the readline library. The problem we are fixing is that when
692fdd4e1e0SJan Lentfer * tgetent calls setupterm, the resulting Ottyb struct in cur_term is
693fdd4e1e0SJan Lentfer * zeroed. A subsequent call to endwin uses the zeroed terminal settings
694fdd4e1e0SJan Lentfer * rather than the ones saved in initscr. So we check if cur_term appears
695fdd4e1e0SJan Lentfer * to contain terminal settings for the same output file as our current
696fdd4e1e0SJan Lentfer * call - and copy those terminal settings. (SVr4 curses does not do this,
697fdd4e1e0SJan Lentfer * however applications that are working around the problem will still work
698fdd4e1e0SJan Lentfer * properly with this feature).
699fdd4e1e0SJan Lentfer */
7001d102085SJan Lentfer if (reuse
70100d8f3c4SJohn Marino && (termp != 0)
7021d102085SJan Lentfer && termp->Filedes == Filedes
7031d102085SJan Lentfer && termp->_termname != 0
704*32bb5217SDaniel Fojt && !strcmp(termp->_termname, myname)
705*32bb5217SDaniel Fojt && _nc_name_match(TerminalType(termp).term_names, myname, "|")) {
706fdd4e1e0SJan Lentfer T(("reusing existing terminal information and mode-settings"));
70700d8f3c4SJohn Marino code = OK;
7083468e90cSJohn Marino #ifdef USE_TERM_DRIVER
7093468e90cSJohn Marino TCB = (TERMINAL_CONTROL_BLOCK *) termp;
7103468e90cSJohn Marino #endif
711fdd4e1e0SJan Lentfer } else {
71200d8f3c4SJohn Marino #ifdef USE_TERM_DRIVER
7133468e90cSJohn Marino TERMINAL_CONTROL_BLOCK *my_tcb;
714*32bb5217SDaniel Fojt termp = 0;
715*32bb5217SDaniel Fojt if ((my_tcb = typeCalloc(TERMINAL_CONTROL_BLOCK, 1)) != 0)
7163468e90cSJohn Marino termp = &(my_tcb->term);
71700d8f3c4SJohn Marino #else
718*32bb5217SDaniel Fojt int status;
719*32bb5217SDaniel Fojt
7201d102085SJan Lentfer termp = typeCalloc(TERMINAL, 1);
72100d8f3c4SJohn Marino #endif
7221d102085SJan Lentfer if (termp == 0) {
723*32bb5217SDaniel Fojt ret_error1(TGETENT_ERR,
724*32bb5217SDaniel Fojt "Not enough memory to create terminal structure.\n",
725*32bb5217SDaniel Fojt myname, free(myname));
726fdd4e1e0SJan Lentfer }
727*32bb5217SDaniel Fojt #if HAVE_SYSCONF
728*32bb5217SDaniel Fojt {
729*32bb5217SDaniel Fojt long limit;
730*32bb5217SDaniel Fojt #ifdef LINE_MAX
731*32bb5217SDaniel Fojt limit = LINE_MAX;
732*32bb5217SDaniel Fojt #else
733*32bb5217SDaniel Fojt limit = _nc_globals.getstr_limit;
734*32bb5217SDaniel Fojt #endif
735*32bb5217SDaniel Fojt #ifdef _SC_LINE_MAX
736*32bb5217SDaniel Fojt if (limit < sysconf(_SC_LINE_MAX))
737*32bb5217SDaniel Fojt limit = sysconf(_SC_LINE_MAX);
738*32bb5217SDaniel Fojt #endif
739*32bb5217SDaniel Fojt if (_nc_globals.getstr_limit < (int) limit)
740*32bb5217SDaniel Fojt _nc_globals.getstr_limit = (int) limit;
741*32bb5217SDaniel Fojt }
742*32bb5217SDaniel Fojt #endif /* HAVE_SYSCONF */
743*32bb5217SDaniel Fojt T(("using %d for getstr limit", _nc_globals.getstr_limit));
744*32bb5217SDaniel Fojt
74500d8f3c4SJohn Marino #ifdef USE_TERM_DRIVER
74600d8f3c4SJohn Marino INIT_TERM_DRIVER();
74700d8f3c4SJohn Marino TCB = (TERMINAL_CONTROL_BLOCK *) termp;
748*32bb5217SDaniel Fojt code = _nc_globals.term_driver(TCB, myname, errret);
74900d8f3c4SJohn Marino if (code == OK) {
75000d8f3c4SJohn Marino termp->Filedes = (short) Filedes;
751*32bb5217SDaniel Fojt termp->_termname = strdup(myname);
75200d8f3c4SJohn Marino } else {
753*32bb5217SDaniel Fojt ret_error1(errret ? *errret : TGETENT_ERR,
754*32bb5217SDaniel Fojt "Could not find any driver to handle terminal.\n",
755*32bb5217SDaniel Fojt myname, free(myname));
75600d8f3c4SJohn Marino }
75700d8f3c4SJohn Marino #else
7583468e90cSJohn Marino #if NCURSES_USE_DATABASE || NCURSES_USE_TERMCAP
759*32bb5217SDaniel Fojt status = _nc_setup_tinfo(myname, &TerminalType(termp));
760*32bb5217SDaniel Fojt T(("_nc_setup_tinfo returns %d", status));
761fdd4e1e0SJan Lentfer #else
762*32bb5217SDaniel Fojt T(("no database available"));
7631d102085SJan Lentfer status = TGETENT_NO;
764fdd4e1e0SJan Lentfer #endif
765fdd4e1e0SJan Lentfer
766fdd4e1e0SJan Lentfer /* try fallback list if entry on disk */
7671d102085SJan Lentfer if (status != TGETENT_YES) {
768*32bb5217SDaniel Fojt const TERMTYPE2 *fallback = _nc_fallback2(myname);
769fdd4e1e0SJan Lentfer
770fdd4e1e0SJan Lentfer if (fallback) {
771*32bb5217SDaniel Fojt T(("found fallback entry"));
772*32bb5217SDaniel Fojt _nc_copy_termtype2(&(TerminalType(termp)), fallback);
7731d102085SJan Lentfer status = TGETENT_YES;
774fdd4e1e0SJan Lentfer }
775fdd4e1e0SJan Lentfer }
776fdd4e1e0SJan Lentfer
7771d102085SJan Lentfer if (status != TGETENT_YES) {
7781d102085SJan Lentfer del_curterm(termp);
7791d102085SJan Lentfer if (status == TGETENT_ERR) {
780*32bb5217SDaniel Fojt free(myname);
7811d102085SJan Lentfer ret_error0(status, "terminals database is inaccessible\n");
7821d102085SJan Lentfer } else if (status == TGETENT_NO) {
783*32bb5217SDaniel Fojt ret_error1(status, "unknown terminal type.\n",
784*32bb5217SDaniel Fojt myname, free(myname));
785*32bb5217SDaniel Fojt } else {
786*32bb5217SDaniel Fojt ret_error0(status, "unexpected return-code\n");
787fdd4e1e0SJan Lentfer }
788fdd4e1e0SJan Lentfer }
789*32bb5217SDaniel Fojt #if NCURSES_EXT_NUMBERS
790*32bb5217SDaniel Fojt _nc_export_termtype2(&termp->type, &TerminalType(termp));
791*32bb5217SDaniel Fojt #endif
7921d102085SJan Lentfer #if !USE_REENTRANT
793*32bb5217SDaniel Fojt save_ttytype(termp);
7941d102085SJan Lentfer #endif
795fdd4e1e0SJan Lentfer
79600d8f3c4SJohn Marino termp->Filedes = (short) Filedes;
797*32bb5217SDaniel Fojt termp->_termname = strdup(myname);
7981d102085SJan Lentfer
7991d102085SJan Lentfer set_curterm(termp);
800fdd4e1e0SJan Lentfer
80100d8f3c4SJohn Marino if (command_character)
8023468e90cSJohn Marino _nc_tinfo_cmdch(termp, UChar(*command_character));
803fdd4e1e0SJan Lentfer
804fdd4e1e0SJan Lentfer /*
805fdd4e1e0SJan Lentfer * If an application calls setupterm() rather than initscr() or
806fdd4e1e0SJan Lentfer * newterm(), we will not have the def_prog_mode() call in
807fdd4e1e0SJan Lentfer * _nc_setupscreen(). Do it now anyway, so we can initialize the
808*32bb5217SDaniel Fojt * baudrate. Also get the shell-mode so that erasechar() works.
809fdd4e1e0SJan Lentfer */
8103468e90cSJohn Marino if (NC_ISATTY(Filedes)) {
811*32bb5217SDaniel Fojt NCURSES_SP_NAME(def_shell_mode) (NCURSES_SP_ARG);
812*32bb5217SDaniel Fojt NCURSES_SP_NAME(def_prog_mode) (NCURSES_SP_ARG);
813fdd4e1e0SJan Lentfer baudrate();
814fdd4e1e0SJan Lentfer }
81500d8f3c4SJohn Marino code = OK;
81600d8f3c4SJohn Marino #endif
817fdd4e1e0SJan Lentfer }
818fdd4e1e0SJan Lentfer
81900d8f3c4SJohn Marino #ifdef USE_TERM_DRIVER
82000d8f3c4SJohn Marino *tp = termp;
82100d8f3c4SJohn Marino NCURSES_SP_NAME(set_curterm) (sp, termp);
8223468e90cSJohn Marino TCB->drv->td_init(TCB);
82300d8f3c4SJohn Marino #else
82400d8f3c4SJohn Marino sp = SP;
82500d8f3c4SJohn Marino #endif
82600d8f3c4SJohn Marino
827fdd4e1e0SJan Lentfer /*
828fdd4e1e0SJan Lentfer * We should always check the screensize, just in case.
829fdd4e1e0SJan Lentfer */
83000d8f3c4SJohn Marino TINFO_GET_SIZE(sp, termp, ptrLines(sp), ptrCols(sp));
831fdd4e1e0SJan Lentfer
832fdd4e1e0SJan Lentfer if (errret)
8331d102085SJan Lentfer *errret = TGETENT_YES;
834fdd4e1e0SJan Lentfer
83500d8f3c4SJohn Marino #ifndef USE_TERM_DRIVER
836fdd4e1e0SJan Lentfer if (generic_type) {
8373468e90cSJohn Marino /*
8383468e90cSJohn Marino * BSD 4.3's termcap contains mis-typed "gn" for wy99. Do a sanity
8393468e90cSJohn Marino * check before giving up.
8403468e90cSJohn Marino */
8413468e90cSJohn Marino if ((VALID_STRING(cursor_address)
8423468e90cSJohn Marino || (VALID_STRING(cursor_down) && VALID_STRING(cursor_home)))
8433468e90cSJohn Marino && VALID_STRING(clear_screen)) {
844*32bb5217SDaniel Fojt ret_error1(TGETENT_YES, "terminal is not really generic.\n",
845*32bb5217SDaniel Fojt myname, free(myname));
8463468e90cSJohn Marino } else {
8473468e90cSJohn Marino del_curterm(termp);
848*32bb5217SDaniel Fojt ret_error1(TGETENT_NO, "I need something more specific.\n",
849*32bb5217SDaniel Fojt myname, free(myname));
850fdd4e1e0SJan Lentfer }
8513468e90cSJohn Marino } else if (hard_copy) {
852*32bb5217SDaniel Fojt ret_error1(TGETENT_YES, "I can't handle hardcopy terminals.\n",
853*32bb5217SDaniel Fojt myname, free(myname));
854fdd4e1e0SJan Lentfer }
85500d8f3c4SJohn Marino #endif
856*32bb5217SDaniel Fojt free(myname);
85700d8f3c4SJohn Marino returnCode(code);
858fdd4e1e0SJan Lentfer }
8591d102085SJan Lentfer
860*32bb5217SDaniel Fojt #ifdef USE_PTHREADS
861*32bb5217SDaniel Fojt /*
862*32bb5217SDaniel Fojt * Returns a non-null pointer unless a new screen should be allocated because
863*32bb5217SDaniel Fojt * no match was found in the pre-screen cache.
864*32bb5217SDaniel Fojt */
865*32bb5217SDaniel Fojt NCURSES_EXPORT(SCREEN *)
_nc_find_prescr(void)866*32bb5217SDaniel Fojt _nc_find_prescr(void)
867*32bb5217SDaniel Fojt {
868*32bb5217SDaniel Fojt SCREEN *result = 0;
869*32bb5217SDaniel Fojt PRESCREEN_LIST *p;
870*32bb5217SDaniel Fojt pthread_t id = GetThreadID();
871*32bb5217SDaniel Fojt for (p = _nc_prescreen.allocated; p != 0; p = p->next) {
872*32bb5217SDaniel Fojt if (p->id == id) {
873*32bb5217SDaniel Fojt result = p->sp;
874*32bb5217SDaniel Fojt break;
875*32bb5217SDaniel Fojt }
876*32bb5217SDaniel Fojt }
877*32bb5217SDaniel Fojt return result;
878*32bb5217SDaniel Fojt }
879*32bb5217SDaniel Fojt
880*32bb5217SDaniel Fojt /*
881*32bb5217SDaniel Fojt * Tells ncurses to forget that this thread was associated with the pre-screen
882*32bb5217SDaniel Fojt * cache. It does not modify the pre-screen cache itself, since that is used
883*32bb5217SDaniel Fojt * for creating new screens.
884*32bb5217SDaniel Fojt */
885*32bb5217SDaniel Fojt NCURSES_EXPORT(void)
_nc_forget_prescr(void)886*32bb5217SDaniel Fojt _nc_forget_prescr(void)
887*32bb5217SDaniel Fojt {
888*32bb5217SDaniel Fojt PRESCREEN_LIST *p, *q;
889*32bb5217SDaniel Fojt pthread_t id = GetThreadID();
890*32bb5217SDaniel Fojt for (p = _nc_prescreen.allocated, q = 0; p != 0; q = p, p = p->next) {
891*32bb5217SDaniel Fojt if (p->id == id) {
892*32bb5217SDaniel Fojt if (q) {
893*32bb5217SDaniel Fojt q->next = p->next;
894*32bb5217SDaniel Fojt } else {
895*32bb5217SDaniel Fojt _nc_prescreen.allocated = p->next;
896*32bb5217SDaniel Fojt }
897*32bb5217SDaniel Fojt free(p);
898*32bb5217SDaniel Fojt break;
899*32bb5217SDaniel Fojt }
900*32bb5217SDaniel Fojt }
901*32bb5217SDaniel Fojt }
902*32bb5217SDaniel Fojt #endif /* USE_PTHREADS */
903*32bb5217SDaniel Fojt
90400d8f3c4SJohn Marino #if NCURSES_SP_FUNCS
90500d8f3c4SJohn Marino /*
90600d8f3c4SJohn Marino * In case of handling multiple screens, we need to have a screen before
907*32bb5217SDaniel Fojt * initialization in _nc_setupscreen takes place. This is to extend the
908*32bb5217SDaniel Fojt * substitute for some of the stuff in _nc_prescreen, especially for slk and
909*32bb5217SDaniel Fojt * ripoff handling which should be done per screen.
91000d8f3c4SJohn Marino */
91100d8f3c4SJohn Marino NCURSES_EXPORT(SCREEN *)
new_prescr(void)91200d8f3c4SJohn Marino new_prescr(void)
91300d8f3c4SJohn Marino {
9143468e90cSJohn Marino SCREEN *sp;
91500d8f3c4SJohn Marino
91600d8f3c4SJohn Marino START_TRACE();
91700d8f3c4SJohn Marino T((T_CALLED("new_prescr()")));
91800d8f3c4SJohn Marino
919*32bb5217SDaniel Fojt _nc_lock_global(screen);
920*32bb5217SDaniel Fojt if ((sp = _nc_find_prescr()) == 0) {
92100d8f3c4SJohn Marino sp = _nc_alloc_screen_sp();
922*32bb5217SDaniel Fojt T(("_nc_alloc_screen_sp %p", (void *) sp));
92300d8f3c4SJohn Marino if (sp != 0) {
924*32bb5217SDaniel Fojt #ifdef USE_PTHREADS
925*32bb5217SDaniel Fojt PRESCREEN_LIST *p = typeCalloc(PRESCREEN_LIST, 1);
926*32bb5217SDaniel Fojt if (p != 0) {
927*32bb5217SDaniel Fojt p->id = GetThreadID();
928*32bb5217SDaniel Fojt p->sp = sp;
929*32bb5217SDaniel Fojt p->next = _nc_prescreen.allocated;
930*32bb5217SDaniel Fojt _nc_prescreen.allocated = p;
931*32bb5217SDaniel Fojt }
932*32bb5217SDaniel Fojt #else
933*32bb5217SDaniel Fojt _nc_prescreen.allocated = sp;
934*32bb5217SDaniel Fojt #endif
93500d8f3c4SJohn Marino sp->rsp = sp->rippedoff;
93600d8f3c4SJohn Marino sp->_filtered = _nc_prescreen.filter_mode;
93700d8f3c4SJohn Marino sp->_use_env = _nc_prescreen.use_env;
93800d8f3c4SJohn Marino #if NCURSES_NO_PADDING
93900d8f3c4SJohn Marino sp->_no_padding = _nc_prescreen._no_padding;
94000d8f3c4SJohn Marino #endif
94100d8f3c4SJohn Marino sp->slk_format = 0;
94200d8f3c4SJohn Marino sp->_slk = 0;
94300d8f3c4SJohn Marino sp->_prescreen = TRUE;
94400d8f3c4SJohn Marino SP_PRE_INIT(sp);
94500d8f3c4SJohn Marino #if USE_REENTRANT
94600d8f3c4SJohn Marino sp->_TABSIZE = _nc_prescreen._TABSIZE;
94700d8f3c4SJohn Marino sp->_ESCDELAY = _nc_prescreen._ESCDELAY;
94800d8f3c4SJohn Marino #endif
94900d8f3c4SJohn Marino }
950*32bb5217SDaniel Fojt } else {
951*32bb5217SDaniel Fojt T(("_nc_alloc_screen_sp %p (reuse)", (void *) sp));
952*32bb5217SDaniel Fojt }
953*32bb5217SDaniel Fojt _nc_unlock_global(screen);
95400d8f3c4SJohn Marino returnSP(sp);
95500d8f3c4SJohn Marino }
95600d8f3c4SJohn Marino #endif
95700d8f3c4SJohn Marino
95800d8f3c4SJohn Marino #ifdef USE_TERM_DRIVER
95900d8f3c4SJohn Marino /*
96000d8f3c4SJohn Marino * This entrypoint is called from tgetent() to allow a special case of reusing
96100d8f3c4SJohn Marino * the same TERMINAL data (see comment).
96200d8f3c4SJohn Marino */
96300d8f3c4SJohn Marino NCURSES_EXPORT(int)
_nc_setupterm(const char * tname,int Filedes,int * errret,int reuse)964*32bb5217SDaniel Fojt _nc_setupterm(const char *tname,
96500d8f3c4SJohn Marino int Filedes,
96600d8f3c4SJohn Marino int *errret,
9673468e90cSJohn Marino int reuse)
96800d8f3c4SJohn Marino {
969*32bb5217SDaniel Fojt int rc = ERR;
9703468e90cSJohn Marino TERMINAL *termp = 0;
971*32bb5217SDaniel Fojt
972*32bb5217SDaniel Fojt _nc_lock_global(prescreen);
973*32bb5217SDaniel Fojt START_TRACE();
974*32bb5217SDaniel Fojt if (TINFO_SETUP_TERM(&termp, tname, Filedes, errret, reuse) == OK) {
975*32bb5217SDaniel Fojt _nc_forget_prescr();
976*32bb5217SDaniel Fojt if (NCURSES_SP_NAME(set_curterm) (CURRENT_SCREEN_PRE, termp) != 0) {
977*32bb5217SDaniel Fojt rc = OK;
978*32bb5217SDaniel Fojt }
979*32bb5217SDaniel Fojt }
980*32bb5217SDaniel Fojt _nc_unlock_global(prescreen);
981*32bb5217SDaniel Fojt return rc;
98200d8f3c4SJohn Marino }
98300d8f3c4SJohn Marino #endif
98400d8f3c4SJohn Marino
9851d102085SJan Lentfer /*
9861d102085SJan Lentfer * setupterm(termname, Filedes, errret)
9871d102085SJan Lentfer *
9881d102085SJan Lentfer * Find and read the appropriate object file for the terminal
9891d102085SJan Lentfer * Make cur_term point to the structure.
9901d102085SJan Lentfer */
9911d102085SJan Lentfer NCURSES_EXPORT(int)
setupterm(const char * tname,int Filedes,int * errret)992*32bb5217SDaniel Fojt setupterm(const char *tname, int Filedes, int *errret)
9931d102085SJan Lentfer {
9943468e90cSJohn Marino START_TRACE();
9951d102085SJan Lentfer return _nc_setupterm(tname, Filedes, errret, FALSE);
9961d102085SJan Lentfer }
997