17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright (c) 1995, by Sun Microsystems, Inc.
247c478bd9Sstevel@tonic-gate  * All rights reserved.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*
28*1da57d55SToomas Soome  * newterm.c
297c478bd9Sstevel@tonic-gate  *
307c478bd9Sstevel@tonic-gate  * XCurses Library
317c478bd9Sstevel@tonic-gate  *
327c478bd9Sstevel@tonic-gate  * Copyright 1990, 1995 by Mortice Kern Systems Inc.  All rights reserved.
337c478bd9Sstevel@tonic-gate  *
347c478bd9Sstevel@tonic-gate  */
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate #ifdef M_RCSID
377c478bd9Sstevel@tonic-gate #ifndef lint
387c478bd9Sstevel@tonic-gate static char const rcsID[] = "$Header: /rd/src/libc/xcurses/rcs/newterm.c 1.15 1995/07/25 19:54:00 ant Exp $";
397c478bd9Sstevel@tonic-gate #endif
407c478bd9Sstevel@tonic-gate #endif
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate #include <private.h>
437c478bd9Sstevel@tonic-gate #include <m_wio.h>
447c478bd9Sstevel@tonic-gate #include <errno.h>
457c478bd9Sstevel@tonic-gate #include <signal.h>
467c478bd9Sstevel@tonic-gate #include <stdlib.h>
477c478bd9Sstevel@tonic-gate #include <string.h>
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate int LINES, COLS;
507c478bd9Sstevel@tonic-gate int COLORS, COLOR_PAIRS;
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate WINDOW *curscr;
537c478bd9Sstevel@tonic-gate WINDOW *stdscr;
547c478bd9Sstevel@tonic-gate SCREEN *__m_screen;
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate static short assume_one_line = FALSE;
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate /*
59*1da57d55SToomas Soome  * Assume terminal has only one screen line by restricting those
607c478bd9Sstevel@tonic-gate  * capabilities that assume more than one line.  This function must
61*1da57d55SToomas Soome  * be called before initscr() or newterm().
627c478bd9Sstevel@tonic-gate  *
637c478bd9Sstevel@tonic-gate  * This flag will reset after initscr() or newterm() so that subsequent
647c478bd9Sstevel@tonic-gate  * calls to newterm(), without a preceding call to filter(), will load
657c478bd9Sstevel@tonic-gate  * an unmodified terminal.  THIS IS NOT HISTORICAL PRACTICE, BUT DEEMED
667c478bd9Sstevel@tonic-gate  * USEFUL.
677c478bd9Sstevel@tonic-gate  */
687c478bd9Sstevel@tonic-gate void
filter(void)697c478bd9Sstevel@tonic-gate filter(void)
707c478bd9Sstevel@tonic-gate {
717c478bd9Sstevel@tonic-gate #ifdef M_CURSES_TRACE
727c478bd9Sstevel@tonic-gate 	__m_trace("filter(void)");
737c478bd9Sstevel@tonic-gate #endif
747c478bd9Sstevel@tonic-gate 	assume_one_line = TRUE;
757c478bd9Sstevel@tonic-gate 	__m_return_void("filter");
767c478bd9Sstevel@tonic-gate }
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate /*f
797c478bd9Sstevel@tonic-gate  * SIGTSTP Handler.
807c478bd9Sstevel@tonic-gate  */
817c478bd9Sstevel@tonic-gate void
tstp(signo)827c478bd9Sstevel@tonic-gate tstp(signo)
837c478bd9Sstevel@tonic-gate int signo;
847c478bd9Sstevel@tonic-gate {
857c478bd9Sstevel@tonic-gate #ifdef SIGTSTP
86*1da57d55SToomas Soome 	/* Only permit SIGTSTP if the curent process is the process
87*1da57d55SToomas Soome 	 * group leader.  If the process is not the current group
887c478bd9Sstevel@tonic-gate 	 * leader, then suspending the current process will suspend
897c478bd9Sstevel@tonic-gate 	 * other members of the process group, such as the parent
90*1da57d55SToomas Soome 	 * process.
917c478bd9Sstevel@tonic-gate 	 */
927c478bd9Sstevel@tonic-gate 	if (getpid() == getpgrp()) {
937c478bd9Sstevel@tonic-gate 		(void) endwin();
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate #ifdef SIG_UNBLOCK
967c478bd9Sstevel@tonic-gate {
977c478bd9Sstevel@tonic-gate 		sigset_t unblock;
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate 		(void) sigemptyset(&unblock);
1007c478bd9Sstevel@tonic-gate 		(void) sigaddset(&unblock, SIGTSTP);
1017c478bd9Sstevel@tonic-gate 		(void) sigprocmask(SIG_UNBLOCK, &unblock, (sigset_t *) 0);
1027c478bd9Sstevel@tonic-gate }
1037c478bd9Sstevel@tonic-gate #endif /* SIG_UNBLOCK */
1047c478bd9Sstevel@tonic-gate 		(void) signal(SIGTSTP, SIG_DFL);
1057c478bd9Sstevel@tonic-gate 		(void) kill(0, SIGTSTP);
1067c478bd9Sstevel@tonic-gate 	} else {
1077c478bd9Sstevel@tonic-gate 		(void) beep();
1087c478bd9Sstevel@tonic-gate 	}
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate 	(void) signal(SIGTSTP, tstp);
1117c478bd9Sstevel@tonic-gate 	(void) wrefresh(curscr);
1127c478bd9Sstevel@tonic-gate #else /* no SIGTSTP */
1137c478bd9Sstevel@tonic-gate 	(void) beep();
1147c478bd9Sstevel@tonic-gate #endif /* SIGTSTP */
1157c478bd9Sstevel@tonic-gate }
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate int __m_slk_format = -1;
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate /*
1207c478bd9Sstevel@tonic-gate  * Do real soft label key initialisation once setupterm() have been called
1217c478bd9Sstevel@tonic-gate  * to load the current terminal.  Determine whether the terminal supplies
1227c478bd9Sstevel@tonic-gate  * soft label keys, or whether we have to fake it by using the last line
1237c478bd9Sstevel@tonic-gate  * of a terminal screen.
1247c478bd9Sstevel@tonic-gate  */
1257c478bd9Sstevel@tonic-gate int
__m_slk_init(SCREEN * sp,int style)1267c478bd9Sstevel@tonic-gate __m_slk_init(SCREEN *sp, int style)
1277c478bd9Sstevel@tonic-gate {
1287c478bd9Sstevel@tonic-gate 	int code;
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate #ifdef M_CURSES_TRACE
1317c478bd9Sstevel@tonic-gate 	__m_trace("__m_slk_init(%d)", style );
1327c478bd9Sstevel@tonic-gate #endif
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate 	code = ERR;
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 	/* Does the terminal have a method to program the soft label key? */
1377c478bd9Sstevel@tonic-gate 	if (plab_norm != (char *) 0 || pkey_plab  != (char *) 0) {
1387c478bd9Sstevel@tonic-gate 		code = OK;
1397c478bd9Sstevel@tonic-gate 		goto done;
1407c478bd9Sstevel@tonic-gate 	}
141*1da57d55SToomas Soome 
1427c478bd9Sstevel@tonic-gate 	/* We have to fake it. */
1437c478bd9Sstevel@tonic-gate 	if (lines < 2)
1447c478bd9Sstevel@tonic-gate 		goto done;
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate 	sp->_slk._w = subwin(sp->_newscr, 1, 0, --lines, 0);
1477c478bd9Sstevel@tonic-gate 	if (sp->_slk._w == (WINDOW *) 0)
1487c478bd9Sstevel@tonic-gate 		goto done;
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate 	code = OK;
1517c478bd9Sstevel@tonic-gate done:
1527c478bd9Sstevel@tonic-gate 	return __m_return_code("__m_slk_init", code);
1537c478bd9Sstevel@tonic-gate }
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate /*
1567c478bd9Sstevel@tonic-gate  * The XCurses specification is unclear how ripoffline() would
1577c478bd9Sstevel@tonic-gate  * affect newterm().  We assume that it can't be used with newterm()
1587c478bd9Sstevel@tonic-gate  * and that it only affects initscr(), which is responsible for
1597c478bd9Sstevel@tonic-gate  * creating stdscr.
1607c478bd9Sstevel@tonic-gate  */
1617c478bd9Sstevel@tonic-gate static t_rip rip = { 0 };
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate /*
164*1da57d55SToomas Soome  * If line is positive (1), one line is removed from the beginning of
1657c478bd9Sstevel@tonic-gate  * stdscr; else if line is negative (-1), one line is removed from the end.
1667c478bd9Sstevel@tonic-gate  */
1677c478bd9Sstevel@tonic-gate int
ripoffline(int line,int (* init)(WINDOW *,int))1687c478bd9Sstevel@tonic-gate ripoffline(int line, int (*init)(WINDOW *, int))
1697c478bd9Sstevel@tonic-gate {
1707c478bd9Sstevel@tonic-gate 	int i;
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate #ifdef M_CURSES_TRACE
1737c478bd9Sstevel@tonic-gate 	__m_trace("ripoffline(%d, %p)", line, init);
1747c478bd9Sstevel@tonic-gate #endif
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate 	i = rip.top - rip.bottom;
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate 	if (line != 0 && i + 1 < M_CURSES_MAX_RIPOFFLINE) {
1797c478bd9Sstevel@tonic-gate 		rip.line[i].init = init;
1807c478bd9Sstevel@tonic-gate 		if (line < 0)
1817c478bd9Sstevel@tonic-gate 			rip.line[i].dy = --rip.bottom;
1827c478bd9Sstevel@tonic-gate 		else
1837c478bd9Sstevel@tonic-gate 			rip.line[i].dy = ++rip.top;
1847c478bd9Sstevel@tonic-gate 	}
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate 	return __m_return_code("ripoffline", OK);
1877c478bd9Sstevel@tonic-gate }
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate /*f
1907c478bd9Sstevel@tonic-gate  * Create a new terminal screen.  Used if a program is going to be sending
1917c478bd9Sstevel@tonic-gate  * output to more than one terminal.  It returns a SCREEN* for the terminal.
1927c478bd9Sstevel@tonic-gate  * The parameters are a terminal name, output FILE*, and input FILE*.  If
1937c478bd9Sstevel@tonic-gate  * the terminal name is null then $TERM is used.  The program must also
1947c478bd9Sstevel@tonic-gate  * call endwin() for each terminal being used before exiting from curses.
1957c478bd9Sstevel@tonic-gate  * If newterm() is called more than once for the same terminal, the first
1967c478bd9Sstevel@tonic-gate  * terminal referred to must be the last one for which endwin() is called.
1977c478bd9Sstevel@tonic-gate  */
198*1da57d55SToomas Soome SCREEN *
newterm(term,out_fp,in_fp)1997c478bd9Sstevel@tonic-gate newterm(term, out_fp, in_fp)
2007c478bd9Sstevel@tonic-gate char *term;
2017c478bd9Sstevel@tonic-gate FILE *out_fp, *in_fp;
2027c478bd9Sstevel@tonic-gate {
2037c478bd9Sstevel@tonic-gate 	WINDOW *w;
2047c478bd9Sstevel@tonic-gate 	t_wide_io *wio;
2057c478bd9Sstevel@tonic-gate 	SCREEN *sp, *osp;
2067c478bd9Sstevel@tonic-gate 	int i, n, y, errret;
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate #ifdef M_CURSES_TRACE
2097c478bd9Sstevel@tonic-gate 	__m_trace(
210*1da57d55SToomas Soome 		"newterm(%s, %p, %p)",
2117c478bd9Sstevel@tonic-gate 		term == (char *) 0 ? "NULL" : term, out_fp, in_fp
2127c478bd9Sstevel@tonic-gate 	);
2137c478bd9Sstevel@tonic-gate #endif
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 	/* Input stream should be unbuffered so that m_tfgetc() works
2167c478bd9Sstevel@tonic-gate 	 * correctly on BSD and SUN systems.
2177c478bd9Sstevel@tonic-gate 	 */
2187c478bd9Sstevel@tonic-gate 	(void) SETVBUF(in_fp, (char *) 0, _IONBF, BUFSIZ);
2197c478bd9Sstevel@tonic-gate #if 0
2207c478bd9Sstevel@tonic-gate /*
2217c478bd9Sstevel@tonic-gate  * Not sure whether we really want to concern ourselves with the output
2227c478bd9Sstevel@tonic-gate  * buffer scheme.  Might be best to leave it upto the application to
2237c478bd9Sstevel@tonic-gate  * deal with buffer schemes and when to perform flushes.
2247c478bd9Sstevel@tonic-gate  *
2257c478bd9Sstevel@tonic-gate  * MKS Vi uses MKS Curses and so must support the ability to switch in
2267c478bd9Sstevel@tonic-gate  * and out of Curses mode when switching from Vi to Ex and back.
2277c478bd9Sstevel@tonic-gate  * Problem is that in Vi mode you would prefer full buffered output to
2287c478bd9Sstevel@tonic-gate  * give updates a smoother appearance and Ex mode you require line
2297c478bd9Sstevel@tonic-gate  * buffered in order to see prompts and messages.
2307c478bd9Sstevel@tonic-gate  */
2317c478bd9Sstevel@tonic-gate 	(void) SETVBUF(out_fp, (char *) 0, _IOLBF, BUFSIZ);
2327c478bd9Sstevel@tonic-gate #endif
2337c478bd9Sstevel@tonic-gate 	errno = 0;
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate 	if (__m_setupterm(term, fileno(in_fp), fileno(out_fp), &errret)==ERR) {
2367c478bd9Sstevel@tonic-gate 		switch (errret) {
2377c478bd9Sstevel@tonic-gate 		case -1:
2387c478bd9Sstevel@tonic-gate 			errno = ENOMEM;
2397c478bd9Sstevel@tonic-gate 			break;
2407c478bd9Sstevel@tonic-gate 		case 2:
2417c478bd9Sstevel@tonic-gate 			errno = ENAMETOOLONG;
2427c478bd9Sstevel@tonic-gate 			break;
2437c478bd9Sstevel@tonic-gate 		case 0:
2447c478bd9Sstevel@tonic-gate 		default:
2457c478bd9Sstevel@tonic-gate 			errno = ENOENT;
2467c478bd9Sstevel@tonic-gate 			break;
2477c478bd9Sstevel@tonic-gate 		}
2487c478bd9Sstevel@tonic-gate 		goto error1;
2497c478bd9Sstevel@tonic-gate 	}
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate 	if (__m_doupdate_init())
2527c478bd9Sstevel@tonic-gate 		goto error1;
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate 	if ((sp = (SCREEN *) calloc(1, sizeof *sp)) == (SCREEN *) 0)
2557c478bd9Sstevel@tonic-gate 		goto error1;
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate 	sp->_if = in_fp;
2587c478bd9Sstevel@tonic-gate 	sp->_of = out_fp;
2597c478bd9Sstevel@tonic-gate 	sp->_term = cur_term;
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate 	sp->_unget._size = __m_decode_init((t_decode **) &sp->_decode);
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate 	/* Maximum length of a multbyte key sequence, including
2647c478bd9Sstevel@tonic-gate 	 * multibyte characters and terminal function keys.
2657c478bd9Sstevel@tonic-gate 	 */
2667c478bd9Sstevel@tonic-gate 	if (sp->_unget._size < MB_LEN_MAX)
2677c478bd9Sstevel@tonic-gate 		sp->_unget._size = MB_LEN_MAX;
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate 	sp->_unget._stack = calloc(
2707c478bd9Sstevel@tonic-gate 		(size_t) sp->_unget._size,  sizeof *sp->_unget._stack
2717c478bd9Sstevel@tonic-gate 	);
2727c478bd9Sstevel@tonic-gate 	if (sp->_unget._stack == (void *) 0)
2737c478bd9Sstevel@tonic-gate 		goto error2;
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate 	if ((wio = (t_wide_io *) calloc(1, sizeof *wio)) == (t_wide_io *) 0)
2767c478bd9Sstevel@tonic-gate 		goto error2;
2777c478bd9Sstevel@tonic-gate 
2787c478bd9Sstevel@tonic-gate 	/* Setup wide input for XCurses. */
2797c478bd9Sstevel@tonic-gate 	wio->get = (int (*)(void *)) wgetch;
2807c478bd9Sstevel@tonic-gate 	wio->unget = __xc_ungetc;
2817c478bd9Sstevel@tonic-gate 	wio->reset = __xc_clearerr;
2827c478bd9Sstevel@tonic-gate 	wio->iserror = __xc_ferror;
2837c478bd9Sstevel@tonic-gate 	wio->iseof = __xc_feof;
2847c478bd9Sstevel@tonic-gate 	sp->_in = wio;
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate 	if (assume_one_line) {
2877c478bd9Sstevel@tonic-gate 		/* Assume only one line. */
2887c478bd9Sstevel@tonic-gate 		lines = 1;
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate 		/* Disable capabilities that assume more than one line. */
2917c478bd9Sstevel@tonic-gate 		clear_screen =
2927c478bd9Sstevel@tonic-gate 		clr_eos =
2937c478bd9Sstevel@tonic-gate 		cursor_up =
2947c478bd9Sstevel@tonic-gate 		cursor_down =
2957c478bd9Sstevel@tonic-gate 		cursor_home =
2967c478bd9Sstevel@tonic-gate 		cursor_to_ll =
2977c478bd9Sstevel@tonic-gate 		cursor_address =
2987c478bd9Sstevel@tonic-gate 		row_address =
2997c478bd9Sstevel@tonic-gate 		parm_up_cursor =
3007c478bd9Sstevel@tonic-gate 		parm_down_cursor = (char *) 0;
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate 		/* Re-evaluate the cursor motion costs. */
3037c478bd9Sstevel@tonic-gate 		__m_mvcur_cost();
3047c478bd9Sstevel@tonic-gate 
3057c478bd9Sstevel@tonic-gate 		/* Reset flag for subsequent calls to newterm(). */
3067c478bd9Sstevel@tonic-gate 		assume_one_line = FALSE;
3077c478bd9Sstevel@tonic-gate 	}
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate 	if ((sp->_curscr = newwin(lines, columns, 0, 0)) == (WINDOW *) 0)
3107c478bd9Sstevel@tonic-gate 		goto error2;
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 	if ((sp->_newscr = newwin(lines, columns, 0, 0)) == (WINDOW *) 0)
3137c478bd9Sstevel@tonic-gate 		goto error2;
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 	sp->_hash = (unsigned long *) calloc(lines, sizeof *sp->_hash);
3167c478bd9Sstevel@tonic-gate 	if (sp->_hash == (unsigned long *) 0)
3177c478bd9Sstevel@tonic-gate 		goto error2;
3187c478bd9Sstevel@tonic-gate 
3197c478bd9Sstevel@tonic-gate 	if (0 <= __m_slk_format && __m_slk_init(sp, __m_slk_format) == ERR)
3207c478bd9Sstevel@tonic-gate 		goto error2;
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate 	/* doupdate() will perform the final screen preparations like
323*1da57d55SToomas Soome 	 * enter_ca_mode, reset_prog_mode() (to assert the termios
3247c478bd9Sstevel@tonic-gate 	 * changes), etc.
325*1da57d55SToomas Soome 	 */
3267c478bd9Sstevel@tonic-gate 	sp->_flags |= S_ENDWIN;
3277c478bd9Sstevel@tonic-gate 
3287c478bd9Sstevel@tonic-gate #ifdef SIGTSTP
3297c478bd9Sstevel@tonic-gate 	(void) signal(SIGTSTP, tstp);
330*1da57d55SToomas Soome #endif
3317c478bd9Sstevel@tonic-gate 	/* Assert that __m_screen is set to the new terminal. */
3327c478bd9Sstevel@tonic-gate 	osp = set_term(sp);
3337c478bd9Sstevel@tonic-gate 
3347c478bd9Sstevel@tonic-gate 	/* Disable echo in tty driver, Curses does software echo. */
3357c478bd9Sstevel@tonic-gate 	cur_term->_prog.c_lflag &= ~ECHO;
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate 	/* Enable mappnig of cr -> nl on input and nl -> crlf on output. */
3387c478bd9Sstevel@tonic-gate         cur_term->_prog.c_iflag |= ICRNL;
3397c478bd9Sstevel@tonic-gate         cur_term->_prog.c_oflag |= OPOST;
3407c478bd9Sstevel@tonic-gate #ifdef ONLCR
3417c478bd9Sstevel@tonic-gate         cur_term->_prog.c_oflag |= ONLCR;
3427c478bd9Sstevel@tonic-gate #endif
3437c478bd9Sstevel@tonic-gate 	cur_term->_flags |= __TERM_NL_IS_CRLF;
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate #ifdef TAB0
3467c478bd9Sstevel@tonic-gate 	/* Use real tabs. */
3477c478bd9Sstevel@tonic-gate 	cur_term->_prog.c_oflag &= ~(TAB1|TAB2|TAB3);
3487c478bd9Sstevel@tonic-gate #endif
3497c478bd9Sstevel@tonic-gate 
3507c478bd9Sstevel@tonic-gate 	(void) __m_tty_set(&cur_term->_prog);
3517c478bd9Sstevel@tonic-gate 	(void) __m_set_echo(1);
3527c478bd9Sstevel@tonic-gate 	(void) typeahead(fileno(in_fp));
3537c478bd9Sstevel@tonic-gate 
3547c478bd9Sstevel@tonic-gate 	if (stdscr == (WINDOW *) 0) {
3557c478bd9Sstevel@tonic-gate 		n = rip.top - rip.bottom;
3567c478bd9Sstevel@tonic-gate 		stdscr = newwin(lines - n, 0, rip.top, 0);
3577c478bd9Sstevel@tonic-gate 		if (stdscr == (WINDOW *) 0)
3587c478bd9Sstevel@tonic-gate 			goto error3;
3597c478bd9Sstevel@tonic-gate 
360*1da57d55SToomas Soome 		/* Create and initialise ripped off line windows.
3617c478bd9Sstevel@tonic-gate 		 * It is the application's responsiblity to free the
3627c478bd9Sstevel@tonic-gate 		 * windows when the application terminates.
3637c478bd9Sstevel@tonic-gate 		 */
3647c478bd9Sstevel@tonic-gate 		for (i = 0; i < n; ++i) {
3657c478bd9Sstevel@tonic-gate 			y = rip.line[i].dy;
3667c478bd9Sstevel@tonic-gate 			if (y < 0)
367*1da57d55SToomas Soome 				y += lines;
3687c478bd9Sstevel@tonic-gate 
3697c478bd9Sstevel@tonic-gate 			w = newwin(1, 0, y, 0);
3707c478bd9Sstevel@tonic-gate 			if (rip.line[i].init != (int (*)(WINDOW *, int)) 0)
3717c478bd9Sstevel@tonic-gate 				(void) (*rip.line[i].init)(w, columns);
3727c478bd9Sstevel@tonic-gate 		}
3737c478bd9Sstevel@tonic-gate 	}
3747c478bd9Sstevel@tonic-gate 
3757c478bd9Sstevel@tonic-gate 	return __m_return_pointer("newterm", sp);
3767c478bd9Sstevel@tonic-gate error3:
3777c478bd9Sstevel@tonic-gate 	(void) set_term(osp);
3787c478bd9Sstevel@tonic-gate error2:
3797c478bd9Sstevel@tonic-gate 	delscreen(sp);
3807c478bd9Sstevel@tonic-gate error1:
3817c478bd9Sstevel@tonic-gate 	return __m_return_pointer("newterm", (SCREEN *) 0);
3827c478bd9Sstevel@tonic-gate }
3837c478bd9Sstevel@tonic-gate 
3847c478bd9Sstevel@tonic-gate /*f
3857c478bd9Sstevel@tonic-gate  * Free storage associated with a screen structure.
3867c478bd9Sstevel@tonic-gate  * NOTE endwin() does not do this.
3877c478bd9Sstevel@tonic-gate  */
3887c478bd9Sstevel@tonic-gate void
delscreen(sp)3897c478bd9Sstevel@tonic-gate delscreen(sp)
3907c478bd9Sstevel@tonic-gate SCREEN *sp;
3917c478bd9Sstevel@tonic-gate {
3927c478bd9Sstevel@tonic-gate #ifdef M_CURSES_TRACE
3937c478bd9Sstevel@tonic-gate 	__m_trace("delscreen(%p)", sp);
3947c478bd9Sstevel@tonic-gate #endif
3957c478bd9Sstevel@tonic-gate 
3967c478bd9Sstevel@tonic-gate 	if (sp != (SCREEN *) 0) {
3977c478bd9Sstevel@tonic-gate 		if (sp->_slk._w != (WINDOW *) 0)
3987c478bd9Sstevel@tonic-gate 			(void) delwin(sp->_slk._w);
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate 		(void) delwin(sp->_newscr);
4017c478bd9Sstevel@tonic-gate 		(void) delwin(sp->_curscr);
4027c478bd9Sstevel@tonic-gate 		(void) del_curterm(sp->_term);
4037c478bd9Sstevel@tonic-gate 
4047c478bd9Sstevel@tonic-gate 		__m_decode_free((t_decode **) &sp->_decode);
4057c478bd9Sstevel@tonic-gate 
4067c478bd9Sstevel@tonic-gate 		if (sp->_hash != (unsigned long *) 0)
4077c478bd9Sstevel@tonic-gate 			free(sp->_hash);
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate 		if (sp->_unget._stack != (int *) 0)
4107c478bd9Sstevel@tonic-gate 			free(sp->_unget._stack);
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate 		if (sp->_in != (void *) 0)
4137c478bd9Sstevel@tonic-gate 			free(sp->_in);
4147c478bd9Sstevel@tonic-gate 
4157c478bd9Sstevel@tonic-gate 		free(sp);
4167c478bd9Sstevel@tonic-gate 	}
4177c478bd9Sstevel@tonic-gate 
4187c478bd9Sstevel@tonic-gate 	__m_return_void("delscreen");
4197c478bd9Sstevel@tonic-gate }
4207c478bd9Sstevel@tonic-gate 
4217c478bd9Sstevel@tonic-gate /*f
4227c478bd9Sstevel@tonic-gate  * Switch current terminal for Curses layer.
4237c478bd9Sstevel@tonic-gate  */
4247c478bd9Sstevel@tonic-gate SCREEN *
set_term(screen)4257c478bd9Sstevel@tonic-gate set_term(screen)
4267c478bd9Sstevel@tonic-gate SCREEN *screen;
4277c478bd9Sstevel@tonic-gate {
4287c478bd9Sstevel@tonic-gate     	SCREEN *osp = __m_screen;
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate #ifdef M_CURSES_TRACE
4317c478bd9Sstevel@tonic-gate 	__m_trace("set_term(%p)", screen);
4327c478bd9Sstevel@tonic-gate #endif
4337c478bd9Sstevel@tonic-gate 	if (screen != (SCREEN *) 0) {
4347c478bd9Sstevel@tonic-gate 		(void) set_curterm(screen->_term);
4357c478bd9Sstevel@tonic-gate 		curscr = screen->_curscr;
4367c478bd9Sstevel@tonic-gate 		__m_screen = screen;
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate 		LINES = lines;
4397c478bd9Sstevel@tonic-gate 		COLS = columns;
4407c478bd9Sstevel@tonic-gate 		COLORS = max_colors;
4417c478bd9Sstevel@tonic-gate 		COLOR_PAIRS = max_pairs;
4427c478bd9Sstevel@tonic-gate 	}
4437c478bd9Sstevel@tonic-gate 
4447c478bd9Sstevel@tonic-gate 	return __m_return_pointer("set_term", osp);
4457c478bd9Sstevel@tonic-gate }
4467c478bd9Sstevel@tonic-gate 
4477c478bd9Sstevel@tonic-gate int
typeahead(fd)4487c478bd9Sstevel@tonic-gate typeahead(fd)
4497c478bd9Sstevel@tonic-gate int fd;
4507c478bd9Sstevel@tonic-gate {
4517c478bd9Sstevel@tonic-gate #ifdef M_CURSES_TRACE
4527c478bd9Sstevel@tonic-gate 	__m_trace("typeahead(%d)", fd);
4537c478bd9Sstevel@tonic-gate #endif
4547c478bd9Sstevel@tonic-gate 
4557c478bd9Sstevel@tonic-gate 	__m_screen->_kfd = fd;
4567c478bd9Sstevel@tonic-gate 	__m_screen->_flags &= ~S_ISATTY;
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate 	if (fd != -1 && isatty(fd))
4597c478bd9Sstevel@tonic-gate 		__m_screen->_flags |= S_ISATTY;
4607c478bd9Sstevel@tonic-gate 
4617c478bd9Sstevel@tonic-gate 	return __m_return_code("typeahead", OK);
4627c478bd9Sstevel@tonic-gate }
4637c478bd9Sstevel@tonic-gate 
4647c478bd9Sstevel@tonic-gate int
__m_set_echo(bf)4657c478bd9Sstevel@tonic-gate __m_set_echo(bf)
4667c478bd9Sstevel@tonic-gate int bf;
4677c478bd9Sstevel@tonic-gate {
4687c478bd9Sstevel@tonic-gate 	int old;
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate 	old = (__m_screen->_flags & S_ECHO) == S_ECHO;
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate 	__m_screen->_flags &= ~S_ECHO;
4737c478bd9Sstevel@tonic-gate 	if (bf)
4747c478bd9Sstevel@tonic-gate 		__m_screen->_flags |= S_ECHO;
4757c478bd9Sstevel@tonic-gate 
4767c478bd9Sstevel@tonic-gate 	return old;
4777c478bd9Sstevel@tonic-gate }
4787c478bd9Sstevel@tonic-gate 
479