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