Added source code
This commit is contained in:
+774
@@ -0,0 +1,774 @@
|
||||
/*
|
||||
* Program: Display routines
|
||||
*
|
||||
*
|
||||
* Michael Seibel
|
||||
* Networks and Distributed Computing
|
||||
* Computing and Communications
|
||||
* University of Washington
|
||||
* Administration Builiding, AG-44
|
||||
* Seattle, Washington, 98195, USA
|
||||
* Internet: mikes@cac.washington.edu
|
||||
*
|
||||
* Please address all bugs and comments to "pine-bugs@cac.washington.edu"
|
||||
*
|
||||
*
|
||||
* Pine and Pico are registered trademarks of the University of Washington.
|
||||
* No commercial use of these trademarks may be made without prior written
|
||||
* permission of the University of Washington.
|
||||
*
|
||||
* Pine, Pico, and Pilot software and its included text are Copyright
|
||||
* 1989-2001 by the University of Washington.
|
||||
*
|
||||
* The full text of our legal notices is contained in the file called
|
||||
* CPYRIGHT, included with this distribution.
|
||||
*
|
||||
*/
|
||||
/* tcap: Unix V5, V7 and BS4.2 Termcap video driver
|
||||
for MicroEMACS
|
||||
*/
|
||||
|
||||
#define termdef 1 /* don't define "term" external */
|
||||
|
||||
#if defined(USE_TERMCAP)
|
||||
#define MARGIN 8
|
||||
#define SCRSIZ 64
|
||||
#define MROW 2
|
||||
|
||||
static int tcapmove PROTO((int, int));
|
||||
static int tcapeeol PROTO((void));
|
||||
static int tcapeeop PROTO((void));
|
||||
static int tcapbeep PROTO((void));
|
||||
static int tcaprev PROTO((int));
|
||||
static int tcapopen PROTO((void));
|
||||
static int tcapterminalinfo PROTO((int));
|
||||
static int tcapclose PROTO((void));
|
||||
static void setup_dflt_esc_seq PROTO((void));
|
||||
static void tcapinsert PROTO((int));
|
||||
static void tcapdelete PROTO((void));
|
||||
|
||||
extern int tput();
|
||||
extern char *tgoto();
|
||||
|
||||
/*
|
||||
* This number used to be 315. No doubt there was a reason for that but we
|
||||
* don't know what it was. It's a bit of a hassle to make it dynamic, and most
|
||||
* modern systems seem to be using terminfo, so we'll just change it to 800.
|
||||
* We weren't stopping on overflow before, so we'll do that, too.
|
||||
*/
|
||||
#define TCAPSLEN 800
|
||||
char tcapbuf[TCAPSLEN];
|
||||
int _tlines, _tcolumns;
|
||||
char *_clearscreen, *_moveto, *_up, *_down, *_right, *_left,
|
||||
*_setinverse, *_clearinverse,
|
||||
*_setunderline, *_clearunderline,
|
||||
*_setbold, *_clearallattr, /* there is no clear only bold! */
|
||||
*_cleartoeoln, *_cleartoeos,
|
||||
*_deleteline, /* delete line */
|
||||
*_insertline, /* insert line */
|
||||
*_scrollregion, /* define a scrolling region, vt100 */
|
||||
*_insertchar, /* insert character, preferable to : */
|
||||
*_startinsert, /* set insert mode and, */
|
||||
*_endinsert, /* end insert mode */
|
||||
*_deletechar, /* delete character */
|
||||
*_startdelete, /* set delete mode and, */
|
||||
*_enddelete, /* end delete mode */
|
||||
*_scrolldown, /* scroll down */
|
||||
*_scrollup, /* scroll up */
|
||||
*_termcap_init, /* string to start termcap */
|
||||
*_termcap_end, /* string to end termcap */
|
||||
*_op, *_oc, *_setaf, *_setab, *_setf, *_setb, *_scp;
|
||||
int _colors, _pairs, _bce;
|
||||
char term_name[40];
|
||||
|
||||
TERM term = {
|
||||
NROW-1,
|
||||
NCOL,
|
||||
MARGIN,
|
||||
SCRSIZ,
|
||||
MROW,
|
||||
tcapopen,
|
||||
tcapterminalinfo,
|
||||
tcapclose,
|
||||
ttgetc,
|
||||
ttputc,
|
||||
ttflush,
|
||||
tcapmove,
|
||||
tcapeeol,
|
||||
tcapeeop,
|
||||
tcapbeep,
|
||||
tcaprev
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Add default keypad sequences to the trie.
|
||||
*/
|
||||
static void
|
||||
setup_dflt_esc_seq()
|
||||
{
|
||||
/*
|
||||
* this is sort of a hack, but it allows us to use
|
||||
* the function keys on pc's running telnet
|
||||
*/
|
||||
|
||||
/*
|
||||
* UW-NDC/UCS vt10[02] application mode.
|
||||
*/
|
||||
kpinsert("\033OP", F1, 1);
|
||||
kpinsert("\033OQ", F2, 1);
|
||||
kpinsert("\033OR", F3, 1);
|
||||
kpinsert("\033OS", F4, 1);
|
||||
kpinsert("\033Op", F5, 1);
|
||||
kpinsert("\033Oq", F6, 1);
|
||||
kpinsert("\033Or", F7, 1);
|
||||
kpinsert("\033Os", F8, 1);
|
||||
kpinsert("\033Ot", F9, 1);
|
||||
kpinsert("\033Ou", F10, 1);
|
||||
kpinsert("\033Ov", F11, 1);
|
||||
kpinsert("\033Ow", F12, 1);
|
||||
|
||||
/*
|
||||
* DC vt100, ANSI and cursor key mode.
|
||||
*/
|
||||
kpinsert("\033OA", KEY_UP, 1);
|
||||
kpinsert("\033OB", KEY_DOWN, 1);
|
||||
kpinsert("\033OC", KEY_RIGHT, 1);
|
||||
kpinsert("\033OD", KEY_LEFT, 1);
|
||||
|
||||
/*
|
||||
* special keypad functions
|
||||
*/
|
||||
kpinsert("\033[4J", KEY_PGUP, 1);
|
||||
kpinsert("\033[3J", KEY_PGDN, 1);
|
||||
kpinsert("\033[2J", KEY_HOME, 1);
|
||||
kpinsert("\033[N", KEY_END, 1);
|
||||
|
||||
/*
|
||||
* vt220?
|
||||
*/
|
||||
kpinsert("\033[5~", KEY_PGUP, 1);
|
||||
kpinsert("\033[6~", KEY_PGDN, 1);
|
||||
kpinsert("\033[1~", KEY_HOME, 1);
|
||||
kpinsert("\033[4~", KEY_END, 1);
|
||||
|
||||
/*
|
||||
* konsole, XTerm (XFree 4.x.x) keyboard setting
|
||||
*/
|
||||
kpinsert("\033[H", KEY_HOME, 1);
|
||||
kpinsert("\033[F", KEY_END, 1);
|
||||
|
||||
/*
|
||||
* gnome-terminal 2.6.0, don't know why it
|
||||
* changed from 2.2.1
|
||||
*/
|
||||
kpinsert("\033OH", KEY_HOME, 1);
|
||||
kpinsert("\033OF", KEY_END, 1);
|
||||
|
||||
/*
|
||||
* "\033[2~" was common for KEY_HOME in a quick survey
|
||||
* of terminals (though typically the Insert key).
|
||||
* Teraterm 2.33 sends the following escape sequences,
|
||||
* which is quite incompatible with everything
|
||||
* else:
|
||||
* Home: "\033[2~" End: "\033[5~" PgUp: "\033[3~"
|
||||
* PgDn: "\033[6~"
|
||||
* The best thing to do would be to fix TeraTerm
|
||||
* keymappings or to tweak terminfo.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ANSI mode.
|
||||
*/
|
||||
kpinsert("\033[=a", F1, 1);
|
||||
kpinsert("\033[=b", F2, 1);
|
||||
kpinsert("\033[=c", F3, 1);
|
||||
kpinsert("\033[=d", F4, 1);
|
||||
kpinsert("\033[=e", F5, 1);
|
||||
kpinsert("\033[=f", F6, 1);
|
||||
kpinsert("\033[=g", F7, 1);
|
||||
kpinsert("\033[=h", F8, 1);
|
||||
kpinsert("\033[=i", F9, 1);
|
||||
kpinsert("\033[=j", F10, 1);
|
||||
kpinsert("\033[=k", F11, 1);
|
||||
kpinsert("\033[=l", F12, 1);
|
||||
|
||||
/*
|
||||
* DEC vt100, ANSI, cursor key mode reset.
|
||||
*/
|
||||
kpinsert("\033[A", KEY_UP, 1);
|
||||
kpinsert("\033[B", KEY_DOWN, 1);
|
||||
kpinsert("\033[C", KEY_RIGHT, 1);
|
||||
kpinsert("\033[D", KEY_LEFT, 1);
|
||||
|
||||
/*
|
||||
* DEC vt52 mode.
|
||||
*/
|
||||
kpinsert("\033A", KEY_UP, 1);
|
||||
kpinsert("\033B", KEY_DOWN, 1);
|
||||
kpinsert("\033C", KEY_RIGHT, 1);
|
||||
kpinsert("\033D", KEY_LEFT, 1);
|
||||
|
||||
/*
|
||||
* DEC vt52 application keys, and some Zenith 19.
|
||||
*/
|
||||
kpinsert("\033?r", KEY_DOWN, 1);
|
||||
kpinsert("\033?t", KEY_LEFT, 1);
|
||||
kpinsert("\033?v", KEY_RIGHT, 1);
|
||||
kpinsert("\033?x", KEY_UP, 1);
|
||||
|
||||
/*
|
||||
* Sun Console sequences.
|
||||
*/
|
||||
kpinsert("\033[1", KEY_SWALLOW_Z, 1);
|
||||
kpinsert("\033[215", KEY_SWAL_UP, 1);
|
||||
kpinsert("\033[217", KEY_SWAL_LEFT, 1);
|
||||
kpinsert("\033[219", KEY_SWAL_RIGHT, 1);
|
||||
kpinsert("\033[221", KEY_SWAL_DOWN, 1);
|
||||
|
||||
/*
|
||||
* Kermit App Prog Cmd, gobble until ESC \ (kermit should intercept this)
|
||||
*/
|
||||
kpinsert("\033_", KEY_KERMIT, 1);
|
||||
|
||||
/*
|
||||
* Fake a control character.
|
||||
*/
|
||||
kpinsert("\033\033", KEY_DOUBLE_ESC, 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read termcap and set some global variables. Initialize input trie to
|
||||
* decode escape sequences.
|
||||
*/
|
||||
static int
|
||||
tcapterminalinfo(termcap_wins)
|
||||
int termcap_wins;
|
||||
{
|
||||
char *p, *tgetstr();
|
||||
char tcbuf[2*1024];
|
||||
char *tv_stype;
|
||||
char err_str[72];
|
||||
int err;
|
||||
char *_ku, *_kd, *_kl, *_kr,
|
||||
*_kppu, *_kppd, *_kphome, *_kpend, *_kpdel,
|
||||
*_kf1, *_kf2, *_kf3, *_kf4, *_kf5, *_kf6,
|
||||
*_kf7, *_kf8, *_kf9, *_kf10, *_kf11, *_kf12;
|
||||
|
||||
if (!(tv_stype = getenv("TERM")) || !strcpy(term_name, tv_stype)){
|
||||
if(Pmaster){
|
||||
return(-1);
|
||||
}
|
||||
else{
|
||||
puts("Environment variable TERM not defined!");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if((err = tgetent(tcbuf, tv_stype)) != 1){
|
||||
if(Pmaster){
|
||||
return(err - 2);
|
||||
}
|
||||
else{
|
||||
sprintf(err_str, "Unknown terminal type %s!", tv_stype);
|
||||
puts(err_str);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
p = tcapbuf;
|
||||
|
||||
_clearscreen = tgetstr("cl", &p);
|
||||
_moveto = tgetstr("cm", &p);
|
||||
_up = tgetstr("up", &p);
|
||||
_down = tgetstr("do", &p);
|
||||
_right = tgetstr("nd", &p);
|
||||
_left = tgetstr("bs", &p);
|
||||
_setinverse = tgetstr("so", &p);
|
||||
_clearinverse = tgetstr("se", &p);
|
||||
_setunderline = tgetstr("us", &p);
|
||||
_clearunderline = tgetstr("ue", &p);
|
||||
_setbold = tgetstr("md", &p);
|
||||
_clearallattr = tgetstr("me", &p);
|
||||
_cleartoeoln = tgetstr("ce", &p);
|
||||
_cleartoeos = tgetstr("cd", &p);
|
||||
_deletechar = tgetstr("dc", &p);
|
||||
_insertchar = tgetstr("ic", &p);
|
||||
_startinsert = tgetstr("im", &p);
|
||||
_endinsert = tgetstr("ei", &p);
|
||||
_deleteline = tgetstr("dl", &p);
|
||||
_insertline = tgetstr("al", &p);
|
||||
_scrollregion = tgetstr("cs", &p);
|
||||
_scrolldown = tgetstr("sf", &p);
|
||||
_scrollup = tgetstr("sr", &p);
|
||||
_termcap_init = tgetstr("ti", &p);
|
||||
_termcap_end = tgetstr("te", &p);
|
||||
_startdelete = tgetstr("dm", &p);
|
||||
_enddelete = tgetstr("ed", &p);
|
||||
_ku = tgetstr("ku", &p);
|
||||
_kd = tgetstr("kd", &p);
|
||||
_kl = tgetstr("kl", &p);
|
||||
_kr = tgetstr("kr", &p);
|
||||
_kppu = tgetstr("kP", &p);
|
||||
_kppd = tgetstr("kN", &p);
|
||||
_kphome = tgetstr("kh", &p);
|
||||
_kpend = tgetstr("kH", &p);
|
||||
_kpdel = tgetstr("kD", &p);
|
||||
_kf1 = tgetstr("k1", &p);
|
||||
_kf2 = tgetstr("k2", &p);
|
||||
_kf3 = tgetstr("k3", &p);
|
||||
_kf4 = tgetstr("k4", &p);
|
||||
_kf5 = tgetstr("k5", &p);
|
||||
_kf6 = tgetstr("k6", &p);
|
||||
_kf7 = tgetstr("k7", &p);
|
||||
_kf8 = tgetstr("k8", &p);
|
||||
_kf9 = tgetstr("k9", &p);
|
||||
if((_kf10 = tgetstr("k;", &p)) == NULL)
|
||||
_kf10 = tgetstr("k0", &p);
|
||||
_kf11 = tgetstr("F1", &p);
|
||||
_kf12 = tgetstr("F2", &p);
|
||||
|
||||
_colors = tgetnum("Co");
|
||||
_pairs = tgetnum("pa");
|
||||
_setaf = tgetstr("AF", &p);
|
||||
_setab = tgetstr("AB", &p);
|
||||
_setf = tgetstr("Sf", &p);
|
||||
_setb = tgetstr("Sb", &p);
|
||||
_scp = tgetstr("sp", &p);
|
||||
_op = tgetstr("op", &p);
|
||||
_oc = tgetstr("oc", &p);
|
||||
_bce = tgetflag("ut");
|
||||
|
||||
if (p >= &tcapbuf[TCAPSLEN]){
|
||||
puts("Terminal description too big!\n");
|
||||
if(Pmaster)
|
||||
return(-3);
|
||||
else
|
||||
exit(1);
|
||||
}
|
||||
|
||||
_tlines = tgetnum("li");
|
||||
if(_tlines == -1){
|
||||
char *er;
|
||||
int rr;
|
||||
|
||||
/* tgetnum failed, try $LINES */
|
||||
er = getenv("LINES");
|
||||
if(er && (rr = atoi(er)) > 0)
|
||||
_tlines = rr;
|
||||
}
|
||||
|
||||
_tcolumns = tgetnum("co");
|
||||
if(_tcolumns == -1){
|
||||
char *ec;
|
||||
int cc;
|
||||
|
||||
/* tgetnum failed, try $COLUMNS */
|
||||
ec = getenv("COLUMNS");
|
||||
if(ec && (cc = atoi(ec)) > 0)
|
||||
_tcolumns = cc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add default keypad sequences to the trie.
|
||||
* Since these come first, they will override any conflicting termcap
|
||||
* or terminfo escape sequences defined below. An escape sequence is
|
||||
* considered conflicting if one is a prefix of the other.
|
||||
* So, without TERMCAP_WINS, there will likely be some termcap/terminfo
|
||||
* escape sequences that don't work, because they conflict with default
|
||||
* sequences defined here.
|
||||
*/
|
||||
if(!termcap_wins)
|
||||
setup_dflt_esc_seq();
|
||||
|
||||
/*
|
||||
* add termcap/info escape sequences to the trie...
|
||||
*/
|
||||
|
||||
if(_ku != NULL && _kd != NULL && _kl != NULL && _kr != NULL){
|
||||
kpinsert(_ku, KEY_UP, termcap_wins);
|
||||
kpinsert(_kd, KEY_DOWN, termcap_wins);
|
||||
kpinsert(_kl, KEY_LEFT, termcap_wins);
|
||||
kpinsert(_kr, KEY_RIGHT, termcap_wins);
|
||||
}
|
||||
|
||||
if(_kppu != NULL && _kppd != NULL){
|
||||
kpinsert(_kppu, KEY_PGUP, termcap_wins);
|
||||
kpinsert(_kppd, KEY_PGDN, termcap_wins);
|
||||
}
|
||||
|
||||
kpinsert(_kphome, KEY_HOME, termcap_wins);
|
||||
kpinsert(_kpend, KEY_END, termcap_wins);
|
||||
kpinsert(_kpdel, KEY_DEL, termcap_wins);
|
||||
|
||||
kpinsert(_kf1, F1, termcap_wins);
|
||||
kpinsert(_kf2, F2, termcap_wins);
|
||||
kpinsert(_kf3, F3, termcap_wins);
|
||||
kpinsert(_kf4, F4, termcap_wins);
|
||||
kpinsert(_kf5, F5, termcap_wins);
|
||||
kpinsert(_kf6, F6, termcap_wins);
|
||||
kpinsert(_kf7, F7, termcap_wins);
|
||||
kpinsert(_kf8, F8, termcap_wins);
|
||||
kpinsert(_kf9, F9, termcap_wins);
|
||||
kpinsert(_kf10, F10, termcap_wins);
|
||||
kpinsert(_kf11, F11, termcap_wins);
|
||||
kpinsert(_kf12, F12, termcap_wins);
|
||||
|
||||
/*
|
||||
* Add default keypad sequences to the trie.
|
||||
* Since these come after the termcap/terminfo escape sequences above,
|
||||
* the termcap/info sequences will override any conflicting default
|
||||
* escape sequences defined here.
|
||||
* So, with TERMCAP_WINS, some of the default sequences will be missing.
|
||||
* This means that you'd better get all of your termcap/terminfo entries
|
||||
* correct if you define TERMCAP_WINS.
|
||||
*/
|
||||
if(termcap_wins)
|
||||
setup_dflt_esc_seq();
|
||||
|
||||
if(Pmaster)
|
||||
return(0);
|
||||
else
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
static int
|
||||
tcapopen()
|
||||
{
|
||||
int row, col;
|
||||
|
||||
/*
|
||||
* determine the terminal's communication speed and decide
|
||||
* if we need to do optimization ...
|
||||
*/
|
||||
optimize = ttisslow();
|
||||
|
||||
col = _tcolumns;
|
||||
row = _tlines;
|
||||
if(row >= 0)
|
||||
row--;
|
||||
|
||||
ttgetwinsz(&row, &col);
|
||||
term.t_nrow = (short) row;
|
||||
term.t_ncol = (short) col;
|
||||
|
||||
eolexist = (_cleartoeoln != NULL); /* able to use clear to EOL? */
|
||||
revexist = (_setinverse != NULL);
|
||||
if(_deletechar == NULL && (_startdelete == NULL || _enddelete == NULL))
|
||||
delchar = FALSE;
|
||||
if(_insertchar == NULL && (_startinsert == NULL || _endinsert == NULL))
|
||||
inschar = FALSE;
|
||||
if((_scrollregion == NULL || _scrolldown == NULL || _scrollup == NULL)
|
||||
&& (_deleteline == NULL || _insertline == NULL))
|
||||
scrollexist = FALSE;
|
||||
|
||||
if(_clearscreen == NULL || _moveto == NULL || _up == NULL){
|
||||
if(Pmaster == NULL){
|
||||
puts("Incomplete termcap entry\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
ttopen();
|
||||
|
||||
if(_termcap_init && !Pmaster) {
|
||||
putpad(_termcap_init); /* any init termcap requires */
|
||||
if (_scrollregion)
|
||||
putpad(tgoto(_scrollregion, term.t_nrow, 0)) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize UW-modified NCSA telnet to use it's functionkeys
|
||||
*/
|
||||
if(gmode&MDFKEY && Pmaster == NULL)
|
||||
puts("\033[99h");
|
||||
|
||||
/* return ignored */
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
tcapclose()
|
||||
{
|
||||
if(!Pmaster){
|
||||
if(gmode&MDFKEY)
|
||||
puts("\033[99l"); /* reset UW-NCSA telnet keys */
|
||||
|
||||
if(_termcap_end) /* any cleanup termcap requires */
|
||||
putpad(_termcap_end);
|
||||
}
|
||||
|
||||
ttclose();
|
||||
|
||||
/* return ignored */
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* tcapinsert - insert a character at the current character position.
|
||||
* _insertchar takes precedence.
|
||||
*/
|
||||
static void
|
||||
tcapinsert(ch)
|
||||
register int ch;
|
||||
{
|
||||
if(_insertchar != NULL){
|
||||
putpad(_insertchar);
|
||||
ttputc(ch);
|
||||
}
|
||||
else{
|
||||
putpad(_startinsert);
|
||||
ttputc(ch);
|
||||
putpad(_endinsert);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* tcapdelete - delete a character at the current character position.
|
||||
*/
|
||||
static void
|
||||
tcapdelete()
|
||||
{
|
||||
if(_startdelete == NULL && _enddelete == NULL)
|
||||
putpad(_deletechar);
|
||||
else{
|
||||
putpad(_startdelete);
|
||||
putpad(_deletechar);
|
||||
putpad(_enddelete);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* o_scrolldown - open a line at the given row position.
|
||||
* use either region scrolling or deleteline/insertline
|
||||
* to open a new line.
|
||||
*/
|
||||
o_scrolldown(row, n)
|
||||
register int row;
|
||||
register int n;
|
||||
{
|
||||
register int i;
|
||||
|
||||
if(_scrollregion != NULL){
|
||||
putpad(tgoto(_scrollregion, term.t_nrow - (term.t_mrow+1), row));
|
||||
tcapmove(row, 0);
|
||||
for(i = 0; i < n; i++)
|
||||
putpad( (_scrollup != NULL && *_scrollup != '\0')
|
||||
? _scrollup : "\n" );
|
||||
putpad(tgoto(_scrollregion, term.t_nrow, 0));
|
||||
tcapmove(row, 0);
|
||||
}
|
||||
else{
|
||||
/*
|
||||
* this code causes a jiggly motion of the keymenu when scrolling
|
||||
*/
|
||||
for(i = 0; i < n; i++){
|
||||
tcapmove(term.t_nrow - (term.t_mrow+1), 0);
|
||||
putpad(_deleteline);
|
||||
tcapmove(row, 0);
|
||||
putpad(_insertline);
|
||||
}
|
||||
#ifdef NOWIGGLYLINES
|
||||
/*
|
||||
* this code causes a sweeping motion up and down the display
|
||||
*/
|
||||
tcapmove(term.t_nrow - term.t_mrow - n, 0);
|
||||
for(i = 0; i < n; i++)
|
||||
putpad(_deleteline);
|
||||
tcapmove(row, 0);
|
||||
for(i = 0; i < n; i++)
|
||||
putpad(_insertline);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* return ignored */
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* o_scrollup - open a line at the given row position.
|
||||
* use either region scrolling or deleteline/insertline
|
||||
* to open a new line.
|
||||
*/
|
||||
o_scrollup(row, n)
|
||||
register int row;
|
||||
register int n;
|
||||
{
|
||||
register int i;
|
||||
|
||||
if(_scrollregion != NULL){
|
||||
putpad(tgoto(_scrollregion, term.t_nrow - (term.t_mrow+1), row));
|
||||
/* setting scrolling region moves cursor to home */
|
||||
tcapmove(term.t_nrow-(term.t_mrow+1), 0);
|
||||
for(i = 0;i < n; i++)
|
||||
putpad((_scrolldown == NULL || _scrolldown[0] == '\0')
|
||||
? "\n" : _scrolldown);
|
||||
putpad(tgoto(_scrollregion, term.t_nrow, 0));
|
||||
tcapmove(2, 0);
|
||||
}
|
||||
else{
|
||||
for(i = 0; i < n; i++){
|
||||
tcapmove(row, 0);
|
||||
putpad(_deleteline);
|
||||
tcapmove(term.t_nrow - (term.t_mrow+1), 0);
|
||||
putpad(_insertline);
|
||||
}
|
||||
#ifdef NOWIGGLYLINES
|
||||
/* see note above */
|
||||
tcapmove(row, 0);
|
||||
for(i = 0; i < n; i++)
|
||||
putpad(_deleteline);
|
||||
tcapmove(term.t_nrow - term.t_mrow - n, 0);
|
||||
for(i = 0;i < n; i++)
|
||||
putpad(_insertline);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* return ignored */
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* o_insert - use termcap info to optimized character insert
|
||||
* returns: true if it optimized output, false otherwise
|
||||
*/
|
||||
o_insert(c)
|
||||
int c;
|
||||
{
|
||||
if(inschar){
|
||||
tcapinsert(c);
|
||||
return(1); /* no problems! */
|
||||
}
|
||||
|
||||
return(0); /* can't do it. */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* o_delete - use termcap info to optimized character insert
|
||||
* returns true if it optimized output, false otherwise
|
||||
*/
|
||||
o_delete()
|
||||
{
|
||||
if(delchar){
|
||||
tcapdelete();
|
||||
return(1); /* deleted, no problem! */
|
||||
}
|
||||
|
||||
return(0); /* no dice. */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
tcapmove(row, col)
|
||||
register int row, col;
|
||||
{
|
||||
putpad(tgoto(_moveto, col, row));
|
||||
|
||||
/* return ignored */
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
tcapeeol()
|
||||
{
|
||||
int c, starting_col, starting_line;
|
||||
char *last_bg_color;
|
||||
|
||||
/*
|
||||
* If the terminal doesn't have back color erase, then we have to
|
||||
* erase manually to preserve the background color.
|
||||
*/
|
||||
if(pico_usingcolor() && (!_bce || !_cleartoeoln)){
|
||||
extern int ttcol, ttrow;
|
||||
|
||||
starting_col = ttcol;
|
||||
starting_line = ttrow;
|
||||
last_bg_color = pico_get_last_bg_color();
|
||||
pico_set_nbg_color();
|
||||
for(c = ttcol; c < term.t_ncol; c++)
|
||||
ttputc(' ');
|
||||
|
||||
tcapmove(starting_line, starting_col);
|
||||
if(last_bg_color){
|
||||
pico_set_bg_color(last_bg_color);
|
||||
free(last_bg_color);
|
||||
}
|
||||
}
|
||||
else if(_cleartoeoln)
|
||||
putpad(_cleartoeoln);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
tcapeeop()
|
||||
{
|
||||
int i, starting_col, starting_row;
|
||||
|
||||
/*
|
||||
* If the terminal doesn't have back color erase, then we have to
|
||||
* erase manually to preserve the background color.
|
||||
*/
|
||||
if(pico_usingcolor() && (!_bce || !_cleartoeos)){
|
||||
extern int ttcol, ttrow;
|
||||
|
||||
starting_col = ttcol;
|
||||
starting_row = ttrow;
|
||||
tcapeeol(); /* rest of this line */
|
||||
for(i = ttrow+1; i <= term.t_nrow; i++){ /* the remaining lines */
|
||||
tcapmove(i, 0);
|
||||
tcapeeol();
|
||||
}
|
||||
|
||||
tcapmove(starting_row, starting_col);
|
||||
}
|
||||
else if(_cleartoeos)
|
||||
putpad(_cleartoeos);
|
||||
|
||||
/* return ignored */
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
tcaprev(state) /* change reverse video status */
|
||||
int state; /* FALSE = normal video, TRUE = reverse video */
|
||||
{
|
||||
if(state)
|
||||
StartInverse();
|
||||
else
|
||||
EndInverse();
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
tcapbeep()
|
||||
{
|
||||
ttputc(BELL);
|
||||
|
||||
/* return ignored */
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
putpad(str)
|
||||
char *str;
|
||||
{
|
||||
tputs(str, 1, ttputc);
|
||||
}
|
||||
|
||||
#endif /* USE_TERMCAP */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user