[BACK]Return to ttyio.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mg

Annotation of src/usr.bin/mg/ttyio.c, Revision 1.6

1.1       deraadt     1: /*
1.5       millert     2:  * POSIX terminal I/O.
1.1       deraadt     3:  *
                      4:  * The functions in this file
                      5:  * negotiate with the operating system for
                      6:  * keyboard characters, and write characters to
                      7:  * the display in a barely buffered fashion.
                      8:  */
                      9: #include       "def.h"
                     10:
                     11: #include       <sys/types.h>
1.5       millert    12: #include       <sys/time.h>
                     13: #include       <sys/ioctl.h>
1.1       deraadt    14: #include       <fcntl.h>
1.2       deraadt    15: #include       <termios.h>
1.4       millert    16: #include       <term.h>
1.1       deraadt    17:
                     18: #define        NOBUF   512                     /* Output buffer size.          */
                     19:
                     20: char   obuf[NOBUF];                    /* Output buffer.               */
                     21: int    nobuf;                          /* buffer count                 */
                     22:
1.2       deraadt    23: static struct termios  ot;             /* entry state of the terminal  */
                     24: static struct termios  nt;             /* editor's terminal state      */
1.1       deraadt    25:
                     26: static int ttyactivep = FALSE;         /* terminal in editor mode?     */
                     27: static int ttysavedp = FALSE;          /* terminal state saved?        */
                     28:
                     29: int    nrow;                           /* Terminal size, rows.         */
                     30: int    ncol;                           /* Terminal size, columns.      */
                     31:
                     32: /*
                     33:  * This function gets called once, to set up
                     34:  * the terminal channel.  This version turns off flow
                     35:  * control.  This may be wrong for your system, but no
                     36:  * good solution has really been found (daveb).
                     37:  */
                     38: ttopen()
                     39: {
                     40:        register char   *cp;
                     41:
                     42:        if (ttyactivep)
                     43:                return;
                     44:
                     45:        if( !ttysavedp )
                     46:        {
1.2       deraadt    47:                if (tcgetattr(0, &ot) < 0)
1.1       deraadt    48:                        abort();
                     49:                nt = ot;                /* save entry state             */
1.6     ! millert    50:                /* Set terminal to 'raw' mode and ignore a 'break' */
        !            51:                nt.c_cc[VMIN] = 1;
        !            52:                nt.c_cc[VTIME] = 0;
1.1       deraadt    53:                nt.c_iflag |= IGNBRK;
1.6     ! millert    54:                nt.c_iflag &= ~(BRKINT|PARMRK|INLCR|IGNCR|ICRNL|IXON);
1.1       deraadt    55:                nt.c_oflag &= ~OPOST;
1.6     ! millert    56:                nt.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
1.1       deraadt    57:
                     58:                ttysavedp = TRUE;
                     59:        }
                     60:
1.6     ! millert    61:        if (tcsetattr(0, TCSASOFT | TCSADRAIN, &nt) < 0)
1.1       deraadt    62:                abort();
                     63:
                     64:        ttyactivep = TRUE;
                     65: }
                     66:
                     67: /*
                     68:  * This function gets called just
                     69:  * before we go back home to the shell. Put all of
                     70:  * the terminal parameters back.
                     71:  */
                     72: ttclose()
                     73: {
                     74:        if(!ttysavedp || !ttyactivep)
                     75:                return;
                     76:        ttflush();
1.6     ! millert    77:        if (tcsetattr(0, TCSASOFT | TCSADRAIN, &ot) < 0)
1.1       deraadt    78:                abort();
                     79:        ttyactivep = FALSE;
                     80: }
                     81:
                     82: /*
                     83:  * Write character to the display.
                     84:  * Characters are buffered up, to make things
                     85:  * a little bit more efficient.
                     86:  */
                     87: ttputc(c)
                     88: {
1.5       millert    89:
1.1       deraadt    90:        if (nobuf >= NOBUF)
                     91:                ttflush();
                     92:        obuf[nobuf++] = c;
                     93: }
                     94:
                     95: /*
                     96:  * Flush output.
                     97:  */
                     98: ttflush()
                     99: {
1.5       millert   100:
1.1       deraadt   101:        if (nobuf != 0) {
                    102:                write(1, obuf, nobuf);
                    103:                nobuf = 0;
                    104:        }
                    105: }
                    106:
                    107: /*
                    108:  * Read character from terminal.
                    109:  * All 8 bits are returned, so that you can use
                    110:  * a multi-national terminal.
                    111:  *
                    112:  * If keyboard 'queue' already has typeahead from a typeahead() call,
                    113:  * just return it.  Otherwise, make sure we are in blocking i/o mode
                    114:  * and read a character.
                    115:  */
                    116: ttgetc()
                    117: {
1.5       millert   118:        int    c;
                    119:
                    120:        while (read(0, &c, 1) != 1)
                    121:                ;
                    122:        return (c & 0xFF);
1.1       deraadt   123: }
                    124:
                    125: /*
1.5       millert   126:  * Return TRUE if there are characters waiting to be read.
1.1       deraadt   127:  */
                    128: typeahead()
                    129: {
1.5       millert   130:        int x;
                    131:
                    132:        return((ioctl(0, FIONREAD, (char *) &x) < 0) ? 0 : x);
1.1       deraadt   133: }
                    134:
                    135:
                    136: /*
                    137:  * panic:  print error and die, leaving core file.
                    138:  * Don't know why this is needed (daveb).
                    139:  */
                    140: panic(s)
                    141: char *s;
                    142: {
1.5       millert   143:
                    144:        (void) fputs("panic: ", stderr);
                    145:        (void) fputs(s, stderr);
                    146:        (void) fputc('\n', stderr);
                    147:        abort();                /* To leave a core image. */
1.1       deraadt   148: }
                    149:
                    150:
                    151: /*
                    152: ** This should check the size of the window, and reset if needed.
                    153: */
                    154:
                    155: setttysize()
                    156: {
                    157: #ifdef TIOCGWINSZ
                    158:         struct winsize winsize;
1.5       millert   159:
1.1       deraadt   160:        if (ioctl(0, TIOCGWINSZ, (char *) &winsize) == 0) {
1.5       millert   161:                nrow = winsize.ws_row;
                    162:                ncol = winsize.ws_col;
1.1       deraadt   163:        } else
                    164: #endif
1.4       millert   165:        if ((nrow = lines) <= 0 || (ncol = columns) <= 0) {
1.1       deraadt   166:                nrow = 24;
                    167:                ncol = 80;
                    168:        }
1.4       millert   169:
                    170:        /* Enforce maximum screen size. */
                    171:        if (nrow > NROW)
                    172:                nrow = NROW;
                    173:        if (ncol > NCOL)
1.1       deraadt   174:                ncol = NCOL;
                    175: }
                    176:
                    177: #ifndef NO_DPROMPT
                    178: /*
                    179:  * Return TRUE if we wait without doing anything, else return FALSE.
                    180:  */
                    181: ttwait()
                    182: {
1.5       millert   183:        fd_set readfds;
                    184:        struct timeval tmout;
                    185:
                    186:        FD_ZERO(&readfds);
                    187:        FD_SET(0, &readfds);
                    188:
                    189:        tmout.tv_sec = 2;
                    190:        tmout.tv_usec = 0;
                    191:
                    192:        if ((select(1, &readfds, NULL, NULL, &tmout)) == 0)
                    193:                return(TRUE);
                    194:        return(FALSE);
1.1       deraadt   195: }
                    196: #endif NO_DPROMPT