xref: /dragonfly/usr.bin/window/xx.c (revision e293de53)
1 /*
2  * Copyright (c) 1989, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Edward Wang at The University of California, Berkeley.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by the University of
19  *	California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * @(#)xx.c	8.1 (Berkeley) 6/6/93
37  * $FreeBSD: src/usr.bin/window/xx.c,v 1.2.12.1 2001/05/17 09:45:02 obrien Exp $
38  * $DragonFly: src/usr.bin/window/xx.c,v 1.2 2003/06/17 04:29:34 dillon Exp $
39  */
40 
41 #include <stdlib.h>
42 #include <string.h>
43 
44 #include "ww.h"
45 #include "xx.h"
46 #include "tt.h"
47 
48 xxinit()
49 {
50 	if (ttinit() < 0)
51 		return -1;
52 	xxbufsize = tt.tt_nrow * tt.tt_ncol * 2;
53 	/* ccinit may choose to change xxbufsize */
54 	if (tt.tt_ntoken > 0 && ccinit() < 0)
55 		return -1;
56 	xxbuf = malloc((unsigned) xxbufsize * sizeof *xxbuf);
57 	if (xxbuf == 0) {
58 		wwerrno = WWE_NOMEM;
59 		return -1;
60 	}
61 	xxbufp = xxbuf;
62 	xxbufe = xxbuf + xxbufsize;
63 	return 0;
64 }
65 
66 xxstart()
67 {
68 	(*tt.tt_start)();
69 	if (tt.tt_ntoken > 0)
70 		ccstart();
71 	xxreset1();			/* might be a restart */
72 }
73 
74 xxreset()
75 {
76 	if (tt.tt_ntoken > 0)
77 		ccreset();
78 	xxreset1();
79 	(*tt.tt_reset)();
80 }
81 
82 xxreset1()
83 {
84 	register struct xx *xp, *xq;
85 
86 	for (xp = xx_head; xp != 0; xp = xq) {
87 		xq = xp->link;
88 		xxfree(xp);
89 	}
90 	xx_tail = xx_head = 0;
91 	xxbufp = xxbuf;
92 }
93 
94 xxend()
95 {
96 	if (tt.tt_scroll_top != 0 || tt.tt_scroll_bot != tt.tt_nrow - 1)
97 		/* tt.tt_setscroll is known to be defined */
98 		(*tt.tt_setscroll)(0, tt.tt_nrow - 1);
99 	if (tt.tt_modes)
100 		(*tt.tt_setmodes)(0);
101 	if (tt.tt_scroll_down)
102 		(*tt.tt_scroll_down)(1);
103 	(*tt.tt_move)(tt.tt_nrow - 1, 0);
104 	if (tt.tt_ntoken > 0)
105 		ccend();
106 	(*tt.tt_end)();
107 	ttflush();
108 }
109 
110 struct xx *
111 xxalloc()
112 {
113 	register struct xx *xp;
114 
115 	if (xxbufp > xxbufe)
116 		abort();
117 	if ((xp = xx_freelist) == 0)
118 		/* XXX can't deal with failure */
119 		xp = (struct xx *) malloc((unsigned) sizeof *xp);
120 	else
121 		xx_freelist = xp->link;
122 	if (xx_head == 0)
123 		xx_head = xp;
124 	else
125 		xx_tail->link = xp;
126 	xx_tail = xp;
127 	xp->link = 0;
128 	return xp;
129 }
130 
131 xxfree(xp)
132 	register struct xx *xp;
133 {
134 	xp->link = xx_freelist;
135 	xx_freelist = xp;
136 }
137 
138 xxmove(row, col)
139 {
140 	register struct xx *xp = xx_tail;
141 
142 	if (xp == 0 || xp->cmd != xc_move) {
143 		xp = xxalloc();
144 		xp->cmd = xc_move;
145 	}
146 	xp->arg0 = row;
147 	xp->arg1 = col;
148 }
149 
150 xxscroll(dir, top, bot)
151 {
152 	register struct xx *xp = xx_tail;
153 
154 	if (xp != 0 && xp->cmd == xc_scroll &&
155 	    xp->arg1 == top && xp->arg2 == bot &&
156 	    (xp->arg0 < 0 && dir < 0 || xp->arg0 > 0 && dir > 0)) {
157 		xp->arg0 += dir;
158 		return;
159 	}
160 	xp = xxalloc();
161 	xp->cmd = xc_scroll;
162 	xp->arg0 = dir;
163 	xp->arg1 = top;
164 	xp->arg2 = bot;
165 }
166 
167 xxinschar(row, col, c, m)
168 {
169 	register struct xx *xp;
170 
171 	xp = xxalloc();
172 	xp->cmd = xc_inschar;
173 	xp->arg0 = row;
174 	xp->arg1 = col;
175 	xp->arg2 = c;
176 	xp->arg3 = m;
177 }
178 
179 xxinsspace(row, col)
180 {
181 	register struct xx *xp = xx_tail;
182 
183 	if (xp != 0 && xp->cmd == xc_insspace && xp->arg0 == row &&
184 	    col >= xp->arg1 && col <= xp->arg1 + xp->arg2) {
185 		xp->arg2++;
186 		return;
187 	}
188 	xp = xxalloc();
189 	xp->cmd = xc_insspace;
190 	xp->arg0 = row;
191 	xp->arg1 = col;
192 	xp->arg2 = 1;
193 }
194 
195 xxdelchar(row, col)
196 {
197 	register struct xx *xp = xx_tail;
198 
199 	if (xp != 0 && xp->cmd == xc_delchar &&
200 	    xp->arg0 == row && xp->arg1 == col) {
201 		xp->arg2++;
202 		return;
203 	}
204 	xp = xxalloc();
205 	xp->cmd = xc_delchar;
206 	xp->arg0 = row;
207 	xp->arg1 = col;
208 	xp->arg2 = 1;
209 }
210 
211 xxclear()
212 {
213 	register struct xx *xp;
214 
215 	xxreset1();
216 	xp = xxalloc();
217 	xp->cmd = xc_clear;
218 }
219 
220 xxclreos(row, col)
221 {
222 	register struct xx *xp = xxalloc();
223 
224 	xp->cmd = xc_clreos;
225 	xp->arg0 = row;
226 	xp->arg1 = col;
227 }
228 
229 xxclreol(row, col)
230 {
231 	register struct xx *xp = xxalloc();
232 
233 	xp->cmd = xc_clreol;
234 	xp->arg0 = row;
235 	xp->arg1 = col;
236 }
237 
238 xxwrite(row, col, p, n, m)
239 	char *p;
240 {
241 	register struct xx *xp;
242 
243 	if (xxbufp + n + 1 > xxbufe)
244 		xxflush(0);
245 	xp = xxalloc();
246 	xp->cmd = xc_write;
247 	xp->arg0 = row;
248 	xp->arg1 = col;
249 	xp->arg2 = n;
250 	xp->arg3 = m;
251 	xp->buf = xxbufp;
252 	bcopy(p, xxbufp, n);
253 	xxbufp += n;
254 	*xxbufp++ = char_sep;
255 }
256