1 /* ELLE - Copyright 1982, 1984, 1987 by Ken Harrenstien, SRI International
2 * This software is quasi-public; it may be used freely with
3 * like software, but may NOT be sold or made part of licensed
4 * products without permission of the author.
7 * EETERM ELLE Terminal Driver.
8 * Directly supports DM2500, H-19, Omron 8025AG, Coherent/IBM-PC, TVI925.
9 * Others also supported if using TX_TERMCAP.
14 /* Define terminal indices (there may be holes but C preprocessor is too
15 * stupid to let us close them). Should be one TN_ definition for every
16 * hardwired terminal type, even though whether or not it is actually
17 * compiled depends on which TX_ switches are defined.
23 #define TN_COHIBM 4 /* Coherent IBM-PC console */
26 #if TX_COHIBM && !(TX_H19) /* Ensure H19 defined if COHIBM is. */
30 #ifndef TXS_DEFAULT /* If no default is explicitly specified */
31 #define TXS_DEFAULT "H19" /* Then settle for H-19 */
32 #endif /*TXS_DEFAULT*/
36 extern char *tv_stype
; /* If set, specifies terminal type */
37 extern int tibfmsk
; /* Crock to mask off parity (meta) bit */
38 static int tv_padc
; /* Pad character to use */
39 static int tv_cspeed
; /* # msec per char (set from trm_ospeed) */
40 static int tv_type
; /* Index of selected terminal type */
42 /* Internal functions */
43 static void tpadn(), tpad();
45 /* Character speed table, indexed by system output speed value (0-017).
46 * Value in table is 100 * <# msec used per character>.
48 static int cspdtab
[] =
49 { /* Val Idx Baud CPS Time/char in msec */
50 0, /* 0 Hangup - ---- */
51 13333, /* 1 50 7.5 133.33 (Baudot) */
52 10000, /* 2 75 10 100.0 (Baudot) */
53 10000, /* 3 110 10 100.0 */
54 8200, /* 4 134.5 12.2 82.0 (IBM2741) */
55 6666, /* 5 150 15 66.6666 */
56 5000, /* 6 200 20 50.0 */
57 3333, /* 7 300 30 33.3333 */
58 1666, /* 8 600 60 16.6666 */
59 833, /* 9 1200 120 8.3333 */
60 555, /* 10 1800 180 5.5555 */
61 416, /* 11 2400 240 4.1666 */
62 208, /* 12 4800 480 2.0833 */
63 104, /* 13 9600 960 1.04166 */
69 /* Declarations for TERMCAP stuff. Only EETERM knows about them. */
71 /* Termcap routines */
72 extern int tgetent(), tgetnum(), tgetflag(), tputs();
73 extern char *tgetstr(), *tgoto();
74 static int getcap(); /* Internal routines */
75 static void putpad(), putnpad(), putpar();
77 /* Gross disgusting externals that must be defined for TERMCAP rtns */
78 char PC
; /* Pad char */
79 char *BC
; /* Backspace to use, if not ^H */
80 char *UP
; /* Cursor up */
81 short ospeed
; /* Terminal output speed */
83 /* Termcap numerical values/flags */
85 tc_am
, /* TRUE if has auto-wrap */
86 tc_km
; /* TRUE if meta key exists */
88 /* Termcap capability strings we want to know about */
90 struct tcap
{ char tcicod1
, tcicod2
, *tccap
; };
91 static struct tcap tcap
[] = {
92 #define TC_al tcap[0].tccap /* Add (insert) line */
94 #define TC_AL tcap[1].tccap /* Add N lines */
96 #define TC_bc tcap[2].tccap /* Backspace Char (for BC) */
98 #define TC_ce tcap[3].tccap /* Erase to end of line (CLEOL) */
100 #define TC_cl tcap[4].tccap /* Clear screen */
102 #define TC_cm tcap[5].tccap /* Cursor motion */
104 #define TC_dc tcap[6].tccap /* Delete char */
106 #define TC_DC tcap[7].tccap /* Delete N chars */
108 #define TC_dl tcap[8].tccap /* Delete line */
110 #define TC_DL tcap[9].tccap /* Delete N lines */
112 #define TC_dm tcap[10].tccap /* Delete mode on */
114 #define TC_ed tcap[11].tccap /* Delete mode off */
116 #define TC_ei tcap[12].tccap /* Insert mode off */
118 #define TC_ia tcap[13].tccap /* Add line while in insert mode (see note) */
120 #define TC_ic tcap[14].tccap /* Insert blank char */
122 #define TC_IC tcap[15].tccap /* Insert N blank chars */
124 #define TC_id tcap[16].tccap /* Delete line while in del mode (see note) */
126 #define TC_im tcap[17].tccap /* Insert mode on */
128 #define TC_ip tcap[18].tccap /* Padding to send after char insertion */
130 #define TC_mm tcap[19].tccap /* String to set (turn on) meta-key mode */
132 #define TC_mo tcap[20].tccap /* String to reset (turn off) meta-key mode */
134 #define TC_pc tcap[21].tccap /* Pad Char (for PC) */
136 #define TC_se tcap[22].tccap /* End standout mode */
138 #define TC_so tcap[23].tccap /* Enter standout mode */
140 #define TC_te tcap[24].tccap /* String to end programs that use termcap */
142 #define TC_ti tcap[25].tccap /* String to beg programs that use termcap */
144 #define TC_up tcap[26].tccap /* Move cursor up (for UP) */
146 #define TC_vb tcap[27].tccap /* Visible bell */
149 #define NTCAPS ((sizeof(tcap))/(sizeof(struct tcap))) /* # entries */
152 * There are many other things that must be taken into account.
153 * The termcap code here will probably not work for many termcap entries,
154 * but the only sure way to find out which ones they are is to try them.
156 /* Note that the "ia" and "id" strings are not defined by the TERMCAP doc;
157 * their usage here is derived from examining other TERMCAP-using programs.
160 #endif /*TX_TERMCAP*/
162 /* T_INIT is called once only at program startup, to identify the
163 * terminal type and set up any one-time things.
164 * T_FATAL is only called if some routine detects an error related to the
165 * terminal specification, before any initialization is done.
166 * It prints a short error message and exits the program.
167 * T_ENTER is called after TS_ENTER to set the terminal parameters for
168 * editing (as opposed to normal typeout). It may be called
170 * T_EXIT is called before TS_EXIT to restore normal typeout modes.
171 * It is called on exit from the program, and perhaps other times.
177 /* Set some default parameters */
181 tvc_cin
= 1; /* Assume 1 char per char I/D pos */
183 tvc_pos
= 4; /* Default abs-move cost is 4 chars */
184 tvc_bs
= 1; /* Default backspace cost is 1 char */
185 tv_cspeed
= cspdtab
[trm_ospeed
]; /* Find # msec per char */
187 /* First must determine terminal type, and check for terminals
188 * that are hardwired into ELLE. */
189 if(!tv_stype
/* String set in command line args? */
191 && !(tv_stype
= getenv("TERM")) /* or given by TERM var? */
193 ) tv_stype
= TXS_DEFAULT
; /* No, try using default */
194 if(0) ; /* Sigh, stupid construct */
196 else if(ustrcmp(tv_stype
,"H19")) tv_type
= TN_H19
;
199 else if(ustrcmp(tv_stype
,"OM8025")) tv_type
= TN_OM8025
;
202 else if(ustrcmp(tv_stype
,"DM2500")) tv_type
= TN_DM2500
;
203 else if(ustrcmp(tv_stype
,"DM3025")) tv_type
= TN_DM2500
;
206 else if(ustrcmp(tv_stype
,"COHIBM")) tv_type
= TN_COHIBM
;
209 else if(ustrcmp(tv_stype
,"TVI925")) tv_type
= TN_TVI925
;
211 #if TX_TERMCAP /* This should be last thing */
212 else if(getcap(tv_stype
)) tv_type
= TN_TERMCAP
;
213 #endif /*TX_TERMCAP*/
214 else t_fatal("type unknown"); /* Ugh, barf and exit */
216 /* Terminal selected, now initialize parameters for it. */
221 tv_padc
= 0177; /* Use rubout for pad */
222 tvc_pos
= 3; /* Only 3 chars for abs mov */
224 /* tvc_cin = 1; */ /* Default is OK */
226 /* tvc_cdn = 1; */ /* Default is OK */
231 if(trm_ospeed
== 13) /* If 9600, */
232 { tvc_cin
= 5; /* Sigh, high cost */
237 trm_flags
|= TF_IDLIN
|TF_IDCHR
|TF_CLEOL
|TF_METAKEY
;
242 trm_flags
|= TF_IDLIN
|TF_IDCHR
|TF_CLEOL
;
244 /* tvc_cin = 1; */ /* default is ok */
247 /* tvc_ld = 0; */ /* Default is OK */
248 tvc_ldn
= 1 << (trm_ospeed
- 7);
249 /* tvc_li = 0; */ /* Default is OK */
255 trm_flags
|= TF_IDLIN
|TF_IDCHR
|TF_CLEOL
|TF_METAKEY
|TF_DIRVID
;
256 /* Always use lowest possible costs */
257 /* tvc_ci = 0; */ /* Default */
259 /* tvc_cd = 0; */ /* Default */
261 /* tvc_ld = 0; */ /* Default */
263 /* tvc_li = 0; */ /* Default */
269 trm_flags
|= TF_IDLIN
|TF_IDCHR
|TF_CLEOL
;
271 /* tvc_ci = tvc_cd = 0; */ /* Default */
274 /* tvc_ld = tvc_li = 0; */ /* Default */
275 tvc_ldn
= 10; /* Crude approx */
277 if(trm_ospeed
> 7) /* If faster than 300 baud */
278 trm_flags
&= ~TF_IDLIN
; /* Turn off LID */
283 trm_flags
|= TF_IDLIN
|TF_IDCHR
|TF_CLEOL
;
284 tvc_ci
= tvc_cd
= tvc_cin
= tvc_cdn
285 = tvc_ldn
= tvc_lin
= 2;
289 if(tibfmsk
< 0) /* If mask is still default -1, set it. */
290 tibfmsk
= ((trm_flags
&TF_METAKEY
) ? 0377 : 0177);
293 /* T_FATAL(str) - prints error message and exits.
297 { writerr("ELLE: \"");
299 writerr("\" terminal ");
302 exit(1); /* Terminate with prejudice */
305 /* T_ENTER is called after TS_ENTER to set the terminal parameters for
306 * editing (as opposed to normal typeout).
307 * Standout mode must initially be off.
316 if(tc_km
) putpad(TC_mm
); /* Use meta if poss */
318 t_standout(0); /* Ensure standout mode off */
321 #endif /*TX_TERMCAP*/
324 tput(030); /* Just in case, flush stray modes */
328 case TN_COHIBM
: /* Note TN_H19 will exist too */
332 /* Enter ZDS (Heath) mode, then
333 * Exit graphics mode (G) Exit ins-char mode (O)
334 * exit rev video mode (q) exit hold-screen mode (\)
337 tputz("\033[?2h\033G\033O\033q\033\\\033y5");
338 /* Set Discard-at-EOL (w)
339 * Set no auto-CR (y9)
340 * Enable 25th line (x1)
342 tputz("\033w\033y9\033x1");
348 /* T_EXIT - Leave editing modes. This function should restore
349 ** the terminal's modes to what they were before ELLE was started.
350 ** Standout mode is turned off.
359 if(tc_km
) putpad(TC_mo
); /* Turn off meta */
362 #endif /*TX_TERMCAP*/
365 tput(035); /* Turn on roll mode */
369 case TN_COHIBM
: /* If this exists, TN_H19 will too */
373 tputz("\033v"); /* Turn EOL-wrap back on */
375 tputz("\033<"); /* Return to ANSI mode */
382 /* T_CLEAR() - Clears the screen and homes the cursor.
383 * Always valid - ELLE refuses to support terminals without this.
391 putnpad(TC_cl
,scr_ht
);
393 #endif /*TX_TERMCAP*/
396 tputz("\036\036"); /* Double Master Clear */
400 case TN_COHIBM
: /* Note TN_H19 will exist too */
405 /* tputn(zpadstr,9); */
410 tputz("\033H\033J"); /* Home then CLEOS */
411 tpad(1000); /* One second!!!! */
420 curs_lin
= curs_col
= 0;
423 /* T_CURPOS(y, x) - Absolute move. Place cursor in given position
424 * regardless of where it currently is.
425 * Updates curs_lin, curs_col.
426 * Always valid -- ELLE refuses to support terminals without this.
430 register int lin
, col
;
432 if(col
> scr_wid
) /* Easiest to catch here */
435 /* Do absolute positioning */
440 putpad(tgoto(TC_cm
, col
, lin
));
442 #endif /*TX_TERMCAP*/
451 case TN_COHIBM
: /* If this exists, TN_H19 will too */
463 tput(0100+((lin
+1)>>4));
464 tput(0100+((lin
+1)&017));
465 tput(0100+((col
+1)>>4));
466 tput(0100+((col
+1)&017));
481 /* T_BACKSPACE() - Back up 1 character position.
483 * Only valid if tvc_bs has a "reasonable" value ( < 1000)
489 if(BC
) tputz(BC
); /* Use alternate BS */
492 tput('\010'); /* Send BS */
496 /* T_BELL() - Ring terminal's bell (or flash something, or whatever).
497 * Forces out all output thus far, to ensure immediate attention.
498 * This used to be an unbuffered feep, but was changed to use normal
499 * output path in order to avoid messing up terminal escape sequences.
503 #if TXC_VISBEL && TX_TERMCAP
505 tputz(TC_vb
); /* Do visible bell if possible */
509 tbufls(); /* Force it out */
512 /* T_CLEOL() - Clear to End Of Line.
513 * Only valid if trm_flags has TF_CLEOL set.
524 #endif /*TX_TERMCAP*/
531 case TN_COHIBM
: /* If this exists, TN_H19 will too */
541 tpad(41); /* 1/25 sec padding */
552 /* T_INSLIN(n, bot) - Insert lines in window.
553 * n - # blank lines to insert.
554 * bot - # of last line of current window
556 * The current line is moved down and N blank lines inserted.
557 * Lines which are moved past bot are lost.
558 * May leave cursor in random place.
559 * Only valid if trm_flags has TF_IDLIN set.
563 int n
; /* number of lines */
564 int bot
; /* line number of last line in window */
568 if((i
= n
) <= 0) return;
574 t_curpos(savl
, savc
);
589 do { putnpad(TC_al
, scr_ht
- curs_lin
);
592 #endif /*TX_TERMCAP*/
595 tput(020); /* Enter I/D mode */
596 do { tput(012); /* Insert line */
598 { case 13: j
= 17; break; /* 9600 */
599 case 12: j
= 8; break; /* 4800 */
600 case 11: j
= 4; break; /* 2400 */
601 case 9: j
= 2; break; /* 1200 */
602 default: j
= 0; break;
606 tput(030); /* Exit I/D mode */
610 /* NOTE: H19 supposedly requires 19 ms for each line during line I/D
612 * In actual practice, at 9600 baud 25 pads are necessary (24 wont work!)
613 * for both I and D. Plus esc-E needs 9 pads.
618 { case 13: j
= 25; break;
619 case 9: j
= 4; break;
620 case 7: j
= 1; break;
621 default: j
= 0; break;
629 do { tputz("\033L"); /* no padding required */
636 tpad(100*(scr_ht
- curs_lin
)); /* .1 per moved line*/
649 /* T_DELLIN(n, bot) - Delete lines from window.
650 * n - # lines to delete.
651 * bot - # of last line of current window.
652 * The current line, and N-1 following lines, are deleted.
653 * Blank lines are inserted past bot.
654 * Cursor should be left at original position.
655 * Only valid if trm_flags has TF_IDLIN set.
658 int n
; /* number of lines */
659 int bot
; /* line number of last line in window */
663 if((i
= n
) <= 0) return;
677 do { putnpad(TC_dl
,scr_ht
- curs_lin
);
681 #endif /*TX_TERMCAP*/
686 if(trm_ospeed
>= 13) /* 9600 */
696 case 13: j
= 25; break;
697 case 9: j
= 4; break;
698 case 7: j
= 1; break;
699 default: j
= 0; break;
707 do { tputz("\033M"); /* no padding required */
714 tpad(100*(scr_ht
- curs_lin
));
734 /* T_INSCHR(n, str) - Insert n chars in current line
735 * n - # characters to insert
736 * str - Pointer to char string. If 0, insert spaces.
738 * Insert N characters from string str at current position.
739 * The cursor may move but curs_col must be updated.
740 * Only valid if trm_flags has TF_IDCHR set.
748 if((i
= n
) <= 0) return;
754 putpad(TC_im
); /* Go into insert mode */
756 { putpar(TC_IC
, i
, 1);
758 else do tput(SP
); while(--i
);
761 if(TC_ic
) putpad(TC_ic
);
764 if(TC_ip
) putpad(TC_ip
);
766 putpad(TC_ei
); /* Exit insert mode */
769 #endif /*TX_TERMCAP*/
771 case TN_COHIBM
: /* If this exists, TN_H19 will too */
775 tputz("\033@"); /* Enter ins char mode */
776 do { if(cp
) tput(*cp
++);
779 tputz("\033O"); /* Exit ins char mode */
785 tput(020); /* Enter I/D mode */
786 if(trm_ospeed
== 13) /* 9600 baud lossage */
788 tputz(" \177"); /* SP and DEL */
792 if(i
< 3) /* If close enough, */
793 tputn("\010\010", i
); /* use BSes */
794 else t_curpos(curs_lin
, curs_col
);
796 else /* Not 9600, can win */
804 do { if(cp
) tput(*cp
++);
833 /* T_DELCHR(n) - Delete N chars in current line.
834 * Deletes the N characters to the right of the cursor. Remaining
835 * chars are shifted left. The cursor should not move.
836 * Only valid if trm_flags has TF_IDCHR set.
838 t_delchr(n
) /* Delete N chars at current loc */
842 if((i
= n
) <= 0) return;
847 putpad(TC_dm
); /* Enter delete mode */
850 else do { /* Delete char while in del mode */
853 putpad(TC_ed
); /* Exit delete mode */
855 #endif /*TX_TERMCAP*/
857 case TN_COHIBM
: /* If this exists, TN_H19 will too */
867 tput(020); /* Enter I/D mode */
868 do if(trm_ospeed
== 13) /* 9600? */
869 tputz("\010\177"); /* BS and DEL */
872 tput(030); /* Exit I/D mode */
891 /* T_STANDOUT(n) - Enter or leave standout mode.
892 * n - 0 to return to normal display mode,
893 * 1 to enter standout display mode.
894 * This is usually reverse video but may be something else.
896 * Only valid if trm_flags has TF_SO set.
906 putpad(on
? TC_so
: TC_se
);
908 #endif /*TX_TERMCAP*/
911 case TN_COHIBM
: /* Note TN_H19 will exist too */
915 tputz(on
? "\033p" : "\033q");
923 /* TPADN(n) - Output N pad chars.
928 { register int i
, pad
;
936 /* TPAD(msec) - Output padding for given # of milliseconds.
941 { register int i
, i2
;
945 { if((i2
= 320) < i
) /* So can use integers */
949 while((i2
-= tv_cspeed
) > 0)
955 * Print the string str, interpreting padding.
957 int tput(); /* Our output function */
961 { if(str
) tputs(str
, 1, tput
); /* Invoke TERMCAP function */
967 { if(str
) tputs(str
, n
, tput
);
970 putpar(str
, par
, n
) /* Wish we had tparm() */
973 { putnpad(tgoto(str
, 0, par
), n
);
975 #endif /*TX_TERMCAP*/
978 * Read in the stuff from termcap upon startup.
982 static int tstrlen(), tstrlp();
985 #define TCAPSLEN 1024 /* Default size of buffer for TERMCAP strings */
993 char *tcbuf
, *tcbptr
; /* Pointers into termcap buffer */
995 char tmpbuf
[TCAPSLEN
]; /* Allocate from stack */
999 /* First see if can find the terminal type. */
1000 if((tgetent(tmpbuf
, stype
)) != 1)
1003 /* Found it! Set up a string buffer to save the caps. */
1004 if(!(tcbuf
= malloc(TCAPSLEN
))) /* Get permanent buffer */
1005 t_fatal(" - cannot allocate termcap buffer");
1008 /* Now gobble all the string caps that ELLE wants to know about. */
1012 tmpstr
[0] = tcap
[i
].tcicod1
; /* Make str of the code */
1013 tmpstr
[1] = tcap
[i
].tcicod2
;
1014 tcap
[i
].tccap
= tgetstr(tmpstr
, &tcbptr
); /* Get cap */
1016 buflen
= tcbptr
- tcbuf
; /* String buffer done, finalize */
1017 if(buflen
>= TCAPSLEN
)
1018 t_fatal("description too big!");
1019 realloc(tcbuf
, buflen
); /* Free up unused part of buffer */
1020 /* (this better not move it!!!) */
1022 /* Now get the number/flag stuff that ELLE needs. */
1023 tc_am
= tgetflag("am"); /* auto wrap */
1024 if (tgetflag("xn")) tc_am
= 0; /* auto wrap at 81st char, nice! */
1025 tc_km
= (tgetflag("km") /* TTY has meta key */
1026 || tgetflag("MT")); /* Alternate version of "km"?? */
1027 scr_ht
= tgetnum("li"); /* Set screen height (# lines) */
1028 scr_wid
= tgetnum("co"); /* Set screen width (# cols) */
1031 /* Now initialize the stupid external vars that TERMCAP rtns want. */
1032 if(TC_pc
) PC
= *TC_pc
; /* Pad char */
1033 BC
= TC_bc
; /* Backspace str (if no BS) */
1034 UP
= TC_up
; /* Cursor up */
1035 ospeed
= trm_ospeed
; /* Put output speed here */
1038 /* Basic data extracted, now mull over it and set the remaining
1042 if(tgetnum("sg") <= 0) /* If no magic cookie problems */
1043 { if (TC_so
&& TC_se
) /* And have standout caps, */
1044 trm_flags
|= TF_SO
; /* Say has standout cap */
1048 if (!(TC_cm
&& TC_cl
))
1049 t_fatal("lacks cursor addressing or clear screen.");
1050 tvc_pos
= tstrlen(TC_cm
); /* Find cost of abs move */
1051 if(BC
) /* Find cost of backspace */
1052 tvc_bs
= tstrlen(BC
);
1054 /* Find costs for doing I/D char operations */
1055 if ((TC_im
||TC_ic
) && (TC_dm
||TC_dc
))
1056 { trm_flags
|= TF_IDCHR
;
1057 tvc_ci
= tstrlen(TC_im
)+tstrlen(TC_ei
);
1058 tvc_cin
= tstrlen(TC_ic
)+1+tstrlen(TC_ip
);
1059 if(TC_IC
) /* If have multi-IC, use it */
1060 { tvc_ci
+= tstrlp(TC_IC
, 1);
1063 tvc_cd
= tstrlen(TC_dm
)+tstrlen(TC_ed
);
1064 tvc_cdn
= tstrlen(TC_dc
);
1065 if(TC_DC
) /* If have multi-DC, use it */
1066 { tvc_cd
+= tstrlp(TC_DC
, 1);
1071 /* Find costs for doing I/D line operations */
1072 if ((TC_ia
|| TC_al
) && (TC_id
|| TC_dl
))
1073 { trm_flags
|= TF_IDLIN
;
1074 tvc_li
= 0; /* Usual case */
1075 tvc_lin
= tstrlen(TC_al
);
1076 if(TC_AL
) /* If have multi-IL, use it */
1077 { tvc_li
= tstrlp(TC_AL
, 1);
1078 tvc_lin
= tstrlp(TC_AL
, 2) - tvc_lin
;
1081 { tvc_li
= tstrlen(TC_im
)+tstrlen(TC_ei
);
1082 tvc_lin
= tstrlen(TC_ia
);
1085 tvc_ld
= 0; /* Usual case */
1086 tvc_ldn
= tstrlen(TC_dl
);
1087 if(TC_DL
) /* If have multi-DL, use it */
1088 { tvc_ld
= tstrlp(TC_DL
, 1);
1089 tvc_ldn
= tstrlp(TC_DL
, 2) - tvc_ld
;
1092 { tvc_ld
= tstrlen(TC_dm
)+tstrlen(TC_ed
);
1093 tvc_ldn
= tstrlen(TC_id
);
1098 { scr_wid
--; /* For now, avoid invoking wrap. */
1100 trm_flags
|= AUTOWRAP
; /* */
1103 if (TC_ce
) trm_flags
|= TF_CLEOL
; /* Term has CLEOL? */
1104 if (tc_km
) trm_flags
|= TF_METAKEY
; /* Term has meta key? */
1109 /* Pair of routines which conspire in order to find # chars actually output
1110 * by a particular termcap string.
1112 static int _tslen
; /* Stored count */
1113 static void _tslinc(ch
) { _tslen
++; }
1119 tputs(str
, 1, _tslinc
); /* Mult padding by just 1 */
1124 tstrlp(str
, par
) /* Same but with parameter */
1130 { char *cp
= tgoto(str
, 0, par
);
1133 printf(" %o", *cp
++);
1137 return !str
? 0 : tstrlen(tgoto(str
, 0, par
));
1139 #endif /*TX_TERMCAP*/
1141 /* Direct-Video terminal output routine
1142 * Currently only COHERENT has this capability.
1149 int v_position
; /* Position in video memory */
1150 int v_count
; /* Number of characters to transfer */
1151 char *v_buffer
; /* Character buffer to read/write */
1154 * Attribute masks for TIOVPUTB - attributes occupy odd addresses
1157 #define VNORM 0x07 /* Ordinary Video */
1158 #define VINTE 0x08 /* Intense video */
1159 #define VBLIN 0x80 /* Blinking video */
1160 #define VREVE 0x70 /* Reverse video */
1161 #define VUNDE 0x01 /* Underline video (mono board) */
1163 /* T_DIRECT(line, col, string, len) - Do direct-video output of string.
1164 * Puts the string ("len" chars in length) on the screen starting at
1165 * the X,Y character position given by col, line.
1166 * This routine is only called if terminal has the "TF_DIRVID" flag set.
1168 t_direct(lin
, col
, str
, len
)
1172 { register char *cp
;
1173 char vbuf
[MAXLINE
*2];
1176 if(len
<= 0) return;
1177 tbufls(); /* Ensure normal output is forced out */
1178 v
.v_position
= (lin
*80 + col
)*2;
1180 v
.v_buffer
= cp
= vbuf
;
1185 ioctl(1, TIOVPUTB
, &v
);
1190 * Terminal Output buffering routines
1193 static char tbuf
[TOBFSIZ
]; /* Output buffer */
1194 static int tbufcnt
= 0; /* # chars of room left in buffer */
1195 static char *tbufp
= 0; /* Pointer to deposit in buffer */
1207 register char *cp
, *tp
;
1225 register char *cp
, *tp
;
1245 && (cnt
= tbufp
- tbuf
) > 0) /* # chars written */
1246 write(1, tbuf
, cnt
); /* Out they go */
1248 tbufcnt
= TOBFSIZ
-1; /* Allow for usual expected decrement */
1252 * Terminal Input buffering routines
1255 int tibfmsk
= -1; /* Mask AND'ed with input chars (external) */
1256 static char tibuf
[TIBFSIZ
]; /* TTY input buffer */
1257 static char *tibfp
; /* Pointer to read from buffer */
1258 static int tibfcnt
= 0; /* # chars left to be read from buffer */
1264 extern int sun_winfd
, sun_rdevf
;
1268 return(sun_input(1)&tibfmsk
);
1269 sun_rdevf
= 0; /* Check mouse too, but only once! */
1271 if(c
!= -1) c
&= tibfmsk
;
1275 while(--tibfcnt
< 0)
1276 tibfcnt
= read(0,(tibfp
= tibuf
),TIBFSIZ
);
1277 return((*tibfp
++)&tibfmsk
);
1281 { return(tibfcnt
> 0 || ts_inp());