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