/* tty.c
 *
 * Tty mode settings
 *
 * Copyright (c) 1993,1994 by Ezra Story.  All rights reserved.  Permission to
 * copy this program is given provided that the copy is not sold and that
 * this copyright notice is included.
 *
 */
static char rcsid[] = "$Id: tty.c 1.3 1994/06/07 02:57:27 Ezra_Story Exp $";

#include "config.h"
#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#ifdef SYSSELECT
#include <sys/select.h>
#endif
#include "lists.h"
#include "mydefs.h"

#define XON     021     /* ASCII XON (ASR-33 paper-tape reader on) */
#define XOFF    023     /* ASCII XOFF (ASR-33 paper-tape reader off) */

proto TtyRaw();
proto TtyRestore();
proto TtyResize();

#ifndef FREAD
#define FREAD 0x0001
#endif
#ifndef FWRITE
#define FWRITE 0x0002
#endif

int            operm;
int            inout = FREAD|FWRITE;

#ifndef TERMIO
#include <sgtty.h>

struct sgttyb  ostty,    nstty;
struct tchars  otchars,  ntchars;
struct ltchars oltchars, nltchars;
int            olmode,   nlmode;

/* TIOCSWINSZ is in 4.3BSD, TIOCSSIZE is in Sun UNIX */
/* no USG code...deal with it! :-)                   */

TtyRaw()
{
        struct stat st;

        /* get old tty settings */

        if (fstat(0, &st) == 0) operm = st.st_mode & 06777;
        else operm = -1;

        ioctl(0, (int)TIOCGETP, (char *)&ostty);
        ioctl(0, (int)TIOCGETC, (char *)&otchars);
        ioctl(0, (int)TIOCGLTC, (char *)&oltchars);
        ioctl(0, (int)TIOCLGET, (char *)&olmode);
        nstty              = ostty;
        ntchars            = otchars;
        nltchars           = oltchars;
        nlmode             = olmode;


        nstty.sg_flags  = RAW;     /* | = RAW;  nstty.sg_flags &= ~ECHO; */

        nstty.sg_erase     = nstty.sg_kill     = -1;

        ntchars.t_intrc    = ntchars.t_quitc   = -1;
        ntchars.t_eofc     = ntchars.t_brkc    = -1;

        nltchars.t_suspc   = nltchars.t_dsuspc = -1;
        nltchars.t_rprntc  = nltchars.t_flushc = -1;
        nltchars.t_werasc  = nltchars.t_lnextc = -1;

        /* tell ourselves about it */
        if (operm != -1 && fchmod(0, S_IREAD|S_IWRITE) < 0) operm = -1;
        ioctl(0, (int)TIOCSETN, (char *)&nstty);
        ioctl(0, (int)TIOCSETC, (char *)&ntchars);
        ioctl(0, (int)TIOCSLTC, (char *)&nltchars);
        ioctl(0, (int)TIOCLSET, (char *)&nlmode);

}


TtyRestore()
{

        /* tell UNIX to restore our old tty settings */

        (void)ioctl(0, (int)TIOCFLUSH, (char *)&inout);
        (void)ioctl(0, (int)TIOCSETP, (char *)&ostty);
        (void)ioctl(0, (int)TIOCSETC, (char *)&otchars);
        (void)ioctl(0, (int)TIOCSLTC, (char *)&oltchars);
        (void)ioctl(0, (int)TIOCLSET, (char *)&olmode);
        if (operm != -1)
                (void)fchmod(0, operm);
}

#else  /* termio */

#include <termios.h>
struct termios otermio, ntermio;
#ifndef TCATTR
#ifndef TCSETS
#define TCSETS TCSANOW
#endif
#ifndef TCGETS
#define TCGETS TCGETP
#endif
#else
#ifndef TCSANOW
#define TCSANOW TCSETS
#endif
#endif

TtyRaw()
{
    struct stat st;

    /* get old tty settings */

    if (fstat(0, &st) == 0) operm = st.st_mode & 06777;
    else operm = -1;

#ifdef TCATTR
    tcgetattr(0,&otermio);
#else
    ioctl(0,TCGETS,&otermio);
#endif
    ntermio = otermio;

    ntermio.c_iflag = 0;
    ntermio.c_oflag = 0;
    ntermio.c_lflag = 0;

    ntermio.c_cc[VMIN] = 128;
    ntermio.c_cc[VTIME] = 1;

    if (operm != -1 && fchmod(0, S_IREAD|S_IWRITE) < 0) operm = -1;
#ifdef TCATTR
    tcsetattr(0,TCSANOW, &ntermio);
#else
    ioctl(0,TCSETS, &ntermio);
#endif

}

TtyRestore()
{
#ifdef TCATTR
    tcsetattr(0,TCSANOW, &otermio);
#else
    ioctl(0,TCSETS,&otermio);
#endif
    if (operm != -1)
        (void)fchmod(0, operm);
}

#endif /* termio */


TtyResize(fd,x,y)
fildes_t fd;
{
#ifdef TIOCSWINSZ
        /* set window size on pty (4.3BSD) */
        struct winsize ws;
        ws.ws_row = y;
        ws.ws_col = x;
        ws.ws_xpixel = x*8;  /* doesn't mean anything in our case */
        ws.ws_ypixel = y*8;  /* so I choose a reasonable default  */
        (void)ioctl(fd, (int)TIOCSWINSZ,(char *)&ws);
#else
#ifdef TIOCSSIZE
        /* set window size on pty (Sun) */
        struct ttysize ts;
        ts.ts_lines = y;
        ts.ts_cols = x;
        (void)ioctl(fd, (int)TIOCSSIZE,(char *)&ts);
#endif
#endif
}


