xref: /netbsd-src/lib/libcurses/newwin.c (revision cda4f8f6ee55684e8d311b86c99ea59191e6b74f)
1 /*
2  * Copyright (c) 1981 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by the University of
16  *	California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #ifndef lint
35 static char sccsid[] = "@(#)newwin.c	5.4 (Berkeley) 6/1/90";
36 #endif /* not lint */
37 
38 /*
39  * allocate space for and set up defaults for a new window
40  *
41  */
42 
43 # include	"curses.ext"
44 
45 char	*malloc();
46 
47 # define	SMALLOC	(short *) malloc
48 
49 static WINDOW	*makenew();
50 
51 # undef		nl	/* don't need it here, and it interferes	*/
52 
53 WINDOW *
54 newwin(num_lines, num_cols, begy, begx)
55 int	num_lines, num_cols, begy, begx;
56 {
57 	reg WINDOW	*win;
58 	reg chtype      *sp;
59 	reg int		i, by, bx, nl, nc;
60 	reg int		j;
61 
62 	by = begy;
63 	bx = begx;
64 	nl = num_lines;
65 	nc = num_cols;
66 
67 	if (nl == 0)
68 		nl = LINES - by;
69 	if (nc == 0)
70 		nc = COLS - bx;
71 	if ((win = makenew(nl, nc, by, bx)) == NULL)
72 		return ERR;
73 	if ((win->_firstch = SMALLOC(nl * sizeof win->_firstch[0])) == NULL) {
74 		free(win->_y);
75 		free(win);
76 		return NULL;
77 	}
78 	if ((win->_lastch = SMALLOC(nl * sizeof win->_lastch[0])) == NULL) {
79 		free(win->_y);
80 		free(win->_firstch);
81 		free(win);
82 		return NULL;
83 	}
84 	win->_nextp = win;
85 	for (i = 0; i < nl; i++) {
86 		win->_firstch[i] = _NOCHANGE;
87 		win->_lastch[i] = _NOCHANGE;
88 	}
89 	for (i = 0; i < nl; i++)
90 		if ((win->_y[i] = (chtype *) malloc(nc * sizeof(chtype))) == NULL) {
91 			for (j = 0; j < i; j++)
92 				free(win->_y[j]);
93 			free(win->_firstch);
94 			free(win->_lastch);
95 			free(win->_y);
96 			free(win);
97 			return ERR;
98 		}
99 		else
100 			for (sp = win->_y[i]; sp < win->_y[i] + nc; )
101 				*sp++ = ' ';
102 	win->_ch_off = 0;
103 # ifdef DEBUG
104 	fprintf(outf, "NEWWIN: win->_ch_off = %d\n", win->_ch_off);
105 # endif
106 	return win;
107 }
108 
109 WINDOW *
110 subwin(orig, num_lines, num_cols, begy, begx)
111 reg WINDOW	*orig;
112 int		num_lines, num_cols, begy, begx;
113 {
114 	reg int		i;
115 	reg WINDOW	*win;
116 	reg int		by, bx, nl, nc;
117 
118 	by = begy;
119 	bx = begx;
120 	nl = num_lines;
121 	nc = num_cols;
122 
123 	/*
124 	 * make sure window fits inside the original one
125 	 */
126 # ifdef	DEBUG
127 	fprintf(outf, "SUBWIN(%0.2o, %d, %d, %d, %d)\n", orig, nl, nc, by, bx);
128 # endif
129 	if (by < orig->_begy || bx < orig->_begx
130 	    || by + nl > orig->_maxy + orig->_begy
131 	    || bx + nc > orig->_maxx + orig->_begx)
132 		return ERR;
133 	if (nl == 0)
134 		nl = orig->_maxy + orig->_begy - by;
135 	if (nc == 0)
136 		nc = orig->_maxx + orig->_begx - bx;
137 	if ((win = makenew(nl, nc, by, bx)) == NULL)
138 		return ERR;
139 	win->_nextp = orig->_nextp;
140 	orig->_nextp = win;
141 	win->_orig = orig;
142 	_set_subwin_(orig, win);
143 	return win;
144 }
145 
146 /*
147  * this code is shared with mvwin()
148  */
149 _set_subwin_(orig, win)
150 register WINDOW	*orig, *win;
151 {
152 	register int	i, j, k;
153 
154 	j = win->_begy - orig->_begy;
155 	k = win->_begx - orig->_begx;
156 	win->_ch_off = k;
157 # ifdef DEBUG
158 	fprintf(outf, "_SET_SUBWIN_: win->_ch_off = %d\n", win->_ch_off);
159 # endif
160 	win->_firstch = &orig->_firstch[j];
161 	win->_lastch = &orig->_lastch[j];
162 	for (i = 0; i < win->_maxy; i++, j++)
163 		win->_y[i] = &orig->_y[j][k];
164 
165 }
166 
167 /*
168  *	This routine sets up a window buffer and returns a pointer to it.
169  */
170 static WINDOW *
171 makenew(num_lines, num_cols, begy, begx)
172 int	num_lines, num_cols, begy, begx; {
173 
174 	reg int		i;
175 	reg WINDOW	*win;
176 	reg int		by, bx, nl, nc;
177 
178 	by = begy;
179 	bx = begx;
180 	nl = num_lines;
181 	nc = num_cols;
182 
183 # ifdef	DEBUG
184 	fprintf(outf, "MAKENEW(%d, %d, %d, %d)\n", nl, nc, by, bx);
185 # endif
186 	if ((win = (WINDOW *) malloc(sizeof *win)) == NULL)
187 		return NULL;
188 # ifdef DEBUG
189 	fprintf(outf, "MAKENEW: nl = %d\n", nl);
190 # endif
191 	if ((win->_y = (chtype **) malloc(nl * sizeof(chtype *))) == NULL) {
192 		free(win);
193 		return NULL;
194 	}
195 # ifdef DEBUG
196 	fprintf(outf, "MAKENEW: nc = %d\n", nc);
197 # endif
198 	win->_cury = win->_curx = 0;
199 	win->_clear = FALSE;
200 	win->_maxy = nl;
201 	win->_maxx = nc;
202 	win->_begy = by;
203 	win->_begx = bx;
204 	win->_flags = 0;
205 	win->_scroll = win->_leave = FALSE;
206 	_swflags_(win);
207 # ifdef DEBUG
208 	fprintf(outf, "MAKENEW: win->_clear = %d\n", win->_clear);
209 	fprintf(outf, "MAKENEW: win->_leave = %d\n", win->_leave);
210 	fprintf(outf, "MAKENEW: win->_scroll = %d\n", win->_scroll);
211 	fprintf(outf, "MAKENEW: win->_flags = %0.2o\n", win->_flags);
212 	fprintf(outf, "MAKENEW: win->_maxy = %d\n", win->_maxy);
213 	fprintf(outf, "MAKENEW: win->_maxx = %d\n", win->_maxx);
214 	fprintf(outf, "MAKENEW: win->_begy = %d\n", win->_begy);
215 	fprintf(outf, "MAKENEW: win->_begx = %d\n", win->_begx);
216 # endif
217 	return win;
218 }
219 
220 _swflags_(win)
221 register WINDOW	*win;
222 {
223 	win->_flags &= ~(_ENDLINE|_FULLLINE|_FULLWIN|_SCROLLWIN);
224 	if (win->_begx + win->_maxx == COLS) {
225 		win->_flags |= _ENDLINE;
226 		if (win->_begx == 0) {
227 			if (AL && DL)
228 				win->_flags |= _FULLLINE;
229 			if (win->_maxy == LINES && win->_begy == 0)
230 				win->_flags |= _FULLWIN;
231 		}
232 		if (win->_begy + win->_maxy == LINES)
233 			win->_flags |= _SCROLLWIN;
234 	}
235 }
236