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 56184989SrafanMODULE_ID("$Id: lib_setup.c,v 1.111 2008/08/03 22:42:33 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/* 103184989Srafan * Reduce explicit use of "cur_term" global variable. 104184989Srafan */ 105184989Srafan#undef CUR 106184989Srafan#define CUR termp->type. 107184989Srafan 108184989Srafan/* 109176187Srafan * Wrap global variables in this module. 110176187Srafan */ 111174993Srafan#if USE_REENTRANT 112174993SrafanNCURSES_EXPORT(char *) 113174993SrafanNCURSES_PUBLIC_VAR(ttytype) (void) 114174993Srafan{ 115174993Srafan static char empty[] = ""; 116174993Srafan return cur_term ? cur_term->type.term_names : empty; 117174993Srafan} 118184989SrafanNCURSES_EXPORT(int *) 119184989Srafan_nc_ptr_Lines(void) 120184989Srafan{ 121184989Srafan return ptrLines(); 122184989Srafan} 123174993SrafanNCURSES_EXPORT(int) 124174993SrafanNCURSES_PUBLIC_VAR(LINES) (void) 125174993Srafan{ 126184989Srafan return *_nc_ptr_Lines(); 127174993Srafan} 128184989SrafanNCURSES_EXPORT(int *) 129184989Srafan_nc_ptr_Cols(void) 130184989Srafan{ 131184989Srafan return ptrCols(); 132184989Srafan} 133174993SrafanNCURSES_EXPORT(int) 134174993SrafanNCURSES_PUBLIC_VAR(COLS) (void) 135174993Srafan{ 136184989Srafan return *_nc_ptr_Cols(); 137174993Srafan} 138174993SrafanNCURSES_EXPORT(int) 139174993SrafanNCURSES_PUBLIC_VAR(TABSIZE) (void) 140174993Srafan{ 141174993Srafan return SP ? SP->_TABSIZE : 8; 142174993Srafan} 143174993Srafan#else 144166124SrafanNCURSES_EXPORT_VAR(char) ttytype[NAMESIZE] = ""; 145166124SrafanNCURSES_EXPORT_VAR(int) LINES = 0; 146166124SrafanNCURSES_EXPORT_VAR(int) COLS = 0; 147166124SrafanNCURSES_EXPORT_VAR(int) TABSIZE = 0; 148174993Srafan#endif 149166124Srafan 150176187Srafan#if NCURSES_EXT_FUNCS 151176187SrafanNCURSES_EXPORT(int) 152176187Srafanset_tabsize(int value) 153176187Srafan{ 154176187Srafan int code = OK; 155176187Srafan#if USE_REENTRANT 156176187Srafan if (SP) { 157176187Srafan SP->_TABSIZE = value; 158176187Srafan } else { 159176187Srafan code = ERR; 160176187Srafan } 161176187Srafan#else 162176187Srafan TABSIZE = value; 163176187Srafan#endif 164176187Srafan return code; 165176187Srafan} 166176187Srafan#endif 167176187Srafan 168166124Srafan#if USE_SIGWINCH 169174993Srafan/* 170174993Srafan * If we have a pending SIGWINCH, set the flag in each screen. 171174993Srafan */ 172174993SrafanNCURSES_EXPORT(int) 173178866Srafan_nc_handle_sigwinch(SCREEN *sp) 174166124Srafan{ 175166124Srafan SCREEN *scan; 17650276Speter 177174993Srafan if (_nc_globals.have_sigwinch) { 178174993Srafan _nc_globals.have_sigwinch = 0; 179174993Srafan 180178866Srafan for (each_screen(scan)) { 181174993Srafan scan->_sig_winch = TRUE; 182166124Srafan } 183166124Srafan } 184166124Srafan 185178866Srafan return (sp ? sp->_sig_winch : 0); 186166124Srafan} 187166124Srafan 188166124Srafan#endif 189166124Srafan 19076726SpeterNCURSES_EXPORT(void) 19162449Speteruse_env(bool f) 19250276Speter{ 19397049Speter T((T_CALLED("use_env()"))); 194174993Srafan _nc_prescreen.use_env = f; 19597049Speter returnVoid; 19650276Speter} 19750276Speter 198174993SrafanNCURSES_EXPORT(void) 199178866Srafan_nc_get_screensize(SCREEN *sp, int *linep, int *colp) 20050276Speter/* Obtain lines/columns values from the environment and/or terminfo entry */ 20150276Speter{ 202184989Srafan TERMINAL *termp = cur_term; 203174993Srafan int my_tabsize; 204174993Srafan 20562449Speter /* figure out the size of the screen */ 20662449Speter T(("screen size: terminfo lines = %d columns = %d", lines, columns)); 20750276Speter 208174993Srafan if (!_nc_prescreen.use_env) { 20962449Speter *linep = (int) lines; 21062449Speter *colp = (int) columns; 21162449Speter } else { /* usually want to query LINES and COLUMNS from environment */ 21262449Speter int value; 21350276Speter 21462449Speter *linep = *colp = 0; 21550276Speter 21662449Speter /* first, look for environment variables */ 21762449Speter if ((value = _nc_getenv_num("LINES")) > 0) { 21862449Speter *linep = value; 21962449Speter } 22062449Speter if ((value = _nc_getenv_num("COLUMNS")) > 0) { 22162449Speter *colp = value; 22262449Speter } 22362449Speter T(("screen size: environment LINES = %d COLUMNS = %d", *linep, *colp)); 22450276Speter 22550276Speter#ifdef __EMX__ 22662449Speter if (*linep <= 0 || *colp <= 0) { 22762449Speter int screendata[2]; 22862449Speter _scrsize(screendata); 22962449Speter *colp = screendata[0]; 23062449Speter *linep = screendata[1]; 23162449Speter T(("EMX screen size: environment LINES = %d COLUMNS = %d", 23276726Speter *linep, *colp)); 23362449Speter } 23450276Speter#endif 23550276Speter#if HAVE_SIZECHANGE 23662449Speter /* if that didn't work, maybe we can try asking the OS */ 23762449Speter if (*linep <= 0 || *colp <= 0) { 23862449Speter if (isatty(cur_term->Filedes)) { 23962449Speter STRUCT_WINSIZE size; 24050276Speter 24162449Speter errno = 0; 24262449Speter do { 24362449Speter if (ioctl(cur_term->Filedes, IOCTL_WINSIZE, &size) < 0 24462449Speter && errno != EINTR) 24562449Speter goto failure; 24662449Speter } while 24762449Speter (errno == EINTR); 24850276Speter 24962449Speter /* 25062449Speter * Solaris lets users override either dimension with an 25162449Speter * environment variable. 25262449Speter */ 25362449Speter if (*linep <= 0) 254178866Srafan *linep = (sp != 0 && sp->_filtered) ? 1 : WINSIZE_ROWS(size); 25562449Speter if (*colp <= 0) 25662449Speter *colp = WINSIZE_COLS(size); 25750276Speter } 25862449Speter /* FALLTHRU */ 25962449Speter failure:; 26062449Speter } 26150276Speter#endif /* HAVE_SIZECHANGE */ 26250276Speter 26362449Speter /* if we can't get dynamic info about the size, use static */ 26476726Speter if (*linep <= 0) { 26576726Speter *linep = (int) lines; 26676726Speter } 26776726Speter if (*colp <= 0) { 26876726Speter *colp = (int) columns; 26976726Speter } 27050276Speter 27162449Speter /* the ultimate fallback, assume fixed 24x80 size */ 27297049Speter if (*linep <= 0) { 27362449Speter *linep = 24; 27497049Speter } 27597049Speter if (*colp <= 0) { 27662449Speter *colp = 80; 27750276Speter } 27850276Speter 27962449Speter /* 28062449Speter * Put the derived values back in the screen-size caps, so 28162449Speter * tigetnum() and tgetnum() will do the right thing. 28262449Speter */ 28362449Speter lines = (short) (*linep); 28462449Speter columns = (short) (*colp); 28562449Speter } 28650276Speter 28762449Speter T(("screen size is %dx%d", *linep, *colp)); 28850276Speter 28962449Speter if (VALID_NUMERIC(init_tabs)) 290174993Srafan my_tabsize = (int) init_tabs; 29162449Speter else 292174993Srafan my_tabsize = 8; 293174993Srafan 294174993Srafan#if USE_REENTRANT 295178866Srafan if (sp != 0) 296178866Srafan sp->_TABSIZE = my_tabsize; 297174993Srafan#else 298174993Srafan TABSIZE = my_tabsize; 299174993Srafan#endif 30062449Speter T(("TABSIZE = %d", TABSIZE)); 30150276Speter} 30250276Speter 30350276Speter#if USE_SIZECHANGE 30476726SpeterNCURSES_EXPORT(void) 305178866Srafan_nc_update_screensize(SCREEN *sp) 30650276Speter{ 307184989Srafan TERMINAL *termp = cur_term; 308166124Srafan int old_lines = lines; 309166124Srafan int new_lines; 310166124Srafan int old_cols = columns; 311166124Srafan int new_cols; 31250276Speter 313178866Srafan _nc_get_screensize(sp, &new_lines, &new_cols); 314166124Srafan 315166124Srafan /* 316166124Srafan * See is_term_resized() and resizeterm(). 317166124Srafan * We're doing it this way because those functions belong to the upper 318166124Srafan * ncurses library, while this resides in the lower terminfo library. 319166124Srafan */ 320178866Srafan if (sp != 0 321178866Srafan && sp->_resize != 0) { 322166124Srafan if ((new_lines != old_lines) || (new_cols != old_cols)) 323178866Srafan sp->_resize(new_lines, new_cols); 324178866Srafan sp->_sig_winch = FALSE; 325166124Srafan } 32650276Speter} 32750276Speter#endif 32850276Speter 32950276Speter/**************************************************************************** 33050276Speter * 33150276Speter * Terminal setup 33250276Speter * 33350276Speter ****************************************************************************/ 33450276Speter 33550276Speter#define ret_error(code, fmt, arg) if (errret) {\ 33650276Speter *errret = code;\ 33750276Speter returnCode(ERR);\ 33850276Speter } else {\ 33950276Speter fprintf(stderr, fmt, arg);\ 34050276Speter exit(EXIT_FAILURE);\ 34150276Speter } 34250276Speter 34350276Speter#define ret_error0(code, msg) if (errret) {\ 34450276Speter *errret = code;\ 34550276Speter returnCode(ERR);\ 34650276Speter } else {\ 34750276Speter fprintf(stderr, msg);\ 34850276Speter exit(EXIT_FAILURE);\ 34950276Speter } 35050276Speter 35197049Speter#if USE_DATABASE || USE_TERMCAP 352166124Srafan/* 353166124Srafan * Return 1 if entry found, 0 if not found, -1 if database not accessible, 354166124Srafan * just like tgetent(). 355166124Srafan */ 35662449Speterstatic int 357166124Srafangrab_entry(const char *const tn, TERMTYPE *const tp) 35850276Speter{ 35962449Speter char filename[PATH_MAX]; 360166124Srafan int status = _nc_read_entry(tn, filename, tp); 36150276Speter 36262449Speter /* 36362449Speter * If we have an entry, force all of the cancelled strings to null 36462449Speter * pointers so we don't have to test them in the rest of the library. 36562449Speter * (The terminfo compiler bypasses this logic, since it must know if 36662449Speter * a string is cancelled, for merging entries). 36762449Speter */ 368166124Srafan if (status == TGETENT_YES) { 369166124Srafan unsigned n; 37076726Speter for_each_boolean(n, tp) { 37162449Speter if (!VALID_BOOLEAN(tp->Booleans[n])) 37276726Speter tp->Booleans[n] = FALSE; 37376726Speter } 37476726Speter for_each_string(n, tp) { 37562449Speter if (tp->Strings[n] == CANCELLED_STRING) 37676726Speter tp->Strings[n] = ABSENT_STRING; 37776726Speter } 37862449Speter } 37962449Speter return (status); 38050276Speter} 38150276Speter#endif 38250276Speter 383166124Srafan/* 384166124Srafan** do_prototype() 385166124Srafan** 386166124Srafan** Take the real command character out of the CC environment variable 387166124Srafan** and substitute it in for the prototype given in 'command_character'. 388166124Srafan*/ 389166124Srafanstatic void 390184989Srafando_prototype(TERMINAL * termp) 391166124Srafan{ 392184989Srafan unsigned i; 393166124Srafan char CC; 394166124Srafan char proto; 395166124Srafan char *tmp; 39650276Speter 397184989Srafan if ((tmp = getenv("CC")) != 0) { 398184989Srafan if ((CC = *tmp) != 0) { 399184989Srafan proto = *command_character; 400166124Srafan 401184989Srafan for_each_string(i, &(termp->type)) { 402184989Srafan for (tmp = termp->type.Strings[i]; *tmp; tmp++) { 403184989Srafan if (*tmp == proto) 404184989Srafan *tmp = CC; 405184989Srafan } 406184989Srafan } 407166124Srafan } 408166124Srafan } 409166124Srafan} 410166124Srafan 41150276Speter/* 412166124Srafan * Find the locale which is in effect. 41350276Speter */ 414166124SrafanNCURSES_EXPORT(char *) 415166124Srafan_nc_get_locale(void) 416166124Srafan{ 417166124Srafan char *env; 418166124Srafan#if HAVE_LOCALE_H 419166124Srafan /* 420166124Srafan * This is preferable to using getenv() since it ensures that we are using 421166124Srafan * the locale which was actually initialized by the application. 422166124Srafan */ 423166124Srafan env = setlocale(LC_CTYPE, 0); 424166124Srafan#else 425166124Srafan if (((env = getenv("LC_ALL")) != 0 && *env != '\0') 426166124Srafan || ((env = getenv("LC_CTYPE")) != 0 && *env != '\0') 427166124Srafan || ((env = getenv("LANG")) != 0 && *env != '\0')) { 428166124Srafan ; 429166124Srafan } 430166124Srafan#endif 431166124Srafan T(("_nc_get_locale %s", _nc_visbuf(env))); 432166124Srafan return env; 433166124Srafan} 43450276Speter 435166124Srafan/* 436166124Srafan * Check if we are running in a UTF-8 locale. 437166124Srafan */ 43876726SpeterNCURSES_EXPORT(int) 439166124Srafan_nc_unicode_locale(void) 44050276Speter{ 441166124Srafan int result = 0; 442166124Srafan#if HAVE_LANGINFO_CODESET 443166124Srafan char *env = nl_langinfo(CODESET); 444166124Srafan result = !strcmp(env, "UTF-8"); 445166124Srafan T(("_nc_unicode_locale(%s) ->%d", env, result)); 446166124Srafan#else 447166124Srafan char *env = _nc_get_locale(); 448166124Srafan if (env != 0) { 449166124Srafan if (strstr(env, ".UTF-8") != 0) { 450166124Srafan result = 1; 451166124Srafan T(("_nc_unicode_locale(%s) ->%d", env, result)); 452166124Srafan } 453166124Srafan } 454166124Srafan#endif 455166124Srafan return result; 456166124Srafan} 457166124Srafan 458166124Srafan#define CONTROL_N(s) ((s) != 0 && strstr(s, "\016") != 0) 459166124Srafan#define CONTROL_O(s) ((s) != 0 && strstr(s, "\017") != 0) 460166124Srafan 461166124Srafan/* 462166124Srafan * Check for known broken cases where a UTF-8 locale breaks the alternate 463166124Srafan * character set. 464166124Srafan */ 465166124SrafanNCURSES_EXPORT(int) 466184989Srafan_nc_locale_breaks_acs(TERMINAL * termp) 467166124Srafan{ 468166124Srafan char *env; 469166124Srafan 470166124Srafan if ((env = getenv("NCURSES_NO_UTF8_ACS")) != 0) { 471166124Srafan return atoi(env); 472166124Srafan } else if ((env = getenv("TERM")) != 0) { 473166124Srafan if (strstr(env, "linux")) 474166124Srafan return 1; /* always broken */ 475166124Srafan if (strstr(env, "screen") != 0 476166124Srafan && ((env = getenv("TERMCAP")) != 0 477166124Srafan && strstr(env, "screen") != 0) 478166124Srafan && strstr(env, "hhII00") != 0) { 479166124Srafan if (CONTROL_N(enter_alt_charset_mode) || 480166124Srafan CONTROL_O(enter_alt_charset_mode) || 481166124Srafan CONTROL_N(set_attributes) || 482166124Srafan CONTROL_O(set_attributes)) 483166124Srafan return 1; 484166124Srafan } 485166124Srafan } 486166124Srafan return 0; 487166124Srafan} 488166124Srafan 489166124Srafan/* 490166124Srafan * This entrypoint is called from tgetent() to allow a special case of reusing 491166124Srafan * the same TERMINAL data (see comment). 492166124Srafan */ 493166124SrafanNCURSES_EXPORT(int) 494166124Srafan_nc_setupterm(NCURSES_CONST char *tname, int Filedes, int *errret, bool reuse) 495166124Srafan{ 496184989Srafan TERMINAL *termp; 49762449Speter int status; 49850276Speter 499166124Srafan START_TRACE(); 50062449Speter T((T_CALLED("setupterm(%s,%d,%p)"), _nc_visbuf(tname), Filedes, errret)); 50150276Speter 50262449Speter if (tname == 0) { 50362449Speter tname = getenv("TERM"); 50462449Speter if (tname == 0 || *tname == '\0') { 505166124Srafan ret_error0(TGETENT_ERR, "TERM environment variable not set.\n"); 50650276Speter } 50762449Speter } 508166124Srafan 50962449Speter if (strlen(tname) > MAX_NAME_SIZE) { 510166124Srafan ret_error(TGETENT_ERR, 511166124Srafan "TERM environment must be <= %d characters.\n", 51276726Speter MAX_NAME_SIZE); 51362449Speter } 51450276Speter 51562449Speter T(("your terminal name is %s", tname)); 51650276Speter 517166124Srafan /* 518166124Srafan * Allow output redirection. This is what SVr3 does. If stdout is 519166124Srafan * directed to a file, screen updates go to standard error. 520166124Srafan */ 521166124Srafan if (Filedes == STDOUT_FILENO && !isatty(Filedes)) 522166124Srafan Filedes = STDERR_FILENO; 52350276Speter 524166124Srafan /* 525166124Srafan * Check if we have already initialized to use this terminal. If so, we 526166124Srafan * do not need to re-read the terminfo entry, or obtain TTY settings. 527166124Srafan * 528166124Srafan * This is an improvement on SVr4 curses. If an application mixes curses 529166124Srafan * and termcap calls, it may call both initscr and tgetent. This is not 530166124Srafan * really a good thing to do, but can happen if someone tries using ncurses 531166124Srafan * with the readline library. The problem we are fixing is that when 532166124Srafan * tgetent calls setupterm, the resulting Ottyb struct in cur_term is 533166124Srafan * zeroed. A subsequent call to endwin uses the zeroed terminal settings 534166124Srafan * rather than the ones saved in initscr. So we check if cur_term appears 535166124Srafan * to contain terminal settings for the same output file as our current 536166124Srafan * call - and copy those terminal settings. (SVr4 curses does not do this, 537166124Srafan * however applications that are working around the problem will still work 538166124Srafan * properly with this feature). 539166124Srafan */ 540166124Srafan if (reuse 541184989Srafan && (termp = cur_term) != 0 542184989Srafan && termp->Filedes == Filedes 543184989Srafan && termp->_termname != 0 544184989Srafan && !strcmp(termp->_termname, tname) 545184989Srafan && _nc_name_match(termp->type.term_names, tname, "|")) { 546166124Srafan T(("reusing existing terminal information and mode-settings")); 547166124Srafan } else { 548166124Srafan 549184989Srafan termp = typeCalloc(TERMINAL, 1); 550166124Srafan 551184989Srafan if (termp == 0) { 552166124Srafan ret_error0(TGETENT_ERR, 553166124Srafan "Not enough memory to create terminal structure.\n"); 554166124Srafan } 55597049Speter#if USE_DATABASE || USE_TERMCAP 556184989Srafan status = grab_entry(tname, &termp->type); 55750276Speter#else 558166124Srafan status = TGETENT_NO; 55950276Speter#endif 56050276Speter 561166124Srafan /* try fallback list if entry on disk */ 562166124Srafan if (status != TGETENT_YES) { 563166124Srafan const TERMTYPE *fallback = _nc_fallback(tname); 56450276Speter 565166124Srafan if (fallback) { 566184989Srafan termp->type = *fallback; 567166124Srafan status = TGETENT_YES; 568166124Srafan } 56950276Speter } 57050276Speter 571166124Srafan if (status != TGETENT_YES) { 572184989Srafan del_curterm(termp); 573166124Srafan if (status == TGETENT_ERR) { 574166124Srafan ret_error0(status, "terminals database is inaccessible\n"); 575166124Srafan } else if (status == TGETENT_NO) { 576166124Srafan ret_error(status, "'%s': unknown terminal type.\n", tname); 577166124Srafan } 578166124Srafan } 579174993Srafan#if !USE_REENTRANT 580184989Srafan strncpy(ttytype, termp->type.term_names, NAMESIZE - 1); 581166124Srafan ttytype[NAMESIZE - 1] = '\0'; 582174993Srafan#endif 58350276Speter 584184989Srafan termp->Filedes = Filedes; 585184989Srafan termp->_termname = strdup(tname); 58650276Speter 587184989Srafan set_curterm(termp); 588184989Srafan 589184989Srafan if (command_character && getenv("CC")) 590184989Srafan do_prototype(termp); 591184989Srafan 592166124Srafan /* 593166124Srafan * If an application calls setupterm() rather than initscr() or 594166124Srafan * newterm(), we will not have the def_prog_mode() call in 595166124Srafan * _nc_setupscreen(). Do it now anyway, so we can initialize the 596166124Srafan * baudrate. 597166124Srafan */ 598166124Srafan if (isatty(Filedes)) { 599166124Srafan def_prog_mode(); 600166124Srafan baudrate(); 601166124Srafan } 602166124Srafan } 603166124Srafan 60462449Speter /* 605166124Srafan * We should always check the screensize, just in case. 60662449Speter */ 607184989Srafan _nc_get_screensize(SP, ptrLines(), ptrCols()); 60850276Speter 60962449Speter if (errret) 610166124Srafan *errret = TGETENT_YES; 61150276Speter 61262449Speter if (generic_type) { 613166124Srafan ret_error(TGETENT_NO, "'%s': I need something more specific.\n", tname); 61462449Speter } 61562449Speter if (hard_copy) { 616166124Srafan ret_error(TGETENT_YES, "'%s': I can't handle hardcopy terminals.\n", tname); 61762449Speter } 61862449Speter returnCode(OK); 61950276Speter} 62050276Speter 62150276Speter/* 622166124Srafan * setupterm(termname, Filedes, errret) 623166124Srafan * 624166124Srafan * Find and read the appropriate object file for the terminal 625166124Srafan * Make cur_term point to the structure. 626166124Srafan */ 627166124SrafanNCURSES_EXPORT(int) 628166124Srafansetupterm(NCURSES_CONST char *tname, int Filedes, int *errret) 62950276Speter{ 630166124Srafan return _nc_setupterm(tname, Filedes, errret, FALSE); 63150276Speter} 632