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