1/**************************************************************************** 2 * Copyright (c) 1998-2012,2013 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_newterm.c 38** 39** The newterm() function. 40** 41*/ 42 43#include <curses.priv.h> 44 45#ifndef CUR 46#define CUR SP_TERMTYPE 47#endif 48 49#include <tic.h> 50 51MODULE_ID("$Id: lib_newterm.c,v 1.90 2013/09/28 21:02:56 tom Exp $") 52 53#ifdef USE_TERM_DRIVER 54#define NumLabels InfoOf(SP_PARM).numlabels 55#else 56#define NumLabels num_labels 57#endif 58 59#ifndef ONLCR /* Allows compilation under the QNX 4.2 OS */ 60#define ONLCR 0 61#endif 62 63/* 64 * SVr4/XSI Curses specify that hardware echo is turned off in initscr, and not 65 * restored during the curses session. The library simulates echo in software. 66 * (The behavior is unspecified if the application enables hardware echo). 67 * 68 * The newterm function also initializes terminal settings, and since initscr 69 * is supposed to behave as if it calls newterm, we do it here. 70 */ 71static NCURSES_INLINE int 72_nc_initscr(NCURSES_SP_DCL0) 73{ 74 int result = ERR; 75 TERMINAL *term = TerminalOf(SP_PARM); 76 77 /* for extended XPG4 conformance requires cbreak() at this point */ 78 /* (SVr4 curses does this anyway) */ 79 if (NCURSES_SP_NAME(cbreak) (NCURSES_SP_ARG) == OK) { 80 TTY buf; 81 82 buf = term->Nttyb; 83#ifdef TERMIOS 84 buf.c_lflag &= (unsigned) ~(ECHO | ECHONL); 85 buf.c_iflag &= (unsigned) ~(ICRNL | INLCR | IGNCR); 86 buf.c_oflag &= (unsigned) ~(ONLCR); 87#elif HAVE_SGTTY_H 88 buf.sg_flags &= ~(ECHO | CRMOD); 89#else 90 memset(&buf, 0, sizeof(buf)); 91#endif 92 result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf); 93 if (result == OK) 94 term->Nttyb = buf; 95 } 96 return result; 97} 98 99/* 100 * filter() has to be called before either initscr() or newterm(), so there is 101 * apparently no way to make this flag apply to some terminals and not others, 102 * aside from possibly delaying a filter() call until some terminals have been 103 * initialized. 104 */ 105NCURSES_EXPORT(void) 106NCURSES_SP_NAME(filter) (NCURSES_SP_DCL0) 107{ 108 START_TRACE(); 109 T((T_CALLED("filter(%p)"), (void *) SP_PARM)); 110#if NCURSES_SP_FUNCS 111 if (IsPreScreen(SP_PARM)) { 112 SP_PARM->_filtered = TRUE; 113 } 114#else 115 _nc_prescreen.filter_mode = TRUE; 116#endif 117 returnVoid; 118} 119 120#if NCURSES_SP_FUNCS 121NCURSES_EXPORT(void) 122filter(void) 123{ 124 START_TRACE(); 125 T((T_CALLED("filter()"))); 126 _nc_prescreen.filter_mode = TRUE; 127 returnVoid; 128} 129#endif 130 131#if NCURSES_EXT_FUNCS 132/* 133 * An extension, allowing the application to open a new screen without 134 * requiring it to also be filtered. 135 */ 136NCURSES_EXPORT(void) 137NCURSES_SP_NAME(nofilter) (NCURSES_SP_DCL0) 138{ 139 START_TRACE(); 140 T((T_CALLED("nofilter(%p)"), (void *) SP_PARM)); 141#if NCURSES_SP_FUNCS 142 if (IsPreScreen(SP_PARM)) { 143 SP_PARM->_filtered = FALSE; 144 } 145#else 146 _nc_prescreen.filter_mode = FALSE; 147#endif 148 returnVoid; 149} 150 151#if NCURSES_SP_FUNCS 152NCURSES_EXPORT(void) 153nofilter(void) 154{ 155 START_TRACE(); 156 T((T_CALLED("nofilter()"))); 157 _nc_prescreen.filter_mode = FALSE; 158 returnVoid; 159} 160#endif 161#endif /* NCURSES_EXT_FUNCS */ 162 163NCURSES_EXPORT(SCREEN *) 164NCURSES_SP_NAME(newterm) (NCURSES_SP_DCLx 165 NCURSES_CONST char *name, 166 FILE *ofp, 167 FILE *ifp) 168{ 169 int value; 170 int errret; 171 SCREEN *result = 0; 172 SCREEN *current; 173 TERMINAL *its_term; 174 FILE *_ofp = ofp ? ofp : stdout; 175 FILE *_ifp = ifp ? ifp : stdin; 176 int cols; 177 int slk_format; 178 int filter_mode; 179 TERMINAL *new_term = 0; 180 181 START_TRACE(); 182 T((T_CALLED("newterm(%p, \"%s\", %p,%p)"), 183 (void *) SP_PARM, 184 (name ? name : ""), 185 (void *) ofp, 186 (void *) ifp)); 187 188#if NCURSES_SP_FUNCS 189 assert(SP_PARM != 0); 190 if (SP_PARM == 0) 191 returnSP(SP_PARM); 192#endif 193 194 _nc_init_pthreads(); 195 _nc_lock_global(curses); 196 197 current = CURRENT_SCREEN; 198 its_term = (current ? current->_term : 0); 199 200 INIT_TERM_DRIVER(); 201 /* this loads the capability entry, then sets LINES and COLS */ 202 if ( 203#if NCURSES_SP_FUNCS 204 SP_PARM->_prescreen && 205#endif 206 TINFO_SETUP_TERM(&new_term, name, 207 fileno(_ofp), &errret, FALSE) != ERR) { 208 209 _nc_set_screen(0); 210#ifdef USE_TERM_DRIVER 211 assert(new_term != 0); 212#endif 213 214#if NCURSES_SP_FUNCS 215 slk_format = SP_PARM->slk_format; 216 filter_mode = SP_PARM->_filtered; 217#else 218 slk_format = _nc_globals.slk_format; 219 filter_mode = _nc_prescreen.filter_mode; 220#endif 221 222 /* 223 * This actually allocates the screen structure, and saves the original 224 * terminal settings. 225 */ 226 if (NCURSES_SP_NAME(_nc_setupscreen) ( 227#if NCURSES_SP_FUNCS 228 &SP_PARM, 229#endif 230 *(ptrLines(SP_PARM)), 231 *(ptrCols(SP_PARM)), 232 _ofp, 233 filter_mode, 234 slk_format) == ERR) { 235 _nc_set_screen(current); 236 result = 0; 237 } else { 238#ifdef USE_TERM_DRIVER 239 TERMINAL_CONTROL_BLOCK *TCB; 240#elif !NCURSES_SP_FUNCS 241 _nc_set_screen(CURRENT_SCREEN); 242#endif 243 assert(SP_PARM != 0); 244 cols = *(ptrCols(SP_PARM)); 245#ifdef USE_TERM_DRIVER 246 _nc_set_screen(SP_PARM); 247 TCB = (TERMINAL_CONTROL_BLOCK *) new_term; 248 TCB->csp = SP_PARM; 249#endif 250 /* 251 * In setupterm() we did a set_curterm(), but it was before we set 252 * CURRENT_SCREEN. So the "current" screen's terminal pointer was 253 * overwritten with a different terminal. Later, in 254 * _nc_setupscreen(), we set CURRENT_SCREEN and the terminal 255 * pointer in the new screen. 256 * 257 * Restore the terminal-pointer for the pre-existing screen, if 258 * any. 259 */ 260 if (current) 261 current->_term = its_term; 262 263#ifdef USE_TERM_DRIVER 264 SP_PARM->_term = new_term; 265#else 266 new_term = SP_PARM->_term; 267#endif 268 269 /* allow user to set maximum escape delay from the environment */ 270 if ((value = _nc_getenv_num("ESCDELAY")) >= 0) { 271 NCURSES_SP_NAME(set_escdelay) (NCURSES_SP_ARGx value); 272 } 273 274 /* if the terminal type has real soft labels, set those up */ 275 if (slk_format && NumLabels > 0 && SLK_STDFMT(slk_format)) 276 _nc_slk_initialize(StdScreen(SP_PARM), cols); 277 278 SP_PARM->_ifd = fileno(_ifp); 279 NCURSES_SP_NAME(typeahead) (NCURSES_SP_ARGx fileno(_ifp)); 280#ifdef TERMIOS 281 SP_PARM->_use_meta = ((new_term->Ottyb.c_cflag & CSIZE) == CS8 && 282 !(new_term->Ottyb.c_iflag & ISTRIP)) || 283 USE_KLIBC_KBD; 284#else 285 SP_PARM->_use_meta = FALSE; 286#endif 287 SP_PARM->_endwin = FALSE; 288#ifndef USE_TERM_DRIVER 289 /* 290 * Check whether we can optimize scrolling under dumb terminals in 291 * case we do not have any of these capabilities, scrolling 292 * optimization will be useless. 293 */ 294 SP_PARM->_scrolling = ((scroll_forward && scroll_reverse) || 295 ((parm_rindex || 296 parm_insert_line || 297 insert_line) && 298 (parm_index || 299 parm_delete_line || 300 delete_line))); 301#endif 302 303 NCURSES_SP_NAME(baudrate) (NCURSES_SP_ARG); /* sets a field in the screen structure */ 304 305 SP_PARM->_keytry = 0; 306 307 /* compute movement costs so we can do better move optimization */ 308#ifdef USE_TERM_DRIVER 309 TCBOf(SP_PARM)->drv->scinit(SP_PARM); 310#else /* ! USE_TERM_DRIVER */ 311 /* 312 * Check for mismatched graphic-rendition capabilities. Most SVr4 313 * terminfo trees contain entries that have rmul or rmso equated to 314 * sgr0 (Solaris curses copes with those entries). We do this only 315 * for curses, since many termcap applications assume that 316 * smso/rmso and smul/rmul are paired, and will not function 317 * properly if we remove rmso or rmul. Curses applications 318 * shouldn't be looking at this detail. 319 */ 320#define SGR0_TEST(mode) (mode != 0) && (exit_attribute_mode == 0 || strcmp(mode, exit_attribute_mode)) 321 SP_PARM->_use_rmso = SGR0_TEST(exit_standout_mode); 322 SP_PARM->_use_rmul = SGR0_TEST(exit_underline_mode); 323#if USE_ITALIC 324 SP_PARM->_use_ritm = SGR0_TEST(exit_italics_mode); 325#endif 326 327 /* compute movement costs so we can do better move optimization */ 328 _nc_mvcur_init(); 329 330 /* initialize terminal to a sane state */ 331 _nc_screen_init(); 332#endif /* USE_TERM_DRIVER */ 333 334 /* Initialize the terminal line settings. */ 335 _nc_initscr(NCURSES_SP_ARG); 336 337 _nc_signal_handler(TRUE); 338 result = SP_PARM; 339 } 340 } 341 _nc_unlock_global(curses); 342 returnSP(result); 343} 344 345#if NCURSES_SP_FUNCS 346NCURSES_EXPORT(SCREEN *) 347newterm(NCURSES_CONST char *name, FILE *ofp, FILE *ifp) 348{ 349 return NCURSES_SP_NAME(newterm) (CURRENT_SCREEN_PRE, name, ofp, ifp); 350} 351#endif 352