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 *
newwin(nl,nc,by,bx)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 *
subwin(orig,nl,nc,by,bx)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
__set_subwin(orig,win)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 *
__makenew(nl,nc,by,bx,sub)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
__swflags(win)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