xref: /onnv-gate/usr/src/lib/libcurses/screen/newscreen.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate /*	Copyright (c) 1988 AT&T	*/
28*0Sstevel@tonic-gate /*	  All Rights Reserved	*/
29*0Sstevel@tonic-gate 
30*0Sstevel@tonic-gate /*
31*0Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
32*0Sstevel@tonic-gate  * The Regents of the University of California
33*0Sstevel@tonic-gate  * All Rights Reserved
34*0Sstevel@tonic-gate  *
35*0Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
36*0Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
37*0Sstevel@tonic-gate  * contributors.
38*0Sstevel@tonic-gate  */
39*0Sstevel@tonic-gate 
40*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
41*0Sstevel@tonic-gate 
42*0Sstevel@tonic-gate /*LINTLIBRARY*/
43*0Sstevel@tonic-gate 
44*0Sstevel@tonic-gate #include	<stdio.h>
45*0Sstevel@tonic-gate #include	<stdlib.h>
46*0Sstevel@tonic-gate #include	<string.h>
47*0Sstevel@tonic-gate #include	<sys/types.h>
48*0Sstevel@tonic-gate #include	"curses_inc.h"
49*0Sstevel@tonic-gate 
50*0Sstevel@tonic-gate #ifdef	_VR2_COMPAT_CODE
51*0Sstevel@tonic-gate extern	char	_endwin;
52*0Sstevel@tonic-gate #endif	/* _VR2_COMPAT_CODE */
53*0Sstevel@tonic-gate 
54*0Sstevel@tonic-gate /* 1200 is put at the 0th location since 0 is probably a mistake. */
55*0Sstevel@tonic-gate static long    baud_convert[] = {
56*0Sstevel@tonic-gate 		    1200, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
57*0Sstevel@tonic-gate 		    1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800,
58*0Sstevel@tonic-gate 		    115200, 153600, 230400, 307200, 460800
59*0Sstevel@tonic-gate 		};
60*0Sstevel@tonic-gate 
61*0Sstevel@tonic-gate static	char	isfilter = 0;
62*0Sstevel@tonic-gate static	int	_chk_trm(void);
63*0Sstevel@tonic-gate static	void	_forget(void);
64*0Sstevel@tonic-gate 
65*0Sstevel@tonic-gate /*
66*0Sstevel@tonic-gate  * newscreen sets up a terminal and returns a pointer to the terminal
67*0Sstevel@tonic-gate  * structure or NULL in case of an error.  The parameters are:
68*0Sstevel@tonic-gate  *	type: terminal type
69*0Sstevel@tonic-gate  *	lsize, csize, tabsize: physical sizes
70*0Sstevel@tonic-gate  *	infptr, outfptr: input and output stdio stream file pointers
71*0Sstevel@tonic-gate  */
72*0Sstevel@tonic-gate 
73*0Sstevel@tonic-gate SCREEN	*
74*0Sstevel@tonic-gate newscreen(char *type, int lsize, int csize, int tabsize,
75*0Sstevel@tonic-gate 	FILE *outfptr, FILE *infptr)
76*0Sstevel@tonic-gate {
77*0Sstevel@tonic-gate 	int		old_lines = LINES, old_cols = COLS, retcode;
78*0Sstevel@tonic-gate #ifndef	_IOFBF
79*0Sstevel@tonic-gate 	char	*sobuf;
80*0Sstevel@tonic-gate #endif	/* _IOBUF */
81*0Sstevel@tonic-gate 	WINDOW	*old_curscr = curscr;
82*0Sstevel@tonic-gate 	SCREEN	*old = SP;
83*0Sstevel@tonic-gate 	TERMINAL	*old_term = cur_term;
84*0Sstevel@tonic-gate 
85*0Sstevel@tonic-gate #ifdef	DEBUG
86*0Sstevel@tonic-gate 	if (outf == NULL) {
87*0Sstevel@tonic-gate 		outf = fopen("trace", "w");
88*0Sstevel@tonic-gate 		if (outf == NULL) {
89*0Sstevel@tonic-gate 			perror("trace");
90*0Sstevel@tonic-gate 			exit(-1);
91*0Sstevel@tonic-gate 		}
92*0Sstevel@tonic-gate 		setbuf(outf, (char *)NULL);
93*0Sstevel@tonic-gate 	}
94*0Sstevel@tonic-gate 
95*0Sstevel@tonic-gate 	if (outf)
96*0Sstevel@tonic-gate 		fprintf(outf, "NEWTERM(type=%s, outfptr=%x %d, infptr=%x %d) "
97*0Sstevel@tonic-gate 		    "isatty(2) %d, getenv %s\n", type, outfptr,
98*0Sstevel@tonic-gate 		    fileno(outfptr), infptr, fileno(infptr), isatty(2),
99*0Sstevel@tonic-gate 		    getenv("TERM"));
100*0Sstevel@tonic-gate #endif	/* DEBUG */
101*0Sstevel@tonic-gate 
102*0Sstevel@tonic-gate 
103*0Sstevel@tonic-gate 	/* read in terminfo file */
104*0Sstevel@tonic-gate 
105*0Sstevel@tonic-gate 	if (setupterm(type, fileno(outfptr), &retcode) != 0)
106*0Sstevel@tonic-gate 		goto err2;
107*0Sstevel@tonic-gate 
108*0Sstevel@tonic-gate 	/* the max length of a multi-byte character */
109*0Sstevel@tonic-gate 	_csmax = (cswidth[0] > cswidth[1]+1 ?
110*0Sstevel@tonic-gate 	    (cswidth[0] > cswidth[2]+1 ? cswidth[0] : cswidth[2]+1) :
111*0Sstevel@tonic-gate 	    (cswidth[1] > cswidth[2] ? cswidth[1]+1 : cswidth[2]+1));
112*0Sstevel@tonic-gate 	if (_csmax > CSMAX)
113*0Sstevel@tonic-gate 		goto err2;
114*0Sstevel@tonic-gate 	/* the max length of a multi-column character */
115*0Sstevel@tonic-gate 	_scrmax = _curs_scrwidth[0] > _curs_scrwidth[1] ?
116*0Sstevel@tonic-gate 	    (_curs_scrwidth[0] > _curs_scrwidth[2] ? _curs_scrwidth[0] :
117*0Sstevel@tonic-gate 	    _curs_scrwidth[2]) : (_curs_scrwidth[1] > _curs_scrwidth[2] ?
118*0Sstevel@tonic-gate 	    _curs_scrwidth[1] : _curs_scrwidth[2]);
119*0Sstevel@tonic-gate 	/* true multi-byte/multi-column case */
120*0Sstevel@tonic-gate 	_mbtrue = (_csmax > 1 || _scrmax > 1);
121*0Sstevel@tonic-gate 
122*0Sstevel@tonic-gate 	if ((curs_errno = _chk_trm()) != -1) {
123*0Sstevel@tonic-gate 		(void) strcpy(curs_parm_err, cur_term->_termname);
124*0Sstevel@tonic-gate 		goto err2;
125*0Sstevel@tonic-gate 	}
126*0Sstevel@tonic-gate 
127*0Sstevel@tonic-gate 	/* use calloc because almost everything needs to be zero */
128*0Sstevel@tonic-gate 	if ((SP = (SCREEN *) calloc(1, sizeof (SCREEN))) == NULL)
129*0Sstevel@tonic-gate 		goto err1;
130*0Sstevel@tonic-gate 
131*0Sstevel@tonic-gate 	SP->term_file = outfptr;
132*0Sstevel@tonic-gate 	SP->input_file = infptr;
133*0Sstevel@tonic-gate 
134*0Sstevel@tonic-gate 	/*
135*0Sstevel@tonic-gate 	 * The default is echo, for upward compatibility, but we do
136*0Sstevel@tonic-gate 	 * all echoing in curses to avoid problems with the tty driver
137*0Sstevel@tonic-gate 	 * echoing things during critical sections.
138*0Sstevel@tonic-gate 	 */
139*0Sstevel@tonic-gate 
140*0Sstevel@tonic-gate 	SP->fl_echoit = 1;
141*0Sstevel@tonic-gate 
142*0Sstevel@tonic-gate 	/* set some fields for cur_term structure */
143*0Sstevel@tonic-gate 
144*0Sstevel@tonic-gate 	(void) typeahead(fileno(infptr));
145*0Sstevel@tonic-gate 	(void) tinputfd(fileno(infptr));
146*0Sstevel@tonic-gate 
147*0Sstevel@tonic-gate 	/*
148*0Sstevel@tonic-gate 	 * We use LINES instead of the SP variable and a local variable because
149*0Sstevel@tonic-gate 	 * slk_init and rip_init update the LINES value and application code
150*0Sstevel@tonic-gate 	 * may look at the value of LINES in the function called by rip_init.
151*0Sstevel@tonic-gate 	 */
152*0Sstevel@tonic-gate 
153*0Sstevel@tonic-gate 	/* LINTED */
154*0Sstevel@tonic-gate 	LINES = SP->lsize = lsize > 0 ? lsize : lines;
155*0Sstevel@tonic-gate 
156*0Sstevel@tonic-gate 	/* force the output to be buffered */
157*0Sstevel@tonic-gate #ifdef	_IOFBF
158*0Sstevel@tonic-gate 	(void) setvbuf(outfptr, (char *)NULL, _IOFBF, 0);
159*0Sstevel@tonic-gate #else	/* _IOFBF */
160*0Sstevel@tonic-gate 	if ((sobuf = malloc(BUFSIZ)) == NULL) {
161*0Sstevel@tonic-gate 		curs_errno = CURS_BAD_MALLOC;
162*0Sstevel@tonic-gate #ifdef	DEBUG
163*0Sstevel@tonic-gate 		strcpy(curs_parm_err, "newscreen");
164*0Sstevel@tonic-gate #endif	/* DEBUG */
165*0Sstevel@tonic-gate 	}
166*0Sstevel@tonic-gate 	setbuf(outfptr, sobuf);
167*0Sstevel@tonic-gate #endif	/* _IOFBF */
168*0Sstevel@tonic-gate 
169*0Sstevel@tonic-gate #ifdef	SYSV
170*0Sstevel@tonic-gate 	SP->baud = baud_convert[_BRS(PROGTTYS)];
171*0Sstevel@tonic-gate #else	/* SYSV */
172*0Sstevel@tonic-gate 	SP->baud = baud_convert[_BR(PROGTTY)];
173*0Sstevel@tonic-gate #endif	/* SYSV */
174*0Sstevel@tonic-gate 
175*0Sstevel@tonic-gate 	/* figure out how much each terminal capability costs */
176*0Sstevel@tonic-gate 	_init_costs();
177*0Sstevel@tonic-gate 
178*0Sstevel@tonic-gate 	/* initialize the array of alternate characters */
179*0Sstevel@tonic-gate 	(void) init_acs();
180*0Sstevel@tonic-gate 
181*0Sstevel@tonic-gate 	SP->tcap = cur_term;
182*0Sstevel@tonic-gate 
183*0Sstevel@tonic-gate 	/* set tty settings to something reasonable for us */
184*0Sstevel@tonic-gate #ifdef	SYSV
185*0Sstevel@tonic-gate 	PROGTTYS.c_lflag &= ~ECHO;
186*0Sstevel@tonic-gate 	PROGTTYS.c_lflag |= ISIG;
187*0Sstevel@tonic-gate 	PROGTTYS.c_oflag &= ~(OCRNL|ONLCR); /* why would anyone set OCRNL? */
188*0Sstevel@tonic-gate #else	/* SYSV */
189*0Sstevel@tonic-gate 	PROGTTY.sg_flags &= ~(RAW|ECHO|CRMOD);
190*0Sstevel@tonic-gate #endif	/* SYSV */
191*0Sstevel@tonic-gate 
192*0Sstevel@tonic-gate 	(void) cbreak();
193*0Sstevel@tonic-gate 
194*0Sstevel@tonic-gate 	/* LINTED */
195*0Sstevel@tonic-gate 	COLS = SP->csize = csize > 0 ? csize : columns;
196*0Sstevel@tonic-gate 	if (tabsize == 0)
197*0Sstevel@tonic-gate 		tabsize = (init_tabs == -1) ? 8 : init_tabs;
198*0Sstevel@tonic-gate 	/* LINTED */
199*0Sstevel@tonic-gate 	SP->tsize = (short)tabsize;
200*0Sstevel@tonic-gate #ifdef	DEBUG
201*0Sstevel@tonic-gate 	if (outf)
202*0Sstevel@tonic-gate 		fprintf(outf, "LINES = %d, COLS = %d\n", LINES, COLS);
203*0Sstevel@tonic-gate #endif	/* DEBUG */
204*0Sstevel@tonic-gate 
205*0Sstevel@tonic-gate 	if ((curscr = SP->cur_scr = newwin(LINES, COLS, 0, 0)) == NULL)
206*0Sstevel@tonic-gate 		goto err;
207*0Sstevel@tonic-gate 
208*0Sstevel@tonic-gate 	SP->fl_endwin = 2;
209*0Sstevel@tonic-gate #ifdef	_VR2_COMPAT_CODE
210*0Sstevel@tonic-gate 	_endwin = FALSE;
211*0Sstevel@tonic-gate #endif	/* _VR2_COMPAT_CODE */
212*0Sstevel@tonic-gate 	curscr->_sync = TRUE;
213*0Sstevel@tonic-gate 
214*0Sstevel@tonic-gate 	/*
215*0Sstevel@tonic-gate 	 * This will tell _quick_echo(if it's ever called), whether
216*0Sstevel@tonic-gate 	 * _quick_echo should let wrefresh handle everything.
217*0Sstevel@tonic-gate 	 */
218*0Sstevel@tonic-gate 
219*0Sstevel@tonic-gate 	if (ceol_standout_glitch || (magic_cookie_glitch >= 0) ||
220*0Sstevel@tonic-gate 	    tilde_glitch || (transparent_underline && erase_overstrike)) {
221*0Sstevel@tonic-gate 		curscr->_flags |= _CANT_BE_IMMED;
222*0Sstevel@tonic-gate 	}
223*0Sstevel@tonic-gate 	if (!(SP->virt_scr = newwin(LINES, COLS, 0, 0)))
224*0Sstevel@tonic-gate 		goto err;
225*0Sstevel@tonic-gate 	_virtscr = SP->virt_scr;
226*0Sstevel@tonic-gate 
227*0Sstevel@tonic-gate 	SP->virt_scr->_clear = FALSE;
228*0Sstevel@tonic-gate 
229*0Sstevel@tonic-gate 	/* video mark map for cookie terminals */
230*0Sstevel@tonic-gate 
231*0Sstevel@tonic-gate 	if (ceol_standout_glitch || (magic_cookie_glitch >= 0)) {
232*0Sstevel@tonic-gate 		int	i, nc;
233*0Sstevel@tonic-gate 		char	**marks;
234*0Sstevel@tonic-gate 
235*0Sstevel@tonic-gate 		if ((marks = (char **)calloc((unsigned)LINES,
236*0Sstevel@tonic-gate 		    sizeof (char *))) == NULL)
237*0Sstevel@tonic-gate 			goto err;
238*0Sstevel@tonic-gate 		SP->_mks = marks;
239*0Sstevel@tonic-gate 		nc = (COLS / BITSPERBYTE) + (COLS % BITSPERBYTE ? 1 : 0);
240*0Sstevel@tonic-gate 		if ((*marks = (char *)calloc((unsigned)nc * LINES,
241*0Sstevel@tonic-gate 		    sizeof (char))) == NULL)
242*0Sstevel@tonic-gate 			goto err;
243*0Sstevel@tonic-gate 		for (i = LINES - 1; i-- > 0; ++marks)
244*0Sstevel@tonic-gate 			*(marks + 1) = *marks + nc;
245*0Sstevel@tonic-gate 	}
246*0Sstevel@tonic-gate 
247*0Sstevel@tonic-gate 	/* hash tables for lines */
248*0Sstevel@tonic-gate 	if ((SP->cur_hash = (int *)calloc((unsigned)2 * LINES,
249*0Sstevel@tonic-gate 	    sizeof (int))) == NULL)
250*0Sstevel@tonic-gate 		goto err;
251*0Sstevel@tonic-gate 	SP->virt_hash = SP->cur_hash + LINES;
252*0Sstevel@tonic-gate 
253*0Sstevel@tonic-gate 	/* adjust the screen size if soft labels and/or ripoffline are used */
254*0Sstevel@tonic-gate 	if (_slk_init)
255*0Sstevel@tonic-gate 		(*_slk_init)();
256*0Sstevel@tonic-gate 	if (_rip_init)
257*0Sstevel@tonic-gate 		(*_rip_init)();
258*0Sstevel@tonic-gate 
259*0Sstevel@tonic-gate 	if ((SP->std_scr = newwin(LINES, COLS, 0, 0)) == NULL) {
260*0Sstevel@tonic-gate 		/* free all the storage allocated above and return NULL */
261*0Sstevel@tonic-gate err:
262*0Sstevel@tonic-gate 		delscreen(SP);
263*0Sstevel@tonic-gate 		COLS = old_cols;
264*0Sstevel@tonic-gate 		curscr = old_curscr;
265*0Sstevel@tonic-gate 		LINES = old_lines;
266*0Sstevel@tonic-gate err1:
267*0Sstevel@tonic-gate 		SP = old;
268*0Sstevel@tonic-gate 
269*0Sstevel@tonic-gate 		curs_errno = CURS_BAD_MALLOC;
270*0Sstevel@tonic-gate #ifdef	DEBUG
271*0Sstevel@tonic-gate 		strcpy(curs_parm_err, "newscreen");
272*0Sstevel@tonic-gate #endif	/* DEBUG */
273*0Sstevel@tonic-gate 
274*0Sstevel@tonic-gate err2:
275*0Sstevel@tonic-gate 		cur_term = old_term;
276*0Sstevel@tonic-gate 		return (NULL);
277*0Sstevel@tonic-gate 	}
278*0Sstevel@tonic-gate #ifdef	DEBUG
279*0Sstevel@tonic-gate 	if (outf)
280*0Sstevel@tonic-gate 		fprintf(outf, "SP %x, stdscr %x, curscr %x\n",
281*0Sstevel@tonic-gate 		    SP, SP->std_scr, curscr);
282*0Sstevel@tonic-gate #endif	/* DEBUG */
283*0Sstevel@tonic-gate 
284*0Sstevel@tonic-gate 	if (((SP->imode = (enter_insert_mode && exit_insert_mode)) != 0) &&
285*0Sstevel@tonic-gate 	    ((SP->dmode = (enter_delete_mode && exit_delete_mode)) != 0)) {
286*0Sstevel@tonic-gate 		if (strcmp(enter_insert_mode, enter_delete_mode) == 0)
287*0Sstevel@tonic-gate 			SP->sid_equal = TRUE;
288*0Sstevel@tonic-gate 		if (strcmp(exit_insert_mode, exit_delete_mode) == 0)
289*0Sstevel@tonic-gate 			SP->eid_equal = TRUE;
290*0Sstevel@tonic-gate 	}
291*0Sstevel@tonic-gate 	SP->ichok = (SP->imode || insert_character || parm_ich);
292*0Sstevel@tonic-gate 	SP->dchok = (delete_character || parm_dch);
293*0Sstevel@tonic-gate 
294*0Sstevel@tonic-gate 	stdscr = SP->std_scr;
295*0Sstevel@tonic-gate 	TABSIZE = SP->tsize;
296*0Sstevel@tonic-gate 
297*0Sstevel@tonic-gate 	return (SP);
298*0Sstevel@tonic-gate }
299*0Sstevel@tonic-gate 
300*0Sstevel@tonic-gate /*
301*0Sstevel@tonic-gate  * check if terminal have capabilities to do basic cursor movements and
302*0Sstevel@tonic-gate  * screen clearing
303*0Sstevel@tonic-gate  */
304*0Sstevel@tonic-gate static int
305*0Sstevel@tonic-gate _chk_trm(void)
306*0Sstevel@tonic-gate {
307*0Sstevel@tonic-gate 	short	error_num = -1;
308*0Sstevel@tonic-gate #ifdef	DEBUG
309*0Sstevel@tonic-gate 	if (outf)
310*0Sstevel@tonic-gate 		fprintf(outf, "chk_trm().\n");
311*0Sstevel@tonic-gate #endif	/* DEBUG */
312*0Sstevel@tonic-gate 
313*0Sstevel@tonic-gate 	if (generic_type)
314*0Sstevel@tonic-gate 		error_num = CURS_UNKNOWN;
315*0Sstevel@tonic-gate 	else {
316*0Sstevel@tonic-gate 		if (isfilter) {
317*0Sstevel@tonic-gate 			_forget();
318*0Sstevel@tonic-gate 			/* Only need to move left or right on current line */
319*0Sstevel@tonic-gate 			if (!(cursor_left || carriage_return ||
320*0Sstevel@tonic-gate 			    column_address || parm_left_cursor)) {
321*0Sstevel@tonic-gate 				goto out_stupid;
322*0Sstevel@tonic-gate 			}
323*0Sstevel@tonic-gate 		} else {
324*0Sstevel@tonic-gate 			if ((hard_copy || over_strike) ||
325*0Sstevel@tonic-gate 			/* some way to move up, down, left */
326*0Sstevel@tonic-gate 			    (!(cursor_address) &&
327*0Sstevel@tonic-gate 			    (!((cursor_up || cursor_home) && cursor_down &&
328*0Sstevel@tonic-gate 			    (cursor_left || carriage_return)))) ||
329*0Sstevel@tonic-gate 			    (!clear_screen)) {
330*0Sstevel@tonic-gate out_stupid:
331*0Sstevel@tonic-gate 				error_num = CURS_STUPID;
332*0Sstevel@tonic-gate 			}
333*0Sstevel@tonic-gate 		}
334*0Sstevel@tonic-gate 	}
335*0Sstevel@tonic-gate 	return (error_num);
336*0Sstevel@tonic-gate }
337*0Sstevel@tonic-gate 
338*0Sstevel@tonic-gate int
339*0Sstevel@tonic-gate filter(void)
340*0Sstevel@tonic-gate {
341*0Sstevel@tonic-gate 	isfilter = 1;
342*0Sstevel@tonic-gate 	return (OK);
343*0Sstevel@tonic-gate }
344*0Sstevel@tonic-gate 
345*0Sstevel@tonic-gate /*
346*0Sstevel@tonic-gate  * if (for some reason) user assumes that terminal has only one line,
347*0Sstevel@tonic-gate  * disable all capabilities that deal with non-horizontal cursor movement
348*0Sstevel@tonic-gate  */
349*0Sstevel@tonic-gate static void
350*0Sstevel@tonic-gate _forget(void)
351*0Sstevel@tonic-gate {
352*0Sstevel@tonic-gate 	row_address = cursor_address = clear_screen = parm_down_cursor =
353*0Sstevel@tonic-gate 	    cursor_up = cursor_down = NULL;
354*0Sstevel@tonic-gate 	cursor_home = carriage_return;
355*0Sstevel@tonic-gate 	lines = 1;
356*0Sstevel@tonic-gate }
357