1 /*	$OpenBSD: xx.c,v 1.7 2003/07/18 23:11:43 david Exp $	*/
2 /*	$NetBSD: xx.c,v 1.3 1995/09/28 10:36:03 tls Exp $	*/
3 
4 /*
5  * Copyright (c) 1989, 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 #ifndef lint
37 #if 0
38 static char sccsid[] = "@(#)xx.c	8.1 (Berkeley) 6/6/93";
39 #else
40 static char rcsid[] = "$OpenBSD: xx.c,v 1.7 2003/07/18 23:11:43 david Exp $";
41 #endif
42 #endif /* not lint */
43 
44 #include <stdlib.h>
45 #include <string.h>
46 #include "ww.h"
47 #include "xx.h"
48 #include "tt.h"
49 
xxinit()50 xxinit()
51 {
52 	if (ttinit() < 0)
53 		return -1;
54 	xxbufsize = tt.tt_nrow * tt.tt_ncol * 2;
55 	/* ccinit may choose to change xxbufsize */
56 	if (tt.tt_ntoken > 0 && ccinit() < 0)
57 		return -1;
58 	xxbuf = malloc(xxbufsize * sizeof *xxbuf);
59 	if (xxbuf == 0) {
60 		wwerrno = WWE_NOMEM;
61 		return -1;
62 	}
63 	xxbufp = xxbuf;
64 	xxbufe = xxbuf + xxbufsize;
65 	return 0;
66 }
67 
xxstart()68 xxstart()
69 {
70 	(*tt.tt_start)();
71 	if (tt.tt_ntoken > 0)
72 		ccstart();
73 	xxreset1();			/* might be a restart */
74 }
75 
xxreset()76 xxreset()
77 {
78 	if (tt.tt_ntoken > 0)
79 		ccreset();
80 	xxreset1();
81 	(*tt.tt_reset)();
82 }
83 
xxreset1()84 xxreset1()
85 {
86 	struct xx *xp, *xq;
87 
88 	for (xp = xx_head; xp != 0; xp = xq) {
89 		xq = xp->link;
90 		xxfree(xp);
91 	}
92 	xx_tail = xx_head = 0;
93 	xxbufp = xxbuf;
94 }
95 
xxend()96 xxend()
97 {
98 	if (tt.tt_scroll_top != 0 || tt.tt_scroll_bot != tt.tt_nrow - 1)
99 		/* tt.tt_setscroll is known to be defined */
100 		(*tt.tt_setscroll)(0, tt.tt_nrow - 1);
101 	if (tt.tt_modes)
102 		(*tt.tt_setmodes)(0);
103 	if (tt.tt_scroll_down)
104 		(*tt.tt_scroll_down)(1);
105 	(*tt.tt_move)(tt.tt_nrow - 1, 0);
106 	if (tt.tt_ntoken > 0)
107 		ccend();
108 	(*tt.tt_end)();
109 	ttflush();
110 }
111 
112 struct xx *
xxalloc()113 xxalloc()
114 {
115 	struct xx *xp;
116 
117 	if (xxbufp > xxbufe)
118 		abort();
119 	if ((xp = xx_freelist) == 0)
120 		/* XXX can't deal with failure */
121 		xp = (struct xx *) malloc(sizeof *xp);
122 	else
123 		xx_freelist = xp->link;
124 	if (xx_head == 0)
125 		xx_head = xp;
126 	else
127 		xx_tail->link = xp;
128 	xx_tail = xp;
129 	xp->link = 0;
130 	return xp;
131 }
132 
133 xxfree(xp)
134 	struct xx *xp;
135 {
136 	xp->link = xx_freelist;
137 	xx_freelist = xp;
138 }
139 
xxmove(row,col)140 xxmove(row, col)
141 {
142 	struct xx *xp = xx_tail;
143 
144 	if (xp == 0 || xp->cmd != xc_move) {
145 		xp = xxalloc();
146 		xp->cmd = xc_move;
147 	}
148 	xp->arg0 = row;
149 	xp->arg1 = col;
150 }
151 
xxscroll(dir,top,bot)152 xxscroll(dir, top, bot)
153 {
154 	struct xx *xp = xx_tail;
155 
156 	if (xp != 0 && xp->cmd == xc_scroll &&
157 	    xp->arg1 == top && xp->arg2 == bot &&
158 	    (xp->arg0 < 0 && dir < 0 || xp->arg0 > 0 && dir > 0)) {
159 		xp->arg0 += dir;
160 		return;
161 	}
162 	xp = xxalloc();
163 	xp->cmd = xc_scroll;
164 	xp->arg0 = dir;
165 	xp->arg1 = top;
166 	xp->arg2 = bot;
167 }
168 
xxinschar(row,col,c,m)169 xxinschar(row, col, c, m)
170 {
171 	struct xx *xp;
172 
173 	xp = xxalloc();
174 	xp->cmd = xc_inschar;
175 	xp->arg0 = row;
176 	xp->arg1 = col;
177 	xp->arg2 = c;
178 	xp->arg3 = m;
179 }
180 
xxinsspace(row,col)181 xxinsspace(row, col)
182 {
183 	struct xx *xp = xx_tail;
184 
185 	if (xp != 0 && xp->cmd == xc_insspace && xp->arg0 == row &&
186 	    col >= xp->arg1 && col <= xp->arg1 + xp->arg2) {
187 		xp->arg2++;
188 		return;
189 	}
190 	xp = xxalloc();
191 	xp->cmd = xc_insspace;
192 	xp->arg0 = row;
193 	xp->arg1 = col;
194 	xp->arg2 = 1;
195 }
196 
xxdelchar(row,col)197 xxdelchar(row, col)
198 {
199 	struct xx *xp = xx_tail;
200 
201 	if (xp != 0 && xp->cmd == xc_delchar &&
202 	    xp->arg0 == row && xp->arg1 == col) {
203 		xp->arg2++;
204 		return;
205 	}
206 	xp = xxalloc();
207 	xp->cmd = xc_delchar;
208 	xp->arg0 = row;
209 	xp->arg1 = col;
210 	xp->arg2 = 1;
211 }
212 
xxclear()213 xxclear()
214 {
215 	struct xx *xp;
216 
217 	xxreset1();
218 	xp = xxalloc();
219 	xp->cmd = xc_clear;
220 }
221 
xxclreos(row,col)222 xxclreos(row, col)
223 {
224 	struct xx *xp = xxalloc();
225 
226 	xp->cmd = xc_clreos;
227 	xp->arg0 = row;
228 	xp->arg1 = col;
229 }
230 
xxclreol(row,col)231 xxclreol(row, col)
232 {
233 	struct xx *xp = xxalloc();
234 
235 	xp->cmd = xc_clreol;
236 	xp->arg0 = row;
237 	xp->arg1 = col;
238 }
239 
xxwrite(row,col,p,n,m)240 xxwrite(row, col, p, n, m)
241 	char *p;
242 {
243 	struct xx *xp;
244 
245 	if (xxbufp + n + 1 > xxbufe)
246 		xxflush(0);
247 	xp = xxalloc();
248 	xp->cmd = xc_write;
249 	xp->arg0 = row;
250 	xp->arg1 = col;
251 	xp->arg2 = n;
252 	xp->arg3 = m;
253 	xp->buf = xxbufp;
254 	memmove(xxbufp, p, n);
255 	xxbufp += n;
256 	*xxbufp++ = char_sep;
257 }
258