Fix buffer scrolling when performing a "clear screen"

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2016-07-27 20:39:24 +02:00
parent 32b668d966
commit 08da3bfc41
1 changed files with 35 additions and 19 deletions

View File

@ -1216,30 +1216,46 @@ dev_console::scroll_window (HANDLE h, int x1, int y1, int x2, int y2)
return false; return false;
SMALL_RECT sr; SMALL_RECT sr;
int toscroll = 2 + dwEnd.Y - b.srWindow.Top; int toscroll = dwEnd.Y - b.srWindow.Top + 1;
int shrink = 1 + toscroll + b.srWindow.Bottom - b.dwSize.Y;
sr.Left = sr.Right = dwEnd.X = 0; sr.Left = sr.Right = dwEnd.X = 0;
/* Can't increment dwEnd yet since we may not have space in
the buffer. */ if (b.srWindow.Bottom + toscroll >= b.dwSize.Y)
SetConsoleCursorPosition (h, dwEnd);
if (shrink > 0)
{ {
COORD c = b.dwSize; /* So we're at the end of the buffer and scrolling the console window
c.Y = dwEnd.Y - shrink; would move us beyond the buffer. What we do here is to scroll the
SetConsoleScreenBufferSize (h, c); console buffer upward by just as much so that the current last line
SetConsoleScreenBufferSize (h, b.dwSize); becomes the last line just prior to the first window line. That
dwEnd.Y = 0; keeps the end of the console buffer intact, as desired.
fillin (h);
toscroll = 2 + dwEnd.Y - b.srWindow.Top; Since we're moving the console buffer under the console window in
this case, we must not move the console window. */
SMALL_RECT br;
COORD dest;
CHAR_INFO fill;
br.Left = 0;
br.Top = dwEnd.Y - b.srWindow.Top + 1;
br.Right = b.dwSize.X - 1;
br.Bottom = b.dwSize.Y - 1;
dest.X = dest.Y = 0;
fill.Char.AsciiChar = ' ';
fill.Attributes = current_win32_attr;
ScrollConsoleScreenBuffer (h, &br, NULL, dest, &fill);
/* Fix dwEnd to reflect the new cursor line (minus 1 to take the
increment a few lines later into account) */
dwEnd.Y = b.dwCursorPosition.Y - 1;
} }
else
sr.Top = sr.Bottom = toscroll; {
/* The reminder of the console buffer is big enough to simply move
SetConsoleWindowInfo (h, FALSE, &sr); the console window. */
sr.Top = sr.Bottom = toscroll;
SetConsoleWindowInfo (h, FALSE, &sr);
}
/* Eventually set cursor to new end position at the top of the window. */
dwEnd.Y++; dwEnd.Y++;
SetConsoleCursorPosition (h, dwEnd); SetConsoleCursorPosition (h, dwEnd);
/* Fix up console buffer info. */
fillin (h); fillin (h);
return true; return true;
} }