xref: /dragonfly/usr.bin/window/ttzapple.c (revision 235099c3)
1 /*	$NetBSD: ttzapple.c,v 1.9 2009/04/14 08:50:06 lukem Exp $	*/
2 
3 /*
4  * Copyright (c) 1989, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Edward Wang at The University of California, Berkeley.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 
35 #include <sys/cdefs.h>
36 #ifndef lint
37 #if 0
38 static char sccsid[] = "@(#)ttzapple.c	8.1 (Berkeley) 6/6/93";
39 #else
40 __RCSID("$NetBSD: ttzapple.c,v 1.9 2009/04/14 08:50:06 lukem Exp $");
41 #endif
42 #endif /* not lint */
43 
44 #include <stdio.h>
45 #include "ww.h"
46 #include "tt.h"
47 #include "char.h"
48 
49 /*
50 zz|zapple|perfect apple:\
51 	:am:pt:co#80:li#24:le=^H:nd=^F:up=^K:do=^J:\
52 	:ho=\E0:ll=\E1:cm=\E=%+ %+ :ch=\E<%+ :cv=\E>%+ :\
53 	:cl=\E4:ce=\E2:cd=\E3:rp=\E@%.%+ :\
54 	:so=\E+:se=\E-:\
55 	:dc=\Ec:DC=\EC%+ :ic=\Ei:IC=\EI%+ :\
56 	:al=\Ea:AL=\EA%+ :dl=\Ed:DL=\ED%+ :\
57 	:sf=\Ef:SF=\EF%+ :sr=\Er:SR=\ER%+ :cs=\E?%+ %+ :\
58 	:is=\E-\ET :
59 */
60 
61 #define NCOL		80
62 #define NROW		24
63 #define TOKEN_MAX	32
64 
65 extern short gen_frame[];
66 
67 	/* for error correction */
68 int zz_ecc;
69 int zz_lastc;
70 
71 	/* for checkpointing */
72 int zz_sum;
73 
74 void	zz_checkpoint(void);
75 void	zz_checksum(char *, int);
76 void	zz_clear(void);
77 void	zz_clreol(void);
78 void	zz_clreos(void);
79 void	zz_compress(int);
80 void	zz_delchar(int);
81 void	zz_delline(int);
82 void	zz_end(void);
83 void	zz_insline(int);
84 void	zz_insspace(int);
85 void	zz_move(int, int);
86 void	zz_put_token(int, const char *, int);
87 void	zz_putc(char);
88 void	zz_reset(void);
89 int	zz_rint(char *, int);
90 void	zz_scroll_down(int);
91 void	zz_scroll_up(int);
92 void	zz_setmodes(int);
93 void	zz_setscroll(int, int);
94 void	zz_set_token(int, char *, int);
95 void	zz_start(void);
96 void	zz_write(const char *, int);
97 
98 void
99 zz_setmodes(int new)
100 {
101 	if (new & WWM_REV) {
102 		if ((tt.tt_modes & WWM_REV) == 0)
103 			ttesc('+');
104 	} else
105 		if (tt.tt_modes & WWM_REV)
106 			ttesc('-');
107 	tt.tt_modes = new;
108 }
109 
110 void
111 zz_insline(int n)
112 {
113 	if (n == 1)
114 		ttesc('a');
115 	else {
116 		ttesc('A');
117 		ttputc(n + ' ');
118 	}
119 }
120 
121 void
122 zz_delline(int n)
123 {
124 	if (n == 1)
125 		ttesc('d');
126 	else {
127 		ttesc('D');
128 		ttputc(n + ' ');
129 	}
130 }
131 
132 void
133 zz_putc(char c)
134 {
135 	if (tt.tt_nmodes != tt.tt_modes)
136 		zz_setmodes(tt.tt_nmodes);
137 	ttputc(c);
138 	if (++tt.tt_col == NCOL)
139 		tt.tt_col = 0, tt.tt_row++;
140 }
141 
142 void
143 zz_write(const char *p, int n)
144 {
145 	if (tt.tt_nmodes != tt.tt_modes)
146 		zz_setmodes(tt.tt_nmodes);
147 	ttwrite(p, n);
148 	tt.tt_col += n;
149 	if (tt.tt_col == NCOL)
150 		tt.tt_col = 0, tt.tt_row++;
151 }
152 
153 void
154 zz_move(int row, int col)
155 {
156 	int x;
157 
158 	if (tt.tt_row == row) {
159 same_row:
160 		if ((x = col - tt.tt_col) == 0)
161 			return;
162 		if (col == 0) {
163 			ttctrl('m');
164 			goto out;
165 		}
166 		switch (x) {
167 		case 2:
168 			ttctrl('f');
169 		case 1:
170 			ttctrl('f');
171 			goto out;
172 		case -2:
173 			ttctrl('h');
174 		case -1:
175 			ttctrl('h');
176 			goto out;
177 		}
178 		if ((col & 7) == 0 && x > 0 && x <= 16) {
179 			ttctrl('i');
180 			if (x > 8)
181 				ttctrl('i');
182 			goto out;
183 		}
184 		ttesc('<');
185 		ttputc(col + ' ');
186 		goto out;
187 	}
188 	if (tt.tt_col == col) {
189 		switch (row - tt.tt_row) {
190 		case 2:
191 			ttctrl('j');
192 		case 1:
193 			ttctrl('j');
194 			goto out;
195 		case -2:
196 			ttctrl('k');
197 		case -1:
198 			ttctrl('k');
199 			goto out;
200 		}
201 		if (col == 0) {
202 			if (row == 0)
203 				goto home;
204 			if (row == NROW - 1)
205 				goto ll;
206 		}
207 		ttesc('>');
208 		ttputc(row + ' ');
209 		goto out;
210 	}
211 	if (col == 0) {
212 		if (row == 0) {
213 home:
214 			ttesc('0');
215 			goto out;
216 		}
217 		if (row == tt.tt_row + 1) {
218 			/*
219 			 * Do newline first to match the sequence
220 			 * for scroll down and return
221 			 */
222 			ttctrl('j');
223 			ttctrl('m');
224 			goto out;
225 		}
226 		if (row == NROW - 1) {
227 ll:
228 			ttesc('1');
229 			goto out;
230 		}
231 	}
232 	/* favor local motion for better compression */
233 	if (row == tt.tt_row + 1) {
234 		ttctrl('j');
235 		goto same_row;
236 	}
237 	if (row == tt.tt_row - 1) {
238 		ttctrl('k');
239 		goto same_row;
240 	}
241 	ttesc('=');
242 	ttputc(' ' + row);
243 	ttputc(' ' + col);
244 out:
245 	tt.tt_col = col;
246 	tt.tt_row = row;
247 }
248 
249 void
250 zz_start(void)
251 {
252 	ttesc('T');
253 	ttputc(TOKEN_MAX + ' ');
254 	ttesc('U');
255 	ttputc('!');
256 	zz_ecc = 1;
257 	zz_lastc = -1;
258 	ttesc('v');
259 	ttflush();
260 	zz_sum = 0;
261 	zz_setscroll(0, NROW - 1);
262 	zz_clear();
263 	zz_setmodes(0);
264 }
265 
266 void
267 zz_reset(void)
268 {
269 	zz_setscroll(0, NROW - 1);
270 	tt.tt_modes = WWM_REV;
271 	zz_setmodes(0);
272 	tt.tt_col = tt.tt_row = -10;
273 }
274 
275 void
276 zz_end(void)
277 {
278 	ttesc('T');
279 	ttputc(' ');
280 	ttesc('U');
281 	ttputc(' ');
282 	zz_ecc = 0;
283 }
284 
285 void
286 zz_clreol(void)
287 {
288 	ttesc('2');
289 }
290 
291 void
292 zz_clreos(void)
293 {
294 	ttesc('3');
295 }
296 
297 void
298 zz_clear(void)
299 {
300 	ttesc('4');
301 	tt.tt_col = tt.tt_row = 0;
302 }
303 
304 void
305 zz_insspace(int n)
306 {
307 	if (n == 1)
308 		ttesc('i');
309 	else {
310 		ttesc('I');
311 		ttputc(n + ' ');
312 	}
313 }
314 
315 void
316 zz_delchar(int n)
317 {
318 	if (n == 1)
319 		ttesc('c');
320 	else {
321 		ttesc('C');
322 		ttputc(n + ' ');
323 	}
324 }
325 
326 void
327 zz_scroll_down(int n)
328 {
329 	if (n == 1) {
330 		if (tt.tt_row == NROW - 1)
331 			ttctrl('j');
332 		else
333 			ttesc('f');
334 	} else {
335 		ttesc('F');
336 		ttputc(n + ' ');
337 	}
338 }
339 
340 void
341 zz_scroll_up(int n)
342 {
343 	if (n == 1)
344 		ttesc('r');
345 	else {
346 		ttesc('R');
347 		ttputc(n + ' ');
348 	}
349 }
350 
351 void
352 zz_setscroll(int top, int bot)
353 {
354 	ttesc('?');
355 	ttputc(top + ' ');
356 	ttputc(bot + ' ');
357 	tt.tt_scroll_top = top;
358 	tt.tt_scroll_bot = bot;
359 }
360 
361 int zz_debug = 0;
362 
363 void
364 zz_set_token(int t, char *s, int n)
365 {
366 	if (tt.tt_nmodes != tt.tt_modes)
367 		zz_setmodes(tt.tt_nmodes);
368 	if (zz_debug) {
369 		char buf[100];
370 		zz_setmodes(WWM_REV);
371 		(void) sprintf(buf, "%02x=", t);
372 		ttputs(buf);
373 		tt.tt_col += 3;
374 	}
375 	ttputc(0x80);
376 	ttputc(t + 1);
377 	s[n - 1] |= 0x80;
378 	ttwrite(s, n);
379 	s[n - 1] &= ~0x80;
380 }
381 
382 void
383 zz_put_token(int t, const char *s __unused, int n __unused)
384 {
385 	if (tt.tt_nmodes != tt.tt_modes)
386 		zz_setmodes(tt.tt_nmodes);
387 	if (zz_debug) {
388 		char buf[100];
389 		zz_setmodes(WWM_REV);
390 		(void) sprintf(buf, "%02x>", t);
391 		ttputs(buf);
392 		tt.tt_col += 3;
393 	}
394 	ttputc(t + 0x81);
395 }
396 
397 int
398 zz_rint(char *p, int n)
399 {
400 	int i;
401 	char *q;
402 
403 	if (!zz_ecc)
404 		return n;
405 	for (i = n, q = p; --i >= 0;) {
406 		int c = (unsigned char) *p++;
407 
408 		if (zz_lastc == 0) {
409 			switch (c) {
410 			case 0:
411 				*q++ = 0;
412 				zz_lastc = -1;
413 				break;
414 			case 1:		/* start input ecc */
415 				zz_ecc = 2;
416 				zz_lastc = -1;
417 				wwnreadstat++;
418 				break;
419 			case 2:		/* ack checkpoint */
420 				tt.tt_ack = 1;
421 				zz_lastc = -1;
422 				wwnreadack++;
423 				break;
424 			case 3:		/* nack checkpoint */
425 				tt.tt_ack = -1;
426 				zz_lastc = -1;
427 				wwnreadnack++;
428 				break;
429 			default:
430 				zz_lastc = c;
431 				wwnreadec++;
432 			}
433 		} else if (zz_ecc == 1) {
434 			if (c)
435 				*q++ = c;
436 			else
437 				zz_lastc = 0;
438 		} else {
439 			if (zz_lastc < 0) {
440 				zz_lastc = c;
441 			} else if (zz_lastc == c) {
442 				*q++ = zz_lastc;
443 				zz_lastc = -1;
444 			} else {
445 				wwnreadec++;
446 				zz_lastc = c;
447 			}
448 		}
449 	}
450 	return q - (p - n);
451 }
452 
453 void
454 zz_checksum(char *p, int n)
455 {
456 	while (--n >= 0) {
457 		int c = *p++ & 0x7f;
458 		c ^= zz_sum;
459 		zz_sum = c << 1 | (c >> 11 & 1);
460 	}
461 }
462 
463 void
464 zz_compress(int flag)
465 {
466 	if (flag)
467 		tt.tt_checksum = 0;
468 	else
469 		tt.tt_checksum = zz_checksum;
470 }
471 
472 void
473 zz_checkpoint(void)
474 {
475 	static char x[] = { ctrl('['), 'V', 0, 0 };
476 
477 	zz_checksum(x, sizeof x);
478 	ttesc('V');
479 	ttputc(' ' + (zz_sum & 0x3f));
480 	ttputc(' ' + (zz_sum >> 6 & 0x3f));
481 	ttflush();
482 	zz_sum = 0;
483 }
484 
485 int
486 tt_zapple(void)
487 {
488 	tt.tt_insspace = zz_insspace;
489 	tt.tt_delchar = zz_delchar;
490 	tt.tt_insline = zz_insline;
491 	tt.tt_delline = zz_delline;
492 	tt.tt_clreol = zz_clreol;
493 	tt.tt_clreos = zz_clreos;
494 	tt.tt_scroll_down = zz_scroll_down;
495 	tt.tt_scroll_up = zz_scroll_up;
496 	tt.tt_setscroll = zz_setscroll;
497 	tt.tt_availmodes = WWM_REV;
498 	tt.tt_wrap = 1;
499 	tt.tt_retain = 0;
500 	tt.tt_ncol = NCOL;
501 	tt.tt_nrow = NROW;
502 	tt.tt_start = zz_start;
503 	tt.tt_reset = zz_reset;
504 	tt.tt_end = zz_end;
505 	tt.tt_write = zz_write;
506 	tt.tt_putc = zz_putc;
507 	tt.tt_move = zz_move;
508 	tt.tt_clear = zz_clear;
509 	tt.tt_setmodes = zz_setmodes;
510 	tt.tt_frame = gen_frame;
511 	tt.tt_padc = TT_PADC_NONE;
512 	tt.tt_ntoken = 127;
513 	tt.tt_set_token = zz_set_token;
514 	tt.tt_put_token = zz_put_token;
515 	tt.tt_token_min = 1;
516 	tt.tt_token_max = TOKEN_MAX;
517 	tt.tt_set_token_cost = 2;
518 	tt.tt_put_token_cost = 1;
519 	tt.tt_compress = zz_compress;
520 	tt.tt_checksum = zz_checksum;
521 	tt.tt_checkpoint = zz_checkpoint;
522 	tt.tt_reset = zz_reset;
523 	tt.tt_rint = zz_rint;
524 	return 0;
525 }
526