/* tcap.c -- implements terminal.h */ #include "terminal.h" /* tcap.c * * 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. */ #ifndef MINGW32 #include <curses.h> #include <term.h> #endif #include "display.h" #include "estruct.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 struct terminal term = { 270, /* actual 269 on 1920x1080 landscape terminal window */ 1910, /* actual 1901 */ 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 = 999; ttcol = 999; 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 */