xref: /illumos-gate/usr/src/ucblib/libcurses/newwin.c (revision 7a6d80f1660abd4755c68cbd094d4a914681d26e)
1 /*
2  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
7 /*	  All Rights Reserved  	*/
8 
9 /*
10  * Copyright (c) 1980 Regents of the University of California.
11  * All rights reserved.  The Berkeley software License Agreement
12  * specifies the terms and conditions for redistribution.
13  */
14 
15 /*LINTLIBRARY*/
16 
17 #ifndef lint
18 static char
19 sccsid[] = "@(#)newwin.c 1.7 89/07/13 SMI"; /* from UCB 5.1 85/06/07 */
20 #endif	/* not lint */
21 
22 /*
23  * allocate space for and set up defaults for a new window
24  *
25  */
26 
27 #include	"curses.ext"
28 #include 	<malloc.h>
29 
30 #define	SMALLOC	(short *)malloc
31 
32 /* forward declaration */
33 static WINDOW *makenew(int, int, int, int);
34 
35 #undef		nl	/* don't need it here, and it interferes	*/
36 
37 WINDOW *
38 newwin(int num_lines, int num_cols, int begy, int begx)
39 {
40 	WINDOW	*win;
41 	char	*sp;
42 	int	i, by, bx, nl, nc;
43 	int	j;
44 
45 	by = begy;
46 	bx = begx;
47 	nl = num_lines;
48 	nc = num_cols;
49 
50 	if (nl == 0)
51 		nl = LINES - by;
52 	if (nc == 0)
53 		nc = COLS - bx;
54 	if ((win = makenew(nl, nc, by, bx)) == NULL)
55 		return (ERR);
56 	if ((win->_firstch = SMALLOC(nl * sizeof (win->_firstch[0]))) == NULL) {
57 		free(win->_y);
58 		free(win);
59 		return (NULL);
60 	}
61 	if ((win->_lastch = SMALLOC(nl * sizeof (win->_lastch[0]))) == NULL) {
62 		free(win->_y);
63 		free(win->_firstch);
64 		free(win);
65 		return (NULL);
66 	}
67 	win->_nextp = win;
68 	for (i = 0; i < nl; i++) {
69 		win->_firstch[i] = _NOCHANGE;
70 		win->_lastch[i] = _NOCHANGE;
71 	}
72 	for (i = 0; i < nl; i++)
73 		if ((win->_y[i] = malloc(nc * sizeof (win->_y[0]))) == NULL) {
74 			for (j = 0; j < i; j++)
75 				free(win->_y[j]);
76 			free(win->_firstch);
77 			free(win->_lastch);
78 			free(win->_y);
79 			free(win);
80 			return (ERR);
81 		}
82 		else
83 			for (sp = win->_y[i]; sp < win->_y[i] + nc; )
84 				*sp++ = ' ';
85 	win->_ch_off = 0;
86 #ifdef DEBUG
87 	fprintf(outf, "NEWWIN: win->_ch_off = %d\n", win->_ch_off);
88 #endif
89 	return (win);
90 }
91 
92 WINDOW *
93 subwin(WINDOW *orig, int num_lines, int num_cols, int begy, int begx)
94 {
95 	WINDOW	*win;
96 	int	by, bx, nl, nc;
97 
98 	by = begy;
99 	bx = begx;
100 	nl = num_lines;
101 	nc = num_cols;
102 
103 	/*
104 	 * make sure window fits inside the original one
105 	 */
106 #ifdef	DEBUG
107 	fprintf(outf, "SUBWIN(%0.2o, %d, %d, %d, %d)\n", orig, nl, nc, by, bx);
108 #endif
109 	if (by < orig->_begy || bx < orig->_begx ||
110 	    by + nl > orig->_maxy + orig->_begy ||
111 	    bx + nc > orig->_maxx + orig->_begx)
112 		return (ERR);
113 	if (nl == 0)
114 		nl = orig->_maxy + orig->_begy - by;
115 	if (nc == 0)
116 		nc = orig->_maxx + orig->_begx - bx;
117 	if ((win = makenew(nl, nc, by, bx)) == NULL)
118 		return (ERR);
119 	win->_nextp = orig->_nextp;
120 	orig->_nextp = win;
121 	win->_orig = orig;
122 	_set_subwin_(orig, win);
123 	return (win);
124 }
125 
126 /*
127  * this code is shared with mvwin()
128  */
129 
130 void
131 _set_subwin_(WINDOW *orig, WINDOW *win)
132 {
133 	int	i, j, k;
134 
135 	j = win->_begy - orig->_begy;
136 	k = win->_begx - orig->_begx;
137 	win->_ch_off = (short)k;
138 #ifdef DEBUG
139 	fprintf(outf, "_SET_SUBWIN_: win->_ch_off = %d\n", win->_ch_off);
140 #endif
141 	win->_firstch = &orig->_firstch[j];
142 	win->_lastch = &orig->_lastch[j];
143 	for (i = 0; i < win->_maxy; i++, j++)
144 		win->_y[i] = &orig->_y[j][k];
145 
146 }
147 
148 /*
149  *	This routine sets up a window buffer and returns a pointer to it.
150  */
151 
152 static WINDOW *
153 makenew(int num_lines, int num_cols, int begy, int begx)
154 {
155 	WINDOW	*win;
156 	int	by, bx, nl, nc;
157 
158 	by = begy;
159 	bx = begx;
160 	nl = num_lines;
161 	nc = num_cols;
162 
163 #ifdef	DEBUG
164 	fprintf(outf, "MAKENEW(%d, %d, %d, %d)\n", nl, nc, by, bx);
165 #endif
166 	if ((win = (WINDOW *) malloc(sizeof (*win))) == NULL)
167 		return (NULL);
168 #ifdef DEBUG
169 	fprintf(outf, "MAKENEW: nl = %d\n", nl);
170 #endif
171 	if ((win->_y = (char **)malloc(nl * sizeof (win->_y[0]))) == NULL) {
172 		free(win);
173 		return (NULL);
174 	}
175 #ifdef DEBUG
176 	fprintf(outf, "MAKENEW: nc = %d\n", nc);
177 #endif
178 	win->_cury = win->_curx = 0;
179 	win->_clear = FALSE;
180 	win->_maxy = (short)nl;
181 	win->_maxx = (short)nc;
182 	win->_begy = (short)by;
183 	win->_begx = (short)bx;
184 	win->_flags = 0;
185 	win->_scroll = win->_leave = FALSE;
186 	_swflags_(win);
187 	win->_orig = NULL;
188 #ifdef DEBUG
189 	fprintf(outf, "MAKENEW: win->_clear = %d\n", win->_clear);
190 	fprintf(outf, "MAKENEW: win->_leave = %d\n", win->_leave);
191 	fprintf(outf, "MAKENEW: win->_scroll = %d\n", win->_scroll);
192 	fprintf(outf, "MAKENEW: win->_flags = %0.2o\n", win->_flags);
193 	fprintf(outf, "MAKENEW: win->_maxy = %d\n", win->_maxy);
194 	fprintf(outf, "MAKENEW: win->_maxx = %d\n", win->_maxx);
195 	fprintf(outf, "MAKENEW: win->_begy = %d\n", win->_begy);
196 	fprintf(outf, "MAKENEW: win->_begx = %d\n", win->_begx);
197 #endif
198 	return (win);
199 }
200 
201 void
202 _swflags_(WINDOW *win)
203 {
204 	win->_flags &= ~(_ENDLINE|_FULLLINE|_FULLWIN|_SCROLLWIN);
205 	if (win->_begx + win->_maxx == COLS) {
206 		win->_flags |= _ENDLINE;
207 		if (win->_begx == 0) {
208 			if (AL && DL)
209 				win->_flags |= _FULLLINE;
210 			if (win->_maxy == LINES && win->_begy == 0)
211 				win->_flags |= _FULLWIN;
212 		}
213 		if (win->_begy + win->_maxy == LINES)
214 			win->_flags |= _SCROLLWIN;
215 	}
216 }
217