NCURSES_SP_NAME(set_curterm) (NCURSES_SP_DCLx TERMINAL * termp) { TERMINAL *oldterm; T((T_CALLED("set_curterm(%p)"), (void *) termp)); _nc_lock_global(curses); oldterm = cur_term; if (SP_PARM) SP_PARM->_term = termp; #if USE_REENTRANT CurTerm = termp; #else cur_term = termp; #endif if (termp != 0) { #ifdef USE_TERM_DRIVER TERMINAL_CONTROL_BLOCK *TCB = (TERMINAL_CONTROL_BLOCK *) termp; ospeed = (NCURSES_OSPEED) _nc_ospeed(termp->_baudrate); if (TCB->drv->isTerminfo && termp->type.Strings) { PC = (char) ((pad_char != NULL) ? pad_char[0] : 0); } TCB->csp = SP_PARM; #else ospeed = (NCURSES_OSPEED) _nc_ospeed(termp->_baudrate); if (termp->type.Strings) { PC = (char) ((pad_char != NULL) ? pad_char[0] : 0); } #endif } _nc_unlock_global(curses); T((T_RETURN("%p"), (void *) oldterm)); return (oldterm); }
/* * If we have reallocated the ldat structs, we will have to repair pointers * used in subwindows. */ static void repair_subwindows(WINDOW *cmp) { WINDOWLIST *wp; struct ldat *pline = cmp->_line; int row; _nc_lock_global(curses); for (each_window(wp)) { WINDOW *tst = &(wp->win); if (tst->_parent == cmp) { if (tst->_pary > cmp->_maxy) tst->_pary = cmp->_maxy; if (tst->_parx > cmp->_maxx) tst->_parx = cmp->_maxx; if (tst->_maxy + tst->_pary > cmp->_maxy) tst->_maxy = cmp->_maxy - tst->_pary; if (tst->_maxx + tst->_parx > cmp->_maxx) tst->_maxx = cmp->_maxx - tst->_parx; for (row = 0; row <= tst->_maxy; ++row) { tst->_line[row].text = &pline[tst->_pary + row].text[tst->_parx]; } repair_subwindows(tst); } } _nc_unlock_global(curses); }
set_curterm(TERMINAL * termp) { TERMINAL *oldterm; T((T_CALLED("set_curterm(%p)"), termp)); _nc_lock_global(curses); oldterm = cur_term; if (SP) SP->_term = termp; #if BROKEN_LINKER || USE_REENTRANT _nc_prescreen._cur_term = termp; #else cur_term = termp; #endif if (termp != 0) { ospeed = _nc_ospeed(termp->_baudrate); if (termp->type.Strings) { PC = (char) ((pad_char != NULL) ? pad_char[0] : 0); } } _nc_unlock_global(curses); T((T_RETURN("%p"), oldterm)); return (oldterm); }
del_curterm(TERMINAL * termp) { int rc = ERR; _nc_lock_global(curses); rc = NCURSES_SP_NAME(del_curterm) (CURRENT_SCREEN, termp); _nc_unlock_global(curses); return (rc); }
static int overlap(const WINDOW *const src, WINDOW *const dst, int const flag) { int rc = ERR; int sx1, sy1, sx2, sy2; int dx1, dy1, dx2, dy2; int sminrow, smincol; int dminrow, dmincol; int dmaxrow, dmaxcol; T((T_CALLED("overlap(%p,%p,%d)"), src, dst, flag)); if (src != 0 && dst != 0) { _nc_lock_global(curses); T(("src : begy %ld, begx %ld, maxy %ld, maxx %ld", (long) src->_begy, (long) src->_begx, (long) src->_maxy, (long) src->_maxx)); T(("dst : begy %ld, begx %ld, maxy %ld, maxx %ld", (long) dst->_begy, (long) dst->_begx, (long) dst->_maxy, (long) dst->_maxx)); sx1 = src->_begx; sy1 = src->_begy; sx2 = sx1 + src->_maxx; sy2 = sy1 + src->_maxy; dx1 = dst->_begx; dy1 = dst->_begy; dx2 = dx1 + dst->_maxx; dy2 = dy1 + dst->_maxy; if (dx2 >= sx1 && dx1 <= sx2 && dy2 >= sy1 && dy1 <= sy2) { sminrow = max(sy1, dy1) - sy1; smincol = max(sx1, dx1) - sx1; dminrow = max(sy1, dy1) - dy1; dmincol = max(sx1, dx1) - dx1; dmaxrow = min(sy2, dy2) - dy1; dmaxcol = min(sx2, dx2) - dx1; rc = copywin(src, dst, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, flag); } _nc_unlock_global(curses); } returnCode(rc); }
use_window(WINDOW *win, NCURSES_WINDOW_CB func, void *data) { int code = OK; T((T_CALLED("use_window(%p,%p,%p)"), (void *) win, func, data)); _nc_lock_global(curses); code = func(win, data); _nc_unlock_global(curses); returnCode(code); }
initscr(void) { WINDOW *result; START_TRACE(); T((T_CALLED("initscr()"))); _nc_init_pthreads(); _nc_lock_global(curses); /* Portable applications must not call initscr() more than once */ if (!_nc_globals.init_screen) { NCURSES_CONST char *name; _nc_globals.init_screen = TRUE; if ((name = getenv("TERM")) == 0 || *name == '\0') name = "unknown"; #ifdef __CYGWIN__ /* * 2002/9/21 * Work around a bug in Cygwin. Full-screen subprocesses run from * bash, in turn spawned from another full-screen process, will dump * core when attempting to write to stdout. Opening /dev/tty * explicitly seems to fix the problem. */ if (NC_ISATTY(fileno(stdout))) { FILE *fp = fopen("/dev/tty", "w"); if (fp != 0 && NC_ISATTY(fileno(fp))) { fclose(stdout); dup2(fileno(fp), STDOUT_FILENO); stdout = fdopen(STDOUT_FILENO, "w"); } } #endif if (newterm(name, stdout, stdin) == 0) { fprintf(stderr, "Error opening terminal: %s.\n", name); exit(EXIT_FAILURE); } /* def_shell_mode - done in newterm/_nc_setupscreen */ #if NCURSES_SP_FUNCS NCURSES_SP_NAME(def_prog_mode) (CURRENT_SCREEN); #else def_prog_mode(); #endif } result = stdscr; _nc_unlock_global(curses); returnWin(result); }
_nc_freeall(void) { WINDOWLIST *p, *q; static va_list empty_va; T((T_CALLED("_nc_freeall()"))); #if NO_LEAKS if (SP != 0) { if (SP->_oldnum_list != 0) { FreeAndNull(SP->_oldnum_list); } if (SP->_panelHook.destroy != 0) { SP->_panelHook.destroy(SP->_panelHook.stdscr_pseudo_panel); } } #endif if (SP != 0) { _nc_lock_global(curses); while (_nc_windows != 0) { bool deleted = FALSE; /* Delete only windows that're not a parent */ for (each_window(p)) { bool found = FALSE; for (each_window(q)) { if ((p != q) && (q->win._flags & _SUBWIN) && (&(p->win) == q->win._parent)) { found = TRUE; break; } } if (!found) { if (delwin(&(p->win)) != ERR) deleted = TRUE; break; } } /* * Don't continue to loop if the list is trashed. */ if (!deleted) break; } delscreen(SP); _nc_unlock_global(curses); }
static void show_window_sizes(const char *name) { WINDOWLIST *wp; _nc_lock_global(curses); _tracef("%s resizing: %2d x %2d (%2d x %2d)", name, LINES, COLS, screen_lines, screen_columns); for (each_window(wp)) { _tracef(" window %p is %2ld x %2ld at %2ld,%2ld", &(wp->win), (long) wp->win._maxy + 1, (long) wp->win._maxx + 1, (long) wp->win._begy, (long) wp->win._begx); } _nc_unlock_global(curses); }
del_curterm(TERMINAL * termp) { int rc = ERR; T((T_CALLED("del_curterm(%p)"), termp)); _nc_lock_global(curses); if (termp != 0) { _nc_free_termtype(&(termp->type)); FreeIfNeeded(termp->_termname); free(termp); if (termp == cur_term) set_curterm(0); rc = OK; } _nc_unlock_global(curses); returnCode(rc); }
_nc_use_tracef(unsigned mask) { bool result = FALSE; _nc_lock_global(tst_tracef); if (!_nc_globals.nested_tracef++) { if ((result = (_nc_tracing & (mask))) != 0 && _nc_try_global(tracef) == 0) { /* we will call _nc_locked_tracef(), no nesting so far */ } else { /* we will not call _nc_locked_tracef() */ _nc_globals.nested_tracef = 0; } } else { /* we may call _nc_locked_tracef(), but with nested_tracef > 0 */ result = (_nc_tracing & (mask)); } _nc_unlock_global(tst_tracef); return result; }
use_screen(SCREEN *screen, NCURSES_SCREEN_CB func, void *data) { SCREEN *save_SP; int code = OK; T((T_CALLED("use_screen(%p,%p,%p)"), screen, func, data)); /* * FIXME - add a flag so a given thread can check if _it_ has already * recurred through this point, return an error if so. */ _nc_lock_global(curses); save_SP = SP; set_term(screen); code = func(screen, data); set_term(save_SP); _nc_unlock_global(curses); returnCode(code); }
set_term(SCREEN *screenp) { SCREEN *oldSP; SCREEN *newSP; T((T_CALLED("set_term(%p)"), screenp)); _nc_lock_global(curses); oldSP = SP; _nc_set_screen(screenp); newSP = SP; if (newSP != 0) { set_curterm(newSP->_term); #if !USE_REENTRANT curscr = newSP->_curscr; newscr = newSP->_newscr; stdscr = newSP->_stdscr; COLORS = newSP->_color_count; COLOR_PAIRS = newSP->_pair_count; #endif } else { set_curterm(0); #if !USE_REENTRANT curscr = 0; newscr = 0; stdscr = 0; COLORS = 0; COLOR_PAIRS = 0; #endif } _nc_unlock_global(curses); T((T_RETURN("%p"), oldSP)); return (oldSP); }
set_term(SCREEN *screenp) { SCREEN *oldSP; SCREEN *newSP; T((T_CALLED("set_term(%p)"), (void *) screenp)); _nc_lock_global(curses); oldSP = CURRENT_SCREEN; _nc_set_screen(screenp); newSP = screenp; if (newSP != 0) { TINFO_SET_CURTERM(newSP, newSP->_term); #if !USE_REENTRANT curscr = CurScreen(newSP); newscr = NewScreen(newSP); stdscr = StdScreen(newSP); COLORS = newSP->_color_count; COLOR_PAIRS = newSP->_pair_count; #endif } else { TINFO_SET_CURTERM(oldSP, 0); #if !USE_REENTRANT curscr = 0; newscr = 0; stdscr = 0; COLORS = 0; COLOR_PAIRS = 0; #endif } _nc_unlock_global(curses); T((T_RETURN("%p"), (void *) oldSP)); return (oldSP); }
newterm(NCURSES_CONST char *name, FILE *ofp, FILE *ifp) { int value; int errret; SCREEN *current; SCREEN *result = 0; TERMINAL *its_term; START_TRACE(); T((T_CALLED("newterm(\"%s\",%p,%p)"), name, ofp, ifp)); _nc_init_pthreads(); _nc_lock_global(curses); current = SP; its_term = (SP ? SP->_term : 0); /* this loads the capability entry, then sets LINES and COLS */ if (setupterm(name, fileno(ofp), &errret) != ERR) { int slk_format = _nc_globals.slk_format; /* * This actually allocates the screen structure, and saves the original * terminal settings. */ _nc_set_screen(0); /* allow user to set maximum escape delay from the environment */ if ((value = _nc_getenv_num("ESCDELAY")) >= 0) { set_escdelay(value); } if (_nc_setupscreen(LINES, COLS, ofp, _nc_prescreen.filter_mode, slk_format) == ERR) { _nc_set_screen(current); result = 0; } else { assert(SP != 0); /* * In setupterm() we did a set_curterm(), but it was before we set * SP. So the "current" screen's terminal pointer was overwritten * with a different terminal. Later, in _nc_setupscreen(), we set * SP and the terminal pointer in the new screen. * * Restore the terminal-pointer for the pre-existing screen, if * any. */ if (current) current->_term = its_term; /* if the terminal type has real soft labels, set those up */ if (slk_format && num_labels > 0 && SLK_STDFMT(slk_format)) _nc_slk_initialize(stdscr, COLS); SP->_ifd = fileno(ifp); typeahead(fileno(ifp)); #ifdef TERMIOS SP->_use_meta = ((cur_term->Ottyb.c_cflag & CSIZE) == CS8 && !(cur_term->Ottyb.c_iflag & ISTRIP)); #else SP->_use_meta = FALSE; #endif SP->_endwin = FALSE; /* * Check whether we can optimize scrolling under dumb terminals in * case we do not have any of these capabilities, scrolling * optimization will be useless. */ SP->_scrolling = ((scroll_forward && scroll_reverse) || ((parm_rindex || parm_insert_line || insert_line) && (parm_index || parm_delete_line || delete_line))); baudrate(); /* sets a field in the SP structure */ SP->_keytry = 0; /* * Check for mismatched graphic-rendition capabilities. Most SVr4 * terminfo trees contain entries that have rmul or rmso equated to * sgr0 (Solaris curses copes with those entries). We do this only * for curses, since many termcap applications assume that * smso/rmso and smul/rmul are paired, and will not function * properly if we remove rmso or rmul. Curses applications * shouldn't be looking at this detail. */ #define SGR0_TEST(mode) (mode != 0) && (exit_attribute_mode == 0 || strcmp(mode, exit_attribute_mode)) SP->_use_rmso = SGR0_TEST(exit_standout_mode); SP->_use_rmul = SGR0_TEST(exit_underline_mode); /* compute movement costs so we can do better move optimization */ _nc_mvcur_init(); /* initialize terminal to a sane state */ _nc_screen_init(); /* Initialize the terminal line settings. */ _nc_initscr(); _nc_signal_handler(TRUE); result = SP; } } _nc_unlock_global(curses); returnSP(result); }
copywin(const WINDOW *src, WINDOW *dst, int sminrow, int smincol, int dminrow, int dmincol, int dmaxrow, int dmaxcol, int over) { int rc = ERR; int sx, sy, dx, dy; bool touched; attr_t bk; attr_t mask; T((T_CALLED("copywin(%p, %p, %d, %d, %d, %d, %d, %d, %d)"), src, dst, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, over)); if (src && dst) { _nc_lock_global(curses); bk = AttrOf(dst->_nc_bkgd); mask = ~(attr_t) ((bk & A_COLOR) ? A_COLOR : 0); /* make sure rectangle exists in source */ if ((sminrow + dmaxrow - dminrow) <= (src->_maxy + 1) && (smincol + dmaxcol - dmincol) <= (src->_maxx + 1)) { T(("rectangle exists in source")); /* make sure rectangle fits in destination */ if (dmaxrow <= dst->_maxy && dmaxcol <= dst->_maxx) { T(("rectangle fits in destination")); for (dy = dminrow, sy = sminrow; dy <= dmaxrow; sy++, dy++) { touched = FALSE; for (dx = dmincol, sx = smincol; dx <= dmaxcol; sx++, dx++) { if (over) { if ((CharOf(src->_line[sy].text[sx]) != L(' ')) && (!CharEq(dst->_line[dy].text[dx], src->_line[sy].text[sx]))) { dst->_line[dy].text[dx] = src->_line[sy].text[sx]; SetAttr(dst->_line[dy].text[dx], ((AttrOf(src->_line[sy].text[sx]) & mask) | bk)); touched = TRUE; } } else { if (!CharEq(dst->_line[dy].text[dx], src->_line[sy].text[sx])) { dst->_line[dy].text[dx] = src->_line[sy].text[sx]; touched = TRUE; } } } if (touched) { touchline(dst, dminrow, (dmaxrow - dminrow + 1)); } } T(("finished copywin")); rc = OK; } } _nc_unlock_global(curses); } returnCode(rc); }
delscreen(SCREEN *sp) { int i; T((T_CALLED("delscreen(%p)"), sp)); _nc_lock_global(curses); if (delink_screen(sp)) { (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); FreeIfNeeded(sp->_acs_map); FreeIfNeeded(sp->_screen_acs_map); /* * 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); } del_curterm(sp->_term); 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) { #if !USE_REENTRANT curscr = 0; newscr = 0; stdscr = 0; COLORS = 0; COLOR_PAIRS = 0; #endif _nc_set_screen(0); } } _nc_unlock_global(curses); returnVoid; }
wget_wch(WINDOW *win, wint_t *result) { SCREEN *sp; int code; char buffer[(MB_LEN_MAX * 9) + 1]; /* allow some redundant shifts */ int status; size_t count = 0; int value = 0; wchar_t wch; #ifndef state_unused mbstate_t state; #endif T((T_CALLED("wget_wch(%p)"), (void *) win)); /* * We can get a stream of single-byte characters and KEY_xxx codes from * _nc_wgetch(), while we want to return a wide character or KEY_xxx code. */ _nc_lock_global(curses); sp = _nc_screen_of(win); if (sp != 0) { for (;;) { T(("reading %d of %d", (int) count + 1, (int) sizeof(buffer))); code = _nc_wgetch(win, &value, TRUE EVENTLIST_2nd((_nc_eventlist *) 0)); if (code == ERR) { break; } else if (code == KEY_CODE_YES) { /* * If we were processing an incomplete multibyte character, * return an error since we have a KEY_xxx code which * interrupts it. For some cases, we could improve this by * writing a new version of lib_getch.c(!), but it is not clear * whether the improvement would be worth the effort. */ if (count != 0) { safe_ungetch(SP_PARM, value); code = ERR; } break; } else if (count + 1 >= sizeof(buffer)) { safe_ungetch(SP_PARM, value); code = ERR; break; } else { buffer[count++] = (char) UChar(value); reset_mbytes(state); status = count_mbytes(buffer, count, state); if (status >= 0) { reset_mbytes(state); if (check_mbytes(wch, buffer, count, state) != status) { code = ERR; /* the two calls should match */ safe_ungetch(SP_PARM, value); } value = wch; break; } } } } else { code = ERR; } *result = (wint_t) value; _nc_unlock_global(curses); T(("result %#o", value)); returnCode(code); }
NCURSES_SP_NAME(newterm) (NCURSES_SP_DCLx NCURSES_CONST char *name, FILE *ofp, FILE *ifp) { int value; int errret; SCREEN *result = 0; SCREEN *current; TERMINAL *its_term; FILE *_ofp = ofp ? ofp : stdout; FILE *_ifp = ifp ? ifp : stdin; int cols; int slk_format; int filter_mode; TERMINAL *new_term = 0; START_TRACE(); T((T_CALLED("newterm(%p, \"%s\", %p,%p)"), (void *) SP_PARM, name, (void *) ofp, (void *) ifp)); #if NCURSES_SP_FUNCS assert(SP_PARM != 0); if (SP_PARM == 0) returnSP(SP_PARM); #endif _nc_init_pthreads(); _nc_lock_global(curses); current = CURRENT_SCREEN; its_term = (current ? current->_term : 0); INIT_TERM_DRIVER(); /* this loads the capability entry, then sets LINES and COLS */ if ( #if NCURSES_SP_FUNCS SP_PARM->_prescreen && #endif TINFO_SETUP_TERM(&new_term, name, fileno(_ofp), &errret, FALSE) != ERR) { _nc_set_screen(0); #ifdef USE_TERM_DRIVER assert(new_term != 0); #endif #if NCURSES_SP_FUNCS slk_format = SP_PARM->slk_format; filter_mode = SP_PARM->_filtered; #else slk_format = _nc_globals.slk_format; filter_mode = _nc_prescreen.filter_mode; #endif /* * This actually allocates the screen structure, and saves the original * terminal settings. */ if (NCURSES_SP_NAME(_nc_setupscreen) ( #if NCURSES_SP_FUNCS &SP_PARM, #endif *(ptrLines(SP_PARM)), *(ptrCols(SP_PARM)), _ofp, filter_mode, slk_format) == ERR) { _nc_set_screen(current); result = 0; } else { #ifdef USE_TERM_DRIVER TERMINAL_CONTROL_BLOCK *TCB; #elif !NCURSES_SP_FUNCS SP_PARM = CURRENT_SCREEN; #endif assert(SP_PARM != 0); cols = *(ptrCols(SP_PARM)); #ifdef USE_TERM_DRIVER _nc_set_screen(SP_PARM); TCB = (TERMINAL_CONTROL_BLOCK *) new_term; TCB->csp = SP_PARM; #endif /* * In setupterm() we did a set_curterm(), but it was before we set * CURRENT_SCREEN. So the "current" screen's terminal pointer was * overwritten with a different terminal. Later, in * _nc_setupscreen(), we set CURRENT_SCREEN and the terminal * pointer in the new screen. * * Restore the terminal-pointer for the pre-existing screen, if * any. */ if (current) current->_term = its_term; #ifdef USE_TERM_DRIVER SP_PARM->_term = new_term; #else new_term = SP_PARM->_term; #endif /* allow user to set maximum escape delay from the environment */ if ((value = _nc_getenv_num("ESCDELAY")) >= 0) { NCURSES_SP_NAME(set_escdelay) (NCURSES_SP_ARGx value); } /* if the terminal type has real soft labels, set those up */ if (slk_format && NumLabels > 0 && SLK_STDFMT(slk_format)) _nc_slk_initialize(StdScreen(SP_PARM), cols); SP_PARM->_ifd = fileno(_ifp); NCURSES_SP_NAME(typeahead) (NCURSES_SP_ARGx fileno(_ifp)); #ifdef TERMIOS SP_PARM->_use_meta = ((new_term->Ottyb.c_cflag & CSIZE) == CS8 && !(new_term->Ottyb.c_iflag & ISTRIP)); #else SP_PARM->_use_meta = FALSE; #endif SP_PARM->_endwin = FALSE; #ifndef USE_TERM_DRIVER /* * Check whether we can optimize scrolling under dumb terminals in * case we do not have any of these capabilities, scrolling * optimization will be useless. */ SP_PARM->_scrolling = ((scroll_forward && scroll_reverse) || ((parm_rindex || parm_insert_line || insert_line) && (parm_index || parm_delete_line || delete_line))); #endif NCURSES_SP_NAME(baudrate) (NCURSES_SP_ARG); /* sets a field in the screen structure */ SP_PARM->_keytry = 0; /* compute movement costs so we can do better move optimization */ #ifdef USE_TERM_DRIVER TCBOf(SP_PARM)->drv->scinit(SP_PARM); #else /* * Check for mismatched graphic-rendition capabilities. Most SVr4 * terminfo trees contain entries that have rmul or rmso equated to * sgr0 (Solaris curses copes with those entries). We do this only * for curses, since many termcap applications assume that * smso/rmso and smul/rmul are paired, and will not function * properly if we remove rmso or rmul. Curses applications * shouldn't be looking at this detail. */ #define SGR0_TEST(mode) (mode != 0) && (exit_attribute_mode == 0 || strcmp(mode, exit_attribute_mode)) SP_PARM->_use_rmso = SGR0_TEST(exit_standout_mode); SP_PARM->_use_rmul = SGR0_TEST(exit_underline_mode); /* compute movement costs so we can do better move optimization */ _nc_mvcur_init(); /* initialize terminal to a sane state */ _nc_screen_init(); #endif /* Initialize the terminal line settings. */ _nc_initscr(NCURSES_SP_ARG); _nc_signal_handler(TRUE); result = SP_PARM; } } _nc_unlock_global(curses); returnSP(result); }
delscreen(SCREEN *sp) { int i; T((T_CALLED("delscreen(%p)"), (void *) sp)); _nc_lock_global(curses); if (delink_screen(sp)) { #ifdef USE_SP_RIPOFF ripoff_t *rop; if (safe_ripoff_sp && safe_ripoff_sp != safe_ripoff_stack) { for (rop = safe_ripoff_stack; rop != safe_ripoff_sp && (rop - safe_ripoff_stack) < N_RIPS; rop++) { if (rop->win) { (void) delwin(rop->win); rop->win = 0; } } } #endif (void) _nc_freewin(CurScreen(sp)); (void) _nc_freewin(NewScreen(sp)); (void) _nc_freewin(StdScreen(sp)); 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); FreeIfNeeded(sp->_acs_map); FreeIfNeeded(sp->_screen_acs_map); NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_ARG); NCURSES_SP_NAME(del_curterm) (NCURSES_SP_ARGx sp->_term); 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 == CURRENT_SCREEN) { #if !USE_REENTRANT curscr = 0; newscr = 0; stdscr = 0; COLORS = 0; COLOR_PAIRS = 0; #endif _nc_set_screen(0); } } _nc_unlock_global(curses); returnVoid; }
dupwin(WINDOW *win) /* make an exact duplicate of the given window */ { WINDOW *nwin = 0; size_t linesize; int i; T((T_CALLED("dupwin(%p)"), (void *) win)); if (win != 0) { #if NCURSES_SP_FUNCS SCREEN *sp = _nc_screen_of(win); #endif _nc_lock_global(curses); if (win->_flags & _ISPAD) { nwin = NCURSES_SP_NAME(newpad) (NCURSES_SP_ARGx win->_maxy + 1, win->_maxx + 1); } else { nwin = NCURSES_SP_NAME(newwin) (NCURSES_SP_ARGx win->_maxy + 1, win->_maxx + 1, win->_begy, win->_begx); } if (nwin != 0) { nwin->_curx = win->_curx; nwin->_cury = win->_cury; nwin->_maxy = win->_maxy; nwin->_maxx = win->_maxx; nwin->_begy = win->_begy; nwin->_begx = win->_begx; nwin->_yoffset = win->_yoffset; nwin->_flags = win->_flags & ~_SUBWIN; /* Due to the use of newwin(), the clone is not a subwindow. * The text is really copied into the clone. */ WINDOW_ATTRS(nwin) = WINDOW_ATTRS(win); nwin->_nc_bkgd = win->_nc_bkgd; nwin->_notimeout = win->_notimeout; nwin->_clear = win->_clear; nwin->_leaveok = win->_leaveok; nwin->_scroll = win->_scroll; nwin->_idlok = win->_idlok; nwin->_idcok = win->_idcok; nwin->_immed = win->_immed; nwin->_sync = win->_sync; nwin->_use_keypad = win->_use_keypad; nwin->_delay = win->_delay; nwin->_parx = 0; nwin->_pary = 0; nwin->_parent = (WINDOW *) 0; /* See above: the clone isn't a subwindow! */ nwin->_regtop = win->_regtop; nwin->_regbottom = win->_regbottom; if (win->_flags & _ISPAD) nwin->_pad = win->_pad; linesize = (unsigned) (win->_maxx + 1) * sizeof(NCURSES_CH_T); for (i = 0; i <= nwin->_maxy; i++) { memcpy(nwin->_line[i].text, win->_line[i].text, linesize); nwin->_line[i].firstchar = win->_line[i].firstchar; nwin->_line[i].lastchar = win->_line[i].lastchar; } } _nc_unlock_global(curses); } returnWin(nwin); }
NCURSES_SP_NAME(_nc_freeall) (NCURSES_SP_DCL0) { static va_list empty_va; T((T_CALLED("_nc_freeall()"))); #if NO_LEAKS _nc_globals.leak_checking = TRUE; if (SP_PARM != 0) { if (SP_PARM->_oldnum_list != 0) { FreeAndNull(SP_PARM->_oldnum_list); } if (SP_PARM->_panelHook.destroy != 0) { SP_PARM->_panelHook.destroy(SP_PARM->_panelHook.stdscr_pseudo_panel); } #if USE_NEW_PAIR _nc_new_pair_leaks(SP_PARM); #endif } #endif if (SP_PARM != 0) { _nc_lock_global(curses); while (WindowList(SP_PARM) != 0) { WINDOWLIST *p, *q; bool deleted = FALSE; /* Delete only windows that're not a parent */ for (each_window(SP_PARM, p)) { WINDOW *p_win = &(p->win); bool found = FALSE; #ifndef USE_SP_WINDOWLIST if (p->screen != SP_PARM) continue; #endif for (each_window(SP_PARM, q)) { WINDOW *q_win = &(q->win); #ifndef USE_SP_WINDOWLIST if (q->screen != SP_PARM) continue; #endif if ((p != q) && (q_win->_flags & _SUBWIN) && (p_win == q_win->_parent)) { found = TRUE; break; } } if (!found) { if (delwin(p_win) != ERR) deleted = TRUE; break; } } /* * Don't continue to loop if the list is trashed. */ if (!deleted) break; } delscreen(SP_PARM); _nc_unlock_global(curses); }