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