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>                         *
32166124Srafan *     and: Thomas E. Dickey                        1996-on                 *
3350276Speter ****************************************************************************/
3450276Speter
3550276Speter/*
3650276Speter**	lib_newterm.c
3750276Speter**
3850276Speter**	The newterm() function.
3950276Speter**
4050276Speter*/
4150276Speter
4250276Speter#include <curses.priv.h>
4350276Speter
4466963Speter#if SVR4_TERMIO && !defined(_POSIX_SOURCE)
4550276Speter#define _POSIX_SOURCE
4650276Speter#endif
4750276Speter
4862449Speter#include <term.h>		/* clear_screen, cup & friends, cur_term */
4962449Speter#include <tic.h>
5050276Speter
51184989SrafanMODULE_ID("$Id: lib_newterm.c,v 1.73 2008/08/16 21:20:48 Werner.Fink Exp $")
5250276Speter
5362449Speter#ifndef ONLCR			/* Allows compilation under the QNX 4.2 OS */
5450276Speter#define ONLCR 0
5550276Speter#endif
5650276Speter
5750276Speter/*
5850276Speter * SVr4/XSI Curses specify that hardware echo is turned off in initscr, and not
5950276Speter * restored during the curses session.  The library simulates echo in software.
6050276Speter * (The behavior is unspecified if the application enables hardware echo).
6150276Speter *
6250276Speter * The newterm function also initializes terminal settings, and since initscr
6350276Speter * is supposed to behave as if it calls newterm, we do it here.
6450276Speter */
65166124Srafanstatic NCURSES_INLINE int
6662449Speter_nc_initscr(void)
6750276Speter{
68166124Srafan    int result = ERR;
69166124Srafan
7062449Speter    /* for extended XPG4 conformance requires cbreak() at this point */
7162449Speter    /* (SVr4 curses does this anyway) */
72166124Srafan    if (cbreak() == OK) {
73166124Srafan	TTY buf;
7450276Speter
75166124Srafan	buf = cur_term->Nttyb;
7650276Speter#ifdef TERMIOS
77166124Srafan	buf.c_lflag &= ~(ECHO | ECHONL);
78166124Srafan	buf.c_iflag &= ~(ICRNL | INLCR | IGNCR);
79166124Srafan	buf.c_oflag &= ~(ONLCR);
80166124Srafan#elif HAVE_SGTTY_H
81166124Srafan	buf.sg_flags &= ~(ECHO | CRMOD);
8250276Speter#else
83166124Srafan	memset(&buf, 0, sizeof(buf));
8450276Speter#endif
85166124Srafan	if ((result = _nc_set_tty_mode(&buf)) == OK)
86166124Srafan	    cur_term->Nttyb = buf;
87166124Srafan    }
88166124Srafan    return result;
8950276Speter}
9050276Speter
9150276Speter/*
9250276Speter * filter() has to be called before either initscr() or newterm(), so there is
9350276Speter * apparently no way to make this flag apply to some terminals and not others,
9450276Speter * aside from possibly delaying a filter() call until some terminals have been
9550276Speter * initialized.
9650276Speter */
9776726SpeterNCURSES_EXPORT(void)
9862449Speterfilter(void)
9950276Speter{
100166124Srafan    START_TRACE();
10197049Speter    T((T_CALLED("filter")));
102174993Srafan    _nc_prescreen.filter_mode = TRUE;
10397049Speter    returnVoid;
10450276Speter}
10550276Speter
106166124Srafan#if NCURSES_EXT_FUNCS
107166124Srafan/*
108166124Srafan * An extension, allowing the application to open a new screen without
109166124Srafan * requiring it to also be filtered.
110166124Srafan */
111166124SrafanNCURSES_EXPORT(void)
112166124Srafannofilter(void)
113166124Srafan{
114166124Srafan    START_TRACE();
115166124Srafan    T((T_CALLED("nofilter")));
116174993Srafan    _nc_prescreen.filter_mode = FALSE;
117166124Srafan    returnVoid;
118166124Srafan}
119166124Srafan#endif
120166124Srafan
12176726SpeterNCURSES_EXPORT(SCREEN *)
122166124Srafannewterm(NCURSES_CONST char *name, FILE *ofp, FILE *ifp)
12350276Speter{
124166124Srafan    int value;
12562449Speter    int errret;
12662449Speter    SCREEN *current;
127166124Srafan    SCREEN *result = 0;
128184989Srafan    TERMINAL *its_term;
12950276Speter
130166124Srafan    START_TRACE();
13162449Speter    T((T_CALLED("newterm(\"%s\",%p,%p)"), name, ofp, ifp));
13250276Speter
133184989Srafan    _nc_init_pthreads();
134184989Srafan    _nc_lock_global(curses);
135184989Srafan
136184989Srafan    current = SP;
137184989Srafan    its_term = (SP ? SP->_term : 0);
138184989Srafan
139166124Srafan    /* this loads the capability entry, then sets LINES and COLS */
140178866Srafan    if (setupterm(name, fileno(ofp), &errret) != ERR) {
141178866Srafan	int slk_format = _nc_globals.slk_format;
142178866Srafan
143166124Srafan	/*
144166124Srafan	 * This actually allocates the screen structure, and saves the original
145166124Srafan	 * terminal settings.
146166124Srafan	 */
147166124Srafan	_nc_set_screen(0);
148174993Srafan
149174993Srafan	/* allow user to set maximum escape delay from the environment */
150174993Srafan	if ((value = _nc_getenv_num("ESCDELAY")) >= 0) {
151178866Srafan	    set_escdelay(value);
152174993Srafan	}
153174993Srafan
154174993Srafan	if (_nc_setupscreen(LINES,
155174993Srafan			    COLS,
156174993Srafan			    ofp,
157174993Srafan			    _nc_prescreen.filter_mode,
158174993Srafan			    slk_format) == ERR) {
159166124Srafan	    _nc_set_screen(current);
160166124Srafan	    result = 0;
161166124Srafan	} else {
162184989Srafan	    assert(SP != 0);
163184989Srafan	    /*
164184989Srafan	     * In setupterm() we did a set_curterm(), but it was before we set
165184989Srafan	     * SP.  So the "current" screen's terminal pointer was overwritten
166184989Srafan	     * with a different terminal.  Later, in _nc_setupscreen(), we set
167184989Srafan	     * SP and the terminal pointer in the new screen.
168184989Srafan	     *
169184989Srafan	     * Restore the terminal-pointer for the pre-existing screen, if
170184989Srafan	     * any.
171184989Srafan	     */
172184989Srafan	    if (current)
173184989Srafan		current->_term = its_term;
174184989Srafan
175166124Srafan	    /* if the terminal type has real soft labels, set those up */
176166124Srafan	    if (slk_format && num_labels > 0 && SLK_STDFMT(slk_format))
177166124Srafan		_nc_slk_initialize(stdscr, COLS);
17850276Speter
179166124Srafan	    SP->_ifd = fileno(ifp);
180166124Srafan	    typeahead(fileno(ifp));
18150276Speter#ifdef TERMIOS
182166124Srafan	    SP->_use_meta = ((cur_term->Ottyb.c_cflag & CSIZE) == CS8 &&
183166124Srafan			     !(cur_term->Ottyb.c_iflag & ISTRIP));
18450276Speter#else
185166124Srafan	    SP->_use_meta = FALSE;
18650276Speter#endif
187166124Srafan	    SP->_endwin = FALSE;
18850276Speter
189166124Srafan	    /*
190166124Srafan	     * Check whether we can optimize scrolling under dumb terminals in
191166124Srafan	     * case we do not have any of these capabilities, scrolling
192166124Srafan	     * optimization will be useless.
193166124Srafan	     */
194166124Srafan	    SP->_scrolling = ((scroll_forward && scroll_reverse) ||
195166124Srafan			      ((parm_rindex ||
196166124Srafan				parm_insert_line ||
197166124Srafan				insert_line) &&
198166124Srafan			       (parm_index ||
199166124Srafan				parm_delete_line ||
200166124Srafan				delete_line)));
20150276Speter
202166124Srafan	    baudrate();		/* sets a field in the SP structure */
20350276Speter
204166124Srafan	    SP->_keytry = 0;
20550276Speter
206166124Srafan	    /*
207166124Srafan	     * Check for mismatched graphic-rendition capabilities.  Most SVr4
208166124Srafan	     * terminfo trees contain entries that have rmul or rmso equated to
209166124Srafan	     * sgr0 (Solaris curses copes with those entries).  We do this only
210166124Srafan	     * for curses, since many termcap applications assume that
211166124Srafan	     * smso/rmso and smul/rmul are paired, and will not function
212166124Srafan	     * properly if we remove rmso or rmul.  Curses applications
213166124Srafan	     * shouldn't be looking at this detail.
214166124Srafan	     */
21550276Speter#define SGR0_TEST(mode) (mode != 0) && (exit_attribute_mode == 0 || strcmp(mode, exit_attribute_mode))
216166124Srafan	    SP->_use_rmso = SGR0_TEST(exit_standout_mode);
217166124Srafan	    SP->_use_rmul = SGR0_TEST(exit_underline_mode);
21850276Speter
219166124Srafan	    /* compute movement costs so we can do better move optimization */
220166124Srafan	    _nc_mvcur_init();
22150276Speter
222166124Srafan	    /* initialize terminal to a sane state */
223166124Srafan	    _nc_screen_init();
22450276Speter
225166124Srafan	    /* Initialize the terminal line settings. */
226166124Srafan	    _nc_initscr();
22750276Speter
228166124Srafan	    _nc_signal_handler(TRUE);
22962449Speter
230166124Srafan	    result = SP;
231166124Srafan	}
232166124Srafan    }
233184989Srafan    _nc_unlock_global(curses);
234166124Srafan    returnSP(result);
23550276Speter}
236