summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/fhandler.h2
-rw-r--r--winsup/cygwin/fhandler_console.cc77
2 files changed, 23 insertions, 56 deletions
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 6deae969e..86c62d698 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -1362,7 +1362,7 @@ class dev_console
int set_cl_x (cltype);
int set_cl_y (cltype);
bool fillin (HANDLE);
- bool __reg3 scroll_window (HANDLE, int, int, int, int);
+ bool __reg3 clear_should_scroll (HANDLE, int, int, int, int);
void __reg3 scroll_buffer (HANDLE, int, int, int, int, int, int);
void __reg3 clear_screen (HANDLE, int, int, int, int);
void __reg3 save_restore (HANDLE, char);
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index 72e85320a..25f2494d7 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -1199,63 +1199,11 @@ dev_console::set_cl_y (cltype y)
}
bool
-dev_console::scroll_window (HANDLE h, int x1, int y1, int x2, int y2)
+dev_console::clear_should_scroll (HANDLE h, int x1, int y1, int x2, int y2)
{
if (save_buf || x1 != 0 || x2 != dwWinSize.X - 1 || y1 != b.srWindow.Top
|| y2 != b.srWindow.Bottom || b.dwSize.Y <= dwWinSize.Y)
return false;
-
- SMALL_RECT sr;
- int toscroll = dwEnd.Y - b.srWindow.Top + 1;
- sr.Left = sr.Right = dwEnd.X = 0;
-
- if (b.srWindow.Bottom + toscroll >= b.dwSize.Y)
- {
- /* So we're at the end of the buffer and scrolling the console window
- 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
- becomes the last line just prior to the first window line. That
- 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;
- 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
- {
- /* The reminder of the console buffer is big enough to simply move
- the console window. We have to set the cursor first, otherwise
- the scroll bars will not be corrected. */
- SetConsoleCursorPosition (h, dwEnd);
- /* If we scroll backwards, setting the cursor position will scroll
- the console window up so that the cursor is at the bottom. Correct
- the action by moving the window down again so the cursor is one line
- above the new window position. */
- if (toscroll < 0)
- toscroll = b.srWindow.Bottom - b.srWindow.Top;
- /* Move the window accordingly. */
- sr.Top = sr.Bottom = toscroll;
- SetConsoleWindowInfo (h, FALSE, &sr);
- }
- /* Eventually set cursor to new end position at the top of the window. */
- dwEnd.Y++;
- SetConsoleCursorPosition (h, dwEnd);
- /* Fix up console buffer info. */
- fillin (h);
return true;
}
@@ -1287,8 +1235,27 @@ fhandler_console::clear_screen (cltype xc1, cltype yc1, cltype xc2, cltype yc2)
/* Detect special case - scroll the screen if we have a buffer in order to
preserve the buffer. */
- if (!con.scroll_window (h, x1, y1, x2, y2))
- con.clear_screen (h, x1, y1, x2, y2);
+ if (!con.clear_should_scroll (h, x1, y1, x2, y2))
+ {
+ con.clear_screen (h, x1, y1, x2, y2);
+ return;
+ }
+
+ int xpos, ypos;
+ DWORD done;
+ cursor_get(&xpos, &ypos);
+ cursor_set(false, 0, con.b.dwSize.Y - 1);
+
+ for (int i = 0; i < con.dwWinSize.Y; i += done)
+ {
+ if (!WriteConsoleW (h, L"\n", 1, &done, 0))
+ {
+ __seterrno ();
+ break;
+ }
+ }
+
+ cursor_set(false, xpos, ypos);
}
void __reg3