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

File: [local] / src / usr.bin / mg / ttyio.c (download)

Revision 1.7, Sun Feb 27 17:30:40 2000 UTC (24 years, 3 months ago) by millert
Branch: MAIN
Changes since 1.6: +14 -0 lines

make this compile on systems w/o TCSASOFT

/*
 * POSIX terminal I/O.
 *
 * The functions in this file
 * negotiate with the operating system for
 * keyboard characters, and write characters to
 * the display in a barely buffered fashion.
 */
#include	"def.h"

#include	<sys/types.h>
#include	<sys/time.h>
#include	<sys/ioctl.h>
#include	<fcntl.h>
#include	<termios.h>
#include	<term.h>

#define	NOBUF	512			/* Output buffer size.		*/

#ifndef TCSASOFT
#define TCSASOFT	0
#endif

char	obuf[NOBUF];			/* Output buffer.		*/
int	nobuf;				/* buffer count			*/

static struct termios	ot;		/* entry state of the terminal	*/
static struct termios	nt;		/* editor's terminal state	*/

static int ttyactivep = FALSE;		/* terminal in editor mode?	*/
static int ttysavedp = FALSE;		/* terminal state saved?	*/

int	nrow;				/* Terminal size, rows.		*/
int	ncol;				/* Terminal size, columns.	*/

/*
 * This function gets called once, to set up
 * the terminal channel.  This version turns off flow
 * control.  This may be wrong for your system, but no
 * good solution has really been found (daveb).
 */
ttopen()
{
	register char	*cp;

	if (ttyactivep)
		return;

	if( !ttysavedp )
	{
		if (tcgetattr(0, &ot) < 0)
			abort();
		nt = ot;		/* save entry state		*/
		/* Set terminal to 'raw' mode and ignore a 'break' */
		nt.c_cc[VMIN] = 1;
		nt.c_cc[VTIME] = 0;
		nt.c_iflag |= IGNBRK;
		nt.c_iflag &= ~(BRKINT|PARMRK|INLCR|IGNCR|ICRNL|IXON);
		nt.c_oflag &= ~OPOST;
		nt.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);

#if !TCSASOFT
		/*
		 * If we don't have TCSASOFT, force terminal to
		 * 8 bits, no parity.
		 */
		nt.c_iflag &= ~ISTRIP;
		nt.c_cflag &= ~(CSIZE|PARENB);
		nt.c_cflag |= CS8;
#endif

		ttysavedp = TRUE;
	}
	
	if (tcsetattr(0, TCSASOFT | TCSADRAIN, &nt) < 0)
		abort();

	ttyactivep = TRUE;
}

/*
 * This function gets called just
 * before we go back home to the shell. Put all of
 * the terminal parameters back.
 */
ttclose()
{
	if(!ttysavedp || !ttyactivep)
		return;
	ttflush();
	if (tcsetattr(0, TCSASOFT | TCSADRAIN, &ot) < 0)
		abort();
	ttyactivep = FALSE;
}

/*
 * Write character to the display.
 * Characters are buffered up, to make things
 * a little bit more efficient.
 */
ttputc(c)
{

	if (nobuf >= NOBUF)
		ttflush();
	obuf[nobuf++] = c;
}

/*
 * Flush output.
 */
ttflush()
{

	if (nobuf != 0) {
		write(1, obuf, nobuf);
		nobuf = 0;
	}
}

/*
 * Read character from terminal.
 * All 8 bits are returned, so that you can use
 * a multi-national terminal.
 *
 * If keyboard 'queue' already has typeahead from a typeahead() call,
 * just return it.  Otherwise, make sure we are in blocking i/o mode
 * and read a character.
 */
ttgetc()
{
	int    c;

	while (read(0, &c, 1) != 1)
		;
	return (c & 0xFF);
}

/*
 * Return TRUE if there are characters waiting to be read.
 */
typeahead()
{
	int x;

	return((ioctl(0, FIONREAD, (char *) &x) < 0) ? 0 : x);
}


/*
 * panic:  print error and die, leaving core file.
 * Don't know why this is needed (daveb).
 */
panic(s)
char *s;
{

	(void) fputs("panic: ", stderr);
	(void) fputs(s, stderr);
	(void) fputc('\n', stderr);
	abort();		/* To leave a core image. */
}


/*
** This should check the size of the window, and reset if needed.
*/

setttysize()
{
#ifdef	TIOCGWINSZ
        struct winsize winsize;

	if (ioctl(0, TIOCGWINSZ, (char *) &winsize) == 0) {
		nrow = winsize.ws_row;
		ncol = winsize.ws_col;
	} else
#endif
	if ((nrow = lines) <= 0 || (ncol = columns) <= 0) {
		nrow = 24;
		ncol = 80;
	}

	/* Enforce maximum screen size. */
	if (nrow > NROW)
		nrow = NROW;
	if (ncol > NCOL)
		ncol = NCOL;
}

#ifndef NO_DPROMPT
/*
 * Return TRUE if we wait without doing anything, else return FALSE.
 */
ttwait()
{
	fd_set readfds;
	struct timeval tmout;

	FD_ZERO(&readfds);
	FD_SET(0, &readfds);

	tmout.tv_sec = 2;
	tmout.tv_usec = 0;

	if ((select(1, &readfds, NULL, NULL, &tmout)) == 0)
		return(TRUE);
	return(FALSE);
}
#endif NO_DPROMPT