xref: /illumos-gate/usr/src/lib/libxcurses/src/libc/xcurses/newwin.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright (c) 1995, by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * newwin.c
31  *
32  * XCurses Library
33  *
34  * Copyright 1990, 1995 by Mortice Kern Systems.  All rights reserved.
35  *
36  */
37 
38 #ifdef M_RCSID
39 #ifndef lint
40 static char rcsID[] = "$Header: /rd/src/libc/xcurses/rcs/newwin.c 1.9 1995/09/28 20:15:58 ant Exp $";
41 #endif
42 #endif
43 
44 #include <private.h>
45 #include <stdlib.h>
46 
47 /*f
48  * Create and return a pointer to a new window or pad.
49  *
50  * For a window, provide the dimensions and location of the upper
51  * left hand corner of the window.  If either dimension is zero (0)
52  * then the default sizes will be LINES-begy and COLS-begx.
53  *
54  * For a pad, provide the dimensions and -1 for begy and begx.
55  * If either dimension is zero (0) then the default sizes will be
56  * LINES and COLS.
57  *
58  * If parent is not null, then create a sub-window of the parent
59  * window.
60  */
61 WINDOW *
62 __m_newwin(parent, nlines, ncols, begy, begx)
63 WINDOW *parent;
64 int nlines, ncols, begy, begx;
65 {
66 	WINDOW *w;
67 	int x, y, dx, dy;
68 
69 #ifdef M_CURSES_TRACE
70 	__m_trace(
71 		"__m_newwin(%p, %d, %d, %d, %d)",
72 		parent, nlines, ncols, begy, begx
73 	);
74 #endif
75 
76 	if (parent == (WINDOW *) 0) {
77 		/* Check for default dimensions. */
78 		if (nlines == 0) {
79 			nlines = lines;
80 			if (0 <= begy)
81 				nlines -= begy;
82 		}
83 		if (ncols == 0) {
84 			ncols = columns;
85 			if (0 <= begx)
86 				ncols -= begx;
87 		}
88 	} else {
89 		/* Make sure window dimensions remain within parent's
90 		 * window so that the new subwindow is a proper subset
91 		 * of the parent.
92 		 */
93 		if (begy < parent->_begy || begx < parent->_begx
94 		|| parent->_maxy < (begy-parent->_begy) + nlines
95 		|| parent->_maxx < (begx-parent->_begx) + ncols)
96 			goto error_1;
97 
98 		/* If either dimension is zero (0), use the max size
99 		 * for the dimension from the parent window less the
100 		 * subwindow's starting location.
101 		 */
102 		if (nlines == 0)
103 			nlines = parent->_maxy - (begy - parent->_begy);
104 		if (ncols == 0)
105 			ncols = parent->_maxx - (begx - parent->_begx);
106 	}
107 
108 	/* Check that a window fits on the screen. */
109 	if (0 <= begy) {
110 		if (lines < begy + nlines)
111 			goto error_1;
112 	}
113 	if (0 <= begx) {
114 		if (columns < begx + ncols)
115 			goto error_1;
116 	}
117 
118 	w = (WINDOW *) calloc(1, sizeof *w);
119 	if (w == (WINDOW *) 0)
120 		goto error_1;
121 
122 	w->_first = (short *) calloc(
123 		(size_t) (nlines + nlines), sizeof *w->_first
124 	);
125 	if (w->_first == (short *) 0)
126 		goto error_2;
127 
128 	w->_last = &w->_first[nlines];
129 
130 	w->_line = (cchar_t **) calloc((size_t) nlines, sizeof *w->_line);
131 	if (w->_line == (cchar_t **) 0)
132 		goto error_2;
133 
134 	/* Window rendition. */
135 	(void) setcchar(
136 		&w->_bg, M_MB_L(" "), WA_NORMAL, 0, (void *) 0
137 	);
138 	(void) setcchar(
139 		&w->_fg, M_MB_L(" "), WA_NORMAL, 0, (void *) 0
140 	);
141 
142 	if (parent == (WINDOW *) 0) {
143 		w->_base = (cchar_t *) malloc(
144 			(size_t) (nlines * ncols) * sizeof *w->_base
145 		);
146 		if (w->_base == (cchar_t *) 0)
147 			goto error_2;
148 
149 		w->_line[y = 0] = w->_base;
150 		do {
151 			for (x = 0; x < ncols; ++x)
152 				w->_line[y][x] = w->_bg;
153 			w->_line[y+1] = &w->_line[y][x];
154 		} while (++y < nlines-1);
155 	} else {
156 		/* The new window's origin (0,0) maps to (begy, begx) in the
157 		 * parent's window.  In effect, subwin() is a method by which
158 		 * a portion of a parent's window can be addressed using a
159 		 * (0,0) origin.
160 		 */
161 		dy = begy - parent->_begy;
162 		dx = begx - parent->_begx;
163 
164 		w->_base = (cchar_t *) 0;
165 
166 		for (y = 0; y < nlines; ++y)
167 			w->_line[y] = &parent->_line[dy++][dx];
168 	}
169 
170 	w->_begy = (short) begy;
171 	w->_begx = (short) begx;
172 	w->_cury = w->_curx = 0;
173 	w->_maxy = (short) nlines;
174 	w->_maxx = (short) ncols;
175 	w->_parent = parent;
176 
177 	/* Software scroll region. */
178 	w->_top = 0;
179 	w->_bottom = (short) nlines;
180 	w->_scroll = 0;
181 
182 	/* Window initially blocks for input. */
183 	w->_vmin = 1;
184 	w->_vtime = 0;
185 	w->_flags = W_USE_TIMEOUT;
186 
187 	/* Determine window properties. */
188 	if ((begy < 0 && begx < 0)
189 	|| (parent != (WINDOW *) 0 && (parent->_flags & W_IS_PAD))) {
190 		w->_flags |= W_IS_PAD;
191 		w->_begy = w->_begx = 0;
192 	} else if (begx + ncols == columns) {
193 		/* Writing to last column should trigger auto-margin wrap. */
194 		w->_flags |= W_END_LINE;
195 
196 		if (begx == 0) {
197 			w->_flags |= W_FULL_LINE;
198 
199 			if (begy == 0 && nlines == lines)
200 				w->_flags |= W_FULL_WINDOW;
201 		}
202 
203 		/* Will writing to bottom-right triggers scroll? */
204 		if (begy + nlines == lines)
205 			w->_flags |= W_SCROLL_WINDOW;
206 	}
207 
208 	/* Initial screen clear for full screen windows only. */
209 	if (w->_flags & W_FULL_WINDOW)
210 		w->_flags |= W_CLEAR_WINDOW;
211 
212 	/* Reset dirty region markers. */
213 	(void) wtouchln(w, 0, w->_maxy, 0);
214 
215 	return __m_return_pointer("__m_newwin", w);
216 error_2:
217 	(void) delwin(w);
218 error_1:
219 	return __m_return_pointer("__m_newwin", (WINDOW *) 0);
220 }
221 
222 int
223 delwin(w)
224 WINDOW *w;
225 {
226 	if (w == (WINDOW *) 0)
227 		return OK;
228 
229 #ifdef M_CURSES_TRACE
230 	__m_trace(
231 		"delwin(%p) which is a %s%s.", w,
232 		(w->_parent == (WINDOW *) 0) ? "normal " : "sub-",
233 		(w->_flags & W_IS_PAD) ? "pad" : "window"
234 	);
235 #endif
236 
237 	if (w->_line != (cchar_t **) 0) {
238 		if (w->_base != (cchar_t *) 0)
239 			free(w->_base);
240 
241 		free(w->_line);
242 	}
243 
244 	if (w->_first != (short *) 0)
245 		free(w->_first);
246 
247         free(w);
248 
249 	return __m_return_code("delwin", OK);
250 }
251 
252 WINDOW *
253 derwin(parent, nlines, ncols, begy, begx)
254 WINDOW *parent;
255 int nlines, ncols, begy, begx;
256 {
257 	WINDOW *w;
258 
259 #ifdef M_CURSES_TRACE
260 	__m_trace(
261 		"derwin(%p, %d, %d, %d, %d)",
262 		parent, nlines, ncols, begy, begx
263 	);
264 #endif
265 
266 	if (parent == (WINDOW *) 0)
267 		return __m_return_pointer("derwin", (WINDOW *) 0);
268 
269 	/* Absolute screen address. */
270 	begy += parent->_begy;
271 	begx += parent->_begx;
272 
273 	w = __m_newwin(parent, nlines, ncols, begy, begx);
274 
275 	return __m_return_pointer("derwin", w);
276 }
277 
278 WINDOW *
279 newwin(nlines, ncols, begy, begx)
280 int nlines, ncols, begy, begx;
281 {
282 	WINDOW *w;
283 
284 #ifdef M_CURSES_TRACE
285 	__m_trace("newwin(%d, %d, %d, %d)", nlines, ncols, begy, begx);
286 #endif
287 
288 	w = __m_newwin((WINDOW *) 0, nlines, ncols, begy, begx);
289 
290 	return __m_return_pointer("newwin", w);
291 }
292 
293 WINDOW *
294 subwin(parent, nlines, ncols, begy, begx)
295 WINDOW *parent;
296 int nlines, ncols, begy, begx;
297 {
298 	WINDOW *w;
299 
300 #ifdef M_CURSES_TRACE
301 	__m_trace(
302 		"subwin(%p, %d, %d, %d, %d)",
303 		parent, nlines, ncols, begy, begx
304 	);
305 #endif
306 
307 	if (parent == (WINDOW *) 0)
308 		return __m_return_pointer("subwin", (WINDOW *) 0);
309 
310 	w = __m_newwin(parent, nlines, ncols, begy, begx);
311 
312 	return __m_return_pointer("subwin", w);
313 }
314 
315