Fix console clear screen if buffer is full

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2016-08-03 14:34:01 +02:00
parent 05847ad6e9
commit 99a3f266c1
1 changed files with 22 additions and 13 deletions

View File

@ -1225,38 +1225,47 @@ dev_console::scroll_window (HANDLE h, int x1, int y1, int x2, int y2)
would move us beyond the buffer. What we do here is to scroll the would move us beyond the buffer. What we do here is to scroll the
console buffer upward by just as much so that the current last line console buffer upward by just as much so that the current last line
becomes the last line just prior to the first window line. That becomes the last line just prior to the first window line. That
keeps the end of the console buffer intact, as desired. keeps the end of the console buffer intact, as desired. */
Since we're moving the console buffer under the console window in
this case, we must not move the console window. */
SMALL_RECT br; SMALL_RECT br;
COORD dest; COORD dest;
CHAR_INFO fill; CHAR_INFO fill;
br.Left = 0; br.Left = 0;
br.Top = dwEnd.Y - b.srWindow.Top + 1; br.Top = (b.srWindow.Bottom - b.srWindow.Top) + 1
- (b.dwSize.Y - dwEnd.Y - 1);
br.Right = b.dwSize.X - 1; br.Right = b.dwSize.X - 1;
br.Bottom = b.dwSize.Y - 1; br.Bottom = b.dwSize.Y - 1;
dest.X = dest.Y = 0; dest.X = dest.Y = 0;
fill.Char.AsciiChar = ' '; fill.Char.AsciiChar = ' ';
fill.Attributes = current_win32_attr; fill.Attributes = current_win32_attr;
ScrollConsoleScreenBuffer (h, &br, NULL, dest, &fill); ScrollConsoleScreenBuffer (h, &br, NULL, dest, &fill);
/* Fix dwEnd to reflect the new cursor line (minus 1 to take the /* Since we're moving the console buffer under the console window
increment a few lines later into account) */ we only have to move the console window if the user scrolled the
dwEnd.Y = b.dwCursorPosition.Y - 1; window upwards. The number of lines is the distance to the
buffer bottom. */
toscroll = b.dwSize.Y - b.srWindow.Bottom - 1;
/* Fix dwEnd to reflect the new cursor line. Take the above scrolling
into account and subtract 1 to account for the increment below. */
dwEnd.Y = b.dwCursorPosition.Y + toscroll - 1;
} }
else if (toscroll)
{ {
/* FIXME: For some reason SetConsoleWindowInfo does not correctly
set the scrollbars. Calling SetConsoleCursorPosition here is
just a workaround which doesn't cover all cases. In some scenarios
the scrollbars are still off by one console window size. */
/* The reminder of the console buffer is big enough to simply move /* The reminder of the console buffer is big enough to simply move
the console window. We have to set the cursor first, otherwise the console window. We have to set the cursor first, otherwise
the scroll bars will not be corrected. */ the scroll bars will not be corrected. */
SetConsoleCursorPosition (h, dwEnd); SetConsoleCursorPosition (h, dwEnd);
/* If we scroll backwards, setting the cursor position will scroll /* If the user scolled manually, setting the cursor position might scroll
the console window up so that the cursor is at the bottom. Correct the console window so that the cursor is not at the top. Correct
the action by moving the window down again so the cursor is one line the action by moving the window down again so the cursor is one line
above the new window position. */ above the new window position. */
if (toscroll < 0) GetConsoleScreenBufferInfo (h, &b);
toscroll = b.srWindow.Bottom - b.srWindow.Top; if (b.dwCursorPosition.Y >= b.srWindow.Top)
toscroll = b.dwCursorPosition.Y - b.srWindow.Top + 1;
/* Move the window accordingly. */ /* Move the window accordingly. */
sr.Top = sr.Bottom = toscroll; sr.Top = sr.Bottom = toscroll;
SetConsoleWindowInfo (h, FALSE, &sr); SetConsoleWindowInfo (h, FALSE, &sr);