* Copyright (c) 1981 Regents of the University of California.
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)refresh.c 5.10 (Berkeley) %G%";
static void domvcur
__P((int, int, int, int));
static int makech
__P((WINDOW
*, int));
static void quickch
__P((WINDOW
*));
static void scrolln
__P((WINDOW
*, int, int));
* Make the current screen look like "win" over the area coverd by
/* Make sure were in visual state. */
tputs(VS
, 0, __cputchar
);
tputs(TI
, 0, __cputchar
);
/* Initialize loop parameters. */
curwin
= (win
== curscr
);
for (wy
= 0; wy
< win
->maxy
; wy
++) {
if (wlp
->flags
& __ISDIRTY
)
wlp
->hash
= __hash(wlp
->line
, win
->maxx
);
if (win
->flags
& __CLEAROK
|| curscr
->flags
& __CLEAROK
|| curwin
) {
if ((win
->flags
& __FULLWIN
) || curscr
->flags
& __CLEAROK
) {
tputs(CL
, 0, __cputchar
);
curscr
->flags
&= ~__CLEAROK
;
win
->flags
&= ~__CLEAROK
;
__TRACE("wrefresh: (%0.2o): curwin = %d\n", win
, curwin
);
__TRACE("wrefresh: \tfirstch\tlastch\n");
for (wy
= 0; wy
< win
->maxy
; wy
++) {
wy
, win
->lines
[wy
]->firstch
, win
->lines
[wy
]->lastch
);
curscr
->lines
[wy
]->hash
= win
->lines
[wy
]->hash
;
if (win
->lines
[wy
]->flags
& __ISDIRTY
)
if (makech(win
, wy
) == ERR
)
if (win
->lines
[wy
]->firstch
>= win
->ch_off
)
win
->lines
[wy
]->firstch
= win
->maxx
+
if (win
->lines
[wy
]->lastch
< win
->maxx
+
win
->lines
[wy
]->lastch
= win
->ch_off
;
if (win
->lines
[wy
]->lastch
<
win
->lines
[wy
]->flags
&= ~__ISDIRTY
;
__TRACE("\t%d\t%d\n", win
->lines
[wy
]->firstch
,
__TRACE("refresh: ly=%d, lx=%d\n", ly
, lx
);
domvcur(ly
, lx
, win
->cury
, win
->curx
);
if (win
->flags
& __LEAVEOK
) {
if (ly
>= 0 && ly
< win
->maxy
&& lx
>= 0 &&
win
->cury
= win
->curx
= 0;
domvcur(ly
, lx
, win
->cury
+ win
->begy
,
curscr
->cury
= win
->cury
+ win
->begy
;
curscr
->curx
= win
->curx
+ win
->begx
;
* Make a change on the screen.
register int nlsp
, clsp
; /* Last space in lines. */
register short wx
, lch
, y
;
register char *nsp
, *csp
, *ce
;
if (!(win
->lines
[wy
]->flags
& __ISDIRTY
))
wx
= win
->lines
[wy
]->firstch
- win
->ch_off
;
lch
= win
->lines
[wy
]->lastch
- win
->ch_off
;
else if (lch
>= win
->maxx
)
csp
= &curscr
->lines
[wy
+ win
->begy
]->line
[wx
+ win
->begx
];
nsp
= &win
->lines
[wy
]->line
[wx
];
for (ce
= &win
->lines
[wy
]->line
[win
->maxx
- 1];
if (ce
<= win
->lines
[wy
]->line
)
nlsp
= ce
- win
->lines
[wy
]->line
;
while (*nsp
== *csp
&& wx
<= lch
) {
domvcur(ly
, lx
, y
, wx
+ win
->begx
);
__TRACE("makech: 1: wx = %d, lx = %d, newy = %d, newx = %d\n",
wx
, lx
, y
, wx
+ win
->begx
);
while (*nsp
!= *csp
&& wx
<= lch
) {
if (ce
!= NULL
&& wx
>= nlsp
&& *nsp
== ' ') {
/* Check for clear to end-of-line. */
ce
= &curscr
->lines
[ly
]->line
[COLS
- 1];
clsp
= ce
- curscr
->lines
[ly
]->line
-
__TRACE("makech: clsp = %d, nlsp = %d\n", clsp
, nlsp
);
if (clsp
- nlsp
>= strlen(CE
) &&
__TRACE("makech: using CE\n");
tputs(CE
, 0, __cputchar
);
/* Enter/exit standout mode as appropriate. */
if (SO
&& (*nsp
& __STANDOUT
) !=
(curscr
->flags
& __STANDOUT
)) {
tputs(SO
, 0, __cputchar
);
curscr
->flags
|= __WSTANDOUT
;
tputs(SE
, 0, __cputchar
);
curscr
->flags
&= ~__WSTANDOUT
;
if (wx
>= win
->maxx
&& wy
== win
->maxy
- 1)
if (win
->flags
& __SCROLLOK
) {
if (curscr
->flags
& __WSTANDOUT
&& win
->flags
& __ENDLINE
)
putchar((*csp
= *nsp
) & 0177);
if (win
->flags
& __FULLWIN
&& !curwin
)
if (win
->flags
& __SCROLLWIN
) {
putchar((*csp
++ = *nsp
) & 0177);
__TRACE("makech: putchar(%c)\n", *nsp
& 0177);
if (UC
&& (*nsp
& __STANDOUT
)) {
tputs(UC
, 0, __cputchar
);
__TRACE("makech: 2: wx = %d, lx = %d\n", wx
, lx
);
if (lx
== wx
+ win
->begx
) /* If no change. */
* xn glitch: chomps a newline after auto-wrap.
* we just feed it now and forget about it.
__TRACE("makech: 3: wx = %d, lx = %d\n", wx
, lx
);
* Do a mvcur, leaving standout mode if necessary.
if (curscr
->flags
& __WSTANDOUT
&& !MS
) {
tputs(SE
, 0, __cputchar
);
curscr
->flags
&= ~__WSTANDOUT
;
* Quickch() attempts to detect a pattern in the change of the window
* inorder to optimize the change, e.g., scroll n lines as opposed to
* repainting the screen line by line.
#define THRESH win->maxy / 2
register LINE
*wlp
, *clp
;
register int bsize
, curs
, curw
, starts
, startw
, i
;
for (bsize
= win
->maxy
; bsize
>= THRESH
; bsize
--)
for (startw
= 0; startw
<= win
->maxy
- bsize
; startw
++)
for (starts
= 0; starts
<= win
->maxy
- bsize
;
for (curw
= startw
, curs
= starts
;
curs
< starts
+ bsize
; curw
++, curs
++)
if (win
->lines
[curw
]->hash
!=
curscr
->lines
[curs
]->hash
)
if (curs
== starts
+ bsize
)
/* Did not find anything or block is in correct place already. */
if (bsize
< THRESH
|| starts
== startw
)
__TRACE("quickch:bsize=%d,starts=%d,startw=%d,curw=%d,curs=%d\n",
bsize
, starts
, startw
, curw
, curs
);
scrolln(win
, starts
, startw
);
/* Mark the block as clean and retain consistency. */
for (i
= startw
; i
< startw
+ bsize
; i
++) {
wlp
->flags
&= ~(__ISDIRTY
| __ISPASTEOL
);
bcopy(wlp
->line
, clp
->line
, win
->maxx
);
scrolln(win
, starts
, startw
)
mvcur(oy
, ox
, startw
, 0);
tputs(tscroll(DL
, n
), 0, __cputchar
);
tputs(dl
, 0, __cputchar
);
mvcur(startw
, 0, oy
, ox
);
/* Delete the bottom lines */
mvcur(oy
, 0, win
->maxy
+ n
, 0); /* n < 0 */
tputs(tscroll(DL
, -n
), 0, __cputchar
);
tputs(dl
, 0, __cputchar
);
mvcur(win
->maxy
+ n
, 0, starts
, 0);
/* Scroll the block down */
tputs(tscroll(AL
, -n
), 0, __cputchar
);
tputs(al
, 0, __cputchar
);
mvcur(starts
, 0, oy
, ox
);