/****************************************************************************
- * Copyright (c) 1998-2013,2014 Free Software Foundation, Inc. *
+ * Copyright 2018-2021,2022 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
#include <curses.priv.h>
#include <tic.h>
-#ifndef CUR
-#define CUR SP_TERMTYPE
+#if USE_GPM_SUPPORT
+#ifdef HAVE_LIBDL
+/* use dynamic loader to avoid linkage dependency */
+#include <dlfcn.h>
+#endif
#endif
-MODULE_ID("$Id: lib_set_term.c,v 1.149 2014/03/08 20:32:59 tom Exp $")
+#undef CUR
+#define CUR SP_TERMTYPE
+
+MODULE_ID("$Id: lib_set_term.c,v 1.181 2022/07/21 23:35:21 tom Exp $")
#ifdef USE_TERM_DRIVER
#define MaxColors InfoOf(sp).maxcolors
NCURSES_EXPORT(void)
delscreen(SCREEN *sp)
{
- int i;
T((T_CALLED("delscreen(%p)"), (void *) sp));
_nc_lock_global(curses);
if (delink_screen(sp)) {
+ bool is_current = (sp == CURRENT_SCREEN);
+
#ifdef USE_SP_RIPOFF
- ripoff_t *rop;
if (safe_ripoff_sp && safe_ripoff_sp != safe_ripoff_stack) {
+ ripoff_t *rop;
for (rop = safe_ripoff_stack;
rop != safe_ripoff_sp && (rop - safe_ripoff_stack) < N_RIPS;
rop++) {
(void) _nc_freewin(StdScreen(sp));
if (sp->_slk != 0) {
+
if (sp->_slk->ent != 0) {
+ int i;
+
for (i = 0; i < sp->_slk->labcnt; ++i) {
FreeIfNeeded(sp->_slk->ent[i].ent_text);
FreeIfNeeded(sp->_slk->ent[i].form_text);
FreeIfNeeded(sp->_color_table);
FreeIfNeeded(sp->_color_pairs);
+ FreeIfNeeded(sp->_oldnum_list);
FreeIfNeeded(sp->oldhash);
FreeIfNeeded(sp->newhash);
FreeIfNeeded(sp->hashtab);
NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_ARG);
NCURSES_SP_NAME(del_curterm) (NCURSES_SP_ARGx sp->_term);
+ FreeIfNeeded(sp->out_buffer);
+ if (_nc_find_prescr() == sp) {
+ _nc_forget_prescr();
+ }
+#if USE_GPM_SUPPORT
+#ifdef HAVE_LIBDL
+ if (sp->_dlopen_gpm != 0) {
+ dlclose(sp->_dlopen_gpm);
+ sp->_dlopen_gpm = 0;
+ }
+#endif
+#endif /* USE_GPM_SUPPORT */
free(sp);
/*
* application might try to use (except cur_term, which may have
* multiple references in different screens).
*/
- if (sp == CURRENT_SCREEN) {
+ if (is_current) {
#if !USE_REENTRANT
curscr = 0;
newscr = 0;
COLOR_PAIRS = 0;
#endif
_nc_set_screen(0);
+#if USE_WIDEC_SUPPORT
+ if (SP == 0) {
+ FreeIfNeeded(_nc_wacs);
+ _nc_wacs = 0;
+ }
+#endif
+ } else {
+ set_term(CURRENT_SCREEN);
}
}
_nc_unlock_global(curses);
}
#if NCURSES_EXT_FUNCS && USE_COLORFGBG
-static char *
-extract_fgbg(char *src, int *result)
+static const char *
+extract_fgbg(const char *src, int *result)
{
- char *dst = 0;
- long value = strtol(src, &dst, 0);
+ const char *dst = 0;
+ char *tmp = 0;
+ long value = strtol(src, &tmp, 0);
- if (dst == 0) {
+ if ((dst = tmp) == 0) {
dst = src;
} else if (value >= 0) {
- *result = value;
+ *result = (int) value;
}
while (*dst != 0 && *dst != ';')
dst++;
}
#endif
-#define ReturnScreenError() { _nc_set_screen(0); \
+#define ReturnScreenError() do { _nc_set_screen(0); \
returnCode(ERR); } while (0)
/* OS-independent screen initializations */
int filtered,
int slk_format)
{
+#ifndef USE_TERM_DRIVER
+ static const TTY null_TTY; /* all zeros iff uninitialized */
+#endif
char *env;
int bottom_stolen = 0;
- ripoff_t *rop;
SCREEN *sp;
#ifndef USE_TERM_DRIVER
bool support_cookies = USE_XMC_SUPPORT;
if (!sp) {
sp = _nc_alloc_screen_sp();
+ T(("_nc_alloc_screen_sp %p", (void *) sp));
*spp = sp;
}
- if (!sp
- || ((sp->_acs_map = typeCalloc(chtype, ACS_LEN)) == 0)
- || ((sp->_screen_acs_map = typeCalloc(bool, ACS_LEN)) == 0)) {
+ if (sp == NULL) {
+ ReturnScreenError();
+ }
+ if ((sp->_acs_map = typeCalloc(chtype, ACS_LEN)) == NULL) {
+ ReturnScreenError();
+ }
+ if ((sp->_screen_acs_map = typeCalloc(bool, ACS_LEN)) == NULL) {
+ free(sp->_acs_map);
ReturnScreenError();
}
sp->_next_screen = _nc_screen_chain;
_nc_screen_chain = sp;
- if ((sp->_current_attr = typeCalloc(NCURSES_CH_T, 1)) == 0)
+ if ((sp->_current_attr = typeCalloc(NCURSES_CH_T, 1)) == 0) {
returnCode(ERR);
+ }
#endif
/*
#ifdef USE_TERM_DRIVER
CallDriver(sp, td_setfilter);
#else
- clear_screen = 0;
- cursor_down = parm_down_cursor = 0;
- cursor_address = 0;
- cursor_up = parm_up_cursor = 0;
- row_address = 0;
+ /* *INDENT-EQLS* */
+ clear_screen = ABSENT_STRING;
+ cursor_address = ABSENT_STRING;
+ cursor_down = ABSENT_STRING;
+ cursor_up = ABSENT_STRING;
+ parm_down_cursor = ABSENT_STRING;
+ parm_up_cursor = ABSENT_STRING;
+ row_address = ABSENT_STRING;
+ cursor_home = carriage_return;
+
+ if (back_color_erase)
+ clr_eos = ABSENT_STRING;
- cursor_home = carriage_return;
#endif
T(("filter screensize %dx%d", slines, scolumns));
}
fflush(output);
setmode(output, O_BINARY);
#endif
- NCURSES_SP_NAME(_nc_set_buffer) (NCURSES_SP_ARGx output, TRUE);
+#if defined(EXP_WIN32_DRIVER)
+ T(("setting output mode to binary"));
+ fflush(output);
+ _setmode(fileno(output), _O_BINARY);
+#endif
sp->_lines = (NCURSES_SIZE_T) slines;
sp->_lines_avail = (NCURSES_SIZE_T) slines;
sp->_columns = (NCURSES_SIZE_T) scolumns;
fflush(output);
sp->_ofd = output ? fileno(output) : -1;
sp->_ofp = output;
+#if defined(EXP_WIN32_DRIVER)
+ if (output)
+ _setmode(fileno(output), _O_BINARY);
+#endif
sp->out_limit = (size_t) ((2 + slines) * (6 + scolumns));
if ((sp->out_buffer = malloc(sp->out_limit)) == 0)
sp->out_limit = 0;
sp->_default_fg = COLOR_WHITE;
sp->_default_bg = COLOR_BLACK;
#else
- sp->_default_fg = C_MASK;
- sp->_default_bg = C_MASK;
+ sp->_default_fg = COLOR_DEFAULT;
+ sp->_default_bg = COLOR_DEFAULT;
#endif
/*
char sep1, sep2;
int count = sscanf(env, "%d%c%d%c", &fg, &sep1, &bg, &sep2);
if (count >= 1) {
- sp->_default_fg = ((fg >= 0 && fg < MaxColors) ? fg : C_MASK);
+ sp->_default_fg = ((fg >= 0 && fg < MaxColors) ? fg : COLOR_DEFAULT);
if (count >= 3) {
- sp->_default_bg = ((bg >= 0 && bg < MaxColors) ? bg : C_MASK);
+ sp->_default_bg = ((bg >= 0 && bg < MaxColors) ? bg : COLOR_DEFAULT);
}
TR(TRACE_CHARPUT | TRACE_MOVE,
("from environment assumed fg=%d, bg=%d",
* decide later if it is worth having default attributes as well.
*/
if (getenv("COLORFGBG") != 0) {
- char *p = getenv("COLORFGBG");
+ const char *p = getenv("COLORFGBG");
TR(TRACE_CHARPUT | TRACE_MOVE, ("decoding COLORFGBG %s", p));
p = extract_fgbg(p, &(sp->_default_fg));
p = extract_fgbg(p, &(sp->_default_bg));
if (*p) /* assume rxvt was compiled with xpm support */
- p = extract_fgbg(p, &(sp->_default_bg));
+ extract_fgbg(p, &(sp->_default_bg));
TR(TRACE_CHARPUT | TRACE_MOVE, ("decoded fg=%d, bg=%d",
sp->_default_fg, sp->_default_bg));
if (sp->_default_fg >= MaxColors) {
if (set_a_foreground != ABSENT_STRING
&& !strcmp(set_a_foreground, "\033[3%p1%dm")) {
- set_a_foreground = "\033[3%?%p1%{8}%>%t9%e%p1%d%;m";
+ set_a_foreground = strdup("\033[3%?%p1%{8}%>%t9%e%p1%d%;m");
} else {
sp->_default_fg %= MaxColors;
}
if (sp->_default_bg >= MaxColors) {
if (set_a_background != ABSENT_STRING
&& !strcmp(set_a_background, "\033[4%p1%dm")) {
- set_a_background = "\033[4%?%p1%{8}%>%t9%e%p1%d%;m";
+ set_a_background = strdup("\033[4%?%p1%{8}%>%t9%e%p1%d%;m");
} else {
sp->_default_bg %= MaxColors;
}
NCURSES_SP_NAME(_nc_init_acs) (NCURSES_SP_ARG);
#if USE_WIDEC_SUPPORT
sp->_screen_unicode = _nc_unicode_locale();
- _nc_init_wacs();
+ if (_nc_wacs == 0) {
+ _nc_init_wacs();
+ }
if (_nc_wacs == 0) {
ReturnScreenError();
}
NewScreen(sp)->_clear = TRUE;
CurScreen(sp)->_clear = FALSE;
- NCURSES_SP_NAME(def_shell_mode) (NCURSES_SP_ARG);
- NCURSES_SP_NAME(def_prog_mode) (NCURSES_SP_ARG);
+ /*
+ * Get the current tty-modes. setupterm() may already have done this,
+ * unless we use the term-driver.
+ */
+#ifndef USE_TERM_DRIVER
+ if (cur_term != 0 &&
+ !memcmp(&cur_term->Ottyb, &null_TTY, sizeof(TTY)))
+#endif
+ {
+ NCURSES_SP_NAME(def_shell_mode) (NCURSES_SP_ARG);
+ NCURSES_SP_NAME(def_prog_mode) (NCURSES_SP_ARG);
+ }
if (safe_ripoff_sp && safe_ripoff_sp != safe_ripoff_stack) {
+ ripoff_t *rop;
+
for (rop = safe_ripoff_stack;
rop != safe_ripoff_sp && (rop - safe_ripoff_stack) < N_RIPS;
rop++) {
formats (4-4 or 3-2-3) for which there may be some hardware
support. */
if (rop->hook == _nc_slk_initialize) {
+ if (!TerminalOf(sp)) {
+ continue;
+ }
if (!(NumLabels <= 0 || !SLK_STDFMT(slk_format))) {
continue;
}
int (*init) (WINDOW *, int))
{
int code = ERR;
+ TR_FUNC_BFR(1);
START_TRACE();
- T((T_CALLED("ripoffline(%p,%d,%p)"), (void *) SP_PARM, line, init));
+ T((T_CALLED("ripoffline(%p,%d,%s)"),
+ (void *) SP_PARM, line,
+ TR_FUNC_ARG(0, init)));
#if NCURSES_SP_FUNCS
if (SP_PARM != 0 && SP_PARM->_prescreen)
if (line == 0) {
code = OK;
} else {
- if (safe_ripoff_sp == 0)
+ if (safe_ripoff_sp == 0) {
safe_ripoff_sp = safe_ripoff_stack;
+ }
if (safe_ripoff_sp < safe_ripoff_stack + N_RIPS) {
safe_ripoff_sp->line = line;
safe_ripoff_sp->hook = init;
(safe_ripoff_sp)++;
+ T(("ripped-off %d:%d chunks",
+ (int) (safe_ripoff_sp - safe_ripoff_stack), N_RIPS));
code = OK;
}
}
NCURSES_EXPORT(int)
_nc_ripoffline(int line, int (*init) (WINDOW *, int))
{
- return NCURSES_SP_NAME(_nc_ripoffline) (CURRENT_SCREEN_PRE, line, init);
+ int rc;
+
+ _nc_init_pthreads();
+ _nc_lock_global(prescreen);
+ START_TRACE();
+ rc = NCURSES_SP_NAME(_nc_ripoffline) (CURRENT_SCREEN_PRE, line, init);
+ _nc_unlock_global(prescreen);
+
+ return rc;
}
#endif
NCURSES_EXPORT(int)
ripoffline(int line, int (*init) (WINDOW *, int))
{
- return NCURSES_SP_NAME(ripoffline) (CURRENT_SCREEN_PRE, line, init);
+ int rc;
+
+ _nc_init_pthreads();
+ _nc_lock_global(prescreen);
+ START_TRACE();
+ rc = NCURSES_SP_NAME(ripoffline) (CURRENT_SCREEN_PRE, line, init);
+ _nc_unlock_global(prescreen);
+
+ return rc;
}
#endif