lib_set_term.c revision 66963
150276Speter/****************************************************************************
262449Speter * Copyright (c) 1998,1999,2000 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
4666963SpeterMODULE_ID("$Id: lib_set_term.c,v 1.58 2000/10/04 22:05:48 tom Exp $")
4750276Speter
4862449SpeterSCREEN *
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 */
8362449Spetervoid
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
9862449Speter    _nc_freewin(sp->_curscr);
9962449Speter    _nc_freewin(sp->_newscr);
10062449Speter    _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
19462449Speterint
19562449Speter_nc_setupscreen(short slines, short const scolumns, FILE * output)
19650276Speter/* OS-independent screen initializations */
19750276Speter{
19862449Speter    int bottom_stolen = 0;
19962449Speter    size_t i;
20050276Speter
20162449Speter    assert(SP == 0);		/* has been reset in newterm() ! */
20262449Speter    if (!_nc_alloc_screen())
20362449Speter	return ERR;
20450276Speter
20562449Speter    SP->_next_screen = _nc_screen_chain;
20662449Speter    _nc_screen_chain = SP;
20750276Speter
20862449Speter    _nc_set_buffer(output, TRUE);
20962449Speter    SP->_term = cur_term;
21062449Speter    SP->_lines = slines;
21162449Speter    SP->_lines_avail = slines;
21262449Speter    SP->_columns = scolumns;
21362449Speter    SP->_cursrow = -1;
21462449Speter    SP->_curscol = -1;
21562449Speter    SP->_nl = TRUE;
21662449Speter    SP->_raw = FALSE;
21762449Speter    SP->_cbreak = 0;
21862449Speter    SP->_echo = TRUE;
21962449Speter    SP->_fifohead = -1;
22062449Speter    SP->_endwin = TRUE;
22162449Speter    SP->_ofp = output;
22262449Speter    SP->_cursor = -1;		/* cannot know real cursor shape */
22366963Speter
22466963Speter#if NCURSES_NO_PADDING
22562449Speter    SP->_no_padding = getenv("NCURSES_NO_PADDING") != 0;
22662449Speter    TR(TRACE_CHARPUT | TRACE_MOVE, ("padding will%s be used",
22762449Speter	    SP->_no_padding ? " not" : ""));
22850276Speter#endif
22966963Speter
23066963Speter#if NCURSES_EXT_FUNCS
23162449Speter    SP->_default_color = FALSE;
23262449Speter    SP->_has_sgr_39_49 = FALSE;
23366963Speter
23466963Speter    /*
23566963Speter     * Set our assumption of the terminal's default foreground and background
23666963Speter     * colors.  The curs_color man-page states that we can assume that the
23766963Speter     * background is black.  The origin of this assumption appears to be
23866963Speter     * terminals that displayed colored text, but no colored backgrounds, e.g.,
23966963Speter     * the first colored terminals around 1980.  More recent ones with better
24066963Speter     * technology can display not only colored backgrounds, but all
24166963Speter     * combinations.  So a terminal might be something other than "white" on
24266963Speter     * black (green/black looks monochrome too), but black on white or even
24366963Speter     * on ivory.
24466963Speter     *
24566963Speter     * White-on-black is the simplest thing to use for monochrome.  Almost
24666963Speter     * all applications that use color paint both text and background, so
24766963Speter     * the distinction is moot.  But a few do not - which is why we leave this
24866963Speter     * configurable (a better solution is to use assume_default_colors() for
24966963Speter     * the rare applications that do require that sort of appearance, since
25066963Speter     * is appears that more users expect to be able to make a white-on-black
25166963Speter     * or black-on-white display under control of the application than not).
25266963Speter     */
25366963Speter#ifdef USE_ASSUMED_COLOR
25462449Speter    SP->_default_fg = COLOR_WHITE;
25562449Speter    SP->_default_bg = COLOR_BLACK;
25666963Speter#else
25766963Speter    SP->_default_fg = C_MASK;
25866963Speter    SP->_default_bg = C_MASK;
25966963Speter#endif
26066963Speter
26166963Speter#if USE_COLORFGBG
26262449Speter    /*
26362449Speter     * If rxvt's $COLORFGBG variable is set, use it to specify the assumed
26462449Speter     * default colors.  Note that rxvt (mis)uses bold colors, equating a bold
26562449Speter     * color to that value plus 8.  We'll only use the non-bold color for now -
26662449Speter     * decide later if it is worth having default attributes as well.
26762449Speter     */
26862449Speter    if (getenv("COLORFGBG") != 0) {
26962449Speter	char *p = getenv("COLORFGBG");
27062449Speter	p = extract_fgbg(p, &(SP->_default_fg));
27162449Speter	p = extract_fgbg(p, &(SP->_default_bg));
27262449Speter    }
27362449Speter#endif
27462449Speter#endif /* NCURSES_EXT_FUNCS */
27550276Speter
27662449Speter    SP->_maxclick = DEFAULT_MAXCLICK;
27762449Speter    SP->_mouse_event = no_mouse_event;
27862449Speter    SP->_mouse_inline = no_mouse_inline;
27962449Speter    SP->_mouse_parse = no_mouse_parse;
28062449Speter    SP->_mouse_resume = no_mouse_resume;
28162449Speter    SP->_mouse_wrap = no_mouse_wrap;
28262449Speter    SP->_mouse_fd = -1;
28350276Speter
28462449Speter    /* initialize the panel hooks */
28562449Speter    SP->_panelHook.top_panel = (struct panel *) 0;
28662449Speter    SP->_panelHook.bottom_panel = (struct panel *) 0;
28762449Speter    SP->_panelHook.stdscr_pseudo_panel = (struct panel *) 0;
28850276Speter
28962449Speter    /*
29062449Speter     * If we've no magic cookie support, we suppress attributes that xmc
29162449Speter     * would affect, i.e., the attributes that affect the rendition of a
29262449Speter     * space.  Note that this impacts the alternate character set mapping
29362449Speter     * as well.
29462449Speter     */
29562449Speter    if (magic_cookie_glitch > 0) {
29650276Speter
29762449Speter	SP->_xmc_triggers = termattrs() & (
29862449Speter	    A_ALTCHARSET |
29962449Speter	    A_BLINK |
30062449Speter	    A_BOLD |
30162449Speter	    A_REVERSE |
30262449Speter	    A_STANDOUT |
30362449Speter	    A_UNDERLINE
30462449Speter	    );
30562449Speter	SP->_xmc_suppress = SP->_xmc_triggers & (chtype) ~ (A_BOLD);
30650276Speter
30762449Speter	T(("magic cookie attributes %s", _traceattr(SP->_xmc_suppress)));
30850276Speter#if USE_XMC_SUPPORT
30962449Speter	/*
31062449Speter	 * To keep this simple, suppress all of the optimization hooks
31162449Speter	 * except for clear_screen and the cursor addressing.
31262449Speter	 */
31362449Speter	clr_eol = 0;
31462449Speter	clr_eos = 0;
31562449Speter	set_attributes = 0;
31650276Speter#else
31762449Speter	magic_cookie_glitch = ABSENT_NUMERIC;
31862449Speter	acs_chars = 0;
31950276Speter#endif
32062449Speter    }
32162449Speter    _nc_init_acs();
32262449Speter    memcpy(SP->_acs_map, acs_map, sizeof(chtype) * ACS_LEN);
32350276Speter
32462449Speter    _nc_idcok = TRUE;
32562449Speter    _nc_idlok = FALSE;
32650276Speter
32762449Speter    _nc_windows = 0;		/* no windows yet */
32850276Speter
32962449Speter    SP->oldhash = 0;
33062449Speter    SP->newhash = 0;
33150276Speter
33262449Speter    T(("creating newscr"));
33362449Speter    if ((newscr = newwin(slines, scolumns, 0, 0)) == 0)
33462449Speter	return ERR;
33550276Speter
33662449Speter    T(("creating curscr"));
33762449Speter    if ((curscr = newwin(slines, scolumns, 0, 0)) == 0)
33862449Speter	return ERR;
33950276Speter
34062449Speter    SP->_newscr = newscr;
34162449Speter    SP->_curscr = curscr;
34250276Speter#if USE_SIZECHANGE
34362449Speter    SP->_resize = resizeterm;
34450276Speter#endif
34550276Speter
34662449Speter    newscr->_clear = TRUE;
34762449Speter    curscr->_clear = FALSE;
34850276Speter
34962449Speter    for (i = 0, rsp = rippedoff; rsp->line && (i < N_RIPS); rsp++, i++) {
35062449Speter	if (rsp->hook) {
35162449Speter	    WINDOW *w;
35262449Speter	    int count = (rsp->line < 0) ? -rsp->line : rsp->line;
35350276Speter
35462449Speter	    if (rsp->line < 0) {
35562449Speter		w = newwin(count, scolumns, SP->_lines_avail - count, 0);
35662449Speter		if (w) {
35762449Speter		    rsp->w = w;
35862449Speter		    rsp->hook(w, scolumns);
35962449Speter		    bottom_stolen += count;
36062449Speter		} else
36150276Speter		    return ERR;
36262449Speter	    } else {
36362449Speter		w = newwin(count, scolumns, 0, 0);
36462449Speter		if (w) {
36562449Speter		    rsp->w = w;
36662449Speter		    rsp->hook(w, scolumns);
36762449Speter		    SP->_topstolen += count;
36862449Speter		} else
36950276Speter		    return ERR;
37062449Speter	    }
37162449Speter	    SP->_lines_avail -= count;
37250276Speter	}
37362449Speter	rsp->line = 0;
37462449Speter    }
37562449Speter    /* reset the stack */
37662449Speter    rsp = rippedoff;
37750276Speter
37862449Speter    T(("creating stdscr"));
37962449Speter    assert((SP->_lines_avail + SP->_topstolen + bottom_stolen) == slines);
38062449Speter    if ((stdscr = newwin(LINES = SP->_lines_avail, scolumns, 0, 0)) == 0)
38162449Speter	return ERR;
38262449Speter    SP->_stdscr = stdscr;
38350276Speter
38462449Speter    def_shell_mode();
38562449Speter    def_prog_mode();
38650276Speter
38762449Speter    return OK;
38850276Speter}
38950276Speter
39050276Speter/* The internal implementation interprets line as the number of
39150276Speter   lines to rip off from the top or bottom.
39250276Speter   */
39350276Speterint
39462449Speter_nc_ripoffline(int line, int (*init) (WINDOW *, int))
39550276Speter{
39650276Speter    if (line == 0)
39762449Speter	return (OK);
39850276Speter
39950276Speter    if (rsp >= rippedoff + N_RIPS)
40062449Speter	return (ERR);
40150276Speter
40250276Speter    rsp->line = line;
40350276Speter    rsp->hook = init;
40462449Speter    rsp->w = 0;
40550276Speter    rsp++;
40650276Speter
40762449Speter    return (OK);
40850276Speter}
40950276Speter
41050276Speterint
41162449Speterripoffline(int line, int (*init) (WINDOW *, int))
41250276Speter{
41350276Speter    T((T_CALLED("ripoffline(%d,%p)"), line, init));
41450276Speter
41550276Speter    if (line == 0)
41650276Speter	returnCode(OK);
41750276Speter
41862449Speter    returnCode(_nc_ripoffline((line < 0) ? -1 : 1, init));
41950276Speter}
420