148
148
#include <curses.priv.h>
150
MODULE_ID("$Id: hardscroll.c,v 1.42 2008/08/03 23:49:30 tom Exp $")
150
MODULE_ID("$Id: hardscroll.c,v 1.43 2009/04/18 21:41:30 tom Exp $")
152
152
#if defined(SCROLLDEBUG) || defined(HASHDEBUG)
154
154
# undef screen_lines
155
# define screen_lines MAXLINES
156
NCURSES_EXPORT_VAR(int)
158
# define OLDNUM(n) oldnums[n]
155
# define screen_lines(sp) MAXLINES
156
NCURSES_EXPORT_VAR (int)
158
# define OLDNUM(sp,n) oldnums[n]
159
159
# define _tracef printf
161
161
# define TR(n, a) if (_nc_tracing & (n)) { _tracef a ; putchar('\n'); }
163
extern NCURSES_EXPORT_VAR(unsigned) _nc_tracing;
163
extern NCURSES_EXPORT_VAR(unsigned) _nc_tracing;
165
165
#else /* no debug */
167
167
/* OLDNUM(n) indicates which line will be shifted to the position n.
168
168
if OLDNUM(n) == _NEWINDEX, then the line n in new, not shifted from
170
NCURSES_EXPORT_VAR(int *)
171
_nc_oldnums = 0; /* obsolete: keep for ABI compat */
170
NCURSES_EXPORT_VAR (int *)
171
_nc_oldnums = 0; /* obsolete: keep for ABI compat */
174
# define oldnums SP->_oldnum_list
175
# define OLDNUM(n) oldnums[n]
174
# define oldnums(sp) (sp)->_oldnum_list
175
# define OLDNUM(sp,n) oldnums(sp)[n]
176
176
# else /* !USE_HASHMAP */
177
# define OLDNUM(n) newscr->_line[n].oldindex
177
# define OLDNUM(sp,n) sp->_newscr->_line[n].oldindex
178
178
# endif /* !USE_HASHMAP */
180
#define OLDNUM_SIZE SP->_oldnum_size
180
#define OLDNUM_SIZE(sp) (sp)->_oldnum_size
182
182
#endif /* defined(SCROLLDEBUG) || defined(HASHDEBUG) */
184
184
NCURSES_EXPORT(void)
185
_nc_scroll_optimize(void)
185
NCURSES_SP_NAME(_nc_scroll_optimize) (NCURSES_SP_DCL0)
186
186
/* scroll optimization to transform curscr to newscr */
189
189
int start, end, shift;
191
TR(TRACE_ICALLS, (T_CALLED("_nc_scroll_optimize")));
191
TR(TRACE_ICALLS, (T_CALLED("_nc_scroll_optimize(%p)"), SP_PARM));
193
193
#if !defined(SCROLLDEBUG) && !defined(HASHDEBUG)
195
195
/* get enough storage */
196
if (OLDNUM_SIZE < screen_lines) {
197
int *new_oldnums = typeRealloc(int, screen_lines, oldnums);
196
if (OLDNUM_SIZE(SP_PARM) < screen_lines(SP_PARM)) {
197
int *new_oldnums = typeRealloc(int, screen_lines(SP_PARM), oldnums(SP_PARM));
198
198
if (!new_oldnums)
200
oldnums = new_oldnums;
201
OLDNUM_SIZE = screen_lines;
200
oldnums(SP_PARM) = new_oldnums;
201
OLDNUM_SIZE(SP_PARM) = screen_lines(SP_PARM);
203
203
/* calculate the indices */
204
NCURSES_SP_NAME(_nc_hash_map) (NCURSES_SP_ARG);
206
206
#endif /* !defined(SCROLLDEBUG) && !defined(HASHDEBUG) */
209
209
if (USE_TRACEF(TRACE_UPDATE | TRACE_MOVE)) {
210
NCURSES_SP_NAME(_nc_linedump) (NCURSES_SP_ARG);
211
211
_nc_unlock_global(tracef);
213
213
#endif /* TRACE */
215
215
/* pass 1 - from top to bottom scrolling up */
216
for (i = 0; i < screen_lines;) {
217
while (i < screen_lines && (OLDNUM(i) == _NEWINDEX || OLDNUM(i) <= i))
216
for (i = 0; i < screen_lines(SP_PARM);) {
217
while (i < screen_lines(SP_PARM)
218
&& (OLDNUM(SP_PARM, i) == _NEWINDEX || OLDNUM(SP_PARM, i) <= i))
219
if (i >= screen_lines)
220
if (i >= screen_lines(SP_PARM))
222
shift = OLDNUM(i) - i; /* shift > 0 */
223
shift = OLDNUM(SP_PARM, i) - i; /* shift > 0 */
226
while (i < screen_lines && OLDNUM(i) != _NEWINDEX && OLDNUM(i) - i
227
while (i < screen_lines(SP_PARM)
228
&& OLDNUM(SP_PARM, i) != _NEWINDEX
229
&& OLDNUM(SP_PARM, i) - i == shift)
229
231
end = i - 1 + shift;
231
233
TR(TRACE_UPDATE | TRACE_MOVE, ("scroll [%d, %d] by %d", start, end, shift));
232
234
#if !defined(SCROLLDEBUG) && !defined(HASHDEBUG)
233
if (_nc_scrolln(shift, start, end, screen_lines - 1) == ERR) {
235
if (NCURSES_SP_NAME(_nc_scrolln) (NCURSES_SP_ARGx
239
screen_lines(SP_PARM) - 1) == ERR) {
234
240
TR(TRACE_UPDATE | TRACE_MOVE, ("unable to scroll"));
240
246
/* pass 2 - from bottom to top scrolling down */
241
for (i = screen_lines - 1; i >= 0;) {
242
while (i >= 0 && (OLDNUM(i) == _NEWINDEX || OLDNUM(i) >= i))
247
for (i = screen_lines(SP_PARM) - 1; i >= 0;) {
249
&& (OLDNUM(SP_PARM, i) == _NEWINDEX
250
|| OLDNUM(SP_PARM, i) >= i)) {
247
shift = OLDNUM(i) - i; /* shift < 0 */
256
shift = OLDNUM(SP_PARM, i) - i; /* shift < 0 */
251
while (i >= 0 && OLDNUM(i) != _NEWINDEX && OLDNUM(i) - i == shift)
261
&& OLDNUM(SP_PARM, i) != _NEWINDEX
262
&& OLDNUM(SP_PARM, i) - i == shift) {
253
265
start = i + 1 - (-shift);
255
267
TR(TRACE_UPDATE | TRACE_MOVE, ("scroll [%d, %d] by %d", start, end, shift));
256
268
#if !defined(SCROLLDEBUG) && !defined(HASHDEBUG)
257
if (_nc_scrolln(shift, start, end, screen_lines - 1) == ERR) {
269
if (NCURSES_SP_NAME(_nc_scrolln) (NCURSES_SP_ARGx
273
screen_lines(SP_PARM) - 1) == ERR) {
258
274
TR(TRACE_UPDATE | TRACE_MOVE, ("unable to scroll"));
263
279
TR(TRACE_ICALLS, (T_RETURN("")));
284
_nc_scroll_optimize(void)
286
NCURSES_SP_NAME(_nc_scroll_optimize) (CURRENT_SCREEN);
266
290
#if defined(TRACE) || defined(SCROLLDEBUG) || defined(HASHDEBUG)
267
291
NCURSES_EXPORT(void)
292
NCURSES_SP_NAME(_nc_linedump) (NCURSES_SP_DCL0)
269
293
/* dump the state of the real and virtual oldnum fields */
273
size_t want = (screen_lines + 1) * 4;
297
size_t want = (screen_lines(SP_PARM) + 1) * 4;
275
299
if ((buf = typeMalloc(char, want)) != 0) {
277
301
(void) strcpy(buf, "virt");
278
for (n = 0; n < screen_lines; n++)
279
(void) sprintf(buf + strlen(buf), " %02d", OLDNUM(n));
302
for (n = 0; n < screen_lines(SP_PARM); n++)
303
(void) sprintf(buf + strlen(buf), " %02d", OLDNUM(SP_PARM, n));
280
304
TR(TRACE_UPDATE | TRACE_MOVE, (buf));
313
NCURSES_SP_NAME(_nc_linedump) (CURRENT_SCREEN);
284
317
#endif /* defined(TRACE) || defined(SCROLLDEBUG) */
286
319
#ifdef SCROLLDEBUG