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