lib_setup.c revision 176187
150276Speter/**************************************************************************** 2176187Srafan * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. * 350276Speter * * 450276Speter * Permission is hereby granted, free of charge, to any person obtaining a * 550276Speter * copy of this software and associated documentation files (the * 650276Speter * "Software"), to deal in the Software without restriction, including * 750276Speter * without limitation the rights to use, copy, modify, merge, publish, * 850276Speter * distribute, distribute with modifications, sublicense, and/or sell * 950276Speter * copies of the Software, and to permit persons to whom the Software is * 1050276Speter * furnished to do so, subject to the following conditions: * 1150276Speter * * 1250276Speter * The above copyright notice and this permission notice shall be included * 1350276Speter * in all copies or substantial portions of the Software. * 1450276Speter * * 1550276Speter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 1650276Speter * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 1750276Speter * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 1850276Speter * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 1950276Speter * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 2050276Speter * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 2150276Speter * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 2250276Speter * * 2350276Speter * Except as contained in this notice, the name(s) of the above copyright * 2450276Speter * holders shall not be used in advertising or otherwise to promote the * 2550276Speter * sale, use or other dealings in this Software without prior written * 2650276Speter * authorization. * 2750276Speter ****************************************************************************/ 2850276Speter 2950276Speter/**************************************************************************** 3050276Speter * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 3150276Speter * and: Eric S. Raymond <esr@snark.thyrsus.com> * 32174993Srafan * and: Thomas E. Dickey 1996-on * 3350276Speter ****************************************************************************/ 3450276Speter 3550276Speter/* 3650276Speter * Terminal setup routines common to termcap and terminfo: 3750276Speter * 3850276Speter * use_env(bool) 3950276Speter * setupterm(char *, int, int *) 4050276Speter */ 4150276Speter 4250276Speter#include <curses.priv.h> 4362449Speter#include <tic.h> /* for MAX_NAME_SIZE */ 4450276Speter#include <term_entry.h> 4550276Speter 4666963Speter#if SVR4_TERMIO && !defined(_POSIX_SOURCE) 4750276Speter#define _POSIX_SOURCE 4850276Speter#endif 4950276Speter 50166124Srafan#if HAVE_LOCALE_H 51166124Srafan#include <locale.h> 52166124Srafan#endif 53166124Srafan 5462449Speter#include <term.h> /* lines, columns, cur_term */ 5550276Speter 56176187SrafanMODULE_ID("$Id: lib_setup.c,v 1.102 2008/01/19 21:07:45 tom Exp $") 5750276Speter 5850276Speter/**************************************************************************** 5950276Speter * 6050276Speter * Terminal size computation 6150276Speter * 6250276Speter ****************************************************************************/ 6350276Speter 6450276Speter#if HAVE_SIZECHANGE 6550276Speter# if !defined(sun) || !TERMIOS 6650276Speter# if HAVE_SYS_IOCTL_H 6750276Speter# include <sys/ioctl.h> 6850276Speter# endif 6950276Speter# endif 7050276Speter#endif 7150276Speter 7250276Speter#if NEED_PTEM_H 7350276Speter /* On SCO, they neglected to define struct winsize in termios.h -- it's only 7450276Speter * in termio.h and ptem.h (the former conflicts with other definitions). 7550276Speter */ 7650276Speter# include <sys/stream.h> 7750276Speter# include <sys/ptem.h> 7850276Speter#endif 7950276Speter 80166124Srafan#if HAVE_LANGINFO_CODESET 81166124Srafan#include <langinfo.h> 82166124Srafan#endif 83166124Srafan 8450276Speter/* 8550276Speter * SCO defines TIOCGSIZE and the corresponding struct. Other systems (SunOS, 8650276Speter * Solaris, IRIX) define TIOCGWINSZ and struct winsize. 8750276Speter */ 8850276Speter#ifdef TIOCGSIZE 8950276Speter# define IOCTL_WINSIZE TIOCGSIZE 9050276Speter# define STRUCT_WINSIZE struct ttysize 9150276Speter# define WINSIZE_ROWS(n) (int)n.ts_lines 9250276Speter# define WINSIZE_COLS(n) (int)n.ts_cols 9350276Speter#else 9450276Speter# ifdef TIOCGWINSZ 9550276Speter# define IOCTL_WINSIZE TIOCGWINSZ 9650276Speter# define STRUCT_WINSIZE struct winsize 9750276Speter# define WINSIZE_ROWS(n) (int)n.ws_row 9850276Speter# define WINSIZE_COLS(n) (int)n.ws_col 9950276Speter# endif 10050276Speter#endif 10150276Speter 102176187Srafan/* 103176187Srafan * Wrap global variables in this module. 104176187Srafan */ 105174993Srafan#if USE_REENTRANT 106174993SrafanNCURSES_EXPORT(char *) 107174993SrafanNCURSES_PUBLIC_VAR(ttytype) (void) 108174993Srafan{ 109174993Srafan static char empty[] = ""; 110174993Srafan return cur_term ? cur_term->type.term_names : empty; 111174993Srafan} 112174993SrafanNCURSES_EXPORT(int) 113174993SrafanNCURSES_PUBLIC_VAR(LINES) (void) 114174993Srafan{ 115174993Srafan return (SP ? SP->_LINES : _nc_prescreen._LINES); 116174993Srafan} 117174993SrafanNCURSES_EXPORT(int) 118174993SrafanNCURSES_PUBLIC_VAR(COLS) (void) 119174993Srafan{ 120174993Srafan return SP ? SP->_COLS : _nc_prescreen._COLS; 121174993Srafan} 122174993SrafanNCURSES_EXPORT(int) 123174993SrafanNCURSES_PUBLIC_VAR(TABSIZE) (void) 124174993Srafan{ 125174993Srafan return SP ? SP->_TABSIZE : 8; 126174993Srafan} 127174993Srafan#else 128166124SrafanNCURSES_EXPORT_VAR(char) ttytype[NAMESIZE] = ""; 129166124SrafanNCURSES_EXPORT_VAR(int) LINES = 0; 130166124SrafanNCURSES_EXPORT_VAR(int) COLS = 0; 131166124SrafanNCURSES_EXPORT_VAR(int) TABSIZE = 0; 132174993Srafan#endif 133166124Srafan 134176187Srafan#if NCURSES_EXT_FUNCS 135176187SrafanNCURSES_EXPORT(int) 136176187Srafanset_tabsize(int value) 137176187Srafan{ 138176187Srafan int code = OK; 139176187Srafan#if USE_REENTRANT 140176187Srafan if (SP) { 141176187Srafan SP->_TABSIZE = value; 142176187Srafan } else { 143176187Srafan code = ERR; 144176187Srafan } 145176187Srafan#else 146176187Srafan TABSIZE = value; 147176187Srafan#endif 148176187Srafan return code; 149176187Srafan} 150176187Srafan#endif 151176187Srafan 152166124Srafan#if USE_SIGWINCH 153174993Srafan/* 154174993Srafan * If we have a pending SIGWINCH, set the flag in each screen. 155174993Srafan */ 156174993SrafanNCURSES_EXPORT(int) 157174993Srafan_nc_handle_sigwinch(int update) 158166124Srafan{ 159166124Srafan SCREEN *scan; 16050276Speter 161174993Srafan (void) update; /* no longer used */ 162166124Srafan 163174993Srafan if (_nc_globals.have_sigwinch) { 164174993Srafan _nc_globals.have_sigwinch = 0; 165174993Srafan 166174993Srafan scan = _nc_screen_chain; 167174993Srafan while (scan) { 168174993Srafan scan->_sig_winch = TRUE; 169174993Srafan scan = scan->_next_screen; 170166124Srafan } 171166124Srafan } 172166124Srafan 173174993Srafan return (SP ? SP->_sig_winch : 0); 174166124Srafan} 175166124Srafan 176166124Srafan#endif 177166124Srafan 17876726SpeterNCURSES_EXPORT(void) 17962449Speteruse_env(bool f) 18050276Speter{ 18197049Speter T((T_CALLED("use_env()"))); 182174993Srafan _nc_prescreen.use_env = f; 18397049Speter returnVoid; 18450276Speter} 18550276Speter 186174993SrafanNCURSES_EXPORT(void) 18797049Speter_nc_get_screensize(int *linep, int *colp) 18850276Speter/* Obtain lines/columns values from the environment and/or terminfo entry */ 18950276Speter{ 190174993Srafan int my_tabsize; 191174993Srafan 19262449Speter /* figure out the size of the screen */ 19362449Speter T(("screen size: terminfo lines = %d columns = %d", lines, columns)); 19450276Speter 195174993Srafan if (!_nc_prescreen.use_env) { 19662449Speter *linep = (int) lines; 19762449Speter *colp = (int) columns; 19862449Speter } else { /* usually want to query LINES and COLUMNS from environment */ 19962449Speter int value; 20050276Speter 20162449Speter *linep = *colp = 0; 20250276Speter 20362449Speter /* first, look for environment variables */ 20462449Speter if ((value = _nc_getenv_num("LINES")) > 0) { 20562449Speter *linep = value; 20662449Speter } 20762449Speter if ((value = _nc_getenv_num("COLUMNS")) > 0) { 20862449Speter *colp = value; 20962449Speter } 21062449Speter T(("screen size: environment LINES = %d COLUMNS = %d", *linep, *colp)); 21150276Speter 21250276Speter#ifdef __EMX__ 21362449Speter if (*linep <= 0 || *colp <= 0) { 21462449Speter int screendata[2]; 21562449Speter _scrsize(screendata); 21662449Speter *colp = screendata[0]; 21762449Speter *linep = screendata[1]; 21862449Speter T(("EMX screen size: environment LINES = %d COLUMNS = %d", 21976726Speter *linep, *colp)); 22062449Speter } 22150276Speter#endif 22250276Speter#if HAVE_SIZECHANGE 22362449Speter /* if that didn't work, maybe we can try asking the OS */ 22462449Speter if (*linep <= 0 || *colp <= 0) { 22562449Speter if (isatty(cur_term->Filedes)) { 22662449Speter STRUCT_WINSIZE size; 22750276Speter 22862449Speter errno = 0; 22962449Speter do { 23062449Speter if (ioctl(cur_term->Filedes, IOCTL_WINSIZE, &size) < 0 23162449Speter && errno != EINTR) 23262449Speter goto failure; 23362449Speter } while 23462449Speter (errno == EINTR); 23550276Speter 23662449Speter /* 23762449Speter * Solaris lets users override either dimension with an 23862449Speter * environment variable. 23962449Speter */ 24062449Speter if (*linep <= 0) 241166124Srafan *linep = (SP != 0 && SP->_filtered) ? 1 : WINSIZE_ROWS(size); 24262449Speter if (*colp <= 0) 24362449Speter *colp = WINSIZE_COLS(size); 24450276Speter } 24562449Speter /* FALLTHRU */ 24662449Speter failure:; 24762449Speter } 24850276Speter#endif /* HAVE_SIZECHANGE */ 24950276Speter 25062449Speter /* if we can't get dynamic info about the size, use static */ 25176726Speter if (*linep <= 0) { 25276726Speter *linep = (int) lines; 25376726Speter } 25476726Speter if (*colp <= 0) { 25576726Speter *colp = (int) columns; 25676726Speter } 25750276Speter 25862449Speter /* the ultimate fallback, assume fixed 24x80 size */ 25997049Speter if (*linep <= 0) { 26062449Speter *linep = 24; 26197049Speter } 26297049Speter if (*colp <= 0) { 26362449Speter *colp = 80; 26450276Speter } 26550276Speter 26662449Speter /* 26762449Speter * Put the derived values back in the screen-size caps, so 26862449Speter * tigetnum() and tgetnum() will do the right thing. 26962449Speter */ 27062449Speter lines = (short) (*linep); 27162449Speter columns = (short) (*colp); 27262449Speter } 27350276Speter 27462449Speter T(("screen size is %dx%d", *linep, *colp)); 27550276Speter 27662449Speter if (VALID_NUMERIC(init_tabs)) 277174993Srafan my_tabsize = (int) init_tabs; 27862449Speter else 279174993Srafan my_tabsize = 8; 280174993Srafan 281174993Srafan#if USE_REENTRANT 282174993Srafan if (SP != 0) 283174993Srafan SP->_TABSIZE = my_tabsize; 284174993Srafan#else 285174993Srafan TABSIZE = my_tabsize; 286174993Srafan#endif 28762449Speter T(("TABSIZE = %d", TABSIZE)); 28850276Speter} 28950276Speter 29050276Speter#if USE_SIZECHANGE 29176726SpeterNCURSES_EXPORT(void) 29262449Speter_nc_update_screensize(void) 29350276Speter{ 294166124Srafan int old_lines = lines; 295166124Srafan int new_lines; 296166124Srafan int old_cols = columns; 297166124Srafan int new_cols; 29850276Speter 299166124Srafan _nc_get_screensize(&new_lines, &new_cols); 300166124Srafan 301166124Srafan /* 302166124Srafan * See is_term_resized() and resizeterm(). 303166124Srafan * We're doing it this way because those functions belong to the upper 304166124Srafan * ncurses library, while this resides in the lower terminfo library. 305166124Srafan */ 306166124Srafan if (SP != 0 307166124Srafan && SP->_resize != 0) { 308166124Srafan if ((new_lines != old_lines) || (new_cols != old_cols)) 309166124Srafan SP->_resize(new_lines, new_cols); 310166124Srafan SP->_sig_winch = FALSE; 311166124Srafan } 31250276Speter} 31350276Speter#endif 31450276Speter 31550276Speter/**************************************************************************** 31650276Speter * 31750276Speter * Terminal setup 31850276Speter * 31950276Speter ****************************************************************************/ 32050276Speter 32150276Speter#define ret_error(code, fmt, arg) if (errret) {\ 32250276Speter *errret = code;\ 32350276Speter returnCode(ERR);\ 32450276Speter } else {\ 32550276Speter fprintf(stderr, fmt, arg);\ 32650276Speter exit(EXIT_FAILURE);\ 32750276Speter } 32850276Speter 32950276Speter#define ret_error0(code, msg) if (errret) {\ 33050276Speter *errret = code;\ 33150276Speter returnCode(ERR);\ 33250276Speter } else {\ 33350276Speter fprintf(stderr, msg);\ 33450276Speter exit(EXIT_FAILURE);\ 33550276Speter } 33650276Speter 33797049Speter#if USE_DATABASE || USE_TERMCAP 338166124Srafan/* 339166124Srafan * Return 1 if entry found, 0 if not found, -1 if database not accessible, 340166124Srafan * just like tgetent(). 341166124Srafan */ 34262449Speterstatic int 343166124Srafangrab_entry(const char *const tn, TERMTYPE *const tp) 34450276Speter{ 34562449Speter char filename[PATH_MAX]; 346166124Srafan int status = _nc_read_entry(tn, filename, tp); 34750276Speter 34862449Speter /* 34962449Speter * If we have an entry, force all of the cancelled strings to null 35062449Speter * pointers so we don't have to test them in the rest of the library. 35162449Speter * (The terminfo compiler bypasses this logic, since it must know if 35262449Speter * a string is cancelled, for merging entries). 35362449Speter */ 354166124Srafan if (status == TGETENT_YES) { 355166124Srafan unsigned n; 35676726Speter for_each_boolean(n, tp) { 35762449Speter if (!VALID_BOOLEAN(tp->Booleans[n])) 35876726Speter tp->Booleans[n] = FALSE; 35976726Speter } 36076726Speter for_each_string(n, tp) { 36162449Speter if (tp->Strings[n] == CANCELLED_STRING) 36276726Speter tp->Strings[n] = ABSENT_STRING; 36376726Speter } 36462449Speter } 36562449Speter return (status); 36650276Speter} 36750276Speter#endif 36850276Speter 369166124Srafan/* 370166124Srafan** do_prototype() 371166124Srafan** 372166124Srafan** Take the real command character out of the CC environment variable 373166124Srafan** and substitute it in for the prototype given in 'command_character'. 374166124Srafan*/ 375166124Srafanstatic void 376166124Srafando_prototype(void) 377166124Srafan{ 378166124Srafan int i; 379166124Srafan char CC; 380166124Srafan char proto; 381166124Srafan char *tmp; 38250276Speter 383166124Srafan tmp = getenv("CC"); 384166124Srafan CC = *tmp; 385166124Srafan proto = *command_character; 386166124Srafan 387166124Srafan for_each_string(i, &(cur_term->type)) { 388166124Srafan for (tmp = cur_term->type.Strings[i]; *tmp; tmp++) { 389166124Srafan if (*tmp == proto) 390166124Srafan *tmp = CC; 391166124Srafan } 392166124Srafan } 393166124Srafan} 394166124Srafan 39550276Speter/* 396166124Srafan * Find the locale which is in effect. 39750276Speter */ 398166124SrafanNCURSES_EXPORT(char *) 399166124Srafan_nc_get_locale(void) 400166124Srafan{ 401166124Srafan char *env; 402166124Srafan#if HAVE_LOCALE_H 403166124Srafan /* 404166124Srafan * This is preferable to using getenv() since it ensures that we are using 405166124Srafan * the locale which was actually initialized by the application. 406166124Srafan */ 407166124Srafan env = setlocale(LC_CTYPE, 0); 408166124Srafan#else 409166124Srafan if (((env = getenv("LC_ALL")) != 0 && *env != '\0') 410166124Srafan || ((env = getenv("LC_CTYPE")) != 0 && *env != '\0') 411166124Srafan || ((env = getenv("LANG")) != 0 && *env != '\0')) { 412166124Srafan ; 413166124Srafan } 414166124Srafan#endif 415166124Srafan T(("_nc_get_locale %s", _nc_visbuf(env))); 416166124Srafan return env; 417166124Srafan} 41850276Speter 419166124Srafan/* 420166124Srafan * Check if we are running in a UTF-8 locale. 421166124Srafan */ 42276726SpeterNCURSES_EXPORT(int) 423166124Srafan_nc_unicode_locale(void) 42450276Speter{ 425166124Srafan int result = 0; 426166124Srafan#if HAVE_LANGINFO_CODESET 427166124Srafan char *env = nl_langinfo(CODESET); 428166124Srafan result = !strcmp(env, "UTF-8"); 429166124Srafan T(("_nc_unicode_locale(%s) ->%d", env, result)); 430166124Srafan#else 431166124Srafan char *env = _nc_get_locale(); 432166124Srafan if (env != 0) { 433166124Srafan if (strstr(env, ".UTF-8") != 0) { 434166124Srafan result = 1; 435166124Srafan T(("_nc_unicode_locale(%s) ->%d", env, result)); 436166124Srafan } 437166124Srafan } 438166124Srafan#endif 439166124Srafan return result; 440166124Srafan} 441166124Srafan 442166124Srafan#define CONTROL_N(s) ((s) != 0 && strstr(s, "\016") != 0) 443166124Srafan#define CONTROL_O(s) ((s) != 0 && strstr(s, "\017") != 0) 444166124Srafan 445166124Srafan/* 446166124Srafan * Check for known broken cases where a UTF-8 locale breaks the alternate 447166124Srafan * character set. 448166124Srafan */ 449166124SrafanNCURSES_EXPORT(int) 450166124Srafan_nc_locale_breaks_acs(void) 451166124Srafan{ 452166124Srafan char *env; 453166124Srafan 454166124Srafan if ((env = getenv("NCURSES_NO_UTF8_ACS")) != 0) { 455166124Srafan return atoi(env); 456166124Srafan } else if ((env = getenv("TERM")) != 0) { 457166124Srafan if (strstr(env, "linux")) 458166124Srafan return 1; /* always broken */ 459166124Srafan if (strstr(env, "screen") != 0 460166124Srafan && ((env = getenv("TERMCAP")) != 0 461166124Srafan && strstr(env, "screen") != 0) 462166124Srafan && strstr(env, "hhII00") != 0) { 463166124Srafan if (CONTROL_N(enter_alt_charset_mode) || 464166124Srafan CONTROL_O(enter_alt_charset_mode) || 465166124Srafan CONTROL_N(set_attributes) || 466166124Srafan CONTROL_O(set_attributes)) 467166124Srafan return 1; 468166124Srafan } 469166124Srafan } 470166124Srafan return 0; 471166124Srafan} 472166124Srafan 473166124Srafan/* 474166124Srafan * This entrypoint is called from tgetent() to allow a special case of reusing 475166124Srafan * the same TERMINAL data (see comment). 476166124Srafan */ 477166124SrafanNCURSES_EXPORT(int) 478166124Srafan_nc_setupterm(NCURSES_CONST char *tname, int Filedes, int *errret, bool reuse) 479166124Srafan{ 48062449Speter int status; 48150276Speter 482166124Srafan START_TRACE(); 48362449Speter T((T_CALLED("setupterm(%s,%d,%p)"), _nc_visbuf(tname), Filedes, errret)); 48450276Speter 48562449Speter if (tname == 0) { 48662449Speter tname = getenv("TERM"); 48762449Speter if (tname == 0 || *tname == '\0') { 488166124Srafan ret_error0(TGETENT_ERR, "TERM environment variable not set.\n"); 48950276Speter } 49062449Speter } 491166124Srafan 49262449Speter if (strlen(tname) > MAX_NAME_SIZE) { 493166124Srafan ret_error(TGETENT_ERR, 494166124Srafan "TERM environment must be <= %d characters.\n", 49576726Speter MAX_NAME_SIZE); 49662449Speter } 49750276Speter 49862449Speter T(("your terminal name is %s", tname)); 49950276Speter 500166124Srafan /* 501166124Srafan * Allow output redirection. This is what SVr3 does. If stdout is 502166124Srafan * directed to a file, screen updates go to standard error. 503166124Srafan */ 504166124Srafan if (Filedes == STDOUT_FILENO && !isatty(Filedes)) 505166124Srafan Filedes = STDERR_FILENO; 50650276Speter 507166124Srafan /* 508166124Srafan * Check if we have already initialized to use this terminal. If so, we 509166124Srafan * do not need to re-read the terminfo entry, or obtain TTY settings. 510166124Srafan * 511166124Srafan * This is an improvement on SVr4 curses. If an application mixes curses 512166124Srafan * and termcap calls, it may call both initscr and tgetent. This is not 513166124Srafan * really a good thing to do, but can happen if someone tries using ncurses 514166124Srafan * with the readline library. The problem we are fixing is that when 515166124Srafan * tgetent calls setupterm, the resulting Ottyb struct in cur_term is 516166124Srafan * zeroed. A subsequent call to endwin uses the zeroed terminal settings 517166124Srafan * rather than the ones saved in initscr. So we check if cur_term appears 518166124Srafan * to contain terminal settings for the same output file as our current 519166124Srafan * call - and copy those terminal settings. (SVr4 curses does not do this, 520166124Srafan * however applications that are working around the problem will still work 521166124Srafan * properly with this feature). 522166124Srafan */ 523166124Srafan if (reuse 524166124Srafan && cur_term != 0 525166124Srafan && cur_term->Filedes == Filedes 526166124Srafan && cur_term->_termname != 0 527166124Srafan && !strcmp(cur_term->_termname, tname) 528166124Srafan && _nc_name_match(cur_term->type.term_names, tname, "|")) { 529166124Srafan T(("reusing existing terminal information and mode-settings")); 530166124Srafan } else { 531166124Srafan TERMINAL *term_ptr; 532166124Srafan 533166124Srafan term_ptr = typeCalloc(TERMINAL, 1); 534166124Srafan 535166124Srafan if (term_ptr == 0) { 536166124Srafan ret_error0(TGETENT_ERR, 537166124Srafan "Not enough memory to create terminal structure.\n"); 538166124Srafan } 53997049Speter#if USE_DATABASE || USE_TERMCAP 540166124Srafan status = grab_entry(tname, &term_ptr->type); 54150276Speter#else 542166124Srafan status = TGETENT_NO; 54350276Speter#endif 54450276Speter 545166124Srafan /* try fallback list if entry on disk */ 546166124Srafan if (status != TGETENT_YES) { 547166124Srafan const TERMTYPE *fallback = _nc_fallback(tname); 54850276Speter 549166124Srafan if (fallback) { 550166124Srafan term_ptr->type = *fallback; 551166124Srafan status = TGETENT_YES; 552166124Srafan } 55350276Speter } 55450276Speter 555166124Srafan if (status != TGETENT_YES) { 556166124Srafan del_curterm(term_ptr); 557166124Srafan if (status == TGETENT_ERR) { 558166124Srafan ret_error0(status, "terminals database is inaccessible\n"); 559166124Srafan } else if (status == TGETENT_NO) { 560166124Srafan ret_error(status, "'%s': unknown terminal type.\n", tname); 561166124Srafan } 562166124Srafan } 56350276Speter 564166124Srafan set_curterm(term_ptr); 56550276Speter 566166124Srafan if (command_character && getenv("CC")) 567166124Srafan do_prototype(); 56850276Speter 569174993Srafan#if !USE_REENTRANT 570166124Srafan strncpy(ttytype, cur_term->type.term_names, NAMESIZE - 1); 571166124Srafan ttytype[NAMESIZE - 1] = '\0'; 572174993Srafan#endif 57350276Speter 574166124Srafan cur_term->Filedes = Filedes; 575166124Srafan cur_term->_termname = strdup(tname); 57650276Speter 577166124Srafan /* 578166124Srafan * If an application calls setupterm() rather than initscr() or 579166124Srafan * newterm(), we will not have the def_prog_mode() call in 580166124Srafan * _nc_setupscreen(). Do it now anyway, so we can initialize the 581166124Srafan * baudrate. 582166124Srafan */ 583166124Srafan if (isatty(Filedes)) { 584166124Srafan def_prog_mode(); 585166124Srafan baudrate(); 586166124Srafan } 587166124Srafan } 588166124Srafan 58962449Speter /* 590166124Srafan * We should always check the screensize, just in case. 59162449Speter */ 592174993Srafan#if USE_REENTRANT 593174993Srafan _nc_get_screensize(SP ? &(SP->_LINES) : &(_nc_prescreen._LINES), 594174993Srafan SP ? &(SP->_COLS) : &(_nc_prescreen._COLS)); 595174993Srafan#else 59662449Speter _nc_get_screensize(&LINES, &COLS); 597174993Srafan#endif 59850276Speter 59962449Speter if (errret) 600166124Srafan *errret = TGETENT_YES; 60150276Speter 60262449Speter if (generic_type) { 603166124Srafan ret_error(TGETENT_NO, "'%s': I need something more specific.\n", tname); 60462449Speter } 60562449Speter if (hard_copy) { 606166124Srafan ret_error(TGETENT_YES, "'%s': I can't handle hardcopy terminals.\n", tname); 60762449Speter } 60862449Speter returnCode(OK); 60950276Speter} 61050276Speter 61150276Speter/* 612166124Srafan * setupterm(termname, Filedes, errret) 613166124Srafan * 614166124Srafan * Find and read the appropriate object file for the terminal 615166124Srafan * Make cur_term point to the structure. 616166124Srafan */ 617166124SrafanNCURSES_EXPORT(int) 618166124Srafansetupterm(NCURSES_CONST char *tname, int Filedes, int *errret) 61950276Speter{ 620166124Srafan return _nc_setupterm(tname, Filedes, errret, FALSE); 62150276Speter} 622