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