wresize.c revision 97049
1/****************************************************************************
2 * Copyright (c) 1998-2001,2002 Free Software Foundation, Inc.              *
3 *                                                                          *
4 * Permission is hereby granted, free of charge, to any person obtaining a  *
5 * copy of this software and associated documentation files (the            *
6 * "Software"), to deal in the Software without restriction, including      *
7 * without limitation the rights to use, copy, modify, merge, publish,      *
8 * distribute, distribute with modifications, sublicense, and/or sell       *
9 * copies of the Software, and to permit persons to whom the Software is    *
10 * furnished to do so, subject to the following conditions:                 *
11 *                                                                          *
12 * The above copyright notice and this permission notice shall be included  *
13 * in all copies or substantial portions of the Software.                   *
14 *                                                                          *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
22 *                                                                          *
23 * Except as contained in this notice, the name(s) of the above copyright   *
24 * holders shall not be used in advertising or otherwise to promote the     *
25 * sale, use or other dealings in this Software without prior written       *
26 * authorization.                                                           *
27 ****************************************************************************/
28
29/****************************************************************************
30 *  Author: Thomas E. Dickey <dickey@clark.net> 1996,1997                   *
31 ****************************************************************************/
32
33#include <curses.priv.h>
34
35MODULE_ID("$Id: wresize.c,v 1.21 2002/05/11 19:36:29 tom Exp $")
36
37/*
38 * Reallocate a curses WINDOW struct to either shrink or grow to the specified
39 * new lines/columns.  If it grows, the new character cells are filled with
40 * blanks.  The application is responsible for repainting the blank area.
41 */
42
43#define DOALLOC(p,t,n)  typeRealloc(t, n, p)
44#define	ld_ALLOC(p,n)	DOALLOC(p,struct ldat,n)
45#define	c_ALLOC(p,n)	DOALLOC(p,NCURSES_CH_T,n)
46
47NCURSES_EXPORT(int)
48wresize(WINDOW *win, int ToLines, int ToCols)
49{
50    register int row;
51    int size_x, size_y;
52    struct ldat *pline;
53    NCURSES_CH_T blank;
54
55#ifdef TRACE
56    T((T_CALLED("wresize(%p,%d,%d)"), win, ToLines, ToCols));
57    if (win) {
58	TR(TRACE_UPDATE, ("...beg (%d, %d), max(%d,%d), reg(%d,%d)",
59			  win->_begy, win->_begx,
60			  win->_maxy, win->_maxx,
61			  win->_regtop, win->_regbottom));
62	if (_nc_tracing & TRACE_UPDATE)
63	    _tracedump("...before", win);
64    }
65#endif
66
67    if (!win || --ToLines < 0 || --ToCols < 0)
68	returnCode(ERR);
69
70    size_x = win->_maxx;
71    size_y = win->_maxy;
72
73    if (ToLines == size_y
74	&& ToCols == size_x)
75	returnCode(OK);
76
77    if ((win->_flags & _SUBWIN)) {
78	/*
79	 * Check if the new limits will fit into the parent window's size.  If
80	 * not, do not resize.  We could adjust the location of the subwindow,
81	 * but the application may not like that.
82	 */
83	if (win->_pary + ToLines > win->_parent->_maxy
84	    || win->_parx + ToCols > win->_parent->_maxx) {
85	    returnCode(ERR);
86	}
87	pline = win->_parent->_line;
88    } else {
89	pline = 0;
90    }
91
92    /*
93     * If the number of lines has changed, adjust the size of the overall
94     * vector:
95     */
96    if (ToLines != size_y) {
97	if (!(win->_flags & _SUBWIN)) {
98	    for (row = ToLines + 1; row <= size_y; row++)
99		free((char *) (win->_line[row].text));
100	}
101
102	win->_line = ld_ALLOC(win->_line, ToLines + 1);
103	if (win->_line == 0)
104	    returnCode(ERR);
105
106	for (row = size_y + 1; row <= ToLines; row++) {
107	    win->_line[row].text = 0;
108	    win->_line[row].firstchar = 0;
109	    win->_line[row].lastchar = ToCols;
110	    if ((win->_flags & _SUBWIN)) {
111		win->_line[row].text =
112		    &pline[win->_pary + row].text[win->_parx];
113	    }
114	}
115    }
116
117    /*
118     * Adjust the width of the columns:
119     */
120    blank = win->_nc_bkgd;
121    for (row = 0; row <= ToLines; row++) {
122	NCURSES_CH_T *s = win->_line[row].text;
123	int begin = (s == 0) ? 0 : size_x + 1;
124	int end = ToCols;
125
126	if_USE_SCROLL_HINTS(win->_line[row].oldindex = row);
127
128	if (ToCols != size_x || s == 0) {
129	    if (!(win->_flags & _SUBWIN)) {
130		win->_line[row].text = s = c_ALLOC(s, ToCols + 1);
131		if (win->_line[row].text == 0)
132		    returnCode(ERR);
133	    } else {
134		win->_line[row].text = s =
135		    &pline[win->_pary + row].text[win->_parx];
136	    }
137
138	    if (end >= begin) {	/* growing */
139		if (win->_line[row].firstchar < begin)
140		    win->_line[row].firstchar = begin;
141		if (!(win->_flags & _SUBWIN)) {
142		    do {
143			s[end] = blank;
144		    } while (--end >= begin);
145		}
146	    } else {		/* shrinking */
147		win->_line[row].firstchar = 0;
148	    }
149	    win->_line[row].lastchar = ToCols;
150	}
151    }
152
153    /*
154     * Finally, adjust the parameters showing screen size and cursor
155     * position:
156     */
157    win->_maxx = ToCols;
158    win->_maxy = ToLines;
159
160    if (win->_regtop > win->_maxy)
161	win->_regtop = win->_maxy;
162    if (win->_regbottom > win->_maxy
163	|| win->_regbottom == size_y)
164	win->_regbottom = win->_maxy;
165
166    if (win->_curx > win->_maxx)
167	win->_curx = win->_maxx;
168    if (win->_cury > win->_maxy)
169	win->_cury = win->_maxy;
170
171#ifdef TRACE
172    TR(TRACE_UPDATE, ("...beg (%d, %d), max(%d,%d), reg(%d,%d)",
173		      win->_begy, win->_begx,
174		      win->_maxy, win->_maxx,
175		      win->_regtop, win->_regbottom));
176    if (_nc_tracing & TRACE_UPDATE)
177	_tracedump("...after:", win);
178#endif
179    returnCode(OK);
180}
181