/* * Free storage associated with a screen structure. * NOTE endwin() does not do this. */ void delscreen(SCREEN *sp) { if (sp != NULL) { if (sp->_slk._w != NULL) (void) delwin(sp->_slk._w); (void) delwin(sp->_newscr); (void) delwin(sp->_curscr); (void) del_curterm(sp->_term); __m_decode_free((t_decode **) &sp->_decode); if (sp->_hash != NULL) free(sp->_hash); if (sp->_unget._stack != NULL) free(sp->_unget._stack); if (sp->_in != NULL) free(sp->_in); free(sp); } }
/* ARGSUSED */ int tgetent(__unused char *bp, const char *name) { int errret; static TERMINAL *last = NULL; _DIAGASSERT(name != NULL); /* Free the old term */ if (cur_term != NULL) { if (last != NULL && cur_term != last) del_curterm(last); last = cur_term; } errret = -1; if (setupterm(name, STDOUT_FILENO, &errret) != 0) return errret; if (last == NULL) last = cur_term; if (pad_char != NULL) PC = pad_char[0]; UP = __UNCONST(cursor_up); BC = __UNCONST(cursor_left); return 1; }
_nc_tgetent_leaks(void) { for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx) { FreeIfNeeded(FIX_SGR0); if (LAST_TRM != 0) del_curterm(LAST_TRM); } }
static void cleanup(MYDATA * data) { set_curterm(data->term); del_curterm(data->term); #if !NO_LEAKS free(data->sp); /* cannot use delscreen in tinfo */ #endif free(data); }
/** Free memory used by various subsystems. */ static void destroy() { env_universal_destroy(); input_common_destroy(); wutil_destroy(); if( del_curterm( cur_term ) == ERR ) { debug( 0, _(L"Error while closing terminfo") ); } fclose( out_file ); }
_nc_leaks_tinfo(void) { #if NO_LEAKS char *s; #endif T((T_CALLED("_nc_free_tinfo()"))); #if NO_LEAKS _nc_globals.leak_checking = TRUE; _nc_free_tparm(); _nc_tgetent_leaks(); if (TerminalOf(CURRENT_SCREEN) != 0) { del_curterm(TerminalOf(CURRENT_SCREEN)); } _nc_forget_prescr(); _nc_comp_captab_leaks(); _nc_free_entries(_nc_head); _nc_get_type(0); _nc_first_name(0); _nc_db_iterator_leaks(); _nc_keyname_leaks(); #if BROKEN_LINKER || USE_REENTRANT _nc_names_leaks(); _nc_codes_leaks(); FreeIfNeeded(_nc_prescreen.real_acs_map); #endif _nc_comp_error_leaks(); if ((s = _nc_home_terminfo()) != 0) free(s); #ifdef TRACE T((T_RETURN(""))); trace(0); _nc_trace_buf(-1, (size_t) 0); #endif #endif /* NO_LEAKS */ returnVoid; }
void input_destroy() { if( !is_init ) return; is_init=0; al_foreach( &mappings, &free ); al_destroy( &mappings ); input_common_destroy(); if( del_curterm( cur_term ) == ERR ) { debug( 0, _(L"Error while closing terminfo") ); } input_terminfo_destroy(); }
static void term_init(int fd, const char *sa[5]) { TERMINAL *ti; int error; const char *bold, *sgr0, *smso, *rmso, *smul, *rmul; if (ti_setupterm(&ti, NULL, fd, &error) == -1) { bold = sgr0 = NULL; smso = rmso = smul = rmul = ""; ti = NULL; } else { bold = ti_getstr(ti, "bold"); sgr0 = ti_getstr(ti, "sgr0"); if (bold == NULL || sgr0 == NULL) { smso = ti_getstr(ti, "smso"); if (smso == NULL || (rmso = ti_getstr(ti, "rmso")) == NULL) smso = rmso = ""; bold = sgr0 = NULL; } else smso = rmso = ""; smul = ti_getstr(ti, "smul"); if (smul == NULL || (rmul = ti_getstr(ti, "rmul")) == NULL) smul = rmul = ""; } sa[0] = term_fix_seq(ti, bold ? bold : smso); sa[1] = term_fix_seq(ti, sgr0 ? sgr0 : rmso); sa[2] = estrdup("..."); sa[3] = term_fix_seq(ti, smul); sa[4] = term_fix_seq(ti, rmul); if (ti) del_curterm(ti); }
static void finish(const char *psz_msg, int rc) { if (b_interactive) { attron(A_STANDOUT); mvprintw(LINE_ACTION, 0, (char *) "%s, exiting...\n", psz_msg); attroff(A_STANDOUT); clrtoeol(); refresh(); } tty_restore(); if (cur_term) del_curterm(cur_term); cur_window = NULL; #ifdef HAVE_CDDB if (p_conn) cddb_destroy(p_conn); cddb_disc_destroy(p_cddb_disc); libcddb_shutdown(); #endif /*HAVE_CDDB*/ cdio_destroy (p_cdio_global); free (psz_device_global); exit (rc); }
int intern initbios( void ) { PossibleDisplay *curr; if( UIConFile == NULL ) { char *tty; tty = getenv( "TTY" ); if( tty == NULL ) { tty = "/dev/tty"; } UIConFile = fopen( tty, "w+" ); if( UIConFile == NULL ) return( FALSE ); UIConHandle = fileno( UIConFile ); fcntl( UIConHandle, F_SETFD, 1 ); } setupterm( GetTermType(), UIConHandle, (int *)0); /* will report an error message and exit if any problem with a terminfo */ // Check to make sure terminal is suitable if( cursor_address == NULL || hard_copy ) { del_curterm( cur_term ); return( FALSE ); } curr = DisplayList; for( ;; ) { if( curr->check == NULL ) return( FALSE ); if( curr->check() ) break; ++curr; } UIVirt = curr->virt; return( _uibiosinit() ); }
tgetent(char *bufp, const char *name) { int errcode; int n; bool found_cache = FALSE; START_TRACE(); T((T_CALLED("tgetent()"))); _nc_setupterm((NCURSES_CONST char *) name, STDOUT_FILENO, &errcode, TRUE); /* * In general we cannot tell if the fixed sgr0 is still used by the * caller, but if tgetent() is called with the same buffer, that is * good enough, since the previous data would be invalidated by the * current call. * * bufp may be a null pointer, e.g., GNU termcap. That allocates data, * which is good until the next tgetent() call. The conventional termcap * is inconvenient because of the fixed buffer size, but because it uses * caller-supplied buffers, can have multiple terminal descriptions in * use at a given time. */ for (n = 0; n < TGETENT_MAX; ++n) { bool same_result = (MyCache[n].last_used && MyCache[n].last_bufp == bufp); if (same_result) { CacheInx = n; if (FIX_SGR0 != 0) { FreeAndNull(FIX_SGR0); } /* * Also free the terminfo data that we loaded (much bigger leak). */ if (LAST_TRM != 0 && LAST_TRM != cur_term) { TERMINAL *trm = LAST_TRM; del_curterm(LAST_TRM); for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx) if (LAST_TRM == trm) LAST_TRM = 0; CacheInx = n; } found_cache = TRUE; break; } } if (!found_cache) { int best = 0; for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx) { if (LAST_SEQ < MyCache[best].sequence) { best = CacheInx; } } CacheInx = best; } LAST_TRM = cur_term; LAST_SEQ = ++CacheSeq; PC = 0; UP = 0; BC = 0; FIX_SGR0 = 0; /* don't free it - application may still use */ if (errcode == 1) { if (cursor_left) if ((backspaces_with_bs = (char) !strcmp(cursor_left, "\b")) == 0) backspace_if_not_bs = cursor_left; /* we're required to export these */ if (pad_char != NULL) PC = pad_char[0]; if (cursor_up != NULL) UP = cursor_up; if (backspace_if_not_bs != NULL) BC = backspace_if_not_bs; if ((FIX_SGR0 = _nc_trim_sgr0(&(cur_term->type))) != 0) { if (!strcmp(FIX_SGR0, exit_attribute_mode)) { if (FIX_SGR0 != exit_attribute_mode) { free(FIX_SGR0); } FIX_SGR0 = 0; } } LAST_BUF = bufp; LAST_USE = TRUE; SetNoPadding(SP); (void) baudrate(); /* sets ospeed as a side-effect */ /* LINT_PREPRO #if 0*/ #include <capdefaults.c> /* LINT_PREPRO #endif*/ } returnCode(errcode); }
static void rt_free(void *ptr) { if(ptr != NULL) del_curterm(ptr); }
/* * cl_ex_init -- * Initialize the ex screen. */ static int cl_ex_init(SCR *sp) { CL_PRIVATE *clp; int error; const char *ttype; clp = CLP(sp); /* If already initialized, just set the terminal modes. */ if (F_ISSET(clp, CL_SCR_EX_INIT)) goto fast; /* If not reading from a file, we're done. */ if (!F_ISSET(clp, CL_STDIN_TTY)) return (0); if (F_ISSET(clp, CL_CHANGE_TERM)) { if (F_ISSET(clp, CL_SETUPTERM) && del_curterm(cur_term)) return (1); F_CLR(clp, CL_SETUPTERM | CL_CHANGE_TERM); } if (!F_ISSET(clp, CL_SETUPTERM)) { /* We'll need a terminal type. */ if (opts_empty(sp, O_TERM, 0)) return (1); ttype = O_STR(sp, O_TERM); (void)setupterm(ttype, STDOUT_FILENO, &error); if (error == 0 || error == -1) return (1); } /* Get the ex termcap/terminfo strings. */ (void)cl_getcap(sp, "cup", &clp->cup); (void)cl_getcap(sp, "smso", &clp->smso); (void)cl_getcap(sp, "rmso", &clp->rmso); (void)cl_getcap(sp, "el", &clp->el); (void)cl_getcap(sp, "cuu1", &clp->cuu1); /* Enter_standout_mode and exit_standout_mode are paired. */ if (clp->smso == NULL || clp->rmso == NULL) { if (clp->smso != NULL) { free(clp->smso); clp->smso = NULL; } if (clp->rmso != NULL) { free(clp->rmso); clp->rmso = NULL; } } /* * Turn on canonical mode, with normal input and output processing. * Start with the original terminal settings as the user probably * had them (including any local extensions) set correctly for the * current terminal. * * !!! * We can't get everything that we need portably; for example, ONLCR, * mapping <newline> to <carriage-return> on output isn't required * by POSIX 1003.1b-1993. If this turns out to be a problem, then * we'll either have to play some games on the mapping, or we'll have * to make all ex printf's output \r\n instead of \n. */ clp->ex_enter = clp->orig; clp->ex_enter.c_lflag |= ECHO | ECHOE | ECHOK | ICANON | IEXTEN | ISIG; #ifdef ECHOCTL clp->ex_enter.c_lflag |= ECHOCTL; #endif #ifdef ECHOKE clp->ex_enter.c_lflag |= ECHOKE; #endif clp->ex_enter.c_iflag |= ICRNL; clp->ex_enter.c_oflag |= OPOST; #ifdef ONLCR clp->ex_enter.c_oflag |= ONLCR; #endif fast: if (tcsetattr(STDIN_FILENO, TCSADRAIN | TCSASOFT, &clp->ex_enter)) { if (errno == EINTR) goto fast; msgq(sp, M_SYSERR, "tcsetattr"); return (1); } return (0); }
void intern finibios( void ) { _uibiosfini(); del_curterm( cur_term ); }
int main( int argc, char **argv ) { char *bgcolor=0; char *fgcolor=0; bool bold=false; bool underline=false; while( 1 ) { static struct option long_options[] = { { "background", required_argument, 0, 'b' } , { "help", no_argument, 0, 'h' } , { "bold", no_argument, 0, 'o' } , { "underline", no_argument, 0, 'u' } , { "version", no_argument, 0, 'v' } , { "print-colors", no_argument, 0, 'c' } , { 0, 0, 0, 0 } } ; int opt_index = 0; int opt = getopt_long( argc, argv, GETOPT_STRING, long_options, &opt_index ); if( opt == -1 ) break; switch( opt ) { case 0: break; case 'b': bgcolor = optarg; break; case 'h': print_help( argv[0], 1 ); exit(0); case 'o': bold=true; break; case 'u': underline=true; break; case 'v': check_locale_init(); fprintf( stderr, _("%s, version %s\n"), SET_COLOR, PACKAGE_VERSION ); exit( 0 ); case 'c': print_colors(); exit(0); case '?': return 1; } } switch( argc-optind) { case 0: // printf( "no fg\n" ); break; case 1: fgcolor=argv[optind]; // printf( "fg %s\n", fgcolor ); break; default: check_locale_init(); printf( _("%s: Too many arguments\n"), SET_COLOR ); return 1; } /* Infer term256 support */ char *fish_term256 = getenv("fish_term256"); if (fish_term256) { support_term256 = from_string<bool>(fish_term256); } else { const char *term = getenv("TERM"); support_term256 = term && strstr(term, "256color"); } if( !fgcolor && !bgcolor && !bold && !underline ) { check_locale_init(); fprintf( stderr, _("%s: Expected an argument\n"), SET_COLOR ); print_help( argv[0], 2 ); return 1; } rgb_color_t fg = rgb_color_t(fgcolor ? fgcolor : ""); if( fgcolor && fg.is_none()) { check_locale_init(); fprintf( stderr, _("%s: Unknown color '%s'\n"), SET_COLOR, fgcolor ); return 1; } rgb_color_t bg = rgb_color_t(bgcolor ? bgcolor : ""); if( bgcolor && bg.is_none()) { check_locale_init(); fprintf( stderr, _("%s: Unknown color '%s'\n"), SET_COLOR, bgcolor ); return 1; } setupterm( 0, STDOUT_FILENO, 0); if( bold ) { if( enter_bold_mode ) putp( enter_bold_mode ); } if( underline ) { if( enter_underline_mode ) putp( enter_underline_mode ); } if( bgcolor ) { if( bg.is_normal() ) { write_background_color(0); putp( tparm(exit_attribute_mode) ); } } if( fgcolor ) { if( fg.is_normal() ) { write_foreground_color(0); putp( tparm(exit_attribute_mode) ); } else { write_foreground_color(index_for_color(fg)); } } if( bgcolor ) { if( ! bg.is_normal() ) { write_background_color(index_for_color(bg)); } } if( del_curterm( cur_term ) == ERR ) { fprintf( stderr, "%s", _("Error while closing terminfo") ); } }
delscreen(SCREEN *sp) { SCREEN **scan = &_nc_screen_chain; int i; T((T_CALLED("delscreen(%p)"), sp)); while (*scan) { if (*scan == sp) { *scan = sp->_next_screen; break; } scan = &(*scan)->_next_screen; } (void) _nc_freewin(sp->_curscr); (void) _nc_freewin(sp->_newscr); (void) _nc_freewin(sp->_stdscr); if (sp->_slk != 0) { if (sp->_slk->ent != 0) { for (i = 0; i < sp->_slk->labcnt; ++i) { FreeIfNeeded(sp->_slk->ent[i].ent_text); FreeIfNeeded(sp->_slk->ent[i].form_text); } free(sp->_slk->ent); } free(sp->_slk); sp->_slk = 0; } _nc_free_keytry(sp->_keytry); sp->_keytry = 0; _nc_free_keytry(sp->_key_ok); sp->_key_ok = 0; FreeIfNeeded(sp->_current_attr); FreeIfNeeded(sp->_color_table); FreeIfNeeded(sp->_color_pairs); FreeIfNeeded(sp->oldhash); FreeIfNeeded(sp->newhash); FreeIfNeeded(sp->hashtab); del_curterm(sp->_term); /* * If the associated output stream has been closed, we can discard the * set-buffer. Limit the error check to EBADF, since fflush may fail * for other reasons than trying to operate upon a closed stream. */ if (sp->_ofp != 0 && sp->_setbuf != 0 && fflush(sp->_ofp) != 0 && errno == EBADF) { free(sp->_setbuf); } free(sp); /* * If this was the current screen, reset everything that the * application might try to use (except cur_term, which may have * multiple references in different screens). */ if (sp == SP) { curscr = 0; newscr = 0; stdscr = 0; COLORS = 0; COLOR_PAIRS = 0; _nc_set_screen(0); } returnVoid; }
_nc_freeall(void) { WINDOWLIST *p, *q; char *s; T((T_CALLED("_nc_freeall()"))); #if NO_LEAKS _nc_free_tparm(); if (_nc_oldnums != 0) { FreeAndNull(_nc_oldnums); } #endif if (SP != 0) { while (_nc_windows != 0) { /* Delete only windows that're not a parent */ for (p = _nc_windows; p != 0; p = p->next) { bool found = FALSE; for (q = _nc_windows; q != 0; q = q->next) { if ((p != q) && (q->win._flags & _SUBWIN) && (&(p->win) == q->win._parent)) { found = TRUE; break; } } if (!found) { delwin(&(p->win)); break; } } } delscreen(SP); } del_curterm(cur_term); _nc_free_entries(_nc_head); _nc_get_type(0); _nc_first_name(0); #if USE_WIDEC_SUPPORT FreeIfNeeded(_nc_wacs); #endif #if NO_LEAKS _nc_alloc_entry_leaks(); _nc_captoinfo_leaks(); _nc_comp_scan_leaks(); #endif if ((s = _nc_home_terminfo()) != 0) free(s); (void) _nc_printf_string(0, 0); #ifdef TRACE (void) _nc_trace_buf(-1, 0); #endif #if HAVE_LIBDBMALLOC malloc_dump(malloc_errfd); #elif HAVE_LIBDMALLOC #elif HAVE_LIBMPATROL __mp_summary(); #elif HAVE_PURIFY purify_all_inuse(); #endif returnVoid; }
/* * cl_vi_init -- * Initialize the curses vi screen. */ static int cl_vi_init(SCR *sp) { CL_PRIVATE *clp; char *o_cols, *o_lines, *o_term; const char *ttype; clp = CLP(sp); /* If already initialized, just set the terminal modes. */ if (F_ISSET(clp, CL_SCR_VI_INIT)) goto fast; /* Curses vi always reads from (and writes to) a terminal. */ if (!F_ISSET(clp, CL_STDIN_TTY) || !isatty(STDOUT_FILENO)) { msgq(sp, M_ERR, "016|Vi's standard input and output must be a terminal"); return (1); } /* We'll need a terminal type. */ if (opts_empty(sp, O_TERM, 0)) return (1); ttype = O_STR(sp, O_TERM); /* * XXX * Changing the row/column and terminal values is done by putting them * into the environment, which is then read by curses. What this loses * in ugliness, it makes up for in stupidity. We can't simply put the * values into the environment ourselves, because in the presence of a * kernel mechanism for returning the window size, entering values into * the environment will screw up future screen resizing events, e.g. if * the user enters a :shell command and then resizes their window. So, * if they weren't already in the environment, we make sure to delete * them immediately after setting them. * * XXX * Putting the TERM variable into the environment is necessary, even * though we're using newterm() here. We may be using initscr() as * the underlying function. */ o_term = getenv("TERM"); cl_putenv(sp, "TERM", ttype, 0); o_lines = getenv("LINES"); cl_putenv(sp, "LINES", NULL, (u_long)O_VAL(sp, O_LINES)); o_cols = getenv("COLUMNS"); cl_putenv(sp, "COLUMNS", NULL, (u_long)O_VAL(sp, O_COLUMNS)); /* Delete cur_term if exists. */ if (F_ISSET(clp, CL_SETUPTERM)) { if (del_curterm(cur_term)) return (1); F_CLR(clp, CL_SETUPTERM); } /* * XXX * The SunOS initscr() can't be called twice. Don't even think about * using it. It fails in subtle ways (e.g. select(2) on fileno(stdin) * stops working). (The SVID notes that applications should only call * initscr() once.) * * XXX * The HP/UX newterm doesn't support the NULL first argument, so we * have to specify the terminal type. */ errno = 0; if ((clp->screen = newterm(__UNCONST(ttype), stdout, stdin)) == NULL) { if (errno) msgq(sp, M_SYSERR, "%s", ttype); else msgq(sp, M_ERR, "%s: unknown terminal type", ttype); return (1); } if (o_term == NULL) cl_unsetenv(sp, "TERM"); if (o_lines == NULL) cl_unsetenv(sp, "LINES"); if (o_cols == NULL) cl_unsetenv(sp, "COLUMNS"); /* * XXX * Someone got let out alone without adult supervision -- the SunOS * newterm resets the signal handlers. There's a race, but it's not * worth closing. */ (void)sig_init(sp->gp, sp); /* * We use raw mode. What we want is 8-bit clean, however, signals * and flow control should continue to work. Admittedly, it sounds * like cbreak, but it isn't. Using cbreak() can get you additional * things like IEXTEN, which turns on flags like DISCARD and LNEXT. * * !!! * If raw isn't turning off echo and newlines, something's wrong. * However, it shouldn't hurt. */ noecho(); /* No character echo. */ nonl(); /* No CR/NL translation. */ raw(); /* 8-bit clean. */ idlok(stdscr, 1); /* Use hardware insert/delete line. */ /* Put the cursor keys into application mode. */ (void)keypad(stdscr, TRUE); /* * XXX * The screen TI sequence just got sent. See the comment in * cl_funcs.c:cl_attr(). */ clp->ti_te = TI_SENT; /* * XXX * Historic implementations of curses handled SIGTSTP signals * in one of three ways. They either: * * 1: Set their own handler, regardless. * 2: Did not set a handler if a handler was already installed. * 3: Set their own handler, but then called any previously set * handler after completing their own cleanup. * * We don't try and figure out which behavior is in place, we force * it to SIG_DFL after initializing the curses interface, which means * that curses isn't going to take the signal. Since curses isn't * reentrant (i.e., the whole curses SIGTSTP interface is a fantasy), * we're doing The Right Thing. */ (void)signal(SIGTSTP, SIG_DFL); /* * If flow control was on, turn it back on. Turn signals on. ISIG * turns on VINTR, VQUIT, VDSUSP and VSUSP. The main curses code * already installed a handler for VINTR. We're going to disable the * other three. * * XXX * We want to use ^Y as a vi scrolling command. If the user has the * DSUSP character set to ^Y (common practice) clean it up. As it's * equally possible that the user has VDSUSP set to 'a', we disable * it regardless. It doesn't make much sense to suspend vi at read, * so I don't think anyone will care. Alternatively, we could look * it up in the table of legal command characters and turn it off if * it matches one. VDSUSP wasn't in POSIX 1003.1-1990, so we test for * it. * * XXX * We don't check to see if the user had signals enabled originally. * If they didn't, it's unclear what we're supposed to do here, but * it's also pretty unlikely. */ if (tcgetattr(STDIN_FILENO, &clp->vi_enter)) { msgq(sp, M_SYSERR, "tcgetattr"); goto err; } if (clp->orig.c_iflag & IXON) clp->vi_enter.c_iflag |= IXON; if (clp->orig.c_iflag & IXOFF) clp->vi_enter.c_iflag |= IXOFF; clp->vi_enter.c_lflag |= ISIG; #ifdef VDSUSP clp->vi_enter.c_cc[VDSUSP] = _POSIX_VDISABLE; #endif clp->vi_enter.c_cc[VQUIT] = _POSIX_VDISABLE; clp->vi_enter.c_cc[VSUSP] = _POSIX_VDISABLE; /* * XXX * OSF/1 doesn't turn off the <discard>, <literal-next> or <status> * characters when curses switches into raw mode. It should be OK * to do it explicitly for everyone. */ #ifdef VDISCARD clp->vi_enter.c_cc[VDISCARD] = _POSIX_VDISABLE; #endif #ifdef VLNEXT clp->vi_enter.c_cc[VLNEXT] = _POSIX_VDISABLE; #endif #ifdef VSTATUS clp->vi_enter.c_cc[VSTATUS] = _POSIX_VDISABLE; #endif /* Initialize terminal based information. */ if (cl_term_init(sp)) goto err; fast: /* Set the terminal modes. */ if (tcsetattr(STDIN_FILENO, TCSASOFT | TCSADRAIN, &clp->vi_enter)) { msgq(sp, M_SYSERR, "tcsetattr"); err: (void)cl_vi_end(sp->gp); return (1); } return (0); }