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