1 /**************************************************************************** 2 * Copyright (c) 1998-2009,2010 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.138 2010/12/20 00:42:20 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 /* 192 * If the associated output stream has been closed, we can discard the 193 * set-buffer. Limit the error check to EBADF, since fflush may fail 194 * for other reasons than trying to operate upon a closed stream. 195 */ 196 if (sp->_ofp != 0 197 && sp->_setbuf != 0 198 && fflush(sp->_ofp) != 0 199 && errno == EBADF) { 200 free(sp->_setbuf); 201 } 202 203 NCURSES_SP_NAME(del_curterm) (NCURSES_SP_ARGx sp->_term); 204 free(sp); 205 206 /* 207 * If this was the current screen, reset everything that the 208 * application might try to use (except cur_term, which may have 209 * multiple references in different screens). 210 */ 211 if (sp == CURRENT_SCREEN) { 212 #if !USE_REENTRANT 213 curscr = 0; 214 newscr = 0; 215 stdscr = 0; 216 COLORS = 0; 217 COLOR_PAIRS = 0; 218 #endif 219 _nc_set_screen(0); 220 } 221 } 222 _nc_unlock_global(curses); 223 224 returnVoid; 225 } 226 227 static bool 228 no_mouse_event(SCREEN *sp GCC_UNUSED) 229 { 230 return FALSE; 231 } 232 233 static bool 234 no_mouse_inline(SCREEN *sp GCC_UNUSED) 235 { 236 return FALSE; 237 } 238 239 static bool 240 no_mouse_parse(SCREEN *sp GCC_UNUSED, int code GCC_UNUSED) 241 { 242 return TRUE; 243 } 244 245 static void 246 no_mouse_resume(SCREEN *sp GCC_UNUSED) 247 { 248 } 249 250 static void 251 no_mouse_wrap(SCREEN *sp GCC_UNUSED) 252 { 253 } 254 255 #if NCURSES_EXT_FUNCS && USE_COLORFGBG 256 static char * 257 extract_fgbg(char *src, int *result) 258 { 259 char *dst = 0; 260 long value = strtol(src, &dst, 0); 261 262 if (dst == 0) { 263 dst = src; 264 } else if (value >= 0) { 265 *result = value; 266 } 267 while (*dst != 0 && *dst != ';') 268 dst++; 269 if (*dst == ';') 270 dst++; 271 return dst; 272 } 273 #endif 274 275 #define ReturnScreenError() _nc_set_screen(0); \ 276 returnCode(ERR) 277 278 /* OS-independent screen initializations */ 279 NCURSES_EXPORT(int) 280 NCURSES_SP_NAME(_nc_setupscreen) ( 281 #if NCURSES_SP_FUNCS 282 SCREEN **spp, 283 #endif 284 int slines, 285 int scolumns, 286 FILE *output, 287 bool filtered, 288 int slk_format) 289 { 290 char *env; 291 int bottom_stolen = 0; 292 ripoff_t *rop; 293 SCREEN *sp; 294 #ifndef USE_TERM_DRIVER 295 bool support_cookies = USE_XMC_SUPPORT; 296 #endif 297 298 T((T_CALLED("_nc_setupscreen(%d, %d, %p, %d, %d)"), 299 slines, scolumns, (void *) output, filtered, slk_format)); 300 301 assert(CURRENT_SCREEN == 0); /* has been reset in newterm() ! */ 302 303 #if NCURSES_SP_FUNCS 304 assert(spp != 0); 305 sp = *spp; 306 307 if (!sp) { 308 sp = _nc_alloc_screen_sp(); 309 *spp = sp; 310 } 311 if (!sp 312 || ((sp->_acs_map = typeCalloc(chtype, ACS_LEN)) == 0) 313 || ((sp->_screen_acs_map = typeCalloc(bool, ACS_LEN)) == 0)) { 314 ReturnScreenError(); 315 } 316 317 T(("created SP %p", (void *) sp)); 318 sp->_next_screen = _nc_screen_chain; 319 _nc_screen_chain = sp; 320 321 if ((sp->_current_attr = typeCalloc(NCURSES_CH_T, 1)) == 0) { 322 ReturnScreenError(); 323 } 324 #else 325 if (!_nc_alloc_screen() 326 || ((SP->_acs_map = typeCalloc(chtype, ACS_LEN)) == 0) 327 || ((SP->_screen_acs_map = typeCalloc(bool, ACS_LEN)) == 0)) { 328 returnCode(ERR); 329 } 330 331 T(("created SP %p", (void *) SP)); 332 333 sp = SP; /* fixup so SET_LINES and SET_COLS works */ 334 sp->_next_screen = _nc_screen_chain; 335 _nc_screen_chain = sp; 336 337 if ((sp->_current_attr = typeCalloc(NCURSES_CH_T, 1)) == 0) 338 returnCode(ERR); 339 #endif 340 341 /* 342 * We should always check the screensize, just in case. 343 */ 344 _nc_set_screen(sp); 345 sp->_term = cur_term; 346 #ifdef USE_TERM_DRIVER 347 TCBOf(sp)->csp = sp; 348 _nc_get_screensize(sp, sp->_term, &slines, &scolumns); 349 #else 350 _nc_get_screensize(sp, &slines, &scolumns); 351 #endif 352 SET_LINES(slines); 353 SET_COLS(scolumns); 354 355 T((T_CREATE("screen %s %dx%d"), 356 NCURSES_SP_NAME(termname) (NCURSES_SP_ARG), slines, scolumns)); 357 358 sp->_filtered = filtered; 359 360 /* implement filter mode */ 361 if (filtered) { 362 slines = 1; 363 SET_LINES(slines); 364 #ifdef USE_TERM_DRIVER 365 CallDriver(sp, setfilter); 366 #else 367 clear_screen = 0; 368 cursor_down = parm_down_cursor = 0; 369 cursor_address = 0; 370 cursor_up = parm_up_cursor = 0; 371 row_address = 0; 372 373 cursor_home = carriage_return; 374 #endif 375 T(("filter screensize %dx%d", slines, scolumns)); 376 } 377 #ifdef __DJGPP__ 378 T(("setting output mode to binary")); 379 fflush(output); 380 setmode(output, O_BINARY); 381 #endif 382 NCURSES_SP_NAME(_nc_set_buffer) (NCURSES_SP_ARGx output, TRUE); 383 sp->_lines = (NCURSES_SIZE_T) slines; 384 sp->_lines_avail = (NCURSES_SIZE_T) slines; 385 sp->_columns = (NCURSES_SIZE_T) scolumns; 386 sp->_ofp = output; 387 SP_PRE_INIT(sp); 388 SetNoPadding(sp); 389 390 #if NCURSES_EXT_FUNCS 391 sp->_default_color = FALSE; 392 sp->_has_sgr_39_49 = FALSE; 393 394 /* 395 * Set our assumption of the terminal's default foreground and background 396 * colors. The curs_color man-page states that we can assume that the 397 * background is black. The origin of this assumption appears to be 398 * terminals that displayed colored text, but no colored backgrounds, e.g., 399 * the first colored terminals around 1980. More recent ones with better 400 * technology can display not only colored backgrounds, but all 401 * combinations. So a terminal might be something other than "white" on 402 * black (green/black looks monochrome too), but black on white or even 403 * on ivory. 404 * 405 * White-on-black is the simplest thing to use for monochrome. Almost 406 * all applications that use color paint both text and background, so 407 * the distinction is moot. But a few do not - which is why we leave this 408 * configurable (a better solution is to use assume_default_colors() for 409 * the rare applications that do require that sort of appearance, since 410 * is appears that more users expect to be able to make a white-on-black 411 * or black-on-white display under control of the application than not). 412 */ 413 #ifdef USE_ASSUMED_COLOR 414 sp->_default_fg = COLOR_WHITE; 415 sp->_default_bg = COLOR_BLACK; 416 #else 417 sp->_default_fg = C_MASK; 418 sp->_default_bg = C_MASK; 419 #endif 420 421 /* 422 * Allow those assumed/default color assumptions to be overridden at 423 * runtime: 424 */ 425 if ((env = getenv("NCURSES_ASSUMED_COLORS")) != 0) { 426 int fg, bg; 427 char sep1, sep2; 428 int count = sscanf(env, "%d%c%d%c", &fg, &sep1, &bg, &sep2); 429 if (count >= 1) { 430 sp->_default_fg = ((fg >= 0 && fg < MaxColors) ? fg : C_MASK); 431 if (count >= 3) { 432 sp->_default_bg = ((bg >= 0 && bg < MaxColors) ? bg : C_MASK); 433 } 434 TR(TRACE_CHARPUT | TRACE_MOVE, 435 ("from environment assumed fg=%d, bg=%d", 436 sp->_default_fg, 437 sp->_default_bg)); 438 } 439 } 440 #if USE_COLORFGBG 441 /* 442 * If rxvt's $COLORFGBG variable is set, use it to specify the assumed 443 * default colors. Note that rxvt (mis)uses bold colors, equating a bold 444 * color to that value plus 8. We'll only use the non-bold color for now - 445 * decide later if it is worth having default attributes as well. 446 */ 447 if (getenv("COLORFGBG") != 0) { 448 char *p = getenv("COLORFGBG"); 449 TR(TRACE_CHARPUT | TRACE_MOVE, ("decoding COLORFGBG %s", p)); 450 p = extract_fgbg(p, &(sp->_default_fg)); 451 p = extract_fgbg(p, &(sp->_default_bg)); 452 if (*p) /* assume rxvt was compiled with xpm support */ 453 p = extract_fgbg(p, &(sp->_default_bg)); 454 TR(TRACE_CHARPUT | TRACE_MOVE, ("decoded fg=%d, bg=%d", 455 sp->_default_fg, sp->_default_bg)); 456 if (sp->_default_fg >= MaxColors) { 457 if (set_a_foreground != ABSENT_STRING 458 && !strcmp(set_a_foreground, "\033[3%p1%dm")) { 459 set_a_foreground = "\033[3%?%p1%{8}%>%t9%e%p1%d%;m"; 460 } else { 461 sp->_default_fg %= MaxColors; 462 } 463 } 464 if (sp->_default_bg >= MaxColors) { 465 if (set_a_background != ABSENT_STRING 466 && !strcmp(set_a_background, "\033[4%p1%dm")) { 467 set_a_background = "\033[4%?%p1%{8}%>%t9%e%p1%d%;m"; 468 } else { 469 sp->_default_bg %= MaxColors; 470 } 471 } 472 } 473 #endif 474 #endif /* NCURSES_EXT_FUNCS */ 475 476 sp->_maxclick = DEFAULT_MAXCLICK; 477 sp->_mouse_event = no_mouse_event; 478 sp->_mouse_inline = no_mouse_inline; 479 sp->_mouse_parse = no_mouse_parse; 480 sp->_mouse_resume = no_mouse_resume; 481 sp->_mouse_wrap = no_mouse_wrap; 482 sp->_mouse_fd = -1; 483 484 /* 485 * If we've no magic cookie support, we suppress attributes that xmc would 486 * affect, i.e., the attributes that affect the rendition of a space. 487 */ 488 sp->_ok_attributes = NCURSES_SP_NAME(termattrs) (NCURSES_SP_ARG); 489 if (NCURSES_SP_NAME(has_colors) (NCURSES_SP_ARG)) { 490 sp->_ok_attributes |= A_COLOR; 491 } 492 #ifdef USE_TERM_DRIVER 493 _nc_cookie_init(sp); 494 #else 495 #if USE_XMC_SUPPORT 496 /* 497 * If we have no magic-cookie support compiled-in, or if it is suppressed 498 * in the environment, reset the support-flag. 499 */ 500 if (magic_cookie_glitch >= 0) { 501 if (getenv("NCURSES_NO_MAGIC_COOKIE") != 0) { 502 support_cookies = FALSE; 503 } 504 } 505 #endif 506 507 if (!support_cookies && magic_cookie_glitch >= 0) { 508 T(("will disable attributes to work w/o magic cookies")); 509 } 510 511 if (magic_cookie_glitch > 0) { /* tvi, wyse */ 512 513 sp->_xmc_triggers = sp->_ok_attributes & ( 514 A_STANDOUT | 515 A_UNDERLINE | 516 A_REVERSE | 517 A_BLINK | 518 A_DIM | 519 A_BOLD | 520 A_INVIS | 521 A_PROTECT 522 ); 523 #if 0 524 /* 525 * We "should" treat colors as an attribute. The wyse350 (and its 526 * clones) appear to be the only ones that have both colors and magic 527 * cookies. 528 */ 529 if (has_colors()) { 530 sp->_xmc_triggers |= A_COLOR; 531 } 532 #endif 533 sp->_xmc_suppress = sp->_xmc_triggers & (chtype) ~(A_BOLD); 534 535 T(("magic cookie attributes %s", _traceattr(sp->_xmc_suppress))); 536 /* 537 * Supporting line-drawing may be possible. But make the regular 538 * video attributes work first. 539 */ 540 acs_chars = ABSENT_STRING; 541 ena_acs = ABSENT_STRING; 542 enter_alt_charset_mode = ABSENT_STRING; 543 exit_alt_charset_mode = ABSENT_STRING; 544 #if USE_XMC_SUPPORT 545 /* 546 * To keep the cookie support simple, suppress all of the optimization 547 * hooks except for clear_screen and the cursor addressing. 548 */ 549 if (support_cookies) { 550 clr_eol = ABSENT_STRING; 551 clr_eos = ABSENT_STRING; 552 set_attributes = ABSENT_STRING; 553 } 554 #endif 555 } else if (magic_cookie_glitch == 0) { /* hpterm */ 556 } 557 558 /* 559 * If magic cookies are not supported, cancel the strings that set 560 * video attributes. 561 */ 562 if (!support_cookies && magic_cookie_glitch >= 0) { 563 magic_cookie_glitch = ABSENT_NUMERIC; 564 set_attributes = ABSENT_STRING; 565 enter_blink_mode = ABSENT_STRING; 566 enter_bold_mode = ABSENT_STRING; 567 enter_dim_mode = ABSENT_STRING; 568 enter_reverse_mode = ABSENT_STRING; 569 enter_standout_mode = ABSENT_STRING; 570 enter_underline_mode = ABSENT_STRING; 571 } 572 573 /* initialize normal acs before wide, since we use mapping in the latter */ 574 #if !USE_WIDEC_SUPPORT 575 if (_nc_unicode_locale() && _nc_locale_breaks_acs(sp->_term)) { 576 acs_chars = NULL; 577 ena_acs = NULL; 578 enter_alt_charset_mode = NULL; 579 exit_alt_charset_mode = NULL; 580 set_attributes = NULL; 581 } 582 #endif 583 #endif 584 585 NCURSES_SP_NAME(_nc_init_acs) (NCURSES_SP_ARG); 586 #if USE_WIDEC_SUPPORT 587 _nc_init_wacs(); 588 589 sp->_screen_acs_fix = (_nc_unicode_locale() 590 && _nc_locale_breaks_acs(sp->_term)); 591 #endif 592 env = _nc_get_locale(); 593 sp->_legacy_coding = ((env == 0) 594 || !strcmp(env, "C") 595 || !strcmp(env, "POSIX")); 596 T(("legacy-coding %d", sp->_legacy_coding)); 597 598 sp->_nc_sp_idcok = TRUE; 599 sp->_nc_sp_idlok = FALSE; 600 601 sp->oldhash = 0; 602 sp->newhash = 0; 603 604 T(("creating newscr")); 605 NewScreen(sp) = NCURSES_SP_NAME(newwin) (NCURSES_SP_ARGx slines, scolumns, 606 0, 0); 607 if (NewScreen(sp) == 0) { 608 ReturnScreenError(); 609 } 610 T(("creating curscr")); 611 CurScreen(sp) = NCURSES_SP_NAME(newwin) (NCURSES_SP_ARGx slines, scolumns, 612 0, 0); 613 if (CurScreen(sp) == 0) { 614 ReturnScreenError(); 615 } 616 #if !USE_REENTRANT 617 newscr = NewScreen(sp); 618 curscr = CurScreen(sp); 619 #endif 620 #if USE_SIZECHANGE 621 sp->_resize = NCURSES_SP_NAME(resizeterm); 622 #endif 623 624 NewScreen(sp)->_clear = TRUE; 625 CurScreen(sp)->_clear = FALSE; 626 627 NCURSES_SP_NAME(def_shell_mode) (NCURSES_SP_ARG); 628 NCURSES_SP_NAME(def_prog_mode) (NCURSES_SP_ARG); 629 630 if (safe_ripoff_sp && safe_ripoff_sp != safe_ripoff_stack) { 631 for (rop = safe_ripoff_stack; 632 rop != safe_ripoff_sp && (rop - safe_ripoff_stack) < N_RIPS; 633 rop++) { 634 635 /* If we must simulate soft labels, grab off the line to be used. 636 We assume that we must simulate, if it is none of the standard 637 formats (4-4 or 3-2-3) for which there may be some hardware 638 support. */ 639 if (rop->hook == _nc_slk_initialize) { 640 if (!(NumLabels <= 0 || !SLK_STDFMT(slk_format))) { 641 continue; 642 } 643 } 644 if (rop->hook) { 645 int count; 646 WINDOW *w; 647 648 count = (rop->line < 0) ? -rop->line : rop->line; 649 T(("ripping off %i lines at %s", count, 650 ((rop->line < 0) 651 ? "bottom" 652 : "top"))); 653 654 w = NCURSES_SP_NAME(newwin) (NCURSES_SP_ARGx 655 count, scolumns, 656 ((rop->line < 0) 657 ? sp->_lines_avail - count 658 : 0), 659 0); 660 if (w) { 661 rop->win = w; 662 rop->hook(w, scolumns); 663 } else { 664 ReturnScreenError(); 665 } 666 if (rop->line < 0) { 667 bottom_stolen += count; 668 } else { 669 sp->_topstolen = (NCURSES_SIZE_T) (sp->_topstolen + count); 670 } 671 sp->_lines_avail = (NCURSES_SIZE_T) (sp->_lines_avail - count); 672 } 673 } 674 /* reset the stack */ 675 safe_ripoff_sp = safe_ripoff_stack; 676 } 677 678 T(("creating stdscr")); 679 assert((sp->_lines_avail + sp->_topstolen + bottom_stolen) == slines); 680 if ((StdScreen(sp) = NCURSES_SP_NAME(newwin) (NCURSES_SP_ARGx 681 sp->_lines_avail, 682 scolumns, 0, 0)) == 0) { 683 ReturnScreenError(); 684 } 685 SET_LINES(sp->_lines_avail); 686 #if !USE_REENTRANT 687 stdscr = StdScreen(sp); 688 #endif 689 sp->_prescreen = FALSE; 690 returnCode(OK); 691 } 692 693 #if NCURSES_SP_FUNCS 694 NCURSES_EXPORT(int) 695 _nc_setupscreen(int slines GCC_UNUSED, 696 int scolumns GCC_UNUSED, 697 FILE *output, 698 bool filtered, 699 int slk_format) 700 { 701 SCREEN *sp = 0; 702 int rc = NCURSES_SP_NAME(_nc_setupscreen) (&sp, 703 slines, 704 scolumns, 705 output, 706 filtered, 707 slk_format); 708 if (rc != OK) 709 _nc_set_screen(0); 710 return rc; 711 } 712 #endif 713 714 /* 715 * The internal implementation interprets line as the number of lines to rip 716 * off from the top or bottom. 717 */ 718 NCURSES_EXPORT(int) 719 NCURSES_SP_NAME(_nc_ripoffline) (NCURSES_SP_DCLx 720 int line, 721 int (*init) (WINDOW *, int)) 722 { 723 int code = ERR; 724 725 START_TRACE(); 726 T((T_CALLED("ripoffline(%p,%d,%p)"), (void *) SP_PARM, line, init)); 727 728 #if NCURSES_SP_FUNCS 729 if (SP_PARM != 0 && SP_PARM->_prescreen) 730 #endif 731 { 732 if (line == 0) { 733 code = OK; 734 } else { 735 if (safe_ripoff_sp == 0) 736 safe_ripoff_sp = safe_ripoff_stack; 737 if (safe_ripoff_sp < safe_ripoff_stack + N_RIPS) { 738 safe_ripoff_sp->line = line; 739 safe_ripoff_sp->hook = init; 740 (safe_ripoff_sp)++; 741 code = OK; 742 } 743 } 744 } 745 746 returnCode(code); 747 } 748 749 #if NCURSES_SP_FUNCS 750 NCURSES_EXPORT(int) 751 _nc_ripoffline(int line, int (*init) (WINDOW *, int)) 752 { 753 return NCURSES_SP_NAME(_nc_ripoffline) (CURRENT_SCREEN_PRE, line, init); 754 } 755 #endif 756 757 NCURSES_EXPORT(int) 758 NCURSES_SP_NAME(ripoffline) (NCURSES_SP_DCLx 759 int line, 760 int (*init) (WINDOW *, int)) 761 { 762 return NCURSES_SP_NAME(_nc_ripoffline) (NCURSES_SP_ARGx 763 (line < 0) ? -1 : 1, 764 init); 765 } 766 767 #if NCURSES_SP_FUNCS 768 NCURSES_EXPORT(int) 769 ripoffline(int line, int (*init) (WINDOW *, int)) 770 { 771 return NCURSES_SP_NAME(ripoffline) (CURRENT_SCREEN_PRE, line, init); 772 } 773 #endif 774