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