lib_set_term.c revision 97049
150276Speter/****************************************************************************
297049Speter * Copyright (c) 1998,1999,2000,2001 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>                         *
3250276Speter ****************************************************************************/
3350276Speter
3450276Speter/*
3550276Speter**	lib_set_term.c
3650276Speter**
3750276Speter**	The routine set_term().
3850276Speter**
3950276Speter*/
4050276Speter
4150276Speter#include <curses.priv.h>
4250276Speter
4362449Speter#include <term.h>		/* cur_term */
4462449Speter#include <tic.h>
4550276Speter
4697049SpeterMODULE_ID("$Id: lib_set_term.c,v 1.64 2002/02/10 00:21:10 tom Exp $")
4750276Speter
4876726SpeterNCURSES_EXPORT(SCREEN *)
4962449Speterset_term(SCREEN * screenp)
5050276Speter{
5162449Speter    SCREEN *oldSP;
5250276Speter
5362449Speter    T((T_CALLED("set_term(%p)"), screenp));
5450276Speter
5562449Speter    oldSP = SP;
5662449Speter    _nc_set_screen(screenp);
5750276Speter
5862449Speter    set_curterm(SP->_term);
5962449Speter    curscr = SP->_curscr;
6062449Speter    newscr = SP->_newscr;
6162449Speter    stdscr = SP->_stdscr;
6262449Speter    COLORS = SP->_color_count;
6362449Speter    COLOR_PAIRS = SP->_pair_count;
6462449Speter    memcpy(acs_map, SP->_acs_map, sizeof(chtype) * ACS_LEN);
6550276Speter
6662449Speter    T((T_RETURN("%p"), oldSP));
6762449Speter    return (oldSP);
6850276Speter}
6950276Speter
7062449Speterstatic void
7162449Speter_nc_free_keytry(struct tries *kt)
7250276Speter{
7362449Speter    if (kt != 0) {
7462449Speter	_nc_free_keytry(kt->child);
7562449Speter	_nc_free_keytry(kt->sibling);
7662449Speter	free(kt);
7762449Speter    }
7850276Speter}
7950276Speter
8050276Speter/*
8150276Speter * Free the storage associated with the given SCREEN sp.
8250276Speter */
8376726SpeterNCURSES_EXPORT(void)
8462449Speterdelscreen(SCREEN * sp)
8550276Speter{
8662449Speter    SCREEN **scan = &_nc_screen_chain;
8750276Speter
8862449Speter    T((T_CALLED("delscreen(%p)"), sp));
8950276Speter
9062449Speter    while (*scan) {
9162449Speter	if (*scan == sp) {
9262449Speter	    *scan = sp->_next_screen;
9362449Speter	    break;
9450276Speter	}
9562449Speter	scan = &(*scan)->_next_screen;
9662449Speter    }
9750276Speter
9876726Speter    (void) _nc_freewin(sp->_curscr);
9976726Speter    (void) _nc_freewin(sp->_newscr);
10076726Speter    (void) _nc_freewin(sp->_stdscr);
10162449Speter    _nc_free_keytry(sp->_keytry);
10262449Speter    _nc_free_keytry(sp->_key_ok);
10350276Speter
10462449Speter    FreeIfNeeded(sp->_color_table);
10562449Speter    FreeIfNeeded(sp->_color_pairs);
10650276Speter
10762449Speter    FreeIfNeeded(sp->oldhash);
10862449Speter    FreeIfNeeded(sp->newhash);
10950276Speter
11062449Speter    del_curterm(sp->_term);
11150276Speter
11262449Speter    /*
11362449Speter     * If the associated output stream has been closed, we can discard the
11462449Speter     * set-buffer.  Limit the error check to EBADF, since fflush may fail
11562449Speter     * for other reasons than trying to operate upon a closed stream.
11662449Speter     */
11762449Speter    if (sp->_ofp != 0
11862449Speter	&& sp->_setbuf != 0
11962449Speter	&& fflush(sp->_ofp) != 0
12062449Speter	&& errno == EBADF) {
12162449Speter	free(sp->_setbuf);
12262449Speter    }
12350276Speter
12462449Speter    free(sp);
12562449Speter
12662449Speter    /*
12762449Speter     * If this was the current screen, reset everything that the
12862449Speter     * application might try to use (except cur_term, which may have
12962449Speter     * multiple references in different screens).
13062449Speter     */
13162449Speter    if (sp == SP) {
13262449Speter	curscr = 0;
13362449Speter	newscr = 0;
13462449Speter	stdscr = 0;
13562449Speter	COLORS = 0;
13662449Speter	COLOR_PAIRS = 0;
13762449Speter	_nc_set_screen(0);
13862449Speter    }
13962449Speter    returnVoid;
14050276Speter}
14150276Speter
14250276Speterstatic ripoff_t rippedoff[5];
14350276Speterstatic ripoff_t *rsp = rippedoff;
14450276Speter#define N_RIPS SIZEOF(rippedoff)
14550276Speter
14662449Speterstatic bool
14762449Speterno_mouse_event(SCREEN * sp GCC_UNUSED)
14862449Speter{
14962449Speter    return FALSE;
15062449Speter}
15150276Speter
15262449Speterstatic bool
15362449Speterno_mouse_inline(SCREEN * sp GCC_UNUSED)
15462449Speter{
15562449Speter    return FALSE;
15662449Speter}
15762449Speter
15862449Speterstatic bool
15962449Speterno_mouse_parse(int code GCC_UNUSED)
16062449Speter{
16162449Speter    return TRUE;
16262449Speter}
16362449Speter
16462449Speterstatic void
16562449Speterno_mouse_resume(SCREEN * sp GCC_UNUSED)
16662449Speter{
16762449Speter}
16862449Speter
16962449Speterstatic void
17062449Speterno_mouse_wrap(SCREEN * sp GCC_UNUSED)
17162449Speter{
17262449Speter}
17362449Speter
17466963Speter#if NCURSES_EXT_FUNCS && USE_COLORFGBG
17562449Speterstatic char *
17662449Speterextract_fgbg(char *src, int *result)
17762449Speter{
17862449Speter    char *dst = 0;
17962449Speter    long value = strtol(src, &dst, 0);
18062449Speter
18162449Speter    if (dst == 0) {
18262449Speter	dst = src;
18362449Speter    } else if (value >= 0) {
18462449Speter	*result = value % max_colors;
18562449Speter    }
18662449Speter    while (*dst != 0 && *dst != ';')
18762449Speter	dst++;
18862449Speter    if (*dst == ';')
18962449Speter	dst++;
19062449Speter    return dst;
19162449Speter}
19262449Speter#endif
19362449Speter
19476726SpeterNCURSES_EXPORT(int)
19576726Speter_nc_setupscreen
19676726Speter(short slines, short const scolumns, FILE * output)
19750276Speter/* OS-independent screen initializations */
19850276Speter{
19962449Speter    int bottom_stolen = 0;
20062449Speter    size_t i;
20150276Speter
20262449Speter    assert(SP == 0);		/* has been reset in newterm() ! */
20362449Speter    if (!_nc_alloc_screen())
20462449Speter	return ERR;
20550276Speter
20662449Speter    SP->_next_screen = _nc_screen_chain;
20762449Speter    _nc_screen_chain = SP;
20850276Speter
20962449Speter    _nc_set_buffer(output, TRUE);
21062449Speter    SP->_term = cur_term;
21162449Speter    SP->_lines = slines;
21262449Speter    SP->_lines_avail = slines;
21362449Speter    SP->_columns = scolumns;
21462449Speter    SP->_cursrow = -1;
21562449Speter    SP->_curscol = -1;
21662449Speter    SP->_nl = TRUE;
21762449Speter    SP->_raw = FALSE;
21862449Speter    SP->_cbreak = 0;
21962449Speter    SP->_echo = TRUE;
22062449Speter    SP->_fifohead = -1;
22162449Speter    SP->_endwin = TRUE;
22262449Speter    SP->_ofp = output;
22362449Speter    SP->_cursor = -1;		/* cannot know real cursor shape */
22466963Speter
22566963Speter#if NCURSES_NO_PADDING
22662449Speter    SP->_no_padding = getenv("NCURSES_NO_PADDING") != 0;
22762449Speter    TR(TRACE_CHARPUT | TRACE_MOVE, ("padding will%s be used",
22876726Speter				    SP->_no_padding ? " not" : ""));
22950276Speter#endif
23066963Speter
23166963Speter#if NCURSES_EXT_FUNCS
23262449Speter    SP->_default_color = FALSE;
23362449Speter    SP->_has_sgr_39_49 = FALSE;
23466963Speter
23566963Speter    /*
23666963Speter     * Set our assumption of the terminal's default foreground and background
23766963Speter     * colors.  The curs_color man-page states that we can assume that the
23866963Speter     * background is black.  The origin of this assumption appears to be
23966963Speter     * terminals that displayed colored text, but no colored backgrounds, e.g.,
24066963Speter     * the first colored terminals around 1980.  More recent ones with better
24166963Speter     * technology can display not only colored backgrounds, but all
24266963Speter     * combinations.  So a terminal might be something other than "white" on
24366963Speter     * black (green/black looks monochrome too), but black on white or even
24466963Speter     * on ivory.
24566963Speter     *
24666963Speter     * White-on-black is the simplest thing to use for monochrome.  Almost
24766963Speter     * all applications that use color paint both text and background, so
24866963Speter     * the distinction is moot.  But a few do not - which is why we leave this
24966963Speter     * configurable (a better solution is to use assume_default_colors() for
25066963Speter     * the rare applications that do require that sort of appearance, since
25166963Speter     * is appears that more users expect to be able to make a white-on-black
25266963Speter     * or black-on-white display under control of the application than not).
25366963Speter     */
25466963Speter#ifdef USE_ASSUMED_COLOR
25562449Speter    SP->_default_fg = COLOR_WHITE;
25662449Speter    SP->_default_bg = COLOR_BLACK;
25766963Speter#else
25866963Speter    SP->_default_fg = C_MASK;
25966963Speter    SP->_default_bg = C_MASK;
26066963Speter#endif
26166963Speter
26266963Speter#if USE_COLORFGBG
26362449Speter    /*
26462449Speter     * If rxvt's $COLORFGBG variable is set, use it to specify the assumed
26562449Speter     * default colors.  Note that rxvt (mis)uses bold colors, equating a bold
26662449Speter     * color to that value plus 8.  We'll only use the non-bold color for now -
26762449Speter     * decide later if it is worth having default attributes as well.
26862449Speter     */
26962449Speter    if (getenv("COLORFGBG") != 0) {
27062449Speter	char *p = getenv("COLORFGBG");
27197049Speter	TR(TRACE_CHARPUT | TRACE_MOVE, ("decoding COLORFGBG %s", p));
27262449Speter	p = extract_fgbg(p, &(SP->_default_fg));
27362449Speter	p = extract_fgbg(p, &(SP->_default_bg));
27497049Speter	if (*p)			/* assume rxvt was compiled with xpm support */
27597049Speter	    p = extract_fgbg(p, &(SP->_default_bg));
27697049Speter	TR(TRACE_CHARPUT | TRACE_MOVE, ("decoded fg=%d, bg=%d",
27797049Speter					SP->_default_fg, SP->_default_bg));
27862449Speter    }
27962449Speter#endif
28062449Speter#endif /* NCURSES_EXT_FUNCS */
28150276Speter
28262449Speter    SP->_maxclick = DEFAULT_MAXCLICK;
28362449Speter    SP->_mouse_event = no_mouse_event;
28462449Speter    SP->_mouse_inline = no_mouse_inline;
28562449Speter    SP->_mouse_parse = no_mouse_parse;
28662449Speter    SP->_mouse_resume = no_mouse_resume;
28762449Speter    SP->_mouse_wrap = no_mouse_wrap;
28862449Speter    SP->_mouse_fd = -1;
28950276Speter
29062449Speter    /* initialize the panel hooks */
29162449Speter    SP->_panelHook.top_panel = (struct panel *) 0;
29262449Speter    SP->_panelHook.bottom_panel = (struct panel *) 0;
29362449Speter    SP->_panelHook.stdscr_pseudo_panel = (struct panel *) 0;
29450276Speter
29562449Speter    /*
29662449Speter     * If we've no magic cookie support, we suppress attributes that xmc
29762449Speter     * would affect, i.e., the attributes that affect the rendition of a
29862449Speter     * space.  Note that this impacts the alternate character set mapping
29962449Speter     * as well.
30062449Speter     */
30162449Speter    if (magic_cookie_glitch > 0) {
30250276Speter
30362449Speter	SP->_xmc_triggers = termattrs() & (
30476726Speter					      A_ALTCHARSET |
30576726Speter					      A_BLINK |
30676726Speter					      A_BOLD |
30776726Speter					      A_REVERSE |
30876726Speter					      A_STANDOUT |
30976726Speter					      A_UNDERLINE
31062449Speter	    );
31162449Speter	SP->_xmc_suppress = SP->_xmc_triggers & (chtype) ~ (A_BOLD);
31250276Speter
31362449Speter	T(("magic cookie attributes %s", _traceattr(SP->_xmc_suppress)));
31450276Speter#if USE_XMC_SUPPORT
31562449Speter	/*
31662449Speter	 * To keep this simple, suppress all of the optimization hooks
31762449Speter	 * except for clear_screen and the cursor addressing.
31862449Speter	 */
31962449Speter	clr_eol = 0;
32062449Speter	clr_eos = 0;
32162449Speter	set_attributes = 0;
32250276Speter#else
32362449Speter	magic_cookie_glitch = ABSENT_NUMERIC;
32462449Speter	acs_chars = 0;
32550276Speter#endif
32662449Speter    }
32797049Speter#if USE_WIDEC_SUPPORT
32897049Speter    _nc_init_wacs();
32997049Speter#endif
33062449Speter    _nc_init_acs();
33162449Speter    memcpy(SP->_acs_map, acs_map, sizeof(chtype) * ACS_LEN);
33250276Speter
33362449Speter    _nc_idcok = TRUE;
33462449Speter    _nc_idlok = FALSE;
33550276Speter
33662449Speter    _nc_windows = 0;		/* no windows yet */
33750276Speter
33862449Speter    SP->oldhash = 0;
33962449Speter    SP->newhash = 0;
34050276Speter
34162449Speter    T(("creating newscr"));
34262449Speter    if ((newscr = newwin(slines, scolumns, 0, 0)) == 0)
34362449Speter	return ERR;
34450276Speter
34562449Speter    T(("creating curscr"));
34662449Speter    if ((curscr = newwin(slines, scolumns, 0, 0)) == 0)
34762449Speter	return ERR;
34850276Speter
34962449Speter    SP->_newscr = newscr;
35062449Speter    SP->_curscr = curscr;
35150276Speter#if USE_SIZECHANGE
35262449Speter    SP->_resize = resizeterm;
35350276Speter#endif
35450276Speter
35562449Speter    newscr->_clear = TRUE;
35662449Speter    curscr->_clear = FALSE;
35750276Speter
35897049Speter    def_shell_mode();
35997049Speter    def_prog_mode();
36097049Speter
36162449Speter    for (i = 0, rsp = rippedoff; rsp->line && (i < N_RIPS); rsp++, i++) {
36262449Speter	if (rsp->hook) {
36362449Speter	    WINDOW *w;
36462449Speter	    int count = (rsp->line < 0) ? -rsp->line : rsp->line;
36550276Speter
36662449Speter	    if (rsp->line < 0) {
36762449Speter		w = newwin(count, scolumns, SP->_lines_avail - count, 0);
36862449Speter		if (w) {
36962449Speter		    rsp->w = w;
37062449Speter		    rsp->hook(w, scolumns);
37162449Speter		    bottom_stolen += count;
37262449Speter		} else
37350276Speter		    return ERR;
37462449Speter	    } else {
37562449Speter		w = newwin(count, scolumns, 0, 0);
37662449Speter		if (w) {
37762449Speter		    rsp->w = w;
37862449Speter		    rsp->hook(w, scolumns);
37962449Speter		    SP->_topstolen += count;
38062449Speter		} else
38150276Speter		    return ERR;
38262449Speter	    }
38362449Speter	    SP->_lines_avail -= count;
38450276Speter	}
38562449Speter	rsp->line = 0;
38662449Speter    }
38762449Speter    /* reset the stack */
38862449Speter    rsp = rippedoff;
38950276Speter
39062449Speter    T(("creating stdscr"));
39162449Speter    assert((SP->_lines_avail + SP->_topstolen + bottom_stolen) == slines);
39262449Speter    if ((stdscr = newwin(LINES = SP->_lines_avail, scolumns, 0, 0)) == 0)
39362449Speter	return ERR;
39462449Speter    SP->_stdscr = stdscr;
39550276Speter
39662449Speter    return OK;
39750276Speter}
39850276Speter
39950276Speter/* The internal implementation interprets line as the number of
40050276Speter   lines to rip off from the top or bottom.
40150276Speter   */
40276726SpeterNCURSES_EXPORT(int)
40362449Speter_nc_ripoffline(int line, int (*init) (WINDOW *, int))
40450276Speter{
40550276Speter    if (line == 0)
40662449Speter	return (OK);
40750276Speter
40850276Speter    if (rsp >= rippedoff + N_RIPS)
40962449Speter	return (ERR);
41050276Speter
41150276Speter    rsp->line = line;
41250276Speter    rsp->hook = init;
41362449Speter    rsp->w = 0;
41450276Speter    rsp++;
41550276Speter
41662449Speter    return (OK);
41750276Speter}
41850276Speter
41976726SpeterNCURSES_EXPORT(int)
42062449Speterripoffline(int line, int (*init) (WINDOW *, int))
42150276Speter{
42250276Speter    T((T_CALLED("ripoffline(%d,%p)"), line, init));
42350276Speter
42450276Speter    if (line == 0)
42550276Speter	returnCode(OK);
42650276Speter
42762449Speter    returnCode(_nc_ripoffline((line < 0) ? -1 : 1, init));
42850276Speter}
429