xref: /original-bsd/usr.bin/window/xx.c (revision 3b6250d9)
1 /*
2  * Copyright (c) 1989 Regents of the University of California.
3  * 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	3.6 (Berkeley) 06/06/90";
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 	xxreset();			/* might be a restart */
43 }
44 
45 xxend()
46 {
47 	if (tt.tt_scroll_top != 0 || tt.tt_scroll_bot != tt.tt_nrow - 1)
48 		/* tt.tt_setscroll is known to be defined */
49 		(*tt.tt_setscroll)(0, tt.tt_nrow - 1);
50 	if (tt.tt_modes)
51 		(*tt.tt_setmodes)(0);
52 	if (tt.tt_scroll_down)
53 		(*tt.tt_scroll_down)(1);
54 	(*tt.tt_move)(tt.tt_nrow - 1, 0);
55 	if (tt.tt_ntoken > 0)
56 		ccend();
57 	(*tt.tt_end)();
58 	(*tt.tt_flush)();
59 }
60 
61 struct xx *
62 xxalloc()
63 {
64 	register struct xx *xp;
65 
66 	if (xxbufp > xxbufe)
67 		abort();
68 	if ((xp = xx_freelist) == 0)
69 		/* XXX can't deal with failure */
70 		xp = (struct xx *) malloc((unsigned) sizeof *xp);
71 	else
72 		xx_freelist = xp->link;
73 	if (xx_head == 0)
74 		xx_head = xp;
75 	else
76 		xx_tail->link = xp;
77 	xx_tail = xp;
78 	xp->link = 0;
79 	return xp;
80 }
81 
82 xxfree(xp)
83 	register struct xx *xp;
84 {
85 	xp->link = xx_freelist;
86 	xx_freelist = xp;
87 }
88 
89 xxmove(row, col)
90 {
91 	register struct xx *xp = xx_tail;
92 
93 	if (xp == 0 || xp->cmd != xc_move) {
94 		xp = xxalloc();
95 		xp->cmd = xc_move;
96 	}
97 	xp->arg0 = row;
98 	xp->arg1 = col;
99 }
100 
101 xxscroll(dir, top, bot)
102 {
103 	register struct xx *xp = xx_tail;
104 
105 	if (xp != 0 && xp->cmd == xc_scroll &&
106 	    xp->arg1 == top && xp->arg2 == bot &&
107 	    (xp->arg0 < 0 && dir < 0 || xp->arg0 > 0 && dir > 0)) {
108 		xp->arg0 += dir;
109 		return;
110 	}
111 	xp = xxalloc();
112 	xp->cmd = xc_scroll;
113 	xp->arg0 = dir;
114 	xp->arg1 = top;
115 	xp->arg2 = bot;
116 }
117 
118 xxinschar(row, col, c, m)
119 {
120 	register struct xx *xp;
121 
122 	xp = xxalloc();
123 	xp->cmd = xc_inschar;
124 	xp->arg0 = row;
125 	xp->arg1 = col;
126 	xp->arg2 = c;
127 	xp->arg3 = m;
128 }
129 
130 xxinsspace(row, col)
131 {
132 	register struct xx *xp = xx_tail;
133 
134 	if (xp != 0 && xp->cmd == xc_insspace && xp->arg0 == row &&
135 	    col >= xp->arg1 && col <= xp->arg1 + xp->arg2) {
136 		xp->arg2++;
137 		return;
138 	}
139 	xp = xxalloc();
140 	xp->cmd = xc_insspace;
141 	xp->arg0 = row;
142 	xp->arg1 = col;
143 	xp->arg2 = 1;
144 }
145 
146 xxdelchar(row, col)
147 {
148 	register struct xx *xp = xx_tail;
149 
150 	if (xp != 0 && xp->cmd == xc_delchar &&
151 	    xp->arg0 == row && xp->arg1 == col) {
152 		xp->arg2++;
153 		return;
154 	}
155 	xp = xxalloc();
156 	xp->cmd = xc_delchar;
157 	xp->arg0 = row;
158 	xp->arg1 = col;
159 	xp->arg2 = 1;
160 }
161 
162 xxclear()
163 {
164 	register struct xx *xp;
165 
166 	xxreset();
167 	xp = xxalloc();
168 	xp->cmd = xc_clear;
169 }
170 
171 xxclreos(row, col)
172 {
173 	register struct xx *xp = xxalloc();
174 
175 	xp->cmd = xc_clreos;
176 	xp->arg0 = row;
177 	xp->arg1 = col;
178 }
179 
180 xxclreol(row, col)
181 {
182 	register struct xx *xp = xxalloc();
183 
184 	xp->cmd = xc_clreol;
185 	xp->arg0 = row;
186 	xp->arg1 = col;
187 }
188 
189 xxwrite(row, col, p, n, m)
190 	char *p;
191 {
192 	register struct xx *xp;
193 
194 	if (xxbufp + n + 1 > xxbufe)
195 		xxflush(0);
196 	xp = xxalloc();
197 	xp->cmd = xc_write;
198 	xp->arg0 = row;
199 	xp->arg1 = col;
200 	xp->arg2 = n;
201 	xp->arg3 = m;
202 	xp->buf = xxbufp;
203 	bcopy(p, xxbufp, n);
204 	xxbufp += n;
205 	*xxbufp++ = char_sep;
206 }
207 
208 xxreset()
209 {
210 	register struct xx *xp, *xq;
211 
212 	for (xp = xx_head; xp != 0; xp = xq) {
213 		xq = xp->link;
214 		xxfree(xp);
215 	}
216 	xx_tail = xx_head = 0;
217 	xxbufp = xxbuf;
218 }
219