1 /* $NetBSD: resize.c,v 1.20 2009/07/22 16:57:15 roy Exp $ */
7 * This code has been donated to The NetBSD Foundation by the Author.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 #include <sys/cdefs.h>
41 static char sccsid
[] = "@(#)resize.c blymn 2001/08/26";
43 __RCSID("$NetBSD: resize.c,v 1.20 2009/07/22 16:57:15 roy Exp $");
50 #include "curses_private.h"
52 static int __resizeterm(WINDOW
*win
, int nlines
, int ncols
);
53 static int __resizewin(WINDOW
*win
, int nlines
, int ncols
);
57 * Resize the given window to the new size.
60 wresize(WINDOW
*win
, int req_nlines
, int req_ncols
)
62 int nlines
= req_nlines
;
63 int ncols
= req_ncols
;
69 __CTRACE(__CTRACE_WINDOW
, "wresize: (%p, %d, %d)\n",
72 if (win
->orig
== NULL
) {
73 /* bound "our" windows by the screen size */
74 if (win
== curscr
|| win
== __virtscr
|| win
== stdscr
) {
84 if (win
->begy
> LINES
)
86 if (win
->begy
+ nlines
> LINES
)
89 nlines
+= LINES
- win
->begy
;
94 if (win
->begx
+ ncols
> COLS
)
97 ncols
+= COLS
- win
->begx
;
102 /* subwins must fit inside the parent - check this */
103 if (win
->begy
> win
->orig
->begy
+ win
->orig
->maxy
)
104 win
->begy
= win
->orig
->begy
+ win
->orig
->maxy
- 1;
105 if (win
->begy
+ nlines
> win
->orig
->begy
+ win
->orig
->maxy
)
108 nlines
+= win
->orig
->begy
+ win
->orig
->maxy
- win
->begy
;
111 if (win
->begx
> win
->orig
->begx
+ win
->orig
->maxx
)
112 win
->begx
= win
->orig
->begx
+ win
->orig
->maxx
- 1;
113 if (win
->begx
+ ncols
> win
->orig
->begx
+ win
->orig
->maxx
)
116 ncols
+= win
->orig
->begx
+ win
->orig
->maxx
- win
->begx
;
121 if ((__resizewin(win
, nlines
, ncols
)) == ERR
)
124 win
->reqy
= req_nlines
;
125 win
->reqx
= req_ncols
;
127 /* If someone resizes curscr, we must also resize __virtscr */
129 if ((__resizewin(__virtscr
, nlines
, ncols
)) == ERR
)
131 __virtscr
->reqy
= req_nlines
;
132 __virtscr
->reqx
= req_ncols
;
140 * Resize the terminal window, resizing the dependent windows.
143 resizeterm(int nlines
, int ncols
)
146 struct __winlist
*list
;
149 __CTRACE(__CTRACE_WINDOW
, "resizeterm: (%d, %d)\n", nlines
, ncols
);
152 if (__resizeterm(curscr
, nlines
, ncols
) == ERR
)
154 if (__resizeterm(__virtscr
, nlines
, ncols
) == ERR
)
156 if (__resizeterm(stdscr
, nlines
, ncols
) == ERR
)
162 /* tweak the flags now that we have updated the LINES and COLS */
163 for (list
= _cursesi_screen
->winlistp
; list
!= NULL
; list
= list
->nextp
) {
166 if (!(win
->flags
& __ISPAD
))
176 * Setup window for resizing.
179 __resizeterm(WINDOW
*win
, int nlines
, int ncols
)
181 int newlines
, newcols
;
183 newlines
= win
->reqy
;
184 if (win
->begy
+ newlines
>= nlines
)
187 newlines
= nlines
- win
->begy
;
190 if (win
->begx
+ newcols
>= ncols
)
193 newcols
= ncols
- win
->begx
;
195 return __resizewin(win
, newlines
, newcols
);
200 * Resize the given window.
203 __resizewin(WINDOW
*win
, int nlines
, int ncols
)
205 __LINE
*lp
, *olp
, **newlines
, *newlspace
;
213 __CTRACE(__CTRACE_WINDOW
, "resize: (%p, %d, %d)\n", win
, nlines
, ncols
);
214 __CTRACE(__CTRACE_WINDOW
, "resize: win->wattr = %08x\n", win
->wattr
);
215 __CTRACE(__CTRACE_WINDOW
, "resize: win->flags = %#.4x\n", win
->flags
);
216 __CTRACE(__CTRACE_WINDOW
, "resize: win->maxy = %d\n", win
->maxy
);
217 __CTRACE(__CTRACE_WINDOW
, "resize: win->maxx = %d\n", win
->maxx
);
218 __CTRACE(__CTRACE_WINDOW
, "resize: win->begy = %d\n", win
->begy
);
219 __CTRACE(__CTRACE_WINDOW
, "resize: win->begx = %d\n", win
->begx
);
220 __CTRACE(__CTRACE_WINDOW
, "resize: win->scr_t = %d\n", win
->scr_t
);
221 __CTRACE(__CTRACE_WINDOW
, "resize: win->scr_b = %d\n", win
->scr_b
);
225 * free up any non-spacing storage before we lose the
229 __cursesi_win_free_nsp(win
);
232 if (nlines
<= 0 || ncols
<= 0)
235 /* Reallocate line pointer array and line space. */
236 newlines
= realloc(win
->alines
, nlines
* sizeof(__LINE
*));
237 if (newlines
== NULL
)
239 win
->alines
= newlines
;
241 newlspace
= realloc(win
->lspace
, nlines
* sizeof(__LINE
));
242 if (newlspace
== NULL
)
244 win
->lspace
= newlspace
;
247 /* Don't allocate window and line space if it's a subwindow */
248 if (win
->orig
== NULL
) {
250 * Allocate window space in one chunk.
253 newwspace
= realloc(win
->wspace
,
254 ncols
* nlines
* sizeof(__LDATA
));
255 if (newwspace
== NULL
)
257 win
->wspace
= newwspace
;
261 * Point line pointers to line space, and lines themselves into
264 for (lp
= win
->lspace
, i
= 0; i
< nlines
; i
++, lp
++) {
266 lp
->line
= &win
->wspace
[i
* ncols
];
268 lp
->sentinel
= SENTINEL_VALUE
;
270 lp
->firstchp
= &lp
->firstch
;
271 lp
->lastchp
= &lp
->lastch
;
273 lp
->lastch
= ncols
- 1;
274 lp
->flags
= __ISDIRTY
;
278 win
->ch_off
= win
->begx
- win
->orig
->begx
;
279 /* Point line pointers to line space. */
280 for (lp
= win
->lspace
, i
= 0; i
< nlines
; i
++, lp
++) {
282 olp
= win
->orig
->alines
[i
+ win
->begy
- win
->orig
->begy
];
283 lp
->line
= &olp
->line
[win
->ch_off
];
285 lp
->sentinel
= SENTINEL_VALUE
;
287 lp
->firstchp
= &olp
->firstch
;
288 lp
->lastchp
= &olp
->lastch
;
289 lp
->flags
= __ISDIRTY
;
294 win
->cury
= win
->curx
= 0;
297 win
->scr_b
= win
->maxy
- 1;
301 * we must zot the window contents otherwise lines may pick
302 * up attributes from the previous line when the window is
303 * made smaller. The client will redraw the window anyway
304 * so this is no big deal.
306 for (i
= 0; i
< win
->maxy
; i
++) {
308 for (sp
= lp
->line
, j
= 0; j
< win
->maxx
; j
++, sp
++) {
313 sp
->ch
= ( wchar_t )btowc(( int ) win
->bch
);
315 if (_cursesi_copy_nsp(win
->bnsp
, sp
) == ERR
)
318 #endif /* HAVE_WCHAR */
320 lp
->hash
= __hash((char *)(void *)lp
->line
,
321 (size_t) (ncols
* __LDATASIZE
));
325 __CTRACE(__CTRACE_WINDOW
, "resize: win->wattr = %08x\n", win
->wattr
);
326 __CTRACE(__CTRACE_WINDOW
, "resize: win->flags = %#.4x\n", win
->flags
);
327 __CTRACE(__CTRACE_WINDOW
, "resize: win->maxy = %d\n", win
->maxy
);
328 __CTRACE(__CTRACE_WINDOW
, "resize: win->maxx = %d\n", win
->maxx
);
329 __CTRACE(__CTRACE_WINDOW
, "resize: win->begy = %d\n", win
->begy
);
330 __CTRACE(__CTRACE_WINDOW
, "resize: win->begx = %d\n", win
->begx
);
331 __CTRACE(__CTRACE_WINDOW
, "resize: win->scr_t = %d\n", win
->scr_t
);
332 __CTRACE(__CTRACE_WINDOW
, "resize: win->scr_b = %d\n", win
->scr_b
);
335 if (win
->orig
== NULL
) {
336 /* bound subwindows to new size and fixup their pointers */
337 for (swin
= win
->nextp
; swin
!= win
; swin
= swin
->nextp
) {
339 if (swin
->begy
> win
->begy
+ win
->maxy
)
340 swin
->begy
= win
->begy
+ win
->maxy
- 1;
341 if (swin
->begy
+ y
> win
->begy
+ win
->maxy
)
344 y
+= win
->begy
+ win
->maxy
- swin
->begy
;
348 if (swin
->begx
> win
->begx
+ win
->maxx
)
349 swin
->begx
= win
->begx
+ win
->maxx
- 1;
350 if (swin
->begx
+ x
> win
->begx
+ win
->maxx
)
353 x
+= win
->begy
+ win
->maxx
- swin
->begx
;
356 __resizewin(swin
, y
, x
);