xref: /original-bsd/usr.bin/window/xx.c (revision 7b081c7c)
1 /*
2  * Copyright (c) 1989 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 static char sccsid[] = "@(#)xx.c	3.4 (Berkeley) 09/15/89";
20 #endif /* not lint */
21 
22 #include "ww.h"
23 #include "xx.h"
24 #include "tt.h"
25 
26 xxinit()
27 {
28 	if (ttinit() < 0)
29 		return -1;
30 	xxbufsize = tt.tt_nrow * tt.tt_ncol * 2;
31 	/* ccinit may choose to change xxbufsize */
32 	if (tt.tt_ntoken > 0 && ccinit() < 0)
33 		return -1;
34 	xxbuf = malloc((unsigned) xxbufsize * sizeof *xxbuf);
35 	if (xxbuf == 0) {
36 		wwerrno = WWE_NOMEM;
37 		return -1;
38 	}
39 	xxbufp = xxbuf;
40 	xxbufe = xxbuf + xxbufsize;
41 	return 0;
42 }
43 
44 xxstart()
45 {
46 	(*tt.tt_start)();
47 	if (tt.tt_ntoken > 0)
48 		ccstart();
49 	xxreset();			/* might be a restart */
50 }
51 
52 xxend()
53 {
54 	if (tt.tt_scroll_top != 0 || tt.tt_scroll_bot != tt.tt_nrow - 1)
55 		/* tt.tt_setscroll is known to be defined */
56 		(*tt.tt_setscroll)(0, tt.tt_nrow - 1);
57 	if (tt.tt_modes)
58 		(*tt.tt_setmodes)(0);
59 	if (tt.tt_scroll_down)
60 		(*tt.tt_scroll_down)(1);
61 	(*tt.tt_move)(tt.tt_nrow - 1, 0);
62 	if (tt.tt_ntoken > 0)
63 		ccend();
64 	(*tt.tt_end)();
65 	(*tt.tt_flush)();
66 }
67 
68 struct xx *
69 xxalloc()
70 {
71 	register struct xx *xp;
72 
73 	if (xxbufp > xxbufe)
74 		abort();
75 	if ((xp = xx_freelist) == 0)
76 		/* XXX can't deal with failure */
77 		xp = (struct xx *) malloc((unsigned) sizeof *xp);
78 	else
79 		xx_freelist = xp->link;
80 	if (xx_head == 0)
81 		xx_head = xp;
82 	else
83 		xx_tail->link = xp;
84 	xx_tail = xp;
85 	xp->link = 0;
86 	return xp;
87 }
88 
89 xxfree(xp)
90 	register struct xx *xp;
91 {
92 	xp->link = xx_freelist;
93 	xx_freelist = xp;
94 }
95 
96 xxmove(row, col)
97 {
98 	register struct xx *xp = xx_tail;
99 
100 	if (xp == 0 || xp->cmd != xc_move) {
101 		xp = xxalloc();
102 		xp->cmd = xc_move;
103 	}
104 	xp->arg0 = row;
105 	xp->arg1 = col;
106 }
107 
108 xxscroll(dir, top, bot)
109 {
110 	register struct xx *xp = xx_tail;
111 
112 	if (xp != 0 && xp->cmd == xc_scroll &&
113 	    xp->arg1 == top && xp->arg2 == bot &&
114 	    (xp->arg0 < 0 && dir < 0 || xp->arg0 > 0 && dir > 0)) {
115 		xp->arg0 += dir;
116 		return;
117 	}
118 	xp = xxalloc();
119 	xp->cmd = xc_scroll;
120 	xp->arg0 = dir;
121 	xp->arg1 = top;
122 	xp->arg2 = bot;
123 }
124 
125 xxinschar(row, col, c, m)
126 {
127 	register struct xx *xp;
128 
129 	xp = xxalloc();
130 	xp->cmd = xc_inschar;
131 	xp->arg0 = row;
132 	xp->arg1 = col;
133 	xp->arg2 = c;
134 	xp->arg3 = m;
135 }
136 
137 xxinsspace(row, col)
138 {
139 	register struct xx *xp = xx_tail;
140 
141 	if (xp != 0 && xp->cmd == xc_insspace && xp->arg0 == row &&
142 	    col >= xp->arg1 && col <= xp->arg1 + xp->arg2) {
143 		xp->arg2++;
144 		return;
145 	}
146 	xp = xxalloc();
147 	xp->cmd = xc_insspace;
148 	xp->arg0 = row;
149 	xp->arg1 = col;
150 	xp->arg2 = 1;
151 }
152 
153 xxdelchar(row, col)
154 {
155 	register struct xx *xp = xx_tail;
156 
157 	if (xp != 0 && xp->cmd == xc_delchar &&
158 	    xp->arg0 == row && xp->arg1 == col) {
159 		xp->arg2++;
160 		return;
161 	}
162 	xp = xxalloc();
163 	xp->cmd = xc_delchar;
164 	xp->arg0 = row;
165 	xp->arg1 = col;
166 	xp->arg2 = 1;
167 }
168 
169 xxclear()
170 {
171 	register struct xx *xp;
172 
173 	xxreset();
174 	xp = xxalloc();
175 	xp->cmd = xc_clear;
176 }
177 
178 xxclreos(row, col)
179 {
180 	register struct xx *xp = xxalloc();
181 
182 	xp->cmd = xc_clreos;
183 	xp->arg0 = row;
184 	xp->arg1 = col;
185 }
186 
187 xxclreol(row, col)
188 {
189 	register struct xx *xp = xxalloc();
190 
191 	xp->cmd = xc_clreol;
192 	xp->arg0 = row;
193 	xp->arg1 = col;
194 }
195 
196 xxwrite(row, col, p, n, m)
197 	char *p;
198 {
199 	register struct xx *xp;
200 
201 	if (xxbufp + n + 1 > xxbufe)
202 		xxflush(0);
203 	xp = xxalloc();
204 	xp->cmd = xc_write;
205 	xp->arg0 = row;
206 	xp->arg1 = col;
207 	xp->arg2 = n;
208 	xp->arg3 = m;
209 	xp->buf = xxbufp;
210 	bcopy(p, xxbufp, n);
211 	xxbufp += n;
212 	*xxbufp++ = char_sep;
213 }
214 
215 xxreset()
216 {
217 	register struct xx *xp, *xq;
218 
219 	for (xp = xx_head; xp != 0; xp = xq) {
220 		xq = xp->link;
221 		xxfree(xp);
222 	}
223 	xx_tail = xx_head = 0;
224 	xxbufp = xxbuf;
225 }
226