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