window(1): Remove __RCSID & friends.
[dragonfly.git] / usr.bin / window / wwsize.c
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
43 wwsize(struct ww *w, int nrow, int ncol)
44 {
45         int i, j;
46         int nline = 0;
47         union ww_char **buf = 0;
48         char **win = 0;
49         short *nvis = 0;
50         char **fmap = 0;
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 == 0)
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 == 0)
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 == 0)
69                         goto bad;
70         }
71         nvis = (short *)malloc((unsigned) nrow * sizeof (short));
72         if (nvis == 0) {
73                 wwerrno = WWE_NOMEM;
74                 goto bad;
75         }
76         nvis -= w->ww_w.t;
77         /*
78          * Copy text buffer.
79          */
80         if (buf != 0) {
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 != 0) {
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 != 0) {
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 != 0)
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 != 0)
179                 wwfree(win, w->ww_w.t);
180         if (fmap != 0)
181                 wwfree(fmap, w->ww_w.t);
182         if (buf != 0)
183                 wwfree((char **)buf, w->ww_b.t);
184         return -1;
185 }