Module: wine Branch: master Commit: f3322891420d4d7c5a1c506a25ef4f99d21b2f8e URL: https://source.winehq.org/git/wine.git/?a=commit;h=f3322891420d4d7c5a1c506a2...
Author: Jacek Caban jacek@codeweavers.com Date: Fri Sep 4 13:51:45 2020 +0200
conhost: Update tty output in scroll_output.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
programs/conhost/conhost.c | 5 +++++ programs/conhost/tests/tty.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+)
diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c index 8f0a48c097..9edd5971b8 100644 --- a/programs/conhost/conhost.c +++ b/programs/conhost/conhost.c @@ -905,6 +905,7 @@ static NTSTATUS scroll_output( struct screen_buffer *screen_buffer, const struct int x, y, xsrc, ysrc, w, h; char_info_t *psrc, *pdst; SMALL_RECT src, dst; + RECT update_rect; SMALL_RECT clip;
xsrc = params->scroll.Left; @@ -993,6 +994,10 @@ static NTSTATUS scroll_output( struct screen_buffer *screen_buffer, const struct for (x = left; x <= right; x++) screen_buffer->data[y * screen_buffer->width + x] = params->fill; }
+ SetRect( &update_rect, min( src.Left, dst.Left ), min( src.Top, dst.Top ), + max( src.Right, dst.Right ), max( src.Bottom, dst.Bottom )); + update_output( screen_buffer, &update_rect ); + tty_sync( screen_buffer->console ); return STATUS_SUCCESS; }
diff --git a/programs/conhost/tests/tty.c b/programs/conhost/tests/tty.c index 4a0ec30875..c28928701f 100644 --- a/programs/conhost/tests/tty.c +++ b/programs/conhost/tests/tty.c @@ -146,6 +146,7 @@ static BOOL expect_erase_line_(unsigned line, unsigned int cnt) enum req_type { REQ_FILL_CHAR, + REQ_SCROLL, REQ_SET_CURSOR, REQ_SET_TITLE, REQ_WRITE_CHARACTERS, @@ -173,6 +174,12 @@ struct pseudoconsole_req CHAR_INFO buf[1]; } write_output; struct + { + SMALL_RECT rect; + COORD dst; + CHAR_INFO fill; + } scroll; + struct { WCHAR ch; DWORD count; @@ -259,6 +266,26 @@ static void child_write_output_(unsigned int line, CHAR_INFO *buf, unsigned int ok_(__FILE__,line)(region.Bottom == out_bottom, "Bottom = %u\n", region.Bottom); }
+static void child_scroll(unsigned int src_left, unsigned int src_top, unsigned int src_right, + unsigned int src_bottom, unsigned int dst_x, unsigned int dst_y, WCHAR fill) +{ + struct pseudoconsole_req req; + DWORD count; + BOOL ret; + + req.type = REQ_SCROLL; + req.u.scroll.rect.Left = src_left; + req.u.scroll.rect.Top = src_top; + req.u.scroll.rect.Right = src_right; + req.u.scroll.rect.Bottom = src_bottom; + req.u.scroll.dst.X = dst_x; + req.u.scroll.dst.Y = dst_y; + req.u.scroll.fill.Char.UnicodeChar = fill; + req.u.scroll.fill.Attributes = 0; + ret = WriteFile(child_pipe, &req, sizeof(req), &count, NULL); + ok(ret, "WriteFile failed: %u\n", GetLastError()); +} + static void child_fill_character(WCHAR ch, DWORD count, int x, int y) { struct pseudoconsole_req req; @@ -418,6 +445,18 @@ static void test_tty_output(void) expect_output_sequence("\x1b[?25h"); /* show cursor */ expect_empty_output();
+ child_scroll(/* scroll rect */ 0, 7, 2, 8, /* destination */ 2, 8, /* fill */ 'x'); + expect_hide_cursor(); + if (skip_sequence("\x1b[m")) /* default attr */ + expect_output_sequence("\x1b[30m");/* foreground black */ + expect_output_sequence("\x1b[8;1H"); /* set cursor */ + expect_output_sequence("xxx89\r\n"); + expect_output_sequence("xx567\r\n"); + expect_output_sequence("90234"); + expect_output_sequence("\x1b[4;3H"); /* set cursor */ + expect_output_sequence("\x1b[?25h"); /* show cursor */ + expect_empty_output(); + child_write_characters(L"xxx", 3, 10); expect_hide_cursor(); expect_output_sequence("\x1b[m"); /* default attributes */ @@ -513,6 +552,11 @@ static void child_process(HANDLE pipe) const struct pseudoconsole_req *req = (void *)buf; switch (req->type) { + case REQ_SCROLL: + ret = ScrollConsoleScreenBufferW(output, &req->u.scroll.rect, NULL, req->u.scroll.dst, &req->u.scroll.fill); + ok(ret, "ScrollConsoleScreenBuffer failed: %u\n", GetLastError()); + break; + case REQ_FILL_CHAR: ret = FillConsoleOutputCharacterW(output, req->u.fill.ch, req->u.fill.count, req->u.fill.coord, &count); ok(ret, "FillConsoleOutputCharacter failed: %u\n", GetLastError());