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