2 /***************************************************************************
4 ****************************************************************************
5 * ncurses is copyright (C) 1992-1995 *
7 * zmbenhal@netcom.com *
9 * esr@snark.thyrsus.com *
11 * Permission is hereby granted to reproduce and distribute ncurses *
12 * by any means and for any fee, whether alone or as part of a *
13 * larger distribution, in source or in binary form, PROVIDED *
14 * this notice is included with any such distribution, and is not *
15 * removed from any of its header files. Mention of ncurses in any *
16 * applications linked with it is highly appreciated. *
18 * ncurses comes AS IS with no warranty, implied or expressed. *
20 ***************************************************************************/
27 * The routines wredrawln(), wrefresh() and wnoutrefresh().
31 #include <curses.priv.h>
33 MODULE_ID("$Id: lib_refresh.c,v 1.14 1997/02/02 01:05:26 tom Exp $")
35 int wredrawln(WINDOW *win, int beg, int num)
37 T((T_CALLED("wredrawln(%p,%d,%d)"), win, beg, num));
38 touchline(win, beg, num);
43 int wrefresh(WINDOW *win)
47 T((T_CALLED("wrefresh(%p)"), win));
50 curscr->_clear = TRUE;
52 } else if ((code = wnoutrefresh(win)) == OK) {
54 newscr->_clear = TRUE;
57 * Reset the clearok() flag in case it was set for the special
58 * case in hardscroll.c (if we don't reset it here, we'll get 2
59 * refreshes because the flag is copied from stdscr to newscr).
60 * Resetting the flag shouldn't do any harm, anyway.
67 int wnoutrefresh(WINDOW *win)
70 short begx = win->_begx;
71 short begy = win->_begy;
75 T((T_CALLED("wnoutrefresh(%p)"), win));
77 if (_nc_tracing & TRACE_UPDATE)
78 _tracedump("...win", win);
82 * This function will break badly if we try to refresh a pad.
85 || (win->_flags & _ISPAD))
89 * If 'newscr' has a different background than the window that we're
90 * trying to refresh, we'll have to copy the whole thing.
92 if (win->_bkgd != newscr->_bkgd) {
94 newscr->_bkgd = win->_bkgd;
96 newscr->_attrs = win->_attrs;
98 /* merge in change information from all subwindows of this window */
102 * For pure efficiency, we'd want to transfer scrolling information
103 * from the window to newscr whenever the window is wide enough that
104 * its update will dominate the cost of the update for the horizontal
105 * band of newscr that it occupies. Unfortunately, this threshold
106 * tends to be complex to estimate, and in any case scrolling the
107 * whole band and rewriting the parts outside win's image would look
108 * really ugly. So. What we do is consider the window "wide" if it
109 * either (a) occupies the whole width of newscr, or (b) occupies
110 * all but at most one column on either vertical edge of the screen
111 * (this caters to fussy people who put boxes around full-screen
112 * windows). Note that changing this formula will not break any code,
113 * merely change the costs of various update cases.
115 wide = (begx <= 1 && win->_maxx >= (newscr->_maxx - 1));
117 win->_flags &= ~_HASMOVED;
120 * Microtweaking alert! This double loop is one of the genuine
121 * hot spots in the code. Even gcc doesn't seem to do enough
122 * common-subexpression chunking to make it really tense,
123 * so we'll force the issue.
125 for (i = 0, m = begy + win->_yoffset;
126 i <= win->_maxy && m <= newscr->_maxy;
128 register struct ldat *nline = &newscr->_line[m];
129 register struct ldat *oline = &win->_line[i];
131 if (oline->firstchar != _NOCHANGE) {
132 int last = oline->lastchar;
135 if (last > win->_maxx)
138 if (last > newscr->_maxx - begx)
139 last = newscr->_maxx - begx;
141 for (j = oline->firstchar, n = j + begx; j <= last; j++, n++) {
142 if (oline->text[j] != nline->text[n]) {
143 nline->text[n] = oline->text[j];
145 if (nline->firstchar == _NOCHANGE)
146 nline->firstchar = nline->lastchar = n;
147 else if (n < nline->firstchar)
148 nline->firstchar = n;
149 else if (n > nline->lastchar)
157 int oind = oline->oldindex;
159 nline->oldindex = (oind == _NEWINDEX) ? _NEWINDEX : begy + oind + win->_yoffset;
162 oline->firstchar = oline->lastchar = _NOCHANGE;
168 newscr->_clear = TRUE;
171 if (! win->_leaveok) {
172 newscr->_cury = win->_cury + win->_begy + win->_yoffset;
173 newscr->_curx = win->_curx + win->_begx;
176 if (_nc_tracing & TRACE_UPDATE)
177 _tracedump("newscr", newscr);