version 1.2, 2000/02/26 22:53:16 |
version 1.3, 2000/04/13 06:12:14 |
|
|
*/ |
*/ |
/* These defines really belong in sysdef.h */ |
/* These defines really belong in sysdef.h */ |
#ifndef XCHAR |
#ifndef XCHAR |
# define XCHAR int |
#define XCHAR int |
# define XSHORT int |
#define XSHORT int |
#endif |
#endif |
|
|
#ifdef STANDOUT_GLITCH |
#ifdef STANDOUT_GLITCH |
|
|
* the longest line possible. Only some of this is |
* the longest line possible. Only some of this is |
* used if "ncol" isn't the same as "NCOL". |
* used if "ncol" isn't the same as "NCOL". |
*/ |
*/ |
typedef struct { |
typedef struct { |
short v_hash; /* Hash code, for compares. */ |
short v_hash; /* Hash code, for compares. */ |
short v_flag; /* Flag word. */ |
short v_flag; /* Flag word. */ |
short v_color; /* Color of the line. */ |
short v_color; /* Color of the line. */ |
XSHORT v_cost; /* Cost of display. */ |
XSHORT v_cost; /* Cost of display. */ |
char v_text[NCOL]; /* The actual characters. */ |
char v_text[NCOL]; /* The actual characters. */ |
} VIDEO; |
} VIDEO; |
|
|
#define VFCHG 0x0001 /* Changed. */ |
#define VFCHG 0x0001 /* Changed. */ |
#define VFHBAD 0x0002 /* Hash and cost are bad. */ |
#define VFHBAD 0x0002 /* Hash and cost are bad. */ |
#define VFEXT 0x0004 /* extended line (beond ncol) */ |
#define VFEXT 0x0004 /* extended line (beond ncol) */ |
|
|
/* |
/* |
* SCORE structures hold the optimal |
* SCORE structures hold the optimal |
|
|
* fields can be "char", and the score a "short", but |
* fields can be "char", and the score a "short", but |
* this makes the code worse on the VAX. |
* this makes the code worse on the VAX. |
*/ |
*/ |
typedef struct { |
typedef struct { |
XCHAR s_itrace; /* "i" index for track back. */ |
XCHAR s_itrace; /* "i" index for track back. */ |
XCHAR s_jtrace; /* "j" index for trace back. */ |
XCHAR s_jtrace; /* "j" index for trace back. */ |
XSHORT s_cost; /* Display cost. */ |
XSHORT s_cost; /* Display cost. */ |
} SCORE; |
} SCORE; |
|
|
int sgarbf = TRUE; /* TRUE if screen is garbage. */ |
|
int vtrow = 0; /* Virtual cursor row. */ |
|
int vtcol = 0; /* Virtual cursor column. */ |
|
int tthue = CNONE; /* Current color. */ |
|
int ttrow = HUGE; /* Physical cursor row. */ |
|
int ttcol = HUGE; /* Physical cursor column. */ |
|
int tttop = HUGE; /* Top of scroll region. */ |
|
int ttbot = HUGE; /* Bottom of scroll region. */ |
|
int lbound = 0; /* leftmost bound of the current line */ |
|
/* being displayed */ |
|
|
|
VIDEO *vscreen[NROW-1]; /* Edge vector, virtual. */ |
VOID vtmove __P((int, int)); |
VIDEO *pscreen[NROW-1]; /* Edge vector, physical. */ |
VOID vtputc __P((int)); |
VIDEO video[2*(NROW-1)]; /* Actual screen data. */ |
VOID vtpute __P((int)); |
VIDEO blanks; /* Blank line image. */ |
int vtputs __P((char *)); |
|
VOID vteeol __P((void)); |
|
VOID updext __P((int, int)); |
|
VOID modeline __P((MGWIN *)); |
|
VOID setscores __P((int, int)); |
|
VOID traceback __P((int, int, int, int)); |
|
VOID ucopy __P((VIDEO *, VIDEO *)); |
|
VOID uline __P((int, VIDEO *, VIDEO *)); |
|
VOID hash __P((VIDEO *)); |
|
|
/* |
|
* Some predeclerations to make ANSI compilers happy |
|
*/ |
|
VOID vtinit(); |
|
VOID vttidy(); |
|
VOID vtmove(); |
|
VOID vtputc(); |
|
VOID vtpute(); |
|
VOID vteeol(); |
|
VOID update(); |
|
VOID updext(); |
|
VOID ucopy(); |
|
VOID uline(); |
|
VOID modeline(); |
|
VOID hash(); |
|
VOID setscores(); |
|
VOID traceback(); |
|
|
|
|
int sgarbf = TRUE; /* TRUE if screen is garbage. */ |
|
int vtrow = 0; /* Virtual cursor row. */ |
|
int vtcol = 0; /* Virtual cursor column. */ |
|
int tthue = CNONE; /* Current color. */ |
|
int ttrow = HUGE; /* Physical cursor row. */ |
|
int ttcol = HUGE; /* Physical cursor column. */ |
|
int tttop = HUGE; /* Top of scroll region. */ |
|
int ttbot = HUGE; /* Bottom of scroll region. */ |
|
int lbound = 0; /* leftmost bound of the current line */ |
|
/* being displayed */ |
|
|
|
VIDEO *vscreen[NROW - 1]; /* Edge vector, virtual. */ |
|
VIDEO *pscreen[NROW - 1]; /* Edge vector, physical. */ |
|
VIDEO video[2 * (NROW - 1)]; /* Actual screen data. */ |
|
VIDEO blanks; /* Blank line image. */ |
|
|
#ifdef GOSLING |
#ifdef GOSLING |
/* |
/* |
* This matrix is written as an array because |
* This matrix is written as an array because |
|
|
* It would be "SCORE score[NROW][NROW]" in old speak. |
* It would be "SCORE score[NROW][NROW]" in old speak. |
* Look at "setscores" to understand what is up. |
* Look at "setscores" to understand what is up. |
*/ |
*/ |
SCORE score[NROW*NROW]; |
SCORE score[NROW * NROW]; |
#endif |
#endif |
|
|
/* |
/* |
|
|
* on the first call to redisplay. |
* on the first call to redisplay. |
*/ |
*/ |
VOID |
VOID |
vtinit() { |
vtinit() |
register VIDEO *vp; |
{ |
register int i; |
VIDEO *vp; |
|
int i; |
|
|
ttopen(); |
ttopen(); |
ttinit(); |
ttinit(); |
vp = &video[0]; |
vp = &video[0]; |
for (i=0; i<NROW-1; ++i) { |
for (i = 0; i < NROW - 1; ++i) { |
vscreen[i] = vp; |
vscreen[i] = vp; |
++vp; |
++vp; |
pscreen[i] = vp; |
pscreen[i] = vp; |
++vp; |
++vp; |
} |
} |
blanks.v_color = CTEXT; |
blanks.v_color = CTEXT; |
for (i=0; i<NCOL; ++i) |
for (i = 0; i < NCOL; ++i) |
blanks.v_text[i] = ' '; |
blanks.v_text[i] = ' '; |
} |
} |
|
|
|
|
* close the terminal channel. |
* close the terminal channel. |
*/ |
*/ |
VOID |
VOID |
vttidy() { |
vttidy() |
|
{ |
|
|
ttcolor(CTEXT); |
ttcolor(CTEXT); |
ttnowindow(); /* No scroll window. */ |
ttnowindow(); /* No scroll window. */ |
ttmove(nrow-1, 0); /* Echo line. */ |
ttmove(nrow - 1, 0); /* Echo line. */ |
tteeol(); |
tteeol(); |
tttidy(); |
tttidy(); |
ttflush(); |
ttflush(); |
|
|
* more efficient. No checking for errors. |
* more efficient. No checking for errors. |
*/ |
*/ |
VOID |
VOID |
vtmove(row, col) { |
vtmove(row, col) |
|
int row, col; |
|
{ |
|
|
vtrow = row; |
vtrow = row; |
vtcol = col; |
vtcol = col; |
} |
} |
|
|
* Three guesses how we found this. |
* Three guesses how we found this. |
*/ |
*/ |
VOID |
VOID |
vtputc(c) register int c; { |
vtputc(c) |
register VIDEO *vp; |
int c; |
|
{ |
|
VIDEO *vp; |
|
|
vp = vscreen[vtrow]; |
vp = vscreen[vtrow]; |
if (vtcol >= ncol) |
if (vtcol >= ncol) |
vp->v_text[ncol-1] = '$'; |
vp->v_text[ncol - 1] = '$'; |
else if (c == '\t' |
else if (c == '\t' |
#ifdef NOTAB |
#ifdef NOTAB |
&& !(curbp->b_flag & BFNOTAB) |
&& !(curbp->b_flag & BFNOTAB) |
#endif |
#endif |
) { |
) { |
do { |
do { |
vtputc(' '); |
vtputc(' '); |
} while (vtcol<ncol && (vtcol&0x07)!=0); |
} while (vtcol < ncol && (vtcol & 0x07) != 0); |
} else if (ISCTRL(c)) { |
} else if (ISCTRL(c)) { |
vtputc('^'); |
vtputc('^'); |
vtputc(CCHR(c)); |
vtputc(CCHR(c)); |
|
|
vp->v_text[vtcol++] = c; |
vp->v_text[vtcol++] = c; |
} |
} |
|
|
/* Put a character to the virtual screen in an extended line. If we are |
/* |
* not yet on left edge, don't print it yet. Check for overflow on |
* Put a character to the virtual screen in an extended line. If we are not |
* the right margin. |
* yet on left edge, don't print it yet. Check for overflow on the right |
|
* margin. |
*/ |
*/ |
VOID |
VOID |
vtpute(c) |
vtpute(c) |
int c; |
int c; |
{ |
{ |
register VIDEO *vp; |
VIDEO *vp; |
|
|
vp = vscreen[vtrow]; |
vp = vscreen[vtrow]; |
|
|
if (vtcol >= ncol) vp->v_text[ncol - 1] = '$'; |
if (vtcol >= ncol) |
else if (c == '\t' |
vp->v_text[ncol - 1] = '$'; |
|
else if (c == '\t' |
#ifdef NOTAB |
#ifdef NOTAB |
&& !(curbp->b_flag & BFNOTAB) |
&& !(curbp->b_flag & BFNOTAB) |
#endif |
#endif |
) { |
) { |
do { |
do { |
vtpute(' '); |
vtpute(' '); |
|
} |
|
while (((vtcol + lbound) & 0x07) != 0 && vtcol < ncol); |
|
} else if (ISCTRL(c) != FALSE) { |
|
vtpute('^'); |
|
vtpute(CCHR(c)); |
|
} else { |
|
if (vtcol >= 0) |
|
vp->v_text[vtcol] = c; |
|
++vtcol; |
} |
} |
while (((vtcol + lbound)&0x07) != 0 && vtcol < ncol); |
|
} else if (ISCTRL(c) != FALSE) { |
|
vtpute('^'); |
|
vtpute(CCHR(c)); |
|
} else { |
|
if (vtcol >= 0) vp->v_text[vtcol] = c; |
|
++vtcol; |
|
} |
|
} |
} |
|
|
/* Erase from the end of the |
/* |
* software cursor to the end of the |
* Erase from the end of the software cursor to the end of the line on which |
* line on which the software cursor is |
* the software cursor is located. The display routines will decide if a |
* located. The display routines will decide |
* hardware erase to end of line command should be used to display this. |
* if a hardware erase to end of line command |
|
* should be used to display this. |
|
*/ |
*/ |
VOID |
VOID |
vteeol() { |
vteeol() |
register VIDEO *vp; |
{ |
|
VIDEO *vp; |
|
|
vp = vscreen[vtrow]; |
vp = vscreen[vtrow]; |
while (vtcol < ncol) |
while (vtcol < ncol) |
|
|
* virtual and physical screens the same. |
* virtual and physical screens the same. |
*/ |
*/ |
VOID |
VOID |
update() { |
update() |
register LINE *lp; |
{ |
register MGWIN *wp; |
LINE *lp; |
register VIDEO *vp1; |
MGWIN *wp; |
VIDEO *vp2; |
VIDEO *vp1; |
register int i; |
VIDEO *vp2; |
register int j; |
int i; |
register int c; |
int j; |
register int hflag; |
int c; |
register int currow; |
int hflag; |
register int curcol; |
int currow; |
register int offs; |
int curcol; |
register int size; |
int offs; |
VOID traceback (); |
int size; |
VOID uline (); |
|
|
|
if (typeahead()) return; |
if (typeahead()) |
if (sgarbf) { /* must update everything */ |
return; |
|
if (sgarbf) { /* must update everything */ |
wp = wheadp; |
wp = wheadp; |
while(wp != NULL) { |
while (wp != NULL) { |
wp->w_flag |= WFMODE | WFHARD; |
wp->w_flag |= WFMODE | WFHARD; |
wp = wp->w_wndp; |
wp = wp->w_wndp; |
} |
} |
} |
} |
hflag = FALSE; /* Not hard. */ |
hflag = FALSE; /* Not hard. */ |
wp = wheadp; |
wp = wheadp; |
while (wp != NULL) { |
while (wp != NULL) { |
if (wp->w_flag != 0) { /* Need update. */ |
if (wp->w_flag != 0) { /* Need update. */ |
if ((wp->w_flag&WFFORCE) == 0) { |
if ((wp->w_flag & WFFORCE) == 0) { |
lp = wp->w_linep; |
lp = wp->w_linep; |
for (i=0; i<wp->w_ntrows; ++i) { |
for (i = 0; i < wp->w_ntrows; ++i) { |
if (lp == wp->w_dotp) |
if (lp == wp->w_dotp) |
goto out; |
goto out; |
if (lp == wp->w_bufp->b_linep) |
if (lp == wp->w_bufp->b_linep) |
|
|
lp = lforw(lp); |
lp = lforw(lp); |
} |
} |
} |
} |
i = wp->w_force; /* Reframe this one. */ |
i = wp->w_force; /* Reframe this one. */ |
if (i > 0) { |
if (i > 0) { |
--i; |
--i; |
if (i >= wp->w_ntrows) |
if (i >= wp->w_ntrows) |
i = wp->w_ntrows-1; |
i = wp->w_ntrows - 1; |
} else if (i < 0) { |
} else if (i < 0) { |
i += wp->w_ntrows; |
i += wp->w_ntrows; |
if (i < 0) |
if (i < 0) |
i = 0; |
i = 0; |
} else |
} else |
i = wp->w_ntrows/2; |
i = wp->w_ntrows / 2; |
lp = wp->w_dotp; |
lp = wp->w_dotp; |
while (i!=0 && lback(lp)!=wp->w_bufp->b_linep) { |
while (i != 0 && lback(lp) != wp->w_bufp->b_linep) { |
--i; |
--i; |
lp = lback(lp); |
lp = lback(lp); |
} |
} |
wp->w_linep = lp; |
wp->w_linep = lp; |
wp->w_flag |= WFHARD; /* Force full. */ |
wp->w_flag |= WFHARD; /* Force full. */ |
out: |
out: |
lp = wp->w_linep; /* Try reduced update. */ |
lp = wp->w_linep; /* Try reduced update. */ |
i = wp->w_toprow; |
i = wp->w_toprow; |
if ((wp->w_flag&~WFMODE) == WFEDIT) { |
if ((wp->w_flag & ~WFMODE) == WFEDIT) { |
while (lp != wp->w_dotp) { |
while (lp != wp->w_dotp) { |
++i; |
++i; |
lp = lforw(lp); |
lp = lforw(lp); |
} |
} |
vscreen[i]->v_color = CTEXT; |
vscreen[i]->v_color = CTEXT; |
vscreen[i]->v_flag |= (VFCHG|VFHBAD); |
vscreen[i]->v_flag |= (VFCHG | VFHBAD); |
vtmove(i, 0); |
vtmove(i, 0); |
for (j=0; j<llength(lp); ++j) |
for (j = 0; j < llength(lp); ++j) |
vtputc(lgetc(lp, j)); |
vtputc(lgetc(lp, j)); |
vteeol(); |
vteeol(); |
} else if ((wp->w_flag&(WFEDIT|WFHARD)) != 0) { |
} else if ((wp->w_flag & (WFEDIT | WFHARD)) != 0) { |
hflag = TRUE; |
hflag = TRUE; |
while (i < wp->w_toprow+wp->w_ntrows) { |
while (i < wp->w_toprow + wp->w_ntrows) { |
vscreen[i]->v_color = CTEXT; |
vscreen[i]->v_color = CTEXT; |
vscreen[i]->v_flag |= (VFCHG|VFHBAD); |
vscreen[i]->v_flag |= (VFCHG | VFHBAD); |
vtmove(i, 0); |
vtmove(i, 0); |
if (lp != wp->w_bufp->b_linep) { |
if (lp != wp->w_bufp->b_linep) { |
for (j=0; j<llength(lp); ++j) |
for (j = 0; j < llength(lp); ++j) |
vtputc(lgetc(lp, j)); |
vtputc(lgetc(lp, j)); |
lp = lforw(lp); |
lp = lforw(lp); |
} |
} |
|
|
++i; |
++i; |
} |
} |
} |
} |
if ((wp->w_flag&WFMODE) != 0) |
if ((wp->w_flag & WFMODE) != 0) |
modeline(wp); |
modeline(wp); |
wp->w_flag = 0; |
wp->w_flag = 0; |
wp->w_force = 0; |
wp->w_force = 0; |
} |
} |
wp = wp->w_wndp; |
wp = wp->w_wndp; |
} |
} |
lp = curwp->w_linep; /* Cursor location. */ |
lp = curwp->w_linep; /* Cursor location. */ |
currow = curwp->w_toprow; |
currow = curwp->w_toprow; |
while (lp != curwp->w_dotp) { |
while (lp != curwp->w_dotp) { |
++currow; |
++currow; |
|
|
c = lgetc(lp, i++); |
c = lgetc(lp, i++); |
if (c == '\t' |
if (c == '\t' |
#ifdef NOTAB |
#ifdef NOTAB |
&& !(curbp->b_flag & BFNOTAB) |
&& !(curbp->b_flag & BFNOTAB) |
#endif |
#endif |
) curcol |= 0x07; |
) |
|
curcol |= 0x07; |
else if (ISCTRL(c) != FALSE) |
else if (ISCTRL(c) != FALSE) |
++curcol; |
++curcol; |
++curcol; |
++curcol; |
} |
} |
if (curcol >= ncol - 1) { /* extended line. */ |
if (curcol >= ncol - 1) { /* extended line. */ |
/* flag we are extended and changed */ |
/* flag we are extended and changed */ |
vscreen[currow]->v_flag |= VFEXT | VFCHG; |
vscreen[currow]->v_flag |= VFEXT | VFCHG; |
updext(currow, curcol); /* and output extended line */ |
updext(currow, curcol); /* and output extended line */ |
} else lbound = 0; /* not extended line */ |
} else |
|
lbound = 0; /* not extended line */ |
|
|
/* make sure no lines need to be de-extended because the cursor is |
/* |
no longer on them */ |
* make sure no lines need to be de-extended because the cursor is no |
|
* longer on them |
|
*/ |
wp = wheadp; |
wp = wheadp; |
|
|
while (wp != NULL) { |
while (wp != NULL) { |
lp = wp->w_linep; |
lp = wp->w_linep; |
i = wp->w_toprow; |
i = wp->w_toprow; |
while (i < wp->w_toprow + wp->w_ntrows) { |
while (i < wp->w_toprow + wp->w_ntrows) { |
if (vscreen[i]->v_flag & VFEXT) { |
if (vscreen[i]->v_flag & VFEXT) { |
/* always flag extended lines as changed */ |
/* always flag extended lines as changed */ |
vscreen[i]->v_flag |= VFCHG; |
vscreen[i]->v_flag |= VFCHG; |
if ((wp != curwp) || (lp != wp->w_dotp) || |
if ((wp != curwp) || (lp != wp->w_dotp) || |
(curcol < ncol - 1)) { |
(curcol < ncol - 1)) { |
vtmove(i, 0); |
vtmove(i, 0); |
for (j = 0; j < llength(lp); ++j) |
for (j = 0; j < llength(lp); ++j) |
vtputc(lgetc(lp, j)); |
vtputc(lgetc(lp, j)); |
vteeol(); |
vteeol(); |
/* this line no longer is extended */ |
/* this line no longer is extended */ |
vscreen[i]->v_flag &= ~VFEXT; |
vscreen[i]->v_flag &= ~VFEXT; |
} |
} |
|
} |
|
lp = lforw(lp); |
|
++i; |
} |
} |
lp = lforw(lp); |
/* if garbaged then fix up mode lines */ |
++i; |
if (sgarbf != FALSE) |
} |
vscreen[i]->v_flag |= VFCHG; |
/* if garbaged then fix up mode lines */ |
/* and onward to the next window */ |
if (sgarbf != FALSE) vscreen[i]->v_flag |= VFCHG; |
wp = wp->w_wndp; |
/* and onward to the next window */ |
|
wp = wp->w_wndp; |
|
} |
} |
|
|
if (sgarbf != FALSE) { /* Screen is garbage. */ |
if (sgarbf != FALSE) { /* Screen is garbage. */ |
sgarbf = FALSE; /* Erase-page clears */ |
sgarbf = FALSE; /* Erase-page clears */ |
epresf = FALSE; /* the message area. */ |
epresf = FALSE; /* the message area. */ |
tttop = HUGE; /* Forget where you set */ |
tttop = HUGE; /* Forget where you set */ |
ttbot = HUGE; /* scroll region. */ |
ttbot = HUGE; /* scroll region. */ |
tthue = CNONE; /* Color unknown. */ |
tthue = CNONE; /* Color unknown. */ |
ttmove(0, 0); |
ttmove(0, 0); |
tteeop(); |
tteeop(); |
for (i=0; i<nrow-1; ++i) { |
for (i = 0; i < nrow - 1; ++i) { |
uline(i, vscreen[i], &blanks); |
uline(i, vscreen[i], &blanks); |
ucopy(vscreen[i], pscreen[i]); |
ucopy(vscreen[i], pscreen[i]); |
} |
} |
|
|
} |
} |
#ifdef GOSLING |
#ifdef GOSLING |
if (hflag != FALSE) { /* Hard update? */ |
if (hflag != FALSE) { /* Hard update? */ |
for (i=0; i<nrow-1; ++i) { /* Compute hash data. */ |
for (i = 0; i < nrow - 1; ++i) {/* Compute hash data. */ |
hash(vscreen[i]); |
hash(vscreen[i]); |
hash(pscreen[i]); |
hash(pscreen[i]); |
} |
} |
offs = 0; /* Get top match. */ |
offs = 0; /* Get top match. */ |
while (offs != nrow-1) { |
while (offs != nrow - 1) { |
vp1 = vscreen[offs]; |
vp1 = vscreen[offs]; |
vp2 = pscreen[offs]; |
vp2 = pscreen[offs]; |
if (vp1->v_color != vp2->v_color |
if (vp1->v_color != vp2->v_color |
|| vp1->v_hash != vp2->v_hash) |
|| vp1->v_hash != vp2->v_hash) |
break; |
break; |
uline(offs, vp1, vp2); |
uline(offs, vp1, vp2); |
ucopy(vp1, vp2); |
ucopy(vp1, vp2); |
++offs; |
++offs; |
} |
} |
if (offs == nrow-1) { /* Might get it all. */ |
if (offs == nrow - 1) { /* Might get it all. */ |
ttmove(currow, curcol - lbound); |
ttmove(currow, curcol - lbound); |
ttflush(); |
ttflush(); |
return; |
return; |
} |
} |
size = nrow-1; /* Get bottom match. */ |
size = nrow - 1; /* Get bottom match. */ |
while (size != offs) { |
while (size != offs) { |
vp1 = vscreen[size-1]; |
vp1 = vscreen[size - 1]; |
vp2 = pscreen[size-1]; |
vp2 = pscreen[size - 1]; |
if (vp1->v_color != vp2->v_color |
if (vp1->v_color != vp2->v_color |
|| vp1->v_hash != vp2->v_hash) |
|| vp1->v_hash != vp2->v_hash) |
break; |
break; |
uline(size-1, vp1, vp2); |
uline(size - 1, vp1, vp2); |
ucopy(vp1, vp2); |
ucopy(vp1, vp2); |
--size; |
--size; |
} |
} |
|
|
panic("Illegal screen size in update"); |
panic("Illegal screen size in update"); |
setscores(offs, size); /* Do hard update. */ |
setscores(offs, size); /* Do hard update. */ |
traceback(offs, size, size, size); |
traceback(offs, size, size, size); |
for (i=0; i<size; ++i) |
for (i = 0; i < size; ++i) |
ucopy(vscreen[offs+i], pscreen[offs+i]); |
ucopy(vscreen[offs + i], pscreen[offs + i]); |
ttmove(currow, curcol - lbound); |
ttmove(currow, curcol - lbound); |
ttflush(); |
ttflush(); |
return; |
return; |
} |
} |
#endif |
#endif |
for (i=0; i<nrow-1; ++i) { /* Easy update. */ |
for (i = 0; i < nrow - 1; ++i) { /* Easy update. */ |
vp1 = vscreen[i]; |
vp1 = vscreen[i]; |
vp2 = pscreen[i]; |
vp2 = pscreen[i]; |
if ((vp1->v_flag&VFCHG) != 0) { |
if ((vp1->v_flag & VFCHG) != 0) { |
uline(i, vp1, vp2); |
uline(i, vp1, vp2); |
ucopy(vp1, vp2); |
ucopy(vp1, vp2); |
} |
} |
|
|
* display has done an update. |
* display has done an update. |
*/ |
*/ |
VOID |
VOID |
ucopy(vvp, pvp) register VIDEO *vvp; register VIDEO *pvp; { |
ucopy(vvp, pvp) |
|
VIDEO *vvp; |
|
VIDEO *pvp; |
|
{ |
|
|
vvp->v_flag &= ~VFCHG; /* Changes done. */ |
vvp->v_flag &= ~VFCHG; /* Changes done. */ |
pvp->v_flag = vvp->v_flag; /* Update model. */ |
pvp->v_flag = vvp->v_flag; /* Update model. */ |
pvp->v_hash = vvp->v_hash; |
pvp->v_hash = vvp->v_hash; |
pvp->v_cost = vvp->v_cost; |
pvp->v_cost = vvp->v_cost; |
pvp->v_color = vvp->v_color; |
pvp->v_color = vvp->v_color; |
bcopy(vvp->v_text, pvp->v_text, ncol); |
bcopy(vvp->v_text, pvp->v_text, ncol); |
} |
} |
|
|
/* updext: update the extended line which the cursor is currently |
/* |
* on at a column greater than the terminal width. The line |
* updext: update the extended line which the cursor is currently on at a |
* will be scrolled right or left to let the user see where |
* column greater than the terminal width. The line will be scrolled right or |
* the cursor is |
* left to let the user see where the cursor is |
*/ |
*/ |
VOID |
VOID |
updext(currow, curcol) |
updext(currow, curcol) |
int currow, curcol; |
int currow, curcol; |
{ |
{ |
register LINE *lp; /* pointer to current line */ |
LINE *lp; /* pointer to current line */ |
register int j; /* index into line */ |
int j; /* index into line */ |
|
|
/* calculate what column the left bound should be */ |
/* |
/* (force cursor into middle half of screen) */ |
* calculate what column the left bound should be |
lbound = curcol - (curcol % (ncol>>1)) - (ncol>>2); |
* (force cursor into middle half of screen) |
/* scan through the line outputing characters to the virtual screen */ |
*/ |
/* once we reach the left edge */ |
lbound = curcol - (curcol % (ncol >> 1)) - (ncol >> 2); |
vtmove(currow, -lbound); /* start scanning offscreen */ |
/* |
lp = curwp->w_dotp; /* line to output */ |
* scan through the line outputing characters to the virtual screen |
for (j=0; j<llength(lp); ++j) /* until the end-of-line */ |
* once we reach the left edge |
vtpute(lgetc(lp, j)); |
*/ |
vteeol(); /* truncate the virtual line */ |
vtmove(currow, -lbound); /* start scanning offscreen */ |
vscreen[currow]->v_text[0] = '$'; /* and put a '$' in column 1 */ |
lp = curwp->w_dotp; /* line to output */ |
|
for (j = 0; j < llength(lp); ++j) /* until the end-of-line */ |
|
vtpute(lgetc(lp, j)); |
|
vteeol(); /* truncate the virtual line */ |
|
vscreen[currow]->v_text[0] = '$'; /* and put a '$' in column 1 */ |
} |
} |
|
|
/* |
/* |
|
|
* line when updating CMODE color lines, because of the way that |
* line when updating CMODE color lines, because of the way that |
* reverse video works on most terminals. |
* reverse video works on most terminals. |
*/ |
*/ |
VOID uline(row, vvp, pvp) VIDEO *vvp; VIDEO *pvp; { |
VOID |
|
uline(row, vvp, pvp) |
|
int row; |
|
VIDEO *vvp; |
|
VIDEO *pvp; |
|
{ |
#ifdef MEMMAP |
#ifdef MEMMAP |
putline(row+1, 1, &vvp->v_text[0]); |
putline(row + 1, 1, &vvp->v_text[0]); |
#else |
#else |
register char *cp1; |
char *cp1; |
register char *cp2; |
char *cp2; |
register char *cp3; |
char *cp3; |
char *cp4; |
char *cp4; |
char *cp5; |
char *cp5; |
register int nbflag; |
int nbflag; |
|
|
if (vvp->v_color != pvp->v_color) { /* Wrong color, do a */ |
if (vvp->v_color != pvp->v_color) { /* Wrong color, do a */ |
ttmove(row, 0); /* full redraw. */ |
ttmove(row, 0); /* full redraw. */ |
#ifdef STANDOUT_GLITCH |
#ifdef STANDOUT_GLITCH |
if (pvp->v_color != CTEXT && magic_cookie_glitch >= 0) |
if (pvp->v_color != CTEXT && magic_cookie_glitch >= 0) |
tteeol(); |
tteeol(); |
|
|
ttcolor(vvp->v_color); |
ttcolor(vvp->v_color); |
#ifdef STANDOUT_GLITCH |
#ifdef STANDOUT_GLITCH |
cp1 = &vvp->v_text[magic_cookie_glitch > 0 ? magic_cookie_glitch : 0]; |
cp1 = &vvp->v_text[magic_cookie_glitch > 0 ? magic_cookie_glitch : 0]; |
/* the odd code for magic_cookie_glitch==0 |
/* |
* is to avoid putting the invisable |
* the odd code for magic_cookie_glitch==0 is to avoid |
* glitch character on the next line. |
* putting the invisable glitch character on the next line. |
* (Hazeltine executive 80 model 30) |
* (Hazeltine executive 80 model 30) |
*/ |
*/ |
cp2 = &vvp->v_text[ncol - (magic_cookie_glitch >= 0 ? (magic_cookie_glitch!=0 ? magic_cookie_glitch : 1) : 0)]; |
cp2 = &vvp->v_text[ncol - (magic_cookie_glitch >= 0 ? (magic_cookie_glitch != 0 ? magic_cookie_glitch : 1) : 0)]; |
#else |
#else |
cp1 = &vvp->v_text[0]; |
cp1 = &vvp->v_text[0]; |
cp2 = &vvp->v_text[ncol]; |
cp2 = &vvp->v_text[ncol]; |
|
|
#endif |
#endif |
return; |
return; |
} |
} |
cp1 = &vvp->v_text[0]; /* Compute left match. */ |
cp1 = &vvp->v_text[0]; /* Compute left match. */ |
cp2 = &pvp->v_text[0]; |
cp2 = &pvp->v_text[0]; |
while (cp1!=&vvp->v_text[ncol] && cp1[0]==cp2[0]) { |
while (cp1 != &vvp->v_text[ncol] && cp1[0] == cp2[0]) { |
++cp1; |
++cp1; |
++cp2; |
++cp2; |
} |
} |
if (cp1 == &vvp->v_text[ncol]) /* All equal. */ |
if (cp1 == &vvp->v_text[ncol]) /* All equal. */ |
return; |
return; |
nbflag = FALSE; |
nbflag = FALSE; |
cp3 = &vvp->v_text[ncol]; /* Compute right match. */ |
cp3 = &vvp->v_text[ncol]; /* Compute right match. */ |
cp4 = &pvp->v_text[ncol]; |
cp4 = &pvp->v_text[ncol]; |
while (cp3[-1] == cp4[-1]) { |
while (cp3[-1] == cp4[-1]) { |
--cp3; |
--cp3; |
--cp4; |
--cp4; |
if (cp3[0] != ' ') /* Note non-blanks in */ |
if (cp3[0] != ' ') /* Note non-blanks in */ |
nbflag = TRUE; /* the right match. */ |
nbflag = TRUE; /* the right match. */ |
} |
} |
cp5 = cp3; /* Is erase good? */ |
cp5 = cp3; /* Is erase good? */ |
if (nbflag==FALSE && vvp->v_color==CTEXT) { |
if (nbflag == FALSE && vvp->v_color == CTEXT) { |
while (cp5!=cp1 && cp5[-1]==' ') |
while (cp5 != cp1 && cp5[-1] == ' ') |
--cp5; |
--cp5; |
/* Alcyon hack */ |
/* Alcyon hack */ |
if ((int)(cp3-cp5) <= tceeol) |
if ((int) (cp3 - cp5) <= tceeol) |
cp5 = cp3; |
cp5 = cp3; |
} |
} |
/* Alcyon hack */ |
/* Alcyon hack */ |
ttmove(row, (int)(cp1-&vvp->v_text[0])); |
ttmove(row, (int) (cp1 - &vvp->v_text[0])); |
#ifdef STANDOUT_GLITCH |
#ifdef STANDOUT_GLITCH |
if (vvp->v_color != CTEXT && magic_cookie_glitch > 0) { |
if (vvp->v_color != CTEXT && magic_cookie_glitch > 0) { |
if(cp1 < &vvp->v_text[magic_cookie_glitch]) cp1 = &vvp->v_text[magic_cookie_glitch]; |
if (cp1 < &vvp->v_text[magic_cookie_glitch]) |
if(cp5 > &vvp->v_text[ncol-magic_cookie_glitch]) cp5 = &vvp->v_text[ncol-magic_cookie_glitch]; |
cp1 = &vvp->v_text[magic_cookie_glitch]; |
|
if (cp5 > &vvp->v_text[ncol - magic_cookie_glitch]) |
|
cp5 = &vvp->v_text[ncol - magic_cookie_glitch]; |
} else if (magic_cookie_glitch < 0) |
} else if (magic_cookie_glitch < 0) |
#endif |
#endif |
ttcolor(vvp->v_color); |
ttcolor(vvp->v_color); |
|
|
ttputc(*cp1++); |
ttputc(*cp1++); |
++ttcol; |
++ttcol; |
} |
} |
if (cp5 != cp3) /* Do erase. */ |
if (cp5 != cp3) /* Do erase. */ |
tteeol(); |
tteeol(); |
#endif |
#endif |
} |
} |
|
|
/* |
/* |
* Redisplay the mode line for |
* Redisplay the mode line for the window pointed to by the "wp". |
* the window pointed to by the "wp". |
* This is the only routine that has any idea of how the modeline is |
* This is the only routine that has any idea |
* formatted. You can change the modeline format by hacking at this |
* of how the modeline is formatted. You can |
* routine. Called by "update" any time there is a dirty window. Note |
* change the modeline format by hacking at |
* that if STANDOUT_GLITCH is defined, first and last magic_cookie_glitch |
* this routine. Called by "update" any time |
* characters may never be seen. |
* there is a dirty window. |
|
* Note that if STANDOUT_GLITCH is defined, first and last |
|
* magic_cookie_glitch characters may never be seen. |
|
*/ |
*/ |
VOID |
VOID |
modeline(wp) register MGWIN *wp; { |
modeline(wp) |
register int n; |
MGWIN *wp; |
register BUFFER *bp; |
{ |
int mode; |
int n; |
|
BUFFER *bp; |
|
int mode; |
|
|
n = wp->w_toprow+wp->w_ntrows; /* Location. */ |
n = wp->w_toprow + wp->w_ntrows; /* Location. */ |
vscreen[n]->v_color = CMODE; /* Mode line color. */ |
vscreen[n]->v_color = CMODE; /* Mode line color. */ |
vscreen[n]->v_flag |= (VFCHG|VFHBAD); /* Recompute, display. */ |
vscreen[n]->v_flag |= (VFCHG | VFHBAD); /* Recompute, display. */ |
vtmove(n, 0); /* Seek to right line. */ |
vtmove(n, 0); /* Seek to right line. */ |
bp = wp->w_bufp; |
bp = wp->w_bufp; |
vtputc('-'); vtputc('-'); |
vtputc('-'); |
if ((bp->b_flag&BFCHG) != 0) { /* "*" if changed. */ |
vtputc('-'); |
vtputc('*'); vtputc('*'); |
if ((bp->b_flag & BFCHG) != 0) { /* "*" if changed. */ |
|
vtputc('*'); |
|
vtputc('*'); |
} else { |
} else { |
vtputc('-'); vtputc('-'); |
vtputc('-'); |
|
vtputc('-'); |
} |
} |
vtputc('-'); |
vtputc('-'); |
n = 5; |
n = 5; |
n += vtputs("Mg: "); |
n += vtputs("Mg: "); |
if (bp->b_bname[0] != '\0') |
if (bp->b_bname[0] != '\0') |
n += vtputs(&(bp->b_bname[0])); |
n += vtputs(&(bp->b_bname[0])); |
while (n < 42) { /* Pad out with blanks */ |
while (n < 42) { /* Pad out with blanks */ |
vtputc(' '); |
vtputc(' '); |
++n; |
++n; |
} |
} |
vtputc('('); |
vtputc('('); |
++n; |
++n; |
for(mode=0;;) { |
for (mode = 0;;) { |
n += vtputs(bp->b_modes[mode]->p_name); |
n += vtputs(bp->b_modes[mode]->p_name); |
if(++mode > bp->b_nmodes) break; |
if (++mode > bp->b_nmodes) |
vtputc('-'); |
break; |
++n; |
vtputc('-'); |
|
++n; |
} |
} |
vtputc(')'); |
vtputc(')'); |
++n; |
++n; |
while (n < ncol) { /* Pad out. */ |
while (n < ncol) { /* Pad out. */ |
vtputc('-'); |
vtputc('-'); |
++n; |
++n; |
} |
} |
|
|
/* |
/* |
* output a string to the mode line, report how long it was. |
* output a string to the mode line, report how long it was. |
*/ |
*/ |
vtputs(s) register char *s; { |
int |
register int n = 0; |
vtputs(s) |
|
char *s; |
|
{ |
|
int n = 0; |
|
|
while (*s != '\0') { |
while (*s != '\0') { |
vtputc(*s++); |
vtputc(*s++); |
|
|
} |
} |
return n; |
return n; |
} |
} |
|
|
#ifdef GOSLING |
#ifdef GOSLING |
/* |
/* |
* Compute the hash code for |
* Compute the hash code for the line pointed to by the "vp". |
* the line pointed to by the "vp". Recompute |
* Recompute it if necessary. Also set the approximate redisplay |
* it if necessary. Also set the approximate redisplay |
* cost. The validity of the hash code is marked by a flag bit. |
* cost. The validity of the hash code is marked by |
* The cost understand the advantages of erase to end of line. |
* a flag bit. The cost understand the advantages |
* Tuned for the VAX by Bob McNamara; better than it used to be on |
* of erase to end of line. Tuned for the VAX |
|
* by Bob McNamara; better than it used to be on |
|
* just about any machine. |
* just about any machine. |
*/ |
*/ |
VOID |
VOID |
hash(vp) register VIDEO *vp; { |
hash(vp) |
register int i; |
VIDEO *vp; |
register int n; |
{ |
register char *s; |
int i; |
|
int n; |
|
char *s; |
|
|
if ((vp->v_flag&VFHBAD) != 0) { /* Hash bad. */ |
if ((vp->v_flag & VFHBAD) != 0) { /* Hash bad. */ |
s = &vp->v_text[ncol-1]; |
s = &vp->v_text[ncol - 1]; |
for (i=ncol; i!=0; --i, --s) |
for (i = ncol; i != 0; --i, --s) |
if (*s != ' ') |
if (*s != ' ') |
break; |
break; |
n = ncol-i; /* Erase cheaper? */ |
n = ncol - i; /* Erase cheaper? */ |
if (n > tceeol) |
if (n > tceeol) |
n = tceeol; |
n = tceeol; |
vp->v_cost = i+n; /* Bytes + blanks. */ |
vp->v_cost = i + n; /* Bytes + blanks. */ |
for (n=0; i!=0; --i, --s) |
for (n = 0; i != 0; --i, --s) |
n = (n<<5) + n + *s; |
n = (n << 5) + n + *s; |
vp->v_hash = n; /* Hash code. */ |
vp->v_hash = n; /* Hash code. */ |
vp->v_flag &= ~VFHBAD; /* Flag as all done. */ |
vp->v_flag &= ~VFHBAD; /* Flag as all done. */ |
} |
} |
} |
} |
|
|
|
|
* bit better; but it looks ugly. |
* bit better; but it looks ugly. |
*/ |
*/ |
VOID |
VOID |
setscores(offs, size) { |
setscores(offs, size) |
register SCORE *sp; |
int offs; |
SCORE *sp1; |
int size; |
register int tempcost; |
{ |
register int bestcost; |
SCORE *sp; |
register int j; |
SCORE *sp1; |
register int i; |
int tempcost; |
register VIDEO **vp; |
int bestcost; |
VIDEO **pp, **vbase, **pbase; |
int j; |
|
int i; |
|
VIDEO **vp, **pp; |
|
VIDEO **vbase, **pbase; |
|
|
vbase = &vscreen[offs-1]; /* By hand CSE's. */ |
vbase = &vscreen[offs - 1]; /* By hand CSE's. */ |
pbase = &pscreen[offs-1]; |
pbase = &pscreen[offs - 1]; |
score[0].s_itrace = 0; /* [0, 0] */ |
score[0].s_itrace = 0; /* [0, 0] */ |
score[0].s_jtrace = 0; |
score[0].s_jtrace = 0; |
score[0].s_cost = 0; |
score[0].s_cost = 0; |
sp = &score[1]; /* Row 0, inserts. */ |
sp = &score[1]; /* Row 0, inserts. */ |
tempcost = 0; |
tempcost = 0; |
vp = &vbase[1]; |
vp = &vbase[1]; |
for (j=1; j<=size; ++j) { |
for (j = 1; j <= size; ++j) { |
sp->s_itrace = 0; |
sp->s_itrace = 0; |
sp->s_jtrace = j-1; |
sp->s_jtrace = j - 1; |
tempcost += tcinsl; |
tempcost += tcinsl; |
tempcost += (*vp)->v_cost; |
tempcost += (*vp)->v_cost; |
sp->s_cost = tempcost; |
sp->s_cost = tempcost; |
++vp; |
++vp; |
++sp; |
++sp; |
} |
} |
sp = &score[NROW]; /* Column 0, deletes. */ |
sp = &score[NROW]; /* Column 0, deletes. */ |
tempcost = 0; |
tempcost = 0; |
for (i=1; i<=size; ++i) { |
for (i = 1; i <= size; ++i) { |
sp->s_itrace = i-1; |
sp->s_itrace = i - 1; |
sp->s_jtrace = 0; |
sp->s_jtrace = 0; |
tempcost += tcdell; |
tempcost += tcdell; |
sp->s_cost = tempcost; |
sp->s_cost = tempcost; |
sp += NROW; |
sp += NROW; |
} |
} |
sp1 = &score[NROW+1]; /* [1, 1]. */ |
sp1 = &score[NROW + 1]; /* [1, 1]. */ |
pp = &pbase[1]; |
pp = &pbase[1]; |
for (i=1; i<=size; ++i) { |
for (i = 1; i <= size; ++i) { |
sp = sp1; |
sp = sp1; |
vp = &vbase[1]; |
vp = &vbase[1]; |
for (j=1; j<=size; ++j) { |
for (j = 1; j <= size; ++j) { |
sp->s_itrace = i-1; |
sp->s_itrace = i - 1; |
sp->s_jtrace = j; |
sp->s_jtrace = j; |
bestcost = (sp-NROW)->s_cost; |
bestcost = (sp - NROW)->s_cost; |
if (j != size) /* Cd(A[i])=0 @ Dis. */ |
if (j != size) /* Cd(A[i])=0 @ Dis. */ |
bestcost += tcdell; |
bestcost += tcdell; |
tempcost = (sp-1)->s_cost; |
tempcost = (sp - 1)->s_cost; |
tempcost += (*vp)->v_cost; |
tempcost += (*vp)->v_cost; |
if (i != size) /* Ci(B[j])=0 @ Dsj. */ |
if (i != size) /* Ci(B[j])=0 @ Dsj. */ |
tempcost += tcinsl; |
tempcost += tcinsl; |
if (tempcost < bestcost) { |
if (tempcost < bestcost) { |
sp->s_itrace = i; |
sp->s_itrace = i; |
sp->s_jtrace = j-1; |
sp->s_jtrace = j - 1; |
bestcost = tempcost; |
bestcost = tempcost; |
} |
} |
tempcost = (sp-NROW-1)->s_cost; |
tempcost = (sp - NROW - 1)->s_cost; |
if ((*pp)->v_color != (*vp)->v_color |
if ((*pp)->v_color != (*vp)->v_color |
|| (*pp)->v_hash != (*vp)->v_hash) |
|| (*pp)->v_hash != (*vp)->v_hash) |
tempcost += (*vp)->v_cost; |
tempcost += (*vp)->v_cost; |
if (tempcost < bestcost) { |
if (tempcost < bestcost) { |
sp->s_itrace = i-1; |
sp->s_itrace = i - 1; |
sp->s_jtrace = j-1; |
sp->s_jtrace = j - 1; |
bestcost = tempcost; |
bestcost = tempcost; |
} |
} |
sp->s_cost = bestcost; |
sp->s_cost = bestcost; |
++sp; /* Next column. */ |
++sp; /* Next column. */ |
++vp; |
++vp; |
} |
} |
++pp; |
++pp; |
sp1 += NROW; /* Next row. */ |
sp1 += NROW; /* Next row. */ |
} |
} |
} |
} |
|
|
|
|
* which is acceptable because this routine is much less compute |
* which is acceptable because this routine is much less compute |
* intensive then the code that builds the score matrix! |
* intensive then the code that builds the score matrix! |
*/ |
*/ |
VOID traceback(offs, size, i, j) { |
VOID |
register int itrace; |
traceback(offs, size, i, j) |
register int jtrace; |
int offs; |
register int k; |
int size; |
register int ninsl; |
int i; |
register int ndraw; |
int j; |
register int ndell; |
{ |
|
int itrace; |
|
int jtrace; |
|
int k; |
|
int ninsl; |
|
int ndraw; |
|
int ndell; |
|
|
if (i==0 && j==0) /* End of update. */ |
if (i == 0 && j == 0) /* End of update. */ |
return; |
return; |
itrace = score[(NROW*i) + j].s_itrace; |
itrace = score[(NROW * i) + j].s_itrace; |
jtrace = score[(NROW*i) + j].s_jtrace; |
jtrace = score[(NROW * i) + j].s_jtrace; |
if (itrace == i) { /* [i, j-1] */ |
if (itrace == i) { /* [i, j-1] */ |
ninsl = 0; /* Collect inserts. */ |
ninsl = 0; /* Collect inserts. */ |
if (i != size) |
if (i != size) |
ninsl = 1; |
ninsl = 1; |
ndraw = 1; |
ndraw = 1; |
while (itrace!=0 || jtrace!=0) { |
while (itrace != 0 || jtrace != 0) { |
if (score[(NROW*itrace) + jtrace].s_itrace != itrace) |
if (score[(NROW * itrace) + jtrace].s_itrace != itrace) |
break; |
break; |
jtrace = score[(NROW*itrace) + jtrace].s_jtrace; |
jtrace = score[(NROW * itrace) + jtrace].s_jtrace; |
if (i != size) |
if (i != size) |
++ninsl; |
++ninsl; |
++ndraw; |
++ndraw; |
|
|
traceback(offs, size, itrace, jtrace); |
traceback(offs, size, itrace, jtrace); |
if (ninsl != 0) { |
if (ninsl != 0) { |
ttcolor(CTEXT); |
ttcolor(CTEXT); |
ttinsl(offs+j-ninsl, offs+size-1, ninsl); |
ttinsl(offs + j - ninsl, offs + size - 1, ninsl); |
} |
} |
do { /* B[j], A[j] blank. */ |
do { /* B[j], A[j] blank. */ |
k = offs+j-ndraw; |
k = offs + j - ndraw; |
uline(k, vscreen[k], &blanks); |
uline(k, vscreen[k], &blanks); |
} while (--ndraw); |
} while (--ndraw); |
return; |
return; |
} |
} |
if (jtrace == j) { /* [i-1, j] */ |
if (jtrace == j) { /* [i-1, j] */ |
ndell = 0; /* Collect deletes. */ |
ndell = 0; /* Collect deletes. */ |
if (j != size) |
if (j != size) |
ndell = 1; |
ndell = 1; |
while (itrace!=0 || jtrace!=0) { |
while (itrace != 0 || jtrace != 0) { |
if (score[(NROW*itrace) + jtrace].s_jtrace != jtrace) |
if (score[(NROW * itrace) + jtrace].s_jtrace != jtrace) |
break; |
break; |
itrace = score[(NROW*itrace) + jtrace].s_itrace; |
itrace = score[(NROW * itrace) + jtrace].s_itrace; |
if (j != size) |
if (j != size) |
++ndell; |
++ndell; |
} |
} |
if (ndell != 0) { |
if (ndell != 0) { |
ttcolor(CTEXT); |
ttcolor(CTEXT); |
ttdell(offs+i-ndell, offs+size-1, ndell); |
ttdell(offs + i - ndell, offs + size - 1, ndell); |
} |
} |
traceback(offs, size, itrace, jtrace); |
traceback(offs, size, itrace, jtrace); |
return; |
return; |
} |
} |
traceback(offs, size, itrace, jtrace); |
traceback(offs, size, itrace, jtrace); |
k = offs+j-1; |
k = offs + j - 1; |
uline(k, vscreen[k], pscreen[offs+i-1]); |
uline(k, vscreen[k], pscreen[offs + i - 1]); |
} |
} |
#endif |
#endif |