xref: /original-bsd/lib/libcurses/newwin.c (revision 404544c8)
1 /*
2  * Copyright (c) 1981 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)newwin.c	5.8 (Berkeley) 09/21/92";
10 #endif	/* not lint */
11 
12 #include <curses.h>
13 #include <stdlib.h>
14 
15 #undef	nl		/* Don't need it here, and it interferes. */
16 
17 static WINDOW 	*makenew __P((int, int, int, int));
18 static void	 __swflags __P((WINDOW *));
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 char *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)) == NULL)
41 		return (NULL);
42 
43 	win->nextp = win;
44 	win->ch_off = 0;
45 
46 #ifdef DEBUG
47 	__TRACE("newwin: win->ch_off = %d\n", win->ch_off);
48 #endif
49 
50 	for (lp = win->topline, i = 0; i < nl; i++, lp = lp->next) {
51 		lp->flags = 0;
52 		lp->flags &= ~__ISDIRTY;
53 		lp->flags &= ~__ISPASTEOL;
54 		for (sp = lp->line; sp < lp->line + nc; sp++)
55 			*sp = ' ';
56 		lp->hash = __hash(lp->line, nc);
57 	}
58 
59 	return (win);
60 }
61 
62 WINDOW *
63 subwin(orig, nl, nc, by, bx)
64 	register WINDOW *orig;
65 	register int by, bx, nl, nc;
66 {
67 	register WINDOW *win;
68 
69 	/* Make sure window fits inside the original one. */
70 #ifdef	DEBUG
71 	__TRACE("subwin: (%0.2o, %d, %d, %d, %d)\n", orig, nl, nc, by, bx);
72 #endif
73 	if (by < orig->begy || bx < orig->begx
74 	    || by + nl > orig->maxy + orig->begy
75 	    || bx + nc > orig->maxx + orig->begx)
76 		return (NULL);
77 	if (nl == 0)
78 		nl = orig->maxy + orig->begy - by;
79 	if (nc == 0)
80 		nc = orig->maxx + orig->begx - bx;
81 	if ((win = makenew(nl, nc, by, bx)) == NULL)
82 		return (NULL);
83 	win->nextp = orig->nextp;
84 	orig->nextp = win;
85 	win->orig = orig;
86 	__set_subwin(orig, win);
87 	return (win);
88 }
89 
90 /*
91  * This code is shared with mvwin().
92  */
93 void
94 __set_subwin(orig, win)
95 	register WINDOW *orig, *win;
96 {
97 	register int j, k, ocnt, cnt;
98 	register LINE *lp, *olp;
99 
100 	j = win->begy - orig->begy;
101 	k = win->begx - orig->begx;
102 	win->ch_off = k;
103 #ifdef DEBUG
104 	__TRACE("__set_subwin: win->ch_off = %d\n", win->ch_off);
105 #endif
106 
107 	lp = win->topline;
108 	olp = orig->topline;
109 	ocnt = 0;
110 	for (ocnt = 0; ocnt < orig->maxy && cnt < win->maxy; ocnt++) {
111 		if (ocnt >= j) {
112 			lp->firstch = olp->firstch;
113 			lp->lastch = olp->lastch;
114 			lp->line = &olp->line[k];
115 			lp = lp->next;
116 			lp->flags = olp->flags;
117 			cnt++;
118 		}
119 		olp = olp->next;
120 	}
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)
129 	register int by, bx, nl, nc;
130 {
131 	register WINDOW *win;
132 	register LINE *cur, *prev;
133 	int i;
134 
135 #ifdef	DEBUG
136 	__TRACE("makenew: (%d, %d, %d, %d)\n", nl, nc, by, bx);
137 #endif
138 	if ((win = malloc(sizeof(*win))) == NULL)
139 		return (NULL);
140 #ifdef DEBUG
141 	__TRACE("makenew: nl = %d\n", nl);
142 #endif
143 
144 	/*
145 	 * Allocate structure of lines in a window.
146          */
147 	if ((win->topline = malloc (nl * sizeof (LINE))) == NULL) {
148 		free (win);
149 		return NULL;
150 	}
151 
152 	/*
153 	 * Allocate window space in one chunk.
154 	 */
155 	if ((win->wspace = malloc(nc * nl)) == NULL) {
156 		free(win->topline);
157 		free(win);
158 		return NULL;
159 	}
160 	/*
161  	 * Link up the lines, set up line pointer array and point line pointers
162 	 * to the line space.
163          */
164 	if ((win->lines = malloc (nl * sizeof (LINE *))) == NULL) {
165 		free(win->wspace);
166 		free(win->topline);
167 		free(win);
168 		return NULL;
169 	}
170 	prev = &win->topline[nl - 1];
171 	cur = win->topline;
172 	for (i = 1; i <= nl; i++, prev = cur, cur = cur->next) {
173 		cur->next = &win->topline[i % nl];
174 		cur->prev = prev;
175 		cur->line = &win->wspace[(i - 1) * nc];
176 		win->lines[i - 1] = cur;
177 	}
178 
179 #ifdef DEBUG
180 	__TRACE("makenew: nc = %d\n", nc);
181 #endif
182 	win->cury = win->curx = 0;
183 	win->maxy = nl;
184 	win->maxx = nc;
185 
186 	win->begy = by;
187 	win->begx = bx;
188 	win->flags = 0;
189 	__swflags(win);
190 #ifdef DEBUG
191 	__TRACE("makenew: win->flags = %0.2o\n", win->flags);
192 	__TRACE("makenew: win->maxy = %d\n", win->maxy);
193 	__TRACE("makenew: win->maxx = %d\n", win->maxx);
194 	__TRACE("makenew: win->begy = %d\n", win->begy);
195 	__TRACE("makenew: win->begx = %d\n", win->begx);
196 #endif
197 	return (win);
198 }
199 
200 static void
201 __swflags(win)
202 	register WINDOW *win;
203 {
204 	win->flags &=
205 	    ~(__ENDLINE | __FULLLINE | __FULLWIN | __SCROLLWIN | __LEAVEOK);
206 	if (win->begx + win->maxx == COLS) {
207 		win->flags |= __ENDLINE;
208 		if (win->begx == 0) {
209 			if (AL && DL)
210 				win->flags |= __FULLLINE;
211 			if (win->maxy == LINES && win->begy == 0)
212 				win->flags |= __FULLWIN;
213 		}
214 		if (win->begy + win->maxy == LINES)
215 			win->flags |= __SCROLLWIN;
216 	}
217 }
218