1/**************************************************************************** 2 * Copyright 2018-2021,2022 Thomas E. Dickey * 3 * Copyright 1998-2016,2017 Free Software Foundation, Inc. * 4 * * 5 * Permission is hereby granted, free of charge, to any person obtaining a * 6 * copy of this software and associated documentation files (the * 7 * "Software"), to deal in the Software without restriction, including * 8 * without limitation the rights to use, copy, modify, merge, publish, * 9 * distribute, distribute with modifications, sublicense, and/or sell * 10 * copies of the Software, and to permit persons to whom the Software is * 11 * furnished to do so, subject to the following conditions: * 12 * * 13 * The above copyright notice and this permission notice shall be included * 14 * in all copies or substantial portions of the Software. * 15 * * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 19 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 22 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 23 * * 24 * Except as contained in this notice, the name(s) of the above copyright * 25 * holders shall not be used in advertising or otherwise to promote the * 26 * sale, use or other dealings in this Software without prior written * 27 * authorization. * 28 ****************************************************************************/ 29 30/**************************************************************************** 31 * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 32 * and: Eric S. Raymond <esr@snark.thyrsus.com> * 33 * and: Thomas E. Dickey 1996-on * 34 * and: Juergen Pfeifer 2009 * 35 ****************************************************************************/ 36 37/* 38** lib_set_term.c 39** 40** The routine set_term(). 41** 42*/ 43 44#define NEW_PAIR_INTERNAL 1 45 46#include <curses.priv.h> 47#include <tic.h> 48#include <new_pair.h> 49 50#if USE_GPM_SUPPORT 51#ifdef HAVE_LIBDL 52/* use dynamic loader to avoid linkage dependency */ 53#include <dlfcn.h> 54#endif 55#endif 56 57#undef CUR 58#define CUR SP_TERMTYPE 59 60MODULE_ID("$Id: lib_set_term.c,v 1.184 2022/12/10 21:34:12 tom Exp $") 61 62#ifdef USE_TERM_DRIVER 63#define MaxColors InfoOf(sp).maxcolors 64#define NumLabels InfoOf(sp).numlabels 65#else 66#define MaxColors max_colors 67#define NumLabels num_labels 68#endif 69 70NCURSES_EXPORT(SCREEN *) 71set_term(SCREEN *screenp) 72{ 73 SCREEN *oldSP; 74 SCREEN *newSP; 75 76 T((T_CALLED("set_term(%p)"), (void *) screenp)); 77 78 _nc_lock_global(curses); 79 80 oldSP = CURRENT_SCREEN; 81 _nc_set_screen(screenp); 82 newSP = screenp; 83 84 if (newSP != 0) { 85 TINFO_SET_CURTERM(newSP, newSP->_term); 86#if !USE_REENTRANT 87 curscr = CurScreen(newSP); 88 newscr = NewScreen(newSP); 89 stdscr = StdScreen(newSP); 90 COLORS = newSP->_color_count; 91 COLOR_PAIRS = newSP->_pair_count; 92#endif 93 } else { 94 TINFO_SET_CURTERM(oldSP, 0); 95#if !USE_REENTRANT 96 curscr = 0; 97 newscr = 0; 98 stdscr = 0; 99 COLORS = 0; 100 COLOR_PAIRS = 0; 101#endif 102 } 103 104 _nc_unlock_global(curses); 105 106 T((T_RETURN("%p"), (void *) oldSP)); 107 return (oldSP); 108} 109 110static void 111_nc_free_keytry(TRIES * kt) 112{ 113 if (kt != 0) { 114 _nc_free_keytry(kt->child); 115 _nc_free_keytry(kt->sibling); 116 free(kt); 117 } 118} 119 120static bool 121delink_screen(SCREEN *sp) 122{ 123 SCREEN *last = 0; 124 SCREEN *temp; 125 bool result = FALSE; 126 127 for (each_screen(temp)) { 128 if (temp == sp) { 129 if (last) 130 last->_next_screen = sp->_next_screen; 131 else 132 _nc_screen_chain = sp->_next_screen; 133 result = TRUE; 134 break; 135 } 136 last = temp; 137 } 138 return result; 139} 140 141/* 142 * Free the storage associated with the given SCREEN sp. 143 */ 144NCURSES_EXPORT(void) 145delscreen(SCREEN *sp) 146{ 147 148 T((T_CALLED("delscreen(%p)"), (void *) sp)); 149 150 _nc_lock_global(curses); 151 if (delink_screen(sp)) { 152 WINDOWLIST *wl; 153 bool is_current = (sp == CURRENT_SCREEN); 154 155#ifdef USE_SP_RIPOFF 156 if (safe_ripoff_sp && safe_ripoff_sp != safe_ripoff_stack) { 157 ripoff_t *rop; 158 for (rop = safe_ripoff_stack; 159 rop != safe_ripoff_sp && (rop - safe_ripoff_stack) < N_RIPS; 160 rop++) { 161 if (rop->win) { 162 (void) delwin(rop->win); 163 rop->win = 0; 164 } 165 } 166 } 167#endif 168 169 /* delete all of the windows in this screen */ 170 rescan: 171 for (each_window(sp, wl)) { 172 if (_nc_freewin(&(wl->win)) == OK) { 173 goto rescan; 174 } 175 } 176 177 if (sp->_slk != 0) { 178 179 if (sp->_slk->ent != 0) { 180 int i; 181 182 for (i = 0; i < sp->_slk->labcnt; ++i) { 183 FreeIfNeeded(sp->_slk->ent[i].ent_text); 184 FreeIfNeeded(sp->_slk->ent[i].form_text); 185 } 186 free(sp->_slk->ent); 187 } 188 free(sp->_slk); 189 sp->_slk = 0; 190 } 191 192 _nc_free_keytry(sp->_keytry); 193 sp->_keytry = 0; 194 195 _nc_free_keytry(sp->_key_ok); 196 sp->_key_ok = 0; 197 198 FreeIfNeeded(sp->_current_attr); 199 200 _nc_free_ordered_pairs(sp); 201 FreeIfNeeded(sp->_color_table); 202 FreeIfNeeded(sp->_color_pairs); 203 204 FreeIfNeeded(sp->_oldnum_list); 205 FreeIfNeeded(sp->oldhash); 206 FreeIfNeeded(sp->newhash); 207 FreeIfNeeded(sp->hashtab); 208 209 FreeIfNeeded(sp->_acs_map); 210 FreeIfNeeded(sp->_screen_acs_map); 211 212 NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_ARG); 213 NCURSES_SP_NAME(del_curterm) (NCURSES_SP_ARGx sp->_term); 214 FreeIfNeeded(sp->out_buffer); 215 if (_nc_find_prescr() == sp) { 216 _nc_forget_prescr(); 217 } 218#if USE_GPM_SUPPORT 219#ifdef HAVE_LIBDL 220 if (sp->_dlopen_gpm != 0) { 221 dlclose(sp->_dlopen_gpm); 222 sp->_dlopen_gpm = 0; 223 } 224#endif 225#endif /* USE_GPM_SUPPORT */ 226 free(sp); 227 228 /* 229 * If this was the current screen, reset everything that the 230 * application might try to use (except cur_term, which may have 231 * multiple references in different screens). 232 */ 233 if (is_current) { 234#if !USE_REENTRANT 235 curscr = 0; 236 newscr = 0; 237 stdscr = 0; 238 COLORS = 0; 239 COLOR_PAIRS = 0; 240#endif 241 _nc_set_screen(0); 242#if USE_WIDEC_SUPPORT 243 if (SP == 0) { 244 FreeIfNeeded(_nc_wacs); 245 _nc_wacs = 0; 246 } 247#endif 248 } else { 249 set_term(CURRENT_SCREEN); 250 } 251 } 252 _nc_unlock_global(curses); 253 254 returnVoid; 255} 256 257static bool 258no_mouse_event(SCREEN *sp GCC_UNUSED) 259{ 260 return FALSE; 261} 262 263static bool 264no_mouse_inline(SCREEN *sp GCC_UNUSED) 265{ 266 return FALSE; 267} 268 269static bool 270no_mouse_parse(SCREEN *sp GCC_UNUSED, int code GCC_UNUSED) 271{ 272 return TRUE; 273} 274 275static void 276no_mouse_resume(SCREEN *sp GCC_UNUSED) 277{ 278} 279 280static void 281no_mouse_wrap(SCREEN *sp GCC_UNUSED) 282{ 283} 284 285#if NCURSES_EXT_FUNCS && USE_COLORFGBG 286static const char * 287extract_fgbg(const char *src, int *result) 288{ 289 const char *dst = 0; 290 char *tmp = 0; 291 long value = strtol(src, &tmp, 0); 292 293 if ((dst = tmp) == 0) { 294 dst = src; 295 } else if (value >= 0) { 296 *result = (int) value; 297 } 298 while (*dst != 0 && *dst != ';') 299 dst++; 300 if (*dst == ';') 301 dst++; 302 return dst; 303} 304#endif 305 306#define ReturnScreenError() do { _nc_set_screen(0); \ 307 returnCode(ERR); } while (0) 308 309/* OS-independent screen initializations */ 310NCURSES_EXPORT(int) 311NCURSES_SP_NAME(_nc_setupscreen) ( 312#if NCURSES_SP_FUNCS 313 SCREEN **spp, 314#endif 315 int slines, 316 int scolumns, 317 FILE *output, 318 int filtered, 319 int slk_format) 320{ 321#ifndef USE_TERM_DRIVER 322 static const TTY null_TTY; /* all zeros iff uninitialized */ 323#endif 324 char *env; 325 int bottom_stolen = 0; 326 SCREEN *sp; 327#ifndef USE_TERM_DRIVER 328 bool support_cookies = USE_XMC_SUPPORT; 329#endif 330 331 T((T_CALLED("_nc_setupscreen(%d, %d, %p, %d, %d)"), 332 slines, scolumns, (void *) output, filtered, slk_format)); 333 334 assert(CURRENT_SCREEN == 0); /* has been reset in newterm() ! */ 335 336#if NCURSES_SP_FUNCS 337 assert(spp != 0); 338 sp = *spp; 339 340 if (!sp) { 341 sp = _nc_alloc_screen_sp(); 342 T(("_nc_alloc_screen_sp %p", (void *) sp)); 343 *spp = sp; 344 } 345 if (sp == NULL) { 346 ReturnScreenError(); 347 } 348 if ((sp->_acs_map = typeCalloc(chtype, ACS_LEN)) == NULL) { 349 ReturnScreenError(); 350 } 351 if ((sp->_screen_acs_map = typeCalloc(bool, ACS_LEN)) == NULL) { 352 free(sp->_acs_map); 353 ReturnScreenError(); 354 } 355 356 T(("created SP %p", (void *) sp)); 357 sp->_next_screen = _nc_screen_chain; 358 _nc_screen_chain = sp; 359 360 if ((sp->_current_attr = typeCalloc(NCURSES_CH_T, 1)) == 0) { 361 ReturnScreenError(); 362 } 363#else 364 if (!_nc_alloc_screen() 365 || ((SP->_acs_map = typeCalloc(chtype, ACS_LEN)) == 0) 366 || ((SP->_screen_acs_map = typeCalloc(bool, ACS_LEN)) == 0)) { 367 returnCode(ERR); 368 } 369 370 T(("created SP %p", (void *) SP)); 371 372 sp = SP; /* fixup so SET_LINES and SET_COLS works */ 373 sp->_next_screen = _nc_screen_chain; 374 _nc_screen_chain = sp; 375 376 if ((sp->_current_attr = typeCalloc(NCURSES_CH_T, 1)) == 0) { 377 returnCode(ERR); 378 } 379#endif 380 381 /* 382 * We should always check the screensize, just in case. 383 */ 384 _nc_set_screen(sp); 385 sp->_term = cur_term; 386#ifdef USE_TERM_DRIVER 387 TCBOf(sp)->csp = sp; 388 _nc_get_screensize(sp, sp->_term, &slines, &scolumns); 389#else 390 _nc_get_screensize(sp, &slines, &scolumns); 391#endif 392 SET_LINES(slines); 393 SET_COLS(scolumns); 394 395 T((T_CREATE("screen %s %dx%d"), 396 NCURSES_SP_NAME(termname) (NCURSES_SP_ARG), slines, scolumns)); 397 398 sp->_filtered = filtered; 399 400 /* implement filter mode */ 401 if (filtered) { 402 slines = 1; 403 SET_LINES(slines); 404#ifdef USE_TERM_DRIVER 405 CallDriver(sp, td_setfilter); 406#else 407 /* *INDENT-EQLS* */ 408 clear_screen = ABSENT_STRING; 409 cursor_address = ABSENT_STRING; 410 cursor_down = ABSENT_STRING; 411 cursor_up = ABSENT_STRING; 412 parm_down_cursor = ABSENT_STRING; 413 parm_up_cursor = ABSENT_STRING; 414 row_address = ABSENT_STRING; 415 cursor_home = carriage_return; 416 417 if (back_color_erase) 418 clr_eos = ABSENT_STRING; 419 420#endif 421 T(("filter screensize %dx%d", slines, scolumns)); 422 } 423#ifdef __DJGPP__ 424 T(("setting output mode to binary")); 425 fflush(output); 426 setmode(output, O_BINARY); 427#endif 428#if defined(EXP_WIN32_DRIVER) 429 T(("setting output mode to binary")); 430 fflush(output); 431 _setmode(fileno(output), _O_BINARY); 432#endif 433 sp->_lines = (NCURSES_SIZE_T) slines; 434 sp->_lines_avail = (NCURSES_SIZE_T) slines; 435 sp->_columns = (NCURSES_SIZE_T) scolumns; 436 437 fflush(output); 438 sp->_ofd = output ? fileno(output) : -1; 439 sp->_ofp = output; 440#if defined(EXP_WIN32_DRIVER) 441 if (output) 442 _setmode(fileno(output), _O_BINARY); 443#endif 444 sp->out_limit = (size_t) ((2 + slines) * (6 + scolumns)); 445 if ((sp->out_buffer = malloc(sp->out_limit)) == 0) 446 sp->out_limit = 0; 447 sp->out_inuse = 0; 448 449 SP_PRE_INIT(sp); 450 SetNoPadding(sp); 451 452#if NCURSES_EXT_FUNCS 453 sp->_default_color = FALSE; 454 sp->_has_sgr_39_49 = FALSE; 455 456 /* 457 * Set our assumption of the terminal's default foreground and background 458 * colors. The curs_color man-page states that we can assume that the 459 * background is black. The origin of this assumption appears to be 460 * terminals that displayed colored text, but no colored backgrounds, e.g., 461 * the first colored terminals around 1980. More recent ones with better 462 * technology can display not only colored backgrounds, but all 463 * combinations. So a terminal might be something other than "white" on 464 * black (green/black looks monochrome too), but black on white or even 465 * on ivory. 466 * 467 * White-on-black is the simplest thing to use for monochrome. Almost 468 * all applications that use color paint both text and background, so 469 * the distinction is moot. But a few do not - which is why we leave this 470 * configurable (a better solution is to use assume_default_colors() for 471 * the rare applications that do require that sort of appearance, since 472 * is appears that more users expect to be able to make a white-on-black 473 * or black-on-white display under control of the application than not). 474 */ 475#ifdef USE_ASSUMED_COLOR 476 sp->_default_fg = COLOR_WHITE; 477 sp->_default_bg = COLOR_BLACK; 478#else 479 sp->_default_fg = COLOR_DEFAULT; 480 sp->_default_bg = COLOR_DEFAULT; 481#endif 482 483 /* 484 * Allow those assumed/default color assumptions to be overridden at 485 * runtime: 486 */ 487 if ((env = getenv("NCURSES_ASSUMED_COLORS")) != 0) { 488 int fg, bg; 489 char sep1, sep2; 490 int count = sscanf(env, "%d%c%d%c", &fg, &sep1, &bg, &sep2); 491 if (count >= 1) { 492 sp->_default_fg = ((fg >= 0 && fg < MaxColors) ? fg : COLOR_DEFAULT); 493 if (count >= 3) { 494 sp->_default_bg = ((bg >= 0 && bg < MaxColors) ? bg : COLOR_DEFAULT); 495 } 496 TR(TRACE_CHARPUT | TRACE_MOVE, 497 ("from environment assumed fg=%d, bg=%d", 498 sp->_default_fg, 499 sp->_default_bg)); 500 } 501 } 502#if USE_COLORFGBG 503 /* 504 * If rxvt's $COLORFGBG variable is set, use it to specify the assumed 505 * default colors. Note that rxvt (mis)uses bold colors, equating a bold 506 * color to that value plus 8. We'll only use the non-bold color for now - 507 * decide later if it is worth having default attributes as well. 508 */ 509 if (getenv("COLORFGBG") != 0) { 510 const char *p = getenv("COLORFGBG"); 511 TR(TRACE_CHARPUT | TRACE_MOVE, ("decoding COLORFGBG %s", p)); 512 p = extract_fgbg(p, &(sp->_default_fg)); 513 p = extract_fgbg(p, &(sp->_default_bg)); 514 if (*p) /* assume rxvt was compiled with xpm support */ 515 extract_fgbg(p, &(sp->_default_bg)); 516 TR(TRACE_CHARPUT | TRACE_MOVE, ("decoded fg=%d, bg=%d", 517 sp->_default_fg, sp->_default_bg)); 518 if (sp->_default_fg >= MaxColors) { 519 if (set_a_foreground != ABSENT_STRING 520 && !strcmp(set_a_foreground, "\033[3%p1%dm")) { 521 set_a_foreground = strdup("\033[3%?%p1%{8}%>%t9%e%p1%d%;m"); 522 } else { 523 sp->_default_fg %= MaxColors; 524 } 525 } 526 if (sp->_default_bg >= MaxColors) { 527 if (set_a_background != ABSENT_STRING 528 && !strcmp(set_a_background, "\033[4%p1%dm")) { 529 set_a_background = strdup("\033[4%?%p1%{8}%>%t9%e%p1%d%;m"); 530 } else { 531 sp->_default_bg %= MaxColors; 532 } 533 } 534 } 535#endif 536#endif /* NCURSES_EXT_FUNCS */ 537 538 sp->_maxclick = DEFAULT_MAXCLICK; 539 sp->_mouse_event = no_mouse_event; 540 sp->_mouse_inline = no_mouse_inline; 541 sp->_mouse_parse = no_mouse_parse; 542 sp->_mouse_resume = no_mouse_resume; 543 sp->_mouse_wrap = no_mouse_wrap; 544 sp->_mouse_fd = -1; 545 546 /* 547 * If we've no magic cookie support, we suppress attributes that xmc would 548 * affect, i.e., the attributes that affect the rendition of a space. 549 */ 550 sp->_ok_attributes = NCURSES_SP_NAME(termattrs) (NCURSES_SP_ARG); 551 if (NCURSES_SP_NAME(has_colors) (NCURSES_SP_ARG)) { 552 sp->_ok_attributes |= A_COLOR; 553 } 554#ifdef USE_TERM_DRIVER 555 _nc_cookie_init(sp); 556#else 557#if USE_XMC_SUPPORT 558 /* 559 * If we have no magic-cookie support compiled-in, or if it is suppressed 560 * in the environment, reset the support-flag. 561 */ 562 if (magic_cookie_glitch >= 0) { 563 if (getenv("NCURSES_NO_MAGIC_COOKIE") != 0) { 564 support_cookies = FALSE; 565 } 566 } 567#endif 568 569 if (!support_cookies && magic_cookie_glitch >= 0) { 570 T(("will disable attributes to work w/o magic cookies")); 571 } 572 573 if (magic_cookie_glitch > 0) { /* tvi, wyse */ 574 575 sp->_xmc_triggers = sp->_ok_attributes & XMC_CONFLICT; 576#if 0 577 /* 578 * We "should" treat colors as an attribute. The wyse350 (and its 579 * clones) appear to be the only ones that have both colors and magic 580 * cookies. 581 */ 582 if (has_colors()) { 583 sp->_xmc_triggers |= A_COLOR; 584 } 585#endif 586 sp->_xmc_suppress = sp->_xmc_triggers & (chtype) ~(A_BOLD); 587 588 T(("magic cookie attributes %s", _traceattr(sp->_xmc_suppress))); 589 /* 590 * Supporting line-drawing may be possible. But make the regular 591 * video attributes work first. 592 */ 593 acs_chars = ABSENT_STRING; 594 ena_acs = ABSENT_STRING; 595 enter_alt_charset_mode = ABSENT_STRING; 596 exit_alt_charset_mode = ABSENT_STRING; 597#if USE_XMC_SUPPORT 598 /* 599 * To keep the cookie support simple, suppress all of the optimization 600 * hooks except for clear_screen and the cursor addressing. 601 */ 602 if (support_cookies) { 603 clr_eol = ABSENT_STRING; 604 clr_eos = ABSENT_STRING; 605 set_attributes = ABSENT_STRING; 606 } 607#endif 608 } else if (magic_cookie_glitch == 0) { /* hpterm */ 609 } 610 611 /* 612 * If magic cookies are not supported, cancel the strings that set 613 * video attributes. 614 */ 615 if (!support_cookies && magic_cookie_glitch >= 0) { 616 magic_cookie_glitch = ABSENT_NUMERIC; 617 set_attributes = ABSENT_STRING; 618 enter_blink_mode = ABSENT_STRING; 619 enter_bold_mode = ABSENT_STRING; 620 enter_dim_mode = ABSENT_STRING; 621 enter_reverse_mode = ABSENT_STRING; 622 enter_standout_mode = ABSENT_STRING; 623 enter_underline_mode = ABSENT_STRING; 624 } 625 626 /* initialize normal acs before wide, since we use mapping in the latter */ 627#if !USE_WIDEC_SUPPORT 628 if (_nc_unicode_locale() && _nc_locale_breaks_acs(sp->_term)) { 629 acs_chars = NULL; 630 ena_acs = NULL; 631 enter_alt_charset_mode = NULL; 632 exit_alt_charset_mode = NULL; 633 set_attributes = NULL; 634 } 635#endif 636#endif 637 638 NCURSES_SP_NAME(_nc_init_acs) (NCURSES_SP_ARG); 639#if USE_WIDEC_SUPPORT 640 sp->_screen_unicode = _nc_unicode_locale(); 641 if (_nc_wacs == 0) { 642 _nc_init_wacs(); 643 } 644 if (_nc_wacs == 0) { 645 ReturnScreenError(); 646 } 647 648 sp->_screen_acs_fix = (sp->_screen_unicode 649 && _nc_locale_breaks_acs(sp->_term)); 650#endif 651 env = _nc_get_locale(); 652 sp->_legacy_coding = ((env == 0) 653 || !strcmp(env, "C") 654 || !strcmp(env, "POSIX")); 655 T(("legacy-coding %d", sp->_legacy_coding)); 656 657 sp->_nc_sp_idcok = TRUE; 658 sp->_nc_sp_idlok = FALSE; 659 660 sp->oldhash = 0; 661 sp->newhash = 0; 662 663 T(("creating newscr")); 664 NewScreen(sp) = NCURSES_SP_NAME(newwin) (NCURSES_SP_ARGx slines, scolumns, 665 0, 0); 666 if (NewScreen(sp) == 0) { 667 ReturnScreenError(); 668 } 669 T(("creating curscr")); 670 CurScreen(sp) = NCURSES_SP_NAME(newwin) (NCURSES_SP_ARGx slines, scolumns, 671 0, 0); 672 if (CurScreen(sp) == 0) { 673 ReturnScreenError(); 674 } 675#if !USE_REENTRANT 676 newscr = NewScreen(sp); 677 curscr = CurScreen(sp); 678#endif 679#if USE_SIZECHANGE 680 sp->_resize = NCURSES_SP_NAME(resizeterm); 681 sp->_ungetch = safe_ungetch; 682#endif 683 684 NewScreen(sp)->_clear = TRUE; 685 CurScreen(sp)->_clear = FALSE; 686 687 /* 688 * Get the current tty-modes. setupterm() may already have done this, 689 * unless we use the term-driver. 690 */ 691#ifndef USE_TERM_DRIVER 692 if (cur_term != 0 && 693 !memcmp(&cur_term->Ottyb, &null_TTY, sizeof(TTY))) 694#endif 695 { 696 NCURSES_SP_NAME(def_shell_mode) (NCURSES_SP_ARG); 697 NCURSES_SP_NAME(def_prog_mode) (NCURSES_SP_ARG); 698 } 699 700 if (safe_ripoff_sp && safe_ripoff_sp != safe_ripoff_stack) { 701 ripoff_t *rop; 702 703 for (rop = safe_ripoff_stack; 704 rop != safe_ripoff_sp && (rop - safe_ripoff_stack) < N_RIPS; 705 rop++) { 706 707 /* If we must simulate soft labels, grab off the line to be used. 708 We assume that we must simulate, if it is none of the standard 709 formats (4-4 or 3-2-3) for which there may be some hardware 710 support. */ 711 if (rop->hook == _nc_slk_initialize) { 712 if (!TerminalOf(sp)) { 713 continue; 714 } 715 if (!(NumLabels <= 0 || !SLK_STDFMT(slk_format))) { 716 continue; 717 } 718 } 719 if (rop->hook) { 720 int count; 721 WINDOW *w; 722 723 count = (rop->line < 0) ? -rop->line : rop->line; 724 T(("ripping off %i lines at %s", count, 725 ((rop->line < 0) 726 ? "bottom" 727 : "top"))); 728 729 w = NCURSES_SP_NAME(newwin) (NCURSES_SP_ARGx 730 count, scolumns, 731 ((rop->line < 0) 732 ? sp->_lines_avail - count 733 : 0), 734 0); 735 if (w) { 736 rop->win = w; 737 rop->hook(w, scolumns); 738 } else { 739 ReturnScreenError(); 740 } 741 if (rop->line < 0) { 742 bottom_stolen += count; 743 } else { 744 sp->_topstolen = (NCURSES_SIZE_T) (sp->_topstolen + count); 745 } 746 sp->_lines_avail = (NCURSES_SIZE_T) (sp->_lines_avail - count); 747 } 748 } 749 /* reset the stack */ 750 safe_ripoff_sp = safe_ripoff_stack; 751 } 752 753 T(("creating stdscr")); 754 (void) bottom_stolen; 755 assert((sp->_lines_avail + sp->_topstolen + bottom_stolen) == slines); 756 if ((StdScreen(sp) = NCURSES_SP_NAME(newwin) (NCURSES_SP_ARGx 757 sp->_lines_avail, 758 scolumns, 0, 0)) == 0) { 759 ReturnScreenError(); 760 } 761 SET_LINES(sp->_lines_avail); 762#if !USE_REENTRANT 763 stdscr = StdScreen(sp); 764#endif 765 sp->_prescreen = FALSE; 766 returnCode(OK); 767} 768 769#if NCURSES_SP_FUNCS 770NCURSES_EXPORT(int) 771_nc_setupscreen(int slines GCC_UNUSED, 772 int scolumns GCC_UNUSED, 773 FILE *output, 774 int filtered, 775 int slk_format) 776{ 777 SCREEN *sp = 0; 778 int rc = NCURSES_SP_NAME(_nc_setupscreen) (&sp, 779 slines, 780 scolumns, 781 output, 782 filtered, 783 slk_format); 784 if (rc != OK) 785 _nc_set_screen(0); 786 return rc; 787} 788#endif 789 790/* 791 * The internal implementation interprets line as the number of lines to rip 792 * off from the top or bottom. 793 */ 794NCURSES_EXPORT(int) 795NCURSES_SP_NAME(_nc_ripoffline) (NCURSES_SP_DCLx 796 int line, 797 int (*init) (WINDOW *, int)) 798{ 799 int code = ERR; 800 TR_FUNC_BFR(1); 801 802 START_TRACE(); 803 T((T_CALLED("ripoffline(%p,%d,%s)"), 804 (void *) SP_PARM, line, 805 TR_FUNC_ARG(0, init))); 806 807#if NCURSES_SP_FUNCS 808 if (SP_PARM != 0 && SP_PARM->_prescreen) 809#endif 810 { 811 if (line == 0) { 812 code = OK; 813 } else { 814 if (safe_ripoff_sp == 0) { 815 safe_ripoff_sp = safe_ripoff_stack; 816 } 817 if (safe_ripoff_sp < safe_ripoff_stack + N_RIPS) { 818 safe_ripoff_sp->line = line; 819 safe_ripoff_sp->hook = init; 820 (safe_ripoff_sp)++; 821 T(("ripped-off %d:%d chunks", 822 (int) (safe_ripoff_sp - safe_ripoff_stack), N_RIPS)); 823 code = OK; 824 } 825 } 826 } 827 828 returnCode(code); 829} 830 831#if NCURSES_SP_FUNCS 832NCURSES_EXPORT(int) 833_nc_ripoffline(int line, int (*init) (WINDOW *, int)) 834{ 835 int rc; 836 837 _nc_init_pthreads(); 838 _nc_lock_global(prescreen); 839 START_TRACE(); 840 rc = NCURSES_SP_NAME(_nc_ripoffline) (CURRENT_SCREEN_PRE, line, init); 841 _nc_unlock_global(prescreen); 842 843 return rc; 844} 845#endif 846 847NCURSES_EXPORT(int) 848NCURSES_SP_NAME(ripoffline) (NCURSES_SP_DCLx 849 int line, 850 int (*init) (WINDOW *, int)) 851{ 852 START_TRACE(); 853 return NCURSES_SP_NAME(_nc_ripoffline) (NCURSES_SP_ARGx 854 (line < 0) ? -1 : 1, 855 init); 856} 857 858#if NCURSES_SP_FUNCS 859NCURSES_EXPORT(int) 860ripoffline(int line, int (*init) (WINDOW *, int)) 861{ 862 int rc; 863 864 _nc_init_pthreads(); 865 _nc_lock_global(prescreen); 866 START_TRACE(); 867 rc = NCURSES_SP_NAME(ripoffline) (CURRENT_SCREEN_PRE, line, init); 868 _nc_unlock_global(prescreen); 869 870 return rc; 871} 872#endif 873