home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
TELECOM
/
tass.lzh
/
curses.c
< prev
next >
Wrap
Text File
|
1993-01-24
|
12KB
|
453 lines
/*
* This is a screen management library borrowed with permission from the
* Elm mail system (a great mailer--I highly recommend it!).
*
* I've hacked this library to only provide what Tass needs.
*
* Original copyright follows:
*/
/*******************************************************************************
* The Elm Mail System - $Revision: 2.1 $ $State: Exp $
*
* Copyright (c) 1986 Dave Taylor
******************************************************************************/
#include <stdio.h>
#ifndef OSK
#include <curses.h>
#include <sys/ioctl.h>
#else /* OSK */
#include <termcap.h>
#include <sgstat.h>
char PC_, *UP, *BC;
short ospeed;
#endif /* OSK */
#include "tass.h"
#define BACKSPACE '\b'
#define VERY_LONG_STRING 2500
int LINES=23;
int COLS=80;
int inverse_okay = TRUE;
/*
#ifdef BSD
# ifndef BSD4_1
# include <sgtty.h>
# else
# include <termio.h>
# endif
# else
# include <termio.h>
#endif
*/
#include <ctype.h>
/*
#ifdef BSD
#undef tolower
#endif
*/
#define TTYIN 0
#ifdef SHORTNAMES
# define _clearinverse _clrinv
# define _cleartoeoln _clrtoeoln
# define _cleartoeos _clr2eos
#endif
#ifndef BSD
#ifndef OSK
struct termio _raw_tty,
_original_tty;
#else /* OSK */
struct sgbuf _raw_tty,
_original_tty;
#endif /* OSK */
#else
#define TCGETA TIOCGETP
#define TCSETAW TIOCSETP
struct sgttyb _raw_tty,
_original_tty;
#endif
static int _inraw = 0; /* are we IN rawmode? */
#define DEFAULT_LINES_ON_TERMINAL 24
#define DEFAULT_COLUMNS_ON_TERMINAL 80
static int _memory_locked = 0; /* are we IN memlock?? */
static int _intransmit; /* are we transmitting keys? */
static
char *_clearscreen, *_moveto, *_cleartoeoln, *_cleartoeos,
*_setinverse, *_clearinverse, *_setunderline, *_clearunderline;
# define K_UP 0
# define K_DOWN 1
# define K_LEFT 2
# define K_RIGHT 3
# define K_PUP 4
# define K_PDOWN 5
# define K_MAX 6
static
char *_spckey[K_MAX];
static
char *_spckeytc[K_MAX] = {
"ku", "kd", "kl", "kr", "kP", "kN"
};
static
int _lines,_columns;
static char _terminal[1024]; /* Storage for terminal entry */
static char _capabilities[1024]; /* String for cursor motion */
static char *ptr = _capabilities; /* for buffering */
int outchar(); /* char output for tputs */
char *tgetstr(), /* Get termcap capability */
*tgoto(); /* and the goto stuff */
InitScreen()
{
int tgetent(), /* get termcap entry */
err;
char termname[40];
char *strcpy(), *getenv();
int i;
if (getenv("TERM") == NULL) {
fprintf(stderr,
"TERM variable not set; Tass requires screen capabilities\n");
return(FALSE);
}
if (strcpy(termname, getenv("TERM")) == NULL) {
fprintf(stderr,"Can't get TERM variable\n");
return(FALSE);
}
if ((err = tgetent(_terminal, termname)) != 1) {
fprintf(stderr,"Can't get entry for TERM\n");
return(FALSE);
}
/* load in all those pesky values */
_clearscreen = tgetstr("cl", &ptr);
_moveto = tgetstr("cm", &ptr);
_cleartoeoln = tgetstr("ce", &ptr);
_cleartoeos = tgetstr("cd", &ptr);
_lines = tgetnum("li");
_columns = tgetnum("co");
_setinverse = tgetstr("so", &ptr);
_clearinverse = tgetstr("se", &ptr);
_setunderline = tgetstr("us", &ptr);
_clearunderline = tgetstr("ue", &ptr);
if (!_clearscreen) {
fprintf(stderr,
"Terminal must have clearscreen (cl) capability\n");
return(FALSE);
}
if (!_moveto) {
fprintf(stderr,
"Terminal must have cursor motion (cm)\n");
return(FALSE);
}
if (!_cleartoeoln) {
fprintf(stderr,
"Terminal must have clear to end-of-line (ce)\n");
return(FALSE);
}
if (!_cleartoeos) {
fprintf(stderr,
"Terminal must have clear to end-of-screen (cd)\n");
return(FALSE);
}
if (_lines == -1)
_lines = DEFAULT_LINES_ON_TERMINAL;
if (_columns == -1)
_columns = DEFAULT_COLUMNS_ON_TERMINAL;
for (i = 0; i < K_MAX; ++i)
_spckey[i] = tgetstr (_spckeytc[i], &ptr);
return(TRUE);
}
ScreenSize(lines, columns)
int *lines, *columns;
{
/** returns the number of lines and columns on the display. **/
if (_lines == 0) _lines = DEFAULT_LINES_ON_TERMINAL;
if (_columns == 0) _columns = DEFAULT_COLUMNS_ON_TERMINAL;
*lines = _lines - 1; /* assume index from zero*/
*columns = _columns; /* assume index from one */
}
ClearScreen()
{
/* clear the screen: returns -1 if not capable */
tputs(_clearscreen, 1, outchar);
fflush(stdout); /* clear the output buffer */
}
MoveCursor(row, col)
int row, col;
{
/** move cursor to the specified row column on the screen.
0,0 is the top left! **/
char *stuff, *tgoto();
stuff = tgoto(_moveto, col, row);
tputs(stuff, 1, outchar);
fflush(stdout);
}
CleartoEOLN()
{
/** clear to end of line **/
tputs(_cleartoeoln, 1, outchar);
fflush(stdout); /* clear the output buffer */
}
CleartoEOS()
{
/** clear to end of screen **/
tputs(_cleartoeos, 1, outchar);
fflush(stdout); /* clear the output buffer */
}
StartInverse()
{
/** set inverse video mode **/
if (_setinverse && inverse_okay)
tputs(_setinverse, 1, outchar);
/* fflush(stdout); */
}
EndInverse()
{
/** compliment of startinverse **/
if (_clearinverse && inverse_okay)
tputs(_clearinverse, 1, outchar);
/* fflush(stdout); */
}
#if 0
StartUnderline()
{
/** start underline mode **/
if (!_setunderline)
return(-1);
tputs(_setunderline, 1, outchar);
fflush(stdout);
return(0);
}
EndUnderline()
{
/** the compliment of start underline mode **/
if (!_clearunderline)
return(-1);
tputs(_clearunderline, 1, outchar);
fflush(stdout);
return(0);
}
#endif
RawState()
{
/** returns either 1 or 0, for ON or OFF **/
return( _inraw );
}
Raw(state)
int state;
{
/** state is either TRUE or FALSE, as indicated by call **/
if (state == FALSE && _inraw) {
#ifndef OSK
(void) ioctl(TTYIN, TCSETAW, &_original_tty);
#else /* OSK */
(void) _ss_opt (TTYIN, &_original_tty);
#endif /* OSK */
_inraw = 0;
}
else if (state == TRUE && ! _inraw) {
#ifndef OSK
(void) ioctl(TTYIN, TCGETA, &_original_tty); /** current setting **/
(void) ioctl(TTYIN, TCGETA, &_raw_tty); /** again! **/
#ifdef BSD
_raw_tty.sg_flags &= ~(ECHO | CRMOD); /* echo off */
_raw_tty.sg_flags |= CBREAK; /* raw on */
#else
_raw_tty.c_lflag &= ~(ICANON | ECHO); /* noecho raw mode */
_raw_tty.c_cc[VMIN] = '\01'; /* minimum # of chars to queue */
_raw_tty.c_cc[VTIME] = '\0'; /* minimum time to wait for input */
#endif
(void) ioctl(TTYIN, TCSETAW, &_raw_tty);
#else /* OSK */
(void) _gs_opt (TTYIN, &_original_tty);
_raw_tty = _original_tty;
_raw_tty.sg_echo = 0;
_raw_tty.sg_pause = 0;
_raw_tty.sg_alf = 0;
_raw_tty.sg_psch = 0;
_raw_tty.sg_eofch = 0;
(void) _ss_opt (TTYIN, &_raw_tty);
#endif /* OSK */
_inraw = 1;
}
}
int
ReadCh()
{
/** read a character with Raw mode set! **/
register int result;
char ch;
register int i, j, n;
register char *spc;
spc = NULL;
do {
if (spc) {
#ifdef OSK
tsleep (4);
if (_gs_rdy (0) < 1)
tsleep (50 | (1 << 31));
if (_gs_rdy (0) < 1)
#else /* OSK */
#ifdef FIONREAD
#define CH_READ FIONREAD
#else /* FIONREAD */
#ifdef TCRDCHK
#define CH_READ TCRDCHK
#else /* TCRDCHK */
Panic!
#endif /* TCRDCHK */
#endif /* FIONREAD */
int tmp;
ioctl (0, CH_READ, &tmp);
if (tmp < 1)
nap (200);
ioctl (0, CH_READ, &tmp);
if (tmp < 1)
#endif /* OSK */
spc = NULL;
}
if ((result = read(0, &ch, 1)) != 1)
break;
if (!spc) {
for (i = 0; i < K_MAX; ++i)
if (_spckey[i] && (_spckey[i][0] == ch)) {
spc = _spckey[i];
n = 1;
break;
}
} else if (ch != spc[n]) {
for (j = 0; j < K_MAX; ++j)
if (!_spckey[j])
continue;
else if (spc[0]) {
if ((!strncmp (spc, _spckey[j], n - 1)) && (_spckey[j][n] == ch))
break;
} else if (spc[0] == _spckey[j][0]) {
if (n > 1) {
if ((!strncmp (spc + 1, _spckey[j] + 1, n - 2)) && (_spckey[j][n] == ch))
break;
} else if (_spckey[j][n] == ch)
break;
}
if (j < K_MAX) {
spc = _spckey[j];
i = j;
++n;
} else {
spc = NULL;
result = -1;
}
} else
++n;
if (spc && (!spc[n])) {
spc = NULL;
switch (i) {
case K_UP:
ch = ctrl('P');
break;
case K_DOWN:
ch = ctrl('N');
break;
case K_LEFT:
ch = ctrl('B');
break;
case K_RIGHT:
ch = ctrl('F');
break;
case K_PUP:
ch = ctrl('Z');
break;
case K_PDOWN:
ch = ctrl('V');
break;
}
}
} while (spc || (result < 0));
return((result <= 0 ) ? EOF : ch & 0x7F);
}
outchar(c)
char c;
{
/** output the given character. From tputs... **/
/** Note: this CANNOT be a macro! **/
putc(c, stdout);
}
#ifdef NO_NAP
nap (n)
int n;
{
int t;
for (t = 100 * n; t > 0; --t)
;
}
#endif /* NO_NAP */