2 /***************************************************************************
4 ****************************************************************************
5 * ncurses is copyright (C) 1992-1995 *
7 * zmbenhal@netcom.com *
9 * esr@snark.thyrsus.com *
11 * Permission is hereby granted to reproduce and distribute ncurses *
12 * by any means and for any fee, whether alone or as part of a *
13 * larger distribution, in source or in binary form, PROVIDED *
14 * this notice is included with any such distribution, and is not *
15 * removed from any of its header files. Mention of ncurses in any *
16 * applications linked with it is highly appreciated. *
18 * ncurses comes AS IS with no warranty, implied or expressed. *
20 ***************************************************************************/
24 * Terminal setup routines common to termcap and terminfo:
27 * setupterm(char *, int, int *)
30 #include <curses.priv.h>
36 #include <term.h> /* lines, columns, cur_term */
38 MODULE_ID("$Id: lib_setup.c,v 1.24 1997/03/08 21:25:44 tom Exp $")
40 /****************************************************************************
42 * Terminal size computation
44 ****************************************************************************/
46 #if !defined(sun) || !HAVE_TERMIOS_H
47 #include <sys/ioctl.h>
50 static int _use_env = TRUE;
52 static void do_prototype(void);
59 int LINES, COLS, TABSIZE;
61 void _nc_get_screensize(void)
62 /* set LINES and COLS from the environment and/or terminfo entry */
66 /* figure out the size of the screen */
67 T(("screen size: terminfo lines = %d columns = %d", lines, columns));
74 else /* usually want to query LINES and COLUMNS from environment */
78 /* first, look for environment variables */
79 rows = getenv("LINES");
80 if (rows != (char *)NULL)
82 cols = getenv("COLUMNS");
83 if (cols != (char *)NULL)
85 T(("screen size: environment LINES = %d COLUMNS = %d",LINES,COLS));
87 #if defined(TIOCGWINSZ) && !BROKEN_TIOCGWINSZ
88 /* if that didn't work, maybe we can try asking the OS */
89 if (LINES <= 0 || COLS <= 0)
91 if (isatty(cur_term->Filedes))
97 if (ioctl(cur_term->Filedes, TIOCGWINSZ, &size) < 0
103 LINES = (int)size.ws_row;
104 COLS = (int)size.ws_col;
109 #endif /* defined(TIOCGWINSZ) && !defined(BROKEN_TIOCGWINSZ) */
111 /* if we can't get dynamic info about the size, use static */
112 if (LINES <= 0 || COLS <= 0)
113 if (lines > 0 && columns > 0)
119 /* the ultimate fallback, assume fixed 24x80 size */
120 if (LINES <= 0 || COLS <= 0)
127 * Put the derived values back in the screen-size caps, so
128 * tigetnum() and tgetnum() will do the right thing.
130 lines = (short)LINES;
131 columns = (short)COLS;
134 T(("screen size is %dx%d", LINES, COLS));
138 TABSIZE = (int)init_tabs;
140 #endif /* init_tabs */
142 T(("TABSIZE = %d", TABSIZE));
146 /****************************************************************************
150 ****************************************************************************/
152 #define ret_error(code, fmt, arg) if (errret) {\
156 fprintf(stderr, fmt, arg);\
160 #define ret_error0(code, msg) if (errret) {\
164 fprintf(stderr, msg);\
168 static int grab_entry(const char *const tn, TERMTYPE *const tp)
169 /* return 1 if entry found, 0 if not found, -1 if database not accessible */
171 char filename[PATH_MAX];
174 if ((status = _nc_read_entry(tn, filename, tp)) == 1)
177 #ifndef PURE_TERMINFO
179 * Try falling back on the termcap file. Note: allowing this call
180 * links the entire terminfo/termcap compiler into the startup code.
181 * It's preferable to build a real terminfo database and use that.
183 status = _nc_read_termcap_entry(tn, tp);
184 #endif /* PURE_TERMINFO */
189 char ttytype[NAMESIZE];
192 * setupterm(termname, Filedes, errret)
194 * Find and read the appropriate object file for the terminal
195 * Make cur_term point to the structure.
199 int setupterm(const char *tname, int Filedes, int *errret)
201 struct term *term_ptr;
204 T((T_CALLED("setupterm(\"%s\",%d,%p)"), tname, Filedes, errret));
207 tname = getenv("TERM");
209 ret_error0(-1, "TERM environment variable not set.\n");
212 T(("your terminal name is %s", tname));
214 term_ptr = typeCalloc(TERMINAL, 1);
216 if (term_ptr == NULL)
217 ret_error0(-1, "Not enough memory to create terminal structure.\n") ;
218 status = grab_entry(tname, &term_ptr->type);
220 /* try fallback list if entry on disk */
223 const TERMTYPE *fallback = _nc_fallback(tname);
227 memcpy(&term_ptr->type, fallback, sizeof(TERMTYPE));
234 ret_error0(-1, "terminals database is inaccessible\n");
236 else if (status == 0)
238 ret_error(0, "'%s': unknown terminal type.\n", tname);
243 ret_error(0, "'%s': I need something more specific.\n", tname);
245 ret_error(1, "'%s': I can't handle hardcopy terminals.\n", tname);
247 if (command_character && getenv("CC"))
250 strncpy(ttytype, cur_term->type.term_names, NAMESIZE - 1);
251 ttytype[NAMESIZE - 1] = '\0';
254 * Allow output redirection. This is what SVr3 does.
255 * If stdout is directed to a file, screen updates go
258 if (Filedes == STDOUT_FILENO && !isatty(Filedes))
259 Filedes = STDERR_FILENO;
260 cur_term->Filedes = Filedes;
262 _nc_get_screensize();
267 T((T_CREATE("screen %s %dx%d"), tname, LINES, COLS));
275 ** Take the real command character out of the CC environment variable
276 ** and substitute it in for the prototype given in 'command_character'.
290 proto = *command_character;
292 for (i=0; i < STRCOUNT; i++) {
294 while (cur_term->type.Strings[i][j]) {
295 if (cur_term->type.Strings[i][j] == proto)
296 cur_term->type.Strings[i][j] = CC;