lingt
[nvi.git] / common / screen.c
blobbce40c06b7481bce46c1fce1b030e35994f1a4d6
1 /*-
2 * Copyright (c) 1993
3 * The Regents of the University of California. All rights reserved.
5 * %sccs.include.redist.c%
6 */
8 #ifndef lint
9 static char sccsid[] = "$Id: screen.c,v 8.50 1993/12/16 14:59:01 bostic Exp $ (Berkeley) $Date: 1993/12/16 14:59:01 $";
10 #endif /* not lint */
12 #include <sys/types.h>
14 #include <errno.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <unistd.h>
19 #include "vi.h"
20 #include "vcmd.h"
21 #include "excmd.h"
22 #include "tag.h"
25 * screen_init --
26 * Do the default initialization of an SCR structure.
28 int
29 screen_init(orig, spp, flags)
30 SCR *orig, **spp;
31 u_int flags;
33 SCR *sp;
34 size_t len;
36 CALLOC_RET(orig, sp, SCR *, 1, sizeof(SCR));
38 /* INITIALIZED AT SCREEN CREATE. */
39 sp->gp = __global_list; /* All ref the GS structure. */
41 LIST_INIT(&sp->msgq);
42 CIRCLEQ_INIT(&sp->frefq);
44 sp->ccnt = 2; /* Anything > 1 */
46 FD_ZERO(&sp->rdfd);
48 CIRCLEQ_INIT(&sp->tiq);
50 /* PARTIALLY OR COMPLETELY COPIED FROM PREVIOUS SCREEN. */
51 if (orig == NULL) {
52 sp->searchdir = NOTSET;
53 sp->csearchdir = CNOTSET;
55 switch (flags & S_SCREENS) {
56 case S_EX:
57 if (sex_screen_init(sp))
58 return (1);
59 break;
60 case S_VI_CURSES:
61 if (svi_screen_init(sp))
62 return (1);
63 break;
64 case S_VI_XAW:
65 if (xaw_screen_init(sp))
66 return (1);
67 break;
68 default:
69 abort();
72 sp->flags = flags;
73 } else {
74 if (orig->alt_name != NULL &&
75 (sp->alt_name = strdup(orig->alt_name)) == NULL)
76 goto mem;
78 /* Retain all searching/substitution information. */
79 if (F_ISSET(orig, S_SRE_SET)) {
80 F_SET(sp, S_SRE_SET);
81 sp->sre = orig->sre;
83 if (F_ISSET(orig, S_SUBRE_SET)) {
84 F_SET(sp, S_SUBRE_SET);
85 sp->subre = orig->subre;
87 sp->searchdir = orig->searchdir == NOTSET ? NOTSET : FORWARD;
88 sp->csearchdir = CNOTSET;
89 sp->lastckey = orig->lastckey;
91 if (orig->matchsize) {
92 len = orig->matchsize * sizeof(regmatch_t);
93 MALLOC(sp, sp->match, regmatch_t *, len);
94 if (sp->match == NULL)
95 goto mem;
96 sp->matchsize = orig->matchsize;
97 memmove(sp->match, orig->match, len);
99 if (orig->repl_len) {
100 MALLOC(sp, sp->repl, char *, orig->repl_len);
101 if (sp->repl == NULL)
102 goto mem;
103 sp->repl_len = orig->repl_len;
104 memmove(sp->repl, orig->repl, orig->repl_len);
106 if (orig->newl_len) {
107 len = orig->newl_len * sizeof(size_t);
108 MALLOC(sp, sp->newl, size_t *, len);
109 if (sp->newl == NULL)
110 goto mem;
111 sp->newl_len = orig->newl_len;
112 sp->newl_cnt = orig->newl_cnt;
113 memmove(sp->newl, orig->newl, len);
116 sp->saved_vi_mode = orig->saved_vi_mode;
118 if (opts_copy(orig, sp)) {
119 mem: msgq(orig, M_SYSERR, "new screen attributes");
120 (void)screen_end(sp);
121 return (1);
124 sp->s_bell = orig->s_bell;
125 sp->s_bg = orig->s_bg;
126 sp->s_busy = orig->s_busy;
127 sp->s_change = orig->s_change;
128 sp->s_chposition = orig->s_chposition;
129 sp->s_clear = orig->s_clear;
130 sp->s_column = orig->s_column;
131 sp->s_confirm = orig->s_confirm;
132 sp->s_down = orig->s_down;
133 sp->s_edit = orig->s_edit;
134 sp->s_end = orig->s_end;
135 sp->s_ex_cmd = orig->s_ex_cmd;
136 sp->s_ex_run = orig->s_ex_run;
137 sp->s_ex_write = orig->s_ex_write;
138 sp->s_fg = orig->s_fg;
139 sp->s_fill = orig->s_fill;
140 sp->s_get = orig->s_get;
141 sp->s_key_read = orig->s_key_read;
142 sp->s_optchange = orig->s_optchange;
143 sp->s_position = orig->s_position;
144 sp->s_rabs = orig->s_rabs;
145 sp->s_refresh = orig->s_refresh;
146 sp->s_relative = orig->s_relative;
147 sp->s_rrel = orig->s_rrel;
148 sp->s_split = orig->s_split;
149 sp->s_suspend = orig->s_suspend;
150 sp->s_up = orig->s_up;
152 F_SET(sp, F_ISSET(orig, S_SCREENS));
155 if (xaw_screen_copy(orig, sp)) /* Init S_VI_XAW screen. */
156 return (1);
157 if (svi_screen_copy(orig, sp)) /* Init S_VI_CURSES screen. */
158 return (1);
159 if (sex_screen_copy(orig, sp)) /* Init S_EX screen. */
160 return (1);
161 if (v_screen_copy(orig, sp)) /* Init vi. */
162 return (1);
163 if (ex_screen_copy(orig, sp)) /* Init ex. */
164 return (1);
166 *spp = sp;
167 return (0);
171 * screen_end --
172 * Release a screen.
175 screen_end(sp)
176 SCR *sp;
178 int rval;
180 rval = 0;
181 if (xaw_screen_end(sp)) /* End S_VI_XAW screen. */
182 rval = 1;
183 if (svi_screen_end(sp)) /* End S_VI_CURSES screen. */
184 rval = 1;
185 if (sex_screen_end(sp)) /* End S_EX screen. */
186 rval = 1;
187 if (v_screen_end(sp)) /* End vi. */
188 rval = 1;
189 if (ex_screen_end(sp)) /* End ex. */
190 rval = 1;
192 /* Free FREF's. */
193 { FREF *frp;
194 while ((frp = sp->frefq.cqh_first) != (FREF *)&sp->frefq) {
195 CIRCLEQ_REMOVE(&sp->frefq, frp, q);
196 if (frp->cname != NULL)
197 free(frp->cname);
198 if (frp->name != NULL)
199 free(frp->name);
200 if (frp->tname != NULL)
201 free(frp->tname);
202 FREE(frp, sizeof(FREF));
206 /* Free any text input. */
207 text_lfree(&sp->tiq);
209 /* Free any script information. */
210 if (F_ISSET(sp, S_SCRIPT))
211 sscr_end(sp);
213 /* Free alternate file name. */
214 if (sp->alt_name != NULL)
215 FREE(sp->alt_name, strlen(sp->alt_name) + 1);
217 /* Free up search information. */
218 if (sp->match != NULL)
219 FREE(sp->match, sizeof(regmatch_t));
220 if (sp->repl != NULL)
221 FREE(sp->repl, sp->repl_len);
222 if (sp->newl != NULL)
223 FREE(sp->newl, sp->newl_len);
225 /* Free all the options */
226 opts_free(sp);
229 * Free the message chain last, so previous failures have a place
230 * to put messages. Copy messages to (in order) a related screen,
231 * any screen, the global area.
233 { SCR *c_sp; MSG *mp, *next;
234 if ((c_sp = sp->q.cqe_prev) != (void *)&sp->gp->dq) {
235 if (F_ISSET(sp, S_BELLSCHED))
236 F_SET(c_sp, S_BELLSCHED);
237 } else if ((c_sp = sp->q.cqe_next) != (void *)&sp->gp->dq) {
238 if (F_ISSET(sp, S_BELLSCHED))
239 F_SET(c_sp, S_BELLSCHED);
240 } else if ((c_sp =
241 sp->gp->hq.cqh_first) != (void *)&sp->gp->hq) {
242 if (F_ISSET(sp, S_BELLSCHED))
243 F_SET(c_sp, S_BELLSCHED);
244 } else {
245 c_sp = NULL;
246 if (F_ISSET(sp, S_BELLSCHED))
247 F_SET(sp->gp, G_BELLSCHED);
250 for (mp = sp->msgq.lh_first; mp != NULL; mp = next) {
251 if (!F_ISSET(mp, M_EMPTY))
252 msg_app(sp->gp, c_sp,
253 mp->flags & M_INV_VIDEO, mp->mbuf, mp->len);
254 next = mp->q.le_next;
255 if (mp->mbuf != NULL)
256 FREE(mp->mbuf, mp->blen);
257 FREE(mp, sizeof(MSG));
261 /* Remove the screen from the displayed queue. */
262 CIRCLEQ_REMOVE(&sp->gp->dq, sp, q);
264 /* Free the screen itself. */
265 FREE(sp, sizeof(SCR));
267 return (rval);