xref: /openbsd-src/lib/libcurses/base/lib_set_term.c (revision 92dd1ec0a89df25171bc5d61a3d95ea1a68cef0b)
1 /*	$OpenBSD: lib_set_term.c,v 1.1 1999/01/18 19:09:59 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 
38 /*
39 **	lib_set_term.c
40 **
41 **	The routine set_term().
42 **
43 */
44 
45 #include <curses.priv.h>
46 
47 #include <term.h>	/* cur_term */
48 
49 MODULE_ID("$From: lib_set_term.c,v 1.43 1998/11/08 00:58:25 tom Exp $")
50 
51 SCREEN * set_term(SCREEN *screen)
52 {
53 SCREEN	*oldSP;
54 
55 	T((T_CALLED("set_term(%p)"), screen));
56 
57 	oldSP = SP;
58 	_nc_set_screen(screen);
59 
60 	set_curterm(SP->_term);
61 	curscr      = SP->_curscr;
62 	newscr      = SP->_newscr;
63 	stdscr      = SP->_stdscr;
64 	COLORS      = SP->_color_count;
65 	COLOR_PAIRS = SP->_pair_count;
66 	memcpy(acs_map, SP->_acs_map, sizeof(chtype)*ACS_LEN);
67 
68 	T((T_RETURN("%p"), oldSP));
69 	return(oldSP);
70 }
71 
72 static void _nc_free_keytry(struct tries *kt)
73 {
74 	if (kt != 0) {
75 		_nc_free_keytry(kt->child);
76 		_nc_free_keytry(kt->sibling);
77 		free(kt);
78 	}
79 }
80 
81 /*
82  * Free the storage associated with the given SCREEN sp.
83  */
84 void delscreen(SCREEN *sp)
85 {
86 	SCREEN **scan = &_nc_screen_chain;
87 
88 	T((T_CALLED("delscreen(%p)"), sp));
89 
90 	while(*scan)
91 	{
92 	    if (*scan == sp)
93 	    {
94 		*scan = sp->_next_screen;
95 		break;
96 	    }
97 	    scan = &(*scan)->_next_screen;
98 	}
99 
100 	_nc_freewin(sp->_curscr);
101 	_nc_freewin(sp->_newscr);
102 	_nc_freewin(sp->_stdscr);
103 	_nc_free_keytry(sp->_keytry);
104 	_nc_free_keytry(sp->_key_ok);
105 
106 	FreeIfNeeded(sp->_color_table);
107 	FreeIfNeeded(sp->_color_pairs);
108 
109 	FreeIfNeeded(sp->oldhash);
110 	FreeIfNeeded(sp->newhash);
111 
112 	del_curterm(sp->_term);
113 
114 	free(sp);
115 
116 	/*
117 	 * If this was the current screen, reset everything that the
118 	 * application might try to use (except cur_term, which may have
119 	 * multiple references in different screens).
120 	 */
121 	if (sp == SP) {
122 		curscr = 0;
123 		newscr = 0;
124 		stdscr = 0;
125 		COLORS = 0;
126 		COLOR_PAIRS = 0;
127 		_nc_set_screen(0);
128 	}
129 	returnVoid;
130 }
131 
132 static ripoff_t rippedoff[5];
133 static ripoff_t *rsp = rippedoff;
134 #define N_RIPS SIZEOF(rippedoff)
135 
136 static bool no_mouse_event (SCREEN *sp GCC_UNUSED) { return FALSE; }
137 static bool no_mouse_inline(SCREEN *sp GCC_UNUSED) { return FALSE; }
138 static bool no_mouse_parse (int code   GCC_UNUSED) { return TRUE; }
139 static void no_mouse_resume(SCREEN *sp GCC_UNUSED) { }
140 static void no_mouse_wrap  (SCREEN *sp GCC_UNUSED) { }
141 
142 int _nc_setupscreen(short slines, short const scolumns, FILE *output)
143 /* OS-independent screen initializations */
144 {
145 int	bottom_stolen = 0;
146 size_t	i;
147 
148         assert(SP==0); /* has been reset in newterm() ! */
149 	if (!_nc_alloc_screen())
150 		return ERR;
151 
152 	SP->_next_screen = _nc_screen_chain;
153 	_nc_screen_chain = SP;
154 
155 	_nc_set_buffer(output, TRUE);
156 	SP->_term        = cur_term;
157 	SP->_lines       = slines;
158 	SP->_lines_avail = slines;
159 	SP->_columns     = scolumns;
160 	SP->_cursrow     = -1;
161 	SP->_curscol     = -1;
162 	SP->_nl          = TRUE;
163 	SP->_raw         = FALSE;
164 	SP->_cbreak      = FALSE;
165 	SP->_echo        = TRUE;
166 	SP->_fifohead    = -1;
167 	SP->_endwin      = TRUE;
168 	SP->_ofp         = output;
169 	SP->_cursor      = -1;	/* cannot know real cursor shape */
170 #ifdef NCURSES_NO_PADDING
171 	SP->_no_padding  = getenv("NCURSES_NO_PADDING") != 0;
172 #endif
173 
174 	SP->_maxclick     = DEFAULT_MAXCLICK;
175 	SP->_mouse_event  = no_mouse_event;
176 	SP->_mouse_inline = no_mouse_inline;
177 	SP->_mouse_parse  = no_mouse_parse;
178 	SP->_mouse_resume = no_mouse_resume;
179 	SP->_mouse_wrap   = no_mouse_wrap;
180 	SP->_mouse_fd     = -1;
181 
182 	/* initialize the panel hooks */
183 	SP->_panelHook.top_panel = (struct panel*)0;
184 	SP->_panelHook.bottom_panel = (struct panel*)0;
185 	SP->_panelHook.stdscr_pseudo_panel = (struct panel*)0;
186 
187 	/*
188 	 * If we've no magic cookie support, we suppress attributes that xmc
189 	 * would affect, i.e., the attributes that affect the rendition of a
190 	 * space.  Note that this impacts the alternate character set mapping
191 	 * as well.
192 	 */
193 	if (magic_cookie_glitch > 0) {
194 
195 		SP->_xmc_triggers = termattrs() & (
196 				A_ALTCHARSET |
197 				A_BLINK |
198 				A_BOLD |
199 				A_REVERSE |
200 				A_STANDOUT |
201 				A_UNDERLINE
202 				);
203 		SP->_xmc_suppress = SP->_xmc_triggers & (chtype)~(A_BOLD);
204 
205 		T(("magic cookie attributes %s", _traceattr(SP->_xmc_suppress)));
206 #if USE_XMC_SUPPORT
207 		/*
208 		 * To keep this simple, suppress all of the optimization hooks
209 		 * except for clear_screen and the cursor addressing.
210 		 */
211 		clr_eol = 0;
212 		clr_eos = 0;
213 		set_attributes = 0;
214 #else
215 		magic_cookie_glitch = -1;
216 		acs_chars = 0;
217 #endif
218 	}
219 	init_acs();
220 	memcpy(SP->_acs_map, acs_map, sizeof(chtype)*ACS_LEN);
221 
222 	_nc_idcok = TRUE;
223 	_nc_idlok = FALSE;
224 
225 	_nc_windows = 0; /* no windows yet */
226 
227 	SP->oldhash = 0;
228 	SP->newhash = 0;
229 
230 	T(("creating newscr"));
231 	if ((newscr = newwin(slines, scolumns, 0, 0)) == 0)
232 		return ERR;
233 
234 	T(("creating curscr"));
235 	if ((curscr = newwin(slines, scolumns, 0, 0)) == 0)
236 		return ERR;
237 
238 	SP->_newscr = newscr;
239 	SP->_curscr = curscr;
240 #if USE_SIZECHANGE
241 	SP->_resize = resizeterm;
242 #endif
243 
244 	newscr->_clear = TRUE;
245 	curscr->_clear = FALSE;
246 
247 	for (i=0, rsp = rippedoff; rsp->line && (i < N_RIPS); rsp++, i++) {
248 	  if (rsp->hook) {
249 	      WINDOW *w;
250 	      int count = (rsp->line < 0) ? -rsp->line : rsp->line;
251 
252 	      if (rsp->line < 0) {
253 		  w = newwin(count,scolumns,SP->_lines_avail - count,0);
254 		  if (w) {
255 		      rsp->w = w;
256 		      rsp->hook(w, scolumns);
257 		      bottom_stolen += count;
258 		  }
259 		  else
260 		    return ERR;
261 	      } else {
262 		  w = newwin(count,scolumns, 0, 0);
263 		  if (w) {
264 		      rsp->w = w;
265 		      rsp->hook(w, scolumns);
266 		      SP->_topstolen += count;
267 		  }
268 		  else
269 		    return ERR;
270 	      }
271 	      SP->_lines_avail -= count;
272 	  }
273 	  rsp->line = 0;
274 	}
275 	/* reset the stack */
276 	rsp = rippedoff;
277 
278 	T(("creating stdscr"));
279 	assert ((SP->_lines_avail + SP->_topstolen + bottom_stolen) == slines);
280 	if ((stdscr = newwin(LINES = SP->_lines_avail, scolumns, 0, 0)) == 0)
281 		return ERR;
282 	SP->_stdscr = stdscr;
283 
284 	def_shell_mode();
285 	def_prog_mode();
286 
287 	return OK;
288 }
289 
290 /* The internal implementation interprets line as the number of
291    lines to rip off from the top or bottom.
292    */
293 int
294 _nc_ripoffline(int line, int (*init)(WINDOW *,int))
295 {
296     if (line == 0)
297 	return(OK);
298 
299     if (rsp >= rippedoff + N_RIPS)
300 	return(ERR);
301 
302     rsp->line = line;
303     rsp->hook = init;
304     rsp->w    = 0;
305     rsp++;
306 
307     return(OK);
308 }
309 
310 int
311 ripoffline(int line, int (*init)(WINDOW *, int))
312 {
313     T((T_CALLED("ripoffline(%d,%p)"), line, init));
314 
315     if (line == 0)
316 	returnCode(OK);
317 
318     returnCode(_nc_ripoffline ((line<0) ? -1 : 1, init));
319 }
320