xref: /original-bsd/usr.bin/window/xx.c (revision c3e32dec)
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  * %sccs.include.redist.c%
9  */
10 
11 #ifndef lint
12 static char sccsid[] = "@(#)xx.c	8.1 (Berkeley) 06/06/93";
13 #endif /* not lint */
14 
15 #include "ww.h"
16 #include "xx.h"
17 #include "tt.h"
18 
19 xxinit()
20 {
21 	if (ttinit() < 0)
22 		return -1;
23 	xxbufsize = tt.tt_nrow * tt.tt_ncol * 2;
24 	/* ccinit may choose to change xxbufsize */
25 	if (tt.tt_ntoken > 0 && ccinit() < 0)
26 		return -1;
27 	xxbuf = malloc((unsigned) xxbufsize * sizeof *xxbuf);
28 	if (xxbuf == 0) {
29 		wwerrno = WWE_NOMEM;
30 		return -1;
31 	}
32 	xxbufp = xxbuf;
33 	xxbufe = xxbuf + xxbufsize;
34 	return 0;
35 }
36 
37 xxstart()
38 {
39 	(*tt.tt_start)();
40 	if (tt.tt_ntoken > 0)
41 		ccstart();
42 	xxreset1();			/* might be a restart */
43 }
44 
45 xxreset()
46 {
47 	if (tt.tt_ntoken > 0)
48 		ccreset();
49 	xxreset1();
50 	(*tt.tt_reset)();
51 }
52 
53 xxreset1()
54 {
55 	register struct xx *xp, *xq;
56 
57 	for (xp = xx_head; xp != 0; xp = xq) {
58 		xq = xp->link;
59 		xxfree(xp);
60 	}
61 	xx_tail = xx_head = 0;
62 	xxbufp = xxbuf;
63 }
64 
65 xxend()
66 {
67 	if (tt.tt_scroll_top != 0 || tt.tt_scroll_bot != tt.tt_nrow - 1)
68 		/* tt.tt_setscroll is known to be defined */
69 		(*tt.tt_setscroll)(0, tt.tt_nrow - 1);
70 	if (tt.tt_modes)
71 		(*tt.tt_setmodes)(0);
72 	if (tt.tt_scroll_down)
73 		(*tt.tt_scroll_down)(1);
74 	(*tt.tt_move)(tt.tt_nrow - 1, 0);
75 	if (tt.tt_ntoken > 0)
76 		ccend();
77 	(*tt.tt_end)();
78 	ttflush();
79 }
80 
81 struct xx *
82 xxalloc()
83 {
84 	register struct xx *xp;
85 
86 	if (xxbufp > xxbufe)
87 		abort();
88 	if ((xp = xx_freelist) == 0)
89 		/* XXX can't deal with failure */
90 		xp = (struct xx *) malloc((unsigned) sizeof *xp);
91 	else
92 		xx_freelist = xp->link;
93 	if (xx_head == 0)
94 		xx_head = xp;
95 	else
96 		xx_tail->link = xp;
97 	xx_tail = xp;
98 	xp->link = 0;
99 	return xp;
100 }
101 
102 xxfree(xp)
103 	register struct xx *xp;
104 {
105 	xp->link = xx_freelist;
106 	xx_freelist = xp;
107 }
108 
109 xxmove(row, col)
110 {
111 	register struct xx *xp = xx_tail;
112 
113 	if (xp == 0 || xp->cmd != xc_move) {
114 		xp = xxalloc();
115 		xp->cmd = xc_move;
116 	}
117 	xp->arg0 = row;
118 	xp->arg1 = col;
119 }
120 
121 xxscroll(dir, top, bot)
122 {
123 	register struct xx *xp = xx_tail;
124 
125 	if (xp != 0 && xp->cmd == xc_scroll &&
126 	    xp->arg1 == top && xp->arg2 == bot &&
127 	    (xp->arg0 < 0 && dir < 0 || xp->arg0 > 0 && dir > 0)) {
128 		xp->arg0 += dir;
129 		return;
130 	}
131 	xp = xxalloc();
132 	xp->cmd = xc_scroll;
133 	xp->arg0 = dir;
134 	xp->arg1 = top;
135 	xp->arg2 = bot;
136 }
137 
138 xxinschar(row, col, c, m)
139 {
140 	register struct xx *xp;
141 
142 	xp = xxalloc();
143 	xp->cmd = xc_inschar;
144 	xp->arg0 = row;
145 	xp->arg1 = col;
146 	xp->arg2 = c;
147 	xp->arg3 = m;
148 }
149 
150 xxinsspace(row, col)
151 {
152 	register struct xx *xp = xx_tail;
153 
154 	if (xp != 0 && xp->cmd == xc_insspace && xp->arg0 == row &&
155 	    col >= xp->arg1 && col <= xp->arg1 + xp->arg2) {
156 		xp->arg2++;
157 		return;
158 	}
159 	xp = xxalloc();
160 	xp->cmd = xc_insspace;
161 	xp->arg0 = row;
162 	xp->arg1 = col;
163 	xp->arg2 = 1;
164 }
165 
166 xxdelchar(row, col)
167 {
168 	register struct xx *xp = xx_tail;
169 
170 	if (xp != 0 && xp->cmd == xc_delchar &&
171 	    xp->arg0 == row && xp->arg1 == col) {
172 		xp->arg2++;
173 		return;
174 	}
175 	xp = xxalloc();
176 	xp->cmd = xc_delchar;
177 	xp->arg0 = row;
178 	xp->arg1 = col;
179 	xp->arg2 = 1;
180 }
181 
182 xxclear()
183 {
184 	register struct xx *xp;
185 
186 	xxreset1();
187 	xp = xxalloc();
188 	xp->cmd = xc_clear;
189 }
190 
191 xxclreos(row, col)
192 {
193 	register struct xx *xp = xxalloc();
194 
195 	xp->cmd = xc_clreos;
196 	xp->arg0 = row;
197 	xp->arg1 = col;
198 }
199 
200 xxclreol(row, col)
201 {
202 	register struct xx *xp = xxalloc();
203 
204 	xp->cmd = xc_clreol;
205 	xp->arg0 = row;
206 	xp->arg1 = col;
207 }
208 
209 xxwrite(row, col, p, n, m)
210 	char *p;
211 {
212 	register struct xx *xp;
213 
214 	if (xxbufp + n + 1 > xxbufe)
215 		xxflush(0);
216 	xp = xxalloc();
217 	xp->cmd = xc_write;
218 	xp->arg0 = row;
219 	xp->arg1 = col;
220 	xp->arg2 = n;
221 	xp->arg3 = m;
222 	xp->buf = xxbufp;
223 	bcopy(p, xxbufp, n);
224 	xxbufp += n;
225 	*xxbufp++ = char_sep;
226 }
227