This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / usr.bin / vi / screen.c
CommitLineData
1e64b3ba
JH
1/*-
2 * Copyright (c) 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static char sccsid[] = "@(#)screen.c 8.51 (Berkeley) 1/11/94";
36#endif /* not lint */
37
38#include <sys/types.h>
39
40#include <errno.h>
41#include <stdlib.h>
42#include <string.h>
43#include <unistd.h>
44
45#include "vi.h"
46#include "vcmd.h"
47#include "excmd.h"
48#include "tag.h"
49
50/*
51 * screen_init --
52 * Do the default initialization of an SCR structure.
53 */
54int
55screen_init(orig, spp, flags)
56 SCR *orig, **spp;
57 u_int flags;
58{
59 SCR *sp;
60 size_t len;
61
62 *spp = NULL;
63 CALLOC_RET(orig, sp, SCR *, 1, sizeof(SCR));
64 *spp = sp;
65
66/* INITIALIZED AT SCREEN CREATE. */
67 sp->gp = __global_list; /* All ref the GS structure. */
68
69 LIST_INIT(&sp->msgq);
70 CIRCLEQ_INIT(&sp->frefq);
71
72 sp->ccnt = 2; /* Anything > 1 */
73
74 FD_ZERO(&sp->rdfd);
75
76 CIRCLEQ_INIT(&sp->tiq);
77
78/* PARTIALLY OR COMPLETELY COPIED FROM PREVIOUS SCREEN. */
79 if (orig == NULL) {
80 sp->searchdir = NOTSET;
81 sp->csearchdir = CNOTSET;
82
83 switch (flags & S_SCREENS) {
84 case S_EX:
85 if (sex_screen_init(sp))
86 return (1);
87 break;
88 case S_VI_CURSES:
89 if (svi_screen_init(sp))
90 return (1);
91 break;
92 case S_VI_XAW:
93 if (xaw_screen_init(sp))
94 return (1);
95 break;
96 default:
97 abort();
98 }
99
100 sp->flags = flags;
101 } else {
102 if (orig->alt_name != NULL &&
103 (sp->alt_name = strdup(orig->alt_name)) == NULL)
104 goto mem;
105
106 /* Retain all searching/substitution information. */
107 if (F_ISSET(orig, S_SRE_SET)) {
108 F_SET(sp, S_SRE_SET);
109 sp->sre = orig->sre;
110 }
111 if (F_ISSET(orig, S_SUBRE_SET)) {
112 F_SET(sp, S_SUBRE_SET);
113 sp->subre = orig->subre;
114 }
115 sp->searchdir = orig->searchdir == NOTSET ? NOTSET : FORWARD;
116 sp->csearchdir = CNOTSET;
117 sp->lastckey = orig->lastckey;
118
119 if (orig->matchsize) {
120 len = orig->matchsize * sizeof(regmatch_t);
121 MALLOC(sp, sp->match, regmatch_t *, len);
122 if (sp->match == NULL)
123 goto mem;
124 sp->matchsize = orig->matchsize;
125 memmove(sp->match, orig->match, len);
126 }
127 if (orig->repl_len) {
128 MALLOC(sp, sp->repl, char *, orig->repl_len);
129 if (sp->repl == NULL)
130 goto mem;
131 sp->repl_len = orig->repl_len;
132 memmove(sp->repl, orig->repl, orig->repl_len);
133 }
134 if (orig->newl_len) {
135 len = orig->newl_len * sizeof(size_t);
136 MALLOC(sp, sp->newl, size_t *, len);
137 if (sp->newl == NULL)
138 goto mem;
139 sp->newl_len = orig->newl_len;
140 sp->newl_cnt = orig->newl_cnt;
141 memmove(sp->newl, orig->newl, len);
142 }
143
144 sp->saved_vi_mode = orig->saved_vi_mode;
145
146 if (opts_copy(orig, sp)) {
147mem: msgq(orig, M_SYSERR, "new screen attributes");
148 (void)screen_end(sp);
149 return (1);
150 }
151
152 sp->s_bell = orig->s_bell;
153 sp->s_bg = orig->s_bg;
154 sp->s_busy = orig->s_busy;
155 sp->s_change = orig->s_change;
156 sp->s_chposition = orig->s_chposition;
157 sp->s_clear = orig->s_clear;
158 sp->s_column = orig->s_column;
159 sp->s_confirm = orig->s_confirm;
160 sp->s_down = orig->s_down;
161 sp->s_edit = orig->s_edit;
162 sp->s_end = orig->s_end;
163 sp->s_ex_cmd = orig->s_ex_cmd;
164 sp->s_ex_run = orig->s_ex_run;
165 sp->s_ex_write = orig->s_ex_write;
166 sp->s_fg = orig->s_fg;
167 sp->s_fill = orig->s_fill;
168 sp->s_get = orig->s_get;
169 sp->s_key_read = orig->s_key_read;
170 sp->s_optchange = orig->s_optchange;
171 sp->s_position = orig->s_position;
172 sp->s_rabs = orig->s_rabs;
173 sp->s_refresh = orig->s_refresh;
174 sp->s_relative = orig->s_relative;
175 sp->s_rrel = orig->s_rrel;
176 sp->s_split = orig->s_split;
177 sp->s_suspend = orig->s_suspend;
178 sp->s_up = orig->s_up;
179
180 F_SET(sp, F_ISSET(orig, S_SCREENS));
181 }
182
183 if (xaw_screen_copy(orig, sp)) /* Init S_VI_XAW screen. */
184 return (1);
185 if (svi_screen_copy(orig, sp)) /* Init S_VI_CURSES screen. */
186 return (1);
187 if (sex_screen_copy(orig, sp)) /* Init S_EX screen. */
188 return (1);
189 if (v_screen_copy(orig, sp)) /* Init vi. */
190 return (1);
191 if (ex_screen_copy(orig, sp)) /* Init ex. */
192 return (1);
193
194 *spp = sp;
195 return (0);
196}
197
198/*
199 * screen_end --
200 * Release a screen.
201 */
202int
203screen_end(sp)
204 SCR *sp;
205{
206 int rval;
207
208 rval = 0;
209 if (xaw_screen_end(sp)) /* End S_VI_XAW screen. */
210 rval = 1;
211 if (svi_screen_end(sp)) /* End S_VI_CURSES screen. */
212 rval = 1;
213 if (sex_screen_end(sp)) /* End S_EX screen. */
214 rval = 1;
215 if (v_screen_end(sp)) /* End vi. */
216 rval = 1;
217 if (ex_screen_end(sp)) /* End ex. */
218 rval = 1;
219
220 /* Free FREF's. */
221 { FREF *frp;
222 while ((frp = sp->frefq.cqh_first) != (FREF *)&sp->frefq) {
223 CIRCLEQ_REMOVE(&sp->frefq, frp, q);
224 if (frp->cname != NULL)
225 free(frp->cname);
226 if (frp->name != NULL)
227 free(frp->name);
228 if (frp->tname != NULL)
229 free(frp->tname);
230 FREE(frp, sizeof(FREF));
231 }
232 }
233
234 /* Free any text input. */
235 text_lfree(&sp->tiq);
236
237 /* Free any script information. */
238 if (F_ISSET(sp, S_SCRIPT))
239 sscr_end(sp);
240
241 /* Free alternate file name. */
242 if (sp->alt_name != NULL)
243 FREE(sp->alt_name, strlen(sp->alt_name) + 1);
244
245 /* Free up search information. */
246 if (sp->match != NULL)
247 FREE(sp->match, sizeof(regmatch_t));
248 if (sp->repl != NULL)
249 FREE(sp->repl, sp->repl_len);
250 if (sp->newl != NULL)
251 FREE(sp->newl, sp->newl_len);
252
253 /* Free all the options */
254 opts_free(sp);
255
256 /*
257 * Free the message chain last, so previous failures have a place
258 * to put messages. Copy messages to (in order) a related screen,
259 * any screen, the global area.
260 */
261 { SCR *c_sp; MSG *mp, *next;
262 if ((c_sp = sp->q.cqe_prev) != (void *)&sp->gp->dq) {
263 if (F_ISSET(sp, S_BELLSCHED))
264 F_SET(c_sp, S_BELLSCHED);
265 } else if ((c_sp = sp->q.cqe_next) != (void *)&sp->gp->dq) {
266 if (F_ISSET(sp, S_BELLSCHED))
267 F_SET(c_sp, S_BELLSCHED);
268 } else if ((c_sp =
269 sp->gp->hq.cqh_first) != (void *)&sp->gp->hq) {
270 if (F_ISSET(sp, S_BELLSCHED))
271 F_SET(c_sp, S_BELLSCHED);
272 } else {
273 c_sp = NULL;
274 if (F_ISSET(sp, S_BELLSCHED))
275 F_SET(sp->gp, G_BELLSCHED);
276 }
277
278 for (mp = sp->msgq.lh_first; mp != NULL; mp = next) {
279 if (!F_ISSET(mp, M_EMPTY))
280 msg_app(sp->gp, c_sp,
281 mp->flags & M_INV_VIDEO, mp->mbuf, mp->len);
282 next = mp->q.le_next;
283 if (mp->mbuf != NULL)
284 FREE(mp->mbuf, mp->blen);
285 FREE(mp, sizeof(MSG));
286 }
287 }
288
289 /* Remove the screen from the displayed queue. */
290 CIRCLEQ_REMOVE(&sp->gp->dq, sp, q);
291
292 /* Free the screen itself. */
293 FREE(sp, sizeof(SCR));
294
295 return (rval);
296}