443236cf9cdafadf0e163d846fbf4a65d098876b
[ncurses.git] / ncurses / base / lib_set_term.c
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
45 MODULE_ID("$Id: lib_set_term.c,v 1.46 1999/07/24 20:05:49 tom Exp $")
46
47 SCREEN * set_term(SCREEN *screenp)
48 {
49 SCREEN  *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
68 static 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  */
80 void 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
128 static ripoff_t rippedoff[5];
129 static ripoff_t *rsp = rippedoff;
130 #define N_RIPS SIZEOF(rippedoff)
131
132 static bool no_mouse_event (SCREEN *sp GCC_UNUSED) { return FALSE; }
133 static bool no_mouse_inline(SCREEN *sp GCC_UNUSED) { return FALSE; }
134 static bool no_mouse_parse (int code   GCC_UNUSED) { return TRUE; }
135 static void no_mouse_resume(SCREEN *sp GCC_UNUSED) { }
136 static void no_mouse_wrap  (SCREEN *sp GCC_UNUSED) { }
137
138 int _nc_setupscreen(short slines, short const scolumns, FILE *output)
139 /* OS-independent screen initializations */
140 {
141 int     bottom_stolen = 0;
142 size_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    */
289 int
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
306 int
307 ripoffline(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 }