xref: /original-bsd/usr.bin/window/wwsize.c (revision b424313c)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that this notice is preserved and that due credit is given
7  * to the University of California at Berkeley. The name of the University
8  * may not be used to endorse or promote products derived from this
9  * software without specific prior written permission. This software
10  * is provided ``as is'' without express or implied warranty.
11  */
12 
13 #ifndef lint
14 static char sccsid[] = "@(#)wwsize.c	3.5 (Berkeley) 02/21/88";
15 #endif /* not lint */
16 
17 #include "ww.h"
18 
19 /*
20  * Resize a window.  Should be unattached.
21  */
22 wwsize(w, nrow, ncol)
23 register struct ww *w;
24 {
25 	register i, j;
26 	int nline;
27 	union ww_char **buf = 0;
28 	char **win = 0;
29 	short *nvis = 0;
30 	char **fmap = 0;
31 	char m;
32 
33 	/*
34 	 * First allocate new buffers.
35 	 */
36 	win = wwalloc(w->ww_w.t, w->ww_w.l, nrow, ncol, sizeof (char));
37 	if (win == 0)
38 		goto bad;
39 	if (w->ww_fmap != 0) {
40 		fmap = wwalloc(w->ww_w.t, w->ww_w.l, nrow, ncol, sizeof (char));
41 		if (fmap == 0)
42 			goto bad;
43 	}
44 	if (nrow > w->ww_b.nr || ncol > w->ww_b.nc) {
45 		nline = MAX(w->ww_b.nr, nrow);
46 		buf = (union ww_char **) wwalloc(w->ww_b.t, w->ww_b.l,
47 			nline, ncol, sizeof (union ww_char));
48 		if (buf == 0)
49 			goto bad;
50 	}
51 	nvis = (short *)malloc((unsigned) nrow * sizeof (short));
52 	if (nvis == 0) {
53 		wwerrno = WWE_NOMEM;
54 		goto bad;
55 	}
56 	nvis -= w->ww_w.t;
57 	/*
58 	 * Copy text buffer.
59 	 */
60 	if (buf != 0) {
61 		int b, r;
62 
63 		b = w->ww_b.t + nline;
64 		r = w->ww_b.l + ncol;
65 		if (ncol < w->ww_b.nc)
66 			for (i = w->ww_b.t; i < w->ww_b.b; i++)
67 				for (j = w->ww_b.l; j < r; j++)
68 					buf[i][j] = w->ww_buf[i][j];
69 		else
70 			for (i = w->ww_b.t; i < w->ww_b.b; i++) {
71 				for (j = w->ww_b.l; j < w->ww_b.r; j++)
72 					buf[i][j] = w->ww_buf[i][j];
73 				for (; j < r; j++)
74 					buf[i][j].c_w = ' ';
75 			}
76 		for (; i < b; i++)
77 			for (j = w->ww_b.l; j < r; j++)
78 				buf[i][j].c_w = ' ';
79 	}
80 	/*
81 	 * Now free the old stuff.
82 	 */
83 	wwfree((char **)w->ww_win, w->ww_w.t);
84 	w->ww_win = win;
85 	if (buf != 0) {
86 		wwfree((char **)w->ww_buf, w->ww_b.t);
87 		w->ww_buf = buf;
88 	}
89 	if (w->ww_fmap != 0) {
90 		wwfree((char **)w->ww_fmap, w->ww_w.t);
91 		w->ww_fmap = fmap;
92 	}
93 	free((char *)(w->ww_nvis + w->ww_w.t));
94 	w->ww_nvis = nvis;
95 	/*
96 	 * Set new sizes.
97 	 */
98 		/* window */
99 	w->ww_w.b = w->ww_w.t + nrow;
100 	w->ww_w.r = w->ww_w.l + ncol;
101 	w->ww_w.nr = nrow;
102 	w->ww_w.nc = ncol;
103 		/* text buffer */
104 	if (buf != 0) {
105 		w->ww_b.b = w->ww_b.t + nline;
106 		w->ww_b.r = w->ww_b.l + ncol;
107 		w->ww_b.nr = nline;
108 		w->ww_b.nc = ncol;
109 	}
110 		/* scroll */
111 	if ((i = w->ww_b.b - w->ww_w.b) < 0 ||
112 	    (i = w->ww_cur.r - w->ww_w.b + 1) > 0) {
113 		w->ww_buf += i;
114 		w->ww_b.t -= i;
115 		w->ww_b.b -= i;
116 		w->ww_cur.r -= i;
117 	}
118 		/* interior */
119 	w->ww_i.b = MIN(w->ww_w.b, wwnrow);
120 	w->ww_i.r = MIN(w->ww_w.r, wwncol);
121 	w->ww_i.nr = w->ww_i.b - w->ww_i.t;
122 	w->ww_i.nc = w->ww_i.r - w->ww_i.l;
123 	/*
124 	 * Initialize new buffers.
125 	 */
126 		/* window */
127 	m = 0;
128 	if (w->ww_oflags & WWO_GLASS)
129 		m |= WWM_GLS;
130 	if (w->ww_oflags & WWO_REVERSE)
131 		m |= WWM_REV;
132 	for (i = w->ww_w.t; i < w->ww_w.b; i++)
133 		for (j = w->ww_w.l; j < w->ww_w.r; j++)
134 			w->ww_win[i][j] = m;
135 		/* frame map */
136 	if (fmap != 0)
137 		for (i = w->ww_w.t; i < w->ww_w.b; i++)
138 			for (j = w->ww_w.l; j < w->ww_w.r; j++)
139 				w->ww_fmap[i][j] = 0;
140 		/* visibility */
141 	j = m ? 0 : w->ww_w.nc;
142 	for (i = w->ww_w.t; i < w->ww_w.b; i++)
143 		w->ww_nvis[i] = j;
144 	/*
145 	 * Put cursor back.
146 	 */
147 	if (w->ww_hascursor) {
148 		w->ww_hascursor = 0;
149 		wwcursor(w, 1);
150 	}
151 	/*
152 	 * Fool with pty.
153 	 */
154 	if (w->ww_ispty && w->ww_pty >= 0) {
155 		struct winsize winsize;
156 
157 		winsize.ws_row = nrow;
158 		winsize.ws_col = ncol;
159 		winsize.ws_xpixel = winsize.ws_ypixel = 0;
160 		(void) ioctl(w->ww_pty, TIOCSWINSZ, (char *)&winsize);
161 	}
162 	return 0;
163 bad:
164 	if (win != 0)
165 		wwfree(win, w->ww_w.t);
166 	if (fmap != 0)
167 		wwfree(fmap, w->ww_w.t);
168 	if (buf != 0)
169 		wwfree((char **)buf, w->ww_b.t);
170 	if (nvis != 0)
171 		free((char *)(nvis + w->ww_w.t));
172 	return -1;
173 }
174