|
|
1.1 ! root 1: /************************************************************************* ! 2: * This program is copyright (C) 1985, 1986 by Jonathan Payne. It is * ! 3: * provided to you without charge for use only on a licensed Unix * ! 4: * system. You may copy JOVE provided that this notice is included with * ! 5: * the copy. You may not sell copies of this program or versions * ! 6: * modified for use on microcomputer systems, unless the copies are * ! 7: * included with a Unix system distribution and the source is provided. * ! 8: *************************************************************************/ ! 9: ! 10: #include "jove.h" ! 11: #include "io.h" ! 12: #include "ctype.h" ! 13: #include "temp.h" ! 14: #include "termcap.h" ! 15: ! 16: extern int BufSize; ! 17: ! 18: int OkayAbort, ! 19: tabstop = 8; ! 20: ! 21: int (*TTins_line)(), ! 22: (*TTdel_line)(); ! 23: ! 24: struct scrimage ! 25: *DesiredScreen = 0, ! 26: *PhysScreen = 0; ! 27: ! 28: struct screenline *Screen = 0, /* the screen (a bunch of screenline) */ ! 29: *Savelines = 0, /* another bunch (LI of them) */ ! 30: *Curline = 0; /* current line */ ! 31: char *cursor, /* offset into current Line */ ! 32: *cursend; ! 33: ! 34: int CapCol, ! 35: CapLine, ! 36: ! 37: i_line, ! 38: i_col; ! 39: ! 40: make_scr() ! 41: { ! 42: register int i; ! 43: register struct screenline *ns; ! 44: register char *nsp; ! 45: ! 46: #ifdef RESHAPING ! 47: /* In case we are RESHAPING the window! */ ! 48: if (DesiredScreen) ! 49: free((char *) DesiredScreen); ! 50: if (PhysScreen) ! 51: free((char *) PhysScreen); ! 52: if (Savelines) ! 53: free((char *) Savelines); ! 54: if (Screen) { ! 55: ns = Screen; ! 56: for (i = 0; i < LI; i++) ! 57: free((ns++)->s_line); ! 58: free((char *) Screen); ! 59: } ! 60: #endif RESHAPING ! 61: ! 62: DesiredScreen = (struct scrimage *) malloc((unsigned) LI * sizeof (struct scrimage)); ! 63: PhysScreen = (struct scrimage *) malloc((unsigned) LI * sizeof (struct scrimage)); ! 64: ! 65: Savelines = (struct screenline *) ! 66: malloc((unsigned) LI * sizeof(struct screenline)); ! 67: ns = Screen = (struct screenline *) ! 68: malloc((unsigned) LI * sizeof(struct screenline)); ! 69: ! 70: nsp = (char *) malloc((unsigned)CO * LI); ! 71: if (nsp == 0) { ! 72: printf("\n\rCannot malloc screen!\n"); ! 73: finish(1); ! 74: } ! 75: ! 76: for (i = 0; i < LI; i++) { ! 77: ns->s_line = nsp; ! 78: nsp += CO; ! 79: ns->s_length = nsp - 1; /* End of Line */ ! 80: ns++; ! 81: } ! 82: cl_scr(0); ! 83: } ! 84: ! 85: clrline(cp1, cp2) ! 86: register char *cp1, ! 87: *cp2; ! 88: { ! 89: while (cp1 <= cp2) ! 90: *cp1++ = ' '; ! 91: } ! 92: ! 93: #define sputc(c) ((*cursor != (char) (c)) ? dosputc(c) : (cursor++, i_col++)) ! 94: #define soutputc(c) if (--n <= 0) break; else sputc(c) ! 95: ! 96: cl_eol() ! 97: { ! 98: if (cursor > cursend) ! 99: return; ! 100: ! 101: if (cursor < Curline->s_length) { ! 102: if (CE) { ! 103: Placur(i_line, i_col); ! 104: putpad(CE, 1); ! 105: clrline(cursor, Curline->s_length); ! 106: } else { ! 107: /* Ugh. The slow way for dumb terminals. */ ! 108: register char *savecp = cursor; ! 109: ! 110: while (cursor <= Curline->s_length) ! 111: sputc(' '); ! 112: cursor = savecp; ! 113: } ! 114: Curline->s_length = cursor; ! 115: } ! 116: } ! 117: ! 118: cl_scr(doit) ! 119: { ! 120: register int i; ! 121: register struct screenline *sp = Screen; ! 122: ! 123: for (i = 0; i < LI; i++, sp++) { ! 124: clrline(sp->s_line, sp->s_length); ! 125: sp->s_length = sp->s_line; ! 126: PhysScreen[i].s_id = 0; ! 127: } ! 128: if (doit) { ! 129: putpad(CL, LI); ! 130: CapCol = CapLine = 0; ! 131: UpdMesg++; ! 132: } ! 133: } ! 134: ! 135: #ifdef ID_CHAR ! 136: extern int IN_INSmode; ! 137: #endif ! 138: ! 139: /* Output one character (if necessary) at the current position */ ! 140: ! 141: dosputc(c) ! 142: register char c; ! 143: { ! 144: if (*cursor != c) { ! 145: #ifdef ID_CHAR ! 146: if (IN_INSmode) ! 147: INSmode(0); ! 148: #endif ! 149: if (i_line != CapLine || i_col != CapCol) ! 150: Placur(i_line, i_col); ! 151: if (UL && (c & 0177) == '_' && (*cursor & 0177) != ' ') ! 152: putstr(" \b"); /* Erase so '_' looks right. */ ! 153: *cursor++ = c; ! 154: putchar(c & 0177); ! 155: CapCol++; ! 156: i_col++; ! 157: } else { ! 158: cursor++; ! 159: i_col++; ! 160: } ! 161: } ! 162: ! 163: /* Write `line' at the current position of `cursor'. Stop when we ! 164: reach the end of the screen. Aborts if there is a character ! 165: waiting. */ ! 166: ! 167: swrite(line, inversep, abortable) ! 168: register char *line; ! 169: register int abortable; ! 170: { ! 171: register int c; ! 172: int col = i_col, ! 173: aborted = 0; ! 174: register int n = cursend - cursor; ! 175: int or_byte = inversep ? 0200 : 0, ! 176: thebyte; ! 177: ! 178: if (n <= 0) ! 179: return 1; ! 180: ! 181: OkayAbort = 0; ! 182: while (c = *line++) { ! 183: if (abortable && OkayAbort) { ! 184: OkayAbort = NO; ! 185: if (InputPending = charp()) { ! 186: aborted = 1; ! 187: break; ! 188: } ! 189: } ! 190: if (c == '\t') { ! 191: int nchars; ! 192: ! 193: nchars = (tabstop - (col % tabstop)); ! 194: col += nchars; ! 195: ! 196: thebyte = (' ' | or_byte); ! 197: while (nchars--) ! 198: soutputc(thebyte); ! 199: if (n <= 0) ! 200: break; ! 201: } else if (isctrl(c)) { ! 202: thebyte = ('^' | or_byte); ! 203: soutputc(thebyte); ! 204: thebyte = (((c == '\177') ? '?' : c + '@') | or_byte); ! 205: soutputc(thebyte); ! 206: col += 2; ! 207: } else { ! 208: thebyte = (c | or_byte); ! 209: soutputc(thebyte); ! 210: col++; ! 211: } ! 212: } ! 213: if (n <= 0) { ! 214: thebyte = ('!' | or_byte); ! 215: sputc(thebyte); ! 216: } ! 217: if (cursor > Curline->s_length) ! 218: Curline->s_length = cursor; ! 219: return !aborted; ! 220: } ! 221: ! 222: /* This is for writing a buffer line to the screen. This is to ! 223: minimize the amount of copying from one buffer to another buffer. ! 224: This gets the info directly from the disk buffers. */ ! 225: ! 226: BufSwrite(linenum) ! 227: { ! 228: char *bp; ! 229: register int n = cursend - cursor, ! 230: col = 0, ! 231: c; ! 232: int StartCol = DesiredScreen[linenum].s_offset, ! 233: visspace = DesiredScreen[linenum].s_window->w_visspace, ! 234: aborted = 0; ! 235: ! 236: bp = lcontents(DesiredScreen[linenum].s_lp); ! 237: if (*bp) for (;;) { ! 238: if (col >= StartCol) { ! 239: DesiredScreen[linenum].s_offset = col; ! 240: break; ! 241: } ! 242: ! 243: c = *bp++ & 0177; ! 244: if (c == '\t') ! 245: col += (tabstop - (col % tabstop)); ! 246: else if (isctrl(c)) ! 247: col += 2; ! 248: else ! 249: col++; ! 250: } ! 251: ! 252: OkayAbort = 0; ! 253: while (c = (*bp++ & 0177)) { ! 254: if (OkayAbort) { ! 255: OkayAbort = NO; ! 256: if (InputPending = charp()) { ! 257: aborted = 1; ! 258: break; ! 259: } ! 260: } ! 261: if (c == '\t') { ! 262: int nchars = (tabstop - (col % tabstop)); ! 263: ! 264: col += nchars; ! 265: if (visspace) { ! 266: soutputc('>'); ! 267: nchars--; ! 268: } ! 269: while (--nchars >= 0) ! 270: soutputc(' '); ! 271: if (n <= 0) ! 272: break; ! 273: } else if (isctrl(c)) { ! 274: soutputc('^'); ! 275: soutputc((c == '\177') ? '?' : c + '@'); ! 276: col += 2; ! 277: } else { ! 278: if (visspace && c == ' ') ! 279: c = '_'; ! 280: soutputc(c); ! 281: col++; ! 282: } ! 283: } ! 284: if (n <= 0) ! 285: sputc('!'); ! 286: if (cursor > Curline->s_length) ! 287: Curline->s_length = cursor; ! 288: return !aborted; /* Didn't abort */ ! 289: } ! 290: ! 291: i_set(nline, ncol) ! 292: register int nline, ! 293: ncol; ! 294: { ! 295: Curline = &Screen[nline]; ! 296: cursor = Curline->s_line + ncol; ! 297: cursend = &Curline->s_line[CO - 1]; ! 298: i_line = nline; ! 299: i_col = ncol; ! 300: } ! 301: ! 302: /* Insert `num' lines a top, but leave all the lines BELOW `bottom' ! 303: alone (at least they won't look any different when we are done). ! 304: This changes the screen array AND does the physical changes. */ ! 305: ! 306: v_ins_line(num, top, bottom) ! 307: { ! 308: register int i; ! 309: ! 310: /* Save the screen pointers. */ ! 311: ! 312: for(i = 0; i < num && top + i <= bottom; i++) ! 313: Savelines[i] = Screen[bottom - i]; ! 314: ! 315: /* Num number of bottom lines will be lost. ! 316: Copy everything down num number of times. */ ! 317: ! 318: for (i = bottom; i > top && i-num >= 0; i--) ! 319: Screen[i] = Screen[i - num]; ! 320: ! 321: /* Restore the saved ones, making them blank. */ ! 322: ! 323: for (i = 0; i < num; i++) { ! 324: Screen[top + i] = Savelines[i]; ! 325: clrline(Screen[top + i].s_line, Screen[top + i].s_length); ! 326: Screen[top + i].s_length = Screen[top + i].s_line; ! 327: } ! 328: ! 329: (*TTins_line)(top, bottom, num); ! 330: } ! 331: ! 332: /* Delete `num' lines starting at `top' leaving the lines below `bottom' ! 333: alone. This updates the internal image as well as the physical image. */ ! 334: ! 335: v_del_line(num, top, bottom) ! 336: { ! 337: register int i, ! 338: bot; ! 339: ! 340: bot = bottom; ! 341: ! 342: /* Save the lost lines. */ ! 343: ! 344: for (i = 0; i < num && top + i <= bottom; i++) ! 345: Savelines[i] = Screen[top + i]; ! 346: ! 347: /* Copy everything up num number of lines. */ ! 348: ! 349: for (i = top; num + i <= bottom; i++) ! 350: Screen[i] = Screen[i + num]; ! 351: ! 352: /* Restore the lost ones, clearing them. */ ! 353: ! 354: for (i = 0; i < num; i++) { ! 355: Screen[bottom - i] = Savelines[i]; ! 356: clrline(Screen[bot].s_line, Screen[bot].s_length); ! 357: Screen[bot].s_length = Screen[bot].s_line; ! 358: bot--; ! 359: } ! 360: ! 361: (*TTdel_line)(top, bottom, num); ! 362: } ! 363: ! 364: ! 365: /* The cursor optimization happens here. You may decide that this ! 366: is going too far with cursor optimization, or perhaps it should ! 367: limit the amount of checking to when the output speed is slow. ! 368: What ever turns you on ... */ ! 369: ! 370: private struct cursaddr { ! 371: int c_numchars, ! 372: (*c_proc)(); ! 373: }; ! 374: ! 375: private char *Cmstr; ! 376: private struct cursaddr *HorMin, ! 377: *VertMin, ! 378: *DirectMin; ! 379: ! 380: private ForMotion(), ! 381: ForTab(), ! 382: BackMotion(), ! 383: RetTab(), ! 384: DownMotion(), ! 385: UpMotion(), ! 386: GoDirect(), ! 387: HomeGo(), ! 388: BottomUp(); ! 389: ! 390: ! 391: private struct cursaddr WarpHor[] = { ! 392: 0, ForMotion, ! 393: 0, ForTab, ! 394: 0, BackMotion, ! 395: 0, RetTab ! 396: }; ! 397: ! 398: private struct cursaddr WarpVert[] = { ! 399: 0, DownMotion, ! 400: 0, UpMotion ! 401: }; ! 402: ! 403: private struct cursaddr WarpDirect[] = { ! 404: 0, GoDirect, ! 405: 0, HomeGo, ! 406: 0, BottomUp ! 407: }; ! 408: ! 409: #undef FORWARD ! 410: #define FORWARD 0 /* Move forward */ ! 411: #define FORTAB 1 /* Forward using tabs */ ! 412: #undef BACKWARD ! 413: #define BACKWARD 2 /* Move backward */ ! 414: #define RETFORWARD 3 /* Beginning of line and then tabs */ ! 415: #define NUMHOR 4 ! 416: ! 417: #define DOWN 0 /* Move down */ ! 418: #define UPMOVE 1 /* Move up */ ! 419: #define NUMVERT 2 ! 420: ! 421: #define DIRECT 0 /* Using CM */ ! 422: #define HOME 1 /* HOME */ ! 423: #define LOWER 2 /* Lower Line */ ! 424: #define NUMDIRECT 3 ! 425: ! 426: #define home() Placur(0, 0) ! 427: #define LowLine() putpad(LL, 1), CapLine = ILI, CapCol = 0 ! 428: #define PrintHo() putpad(HO, 1), CapLine = CapCol = 0 ! 429: ! 430: int phystab = 8; ! 431: ! 432: private ! 433: GoDirect(line, col) ! 434: register int line, ! 435: col; ! 436: { ! 437: putpad(Cmstr, 1); ! 438: CapLine = line; ! 439: CapCol = col; ! 440: } ! 441: ! 442: private ! 443: RetTab(col) ! 444: register int col; ! 445: { ! 446: putchar('\r'); ! 447: CapCol = 0; ! 448: ForTab(col); ! 449: } ! 450: ! 451: private ! 452: HomeGo(line, col) ! 453: { ! 454: PrintHo(); ! 455: DownMotion(line); ! 456: ForTab(col); ! 457: } ! 458: ! 459: private ! 460: BottomUp(line, col) ! 461: register int line, ! 462: col; ! 463: { ! 464: LowLine(); ! 465: UpMotion(line); ! 466: ForTab(col); ! 467: } ! 468: ! 469: /* Tries to move forward using tabs (if possible). It tabs to the ! 470: closest tabstop which means it may go past 'destcol' and backspace ! 471: to it. */ ! 472: ! 473: private ! 474: ForTab(destcol) ! 475: int destcol; ! 476: { ! 477: register int tabgoal, ! 478: ntabs, ! 479: tabstp = phystab; ! 480: ! 481: if (TABS && (tabstp > 0)) { ! 482: tabgoal = destcol + (tabstp / 2); ! 483: tabgoal -= (tabgoal % tabstp); ! 484: ! 485: /* Don't tab to last place or else it is likely to screw up. */ ! 486: if (tabgoal >= CO) ! 487: tabgoal -= tabstp; ! 488: ! 489: ntabs = (tabgoal / tabstp) - (CapCol / tabstp); ! 490: while (--ntabs >= 0) ! 491: putchar('\t'); ! 492: CapCol = tabgoal; ! 493: } ! 494: if (CapCol > destcol) ! 495: BackMotion(destcol); ! 496: else if (CapCol < destcol) ! 497: ForMotion(destcol); ! 498: } ! 499: ! 500: private ! 501: ForMotion(destcol) ! 502: register int destcol; ! 503: { ! 504: register int nchars = destcol - CapCol; ! 505: register char *cp = &Screen[CapLine].s_line[CapCol]; ! 506: ! 507: while (--nchars >= 0) ! 508: putchar(*cp++ & 0177); ! 509: CapCol = destcol; ! 510: } ! 511: ! 512: private ! 513: BackMotion(destcol) ! 514: register int destcol; ! 515: { ! 516: register int nchars = CapCol - destcol; ! 517: ! 518: if (BC) ! 519: while (--nchars >= 0) ! 520: putpad(BC, 1); ! 521: else ! 522: while (--nchars >= 0) ! 523: putchar('\b'); ! 524: CapCol = destcol; ! 525: } ! 526: ! 527: private ! 528: DownMotion(destline) ! 529: register int destline; ! 530: { ! 531: register int nlines = destline - CapLine; ! 532: ! 533: while (--nlines >= 0) ! 534: putchar('\n'); ! 535: CapLine = destline; ! 536: } ! 537: ! 538: private ! 539: UpMotion(destline) ! 540: register int destline; ! 541: { ! 542: register int nchars = CapLine - destline; ! 543: ! 544: while (--nchars >= 0) ! 545: putpad(UP, 1); ! 546: CapLine = destline; ! 547: } ! 548: ! 549: #ifdef ID_CHAR ! 550: static int EIlen; ! 551: #endif ! 552: extern int IMlen; ! 553: ! 554: InitCM() ! 555: { ! 556: HOlen = HO ? strlen(HO) : 1000; ! 557: LLlen = LL ? strlen(LL) : 1000; ! 558: UPlen = UP ? strlen(UP) : 1000; ! 559: #ifdef ID_CHAR ! 560: if (EI) ! 561: EIlen = strlen(EI); ! 562: #endif ! 563: } ! 564: ! 565: Placur(line, col) ! 566: { ! 567: int dline, /* Number of lines to move */ ! 568: dcol; /* Number of columns to move */ ! 569: register int best, ! 570: i; ! 571: register struct cursaddr *cp; ! 572: int xtracost = 0; /* Misc addition to cost. */ ! 573: ! 574: #define CursMin(which,addrs,max) \ ! 575: for (best = 0, cp = &addrs[1], i = 1; i < max; i++, cp++) \ ! 576: if (cp->c_numchars < addrs[best].c_numchars) \ ! 577: best = i; \ ! 578: which = &addrs[best]; ! 579: ! 580: if (line == CapLine && col == CapCol) ! 581: return; /* We are already there. */ ! 582: ! 583: dline = line - CapLine; ! 584: dcol = col - CapCol; ! 585: #ifdef ID_CHAR ! 586: if (IN_INSmode && MI) ! 587: xtracost = EIlen + IMlen; ! 588: /* If we're already in insert mode, it is likely that we will ! 589: want to be in insert mode again, after the insert. */ ! 590: #endif ! 591: ! 592: /* Number of characters to move horizontally for each case. ! 593: 1: Just move forward by typing the right character on the screen. ! 594: 2: Print the correct number of back spaces. ! 595: 3: Try tabbing to the correct place. ! 596: 4: Try going to the beginning of the line, and then tab. */ ! 597: ! 598: if (dcol == 1 || dcol == 0) { /* Most common case. */ ! 599: HorMin = &WarpHor[FORWARD]; ! 600: HorMin->c_numchars = dcol + xtracost; ! 601: } else { ! 602: WarpHor[FORWARD].c_numchars = dcol >= 0 ? dcol + xtracost : 1000; ! 603: WarpHor[BACKWARD].c_numchars = dcol < 0 ? -(dcol + xtracost) : 1000; ! 604: WarpHor[FORTAB].c_numchars = dcol >= 0 && TABS ? ! 605: ForNum(CapCol, col) + xtracost : 1000; ! 606: WarpHor[RETFORWARD].c_numchars = (xtracost + 1 + (TABS ? ForNum(0, col) : col)); ! 607: ! 608: /* Which is the shortest of the bunch */ ! 609: ! 610: CursMin(HorMin, WarpHor, NUMHOR); ! 611: } ! 612: ! 613: /* Moving vertically is more simple. */ ! 614: ! 615: WarpVert[DOWN].c_numchars = dline >= 0 ? dline : 1000; ! 616: WarpVert[UPMOVE].c_numchars = dline < 0 ? ((-dline) * UPlen) : 1000; ! 617: ! 618: /* Which of these is simpler */ ! 619: CursMin(VertMin, WarpVert, NUMVERT); ! 620: ! 621: /* Homing first and lowering first are considered ! 622: direct motions. ! 623: Homing first's total is the sum of the cost of homing ! 624: and the sum of tabbing (if possible) to the right. */ ! 625: ! 626: if (VertMin->c_numchars + HorMin->c_numchars <= 3) { ! 627: DirectMin = &WarpDirect[DIRECT]; /* A dummy ... */ ! 628: DirectMin->c_numchars = 100; ! 629: } else { ! 630: WarpDirect[DIRECT].c_numchars = CM ? ! 631: strlen(Cmstr = tgoto(CM, col, line)) : 1000; ! 632: WarpDirect[HOME].c_numchars = HOlen + line + ! 633: WarpHor[RETFORWARD].c_numchars; ! 634: WarpDirect[LOWER].c_numchars = LLlen + ((ILI - line) * UPlen) + ! 635: WarpHor[RETFORWARD].c_numchars; ! 636: CursMin(DirectMin, WarpDirect, NUMDIRECT); ! 637: } ! 638: ! 639: if (HorMin->c_numchars + VertMin->c_numchars < DirectMin->c_numchars) { ! 640: if (line != CapLine) ! 641: (*VertMin->c_proc)(line); ! 642: if (col != CapCol) { ! 643: #ifdef ID_CHAR ! 644: if (IN_INSmode) /* We may use real characters ... */ ! 645: INSmode(0); ! 646: #endif ! 647: (*HorMin->c_proc)(col); ! 648: } ! 649: } else { ! 650: #ifdef ID_CHAR ! 651: if (IN_INSmode && !MI) ! 652: INSmode(0); ! 653: #endif ! 654: (*DirectMin->c_proc)(line, col); ! 655: } ! 656: } ! 657: ! 658: #define abs(x) ((x) >= 0 ? (x) : -(x)) ! 659: ! 660: ForNum(from, to) ! 661: register int from; ! 662: { ! 663: register int tabgoal, ! 664: tabstp = phystab; ! 665: int numchars = 0; ! 666: ! 667: if (from >= to) ! 668: return from - to; ! 669: if (TABS && (tabstp > 0)) { ! 670: tabgoal = to + (tabstp / 2); ! 671: tabgoal -= (tabgoal % tabstp); ! 672: if (tabgoal >= CO) ! 673: tabgoal -= tabstp; ! 674: numchars = (tabgoal / tabstop) - (from / tabstp); ! 675: from = tabgoal; ! 676: } ! 677: return numchars + abs(from - to); ! 678: } ! 679: ! 680: #ifdef WIRED_TERMS ! 681: ! 682: BGi_lines(top, bottom, num) ! 683: { ! 684: printf("\033[%d;%dr\033[%dL\033[r", top + 1, bottom + 1, num); ! 685: CapCol = CapLine = 0; ! 686: } ! 687: ! 688: SUNi_lines(top, bottom, num) ! 689: { ! 690: Placur(bottom - num + 1, 0); ! 691: printf("\033[%dM", num); ! 692: Placur(top, 0); ! 693: printf("\033[%dL", num); ! 694: } ! 695: ! 696: C100i_lines(top, bottom, num) ! 697: { ! 698: if (num <= 1) { ! 699: GENi_lines(top, bottom, num); ! 700: return; ! 701: } ! 702: printf("\033v%c%c%c%c", ' ', ' ', ' ' + bottom + 1, ' ' + CO); ! 703: CapLine = CapCol = 0; ! 704: Placur(top, 0); ! 705: while (num--) ! 706: putpad(AL, ILI - CapLine); ! 707: printf("\033v%c%c%c%c", ' ', ' ', ' ' + LI, ' ' + CO); ! 708: CapLine = CapCol = 0; ! 709: } ! 710: ! 711: #endif WIRED_TERMS ! 712: ! 713: GENi_lines(top, bottom, num) ! 714: { ! 715: register int i; ! 716: ! 717: if (CS) { ! 718: printf(tgoto(CS, bottom, top)); ! 719: CapCol = CapLine = 0; ! 720: Placur(top, 0); ! 721: for (i = 0; i < num; i++) ! 722: putpad(SR, bottom - top); ! 723: printf(tgoto(CS, ILI, 0)); ! 724: CapCol = CapLine = 0; ! 725: } else { ! 726: Placur(bottom - num + 1, 0); ! 727: if (M_DL && (num > 1)) { ! 728: char minibuf[16]; ! 729: ! 730: sprintf(minibuf, M_DL, num); ! 731: putpad(minibuf, ILI - CapLine); ! 732: } else { ! 733: for (i = 0; i < num; i++) ! 734: putpad(DL, ILI - CapLine); ! 735: } ! 736: Placur(top, 0); ! 737: if (M_AL && (num > 1)) { ! 738: char minibuf[16]; ! 739: ! 740: sprintf(minibuf, M_AL, num); ! 741: putpad(minibuf, ILI - CapLine); ! 742: } else { ! 743: for (i = 0; i < num; i++) ! 744: putpad(AL, ILI - CapLine); ! 745: } ! 746: } ! 747: } ! 748: ! 749: #ifdef WIRED_TERMS ! 750: ! 751: BGd_lines(top, bottom, num) ! 752: { ! 753: printf("\033[%d;%dr\033[%dM\033[r", top + 1, bottom + 1, num); ! 754: CapCol = CapLine = 0; ! 755: } ! 756: ! 757: SUNd_lines(top, bottom, num) ! 758: { ! 759: Placur(top, 0); ! 760: printf("\033[%dM", num); ! 761: Placur(bottom + 1 - num, 0); ! 762: printf("\033[%dL", num); ! 763: } ! 764: ! 765: C100d_lines(top, bottom, num) ! 766: { ! 767: if (num <= 1) { ! 768: GENd_lines(top, bottom, num); ! 769: return; ! 770: } ! 771: printf("\033v%c%c%c%c", ' ', ' ', ' ' + bottom + 1, ' ' + CO); ! 772: CapLine = CapCol = 0; ! 773: Placur(top, 0); ! 774: while (num--) ! 775: putpad(DL, ILI - CapLine); ! 776: printf("\033v%c%c%c%c", ' ', ' ', ' ' + LI, ' ' + CO); ! 777: CapLine = CapCol = 0; ! 778: } ! 779: ! 780: #endif WIRED_TERMS ! 781: ! 782: GENd_lines(top, bottom, num) ! 783: { ! 784: register int i; ! 785: ! 786: if (CS) { ! 787: printf(tgoto(CS, bottom, top)); ! 788: CapCol = CapLine = 0; ! 789: Placur(bottom, 0); ! 790: for (i = 0; i < num; i++) ! 791: putpad(SF, bottom - top); ! 792: printf(tgoto(CS, ILI, 0)); ! 793: CapCol = CapLine = 0; ! 794: } else { ! 795: Placur(top, 0); ! 796: if (M_DL && (num > 1)) { ! 797: char minibuf[16]; ! 798: ! 799: sprintf(minibuf, M_DL, num); ! 800: putpad(minibuf, ILI - top); ! 801: } else { ! 802: for (i = 0; i < num; i++) ! 803: putpad(DL, ILI - top); ! 804: } ! 805: Placur(bottom + 1 - num, 0); ! 806: if (M_AL && (num > 1)) { ! 807: char minibuf[16]; ! 808: ! 809: sprintf(minibuf, M_AL, num); ! 810: putpad(minibuf, ILI - CapLine); ! 811: } else { ! 812: for (i = 0; i < num; i++) ! 813: putpad(AL, ILI - CapLine); ! 814: } ! 815: } ! 816: } ! 817: ! 818: struct ID_lookup { ! 819: char *ID_name; ! 820: int (*I_proc)(); /* proc to insert lines */ ! 821: int (*D_proc)(); /* proc to delete lines */ ! 822: } ID_trms[] = { ! 823: "generic", GENi_lines, GENd_lines, /* This should stay here */ ! 824: #ifdef WIRED_TERMS ! 825: "sun", SUNi_lines, SUNd_lines, ! 826: "bg", BGi_lines, BGd_lines, ! 827: "c1", C100i_lines, C100d_lines, ! 828: #endif WIRED_TERMS ! 829: 0, 0, 0 ! 830: }; ! 831: ! 832: IDline_setup(tname) ! 833: char *tname; ! 834: { ! 835: register struct ID_lookup *idp; ! 836: ! 837: for (idp = &ID_trms[1]; idp->ID_name; idp++) ! 838: if (strncmp(idp->ID_name, tname, strlen(idp->ID_name)) == 0) ! 839: break; ! 840: if (idp->ID_name == 0) ! 841: idp = &ID_trms[0]; ! 842: TTins_line = idp->I_proc; ! 843: TTdel_line = idp->D_proc; ! 844: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.