uemacs/tcap.c

364 lines
6.9 KiB
C

/* tcap.c -- implements terminal.h */
#include "terminal.h"
/* Unix V7 SysV and BS4 Termcap video driver
*
* modified by Petri Kutvonen
*/
#include <stdlib.h>
#include <string.h>
/*
* Defining this to 1 breaks tcapopen() - it doesn't check if the
* sceen size has changed.
* -lbt
*/
#define USE_BROKEN_OPTIMIZATION 0
#define termdef 1 /* Don't define "term" external. */
#include <curses.h>
#include <term.h>
#include "defines.h"
#include "display.h"
#include "termio.h"
#if TERMCAP
boolean eolexist = TRUE ; /* does clear to EOL exist */
boolean revexist = FALSE ; /* does reverse video exist? */
boolean sgarbf = TRUE ; /* TRUE if screen is garbage */
char sres[ 16] ; /* current screen resolution */
/* NORMAL, CGA, EGA, VGA */
# if UNIX
# include <signal.h>
# endif
#define MARGIN 8
#define SCRSIZ 64
#define NPAUSE 10 /* # times thru update to pause. */
#define BEL 0x07
#define ESC 0x1B
static void tcapkopen(void);
static void tcapkclose(void);
static void tcapmove(int, int);
static void tcapeeol(void);
static void tcapeeop(void);
static void tcapbeep(void);
static void tcaprev(int);
static int tcapcres(char *);
static void tcapscrollregion(int top, int bot);
static void putpad(char *str);
static void tcapopen(void);
# if PKCODE
static void tcapclose(void);
# endif
# if COLOR
static void tcapfcol(void);
static void tcapbcol(void);
# endif
# if SCROLLCODE
static void tcapscroll_reg(int from, int to, int linestoscroll);
static void tcapscroll_delins(int from, int to, int linestoscroll);
# endif
#define TCAPSLEN 315
static char tcapbuf[TCAPSLEN];
static char *_UP, _PC, *CM, *CE, *CL, *SO, *SE;
# if PKCODE
static char *TI, *TE;
# if USE_BROKEN_OPTIMIZATION
static int term_init_ok = 0;
# endif
# endif
# if SCROLLCODE
static char *CS, *DL, *AL, *SF, *SR;
# endif
terminal_t term = {
480, /* actual 479 on 2560x1440 landscape terminal window */
2550, /* actual 2541 */
0, /* These four values are set dynamically at open time. */
0,
0,
0,
MARGIN,
SCRSIZ,
NPAUSE,
tcapopen,
# if PKCODE
tcapclose,
# else
ttclose,
# endif
tcapkopen,
tcapkclose,
ttgetc,
ttputc,
ttflush,
tcapmove,
tcapeeol,
tcapeeop,
tcapbeep,
tcaprev,
tcapcres
# if COLOR
, tcapfcol,
tcapbcol
# endif
# if SCROLLCODE
, NULL /* set dynamically at open time */
# endif
} ;
static void tcapopen(void)
{
char *t, *p;
char tcbuf[1024];
char *tv_stype;
int int_col, int_row;
# if PKCODE && USE_BROKEN_OPTIMIZATION
if (!term_init_ok) {
# endif
if ((tv_stype = getenv("TERM")) == NULL) {
fputs( "Environment variable TERM not defined!\n", stderr) ;
exit( EXIT_FAILURE) ;
}
if ((tgetent(tcbuf, tv_stype)) != 1) {
fputs( "Unknown terminal type ", stderr) ;
fputs( tv_stype, stderr) ;
fputs( "!\n", stderr) ;
exit( EXIT_FAILURE) ;
}
/* Get screen size from system, or else from termcap. */
getscreensize( &int_col, &int_row) ;
if( (int_row <= 0)
&& ((int_row = tgetnum("li")) == -1)) {
fputs( "termcap entry incomplete (lines)\n", stderr) ;
exit( EXIT_FAILURE) ;
}
if( (int_col <= 0)
&& ((int_col = tgetnum("co")) == -1)) {
fputs( "Termcap entry incomplete (columns)\n", stderr) ;
exit( EXIT_FAILURE) ;
}
term.t_mrow = int_row < term.t_maxrow ? int_row : term.t_maxrow ;
term.t_nrow = term.t_mrow - 1 ;
term.t_mcol = int_col < term.t_maxcol ? int_col : term.t_maxcol ;
term.t_ncol = term.t_mcol ;
p = tcapbuf;
t = tgetstr("pc", &p);
if (t)
_PC = *t;
else
_PC = 0;
CL = tgetstr("cl", &p);
CM = tgetstr("cm", &p);
CE = tgetstr("ce", &p);
_UP = tgetstr("up", &p);
SE = tgetstr("se", &p);
SO = tgetstr("so", &p);
if (SO != NULL)
revexist = TRUE;
# if PKCODE
if (tgetnum("sg") > 0) { /* can reverse be used? P.K. */
revexist = FALSE;
SE = NULL;
SO = NULL;
}
TI = tgetstr("ti", &p); /* terminal init and exit */
TE = tgetstr("te", &p);
# endif
if (CL == NULL || CM == NULL || _UP == NULL) {
fputs( "Incomplete termcap entry\n", stderr) ;
exit( EXIT_FAILURE) ;
}
if (CE == NULL) /* will we be able to use clear to EOL? */
eolexist = FALSE;
# if SCROLLCODE
CS = tgetstr("cs", &p);
SF = tgetstr("sf", &p);
SR = tgetstr("sr", &p);
DL = tgetstr("dl", &p);
AL = tgetstr("al", &p);
if (CS && SR) {
if (SF == NULL) /* assume '\n' scrolls forward */
SF = "\n";
term.t_scroll = tcapscroll_reg;
} else if (DL && AL) {
term.t_scroll = tcapscroll_delins;
} else {
term.t_scroll = NULL;
}
# endif
if (p >= &tcapbuf[TCAPSLEN]) {
fputs( "Terminal description too big!\n", stderr) ;
exit( EXIT_FAILURE) ;
}
# if PKCODE && USE_BROKEN_OPTIMIZATION
term_init_ok = 1;
}
# endif
ttopen();
}
# if PKCODE
static void tcapclose(void)
{
putpad(tgoto(CM, 0, term.t_nrow));
putpad(TE);
ttflush();
ttclose();
}
# endif
static void tcapkopen( void) {
# if PKCODE
putpad( TI) ;
ttflush() ;
ttrow = ttcol = -1 ;
sgarbf = TRUE ;
# endif
strcpy(sres, "NORMAL") ;
}
static void tcapkclose(void)
{
# if PKCODE
putpad(TE);
ttflush();
# endif
}
static void tcapmove(int row, int col)
{
putpad(tgoto(CM, col, row));
}
static void tcapeeol(void)
{
putpad(CE);
}
static void tcapeeop(void)
{
putpad(CL);
}
/*
* Change reverse video status
*
* @state: FALSE = normal video, TRUE = reverse video.
*/
static void tcaprev(int state)
{
if (state) {
if (SO != NULL)
putpad(SO);
} else if (SE != NULL)
putpad(SE);
}
/* Change screen resolution. */
static int tcapcres(char *res)
{
return TRUE;
}
# if SCROLLCODE
/* move howmanylines lines starting at from to to */
static void tcapscroll_reg(int from, int to, int howmanylines)
{
int i;
if (to == from)
return;
if (to < from) {
tcapscrollregion(to, from + howmanylines - 1);
tcapmove(from + howmanylines - 1, 0);
for (i = from - to; i > 0; i--)
putpad(SF);
} else { /* from < to */
tcapscrollregion(from, to + howmanylines - 1);
tcapmove(from, 0);
for (i = to - from; i > 0; i--)
putpad(SR);
}
tcapscrollregion(0, term.t_nrow);
}
/* move howmanylines lines starting at from to to */
static void tcapscroll_delins(int from, int to, int howmanylines)
{
int i;
if (to == from)
return;
if (to < from) {
tcapmove(to, 0);
for (i = from - to; i > 0; i--)
putpad(DL);
tcapmove(to + howmanylines, 0);
for (i = from - to; i > 0; i--)
putpad(AL);
} else {
tcapmove(from + howmanylines, 0);
for (i = to - from; i > 0; i--)
putpad(DL);
tcapmove(from, 0);
for (i = to - from; i > 0; i--)
putpad(AL);
}
}
/* cs is set up just like cm, so we use tgoto... */
static void tcapscrollregion(int top, int bot)
{
ttputc(_PC);
putpad(tgoto(CS, bot, top));
}
# endif
# if COLOR
/* No colors here, ignore this. */
static void tcapfcol(void)
{
}
/* No colors here, ignore this. */
static void tcapbcol(void)
{
}
# endif
static void tcapbeep(void)
{
ttputc(BEL);
}
static void putpad(char *str)
{
tputs( str, 1, (int (*)( int)) ttputc) ;
}
#endif /* TERMCAP */
/* end of tcap.c */