[PATCH v5 2/3] conhost: Wrap around immediately if ENABLE_VIRTUAL_TERMINAL_PROCESSING is not set.

Gabriel Ivăncescu gabrielopcode at gmail.com
Sat Apr 3 08:12:30 CDT 2021


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
 programs/conhost/conhost.c   | 11 ++++-
 programs/conhost/tests/tty.c | 80 ++++++++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c
index 54ead48..7cd36e2 100644
--- a/programs/conhost/conhost.c
+++ b/programs/conhost/conhost.c
@@ -1948,7 +1948,16 @@ static NTSTATUS write_console( struct screen_buffer *screen_buffer, const WCHAR
 
     if (screen_buffer->cursor_x == screen_buffer->width)
     {
-        if (screen_buffer->mode & ENABLE_WRAP_AT_EOL_OUTPUT) screen_buffer->cursor_x--;
+        if (screen_buffer->mode & ENABLE_WRAP_AT_EOL_OUTPUT)
+        {
+            if (!(screen_buffer->mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING))
+            {
+                screen_buffer->cursor_x = 0;
+                if (++screen_buffer->cursor_y == screen_buffer->height)
+                    new_line( screen_buffer, &update_rect );
+            }
+            else screen_buffer->cursor_x--;
+        }
         else screen_buffer->cursor_x = update_rect.left;
     }
 
diff --git a/programs/conhost/tests/tty.c b/programs/conhost/tests/tty.c
index 7cc37fa..122e8a9 100644
--- a/programs/conhost/tests/tty.c
+++ b/programs/conhost/tests/tty.c
@@ -149,6 +149,7 @@ enum req_type
     REQ_CREATE_SCREEN_BUFFER,
     REQ_FILL_CHAR,
     REQ_GET_INPUT,
+    REQ_GET_SB_INFO,
     REQ_READ_CONSOLE,
     REQ_READ_CONSOLE_A,
     REQ_READ_CONSOLE_FILE,
@@ -551,6 +552,26 @@ static void expect_char_key_(unsigned int line, WCHAR ch)
     expect_key_pressed_(line, ch, ch, vk, ctrl);
 }
 
+#define test_cursor_pos(a,b) _test_cursor_pos(__LINE__,a,b)
+static void _test_cursor_pos(unsigned line, int expect_x, int expect_y)
+{
+    struct pseudoconsole_req req = { REQ_GET_SB_INFO };
+    CONSOLE_SCREEN_BUFFER_INFO info;
+    DWORD read;
+    BOOL ret;
+
+    ret = WriteFile(child_pipe, &req, sizeof(req), &read, NULL);
+    ok(ret, "WriteFile failed: %u\n", GetLastError());
+
+    ret = ReadFile(child_pipe, &info, sizeof(info), &read, NULL);
+    ok(ret, "ReadFile failed: %u\n", GetLastError());
+
+    ok_(__FILE__,line)(info.dwCursorPosition.X == expect_x, "dwCursorPosition.X = %u, expected %u\n",
+                       info.dwCursorPosition.X, expect_x);
+    ok_(__FILE__,line)(info.dwCursorPosition.Y == expect_y, "dwCursorPosition.Y = %u, expected %u\n",
+                       info.dwCursorPosition.Y, expect_y);
+}
+
 static void test_write_console(void)
 {
     child_string_request(REQ_WRITE_CONSOLE, L"abc");
@@ -761,6 +782,55 @@ static void test_write_console(void)
     expect_empty_output();
 
     child_set_output_mode(ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT);
+
+    child_set_cursor(28, 20);
+    skip_hide_cursor();
+    expect_output_sequence("\x1b[21;29H");    /* set cursor */
+    skip_sequence("\x1b[?25h");               /* show cursor */
+    expect_empty_output();
+
+    child_string_request(REQ_WRITE_CONSOLE, L"ab");
+    skip_hide_cursor();
+    expect_output_sequence("ab");
+    expect_output_sequence("\r\n");
+    skip_sequence("\x1b[?25h");               /* show cursor */
+    expect_empty_output();
+    test_cursor_pos(0, 21);
+
+    child_string_request(REQ_WRITE_CONSOLE, L"c");
+    skip_hide_cursor();
+    expect_output_sequence("c");
+    skip_sequence("\x1b[?25h");               /* show cursor */
+    expect_empty_output();
+    test_cursor_pos(1, 21);
+
+    child_set_cursor(28, 22);
+    skip_hide_cursor();
+    expect_output_sequence("\x1b[23;29H");    /* set cursor */
+    skip_sequence("\x1b[?25h");               /* show cursor */
+    expect_empty_output();
+
+    child_string_request(REQ_WRITE_CONSOLE, L"x");
+    skip_hide_cursor();
+    expect_output_sequence("x");
+    skip_sequence("\x1b[?25h");               /* show cursor */
+    expect_empty_output();
+    test_cursor_pos(29, 22);
+
+    child_string_request(REQ_WRITE_CONSOLE, L"y");
+    skip_hide_cursor();
+    expect_output_sequence("y");
+    expect_output_sequence("\r\n");
+    skip_sequence("\x1b[?25h");               /* show cursor */
+    expect_empty_output();
+    test_cursor_pos(0, 23);
+
+    child_string_request(REQ_WRITE_CONSOLE, L"z");
+    skip_hide_cursor();
+    expect_output_sequence("z");
+    skip_sequence("\x1b[?25h");               /* show cursor */
+    expect_empty_output();
+    test_cursor_pos(1, 23);
 }
 
 static void test_tty_output(void)
@@ -1300,6 +1370,16 @@ static void child_process(HANDLE pipe)
                 break;
             }
 
+        case REQ_GET_SB_INFO:
+            {
+                CONSOLE_SCREEN_BUFFER_INFO info;
+                ret = GetConsoleScreenBufferInfo(output, &info);
+                ok(ret, "GetConsoleScreenBufferInfo failed: %u\n", GetLastError());
+                ret = WriteFile(pipe, &info, sizeof(info), &count, NULL);
+                ok(ret, "WriteFile failed: %u\n", GetLastError());
+                break;
+            }
+
         case REQ_READ_CONSOLE:
             ret = ReadConsoleW(input, buf, req->u.size, &count, NULL );
             ok(ret, "ReadConsoleW failed: %u\n", GetLastError());
-- 
2.30.0




More information about the wine-devel mailing list