xref: /dragonfly/usr.bin/window/wwsize.c (revision bcc8941083d0b963b673c93192148e2e23a76740)
1 /*        @(#)wwsize.c        8.1 (Berkeley) 6/6/93         */
2 /*        $NetBSD: wwsize.c,v 1.9 2006/05/02 22:24:05 christos Exp $  */
3 
4 /*
5  * Copyright (c) 1983, 1993
6  *        The Regents of the University of California.  All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * Edward Wang at The University of California, Berkeley.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35 
36 #include <stdlib.h>
37 #include "ww.h"
38 
39 /*
40  * Resize a window.  Should be unattached.
41  */
42 int
wwsize(struct ww * w,int nrow,int ncol)43 wwsize(struct ww *w, int nrow, int ncol)
44 {
45           int i, j;
46           int nline = 0;
47           union ww_char **buf = NULL;
48           char **win = NULL;
49           short *nvis = NULL;
50           char **fmap = NULL;
51           char m;
52 
53           /*
54            * First allocate new buffers.
55            */
56           win = wwalloc(w->ww_w.t, w->ww_w.l, nrow, ncol, sizeof (char));
57           if (win == NULL)
58                     goto bad;
59           if (w->ww_fmap != 0) {
60                     fmap = wwalloc(w->ww_w.t, w->ww_w.l, nrow, ncol, sizeof (char));
61                     if (fmap == NULL)
62                               goto bad;
63           }
64           if (nrow > w->ww_b.nr || ncol > w->ww_b.nc) {
65                     nline = MAX(w->ww_b.nr, nrow);
66                     buf = (union ww_char **) wwalloc(w->ww_b.t, w->ww_b.l,
67                               nline, ncol, sizeof (union ww_char));
68                     if (buf == NULL)
69                               goto bad;
70           }
71           nvis = malloc((unsigned) nrow * sizeof (short));
72           if (nvis == NULL) {
73                     wwerrno = WWE_NOMEM;
74                     goto bad;
75           }
76           nvis -= w->ww_w.t;
77           /*
78            * Copy text buffer.
79            */
80           if (buf != NULL) {
81                     int b, r;
82 
83                     b = w->ww_b.t + nline;
84                     r = w->ww_b.l + ncol;
85                     if (ncol < w->ww_b.nc)
86                               for (i = w->ww_b.t; i < w->ww_b.b; i++)
87                                         for (j = w->ww_b.l; j < r; j++)
88                                                   buf[i][j] = w->ww_buf[i][j];
89                     else
90                               for (i = w->ww_b.t; i < w->ww_b.b; i++) {
91                                         for (j = w->ww_b.l; j < w->ww_b.r; j++)
92                                                   buf[i][j] = w->ww_buf[i][j];
93                                         for (; j < r; j++)
94                                                   buf[i][j].c_w = ' ';
95                               }
96                     for (; i < b; i++)
97                               for (j = w->ww_b.l; j < r; j++)
98                                         buf[i][j].c_w = ' ';
99           }
100           /*
101            * Now free the old stuff.
102            */
103           wwfree((char **)w->ww_win, w->ww_w.t);
104           w->ww_win = win;
105           if (buf != NULL) {
106                     wwfree((char **)w->ww_buf, w->ww_b.t);
107                     w->ww_buf = buf;
108           }
109           if (w->ww_fmap != 0) {
110                     wwfree((char **)w->ww_fmap, w->ww_w.t);
111                     w->ww_fmap = fmap;
112           }
113           free((char *)(w->ww_nvis + w->ww_w.t));
114           w->ww_nvis = nvis;
115           /*
116            * Set new sizes.
117            */
118                     /* window */
119           w->ww_w.b = w->ww_w.t + nrow;
120           w->ww_w.r = w->ww_w.l + ncol;
121           w->ww_w.nr = nrow;
122           w->ww_w.nc = ncol;
123                     /* text buffer */
124           if (buf != NULL) {
125                     w->ww_b.b = w->ww_b.t + nline;
126                     w->ww_b.r = w->ww_b.l + ncol;
127                     w->ww_b.nr = nline;
128                     w->ww_b.nc = ncol;
129           }
130                     /* scroll */
131           if ((i = w->ww_b.b - w->ww_w.b) < 0 ||
132               (i = w->ww_cur.r - w->ww_w.b + 1) > 0) {
133                     w->ww_buf += i;
134                     w->ww_b.t -= i;
135                     w->ww_b.b -= i;
136                     w->ww_cur.r -= i;
137           }
138                     /* interior */
139           w->ww_i.b = MIN(w->ww_w.b, wwnrow);
140           w->ww_i.r = MIN(w->ww_w.r, wwncol);
141           w->ww_i.nr = w->ww_i.b - w->ww_i.t;
142           w->ww_i.nc = w->ww_i.r - w->ww_i.l;
143           /*
144            * Initialize new buffers.
145            */
146                     /* window */
147           m = 0;
148           if (w->ww_oflags & WWO_GLASS)
149                     m |= WWM_GLS;
150           if (w->ww_oflags & WWO_REVERSE)
151                     m |= WWM_REV;
152           for (i = w->ww_w.t; i < w->ww_w.b; i++)
153                     for (j = w->ww_w.l; j < w->ww_w.r; j++)
154                               w->ww_win[i][j] = m;
155                     /* frame map */
156           if (fmap != NULL)
157                     for (i = w->ww_w.t; i < w->ww_w.b; i++)
158                               for (j = w->ww_w.l; j < w->ww_w.r; j++)
159                                         w->ww_fmap[i][j] = 0;
160                     /* visibility */
161           j = m ? 0 : w->ww_w.nc;
162           for (i = w->ww_w.t; i < w->ww_w.b; i++)
163                     w->ww_nvis[i] = j;
164           /*
165            * Put cursor back.
166            */
167           if (ISSET(w->ww_wflags, WWW_HASCURSOR)) {
168                     CLR(w->ww_wflags, WWW_HASCURSOR);
169                     wwcursor(w, 1);
170           }
171           /*
172            * Fool with pty.
173            */
174           if (w->ww_type == WWT_PTY && w->ww_pty >= 0)
175                     (void) wwsetttysize(w->ww_pty, nrow, ncol);
176           return 0;
177 bad:
178           if (win != NULL)
179                     wwfree(win, w->ww_w.t);
180           if (fmap != NULL)
181                     wwfree(fmap, w->ww_w.t);
182           if (buf != NULL)
183                     wwfree((char **)buf, w->ww_b.t);
184           return -1;
185 }
186