133686Sbostic /* 233686Sbostic * Copyright (c) 1988 Regents of the University of California. 333686Sbostic * All rights reserved. 433686Sbostic * 533686Sbostic * Redistribution and use in source and binary forms are permitted 634898Sbostic * provided that the above copyright notice and this paragraph are 734898Sbostic * duplicated in all such forms and that any documentation, 834898Sbostic * advertising materials, and other materials related to such 934898Sbostic * distribution and use acknowledge that the software was developed 1034898Sbostic * by the University of California, Berkeley. The name of the 1134898Sbostic * University may not be used to endorse or promote products derived 1234898Sbostic * from this software without specific prior written permission. 1334898Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434898Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1534898Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1633686Sbostic */ 1733686Sbostic 1833686Sbostic #ifndef lint 19*38690Sborman static char sccsid[] = "@(#)terminal.c 1.16 (Berkeley) 08/21/89"; 2033686Sbostic #endif /* not lint */ 2133686Sbostic 2232148Sminshall #include <arpa/telnet.h> 2332381Sminshall #include <sys/types.h> 2432148Sminshall 2532381Sminshall #include "ring.h" 2632381Sminshall 2732148Sminshall #include "externs.h" 2832148Sminshall #include "types.h" 2932148Sminshall 3032531Sminshall Ring ttyoring, ttyiring; 3132531Sminshall char ttyobuf[2*BUFSIZ], ttyibuf[BUFSIZ]; 3232148Sminshall 3338208Sminshall int termdata; /* Debugging flag */ 3438208Sminshall 35*38690Sborman #ifdef USE_TERMIO 3632148Sminshall char 3732148Sminshall termFlushChar, 3832148Sminshall termLiteralNextChar, 39*38690Sborman termSuspChar, 40*38690Sborman termWerasChar, 41*38690Sborman termRprntChar, 42*38690Sborman termStartChar, 43*38690Sborman termStopChar; 44*38690Sborman #endif 4532148Sminshall 4632148Sminshall /* 4732148Sminshall * initialize the terminal data structures. 4832148Sminshall */ 4932148Sminshall 5032148Sminshall init_terminal() 5132148Sminshall { 5234848Sminshall if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) { 5334848Sminshall exit(1); 5434848Sminshall } 5534848Sminshall if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) { 5634848Sminshall exit(1); 5734848Sminshall } 5832148Sminshall autoflush = TerminalAutoFlush(); 5932148Sminshall } 6032148Sminshall 6132148Sminshall 6232148Sminshall /* 6332148Sminshall * Send as much data as possible to the terminal. 6432148Sminshall * 65*38690Sborman * Return value: 66*38690Sborman * -1: No useful work done, data waiting to go out. 67*38690Sborman * 0: No data was waiting, so nothing was done. 68*38690Sborman * 1: All waiting data was written out. 69*38690Sborman * n: All data - n was written out. 7032148Sminshall */ 7132148Sminshall 7232148Sminshall 7332148Sminshall int 7432257Sminshall ttyflush(drop) 7532257Sminshall int drop; 7632148Sminshall { 7732667Sminshall register int n, n0, n1; 7832148Sminshall 7932667Sminshall n0 = ring_full_count(&ttyoring); 8032667Sminshall if ((n1 = n = ring_full_consecutive(&ttyoring)) > 0) { 8132257Sminshall if (drop) { 8232148Sminshall TerminalFlushOutput(); 8332148Sminshall /* we leave 'n' alone! */ 8432257Sminshall } else { 8533286Sminshall n = TerminalWrite(ttyoring.consume, n); 8632148Sminshall } 8732148Sminshall } 8832667Sminshall if (n > 0) { 8938208Sminshall if (termdata && n) { 9038208Sminshall Dump('>', ttyoring.consume, n); 9138208Sminshall } 9232667Sminshall /* 9332667Sminshall * If we wrote everything, and the full count is 9432667Sminshall * larger than what we wrote, then write the 9532667Sminshall * rest of the buffer. 9632667Sminshall */ 9732667Sminshall if (n1 == n && n0 > n) { 9832667Sminshall n1 = n0 - n; 9932667Sminshall if (!drop) 10033286Sminshall n1 = TerminalWrite(ttyoring.bottom, n1); 10132667Sminshall n += n1; 10232667Sminshall } 10332528Sminshall ring_consumed(&ttyoring, n); 10432148Sminshall } 105*38690Sborman if (n < 0) 106*38690Sborman return -1; 107*38690Sborman if (n == n0) { 108*38690Sborman if (n0) 109*38690Sborman return -1; 110*38690Sborman return 0; 111*38690Sborman } 112*38690Sborman return n0 - n + 1; 11332148Sminshall } 11432148Sminshall 11532148Sminshall 11632148Sminshall /* 11732148Sminshall * These routines decides on what the mode should be (based on the values 11832148Sminshall * of various global variables). 11932148Sminshall */ 12032148Sminshall 12132148Sminshall 12232148Sminshall int 12332148Sminshall getconnmode() 12432148Sminshall { 125*38690Sborman extern int linemode; 126*38690Sborman int mode = 0; 127*38690Sborman #ifdef KLUDGELINEMODE 128*38690Sborman extern int kludgelinemode; 129*38690Sborman #endif 13032148Sminshall 131*38690Sborman if (In3270) 132*38690Sborman return(MODE_FLOW); 133*38690Sborman 134*38690Sborman if (my_want_state_is_dont(TELOPT_ECHO)) 135*38690Sborman mode |= MODE_ECHO; 136*38690Sborman 137*38690Sborman if (localflow) 138*38690Sborman mode |= MODE_FLOW; 139*38690Sborman 140*38690Sborman #ifdef KLUDGELINEMODE 141*38690Sborman if (kludgelinemode) { 142*38690Sborman if (my_want_state_is_dont(TELOPT_SGA)) { 143*38690Sborman mode |= (MODE_TRAPSIG|MODE_EDIT); 144*38690Sborman if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) { 145*38690Sborman mode &= ~MODE_ECHO; 146*38690Sborman } 147*38690Sborman } 148*38690Sborman return(mode); 14932148Sminshall } 150*38690Sborman #endif 151*38690Sborman if (my_want_state_is_will(TELOPT_LINEMODE)) 152*38690Sborman mode |= linemode; 153*38690Sborman return(mode); 15432148Sminshall } 15532148Sminshall 15632148Sminshall void 157*38690Sborman setconnmode(force) 15832148Sminshall { 159*38690Sborman TerminalNewMode(getconnmode()|(force?MODE_FORCE:0)); 16032148Sminshall } 16132148Sminshall 16232148Sminshall 16332148Sminshall void 16432148Sminshall setcommandmode() 16532148Sminshall { 166*38690Sborman TerminalNewMode(-1); 16732148Sminshall } 168