screen.c revision 1.27 1 /* $NetBSD: screen.c,v 1.27 2017/01/06 13:53:18 roy Exp $ */
2
3 /*
4 * Copyright (c) 1981, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)screen.c 8.2 (blymn) 11/27/2001";
36 #else
37 __RCSID("$NetBSD: screen.c,v 1.27 2017/01/06 13:53:18 roy Exp $");
38 #endif
39 #endif /* not lint */
40
41 #include <stdlib.h>
42
43 #include "curses.h"
44 #include "curses_private.h"
45
46 static int filtered;
47
48 /*
49 * filter has to be called before either initscr or newterm.
50 */
51 void
52 filter(void)
53 {
54
55 filtered = TRUE;
56 }
57
58 /*
59 * set_term --
60 * Change the term to the given screen.
61 *
62 */
63 SCREEN *
64 set_term(SCREEN *new)
65 {
66 SCREEN *old_screen = _cursesi_screen;
67
68 if (_cursesi_screen != NULL) {
69 /* save changes made to the current screen... */
70 old_screen->echoit = __echoit;
71 old_screen->pfast = __pfast;
72 old_screen->rawmode = __rawmode;
73 old_screen->noqch = __noqch;
74 old_screen->COLS = COLS;
75 old_screen->LINES = LINES;
76 old_screen->COLORS = COLORS;
77 old_screen->COLOR_PAIRS = COLOR_PAIRS;
78 old_screen->GT = __GT;
79 old_screen->NONL = __NONL;
80 old_screen->UPPERCASE = __UPPERCASE;
81 }
82
83 _cursesi_screen = new;
84
85 __echoit = new->echoit;
86 __pfast = new->pfast;
87 __rawmode = new->rawmode;
88 __noqch = new->noqch;
89 COLS = new->COLS;
90 LINES = new->LINES;
91 COLORS = new->COLORS;
92 COLOR_PAIRS = new->COLOR_PAIRS;
93 __GT = new->GT;
94 __NONL = new->NONL;
95 __UPPERCASE = new->UPPERCASE;
96
97 _cursesi_resetterm(new);
98
99 curscr = new->curscr;
100 clearok(curscr, new->clearok);
101 stdscr = new->stdscr;
102 __virtscr = new->__virtscr;
103
104 _cursesi_reset_acs(new);
105 #ifdef HAVE_WCHAR
106 _cursesi_reset_wacs(new);
107 #endif /* HAVE_WCHAR */
108
109 #ifdef DEBUG
110 __CTRACE(__CTRACE_SCREEN, "set_term: LINES = %d, COLS = %d\n",
111 LINES, COLS);
112 #endif
113
114 return old_screen;
115 }
116
117 /*
118 * newterm --
119 * Set up a new screen.
120 *
121 */
122 SCREEN *
123 newterm(char *type, FILE *outfd, FILE *infd)
124 {
125 SCREEN *new_screen;
126 char *sp;
127
128 sp = type;
129 if (type == NULL && (sp = getenv("TERM")) == NULL)
130 return NULL;
131
132 if ((new_screen = calloc(1, sizeof(SCREEN))) == NULL)
133 return NULL;
134
135 #ifdef DEBUG
136 __CTRACE(__CTRACE_INIT, "newterm\n");
137 #endif
138
139 new_screen->infd = infd;
140 new_screen->checkfd = fileno(infd);
141 new_screen->outfd = outfd;
142 new_screen->echoit = new_screen->nl = 1;
143 new_screen->pfast = new_screen->rawmode = new_screen->noqch = 0;
144 new_screen->filtered = filtered;
145 filtered = FALSE; /* filter() must preceed each newterm() */
146 new_screen->nca = A_NORMAL;
147 new_screen->color_type = COLOR_NONE;
148 new_screen->COLOR_PAIRS = 0;
149 new_screen->old_mode = 2;
150 new_screen->stdbuf = NULL;
151 new_screen->stdscr = NULL;
152 new_screen->curscr = NULL;
153 new_screen->__virtscr = NULL;
154 new_screen->curwin = 0;
155 new_screen->notty = FALSE;
156 new_screen->half_delay = FALSE;
157 new_screen->resized = 0;
158 new_screen->unget_len = 32;
159
160 if ((new_screen->unget_list =
161 malloc(sizeof(wchar_t) * new_screen->unget_len)) == NULL) {
162 goto error_exit;
163 }
164 new_screen->unget_pos = 0;
165
166 if (_cursesi_gettmode(new_screen) == ERR)
167 goto error_exit;
168
169 if (_cursesi_setterm((char *)sp, new_screen) == ERR)
170 goto error_exit;
171
172 /* Need either homing or cursor motion for refreshes */
173 if (!t_cursor_home(new_screen->term) &&
174 !t_cursor_address(new_screen->term))
175 goto error_exit;
176
177 new_screen->winlistp = NULL;
178
179 if ((new_screen->curscr = __newwin(new_screen, 0,
180 0, 0, 0, FALSE)) == NULL)
181 goto error_exit;
182
183 if ((new_screen->stdscr = __newwin(new_screen, 0,
184 0, 0, 0, FALSE)) == NULL) {
185 delwin(new_screen->curscr);
186 goto error_exit;
187 }
188
189 clearok(new_screen->stdscr, 1);
190
191 if ((new_screen->__virtscr = __newwin(new_screen, 0,
192 0, 0, 0, FALSE)) == NULL) {
193 delwin(new_screen->curscr);
194 delwin(new_screen->stdscr);
195 goto error_exit;
196 }
197
198 __init_getch(new_screen);
199 __init_acs(new_screen);
200 #ifdef HAVE_WCHAR
201 __init_get_wch( new_screen );
202 __init_wacs(new_screen);
203 #endif /* HAVE_WCHAR */
204
205 __set_stophandler();
206 __set_winchhandler();
207
208 /*
209 * bleh - it seems that apps expect the first newterm to set
210 * up the curses screen.... emulate this.
211 */
212 if (_cursesi_screen == NULL || _cursesi_screen->endwin) {
213 set_term(new_screen);
214 }
215
216 #ifdef DEBUG
217 __CTRACE(__CTRACE_SCREEN, "newterm: LINES = %d, COLS = %d\n",
218 LINES, COLS);
219 #endif
220 __startwin(new_screen);
221
222 return new_screen;
223
224 error_exit:
225 if (new_screen->term != NULL)
226 (void)del_curterm(new_screen->term);
227 free(new_screen->unget_list);
228
229 free(new_screen);
230 return NULL;
231 }
232
233 /*
234 * delscreen --
235 * Free resources used by the given screen and destroy it.
236 *
237 */
238 void
239 delscreen(SCREEN *screen)
240 {
241 struct __winlist *list;
242
243 #ifdef DEBUG
244 __CTRACE(__CTRACE_SCREEN, "delscreen(%p)\n", screen);
245 #endif
246 /* free up the terminfo stuff */
247 del_curterm(screen->term);
248
249 /* walk the window list and kill all the parent windows */
250 while ((list = screen->winlistp) != NULL) {
251 delwin(list->winp);
252 if (list == screen->winlistp)
253 /* sanity - abort if window didn't remove itself */
254 break;
255 }
256
257 /* free the storage of the keymaps */
258 _cursesi_free_keymap(screen->base_keymap);
259
260 free(screen->stdbuf);
261 free(screen->unget_list);
262 if (_cursesi_screen == screen)
263 _cursesi_screen = NULL;
264 free(screen);
265 }
266