xref: /dragonfly/usr.bin/window/wwopen.c (revision a632cd2d33eae3cdf365948061576a303057c733)
1 /*        @(#)wwopen.c        8.2 (Berkeley) 4/28/95        */
2 /*        $NetBSD: wwopen.c,v 1.12 2003/08/07 11:17:42 agc 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 <sys/types.h>
37 #include <sys/socket.h>
38 #include <fcntl.h>
39 #include <stdlib.h>
40 #include <unistd.h>
41 #include "ww.h"
42 
43 struct ww *
wwopen(int type,int oflags,int nrow,int ncol,int row,int col,int nline)44 wwopen(int type, int oflags, int nrow, int ncol, int row, int col, int nline)
45 {
46           struct ww *w;
47           int i, j;
48           char m;
49           short nvis;
50 
51           w = (struct ww *)calloc(1, sizeof (struct ww));
52           if (w == NULL) {
53                     wwerrno = WWE_NOMEM;
54                     goto bad;
55           }
56           w->ww_pty = -1;
57           w->ww_socket = -1;
58 
59           for (i = 0; i < NWW && wwindex[i] != 0; i++)
60                     ;
61           if (i >= NWW) {
62                     wwerrno = WWE_TOOMANY;
63                     goto bad;
64           }
65           w->ww_index = i;
66 
67           if (nline < nrow)
68                     nline = nrow;
69 
70           w->ww_w.t = row;
71           w->ww_w.b = row + nrow;
72           w->ww_w.l = col;
73           w->ww_w.r = col + ncol;
74           w->ww_w.nr = nrow;
75           w->ww_w.nc = ncol;
76 
77           w->ww_b.t = row;
78           w->ww_b.b = row + nline;
79           w->ww_b.l = col;
80           w->ww_b.r = col + ncol;
81           w->ww_b.nr = nline;
82           w->ww_b.nc = ncol;
83 
84           w->ww_i.t = MAX(w->ww_w.t, 0);
85           w->ww_i.b = MIN(w->ww_w.b, wwnrow);
86           w->ww_i.l = MAX(w->ww_w.l, 0);
87           w->ww_i.r = MIN(w->ww_w.r, wwncol);
88           w->ww_i.nr = w->ww_i.b - w->ww_i.t;
89           w->ww_i.nc = w->ww_i.r - w->ww_i.l;
90 
91           w->ww_cur.r = w->ww_w.t;
92           w->ww_cur.c = w->ww_w.l;
93 
94           w->ww_type = type;
95           switch (type) {
96           case WWT_PTY:
97                     if (wwgetpty(w) < 0)
98                               goto bad;
99                     break;
100           case WWT_SOCKET:
101               {
102                     int d[2];
103                     if (socketpair(AF_LOCAL, SOCK_STREAM, PF_UNSPEC, d) < 0) {
104                               wwerrno = WWE_SYS;
105                               goto bad;
106                     }
107                     (void) fcntl(d[0], F_SETFD, 1);
108                     (void) fcntl(d[1], F_SETFD, 1);
109                     w->ww_pty = d[0];
110                     w->ww_socket = d[1];
111                     break;
112               }
113           }
114           if (type != WWT_INTERNAL) {
115                     if ((w->ww_ob = malloc(512)) == 0) {
116                               wwerrno = WWE_NOMEM;
117                               goto bad;
118                     }
119                     w->ww_obe = w->ww_ob + 512;
120                     w->ww_obp = w->ww_obq = w->ww_ob;
121                     if (w->ww_pty >= wwdtablesize)
122                               wwdtablesize = w->ww_pty + 1;
123           }
124 
125           w->ww_win = wwalloc(w->ww_w.t, w->ww_w.l,
126                     w->ww_w.nr, w->ww_w.nc, sizeof (char));
127           if (w->ww_win == 0)
128                     goto bad;
129           m = 0;
130           if (oflags & WWO_GLASS)
131                     m |= WWM_GLS;
132           if (oflags & WWO_REVERSE) {
133                     if (wwavailmodes & WWM_REV)
134                               m |= WWM_REV;
135                     else      oflags &= ~WWO_REVERSE;
136           }
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_win[i][j] = m;
140 
141           if (oflags & WWO_FRAME) {
142                     w->ww_fmap = wwalloc(w->ww_w.t, w->ww_w.l,
143                               w->ww_w.nr, w->ww_w.nc, sizeof (char));
144                     if (w->ww_fmap == 0)
145                               goto bad;
146                     for (i = w->ww_w.t; i < w->ww_w.b; i++)
147                               for (j = w->ww_w.l; j < w->ww_w.r; j++)
148                                         w->ww_fmap[i][j] = 0;
149           }
150 
151           w->ww_buf = (union ww_char **)
152                     wwalloc(w->ww_b.t, w->ww_b.l,
153                               w->ww_b.nr, w->ww_b.nc, sizeof (union ww_char));
154           if (w->ww_buf == 0)
155                     goto bad;
156           for (i = w->ww_b.t; i < w->ww_b.b; i++)
157                     for (j = w->ww_b.l; j < w->ww_b.r; j++)
158                               w->ww_buf[i][j].c_w = ' ';
159 
160           w->ww_nvis = (short *)malloc((unsigned) w->ww_w.nr * sizeof (short));
161           if (w->ww_nvis == 0) {
162                     wwerrno = WWE_NOMEM;
163                     goto bad;
164           }
165           w->ww_nvis -= w->ww_w.t;
166           nvis = m ? 0 : w->ww_w.nc;
167           for (i = w->ww_w.t; i < w->ww_w.b; i++)
168                     w->ww_nvis[i] = nvis;
169 
170           w->ww_state = WWS_INITIAL;
171           CLR(w->ww_oflags, WWO_ALLFLAGS);
172           SET(w->ww_oflags, oflags);
173           return wwindex[w->ww_index] = w;
174 bad:
175           if (w != NULL) {
176                     if (w->ww_win != 0)
177                               wwfree(w->ww_win, w->ww_w.t);
178                     if (w->ww_fmap != 0)
179                               wwfree(w->ww_fmap, w->ww_w.t);
180                     if (w->ww_buf != 0)
181                               wwfree((char **)w->ww_buf, w->ww_b.t);
182                     if (w->ww_nvis != 0)
183                               free((char *)(w->ww_nvis + w->ww_w.t));
184                     if (w->ww_ob != 0)
185                               free(w->ww_ob);
186                     if (w->ww_pty >= 0)
187                               (void) close(w->ww_pty);
188                     if (w->ww_socket >= 0)
189                               (void) close(w->ww_socket);
190                     free((char *)w);
191           }
192           return 0;
193 }
194