diff options
-rw-r--r-- | winsup/cygwin/fhandler.h | 2 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_console.cc | 77 |
2 files changed, 23 insertions, 56 deletions
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index b52761a2e..e9d854987 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -2063,7 +2063,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 e8b2f61bf..080d853a7 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -1585,63 +1585,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.UnicodeChar = L' '; - 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; } @@ -1673,8 +1621,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 |