5e66e17e29f4689cad445fdd194ce42e040af960
[dragonfly.git] / usr.bin / window / xx.c
1 /*      $NetBSD: xx.c,v 1.7 2003/08/07 11:17:46 agc 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
38 static char sccsid[] = "@(#)xx.c        8.1 (Berkeley) 6/6/93";
39 #else
40 __RCSID("$NetBSD: xx.c,v 1.7 2003/08/07 11:17:46 agc 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
52 int
53 xxinit(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
71 void
72 xxstart(void)
73 {
74         (*tt.tt_start)();
75         if (tt.tt_ntoken > 0)
76                 ccstart();
77         xxreset1();                     /* might be a restart */
78 }
79
80 void
81 xxreset(void)
82 {
83         if (tt.tt_ntoken > 0)
84                 ccreset();
85         xxreset1();
86         (*tt.tt_reset)();
87 }
88
89 void
90 xxreset1(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
102 void
103 xxend(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
119 struct xx *
120 xxalloc(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
140 void
141 xxfree(struct xx *xp)
142 {
143         xp->link = xx_freelist;
144         xx_freelist = xp;
145 }
146
147 void
148 xxmove(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
160 void
161 xxscroll(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
178 void
179 xxinschar(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
191 void
192 xxinsspace(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
208 void
209 xxdelchar(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
225 void
226 xxclear(void)
227 {
228         struct xx *xp;
229
230         xxreset1();
231         xp = xxalloc();
232         xp->cmd = xc_clear;
233 }
234
235 void
236 xxclreos(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
245 void
246 xxclreol(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
255 void
256 xxwrite(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 }