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