2.9BSD/usr/contrib/notes/cursor.c

Compare this file to the similar file:
Show the results in this format:

static char *sccsid = "%W%";

/*
 * Terminal driving routines
 */

#include "parms.h"
#include "structs.h"

static char bufcap[256];
static char *CM;			/* cursor motion control */
static char *CL;			/* clear screen control */
static char *CE;			/* clear to end of line */
static char *SO;			/* standout mode */
static char *SE;			/* end standout mode */
static int cur_row;
static int cur_col;
static int top_col;			/* last printable character for top */
static int bot_col;			/* same for the bottom line */

char *tgoto();				/* decodes the cursor via termcap */

/*
 * charout - output 1 character
 * used by termcap tputs routine
 */
charout(c)
{
	putchar(c);
}

/*
 *  at(row,col) places cursor at row,col
 *	row = 1 to 24    ( y coords )
 * 	column = 1 to 80   ( x coords )
 */
at(row, col)
{
	register char  *p;

	if (CM) {
		if (row <= 0)
			row += nrows;		/* wraparound - cute */
		if (col <= 0)
			col += ncols;
		p = tgoto(CM, col - 1, row - 1);
		tputs(p, 1, charout);
	} else {
		if (cur_row != row)
			putchar('\n');
		else
			putchar(' ');
	}
	cur_row = row;
	cur_col = col;
}

/*
 * erase() erases the screen
 */
erase()
{
	if (CL)
		tputs(CL, 1, charout);
	else
		printf("\n\n");
	cur_row = 1;			/* back in top of screen */
	cur_col = 1;			/* back in top of screen */
	top_col = 0;
	bot_col = 0;
}

clear_eol()
{
	int i;
	int last_col;

	/*
	 * No need to do anything if there are no characters to
	 * the right (cur_col > last_col).
	 *
	 * last_col is determined in a rather crude way.
	 * We actually only keep track of the rightmost position for
	 * the bottom line (bot_col) and the lines above it (top_col)
	 */
	last_col = (cur_row == nrows) ? bot_col : top_col;
	if (cur_col > last_col)
		return;
	if (CE)
		tputs(CE, 1, charout);
	else {
		for (i = cur_col; i <= last_col; i++)
			putchar(' ');
		for (i = cur_col; i <= last_col; i++)
			putchar('\b');
	}
	/* update the line position indicators */
	if (cur_row == nrows)
		bot_col = cur_col;
	/* can't update top_col because there are many possible lines */
}

cursget()
{
	char *tgetstr();
	char *q;
	register int i;				/* rows, cols */
	char bp[1024];				/* termcap stuff */
	extern char *myterm;

	if (tgetent(bp, myterm) != 1)
		return(-1);
	q = bufcap;
	CM = tgetstr("cm", &q);			/* get the cursor motion */
	CL = tgetstr("cl", &q);			/* get the clear screen */
	CE = tgetstr("ce", &q);			/* get the clear to eol */
	SO = tgetstr("so", &q);
	SE = tgetstr("se", &q);

	if ((i = tgetnum("li")) != -1)
		nrows = i;				/* rows on screen */
	if (nrows > 24)
		nindex += nrows - 24;
	if ((i = tgetnum("co")) != -1)
		ncols = i;				/* cols on screen */
	return(0);
}

/*
 * get the coordinates of the cursor
 */
curpos(row, col)
int *row, *col;
{
	*row = cur_row;
	*col = cur_col;
}

/*
 * a putchar with no interpretation of characters
 * updates current cursor position
 */
putch(c)
{
	switch (c) {
	case '\t':
		cur_col = ((cur_col + 7) & ~07) + 1;
		break;
	case '\n':
		cur_row++;
		/* FALL INTO ... */
	case '\r':
		cur_col = 1;
		break;
	case '\b':
		if (cur_col > 1)
			cur_col--;
		break;
	default:
		if (c >= 040 && c < 0177)
			cur_col++;
		break;
	}
	putchar(c);
	/* update the line position indicators */
	if (cur_row == nrows) {
		if (cur_col > bot_col)
			bot_col = cur_col;
	} else if (cur_col > top_col)
		top_col = cur_col;
}

standout(flag)
{
	if (flag) {
		if (SO)
			tputs(SO, 1, charout);
		else
			putchar('\007');
	} else {
		if (SE)
			tputs(SE, 1, charout);
	}
}