1: /* Copyright (c) 1979 Regents of the University of California */
   2: #include "ex.h"
   3: #include "ex_tty.h"
   4: #include "ex_vis.h"
   5: 
   6: /*
   7:  * Terminal driving and line formatting routines.
   8:  * Basic motion optimizations are done here as well
   9:  * as formatting of lines (printing of control characters,
  10:  * line numbering and the like).
  11:  */
  12: 
  13: /*
  14:  * The routines outchar, putchar and pline are actually
  15:  * variables, and these variables point at the current definitions
  16:  * of the routines.  See the routine setflav.
  17:  * We sometimes make outchar be routines which catch the characters
  18:  * to be printed, e.g. if we want to see how long a line is.
  19:  * During open/visual, outchar and putchar will be set to
  20:  * routines in the file ex_vput.c (vputchar, vinschar, etc.).
  21:  */
  22: int (*Outchar)() = termchar;
  23: int (*Putchar)() = normchar;
  24: int (*Pline)() = normline;
  25: 
  26: int (*
  27: setlist(t))()
  28:     bool t;
  29: {
  30:     register int (*P)();
  31: 
  32:     listf = t;
  33:     P = Putchar;
  34:     Putchar = t ? listchar : normchar;
  35:     return (P);
  36: }
  37: 
  38: int (*
  39: setnumb(t))()
  40:     bool t;
  41: {
  42:     register int (*P)();
  43: 
  44:     numberf = t;
  45:     P = Pline;
  46:     Pline = t ? numbline : normline;
  47:     return (P);
  48: }
  49: 
  50: /*
  51:  * Format c for list mode; leave things in common
  52:  * with normal print mode to be done by normchar.
  53:  */
  54: listchar(c)
  55:     register short c;
  56: {
  57: 
  58:     c &= (TRIM|QUOTE);
  59:     switch (c) {
  60: 
  61:     case '\t':
  62:     case '\b':
  63:         outchar('^');
  64:         c = ctlof(c);
  65:         break;
  66: 
  67:     case '\n':
  68:         break;
  69: 
  70:     case '\n' | QUOTE:
  71:         outchar('$');
  72:         break;
  73: 
  74:     default:
  75:         if (c & QUOTE)
  76:             break;
  77:         if (c < ' ' && c != '\n' || c == DELETE)
  78:             outchar('^'), c = ctlof(c);
  79:         break;
  80:     }
  81:     normchar(c);
  82: }
  83: 
  84: /*
  85:  * Format c for printing.  Handle funnies of upper case terminals
  86:  * and crocky hazeltines which don't have ~.
  87:  */
  88: normchar(c)
  89:     register short c;
  90: {
  91:     register char *colp;
  92: 
  93:     c &= (TRIM|QUOTE);
  94:     if (c == '~' && HZ) {
  95:         normchar('\\');
  96:         c = '^';
  97:     }
  98:     if (c & QUOTE)
  99:         switch (c) {
 100: 
 101:         case ' ' | QUOTE:
 102:         case '\b' | QUOTE:
 103:             break;
 104: 
 105:         case QUOTE:
 106:             return;
 107: 
 108:         default:
 109:             c &= TRIM;
 110:         }
 111:     else if (c < ' ' && (c != '\b' || !OS) && c != '\n' && c != '\t' || c == DELETE)
 112:         putchar('^'), c = ctlof(c);
 113:     else if (UPPERCASE)
 114:         if (isupper(c)) {
 115:             outchar('\\');
 116:             c = tolower(c);
 117:         } else {
 118:             colp = "({)}!|^~'`";
 119:             while (*colp++)
 120:                 if (c == *colp++) {
 121:                     outchar('\\');
 122:                     c = colp[-2];
 123:                     break;
 124:                 }
 125:         }
 126:     outchar(c);
 127: }
 128: 
 129: /*
 130:  * Print a line with a number.
 131:  */
 132: numbline(i)
 133:     int i;
 134: {
 135: 
 136:     if (shudclob)
 137:         slobber(' ');
 138:     printf("%6d  ", i);
 139:     normline();
 140: }
 141: 
 142: /*
 143:  * Normal line output, no numbering.
 144:  */
 145: normline()
 146: {
 147:     register char *cp;
 148: 
 149:     if (shudclob)
 150:         slobber(linebuf[0]);
 151:     /* pdp-11 doprnt is not reentrant so can't use "printf" here
 152: 	   in case we are tracing */
 153:     for (cp = linebuf; *cp;)
 154:         putchar(*cp++);
 155:     if (!inopen)
 156:         putchar('\n' | QUOTE);
 157: }
 158: 
 159: /*
 160:  * Given c at the beginning of a line, determine whether
 161:  * the printing of the line will erase or otherwise obliterate
 162:  * the prompt which was printed before.  If it won't, do it now.
 163:  */
 164: slobber(c)
 165:     int c;
 166: {
 167: 
 168:     shudclob = 0;
 169:     switch (c) {
 170: 
 171:     case '\t':
 172:         if (Putchar == listchar)
 173:             return;
 174:         break;
 175: 
 176:     default:
 177:         return;
 178: 
 179:     case ' ':
 180:     case 0:
 181:         break;
 182:     }
 183:     if (OS)
 184:         return;
 185:     flush();
 186:     putch(' ');
 187:     if (BC)
 188:         tputs(BC, 0, putch);
 189:     else
 190:         putch('\b');
 191: }
 192: 
 193: /*
 194:  * The output buffer is initialized with a useful error
 195:  * message so we don't have to keep it in data space.
 196:  */
 197: static  char linb[66] = {
 198:     'E', 'r', 'r', 'o', 'r', ' ', 'm', 'e', 's', 's', 'a', 'g', 'e', ' ',
 199:     'f', 'i', 'l', 'e', ' ', 'n', 'o', 't', ' ',
 200:     'a', 'v', 'a', 'i', 'l', 'a', 'b', 'l', 'e', '\n', 0
 201: };
 202: static  char *linp = linb + 33;
 203: 
 204: /*
 205:  * Phadnl records when we have already had a complete line ending with \n.
 206:  * If another line starts without a flush, and the terminal suggests it,
 207:  * we switch into -nl mode so that we can send lineffeeds to avoid
 208:  * a lot of spacing.
 209:  */
 210: static  bool phadnl;
 211: 
 212: /*
 213:  * Indirect to current definition of putchar.
 214:  */
 215: putchar(c)
 216:     int c;
 217: {
 218: 
 219:     (*Putchar)(c);
 220: }
 221: 
 222: /*
 223:  * Termchar routine for command mode.
 224:  * Watch for possible switching to -nl mode.
 225:  * Otherwise flush into next level of buffering when
 226:  * small buffer fills or at a newline.
 227:  */
 228: termchar(c)
 229:     int c;
 230: {
 231: 
 232:     if (pfast == 0 && phadnl)
 233:         pstart();
 234:     if (c == '\n')
 235:         phadnl = 1;
 236:     else if (linp >= &linb[63])
 237:         flush1();
 238:     *linp++ = c;
 239:     if (linp >= &linb[63]) {
 240:         fgoto();
 241:         flush1();
 242:     }
 243: }
 244: 
 245: flush()
 246: {
 247: 
 248:     flush1();
 249:     flush2();
 250: }
 251: 
 252: /*
 253:  * Flush from small line buffer into output buffer.
 254:  * Work here is destroying motion into positions, and then
 255:  * letting fgoto do the optimized motion.
 256:  */
 257: flush1()
 258: {
 259:     register char *lp;
 260:     register short c;
 261: 
 262:     *linp = 0;
 263:     lp = linb;
 264:     while (*lp)
 265:         switch (c = *lp++) {
 266: 
 267:         case '\r':
 268:             destline += destcol / COLUMNS;
 269:             destcol = 0;
 270:             continue;
 271: 
 272:         case '\b':
 273:             if (destcol)
 274:                 destcol--;
 275:             continue;
 276: 
 277:         case ' ':
 278:             destcol++;
 279:             continue;
 280: 
 281:         case '\t':
 282:             destcol += value(TABSTOP) - destcol % value(TABSTOP);
 283:             continue;
 284: 
 285:         case '\n':
 286:             destline += destcol / COLUMNS + 1;
 287:             if (destcol != 0 && destcol % COLUMNS == 0)
 288:                 destline--;
 289:             destcol = 0;
 290:             continue;
 291: 
 292:         default:
 293:             fgoto();
 294:             for (;;) {
 295:                 if (AM == 0 && outcol == COLUMNS)
 296:                     fgoto();
 297:                 c &= TRIM;
 298:                 putch(c);
 299:                 if (c == '\b') {
 300:                     outcol--;
 301:                     destcol--;
 302:                 } else if (c >= ' ' && c != DELETE) {
 303:                     outcol++;
 304:                     destcol++;
 305:                     if (XN && outcol % COLUMNS == 0)
 306:                         putch('\n');
 307:                 }
 308:                 c = *lp++;
 309:                 if (c <= ' ')
 310:                     break;
 311:             }
 312:             --lp;
 313:             continue;
 314:         }
 315:     linp = linb;
 316: }
 317: 
 318: flush2()
 319: {
 320: 
 321:     fgoto();
 322:     flusho();
 323:     pstop();
 324: }
 325: 
 326: /*
 327:  * Sync the position of the output cursor.
 328:  * Most work here is rounding for terminal boundaries getting the
 329:  * column position implied by wraparound or the lack thereof and
 330:  * rolling up the screen to get destline on the screen.
 331:  */
 332: fgoto()
 333: {
 334:     register int l, c;
 335: 
 336:     if (destcol > COLUMNS - 1) {
 337:         destline += destcol / COLUMNS;
 338:         destcol %= COLUMNS;
 339:     }
 340:     if (outcol > COLUMNS - 1) {
 341:         l = (outcol + 1) / COLUMNS;
 342:         outline += l;
 343:         outcol %= COLUMNS;
 344:         if (AM == 0) {
 345:             while (l > 0) {
 346:                 if (pfast)
 347: #ifdef CRNL
 348:                     if (xCR)
 349:                         tputs(xCR, 0, putch);
 350:                     else
 351: #endif
 352:                         putch('\r');
 353: #ifdef CRNL
 354:                 if (xNL)
 355:                     tputs(xNL, 0, putch);
 356:                 else
 357: #endif
 358:                     putch('\n');
 359:                 l--;
 360:             }
 361:             outcol = 0;
 362:         }
 363:         if (outline > LINES - 1) {
 364:             destline -= outline - (LINES - 1);
 365:             outline = LINES - 1;
 366:         }
 367:     }
 368:     if (destline > LINES - 1) {
 369:         l = destline;
 370:         destline = LINES - 1;
 371:         if (outline < LINES - 1) {
 372:             c = destcol;
 373:             if (pfast == 0 && (!CA || holdcm))
 374:                 destcol = 0;
 375:             fgoto();
 376:             destcol = c;
 377:         }
 378:         while (l > LINES - 1) {
 379:             /*
 380: 			 * The following linefeed (or simulation thereof)
 381: 			 * is supposed to scroll up the screen, since we
 382: 			 * are on the bottom line.  We make the assumption
 383: 			 * that linefeed will scroll.  If ns is in the
 384: 			 * capability list this won't work.  We should
 385: 			 * probably have an sc capability but sf will
 386: 			 * generally take the place if it works.
 387: 			 */
 388: #ifdef CRNL
 389:             if (xNL /* && !XB */ && pfast)
 390:                 tputs(xNL, 0, putch);
 391:             else
 392: #endif
 393:                 putch('\n');
 394:             l--;
 395:             if (pfast == 0)
 396:                 outcol = 0;
 397:         }
 398:     }
 399:     if (destline < outline && !(CA && !holdcm || UP != NOSTR))
 400:         destline = outline;
 401:     if (CA && !holdcm)
 402:         if (plod(costCM) > 0)
 403:             plod(0);
 404:         else
 405:             tputs(tgoto(CM, destcol, destline), 0, putch);
 406:     else
 407:         plod(0);
 408:     outline = destline;
 409:     outcol = destcol;
 410: }
 411: 
 412: /*
 413:  * Tab to column col by flushing and then setting destcol.
 414:  * Used by "set all".
 415:  */
 416: tab(col)
 417:     int col;
 418: {
 419: 
 420:     flush1();
 421:     destcol = col;
 422: }
 423: 
 424: /*
 425:  * Move (slowly) to destination.
 426:  * Hard thing here is using home cursor on really deficient terminals.
 427:  * Otherwise just use cursor motions, hacking use of tabs and overtabbing
 428:  * and backspace.
 429:  */
 430: 
 431: static int plodcnt, plodflg;
 432: 
 433: plodput(c)
 434: {
 435: 
 436:     if (plodflg)
 437:         plodcnt--;
 438:     else
 439:         putch(c);
 440: }
 441: 
 442: plod(cnt)
 443: {
 444:     register int i, j, k;
 445:     register int soutcol, soutline;
 446: 
 447:     plodcnt = plodflg = cnt;
 448:     soutcol = outcol;
 449:     soutline = outline;
 450:     if (HO) {
 451:         if (GT)
 452:         i = (destcol / value(HARDTABS)) + (destcol % value(HARDTABS));
 453:         else
 454:             i = destcol;
 455:     if (destcol >= outcol) {
 456:         j = destcol / value(HARDTABS) - outcol / value(HARDTABS);
 457:         if (GT && j)
 458:             j += destcol % value(HARDTABS);
 459:             else
 460:                 j = destcol - outcol;
 461:     } else
 462:             if (outcol - destcol <= i && (BS || BC))
 463:                 i = j = outcol - destcol;
 464:             else
 465:                 j = i + 1;
 466:         k = outline - destline;
 467:         if (k < 0)
 468:             k = -k;
 469:         j += k;
 470:         if (i + destline < j) {
 471:             tputs(HO, 0, plodput);
 472:             outcol = outline = 0;
 473:         } else if (LL) {
 474:             k = (LINES - 1) - destline;
 475:             if (i + k + 2 < j) {
 476:                 tputs(LL, 0, plodput);
 477:                 outcol = 0;
 478:                 outline = LINES - 1;
 479:             }
 480:         }
 481:     }
 482:     if (GT)
 483:     i = destcol % value(HARDTABS) + destcol / value(HARDTABS);
 484:     else
 485:         i = destcol;
 486: /*
 487: 	if (BT && outcol > destcol && (j = (((outcol+7) & ~7) - destcol - 1) >> 3)) {
 488: 		j *= (k = strlen(BT));
 489: 		if ((k += (destcol&7)) > 4)
 490: 			j += 8 - (destcol&7);
 491: 		else
 492: 			j += k;
 493: 	} else
 494: */
 495:         j = outcol - destcol;
 496:     /*
 497: 	 * If we will later need a \n which will turn into a \r\n by
 498: 	 * the system or the terminal, then don't bother to try to \r.
 499: 	 */
 500:     if ((NONL || !pfast) && outline < destline)
 501:         goto dontcr;
 502:     /*
 503: 	 * If the terminal will do a \r\n and there isn't room for it,
 504: 	 * then we can't afford a \r.
 505: 	 */
 506:     if (NC && outline >= destline)
 507:         goto dontcr;
 508:     /*
 509: 	 * If it will be cheaper, or if we can't back up, then send
 510: 	 * a return preliminarily.
 511: 	 */
 512:     if (j > i + 1 || outcol > destcol && !BS && !BC) {
 513: #ifdef CRNL
 514:         if (xCR)
 515:             tputs(xCR, 0, plodput);
 516:         else
 517: #endif
 518:             plodput('\r');
 519:         if (NC) {
 520: #ifdef CRNL
 521:             if (xNL)
 522:                 tputs(xNL, 0, plodput);
 523:             else
 524: #endif
 525:                 plodput('\n');
 526:             outline++;
 527:         }
 528:         outcol = 0;
 529:     }
 530: dontcr:
 531:     while (outline < destline) {
 532:         outline++;
 533: #ifdef CRNL
 534:             if (xNL)
 535:                 tputs(xNL, 0, plodput);
 536:             else
 537: #endif
 538:             plodput('\n');
 539:         if (plodcnt < 0)
 540:             goto out;
 541:         if (NONL || pfast == 0)
 542:             outcol = 0;
 543:     }
 544:     if (BT)
 545:         k = strlen(BT);
 546:     while (outcol > destcol) {
 547:         if (plodcnt < 0)
 548:             goto out;
 549: /*
 550: 		if (BT && !insmode && outcol - destcol > 4+k) {
 551: 			tputs(BT, 0, plodput);
 552: 			outcol--;
 553: 			outcol &= ~7;
 554: 			continue;
 555: 		}
 556: */
 557:         outcol--;
 558:         if (BC)
 559:             tputs(BC, 0, plodput);
 560:         else
 561:             plodput('\b');
 562:     }
 563:     while (outline > destline) {
 564:         outline--;
 565:         tputs(UP, 0, plodput);
 566:         if (plodcnt < 0)
 567:             goto out;
 568:     }
 569:     if (GT && !insmode && destcol - outcol > 1) {
 570:     for (;;) {
 571:         i = (outcol / value(HARDTABS) + 1) * value(HARDTABS);
 572:         if (i > destcol)
 573:             break;
 574:             if (TA)
 575:                 tputs(TA, 0, plodput);
 576:             else
 577:                 plodput('\t');
 578:             outcol = i;
 579:         }
 580:         if (destcol - outcol > 4 && i < COLUMNS && (BC || BS)) {
 581:             if (TA)
 582:                 tputs(TA, 0, plodput);
 583:             else
 584:                 plodput('\t');
 585:             outcol = i;
 586:             while (outcol > destcol) {
 587:                 outcol--;
 588:                 if (BC)
 589:                     tputs(BC, 0, plodput);
 590:                 else
 591:                     plodput('\b');
 592:             }
 593:         }
 594:     }
 595:     while (outcol < destcol) {
 596:         /*
 597: 		 * move one char to the right.  We don't use ND space
 598: 		 * because it's better to just print the char we are
 599: 		 * moving over.  There are various exceptions, however.
 600: 		 * If !inopen, vtube contains garbage.  If the char is
 601: 		 * a null or a tab we want to print a space.  Other random
 602: 		 * chars we use space for instead, too.
 603: 		 */
 604:         if (!inopen || vtube[outline]==NULL ||
 605:             (i=vtube[outline][outcol]) < ' ')
 606:             i = ' ';
 607:         if (insmode && ND)
 608:             tputs(ND, 0, plodput);
 609:         else
 610:             plodput(i);
 611:         outcol++;
 612:         if (plodcnt < 0)
 613:             goto out;
 614:     }
 615: out:
 616:     if (plodflg) {
 617:         outcol = soutcol;
 618:         outline = soutline;
 619:     }
 620:     return(plodcnt);
 621: }
 622: 
 623: /*
 624:  * An input line arrived.
 625:  * Calculate new (approximate) screen line position.
 626:  * Approximate because kill character echoes newline with
 627:  * no feedback and also because of long input lines.
 628:  */
 629: noteinp()
 630: {
 631: 
 632:     outline++;
 633:     if (outline > LINES - 1)
 634:         outline = LINES - 1;
 635:     destline = outline;
 636:     destcol = outcol = 0;
 637: }
 638: 
 639: /*
 640:  * Something weird just happened and we
 641:  * lost track of whats happening out there.
 642:  * Since we cant, in general, read where we are
 643:  * we just reset to some known state.
 644:  * On cursor addressible terminals setting to unknown
 645:  * will force a cursor address soon.
 646:  */
 647: termreset()
 648: {
 649: 
 650:     endim();
 651:     if (TI) /* otherwise it flushes anyway, and 'set tty=dumb' vomits */
 652:         putpad(TI);  /*adb change -- emit terminal initial sequence */
 653:     destcol = 0;
 654:     destline = LINES - 1;
 655:     if (CA) {
 656:         outcol = UKCOL;
 657:         outline = UKCOL;
 658:     } else {
 659:         outcol = destcol;
 660:         outline = destline;
 661:     }
 662: }
 663: 
 664: /*
 665:  * Low level buffering, with the ability to drain
 666:  * buffered output without printing it.
 667:  */
 668: char    *obp = obuf;
 669: 
 670: draino()
 671: {
 672: 
 673:     obp = obuf;
 674: }
 675: 
 676: flusho()
 677: {
 678: 
 679:     if (obp != obuf) {
 680:         write(1, obuf, obp - obuf);
 681:         obp = obuf;
 682:     }
 683: }
 684: 
 685: putnl()
 686: {
 687: 
 688:     putchar('\n');
 689: }
 690: 
 691: putS(cp)
 692:     char *cp;
 693: {
 694: 
 695:     if (cp == NULL)
 696:         return;
 697:     while (*cp)
 698:         putch(*cp++);
 699: }
 700: 
 701: 
 702: putch(c)
 703:     int c;
 704: {
 705: 
 706:     *obp++ = c & 0177;
 707:     if (obp >= &obuf[sizeof obuf])
 708:         flusho();
 709: }
 710: 
 711: /*
 712:  * Miscellaneous routines related to output.
 713:  */
 714: 
 715: /*
 716:  * Put with padding
 717:  */
 718: putpad(cp)
 719:     char *cp;
 720: {
 721: 
 722:     flush();
 723:     tputs(cp, 0, putch);
 724: }
 725: 
 726: /*
 727:  * Set output through normal command mode routine.
 728:  */
 729: setoutt()
 730: {
 731: 
 732:     Outchar = termchar;
 733: }
 734: 
 735: /*
 736:  * Printf (temporarily) in list mode.
 737:  */
 738: /*VARARGS2*/
 739: lprintf(cp, dp)
 740:     char *cp, *dp;
 741: {
 742:     register int (*P)();
 743: 
 744:     P = setlist(1);
 745:     printf(cp, dp);
 746:     Putchar = P;
 747: }
 748: 
 749: /*
 750:  * Newline + flush.
 751:  */
 752: putNFL()
 753: {
 754: 
 755:     putnl();
 756:     flush();
 757: }
 758: 
 759: /*
 760:  * Try to start -nl mode.
 761:  */
 762: pstart()
 763: {
 764: 
 765:     if (NONL)
 766:         return;
 767:     if (!value(OPTIMIZE))
 768:         return;
 769:     if (ruptible == 0 || pfast)
 770:         return;
 771:     fgoto();
 772:     flusho();
 773:     pfast = 1;
 774:     normtty++;
 775: #ifndef USG3TTY
 776:     tty.sg_flags = normf & ~(ECHO|XTABS|CRMOD);
 777: #else
 778:     tty = normf;
 779:     tty.c_oflag &= ~(ONLCR|TAB3);
 780:     tty.c_lflag &= ~ECHO;
 781: #endif
 782:     sTTY(1);
 783: }
 784: 
 785: /*
 786:  * Stop -nl mode.
 787:  */
 788: pstop()
 789: {
 790: 
 791:     if (inopen)
 792:         return;
 793:     phadnl = 0;
 794:     linp = linb;
 795:     draino();
 796:     normal(normf);
 797:     pfast &= ~1;
 798: }
 799: 
 800: /*
 801:  * Prep tty for open mode.
 802:  */
 803: ttymode
 804: ostart()
 805: {
 806:     ttymode f;
 807: 
 808:     if (!intty)
 809:         error("Open and visual must be used interactively");
 810:     gTTY(1);
 811:     normtty++;
 812: #ifndef USG3TTY
 813:     f = tty.sg_flags;
 814:     tty.sg_flags = (normf &~ (ECHO|XTABS|CRMOD)) |
 815: # ifdef CBREAK
 816:                             CBREAK;
 817: # else
 818:                             RAW;
 819: # endif
 820: # ifdef TIOCGETC
 821:     ttcharoff();
 822: # endif
 823: #else
 824:     f = tty;
 825:     tty = normf;
 826:     tty.c_iflag &= ~ICRNL;
 827:     tty.c_lflag &= ~(ECHO|ICANON);
 828:     tty.c_oflag &= ~TAB3;
 829:     tty.c_cc[VMIN] = 1;
 830:     tty.c_cc[VTIME] = 1;
 831:     ttcharoff();
 832: #endif
 833:     sTTY(1);
 834:     putpad(VS);
 835:     pfast |= 2;
 836:     return (f);
 837: }
 838: 
 839: #ifdef TIOCGETC
 840: /*
 841:  * Turn off start/stop chars if they aren't the default ^S/^Q.
 842:  * This is so idiots who make esc their start/stop don't lose.
 843:  * We always turn off quit since datamedias send ^\ for their
 844:  * right arrow key.
 845:  */
 846: ttcharoff()
 847: {
 848:     nttyc.t_quitc = '\377';
 849:     if (nttyc.t_startc != CTRL(q))
 850:         nttyc.t_startc = '\377';
 851:     if (nttyc.t_stopc != CTRL(s))
 852:         nttyc.t_stopc = '\377';
 853: }
 854: #endif
 855: 
 856: #ifdef USG3TTY
 857: ttcharoff()
 858: {
 859:     tty.c_cc[VQUIT] = '\377';
 860: # ifdef VSTART
 861:     /*
 862: 	 * The following is sample code if USG ever lets people change
 863: 	 * their start/stop chars.  As long as they can't we can't get
 864: 	 * into trouble so we just leave them alone.
 865: 	 */
 866:     if (tty.c_cc[VSTART] != CTRL(q))
 867:         tty.c_cc[VSTART] = '\377';
 868:     if (tty.c_cc[VSTOP] != CTRL(s))
 869:         tty.c_cc[VSTOP] = '\377';
 870: # endif
 871: }
 872: #endif
 873: 
 874: /*
 875:  * Stop open, restoring tty modes.
 876:  */
 877: ostop(f)
 878:     ttymode f;
 879: {
 880: 
 881: #ifndef USG3TTY
 882:     pfast = (f & CRMOD) == 0;
 883: #else
 884:     pfast = (f.c_oflag & OCRNL) == 0;
 885: #endif
 886:     termreset(), fgoto(), flusho();
 887:     normal(f);
 888:     putpad(VE);
 889: }
 890: 
 891: #ifndef CBREAK
 892: /*
 893:  * Into cooked mode for interruptibility.
 894:  */
 895: vcook()
 896: {
 897: 
 898:     tty.sg_flags &= ~RAW;
 899:     sTTY(1);
 900: }
 901: 
 902: /*
 903:  * Back into raw mode.
 904:  */
 905: vraw()
 906: {
 907: 
 908:     tty.sg_flags |= RAW;
 909:     sTTY(1);
 910: }
 911: #endif
 912: 
 913: /*
 914:  * Restore flags to normal state f.
 915:  */
 916: normal(f)
 917:     ttymode f;
 918: {
 919: 
 920:     if (normtty > 0) {
 921:         setty(f);
 922:         normtty--;
 923:     }
 924: }
 925: 
 926: /*
 927:  * Straight set of flags to state f.
 928:  */
 929: ttymode
 930: setty(f)
 931:     ttymode f;
 932: {
 933: #ifndef USG3TTY
 934:     register int ot = tty.sg_flags;
 935: #else
 936:     ttymode ot;
 937:     ot = tty;
 938: #endif
 939: 
 940: #ifndef USG3TTY
 941: # ifdef TIOCGETC
 942:     if (f == normf)
 943:         nttyc = ottyc;
 944:     else
 945:         ttcharoff();
 946: # endif
 947:     tty.sg_flags = f;
 948: #else
 949:     if (tty.c_lflag & ICANON)
 950:         ttcharoff();
 951:     tty = f;
 952: #endif
 953:     sTTY(1);
 954:     return (ot);
 955: }
 956: 
 957: gTTY(i)
 958:     int i;
 959: {
 960: 
 961: #ifndef USG3TTY
 962:     ignore(gtty(i, &tty));
 963: # ifdef TIOCGETC
 964:     ioctl(i, TIOCGETC, &ottyc);
 965: # endif
 966: #else
 967:     ioctl(i, TCGETA, &tty);
 968: #endif
 969: #ifdef TIOCGETC
 970:     nttyc = ottyc;
 971: #endif
 972: }
 973: 
 974: /*
 975:  * sTTY: set the tty modes on file descriptor i to be what's currently
 976:  * in global "tty".  (Also use nttyc if needed.)
 977:  */
 978: sTTY(i)
 979:     int i;
 980: {
 981: 
 982: #ifndef USG3TTY
 983: /*
 984:  * Bug in USG tty driver, put out a DEL as a patch.
 985:  */
 986: # ifdef USG
 987:     if (tty.sg_ospeed >= B1200)
 988:         write(1, "\377", 1);
 989: # endif
 990: # ifdef TIOCSETN
 991:     /* Don't flush typeahead if we don't have to. */
 992:     ioctl(i, TIOCSETN, &tty);
 993: # else
 994:     /* We have to.  Too bad. */
 995:     stty(i, &tty);
 996: # endif
 997: # ifdef TIOCGETC
 998:     /*
 999: 	 * Update the other random chars while we're at it.
1000: 	 * Heaven help us if TIOCGETC is defined but TIOCSETC isn't!
1001: 	 */
1002:     ioctl(i, TIOCSETC, &nttyc);
1003: # endif
1004: #else
1005:     /* USG 3 very simple: just set everything */
1006:     ioctl(i, TCSETAW, &tty);
1007: #endif
1008: }
1009: 
1010: /*
1011:  * Print newline, or blank if in open/visual
1012:  */
1013: noonl()
1014: {
1015: 
1016:     putchar(Outchar != termchar ? ' ' : '\n');
1017: }

Defined functions

draino defined in line 670; used 4 times
fgoto defined in line 332; used 10 times
flush1 defined in line 257; used 7 times
flush2 defined in line 318; used 1 times
gTTY defined in line 957; used 2 times
listchar defined in line 54; used 3 times
normal defined in line 916; used 2 times
normchar defined in line 88; used 5 times
normline defined in line 145; used 4 times
noteinp defined in line 629; used 3 times
numbline defined in line 132; used 4 times
plod defined in line 442; used 3 times
plodput defined in line 433; used 19 times
pstart defined in line 762; used 2 times
pstop defined in line 788; used 3 times
putS defined in line 691; never used
putch defined in line 702; used 20 times
putchar defined in line 215; used 11 times
sTTY defined in line 978; used 5 times
setty defined in line 929; used 6 times
slobber defined in line 164; used 2 times
tab defined in line 416; used 5 times
termchar defined in line 228; used 4 times
ttcharoff defined in line 857; used 4 times

Defined variables

linb defined in line 197; used 6 times
linp defined in line 202; used 6 times
obp defined in line 668; used 6 times
phadnl defined in line 210; used 3 times
plodcnt defined in line 431; used 7 times
plodflg defined in line 431; used 3 times
t defined in line 40; used 6 times
Last modified: 1980-09-24
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2402
Valid CSS Valid XHTML 1.0 Strict