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