xref: /original-bsd/usr.bin/window/ttzapple.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[] = "@(#)ttzapple.c	8.1 (Berkeley) 06/06/93";
13 #endif /* not lint */
14 
15 #include "ww.h"
16 #include "tt.h"
17 #include "char.h"
18 
19 /*
20 zz|zapple|perfect apple:\
21 	:am:pt:co#80:li#24:le=^H:nd=^F:up=^K:do=^J:\
22 	:ho=\E0:ll=\E1:cm=\E=%+ %+ :ch=\E<%+ :cv=\E>%+ :\
23 	:cl=\E4:ce=\E2:cd=\E3:rp=\E@%.%+ :\
24 	:so=\E+:se=\E-:\
25 	:dc=\Ec:DC=\EC%+ :ic=\Ei:IC=\EI%+ :\
26 	:al=\Ea:AL=\EA%+ :dl=\Ed:DL=\ED%+ :\
27 	:sf=\Ef:SF=\EF%+ :sr=\Er:SR=\ER%+ :cs=\E?%+ %+ :\
28 	:is=\E-\ET :
29 */
30 
31 #define NCOL		80
32 #define NROW		24
33 #define TOKEN_MAX	32
34 
35 extern short gen_frame[];
36 
37 	/* for error correction */
38 int zz_ecc;
39 int zz_lastc;
40 
41 	/* for checkpointing */
42 int zz_sum;
43 
44 zz_setmodes(new)
45 {
46 	if (new & WWM_REV) {
47 		if ((tt.tt_modes & WWM_REV) == 0)
48 			ttesc('+');
49 	} else
50 		if (tt.tt_modes & WWM_REV)
51 			ttesc('-');
52 	tt.tt_modes = new;
53 }
54 
55 zz_insline(n)
56 {
57 	if (n == 1)
58 		ttesc('a');
59 	else {
60 		ttesc('A');
61 		ttputc(n + ' ');
62 	}
63 }
64 
65 zz_delline(n)
66 {
67 	if (n == 1)
68 		ttesc('d');
69 	else {
70 		ttesc('D');
71 		ttputc(n + ' ');
72 	}
73 }
74 
75 zz_putc(c)
76 	char c;
77 {
78 	if (tt.tt_nmodes != tt.tt_modes)
79 		zz_setmodes(tt.tt_nmodes);
80 	ttputc(c);
81 	if (++tt.tt_col == NCOL)
82 		tt.tt_col = 0, tt.tt_row++;
83 }
84 
85 zz_write(p, n)
86 	register char *p;
87 	register n;
88 {
89 	if (tt.tt_nmodes != tt.tt_modes)
90 		zz_setmodes(tt.tt_nmodes);
91 	ttwrite(p, n);
92 	tt.tt_col += n;
93 	if (tt.tt_col == NCOL)
94 		tt.tt_col = 0, tt.tt_row++;
95 }
96 
97 zz_move(row, col)
98 	register row, col;
99 {
100 	register x;
101 
102 	if (tt.tt_row == row) {
103 same_row:
104 		if ((x = col - tt.tt_col) == 0)
105 			return;
106 		if (col == 0) {
107 			ttctrl('m');
108 			goto out;
109 		}
110 		switch (x) {
111 		case 2:
112 			ttctrl('f');
113 		case 1:
114 			ttctrl('f');
115 			goto out;
116 		case -2:
117 			ttctrl('h');
118 		case -1:
119 			ttctrl('h');
120 			goto out;
121 		}
122 		if ((col & 7) == 0 && x > 0 && x <= 16) {
123 			ttctrl('i');
124 			if (x > 8)
125 				ttctrl('i');
126 			goto out;
127 		}
128 		ttesc('<');
129 		ttputc(col + ' ');
130 		goto out;
131 	}
132 	if (tt.tt_col == col) {
133 		switch (row - tt.tt_row) {
134 		case 2:
135 			ttctrl('j');
136 		case 1:
137 			ttctrl('j');
138 			goto out;
139 		case -2:
140 			ttctrl('k');
141 		case -1:
142 			ttctrl('k');
143 			goto out;
144 		}
145 		if (col == 0) {
146 			if (row == 0)
147 				goto home;
148 			if (row == NROW - 1)
149 				goto ll;
150 		}
151 		ttesc('>');
152 		ttputc(row + ' ');
153 		goto out;
154 	}
155 	if (col == 0) {
156 		if (row == 0) {
157 home:
158 			ttesc('0');
159 			goto out;
160 		}
161 		if (row == tt.tt_row + 1) {
162 			/*
163 			 * Do newline first to match the sequence
164 			 * for scroll down and return
165 			 */
166 			ttctrl('j');
167 			ttctrl('m');
168 			goto out;
169 		}
170 		if (row == NROW - 1) {
171 ll:
172 			ttesc('1');
173 			goto out;
174 		}
175 	}
176 	/* favor local motion for better compression */
177 	if (row == tt.tt_row + 1) {
178 		ttctrl('j');
179 		goto same_row;
180 	}
181 	if (row == tt.tt_row - 1) {
182 		ttctrl('k');
183 		goto same_row;
184 	}
185 	ttesc('=');
186 	ttputc(' ' + row);
187 	ttputc(' ' + col);
188 out:
189 	tt.tt_col = col;
190 	tt.tt_row = row;
191 }
192 
193 zz_start()
194 {
195 	ttesc('T');
196 	ttputc(TOKEN_MAX + ' ');
197 	ttesc('U');
198 	ttputc('!');
199 	zz_ecc = 1;
200 	zz_lastc = -1;
201 	ttesc('v');
202 	ttflush();
203 	zz_sum = 0;
204 	zz_setscroll(0, NROW - 1);
205 	zz_clear();
206 	zz_setmodes(0);
207 }
208 
209 zz_reset()
210 {
211 	zz_setscroll(0, NROW - 1);
212 	tt.tt_modes = WWM_REV;
213 	zz_setmodes(0);
214 	tt.tt_col = tt.tt_row = -10;
215 }
216 
217 zz_end()
218 {
219 	ttesc('T');
220 	ttputc(' ');
221 	ttesc('U');
222 	ttputc(' ');
223 	zz_ecc = 0;
224 }
225 
226 zz_clreol()
227 {
228 	ttesc('2');
229 }
230 
231 zz_clreos()
232 {
233 	ttesc('3');
234 }
235 
236 zz_clear()
237 {
238 	ttesc('4');
239 	tt.tt_col = tt.tt_row = 0;
240 }
241 
242 zz_insspace(n)
243 {
244 	if (n == 1)
245 		ttesc('i');
246 	else {
247 		ttesc('I');
248 		ttputc(n + ' ');
249 	}
250 }
251 
252 zz_delchar(n)
253 {
254 	if (n == 1)
255 		ttesc('c');
256 	else {
257 		ttesc('C');
258 		ttputc(n + ' ');
259 	}
260 }
261 
262 zz_scroll_down(n)
263 {
264 	if (n == 1)
265 		if (tt.tt_row == NROW - 1)
266 			ttctrl('j');
267 		else
268 			ttesc('f');
269 	else {
270 		ttesc('F');
271 		ttputc(n + ' ');
272 	}
273 }
274 
275 zz_scroll_up(n)
276 {
277 	if (n == 1)
278 		ttesc('r');
279 	else {
280 		ttesc('R');
281 		ttputc(n + ' ');
282 	}
283 }
284 
285 zz_setscroll(top, bot)
286 {
287 	ttesc('?');
288 	ttputc(top + ' ');
289 	ttputc(bot + ' ');
290 	tt.tt_scroll_top = top;
291 	tt.tt_scroll_bot = bot;
292 }
293 
294 int zz_debug = 0;
295 
296 zz_set_token(t, s, n)
297 	char *s;
298 {
299 	if (tt.tt_nmodes != tt.tt_modes)
300 		zz_setmodes(tt.tt_nmodes);
301 	if (zz_debug) {
302 		char buf[100];
303 		zz_setmodes(WWM_REV);
304 		(void) sprintf(buf, "%02x=", t);
305 		ttputs(buf);
306 		tt.tt_col += 3;
307 	}
308 	ttputc(0x80);
309 	ttputc(t + 1);
310 	s[n - 1] |= 0x80;
311 	ttwrite(s, n);
312 	s[n - 1] &= ~0x80;
313 }
314 
315 /*ARGSUSED*/
316 zz_put_token(t, s, n)
317 	char *s;
318 {
319 	if (tt.tt_nmodes != tt.tt_modes)
320 		zz_setmodes(tt.tt_nmodes);
321 	if (zz_debug) {
322 		char buf[100];
323 		zz_setmodes(WWM_REV);
324 		(void) sprintf(buf, "%02x>", t);
325 		ttputs(buf);
326 		tt.tt_col += 3;
327 	}
328 	ttputc(t + 0x81);
329 }
330 
331 zz_rint(p, n)
332 	char *p;
333 {
334 	register i;
335 	register char *q;
336 
337 	if (!zz_ecc)
338 		return n;
339 	for (i = n, q = p; --i >= 0;) {
340 		register c = (unsigned char) *p++;
341 
342 		if (zz_lastc == 0) {
343 			switch (c) {
344 			case 0:
345 				*q++ = 0;
346 				zz_lastc = -1;
347 				break;
348 			case 1:		/* start input ecc */
349 				zz_ecc = 2;
350 				zz_lastc = -1;
351 				wwnreadstat++;
352 				break;
353 			case 2:		/* ack checkpoint */
354 				tt.tt_ack = 1;
355 				zz_lastc = -1;
356 				wwnreadack++;
357 				break;
358 			case 3:		/* nack checkpoint */
359 				tt.tt_ack = -1;
360 				zz_lastc = -1;
361 				wwnreadnack++;
362 				break;
363 			default:
364 				zz_lastc = c;
365 				wwnreadec++;
366 			}
367 		} else if (zz_ecc == 1) {
368 			if (c)
369 				*q++ = c;
370 			else
371 				zz_lastc = 0;
372 		} else {
373 			if (zz_lastc < 0) {
374 				zz_lastc = c;
375 			} else if (zz_lastc == c) {
376 				*q++ = zz_lastc;
377 				zz_lastc = -1;
378 			} else {
379 				wwnreadec++;
380 				zz_lastc = c;
381 			}
382 		}
383 	}
384 	return q - (p - n);
385 }
386 
387 zz_checksum(p, n)
388 	register char *p;
389 	register n;
390 {
391 	while (--n >= 0) {
392 		register c = *p++ & 0x7f;
393 		c ^= zz_sum;
394 		zz_sum = c << 1 | c >> 11 & 1;
395 	}
396 }
397 
398 zz_compress(flag)
399 {
400 	if (flag)
401 		tt.tt_checksum = 0;
402 	else
403 		tt.tt_checksum = zz_checksum;
404 }
405 
406 zz_checkpoint()
407 {
408 	static char x[] = { ctrl('['), 'V', 0, 0 };
409 
410 	zz_checksum(x, sizeof x);
411 	ttesc('V');
412 	ttputc(' ' + (zz_sum & 0x3f));
413 	ttputc(' ' + (zz_sum >> 6 & 0x3f));
414 	ttflush();
415 	zz_sum = 0;
416 }
417 
418 tt_zapple()
419 {
420 	tt.tt_insspace = zz_insspace;
421 	tt.tt_delchar = zz_delchar;
422 	tt.tt_insline = zz_insline;
423 	tt.tt_delline = zz_delline;
424 	tt.tt_clreol = zz_clreol;
425 	tt.tt_clreos = zz_clreos;
426 	tt.tt_scroll_down = zz_scroll_down;
427 	tt.tt_scroll_up = zz_scroll_up;
428 	tt.tt_setscroll = zz_setscroll;
429 	tt.tt_availmodes = WWM_REV;
430 	tt.tt_wrap = 1;
431 	tt.tt_retain = 0;
432 	tt.tt_ncol = NCOL;
433 	tt.tt_nrow = NROW;
434 	tt.tt_start = zz_start;
435 	tt.tt_reset = zz_reset;
436 	tt.tt_end = zz_end;
437 	tt.tt_write = zz_write;
438 	tt.tt_putc = zz_putc;
439 	tt.tt_move = zz_move;
440 	tt.tt_clear = zz_clear;
441 	tt.tt_setmodes = zz_setmodes;
442 	tt.tt_frame = gen_frame;
443 	tt.tt_padc = TT_PADC_NONE;
444 	tt.tt_ntoken = 127;
445 	tt.tt_set_token = zz_set_token;
446 	tt.tt_put_token = zz_put_token;
447 	tt.tt_token_min = 1;
448 	tt.tt_token_max = TOKEN_MAX;
449 	tt.tt_set_token_cost = 2;
450 	tt.tt_put_token_cost = 1;
451 	tt.tt_compress = zz_compress;
452 	tt.tt_checksum = zz_checksum;
453 	tt.tt_checkpoint = zz_checkpoint;
454 	tt.tt_reset = zz_reset;
455 	tt.tt_rint = zz_rint;
456 	return 0;
457 }
458