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