xref: /original-bsd/lib/libcurses/newwin.c (revision 27393bdf)
1 /*
2  * Copyright (c) 1981, 1993, 1994
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)newwin.c	8.3 (Berkeley) 07/27/94";
10 #endif	/* not lint */
11 
12 #include <stdlib.h>
13 
14 #include "curses.h"
15 
16 #undef	nl		/* Don't need it here, and it interferes. */
17 
18 static WINDOW 	*__makenew __P((int, int, int, int, int));
19 
20 void	 __set_subwin __P((WINDOW *, WINDOW *));
21 
22 /*
23  * newwin --
24  *	Allocate space for and set up defaults for a new window.
25  */
26 WINDOW *
27 newwin(nl, nc, by, bx)
28 	register int nl, nc, by, bx;
29 {
30 	register WINDOW *win;
31 	register __LINE *lp;
32 	register int  i, j;
33 	register __LDATA *sp;
34 
35 	if (nl == 0)
36 		nl = LINES - by;
37 	if (nc == 0)
38 		nc = COLS - bx;
39 
40 	if ((win = __makenew(nl, nc, by, bx, 0)) == NULL)
41 		return (NULL);
42 
43 	win->nextp = win;
44 	win->ch_off = 0;
45 	win->orig = NULL;
46 
47 #ifdef DEBUG
48 	__CTRACE("newwin: win->ch_off = %d\n", win->ch_off);
49 #endif
50 
51 	for (i = 0; i < nl; i++) {
52 		lp = win->lines[i];
53 		lp->flags = 0;
54 		for (sp = lp->line, j = 0; j < nc; j++, sp++) {
55 			sp->ch = ' ';
56 			sp->attr = 0;
57 		}
58 		lp->hash = __hash((char *) lp->line, nc * __LDATASIZE);
59 	}
60 	return (win);
61 }
62 
63 WINDOW *
64 subwin(orig, nl, nc, by, bx)
65 	register WINDOW *orig;
66 	register int by, bx, nl, nc;
67 {
68 	int i;
69 	__LINE *lp;
70 	register WINDOW *win;
71 
72 	/* Make sure window fits inside the original one. */
73 #ifdef	DEBUG
74 	__CTRACE("subwin: (%0.2o, %d, %d, %d, %d)\n", orig, nl, nc, by, bx);
75 #endif
76 	if (by < orig->begy || bx < orig->begx
77 	    || by + nl > orig->maxy + orig->begy
78 	    || bx + nc > orig->maxx + orig->begx)
79 		return (NULL);
80 	if (nl == 0)
81 		nl = orig->maxy + orig->begy - by;
82 	if (nc == 0)
83 		nc = orig->maxx + orig->begx - bx;
84 	if ((win = __makenew(nl, nc, by, bx, 1)) == NULL)
85 		return (NULL);
86 	win->nextp = orig->nextp;
87 	orig->nextp = win;
88 	win->orig = orig;
89 
90 	/* Initialize flags here so that refresh can also use __set_subwin. */
91 	for (lp = win->lspace, i = 0; i < win->maxy; i++, lp++)
92 		lp->flags = 0;
93 	__set_subwin(orig, win);
94 	return (win);
95 }
96 
97 /*
98  * This code is shared with mvwin().
99  */
100 void
101 __set_subwin(orig, win)
102 	register WINDOW *orig, *win;
103 {
104 	int i;
105 	__LINE *lp, *olp;
106 
107 	win->ch_off = win->begx - orig->begx;
108 	/*  Point line pointers to line space. */
109 	for (lp = win->lspace, i = 0; i < win->maxy; i++, lp++) {
110 		win->lines[i] = lp;
111 		olp = orig->lines[i + win->begy];
112 		lp->line = &olp->line[win->begx];
113 		lp->firstchp = &olp->firstch;
114 		lp->lastchp = &olp->lastch;
115 		lp->hash = __hash((char *) lp->line, win->maxx * __LDATASIZE);
116 	}
117 
118 #ifdef DEBUG
119 	__CTRACE("__set_subwin: win->ch_off = %d\n", win->ch_off);
120 #endif
121 }
122 
123 /*
124  * __makenew --
125  *	Set up a window buffer and returns a pointer to it.
126  */
127 static WINDOW *
128 __makenew(nl, nc, by, bx, sub)
129 	register int by, bx, nl, nc;
130 	int sub;
131 {
132 	register WINDOW *win;
133 	register __LINE *lp;
134 	int i;
135 
136 
137 #ifdef	DEBUG
138 	__CTRACE("makenew: (%d, %d, %d, %d)\n", nl, nc, by, bx);
139 #endif
140 	if ((win = malloc(sizeof(*win))) == NULL)
141 		return (NULL);
142 #ifdef DEBUG
143 	__CTRACE("makenew: nl = %d\n", nl);
144 #endif
145 
146 	/*
147 	 * Set up line pointer array and line space.
148 	 */
149 	if ((win->lines = malloc (nl * sizeof(__LINE *))) == NULL) {
150 		free(win);
151 		return NULL;
152 	}
153 	if ((win->lspace = malloc (nl * sizeof(__LINE))) == NULL) {
154 		free (win);
155 		free (win->lines);
156 		return NULL;
157 	}
158 
159 	/* Don't allocate window and line space if it's a subwindow */
160 	if (!sub) {
161 		/*
162 		 * Allocate window space in one chunk.
163 		 */
164 		if ((win->wspace =
165 		    malloc(nc * nl * sizeof(__LDATA))) == NULL) {
166 			free(win->lines);
167 			free(win->lspace);
168 			free(win);
169 			return NULL;
170 		}
171 
172 		/*
173 		 * Point line pointers to line space, and lines themselves into
174 		 * window space.
175 		 */
176 		for (lp = win->lspace, i = 0; i < nl; i++, lp++) {
177 			win->lines[i] = lp;
178 			lp->line = &win->wspace[i * nc];
179 			lp->firstchp = &lp->firstch;
180 			lp->lastchp = &lp->lastch;
181 			lp->firstch = 0;
182 			lp->lastch = 0;
183 		}
184 	}
185 #ifdef DEBUG
186 	__CTRACE("makenew: nc = %d\n", nc);
187 #endif
188 	win->cury = win->curx = 0;
189 	win->maxy = nl;
190 	win->maxx = nc;
191 
192 	win->begy = by;
193 	win->begx = bx;
194 	win->flags = 0;
195 	__swflags(win);
196 #ifdef DEBUG
197 	__CTRACE("makenew: win->flags = %0.2o\n", win->flags);
198 	__CTRACE("makenew: win->maxy = %d\n", win->maxy);
199 	__CTRACE("makenew: win->maxx = %d\n", win->maxx);
200 	__CTRACE("makenew: win->begy = %d\n", win->begy);
201 	__CTRACE("makenew: win->begx = %d\n", win->begx);
202 #endif
203 	return (win);
204 }
205 
206 void
207 __swflags(win)
208 	register WINDOW *win;
209 {
210 	win->flags &= ~(__ENDLINE | __FULLWIN | __SCROLLWIN | __LEAVEOK);
211 	if (win->begx + win->maxx == COLS) {
212 		win->flags |= __ENDLINE;
213 		if (win->begx == 0 && win->maxy == LINES && win->begy == 0)
214 			win->flags |= __FULLWIN;
215 		if (win->begy + win->maxy == LINES)
216 			win->flags |= __SCROLLWIN;
217 	}
218 }
219