173 lines
4.2 KiB
C
173 lines
4.2 KiB
C
#include <curses.h>
|
|
#include "curspriv.h"
|
|
#include <termcap.h>
|
|
|
|
static WINDOW *twin; /* used by many routines */
|
|
|
|
/****************************************************************/
|
|
/* Gotoxy() moves the physical cursor to the desired address on */
|
|
/* The screen. We don't optimize here - on a PC, it takes more */
|
|
/* Time to optimize than to do things directly. */
|
|
/****************************************************************/
|
|
|
|
_PROTOTYPE(static void gotoxy, (int row, int col ));
|
|
_PROTOTYPE(static void newattr, (int ch ));
|
|
_PROTOTYPE(static void Putchar, (int ch ));
|
|
_PROTOTYPE(static void clrupdate, (WINDOW *scr ));
|
|
_PROTOTYPE(static void transformline, (int lineno ));
|
|
|
|
static void gotoxy(row, col)
|
|
int row, col;
|
|
{
|
|
poscur(row, col);
|
|
_cursvar.cursrow = row;
|
|
_cursvar.curscol = col;
|
|
}
|
|
|
|
/* Update attributes */
|
|
static void newattr(ch)
|
|
int ch;
|
|
{
|
|
extern char *me, *as, *ae, *mb, *md, *mr, *so, *us;
|
|
static int lastattr = 0;
|
|
|
|
if (lastattr != (ch &= ATR_MSK)) {
|
|
lastattr = ch;
|
|
|
|
tputs(me, 1, outc);
|
|
if (ae) tputs(ae, 1, outc);
|
|
|
|
if (ch & A_ALTCHARSET)
|
|
if (as) tputs(as, 1, outc);
|
|
if (ch & A_BLINK) tputs(mb, 1, outc);
|
|
if (ch & A_BOLD) tputs(md, 1, outc);
|
|
if (ch & A_REVERSE) tputs(mr, 1, outc);
|
|
if (ch & A_STANDOUT) tputs(so, 1, outc);
|
|
if (ch & A_UNDERLINE) tputs(us, 1, outc);
|
|
}
|
|
}
|
|
|
|
/* Putchar() writes a character, with attributes, to the physical
|
|
screen, but avoids writing to the lower right screen position.
|
|
Should it care about am?
|
|
*/
|
|
|
|
/* Output char with attribute */
|
|
static void Putchar(ch)
|
|
int ch;
|
|
{
|
|
if ((_cursvar.cursrow < LINES) || (_cursvar.curscol < COLS)) {
|
|
newattr(ch);
|
|
putchar(ch);
|
|
}
|
|
}
|
|
|
|
/****************************************************************/
|
|
/* Clrupdate(scr) updates the screen by clearing it and then */
|
|
/* Redraw it in it's entirety. */
|
|
/****************************************************************/
|
|
|
|
static void clrupdate(scr)
|
|
WINDOW *scr;
|
|
{
|
|
register int *src;
|
|
register int *dst;
|
|
register int i;
|
|
register int j;
|
|
WINDOW *w;
|
|
|
|
w = curscr;
|
|
|
|
if (scr != w) { /* copy scr to curscr */
|
|
for (i = 0; i < LINES; i++) {
|
|
src = scr->_line[i];
|
|
dst = w->_line[i];
|
|
for (j = 0; j < COLS; j++) *dst++ = *src++;
|
|
} /* for */
|
|
} /* if */
|
|
newattr(scr->_attrs);
|
|
clrscr();
|
|
scr->_clear = FALSE;
|
|
for (i = 0; i < LINES; i++) { /* update physical screen */
|
|
src = w->_line[i];
|
|
j = 0;
|
|
while (j < COLS) {
|
|
if (*src != (' ' | ATR_NRM)) {
|
|
gotoxy(i, j);
|
|
while (j < COLS && (*src != (' ' | ATR_NRM))) {
|
|
Putchar(*src++);
|
|
j++;
|
|
}
|
|
} else {
|
|
src++;
|
|
j++;
|
|
}
|
|
} /* for */
|
|
} /* for */
|
|
fflush(stdout);
|
|
} /* clrupdate */
|
|
|
|
/****************************************************************/
|
|
/* Transformline() updates the given physical line to look */
|
|
/* Like the corresponding line in _cursvar.tmpwin. */
|
|
/****************************************************************/
|
|
|
|
static void transformline(lineno)
|
|
register int lineno;
|
|
{
|
|
register int *dstp;
|
|
register int *srcp;
|
|
register int dstc;
|
|
register int srcc;
|
|
int x;
|
|
int endx;
|
|
|
|
x = twin->_minchng[lineno];
|
|
endx = twin->_maxchng[lineno];
|
|
dstp = curscr->_line[lineno] + x;
|
|
srcp = twin->_line[lineno] + x;
|
|
|
|
while (x <= endx) {
|
|
if ((*dstp != *srcp) || (dstc != srcc)) {
|
|
gotoxy(lineno, x);
|
|
while (x <= endx && ((*dstp != *srcp) || (dstc != srcc))) {
|
|
Putchar(*srcp);
|
|
*dstp++ = *srcp++;
|
|
x++;
|
|
}
|
|
} else {
|
|
*dstp++ = *srcp++;
|
|
x++;
|
|
}
|
|
} /* for */
|
|
twin->_minchng[lineno] = _NO_CHANGE;
|
|
twin->_maxchng[lineno] = _NO_CHANGE;
|
|
} /* transformline */
|
|
|
|
/****************************************************************/
|
|
/* Doupdate() updates the physical screen to look like _curs- */
|
|
/* Var.tmpwin if curscr is not 'Clear-marked'. Otherwise it */
|
|
/* Updates the screen to look like curscr. */
|
|
/****************************************************************/
|
|
|
|
void doupdate()
|
|
{
|
|
int i;
|
|
|
|
twin = _cursvar.tmpwin;
|
|
if (curscr->_clear)
|
|
clrupdate(curscr);
|
|
else {
|
|
if (twin->_clear)
|
|
clrupdate(twin);
|
|
else {
|
|
for (i = 0; i < LINES; i++)
|
|
if (twin->_minchng[i] != _NO_CHANGE)
|
|
transformline(i);
|
|
}
|
|
}
|
|
curscr->_curx = twin->_curx;
|
|
curscr->_cury = twin->_cury;
|
|
gotoxy(curscr->_cury, curscr->_curx);
|
|
fflush(stdout);
|
|
} /* doupdate */
|