Merge branch 'vendor/OPENSSL'
[dragonfly.git] / usr.bin / window / xx.c
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 }