|
|
1.1 ! root 1: /*************************************************************************** ! 2: * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE * ! 3: * is provided to you without charge, and with no warranty. You may give * ! 4: * away copies of JOVE, including sources, provided that this notice is * ! 5: * included in all the files. * ! 6: ***************************************************************************/ ! 7: ! 8: #include "jove.h" ! 9: #include "io.h" ! 10: #include "ctype.h" ! 11: #include "termcap.h" ! 12: ! 13: #ifdef IBMPC ! 14: ! 15: /* here come the actual emulation routines */ ! 16: ! 17: #include <dos.h> ! 18: #include <conio.h> ! 19: ! 20: #define BYTE unsigned char ! 21: #define WORD unsigned int ! 22: ! 23: #ifdef MAC ! 24: # undef private ! 25: # define private ! 26: #endif ! 27: ! 28: #ifdef LINT_ARGS ! 29: private BYTE near get_mode(void); ! 30: ! 31: private WORD ! 32: near cur_page(void), ! 33: near get_cur(void); ! 34: ! 35: private void ! 36: near ch_out(BYTE, BYTE), ! 37: near clr_eop(void), ! 38: near cur_advance(void), ! 39: near cur_down(void), ! 40: near cur_left(void), ! 41: near cur_right(void), ! 42: near cur_up(void), ! 43: near line_feed(void), ! 44: near normfun(char), ! 45: near scr_win(int, BYTE, BYTE, BYTE, BYTE), ! 46: near set_cur(WORD), ! 47: near set_mode(BYTE), ! 48: near wherexy(BYTE *, BYTE *); ! 49: #else ! 50: private BYTE near get_mode(); ! 51: ! 52: private WORD ! 53: near cur_page(), ! 54: near get_cur(); ! 55: ! 56: private void ! 57: near ch_out(), ! 58: near clr_eop(), ! 59: near cur_advance(), ! 60: near cur_down(), ! 61: near cur_left(), ! 62: near cur_right(), ! 63: near cur_up(), ! 64: near line_feed(), ! 65: near normfun(), ! 66: near scr_win(), ! 67: near set_cur(), ! 68: near set_mode(), ! 69: near wherexy(); ! 70: #endif /* LINT_ARGS */ ! 71: ! 72: #ifdef MAC ! 73: # undef private ! 74: # define private static ! 75: #endif ! 76: ! 77: #define VIDEO 0x10 ! 78: ! 79: #define intr(n, r) int86(n, r, r); ! 80: ! 81: BYTE CHPL=80, ! 82: LPP=25, ! 83: CUR_PAGE=0, ! 84: C_ATTR = 0x07, ! 85: C_X=0, ! 86: C_Y=0; ! 87: ! 88: int Fgcolor = 7, ! 89: Bgcolor = 0, ! 90: Mdcolor = 0; ! 91: ! 92: void setcolor(fg, bg) ! 93: BYTE fg, bg; ! 94: { ! 95: C_ATTR = ((bg&0xf)<<4)|(fg&0xf); ! 96: } ! 97: ! 98: private ! 99: WORD near cur_page() ! 100: { ! 101: union REGS vr; ! 102: ! 103: vr.h.ah = 0x0f; ! 104: intr(VIDEO, &vr); ! 105: return(vr.h.bh); ! 106: } ! 107: ! 108: private ! 109: void near set_cur(xy) ! 110: WORD xy; ! 111: { ! 112: union REGS vr; ! 113: ! 114: vr.h.bh = CUR_PAGE; ! 115: vr.h.ah = 0x02; ! 116: vr.x.dx = xy; ! 117: intr(VIDEO, &vr); ! 118: } ! 119: ! 120: private ! 121: WORD near get_cur() ! 122: { ! 123: union REGS vr; ! 124: ! 125: vr.h.bh = CUR_PAGE; ! 126: vr.h.ah = 0x03; ! 127: intr(VIDEO, &vr); ! 128: return (vr.x.dx); ! 129: } ! 130: ! 131: private ! 132: BYTE near get_mode() ! 133: { ! 134: union REGS vr; ! 135: ! 136: vr.h.ah = 0x0f; ! 137: intr(VIDEO, &vr); ! 138: return(vr.h.al); ! 139: } ! 140: ! 141: BYTE lpp() ! 142: { ! 143: int far *regen = (int far *) 0x44C; ! 144: int what; ! 145: BYTE chpl(); ! 146: ! 147: what = (*regen&0xff00)/2/chpl(); ! 148: return (what > 43 ? 25 : what); ! 149: } ! 150: ! 151: private ! 152: void near set_mode(n) ! 153: BYTE n; ! 154: { ! 155: union REGS vr; ! 156: ! 157: vr.h.ah = 0x00; ! 158: vr.h.al = n; ! 159: intr(VIDEO, &vr); ! 160: } ! 161: ! 162: #define gotoxy(x,y) set_cur((x)<<8|((y)&0xff)) ! 163: #define cur_mov(x,y) set_cur((C_X=x)<<8|((C_Y=y)&0xff)) ! 164: ! 165: private ! 166: void near wherexy( x, y) ! 167: BYTE *x, *y; ! 168: { ! 169: register WORD xy; ! 170: ! 171: xy = get_cur(); ! 172: *x = xy>>8; ! 173: *y = xy&0xff; ! 174: } ! 175: ! 176: #define wherex() C_X ! 177: #define wherey() C_Y ! 178: ! 179: private ! 180: void near scr_win(no, ulr, ulc, lrr, lrc) ! 181: int no; ! 182: BYTE ulr, ulc, lrr, lrc; ! 183: { ! 184: union REGS vr; ! 185: ! 186: if (no >= 0) ! 187: vr.h.ah = 0x06; ! 188: else { ! 189: vr.h.ah = 0x07; ! 190: no = - no; ! 191: } ! 192: vr.h.al = no; ! 193: vr.x.cx = ulr<<8 | ulc; ! 194: vr.x.dx = lrr<<8 | lrc; ! 195: vr.h.bh = C_ATTR; ! 196: intr(VIDEO, &vr); ! 197: } ! 198: ! 199: BYTE chpl() ! 200: { ! 201: union REGS vr; ! 202: ! 203: vr.h.ah = 0x0f; ! 204: intr(VIDEO, &vr); ! 205: return(vr.h.ah); ! 206: } ! 207: ! 208: #define clr_page() scr_win(0, 0, 0, LPP-1, CHPL-1), \ ! 209: gotoxy(C_X = 0, C_Y = 0) ! 210: ! 211: private ! 212: void near cur_right() ! 213: { ! 214: if (C_Y < CHPL-1) ! 215: C_Y++; ! 216: gotoxy(C_X, C_Y); ! 217: } ! 218: ! 219: private ! 220: void near cur_up() ! 221: { ! 222: if (C_X) ! 223: C_X--; ! 224: gotoxy(C_X, C_Y); ! 225: } ! 226: ! 227: private ! 228: void near cur_left() ! 229: { ! 230: if (C_Y) ! 231: C_Y--; ! 232: gotoxy(C_X, C_Y); ! 233: } ! 234: ! 235: private ! 236: void near cur_down() ! 237: { ! 238: if (C_X < LPP-1) ! 239: C_X++; ! 240: gotoxy(C_X, C_Y); ! 241: } ! 242: ! 243: private ! 244: void near ch_out(c, n) ! 245: BYTE c, n; ! 246: { ! 247: union REGS vr; ! 248: ! 249: vr.h.ah = 0x09; ! 250: vr.h.al = c; ! 251: vr.h.bl = C_ATTR; ! 252: vr.h.bh = CUR_PAGE; ! 253: vr.x.cx = n; ! 254: intr(VIDEO, &vr); ! 255: } ! 256: ! 257: #define wrch(c) ch_out((c), 1), cur_advance() ! 258: ! 259: #define home_cur() gotoxy(C_X = 0, C_Y = 0) ! 260: ! 261: #define clr_eoln() ch_out(' ', CHPL-wherey()) ! 262: ! 263: private ! 264: void near clr_eop() ! 265: { ! 266: clr_eoln(); ! 267: scr_win(LPP-1-wherex(), wherex()+1, 0, LPP-1, CHPL-1); ! 268: } ! 269: ! 270: void init_43() ! 271: { ! 272: BYTE far *info = (BYTE far *) 0x487; ! 273: WORD far *CRTC = (WORD far *) 0x463; ! 274: union REGS vr; ! 275: WORD cur; ! 276: ! 277: CUR_PAGE = cur_page(); ! 278: CHPL = chpl(); ! 279: LPP = lpp(); ! 280: ! 281: if (get_mode()!=3) ! 282: set_mode(3); ! 283: cur = get_cur(); ! 284: ! 285: vr.x.ax = 0x1112; ! 286: vr.h.bl = 0; ! 287: intr(VIDEO, &vr); ! 288: ! 289: *info |= 1; ! 290: vr.x.ax = 0x0100; ! 291: vr.h.bh = 0; ! 292: vr.x.cx = 0x0600; ! 293: intr(VIDEO, &vr); ! 294: ! 295: outp(*CRTC, 0x14); ! 296: outp(*CRTC+1, 0x07); ! 297: ! 298: vr.x.ax = 0x1200; ! 299: vr.h.bl = 0x20; ! 300: intr(VIDEO, &vr); ! 301: ! 302: LPP = lpp(); ! 303: ! 304: set_cur(cur); ! 305: wherexy(&C_X, &C_Y); ! 306: } ! 307: ! 308: void reset_43() ! 309: { ! 310: BYTE far *info = (BYTE far *) 0x487; ! 311: WORD far *CRTC = (WORD far *) 0x463; ! 312: union REGS vr; ! 313: ! 314: set_mode(3); ! 315: ! 316: *info &= 128; ! 317: vr.x.ax = 0x0100; ! 318: vr.h.bh = 0x0607; ! 319: vr.x.cx = 0x0607; ! 320: intr(VIDEO, &vr); ! 321: ! 322: outp(*CRTC, 0x14); ! 323: outp(*CRTC+1, 13); ! 324: ! 325: } ! 326: ! 327: #define scr_up() scr_win(1, 0, 0, LPP-1, CHPL-1) ! 328: #define back_space() cur_left() ! 329: ! 330: private ! 331: void near line_feed() ! 332: { ! 333: if (++C_X > LPP-1) { ! 334: C_X = LPP-1; ! 335: scr_up(); ! 336: } ! 337: gotoxy(C_X, C_Y); ! 338: } ! 339: ! 340: #define BELL_P 0x61 /* speaker */ ! 341: #define BELL_D 0x2dc /* 550 hz */ ! 342: #define TIME_P 0x40 /* timer */ ! 343: #define TINI 182 /* 10110110b timer initialization */ ! 344: ! 345: void dobell(x) ! 346: { ! 347: unsigned int n = 0x8888; ! 348: int orgval; ! 349: ! 350: outp(TIME_P+3, TINI); ! 351: outp(TIME_P+2, BELL_D&0xff); ! 352: outp(TIME_P+2, BELL_D>>8); ! 353: orgval = inp(BELL_P); ! 354: outp(BELL_P, orgval|3); /* turn speaker on */ ! 355: while (--n > 0) ! 356: ; ! 357: outp(BELL_P, orgval); ! 358: } ! 359: ! 360: #define carriage_return() gotoxy(wherex(), C_Y = 0) ! 361: ! 362: private ! 363: void near cur_advance() ! 364: { ! 365: if (++C_Y > CHPL-1) { ! 366: C_Y = 0; ! 367: if (++C_X > LPP-1) { ! 368: scr_up(); ! 369: C_X = LPP-1; ! 370: } ! 371: } ! 372: gotoxy(C_X, C_Y); ! 373: } ! 374: ! 375: void init_term() ! 376: { ! 377: if (lpp() == 43) ! 378: reset_43(); ! 379: CUR_PAGE = cur_page(); ! 380: CHPL = chpl(); ! 381: LPP = lpp(); ! 382: wherexy(&C_X, &C_Y); ! 383: } ! 384: ! 385: private ! 386: void near normfun(); ! 387: ! 388: void write_em(s) ! 389: char *s; ! 390: { ! 391: while (*s) ! 392: normfun(*s++); ! 393: } ! 394: ! 395: void write_emif(s) ! 396: char *s; ! 397: { ! 398: if (s) ! 399: write_em(s); ! 400: } ! 401: ! 402: void write_emc(s, n) ! 403: char *s; ! 404: int n; ! 405: { ! 406: while (n--) ! 407: normfun(*s++); ! 408: } ! 409: ! 410: private ! 411: void near normfun(c) ! 412: char c; ! 413: { ! 414: switch (c) { ! 415: case 10: line_feed(); break; ! 416: case 13: carriage_return(); break; ! 417: case 8: back_space(); break; ! 418: case 7: dobell(0); break; ! 419: case 0: break; ! 420: default: wrch(c); ! 421: } ! 422: } ! 423: ! 424: #endif /* IBMPC */ ! 425: ! 426: ! 427: extern int BufSize; ! 428: ! 429: int AbortCnt, ! 430: tabstop = 8; ! 431: ! 432: #if !(defined(IBMPC) || defined(MAC)) ! 433: int (*TTins_line)(), ! 434: (*TTdel_line)(); ! 435: #endif /* (defined(IBMPC) || defined(MAC)) */ ! 436: ! 437: struct scrimage ! 438: *DesiredScreen = 0, ! 439: *PhysScreen = 0; ! 440: ! 441: struct screenline *Screen = 0, /* the screen (a bunch of screenline) */ ! 442: *Savelines = 0, /* another bunch (LI of them) */ ! 443: *Curline = 0; /* current line */ ! 444: char *cursor, /* offset into current Line */ ! 445: *cursend; ! 446: ! 447: int CapCol, ! 448: CapLine, ! 449: ! 450: i_line, ! 451: i_col; ! 452: ! 453: void ! 454: make_scr() ! 455: { ! 456: register int i; ! 457: register struct screenline *ns; ! 458: register char *nsp; ! 459: ! 460: #ifdef RESHAPING ! 461: /* In case we are RESHAPING the window! */ ! 462: if (DesiredScreen) ! 463: free((char *) DesiredScreen); ! 464: if (PhysScreen) ! 465: free((char *) PhysScreen); ! 466: if (Savelines) ! 467: free((char *) Savelines); ! 468: if (Screen) { ! 469: free(Screen->s_line); /* free all the screen data */ ! 470: free((char *) Screen); ! 471: } ! 472: #endif /* RESHAPING */ ! 473: ! 474: DesiredScreen = (struct scrimage *) malloc((unsigned) LI * sizeof (struct scrimage)); ! 475: PhysScreen = (struct scrimage *) malloc((unsigned) LI * sizeof (struct scrimage)); ! 476: ! 477: Savelines = (struct screenline *) ! 478: malloc((unsigned) LI * sizeof(struct screenline)); ! 479: ns = Screen = (struct screenline *) ! 480: malloc((unsigned) LI * sizeof(struct screenline)); ! 481: ! 482: nsp = (char *) malloc((unsigned)CO * LI); ! 483: if (nsp == 0) { ! 484: printf("\n\rCannot malloc screen!\n"); ! 485: finish(1); ! 486: } ! 487: ! 488: for (i = 0; i < LI; i++) { ! 489: ns->s_line = nsp; ! 490: nsp += CO; ! 491: ns->s_length = nsp - 1; /* End of Line */ ! 492: ns += 1; ! 493: } ! 494: cl_scr(0); ! 495: } ! 496: ! 497: void ! 498: clrline(cp1, cp2) ! 499: register char *cp1, ! 500: *cp2; ! 501: { ! 502: while (cp1 <= cp2) ! 503: *cp1++ = ' '; ! 504: } ! 505: ! 506: #if !(defined(IBMPC) || defined(MAC)) ! 507: # define sputc(c) ((*cursor != (char) (c)) ? dosputc(c) : (cursor++, i_col++)) ! 508: #endif /* (defined(IBMPC) || defined(MAC)) */ ! 509: ! 510: #ifdef IBMPC ! 511: int force = 0; ! 512: # define sputc(c) dosputc(c) ! 513: #endif /* IBMPC */ ! 514: ! 515: #ifdef MAC ! 516: # define sputc(c) bufputc(c) /* line buffered for mac display */ ! 517: #endif /* MAC */ ! 518: ! 519: #define soutputc(c) if (--n <= 0) break; else sputc(c) ! 520: ! 521: void ! 522: cl_eol() ! 523: { ! 524: if (cursor > cursend) ! 525: return; ! 526: ! 527: if (cursor < Curline->s_length) { ! 528: #if !(defined(IBMPC) || defined(MAC)) ! 529: if (CE) { ! 530: #endif /* (defined(IBMPC) || defined(MAC)) */ ! 531: Placur(i_line, i_col); ! 532: #ifdef TERMCAP ! 533: putpad(CE, 1); ! 534: #else ! 535: clr_eoln(); ! 536: #endif /* TERMCAP */ ! 537: clrline(cursor, Curline->s_length); ! 538: #if !(defined(IBMPC) || defined(MAC)) ! 539: } else { ! 540: /* Ugh. The slow way for dumb terminals. */ ! 541: register char *savecp = cursor; ! 542: ! 543: while (cursor <= Curline->s_length) ! 544: sputc(' '); ! 545: cursor = savecp; ! 546: } ! 547: #endif /* (defined(IBMPC) || defined(MAC)) */ ! 548: Curline->s_length = cursor; ! 549: } ! 550: } ! 551: ! 552: void ! 553: cl_scr(doit) ! 554: { ! 555: register int i; ! 556: register struct screenline *sp = Screen; ! 557: ! 558: for (i = 0; i < LI; i++, sp++) { ! 559: clrline(sp->s_line, sp->s_length); ! 560: sp->s_length = sp->s_line; ! 561: PhysScreen[i].s_id = 0; ! 562: } ! 563: if (doit) { ! 564: #ifdef TERMCAP ! 565: putpad(CL, LI); ! 566: #else ! 567: clr_page(); ! 568: #endif /* TERMCAP */ ! 569: CapCol = CapLine = 0; ! 570: UpdMesg = YES; ! 571: } ! 572: } ! 573: ! 574: #ifdef ID_CHAR ! 575: extern int IN_INSmode; ! 576: #endif ! 577: ! 578: /* Output one character (if necessary) at the current position */ ! 579: ! 580: #ifndef MAC ! 581: int /* only for lints sake */ ! 582: dosputc(c) ! 583: register char c; ! 584: { ! 585: #ifndef IBMPC ! 586: if (*cursor != c) { ! 587: # ifdef ID_CHAR ! 588: if (IN_INSmode) ! 589: INSmode(0); ! 590: # endif ! 591: #else /* IBMPC */ ! 592: if ((force) || (*cursor != c)) { ! 593: #endif /* IBMPC */ ! 594: if (i_line != CapLine || i_col != CapCol) ! 595: Placur(i_line, i_col); ! 596: #ifndef IBMPC ! 597: if (UL && (c & CHARMASK) == '_' && (*cursor & CHARMASK) != ' ') ! 598: putstr(" \b"); /* Erase so '_' looks right. */ ! 599: #endif /* IBMPC */ ! 600: *cursor++ = c; ! 601: #ifndef IBMPC ! 602: putchar(c & CHARMASK); ! 603: #else /* IBMPC */ ! 604: normfun(c); ! 605: #endif /* IBMPC */ ! 606: AbortCnt -= 1; ! 607: CapCol += 1; ! 608: i_col += 1; ! 609: } else { ! 610: cursor += 1; ! 611: i_col += 1; ! 612: } ! 613: } ! 614: #else /* MAC */ ! 615: ! 616: /* Character output to bit-mapped screen is very expensive. It makes ! 617: much more sense to write the entire line at once. So, we print all ! 618: the characters, whether already there or not, once the line is ! 619: complete. */ ! 620: ! 621: #define BUFFLUSH (char) 0 ! 622: #define BUFSTART (char) 1 ! 623: ! 624: bufputc(c) ! 625: register char c; ! 626: { ! 627: static char buf[256]; ! 628: static int len = 0; ! 629: ! 630: if(c == BUFSTART) { ! 631: /* if (i_line != CapLine || i_col != CapCol)*/ ! 632: NPlacur(i_line, i_col); ! 633: len = 0; ! 634: return; ! 635: } ! 636: if(c == BUFFLUSH) { ! 637: buf[0] = (unsigned char) len; ! 638: writechr(buf); ! 639: len = 0; ! 640: } ! 641: else { ! 642: if(len > 255) return; ! 643: *cursor++ = c; ! 644: if(c == '0') buf[++len] = 0xAF; /* slashed zero */ ! 645: else buf[++len] = c; ! 646: CapCol++; ! 647: i_col++; ! 648: } ! 649: return; ! 650: } ! 651: #endif /* MAC */ ! 652: ! 653: /* Write `line' at the current position of `cursor'. Stop when we ! 654: reach the end of the screen. Aborts if there is a character ! 655: waiting. */ ! 656: ! 657: #ifdef MAC /* This was getting too complicated with ifdefs ... */ ! 658: int ! 659: swrite(line, inversep, abortable) ! 660: register char *line; ! 661: register int abortable; ! 662: { ! 663: register int c; ! 664: int col = i_col, ! 665: aborted = 0; ! 666: register int n = cursend - cursor; ! 667: ! 668: if (n <= 0) ! 669: return 1; ! 670: sputc(BUFSTART); /* Okay, because no interruption possible */ ! 671: ! 672: while (c = *line++) { ! 673: if (c == '\t') { ! 674: int nchars; ! 675: ! 676: nchars = (tabstop - (col % tabstop)); ! 677: col += nchars; ! 678: ! 679: while (nchars--) ! 680: soutputc(' '); ! 681: if (n <= 0) ! 682: break; ! 683: } else if (isctrl(c)) { ! 684: soutputc('^'); ! 685: c = ((c == '\177') ? '?' : c + '@'); ! 686: soutputc(c); ! 687: col += 2; ! 688: } else { ! 689: soutputc(c); ! 690: col += 1; ! 691: } ! 692: } ! 693: if (n <= 0) { ! 694: if ((*line == '\0') && (c != '\t') && !isctrl(c)) ! 695: sputc(c); ! 696: sputc('!'); ! 697: } ! 698: if (cursor > Curline->s_length) ! 699: Curline->s_length = cursor; ! 700: sputc(BUFFLUSH); ! 701: return !aborted; ! 702: } ! 703: #else /* MAC */ ! 704: ! 705: int ! 706: swrite(line, inversep, abortable) ! 707: register char *line; ! 708: register int abortable; ! 709: { ! 710: register int c; ! 711: int col = i_col, ! 712: aborted = 0; ! 713: register int n = cursend - cursor; ! 714: #ifndef IBMPC ! 715: int or_byte = inversep ? 0200 : 0, ! 716: thebyte; ! 717: #else ! 718: int thebyte; ! 719: #endif /* IBMPC */ ! 720: ! 721: #ifdef IBMPC ! 722: force = inversep? 1: 0; /* to force a redraw of the modeline */ ! 723: #endif /* IBMPC */ ! 724: ! 725: if (n <= 0) ! 726: return 1; ! 727: while (c = *line++) { ! 728: #if !(defined(IBMPC) || defined(MAC)) /* don't check after every character */ ! 729: if (abortable && AbortCnt < 0) { ! 730: AbortCnt = BufSize; ! 731: if (InputPending = charp()) { ! 732: aborted = 1; ! 733: break; ! 734: } ! 735: } ! 736: #endif /* (defined(IBMPC) || defined(MAC)) */ ! 737: if (c == '\t') { ! 738: int nchars; ! 739: ! 740: nchars = (tabstop - (col % tabstop)); ! 741: col += nchars; ! 742: ! 743: #ifndef IBMPC ! 744: thebyte = (' ' | or_byte); ! 745: #endif /* IBMPC */ ! 746: while (nchars--) ! 747: #ifndef IBMPC ! 748: soutputc(thebyte); ! 749: #else /* IBMPC */ ! 750: soutputc(' '); ! 751: #endif /* IBMPC */ ! 752: if (n <= 0) ! 753: break; ! 754: } else if (isctrl(c)) { ! 755: #ifndef IBMPC ! 756: thebyte = ('^' | or_byte); ! 757: soutputc(thebyte); ! 758: thebyte = (((c == '\177') ? '?' : c + '@') | or_byte); ! 759: soutputc(thebyte); ! 760: #else /* IBMPC */ ! 761: soutputc('^'); ! 762: c = ((c == '\177') ? '?' : c + '@'); ! 763: soutputc(c); ! 764: #endif /* IBMPC */ ! 765: col += 2; ! 766: } else { ! 767: #ifndef IBMPC ! 768: thebyte = (c | or_byte); ! 769: soutputc(thebyte); ! 770: #else /* IBMPC */ ! 771: if (c == 255) c = 1; ! 772: if (c == ' ' && inversep) c = 255; ! 773: soutputc(c); ! 774: #endif /* IBMPC */ ! 775: col += 1; ! 776: } ! 777: } ! 778: if (n <= 0) { ! 779: if ((*line == '\0') && (c != '\t') && !isctrl(c)) ! 780: #ifndef IBMPC ! 781: sputc(c|or_byte); ! 782: #else /* IBMPC */ ! 783: sputc(c); ! 784: #endif /* IBMPC */ ! 785: else ! 786: #ifndef IBMPC ! 787: sputc('!'|or_byte); ! 788: #else /* IBMPC */ ! 789: sputc('!'); ! 790: #endif /* IBMPC */ ! 791: } ! 792: if (cursor > Curline->s_length) ! 793: Curline->s_length = cursor; ! 794: #ifdef IBMPC ! 795: force = 0; ! 796: #endif ! 797: return !aborted; ! 798: } ! 799: #endif /* MAC */ ! 800: /* This is for writing a buffer line to the screen. This is to ! 801: minimize the amount of copying from one buffer to another buffer. ! 802: This gets the info directly from the disk buffers. */ ! 803: ! 804: int ! 805: BufSwrite(linenum) ! 806: { ! 807: register int n = cursend - cursor, ! 808: col = 0, ! 809: c = -1; ! 810: register char *bp; ! 811: int StartCol = DesiredScreen[linenum].s_offset, ! 812: visspace = DesiredScreen[linenum].s_window->w_flags & W_VISSPACE, ! 813: aborted = 0; ! 814: ! 815: bp = lcontents(DesiredScreen[linenum].s_lp); ! 816: if (*bp) for (;;) { ! 817: if (col >= StartCol) { ! 818: DesiredScreen[linenum].s_offset = col; ! 819: break; ! 820: } ! 821: ! 822: c = *bp++ & CHARMASK; ! 823: if (c == '\0') ! 824: break; ! 825: if (c == '\t') ! 826: col += (tabstop - (col % tabstop)); ! 827: else if (isctrl(c)) ! 828: col += 2; ! 829: else ! 830: col += 1; ! 831: } ! 832: #ifdef MAC ! 833: sputc(BUFSTART); /* Okay because we can't be interrupted */ ! 834: #endif ! 835: ! 836: if (c != '\0') while (c = *bp++) { ! 837: #if !(defined(IBMPC) || defined(MAC)) /* will never get true so why bother */ ! 838: if (AbortCnt < 0) { ! 839: AbortCnt = BufSize; ! 840: if (InputPending = charp()) { ! 841: aborted = 1; ! 842: break; ! 843: } ! 844: } ! 845: #endif /* (defined(IBMPC) || defined(MAC)) */ ! 846: if (c == '\t') { ! 847: int nchars = (tabstop - (col % tabstop)); ! 848: ! 849: col += nchars; ! 850: if (visspace) { ! 851: soutputc('>'); ! 852: nchars -= 1; ! 853: } ! 854: while (--nchars >= 0) ! 855: soutputc(' '); ! 856: if (n <= 0) ! 857: break; ! 858: } else if (isctrl(c)) { ! 859: soutputc('^'); ! 860: soutputc((c == '\177') ? '?' : c + '@'); ! 861: col += 2; ! 862: } else { ! 863: if (c == ' ' && visspace) ! 864: c = '_'; ! 865: #ifdef IBMPC ! 866: if (c == 255) ! 867: c = 1; ! 868: #endif /* IBMPC */ ! 869: soutputc(c); ! 870: col += 1; ! 871: } ! 872: } ! 873: if (n <= 0) { ! 874: if ((*bp == '\0') && (c != '\t') && !isctrl(c)) ! 875: sputc(c); ! 876: else ! 877: sputc('!'); ! 878: } ! 879: if (cursor > Curline->s_length) ! 880: Curline->s_length = cursor; ! 881: #ifdef MAC ! 882: sputc(BUFFLUSH); ! 883: #endif ! 884: return !aborted; /* Didn't abort */ ! 885: } ! 886: ! 887: void ! 888: i_set(nline, ncol) ! 889: register int nline, ! 890: ncol; ! 891: { ! 892: Curline = &Screen[nline]; ! 893: cursor = Curline->s_line + ncol; ! 894: cursend = &Curline->s_line[CO - 1]; ! 895: i_line = nline; ! 896: i_col = ncol; ! 897: } ! 898: ! 899: /* Insert `num' lines a top, but leave all the lines BELOW `bottom' ! 900: alone (at least they won't look any different when we are done). ! 901: This changes the screen array AND does the physical changes. */ ! 902: ! 903: void ! 904: v_ins_line(num, top, bottom) ! 905: { ! 906: register int i; ! 907: ! 908: /* Save the screen pointers. */ ! 909: ! 910: for(i = 0; i < num && top + i <= bottom; i++) ! 911: Savelines[i] = Screen[bottom - i]; ! 912: ! 913: /* Num number of bottom lines will be lost. ! 914: Copy everything down num number of times. */ ! 915: ! 916: for (i = bottom; i > top && i-num >= 0; i--) ! 917: Screen[i] = Screen[i - num]; ! 918: ! 919: /* Restore the saved ones, making them blank. */ ! 920: ! 921: for (i = 0; i < num; i++) { ! 922: Screen[top + i] = Savelines[i]; ! 923: clrline(Screen[top + i].s_line, Screen[top + i].s_length); ! 924: Screen[top + i].s_length = Screen[top + i].s_line; ! 925: } ! 926: ! 927: #if !(defined(IBMPC) || defined(MAC)) ! 928: (*TTins_line)(top, bottom, num); ! 929: #endif ! 930: ! 931: #ifdef MAC ! 932: i_lines(top, bottom, num); ! 933: #endif ! 934: ! 935: #ifdef IBMPC ! 936: scr_win(-num, top, 0, bottom, CHPL-1); ! 937: #endif ! 938: } ! 939: ! 940: /* Delete `num' lines starting at `top' leaving the lines below `bottom' ! 941: alone. This updates the internal image as well as the physical image. */ ! 942: ! 943: void ! 944: v_del_line(num, top, bottom) ! 945: { ! 946: register int i, ! 947: bot; ! 948: ! 949: bot = bottom; ! 950: ! 951: /* Save the lost lines. */ ! 952: ! 953: for (i = 0; i < num && top + i <= bottom; i++) ! 954: Savelines[i] = Screen[top + i]; ! 955: ! 956: /* Copy everything up num number of lines. */ ! 957: ! 958: for (i = top; num + i <= bottom; i++) ! 959: Screen[i] = Screen[i + num]; ! 960: ! 961: /* Restore the lost ones, clearing them. */ ! 962: ! 963: for (i = 0; i < num; i++) { ! 964: Screen[bottom - i] = Savelines[i]; ! 965: clrline(Screen[bot].s_line, Screen[bot].s_length); ! 966: Screen[bot].s_length = Screen[bot].s_line; ! 967: bot -= 1; ! 968: } ! 969: ! 970: #if !(defined(IBMPC) || defined(MAC)) ! 971: (*TTdel_line)(top, bottom, num); ! 972: #endif ! 973: ! 974: #ifdef MAC ! 975: d_lines(top, bottom, num); ! 976: #endif ! 977: ! 978: #ifdef IBMPC ! 979: scr_win(num, top, 0, bottom, CHPL-1); ! 980: #endif ! 981: ! 982: } ! 983: ! 984: #ifndef MAC /* remainder of this file */ ! 985: #ifdef IBMPC ! 986: ! 987: /* No cursor optimization on an IBMPC, this simplifies things a lot. ! 988: Think about it: it would be silly! ! 989: */ ! 990: ! 991: int phystab = 8; ! 992: ! 993: void ! 994: Placur(line, col) ! 995: { ! 996: cur_mov(line, col); ! 997: CapCol = col; ! 998: CapLine = line; ! 999: } ! 1000: ! 1001: void ! 1002: SO_on() ! 1003: { ! 1004: if (Mdcolor) ! 1005: setcolor(Mdcolor&0xf, Mdcolor>>4); ! 1006: else ! 1007: setcolor(Bgcolor, Fgcolor); ! 1008: } ! 1009: ! 1010: void ! 1011: SO_off() ! 1012: { ! 1013: setcolor(Fgcolor, Bgcolor); ! 1014: } ! 1015: ! 1016: extern int EGA; ! 1017: ! 1018: void ! 1019: ! 1020: UnsetTerm(foo) ! 1021: char *foo; ! 1022: { ! 1023: Placur(ILI, 0); ! 1024: clr_eoln(); ! 1025: if (EGA) ! 1026: reset_43(); ! 1027: } ! 1028: ! 1029: ! 1030: void ! 1031: ResetTerm() ! 1032: { ! 1033: if (EGA) ! 1034: init_43(); ! 1035: else ! 1036: init_term(); ! 1037: ! 1038: do_sgtty(); /* this is so if you change baudrate or stuff ! 1039: like that, JOVE will notice. */ ! 1040: ttyset(ON); ! 1041: } ! 1042: ! 1043: #else /* IBMPC */ ! 1044: ! 1045: /* The cursor optimization happens here. You may decide that this ! 1046: is going too far with cursor optimization, or perhaps it should ! 1047: limit the amount of checking to when the output speed is slow. ! 1048: What ever turns you on ... */ ! 1049: ! 1050: private struct cursaddr { ! 1051: int cm_numchars, ! 1052: (*cm_proc)(); ! 1053: }; ! 1054: ! 1055: private char *Cmstr; ! 1056: private struct cursaddr *HorMin, ! 1057: *VertMin, ! 1058: *DirectMin; ! 1059: ! 1060: private void ! 1061: GENi_lines(), ! 1062: GENd_lines(), ! 1063: ForMotion(), ! 1064: ForTab(), ! 1065: BackMotion(), ! 1066: RetTab(), ! 1067: DownMotion(), ! 1068: UpMotion(), ! 1069: GoDirect(), ! 1070: HomeGo(), ! 1071: BottomUp(); ! 1072: ! 1073: ! 1074: private struct cursaddr WarpHor[] = { ! 1075: 0, ForMotion, ! 1076: 0, ForTab, ! 1077: 0, BackMotion, ! 1078: 0, RetTab ! 1079: }; ! 1080: ! 1081: private struct cursaddr WarpVert[] = { ! 1082: 0, DownMotion, ! 1083: 0, UpMotion ! 1084: }; ! 1085: ! 1086: private struct cursaddr WarpDirect[] = { ! 1087: 0, GoDirect, ! 1088: 0, HomeGo, ! 1089: 0, BottomUp ! 1090: }; ! 1091: ! 1092: #undef FORWARD ! 1093: #define FORWARD 0 /* Move forward */ ! 1094: #define FORTAB 1 /* Forward using tabs */ ! 1095: #undef BACKWARD ! 1096: #define BACKWARD 2 /* Move backward */ ! 1097: #define RETFORWARD 3 /* Beginning of line and then tabs */ ! 1098: #define NUMHOR 4 ! 1099: ! 1100: #define DOWN 0 /* Move down */ ! 1101: #define UPMOVE 1 /* Move up */ ! 1102: #define NUMVERT 2 ! 1103: ! 1104: #define DIRECT 0 /* Using CM */ ! 1105: #define HOME 1 /* HOME */ ! 1106: #define LOWER 2 /* Lower Line */ ! 1107: #define NUMDIRECT 3 ! 1108: ! 1109: #define home() Placur(0, 0) ! 1110: #define LowLine() putpad(LL, 1), CapLine = ILI, CapCol = 0 ! 1111: #define PrintHo() putpad(HO, 1), CapLine = CapCol = 0 ! 1112: ! 1113: int phystab = 8; ! 1114: ! 1115: private void ! 1116: GoDirect(line, col) ! 1117: register int line, ! 1118: col; ! 1119: { ! 1120: putpad(Cmstr, 1); ! 1121: CapLine = line; ! 1122: CapCol = col; ! 1123: } ! 1124: ! 1125: private void ! 1126: RetTab(col) ! 1127: register int col; ! 1128: { ! 1129: putchar('\r'); ! 1130: CapCol = 0; ! 1131: ForTab(col); ! 1132: } ! 1133: ! 1134: private void ! 1135: HomeGo(line, col) ! 1136: { ! 1137: PrintHo(); ! 1138: DownMotion(line); ! 1139: ForTab(col); ! 1140: } ! 1141: ! 1142: private void ! 1143: BottomUp(line, col) ! 1144: register int line, ! 1145: col; ! 1146: { ! 1147: LowLine(); ! 1148: UpMotion(line); ! 1149: ForTab(col); ! 1150: } ! 1151: ! 1152: /* Tries to move forward using tabs (if possible). It tabs to the ! 1153: closest tabstop which means it may go past 'destcol' and backspace ! 1154: to it. */ ! 1155: ! 1156: private void ! 1157: ForTab(destcol) ! 1158: int destcol; ! 1159: { ! 1160: register int tabgoal, ! 1161: ntabs, ! 1162: tabstp = phystab; ! 1163: ! 1164: if (TABS && (tabstp > 0)) { ! 1165: tabgoal = destcol + (tabstp / 2); ! 1166: tabgoal -= (tabgoal % tabstp); ! 1167: ! 1168: /* Don't tab to last place or else it is likely to screw up. */ ! 1169: if (tabgoal >= CO) ! 1170: tabgoal -= tabstp; ! 1171: ! 1172: ntabs = (tabgoal / tabstp) - (CapCol / tabstp); ! 1173: while (--ntabs >= 0) ! 1174: putchar('\t'); ! 1175: CapCol = tabgoal; ! 1176: } ! 1177: if (CapCol > destcol) ! 1178: BackMotion(destcol); ! 1179: else if (CapCol < destcol) ! 1180: ForMotion(destcol); ! 1181: } ! 1182: ! 1183: private void ! 1184: ForMotion(destcol) ! 1185: register int destcol; ! 1186: { ! 1187: register int nchars = destcol - CapCol; ! 1188: register char *cp = &Screen[CapLine].s_line[CapCol]; ! 1189: ! 1190: while (--nchars >= 0) ! 1191: putchar(*cp++ & CHARMASK); ! 1192: CapCol = destcol; ! 1193: } ! 1194: ! 1195: private void ! 1196: BackMotion(destcol) ! 1197: register int destcol; ! 1198: { ! 1199: register int nchars = CapCol - destcol; ! 1200: ! 1201: if (BC) ! 1202: while (--nchars >= 0) ! 1203: putpad(BC, 1); ! 1204: else ! 1205: while (--nchars >= 0) ! 1206: putchar('\b'); ! 1207: CapCol = destcol; ! 1208: } ! 1209: ! 1210: private void ! 1211: DownMotion(destline) ! 1212: register int destline; ! 1213: { ! 1214: register int nlines = destline - CapLine; ! 1215: ! 1216: while (--nlines >= 0) ! 1217: putpad(NL, 1); ! 1218: CapLine = destline; ! 1219: } ! 1220: ! 1221: private void ! 1222: UpMotion(destline) ! 1223: register int destline; ! 1224: { ! 1225: register int nchars = CapLine - destline; ! 1226: ! 1227: while (--nchars >= 0) ! 1228: putpad(UP, 1); ! 1229: CapLine = destline; ! 1230: } ! 1231: ! 1232: #ifdef ID_CHAR ! 1233: static int EIlen; ! 1234: #endif ! 1235: extern int IMlen; ! 1236: ! 1237: void ! 1238: InitCM() ! 1239: { ! 1240: HOlen = HO ? strlen(HO) : 1000; ! 1241: LLlen = LL ? strlen(LL) : 1000; ! 1242: UPlen = UP ? strlen(UP) : 1000; ! 1243: #ifdef ID_CHAR ! 1244: if (EI) ! 1245: EIlen = strlen(EI); ! 1246: #endif ! 1247: } ! 1248: ! 1249: void ! 1250: Placur(line, col) ! 1251: { ! 1252: int dline, /* Number of lines to move */ ! 1253: dcol; /* Number of columns to move */ ! 1254: register int best, ! 1255: i; ! 1256: register struct cursaddr *cp; ! 1257: int xtracost = 0; /* Misc addition to cost. */ ! 1258: ! 1259: #define CursMin(which,addrs,max) \ ! 1260: for (best = 0, cp = &addrs[1], i = 1; i < max; i++, cp++) \ ! 1261: if (cp->cm_numchars < addrs[best].cm_numchars) \ ! 1262: best = i; \ ! 1263: which = &addrs[best]; ! 1264: ! 1265: if (line == CapLine && col == CapCol) ! 1266: return; /* We are already there. */ ! 1267: ! 1268: dline = line - CapLine; ! 1269: dcol = col - CapCol; ! 1270: #ifdef ID_CHAR ! 1271: if (IN_INSmode && MI) ! 1272: xtracost = EIlen + IMlen; ! 1273: /* If we're already in insert mode, it is likely that we will ! 1274: want to be in insert mode again, after the insert. */ ! 1275: #endif ! 1276: ! 1277: /* Number of characters to move horizontally for each case. ! 1278: 1: Just move forward by typing the right character on the screen. ! 1279: 2: Print the correct number of back spaces. ! 1280: 3: Try tabbing to the correct place. ! 1281: 4: Try going to the beginning of the line, and then tab. */ ! 1282: ! 1283: if (dcol == 1 || dcol == 0) { /* Most common case. */ ! 1284: HorMin = &WarpHor[FORWARD]; ! 1285: HorMin->cm_numchars = dcol + xtracost; ! 1286: } else { ! 1287: WarpHor[FORWARD].cm_numchars = dcol >= 0 ? dcol + xtracost : 1000; ! 1288: WarpHor[BACKWARD].cm_numchars = dcol < 0 ? -(dcol + xtracost) : 1000; ! 1289: WarpHor[FORTAB].cm_numchars = dcol >= 0 && TABS ? ! 1290: ForNum(CapCol, col) + xtracost : 1000; ! 1291: WarpHor[RETFORWARD].cm_numchars = (xtracost + 1 + (TABS ? ForNum(0, col) : col)); ! 1292: ! 1293: /* Which is the shortest of the bunch */ ! 1294: ! 1295: CursMin(HorMin, WarpHor, NUMHOR); ! 1296: } ! 1297: ! 1298: /* Moving vertically is more simple. */ ! 1299: ! 1300: WarpVert[DOWN].cm_numchars = dline >= 0 ? dline : 1000; ! 1301: WarpVert[UPMOVE].cm_numchars = dline < 0 ? ((-dline) * UPlen) : 1000; ! 1302: ! 1303: /* Which of these is simpler */ ! 1304: CursMin(VertMin, WarpVert, NUMVERT); ! 1305: ! 1306: /* Homing first and lowering first are considered ! 1307: direct motions. ! 1308: Homing first's total is the sum of the cost of homing ! 1309: and the sum of tabbing (if possible) to the right. */ ! 1310: ! 1311: if (VertMin->cm_numchars + HorMin->cm_numchars <= 3) { ! 1312: DirectMin = &WarpDirect[DIRECT]; /* A dummy ... */ ! 1313: DirectMin->cm_numchars = 100; ! 1314: } else { ! 1315: WarpDirect[DIRECT].cm_numchars = CM ? ! 1316: strlen(Cmstr = tgoto(CM, col, line)) : 1000; ! 1317: WarpDirect[HOME].cm_numchars = HOlen + line + ! 1318: WarpHor[RETFORWARD].cm_numchars; ! 1319: WarpDirect[LOWER].cm_numchars = LLlen + ((ILI - line) * UPlen) + ! 1320: WarpHor[RETFORWARD].cm_numchars; ! 1321: CursMin(DirectMin, WarpDirect, NUMDIRECT); ! 1322: } ! 1323: ! 1324: if (HorMin->cm_numchars + VertMin->cm_numchars < DirectMin->cm_numchars) { ! 1325: if (line != CapLine) ! 1326: (*VertMin->cm_proc)(line); ! 1327: if (col != CapCol) { ! 1328: #ifdef ID_CHAR ! 1329: if (IN_INSmode) /* We may use real characters ... */ ! 1330: INSmode(0); ! 1331: #endif ! 1332: (*HorMin->cm_proc)(col); ! 1333: } ! 1334: } else { ! 1335: #ifdef ID_CHAR ! 1336: if (IN_INSmode && !MI) ! 1337: INSmode(0); ! 1338: #endif ! 1339: (*DirectMin->cm_proc)(line, col); ! 1340: } ! 1341: } ! 1342: ! 1343: #define abs(x) ((x) >= 0 ? (x) : -(x)) ! 1344: ! 1345: int ! 1346: ForNum(from, to) ! 1347: register int from; ! 1348: { ! 1349: register int tabgoal, ! 1350: tabstp = phystab; ! 1351: int numchars = 0; ! 1352: ! 1353: if (from >= to) ! 1354: return from - to; ! 1355: if (TABS && (tabstp > 0)) { ! 1356: tabgoal = to + (tabstp / 2); ! 1357: tabgoal -= (tabgoal % tabstp); ! 1358: if (tabgoal >= CO) ! 1359: tabgoal -= tabstp; ! 1360: numchars = (tabgoal / tabstop) - (from / tabstp); ! 1361: from = tabgoal; ! 1362: } ! 1363: return numchars + abs(from - to); ! 1364: } ! 1365: ! 1366: #ifdef WIRED_TERMS ! 1367: ! 1368: void ! 1369: BGi_lines(top, bottom, num) ! 1370: { ! 1371: printf("\033[%d;%dr\033[%dL\033[r", top + 1, bottom + 1, num); ! 1372: CapCol = CapLine = 0; ! 1373: } ! 1374: ! 1375: void ! 1376: SUNi_lines(top, bottom, num) ! 1377: { ! 1378: Placur(bottom - num + 1, 0); ! 1379: printf("\033[%dM", num); ! 1380: Placur(top, 0); ! 1381: printf("\033[%dL", num); ! 1382: } ! 1383: ! 1384: void ! 1385: C100i_lines(top, bottom, num) ! 1386: { ! 1387: if (num <= 1) { ! 1388: GENi_lines(top, bottom, num); ! 1389: return; ! 1390: } ! 1391: printf("\033v%c%c%c%c", ' ', ' ', ' ' + bottom + 1, ' ' + CO); ! 1392: CapLine = CapCol = 0; ! 1393: Placur(top, 0); ! 1394: while (num--) ! 1395: putpad(AL, ILI - CapLine); ! 1396: printf("\033v%c%c%c%c", ' ', ' ', ' ' + LI, ' ' + CO); ! 1397: CapLine = CapCol = 0; ! 1398: } ! 1399: ! 1400: #endif /* WIRED_TERMS */ ! 1401: ! 1402: private void ! 1403: GENi_lines(top, bottom, num) ! 1404: { ! 1405: register int i; ! 1406: ! 1407: if (CS) { ! 1408: putpad(tgoto(CS, bottom, top), 1); ! 1409: CapCol = CapLine = 0; ! 1410: Placur(top, 0); ! 1411: for (i = 0; i < num; i++) ! 1412: putpad(SR, bottom - top); ! 1413: putpad(tgoto(CS, ILI, 0), 1); ! 1414: CapCol = CapLine = 0; ! 1415: } else { ! 1416: Placur(bottom - num + 1, 0); ! 1417: if (M_DL && (num > 1)) { ! 1418: char minibuf[16]; ! 1419: ! 1420: sprintf(minibuf, M_DL, num); ! 1421: putpad(minibuf, ILI - CapLine); ! 1422: } else { ! 1423: for (i = 0; i < num; i++) ! 1424: putpad(DL, ILI - CapLine); ! 1425: } ! 1426: Placur(top, 0); ! 1427: if (M_AL && (num > 1)) { ! 1428: char minibuf[16]; ! 1429: ! 1430: sprintf(minibuf, M_AL, num); ! 1431: putpad(minibuf, ILI - CapLine); ! 1432: } else { ! 1433: for (i = 0; i < num; i++) ! 1434: putpad(AL, ILI - CapLine); ! 1435: } ! 1436: } ! 1437: } ! 1438: ! 1439: #ifdef WIRED_TERMS ! 1440: ! 1441: void ! 1442: BGd_lines(top, bottom, num) ! 1443: { ! 1444: printf("\033[%d;%dr\033[%dM\033[r", top + 1, bottom + 1, num); ! 1445: CapCol = CapLine = 0; ! 1446: } ! 1447: ! 1448: void ! 1449: SUNd_lines(top, bottom, num) ! 1450: { ! 1451: Placur(top, 0); ! 1452: printf("\033[%dM", num); ! 1453: Placur(bottom + 1 - num, 0); ! 1454: printf("\033[%dL", num); ! 1455: } ! 1456: ! 1457: void ! 1458: C100d_lines(top, bottom, num) ! 1459: { ! 1460: if (num <= 1) { ! 1461: GENd_lines(top, bottom, num); ! 1462: return; ! 1463: } ! 1464: printf("\033v%c%c%c%c", ' ', ' ', ' ' + bottom + 1, ' ' + CO); ! 1465: CapLine = CapCol = 0; ! 1466: Placur(top, 0); ! 1467: while (num--) ! 1468: putpad(DL, ILI - CapLine); ! 1469: printf("\033v%c%c%c%c", ' ', ' ', ' ' + LI, ' ' + CO); ! 1470: CapLine = CapCol = 0; ! 1471: } ! 1472: ! 1473: #endif /* WIRED_TERMS */ ! 1474: ! 1475: private void ! 1476: GENd_lines(top, bottom, num) ! 1477: { ! 1478: register int i; ! 1479: ! 1480: if (CS) { ! 1481: putpad(tgoto(CS, bottom, top), 1); ! 1482: CapCol = CapLine = 0; ! 1483: Placur(bottom, 0); ! 1484: for (i = 0; i < num; i++) ! 1485: putpad(SF, bottom - top); ! 1486: putpad(tgoto(CS, ILI, 0), 1); ! 1487: CapCol = CapLine = 0; ! 1488: } else { ! 1489: Placur(top, 0); ! 1490: if (M_DL && (num > 1)) { ! 1491: char minibuf[16]; ! 1492: ! 1493: sprintf(minibuf, M_DL, num); ! 1494: putpad(minibuf, ILI - top); ! 1495: } else { ! 1496: for (i = 0; i < num; i++) ! 1497: putpad(DL, ILI - top); ! 1498: } ! 1499: Placur(bottom + 1 - num, 0); ! 1500: if (M_AL && (num > 1)) { ! 1501: char minibuf[16]; ! 1502: ! 1503: sprintf(minibuf, M_AL, num); ! 1504: putpad(minibuf, ILI - CapLine); ! 1505: } else { ! 1506: for (i = 0; i < num; i++) ! 1507: putpad(AL, ILI - CapLine); ! 1508: } ! 1509: } ! 1510: } ! 1511: ! 1512: struct ID_lookup { ! 1513: char *ID_name; ! 1514: int (*I_proc)(); /* proc to insert lines */ ! 1515: int (*D_proc)(); /* proc to delete lines */ ! 1516: } ID_trms[] = { ! 1517: "generic", GENi_lines, GENd_lines, /* This should stay here */ ! 1518: #ifdef WIRED_TERMS ! 1519: "sun", SUNi_lines, SUNd_lines, ! 1520: "bg", BGi_lines, BGd_lines, ! 1521: "c1", C100i_lines, C100d_lines, ! 1522: #endif /* WIRED_TERMS */ ! 1523: 0, 0, 0 ! 1524: }; ! 1525: ! 1526: void ! 1527: IDline_setup(tname) ! 1528: char *tname; ! 1529: { ! 1530: register struct ID_lookup *idp; ! 1531: ! 1532: for (idp = &ID_trms[1]; idp->ID_name; idp++) ! 1533: if (strncmp(idp->ID_name, tname, strlen(idp->ID_name)) == 0) ! 1534: break; ! 1535: if (idp->ID_name == 0) ! 1536: idp = &ID_trms[0]; ! 1537: TTins_line = idp->I_proc; ! 1538: TTdel_line = idp->D_proc; ! 1539: } ! 1540: ! 1541: #endif /* IBMPC */ ! 1542: #endif /* MAC */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.