xref: /openbsd-src/lib/libcurses/base/lib_set_term.c (revision 4b107ee47ccf17c9f1ad6db8a59eb142776341c8)
1 /*	$OpenBSD: lib_set_term.c,v 1.7 2000/03/10 01:35:02 millert Exp $	*/
2 
3 /****************************************************************************
4  * Copyright (c) 1998,1999,2000 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 #include <tic.h>
47 
48 MODULE_ID("$From: lib_set_term.c,v 1.50 2000/02/13 00:59:39 tom Exp $")
49 
50 SCREEN *
51 set_term(SCREEN * screenp)
52 {
53     SCREEN *oldSP;
54 
55     T((T_CALLED("set_term(%p)"), screenp));
56 
57     oldSP = SP;
58     _nc_set_screen(screenp);
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
73 _nc_free_keytry(struct tries *kt)
74 {
75     if (kt != 0) {
76 	_nc_free_keytry(kt->child);
77 	_nc_free_keytry(kt->sibling);
78 	free(kt);
79     }
80 }
81 
82 /*
83  * Free the storage associated with the given SCREEN sp.
84  */
85 void
86 delscreen(SCREEN * sp)
87 {
88     SCREEN **scan = &_nc_screen_chain;
89 
90     T((T_CALLED("delscreen(%p)"), sp));
91 
92     while (*scan) {
93 	if (*scan == sp) {
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
137 no_mouse_event(SCREEN * sp GCC_UNUSED)
138 {
139     return FALSE;
140 }
141 static bool
142 no_mouse_inline(SCREEN * sp GCC_UNUSED)
143 {
144     return FALSE;
145 }
146 static bool
147 no_mouse_parse(int code GCC_UNUSED)
148 {
149     return TRUE;
150 }
151 static void
152 no_mouse_resume(SCREEN * sp GCC_UNUSED)
153 {
154 }
155 static void
156 no_mouse_wrap(SCREEN * sp GCC_UNUSED)
157 {
158 }
159 
160 int
161 _nc_setupscreen(short slines, short const scolumns, FILE * output)
162 /* OS-independent screen initializations */
163 {
164     int bottom_stolen = 0;
165     size_t i;
166 
167     assert(SP == 0);		/* has been reset in newterm() ! */
168     if (!_nc_alloc_screen())
169 	return ERR;
170 
171     SP->_next_screen = _nc_screen_chain;
172     _nc_screen_chain = SP;
173 
174     _nc_set_buffer(output, TRUE);
175     SP->_term = cur_term;
176     SP->_lines = slines;
177     SP->_lines_avail = slines;
178     SP->_columns = scolumns;
179     SP->_cursrow = -1;
180     SP->_curscol = -1;
181     SP->_nl = TRUE;
182     SP->_raw = FALSE;
183     SP->_cbreak = 0;
184     SP->_echo = TRUE;
185     SP->_fifohead = -1;
186     SP->_endwin = TRUE;
187     SP->_ofp = output;
188     SP->_cursor = -1;		/* cannot know real cursor shape */
189 #ifdef NCURSES_NO_PADDING
190     SP->_no_padding = getenv("NCURSES_NO_PADDING") != 0;
191 #endif
192 #ifdef NCURSES_EXT_FUNCS
193     SP->_default_fg = COLOR_WHITE;
194     SP->_default_bg = COLOR_BLACK;
195 #endif
196 
197     SP->_maxclick = DEFAULT_MAXCLICK;
198     SP->_mouse_event = no_mouse_event;
199     SP->_mouse_inline = no_mouse_inline;
200     SP->_mouse_parse = no_mouse_parse;
201     SP->_mouse_resume = no_mouse_resume;
202     SP->_mouse_wrap = no_mouse_wrap;
203     SP->_mouse_fd = -1;
204 
205     /* initialize the panel hooks */
206     SP->_panelHook.top_panel = (struct panel *) 0;
207     SP->_panelHook.bottom_panel = (struct panel *) 0;
208     SP->_panelHook.stdscr_pseudo_panel = (struct panel *) 0;
209 
210     /*
211      * If we've no magic cookie support, we suppress attributes that xmc
212      * would affect, i.e., the attributes that affect the rendition of a
213      * space.  Note that this impacts the alternate character set mapping
214      * as well.
215      */
216     if (magic_cookie_glitch > 0) {
217 
218 	SP->_xmc_triggers = termattrs() & (
219 	    A_ALTCHARSET |
220 	    A_BLINK |
221 	    A_BOLD |
222 	    A_REVERSE |
223 	    A_STANDOUT |
224 	    A_UNDERLINE
225 	    );
226 	SP->_xmc_suppress = SP->_xmc_triggers & (chtype) ~ (A_BOLD);
227 
228 	T(("magic cookie attributes %s", _traceattr(SP->_xmc_suppress)));
229 #if USE_XMC_SUPPORT
230 	/*
231 	 * To keep this simple, suppress all of the optimization hooks
232 	 * except for clear_screen and the cursor addressing.
233 	 */
234 	clr_eol = 0;
235 	clr_eos = 0;
236 	set_attributes = 0;
237 #else
238 	magic_cookie_glitch = ABSENT_NUMERIC;
239 	acs_chars = 0;
240 #endif
241     }
242     _nc_init_acs();
243     memcpy(SP->_acs_map, acs_map, sizeof(chtype) * ACS_LEN);
244 
245     _nc_idcok = TRUE;
246     _nc_idlok = FALSE;
247 
248     _nc_windows = 0;		/* no windows yet */
249 
250     SP->oldhash = 0;
251     SP->newhash = 0;
252 
253     T(("creating newscr"));
254     if ((newscr = newwin(slines, scolumns, 0, 0)) == 0)
255 	return ERR;
256 
257     T(("creating curscr"));
258     if ((curscr = newwin(slines, scolumns, 0, 0)) == 0)
259 	return ERR;
260 
261     SP->_newscr = newscr;
262     SP->_curscr = curscr;
263 #if USE_SIZECHANGE
264     SP->_resize = resizeterm;
265 #endif
266 
267     newscr->_clear = TRUE;
268     curscr->_clear = FALSE;
269 
270     for (i = 0, rsp = rippedoff; rsp->line && (i < N_RIPS); rsp++, i++) {
271 	if (rsp->hook) {
272 	    WINDOW *w;
273 	    int count = (rsp->line < 0) ? -rsp->line : rsp->line;
274 
275 	    if (rsp->line < 0) {
276 		w = newwin(count, scolumns, SP->_lines_avail - count, 0);
277 		if (w) {
278 		    rsp->w = w;
279 		    rsp->hook(w, scolumns);
280 		    bottom_stolen += count;
281 		} else
282 		    return ERR;
283 	    } else {
284 		w = newwin(count, scolumns, 0, 0);
285 		if (w) {
286 		    rsp->w = w;
287 		    rsp->hook(w, scolumns);
288 		    SP->_topstolen += count;
289 		} else
290 		    return ERR;
291 	    }
292 	    SP->_lines_avail -= count;
293 	}
294 	rsp->line = 0;
295     }
296     /* reset the stack */
297     rsp = rippedoff;
298 
299     T(("creating stdscr"));
300     assert((SP->_lines_avail + SP->_topstolen + bottom_stolen) == slines);
301     if ((stdscr = newwin(LINES = SP->_lines_avail, scolumns, 0, 0)) == 0)
302 	return ERR;
303     SP->_stdscr = stdscr;
304 
305     def_shell_mode();
306     def_prog_mode();
307 
308     return OK;
309 }
310 
311 /* The internal implementation interprets line as the number of
312    lines to rip off from the top or bottom.
313    */
314 int
315 _nc_ripoffline(int line, int (*init) (WINDOW *, int))
316 {
317     if (line == 0)
318 	return (OK);
319 
320     if (rsp >= rippedoff + N_RIPS)
321 	return (ERR);
322 
323     rsp->line = line;
324     rsp->hook = init;
325     rsp->w = 0;
326     rsp++;
327 
328     return (OK);
329 }
330 
331 int
332 ripoffline(int line, int (*init) (WINDOW *, int))
333 {
334     T((T_CALLED("ripoffline(%d,%p)"), line, init));
335 
336     if (line == 0)
337 	returnCode(OK);
338 
339     returnCode(_nc_ripoffline((line < 0) ? -1 : 1, init));
340 }
341