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