xref: /openbsd-src/lib/libcurses/base/lib_set_term.c (revision bcc05361ef768670d0c5fa5affad379a9b45d34d)
1 /*	$OpenBSD: lib_set_term.c,v 1.3 1999/03/11 21:03:55 millert Exp $	*/
2 
3 /****************************************************************************
4  * Copyright (c) 1998 Free Software Foundation, Inc.                        *
5  *                                                                          *
6  * Permission is hereby granted, free of charge, to any person obtaining a  *
7  * copy of this software and associated documentation files (the            *
8  * "Software"), to deal in the Software without restriction, including      *
9  * without limitation the rights to use, copy, modify, merge, publish,      *
10  * distribute, distribute with modifications, sublicense, and/or sell       *
11  * copies of the Software, and to permit persons to whom the Software is    *
12  * furnished to do so, subject to the following conditions:                 *
13  *                                                                          *
14  * The above copyright notice and this permission notice shall be included  *
15  * in all copies or substantial portions of the Software.                   *
16  *                                                                          *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
20  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
21  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
22  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
23  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
24  *                                                                          *
25  * Except as contained in this notice, the name(s) of the above copyright   *
26  * holders shall not be used in advertising or otherwise to promote the     *
27  * sale, use or other dealings in this Software without prior written       *
28  * authorization.                                                           *
29  ****************************************************************************/
30 
31 /****************************************************************************
32  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
33  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
34  ****************************************************************************/
35 
36 /*
37 **	lib_set_term.c
38 **
39 **	The routine set_term().
40 **
41 */
42 
43 #include <curses.priv.h>
44 
45 #include <term.h>	/* cur_term */
46 
47 MODULE_ID("$From: lib_set_term.c,v 1.45 1999/03/06 22:29:13 tom Exp $")
48 
49 SCREEN * set_term(SCREEN *screen)
50 {
51 SCREEN	*oldSP;
52 
53 	T((T_CALLED("set_term(%p)"), screen));
54 
55 	oldSP = SP;
56 	_nc_set_screen(screen);
57 
58 	set_curterm(SP->_term);
59 	curscr      = SP->_curscr;
60 	newscr      = SP->_newscr;
61 	stdscr      = SP->_stdscr;
62 	COLORS      = SP->_color_count;
63 	COLOR_PAIRS = SP->_pair_count;
64 	memcpy(acs_map, SP->_acs_map, sizeof(chtype)*ACS_LEN);
65 
66 	T((T_RETURN("%p"), oldSP));
67 	return(oldSP);
68 }
69 
70 static void _nc_free_keytry(struct tries *kt)
71 {
72 	if (kt != 0) {
73 		_nc_free_keytry(kt->child);
74 		_nc_free_keytry(kt->sibling);
75 		free(kt);
76 	}
77 }
78 
79 /*
80  * Free the storage associated with the given SCREEN sp.
81  */
82 void delscreen(SCREEN *sp)
83 {
84 	SCREEN **scan = &_nc_screen_chain;
85 
86 	T((T_CALLED("delscreen(%p)"), sp));
87 
88 	while(*scan)
89 	{
90 	    if (*scan == sp)
91 	    {
92 		*scan = sp->_next_screen;
93 		break;
94 	    }
95 	    scan = &(*scan)->_next_screen;
96 	}
97 
98 	_nc_freewin(sp->_curscr);
99 	_nc_freewin(sp->_newscr);
100 	_nc_freewin(sp->_stdscr);
101 	_nc_free_keytry(sp->_keytry);
102 	_nc_free_keytry(sp->_key_ok);
103 
104 	FreeIfNeeded(sp->_color_table);
105 	FreeIfNeeded(sp->_color_pairs);
106 
107 	FreeIfNeeded(sp->oldhash);
108 	FreeIfNeeded(sp->newhash);
109 
110 	del_curterm(sp->_term);
111 
112 	free(sp);
113 
114 	/*
115 	 * If this was the current screen, reset everything that the
116 	 * application might try to use (except cur_term, which may have
117 	 * multiple references in different screens).
118 	 */
119 	if (sp == SP) {
120 		curscr = 0;
121 		newscr = 0;
122 		stdscr = 0;
123 		COLORS = 0;
124 		COLOR_PAIRS = 0;
125 		_nc_set_screen(0);
126 	}
127 	returnVoid;
128 }
129 
130 static ripoff_t rippedoff[5];
131 static ripoff_t *rsp = rippedoff;
132 #define N_RIPS SIZEOF(rippedoff)
133 
134 static bool no_mouse_event (SCREEN *sp GCC_UNUSED) { return FALSE; }
135 static bool no_mouse_inline(SCREEN *sp GCC_UNUSED) { return FALSE; }
136 static bool no_mouse_parse (int code   GCC_UNUSED) { return TRUE; }
137 static void no_mouse_resume(SCREEN *sp GCC_UNUSED) { }
138 static void no_mouse_wrap  (SCREEN *sp GCC_UNUSED) { }
139 
140 int _nc_setupscreen(short slines, short const scolumns, FILE *output)
141 /* OS-independent screen initializations */
142 {
143 int	bottom_stolen = 0;
144 size_t	i;
145 
146         assert(SP==0); /* has been reset in newterm() ! */
147 	if (!_nc_alloc_screen())
148 		return ERR;
149 
150 	SP->_next_screen = _nc_screen_chain;
151 	_nc_screen_chain = SP;
152 
153 	_nc_set_buffer(output, TRUE);
154 	SP->_term        = cur_term;
155 	SP->_lines       = slines;
156 	SP->_lines_avail = slines;
157 	SP->_columns     = scolumns;
158 	SP->_cursrow     = -1;
159 	SP->_curscol     = -1;
160 	SP->_nl          = TRUE;
161 	SP->_raw         = FALSE;
162 	SP->_cbreak      = 0;
163 	SP->_echo        = TRUE;
164 	SP->_fifohead    = -1;
165 	SP->_endwin      = TRUE;
166 	SP->_ofp         = output;
167 	SP->_cursor      = -1;	/* cannot know real cursor shape */
168 #ifdef NCURSES_NO_PADDING
169 	SP->_no_padding  = getenv("NCURSES_NO_PADDING") != 0;
170 #endif
171 
172 	SP->_maxclick     = DEFAULT_MAXCLICK;
173 	SP->_mouse_event  = no_mouse_event;
174 	SP->_mouse_inline = no_mouse_inline;
175 	SP->_mouse_parse  = no_mouse_parse;
176 	SP->_mouse_resume = no_mouse_resume;
177 	SP->_mouse_wrap   = no_mouse_wrap;
178 	SP->_mouse_fd     = -1;
179 
180 	/* initialize the panel hooks */
181 	SP->_panelHook.top_panel = (struct panel*)0;
182 	SP->_panelHook.bottom_panel = (struct panel*)0;
183 	SP->_panelHook.stdscr_pseudo_panel = (struct panel*)0;
184 
185 	/*
186 	 * If we've no magic cookie support, we suppress attributes that xmc
187 	 * would affect, i.e., the attributes that affect the rendition of a
188 	 * space.  Note that this impacts the alternate character set mapping
189 	 * as well.
190 	 */
191 	if (magic_cookie_glitch > 0) {
192 
193 		SP->_xmc_triggers = termattrs() & (
194 				A_ALTCHARSET |
195 				A_BLINK |
196 				A_BOLD |
197 				A_REVERSE |
198 				A_STANDOUT |
199 				A_UNDERLINE
200 				);
201 		SP->_xmc_suppress = SP->_xmc_triggers & (chtype)~(A_BOLD);
202 
203 		T(("magic cookie attributes %s", _traceattr(SP->_xmc_suppress)));
204 #if USE_XMC_SUPPORT
205 		/*
206 		 * To keep this simple, suppress all of the optimization hooks
207 		 * except for clear_screen and the cursor addressing.
208 		 */
209 		clr_eol = 0;
210 		clr_eos = 0;
211 		set_attributes = 0;
212 #else
213 		magic_cookie_glitch = -1;
214 		acs_chars = 0;
215 #endif
216 	}
217 	_nc_init_acs();
218 	memcpy(SP->_acs_map, acs_map, sizeof(chtype)*ACS_LEN);
219 
220 	_nc_idcok = TRUE;
221 	_nc_idlok = FALSE;
222 
223 	_nc_windows = 0; /* no windows yet */
224 
225 	SP->oldhash = 0;
226 	SP->newhash = 0;
227 
228 	T(("creating newscr"));
229 	if ((newscr = newwin(slines, scolumns, 0, 0)) == 0)
230 		return ERR;
231 
232 	T(("creating curscr"));
233 	if ((curscr = newwin(slines, scolumns, 0, 0)) == 0)
234 		return ERR;
235 
236 	SP->_newscr = newscr;
237 	SP->_curscr = curscr;
238 #if USE_SIZECHANGE
239 	SP->_resize = resizeterm;
240 #endif
241 
242 	newscr->_clear = TRUE;
243 	curscr->_clear = FALSE;
244 
245 	for (i=0, rsp = rippedoff; rsp->line && (i < N_RIPS); rsp++, i++) {
246 	  if (rsp->hook) {
247 	      WINDOW *w;
248 	      int count = (rsp->line < 0) ? -rsp->line : rsp->line;
249 
250 	      if (rsp->line < 0) {
251 		  w = newwin(count,scolumns,SP->_lines_avail - count,0);
252 		  if (w) {
253 		      rsp->w = w;
254 		      rsp->hook(w, scolumns);
255 		      bottom_stolen += count;
256 		  }
257 		  else
258 		    return ERR;
259 	      } else {
260 		  w = newwin(count,scolumns, 0, 0);
261 		  if (w) {
262 		      rsp->w = w;
263 		      rsp->hook(w, scolumns);
264 		      SP->_topstolen += count;
265 		  }
266 		  else
267 		    return ERR;
268 	      }
269 	      SP->_lines_avail -= count;
270 	  }
271 	  rsp->line = 0;
272 	}
273 	/* reset the stack */
274 	rsp = rippedoff;
275 
276 	T(("creating stdscr"));
277 	assert ((SP->_lines_avail + SP->_topstolen + bottom_stolen) == slines);
278 	if ((stdscr = newwin(LINES = SP->_lines_avail, scolumns, 0, 0)) == 0)
279 		return ERR;
280 	SP->_stdscr = stdscr;
281 
282 	def_shell_mode();
283 	def_prog_mode();
284 
285 	return OK;
286 }
287 
288 /* The internal implementation interprets line as the number of
289    lines to rip off from the top or bottom.
290    */
291 int
292 _nc_ripoffline(int line, int (*init)(WINDOW *,int))
293 {
294     if (line == 0)
295 	return(OK);
296 
297     if (rsp >= rippedoff + N_RIPS)
298 	return(ERR);
299 
300     rsp->line = line;
301     rsp->hook = init;
302     rsp->w    = 0;
303     rsp++;
304 
305     return(OK);
306 }
307 
308 int
309 ripoffline(int line, int (*init)(WINDOW *, int))
310 {
311     T((T_CALLED("ripoffline(%d,%p)"), line, init));
312 
313     if (line == 0)
314 	returnCode(OK);
315 
316     returnCode(_nc_ripoffline ((line<0) ? -1 : 1, init));
317 }
318