lib_setup.c revision 178866
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 56178866SrafanMODULE_ID("$Id: lib_setup.c,v 1.105 2008/05/03 22:41:42 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) 157178866Srafan_nc_handle_sigwinch(SCREEN *sp) 158166124Srafan{ 159166124Srafan SCREEN *scan; 16050276Speter 161174993Srafan if (_nc_globals.have_sigwinch) { 162174993Srafan _nc_globals.have_sigwinch = 0; 163174993Srafan 164178866Srafan for (each_screen(scan)) { 165174993Srafan scan->_sig_winch = TRUE; 166166124Srafan } 167166124Srafan } 168166124Srafan 169178866Srafan return (sp ? sp->_sig_winch : 0); 170166124Srafan} 171166124Srafan 172166124Srafan#endif 173166124Srafan 17476726SpeterNCURSES_EXPORT(void) 17562449Speteruse_env(bool f) 17650276Speter{ 17797049Speter T((T_CALLED("use_env()"))); 178174993Srafan _nc_prescreen.use_env = f; 17997049Speter returnVoid; 18050276Speter} 18150276Speter 182174993SrafanNCURSES_EXPORT(void) 183178866Srafan_nc_get_screensize(SCREEN *sp, int *linep, int *colp) 18450276Speter/* Obtain lines/columns values from the environment and/or terminfo entry */ 18550276Speter{ 186174993Srafan int my_tabsize; 187174993Srafan 18862449Speter /* figure out the size of the screen */ 18962449Speter T(("screen size: terminfo lines = %d columns = %d", lines, columns)); 19050276Speter 191174993Srafan if (!_nc_prescreen.use_env) { 19262449Speter *linep = (int) lines; 19362449Speter *colp = (int) columns; 19462449Speter } else { /* usually want to query LINES and COLUMNS from environment */ 19562449Speter int value; 19650276Speter 19762449Speter *linep = *colp = 0; 19850276Speter 19962449Speter /* first, look for environment variables */ 20062449Speter if ((value = _nc_getenv_num("LINES")) > 0) { 20162449Speter *linep = value; 20262449Speter } 20362449Speter if ((value = _nc_getenv_num("COLUMNS")) > 0) { 20462449Speter *colp = value; 20562449Speter } 20662449Speter T(("screen size: environment LINES = %d COLUMNS = %d", *linep, *colp)); 20750276Speter 20850276Speter#ifdef __EMX__ 20962449Speter if (*linep <= 0 || *colp <= 0) { 21062449Speter int screendata[2]; 21162449Speter _scrsize(screendata); 21262449Speter *colp = screendata[0]; 21362449Speter *linep = screendata[1]; 21462449Speter T(("EMX screen size: environment LINES = %d COLUMNS = %d", 21576726Speter *linep, *colp)); 21662449Speter } 21750276Speter#endif 21850276Speter#if HAVE_SIZECHANGE 21962449Speter /* if that didn't work, maybe we can try asking the OS */ 22062449Speter if (*linep <= 0 || *colp <= 0) { 22162449Speter if (isatty(cur_term->Filedes)) { 22262449Speter STRUCT_WINSIZE size; 22350276Speter 22462449Speter errno = 0; 22562449Speter do { 22662449Speter if (ioctl(cur_term->Filedes, IOCTL_WINSIZE, &size) < 0 22762449Speter && errno != EINTR) 22862449Speter goto failure; 22962449Speter } while 23062449Speter (errno == EINTR); 23150276Speter 23262449Speter /* 23362449Speter * Solaris lets users override either dimension with an 23462449Speter * environment variable. 23562449Speter */ 23662449Speter if (*linep <= 0) 237178866Srafan *linep = (sp != 0 && sp->_filtered) ? 1 : WINSIZE_ROWS(size); 23862449Speter if (*colp <= 0) 23962449Speter *colp = WINSIZE_COLS(size); 24050276Speter } 24162449Speter /* FALLTHRU */ 24262449Speter failure:; 24362449Speter } 24450276Speter#endif /* HAVE_SIZECHANGE */ 24550276Speter 24662449Speter /* if we can't get dynamic info about the size, use static */ 24776726Speter if (*linep <= 0) { 24876726Speter *linep = (int) lines; 24976726Speter } 25076726Speter if (*colp <= 0) { 25176726Speter *colp = (int) columns; 25276726Speter } 25350276Speter 25462449Speter /* the ultimate fallback, assume fixed 24x80 size */ 25597049Speter if (*linep <= 0) { 25662449Speter *linep = 24; 25797049Speter } 25897049Speter if (*colp <= 0) { 25962449Speter *colp = 80; 26050276Speter } 26150276Speter 26262449Speter /* 26362449Speter * Put the derived values back in the screen-size caps, so 26462449Speter * tigetnum() and tgetnum() will do the right thing. 26562449Speter */ 26662449Speter lines = (short) (*linep); 26762449Speter columns = (short) (*colp); 26862449Speter } 26950276Speter 27062449Speter T(("screen size is %dx%d", *linep, *colp)); 27150276Speter 27262449Speter if (VALID_NUMERIC(init_tabs)) 273174993Srafan my_tabsize = (int) init_tabs; 27462449Speter else 275174993Srafan my_tabsize = 8; 276174993Srafan 277174993Srafan#if USE_REENTRANT 278178866Srafan if (sp != 0) 279178866Srafan sp->_TABSIZE = my_tabsize; 280174993Srafan#else 281174993Srafan TABSIZE = my_tabsize; 282174993Srafan#endif 28362449Speter T(("TABSIZE = %d", TABSIZE)); 28450276Speter} 28550276Speter 28650276Speter#if USE_SIZECHANGE 28776726SpeterNCURSES_EXPORT(void) 288178866Srafan_nc_update_screensize(SCREEN *sp) 28950276Speter{ 290166124Srafan int old_lines = lines; 291166124Srafan int new_lines; 292166124Srafan int old_cols = columns; 293166124Srafan int new_cols; 29450276Speter 295178866Srafan _nc_get_screensize(sp, &new_lines, &new_cols); 296166124Srafan 297166124Srafan /* 298166124Srafan * See is_term_resized() and resizeterm(). 299166124Srafan * We're doing it this way because those functions belong to the upper 300166124Srafan * ncurses library, while this resides in the lower terminfo library. 301166124Srafan */ 302178866Srafan if (sp != 0 303178866Srafan && sp->_resize != 0) { 304166124Srafan if ((new_lines != old_lines) || (new_cols != old_cols)) 305178866Srafan sp->_resize(new_lines, new_cols); 306178866Srafan sp->_sig_winch = FALSE; 307166124Srafan } 30850276Speter} 30950276Speter#endif 31050276Speter 31150276Speter/**************************************************************************** 31250276Speter * 31350276Speter * Terminal setup 31450276Speter * 31550276Speter ****************************************************************************/ 31650276Speter 31750276Speter#define ret_error(code, fmt, arg) if (errret) {\ 31850276Speter *errret = code;\ 31950276Speter returnCode(ERR);\ 32050276Speter } else {\ 32150276Speter fprintf(stderr, fmt, arg);\ 32250276Speter exit(EXIT_FAILURE);\ 32350276Speter } 32450276Speter 32550276Speter#define ret_error0(code, msg) if (errret) {\ 32650276Speter *errret = code;\ 32750276Speter returnCode(ERR);\ 32850276Speter } else {\ 32950276Speter fprintf(stderr, msg);\ 33050276Speter exit(EXIT_FAILURE);\ 33150276Speter } 33250276Speter 33397049Speter#if USE_DATABASE || USE_TERMCAP 334166124Srafan/* 335166124Srafan * Return 1 if entry found, 0 if not found, -1 if database not accessible, 336166124Srafan * just like tgetent(). 337166124Srafan */ 33862449Speterstatic int 339166124Srafangrab_entry(const char *const tn, TERMTYPE *const tp) 34050276Speter{ 34162449Speter char filename[PATH_MAX]; 342166124Srafan int status = _nc_read_entry(tn, filename, tp); 34350276Speter 34462449Speter /* 34562449Speter * If we have an entry, force all of the cancelled strings to null 34662449Speter * pointers so we don't have to test them in the rest of the library. 34762449Speter * (The terminfo compiler bypasses this logic, since it must know if 34862449Speter * a string is cancelled, for merging entries). 34962449Speter */ 350166124Srafan if (status == TGETENT_YES) { 351166124Srafan unsigned n; 35276726Speter for_each_boolean(n, tp) { 35362449Speter if (!VALID_BOOLEAN(tp->Booleans[n])) 35476726Speter tp->Booleans[n] = FALSE; 35576726Speter } 35676726Speter for_each_string(n, tp) { 35762449Speter if (tp->Strings[n] == CANCELLED_STRING) 35876726Speter tp->Strings[n] = ABSENT_STRING; 35976726Speter } 36062449Speter } 36162449Speter return (status); 36250276Speter} 36350276Speter#endif 36450276Speter 365166124Srafan/* 366166124Srafan** do_prototype() 367166124Srafan** 368166124Srafan** Take the real command character out of the CC environment variable 369166124Srafan** and substitute it in for the prototype given in 'command_character'. 370166124Srafan*/ 371166124Srafanstatic void 372166124Srafando_prototype(void) 373166124Srafan{ 374166124Srafan int i; 375166124Srafan char CC; 376166124Srafan char proto; 377166124Srafan char *tmp; 37850276Speter 379166124Srafan tmp = getenv("CC"); 380166124Srafan CC = *tmp; 381166124Srafan proto = *command_character; 382166124Srafan 383166124Srafan for_each_string(i, &(cur_term->type)) { 384166124Srafan for (tmp = cur_term->type.Strings[i]; *tmp; tmp++) { 385166124Srafan if (*tmp == proto) 386166124Srafan *tmp = CC; 387166124Srafan } 388166124Srafan } 389166124Srafan} 390166124Srafan 39150276Speter/* 392166124Srafan * Find the locale which is in effect. 39350276Speter */ 394166124SrafanNCURSES_EXPORT(char *) 395166124Srafan_nc_get_locale(void) 396166124Srafan{ 397166124Srafan char *env; 398166124Srafan#if HAVE_LOCALE_H 399166124Srafan /* 400166124Srafan * This is preferable to using getenv() since it ensures that we are using 401166124Srafan * the locale which was actually initialized by the application. 402166124Srafan */ 403166124Srafan env = setlocale(LC_CTYPE, 0); 404166124Srafan#else 405166124Srafan if (((env = getenv("LC_ALL")) != 0 && *env != '\0') 406166124Srafan || ((env = getenv("LC_CTYPE")) != 0 && *env != '\0') 407166124Srafan || ((env = getenv("LANG")) != 0 && *env != '\0')) { 408166124Srafan ; 409166124Srafan } 410166124Srafan#endif 411166124Srafan T(("_nc_get_locale %s", _nc_visbuf(env))); 412166124Srafan return env; 413166124Srafan} 41450276Speter 415166124Srafan/* 416166124Srafan * Check if we are running in a UTF-8 locale. 417166124Srafan */ 41876726SpeterNCURSES_EXPORT(int) 419166124Srafan_nc_unicode_locale(void) 42050276Speter{ 421166124Srafan int result = 0; 422166124Srafan#if HAVE_LANGINFO_CODESET 423166124Srafan char *env = nl_langinfo(CODESET); 424166124Srafan result = !strcmp(env, "UTF-8"); 425166124Srafan T(("_nc_unicode_locale(%s) ->%d", env, result)); 426166124Srafan#else 427166124Srafan char *env = _nc_get_locale(); 428166124Srafan if (env != 0) { 429166124Srafan if (strstr(env, ".UTF-8") != 0) { 430166124Srafan result = 1; 431166124Srafan T(("_nc_unicode_locale(%s) ->%d", env, result)); 432166124Srafan } 433166124Srafan } 434166124Srafan#endif 435166124Srafan return result; 436166124Srafan} 437166124Srafan 438166124Srafan#define CONTROL_N(s) ((s) != 0 && strstr(s, "\016") != 0) 439166124Srafan#define CONTROL_O(s) ((s) != 0 && strstr(s, "\017") != 0) 440166124Srafan 441166124Srafan/* 442166124Srafan * Check for known broken cases where a UTF-8 locale breaks the alternate 443166124Srafan * character set. 444166124Srafan */ 445166124SrafanNCURSES_EXPORT(int) 446166124Srafan_nc_locale_breaks_acs(void) 447166124Srafan{ 448166124Srafan char *env; 449166124Srafan 450166124Srafan if ((env = getenv("NCURSES_NO_UTF8_ACS")) != 0) { 451166124Srafan return atoi(env); 452166124Srafan } else if ((env = getenv("TERM")) != 0) { 453166124Srafan if (strstr(env, "linux")) 454166124Srafan return 1; /* always broken */ 455166124Srafan if (strstr(env, "screen") != 0 456166124Srafan && ((env = getenv("TERMCAP")) != 0 457166124Srafan && strstr(env, "screen") != 0) 458166124Srafan && strstr(env, "hhII00") != 0) { 459166124Srafan if (CONTROL_N(enter_alt_charset_mode) || 460166124Srafan CONTROL_O(enter_alt_charset_mode) || 461166124Srafan CONTROL_N(set_attributes) || 462166124Srafan CONTROL_O(set_attributes)) 463166124Srafan return 1; 464166124Srafan } 465166124Srafan } 466166124Srafan return 0; 467166124Srafan} 468166124Srafan 469166124Srafan/* 470166124Srafan * This entrypoint is called from tgetent() to allow a special case of reusing 471166124Srafan * the same TERMINAL data (see comment). 472166124Srafan */ 473166124SrafanNCURSES_EXPORT(int) 474166124Srafan_nc_setupterm(NCURSES_CONST char *tname, int Filedes, int *errret, bool reuse) 475166124Srafan{ 47662449Speter int status; 47750276Speter 478166124Srafan START_TRACE(); 47962449Speter T((T_CALLED("setupterm(%s,%d,%p)"), _nc_visbuf(tname), Filedes, errret)); 48050276Speter 48162449Speter if (tname == 0) { 48262449Speter tname = getenv("TERM"); 48362449Speter if (tname == 0 || *tname == '\0') { 484166124Srafan ret_error0(TGETENT_ERR, "TERM environment variable not set.\n"); 48550276Speter } 48662449Speter } 487166124Srafan 48862449Speter if (strlen(tname) > MAX_NAME_SIZE) { 489166124Srafan ret_error(TGETENT_ERR, 490166124Srafan "TERM environment must be <= %d characters.\n", 49176726Speter MAX_NAME_SIZE); 49262449Speter } 49350276Speter 49462449Speter T(("your terminal name is %s", tname)); 49550276Speter 496166124Srafan /* 497166124Srafan * Allow output redirection. This is what SVr3 does. If stdout is 498166124Srafan * directed to a file, screen updates go to standard error. 499166124Srafan */ 500166124Srafan if (Filedes == STDOUT_FILENO && !isatty(Filedes)) 501166124Srafan Filedes = STDERR_FILENO; 50250276Speter 503166124Srafan /* 504166124Srafan * Check if we have already initialized to use this terminal. If so, we 505166124Srafan * do not need to re-read the terminfo entry, or obtain TTY settings. 506166124Srafan * 507166124Srafan * This is an improvement on SVr4 curses. If an application mixes curses 508166124Srafan * and termcap calls, it may call both initscr and tgetent. This is not 509166124Srafan * really a good thing to do, but can happen if someone tries using ncurses 510166124Srafan * with the readline library. The problem we are fixing is that when 511166124Srafan * tgetent calls setupterm, the resulting Ottyb struct in cur_term is 512166124Srafan * zeroed. A subsequent call to endwin uses the zeroed terminal settings 513166124Srafan * rather than the ones saved in initscr. So we check if cur_term appears 514166124Srafan * to contain terminal settings for the same output file as our current 515166124Srafan * call - and copy those terminal settings. (SVr4 curses does not do this, 516166124Srafan * however applications that are working around the problem will still work 517166124Srafan * properly with this feature). 518166124Srafan */ 519166124Srafan if (reuse 520166124Srafan && cur_term != 0 521166124Srafan && cur_term->Filedes == Filedes 522166124Srafan && cur_term->_termname != 0 523166124Srafan && !strcmp(cur_term->_termname, tname) 524166124Srafan && _nc_name_match(cur_term->type.term_names, tname, "|")) { 525166124Srafan T(("reusing existing terminal information and mode-settings")); 526166124Srafan } else { 527166124Srafan TERMINAL *term_ptr; 528166124Srafan 529166124Srafan term_ptr = typeCalloc(TERMINAL, 1); 530166124Srafan 531166124Srafan if (term_ptr == 0) { 532166124Srafan ret_error0(TGETENT_ERR, 533166124Srafan "Not enough memory to create terminal structure.\n"); 534166124Srafan } 53597049Speter#if USE_DATABASE || USE_TERMCAP 536166124Srafan status = grab_entry(tname, &term_ptr->type); 53750276Speter#else 538166124Srafan status = TGETENT_NO; 53950276Speter#endif 54050276Speter 541166124Srafan /* try fallback list if entry on disk */ 542166124Srafan if (status != TGETENT_YES) { 543166124Srafan const TERMTYPE *fallback = _nc_fallback(tname); 54450276Speter 545166124Srafan if (fallback) { 546166124Srafan term_ptr->type = *fallback; 547166124Srafan status = TGETENT_YES; 548166124Srafan } 54950276Speter } 55050276Speter 551166124Srafan if (status != TGETENT_YES) { 552166124Srafan del_curterm(term_ptr); 553166124Srafan if (status == TGETENT_ERR) { 554166124Srafan ret_error0(status, "terminals database is inaccessible\n"); 555166124Srafan } else if (status == TGETENT_NO) { 556166124Srafan ret_error(status, "'%s': unknown terminal type.\n", tname); 557166124Srafan } 558166124Srafan } 55950276Speter 560166124Srafan set_curterm(term_ptr); 56150276Speter 562166124Srafan if (command_character && getenv("CC")) 563166124Srafan do_prototype(); 56450276Speter 565174993Srafan#if !USE_REENTRANT 566166124Srafan strncpy(ttytype, cur_term->type.term_names, NAMESIZE - 1); 567166124Srafan ttytype[NAMESIZE - 1] = '\0'; 568174993Srafan#endif 56950276Speter 570166124Srafan cur_term->Filedes = Filedes; 571166124Srafan cur_term->_termname = strdup(tname); 57250276Speter 573166124Srafan /* 574166124Srafan * If an application calls setupterm() rather than initscr() or 575166124Srafan * newterm(), we will not have the def_prog_mode() call in 576166124Srafan * _nc_setupscreen(). Do it now anyway, so we can initialize the 577166124Srafan * baudrate. 578166124Srafan */ 579166124Srafan if (isatty(Filedes)) { 580166124Srafan def_prog_mode(); 581166124Srafan baudrate(); 582166124Srafan } 583166124Srafan } 584166124Srafan 58562449Speter /* 586166124Srafan * We should always check the screensize, just in case. 58762449Speter */ 588174993Srafan#if USE_REENTRANT 589178866Srafan _nc_get_screensize(SP, 590178866Srafan SP ? &(SP->_LINES) : &(_nc_prescreen._LINES), 591174993Srafan SP ? &(SP->_COLS) : &(_nc_prescreen._COLS)); 592174993Srafan#else 593178866Srafan _nc_get_screensize(SP, &LINES, &COLS); 594174993Srafan#endif 59550276Speter 59662449Speter if (errret) 597166124Srafan *errret = TGETENT_YES; 59850276Speter 59962449Speter if (generic_type) { 600166124Srafan ret_error(TGETENT_NO, "'%s': I need something more specific.\n", tname); 60162449Speter } 60262449Speter if (hard_copy) { 603166124Srafan ret_error(TGETENT_YES, "'%s': I can't handle hardcopy terminals.\n", tname); 60462449Speter } 60562449Speter returnCode(OK); 60650276Speter} 60750276Speter 60850276Speter/* 609166124Srafan * setupterm(termname, Filedes, errret) 610166124Srafan * 611166124Srafan * Find and read the appropriate object file for the terminal 612166124Srafan * Make cur_term point to the structure. 613166124Srafan */ 614166124SrafanNCURSES_EXPORT(int) 615166124Srafansetupterm(NCURSES_CONST char *tname, int Filedes, int *errret) 61650276Speter{ 617166124Srafan return _nc_setupterm(tname, Filedes, errret, FALSE); 61850276Speter} 619