conhost: Fix line wrapping around when ENABLE_VIRTUAL_TERMINAL_PROCESSING is set.
Remember the fact we completed the entire line but normalize the cursor otherwise. A newline is delayed so it wraps when writing a new character if the cursor is outside the width. Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com> Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
85c4adc80b
commit
8d076bc5e4
|
@ -195,13 +195,21 @@ static void set_tty_cursor( struct console *console, unsigned int x, unsigned in
|
|||
else if (!x && y == console->tty_cursor_y) strcpy( buf, "\r" );
|
||||
else if (y == console->tty_cursor_y)
|
||||
{
|
||||
if (console->is_unix && console->tty_cursor_x >= console->active->width)
|
||||
if (console->tty_cursor_x >= console->active->width)
|
||||
{
|
||||
/* Unix will usually have the cursor at width-1 in this case. instead of depending
|
||||
* on the exact behaviour, move the cursor to the first column and move forward
|
||||
* from threre. */
|
||||
tty_write( console, "\r", 1 );
|
||||
console->tty_cursor_x = 0;
|
||||
if (console->is_unix)
|
||||
{
|
||||
/* Unix will usually have the cursor at width-1 in this case. instead of depending
|
||||
* on the exact behaviour, move the cursor to the first column and move forward
|
||||
* from there. */
|
||||
tty_write( console, "\r", 1 );
|
||||
console->tty_cursor_x = 0;
|
||||
}
|
||||
else if (console->active->mode & ENABLE_WRAP_AT_EOL_OUTPUT)
|
||||
{
|
||||
console->tty_cursor_x--;
|
||||
}
|
||||
if (console->tty_cursor_x == x) return;
|
||||
}
|
||||
if (x + 1 == console->tty_cursor_x) strcpy( buf, "\b" );
|
||||
else if (x > console->tty_cursor_x) sprintf( buf, "\x1b[%uC", x - console->tty_cursor_x );
|
||||
|
@ -278,7 +286,7 @@ static void tty_sync( struct console *console )
|
|||
|
||||
if (console->active->cursor_visible)
|
||||
{
|
||||
set_tty_cursor( console, console->active->cursor_x, console->active->cursor_y );
|
||||
set_tty_cursor( console, get_bounded_cursor_x( console->active ), console->active->cursor_y );
|
||||
if (!console->tty_cursor_visible)
|
||||
{
|
||||
tty_write( console, "\x1b[?25h", 6 ); /* show cursor */
|
||||
|
@ -305,13 +313,14 @@ static void init_tty_output( struct console *console )
|
|||
|
||||
static void scroll_to_cursor( struct screen_buffer *screen_buffer )
|
||||
{
|
||||
unsigned int cursor_x = get_bounded_cursor_x( screen_buffer );
|
||||
int w = screen_buffer->win.right - screen_buffer->win.left + 1;
|
||||
int h = screen_buffer->win.bottom - screen_buffer->win.top + 1;
|
||||
|
||||
if (screen_buffer->cursor_x < screen_buffer->win.left)
|
||||
screen_buffer->win.left = min( screen_buffer->cursor_x, screen_buffer->width - w );
|
||||
else if (screen_buffer->cursor_x > screen_buffer->win.right)
|
||||
screen_buffer->win.left = max( screen_buffer->cursor_x, w ) - w + 1;
|
||||
if (cursor_x < screen_buffer->win.left)
|
||||
screen_buffer->win.left = min( cursor_x, screen_buffer->width - w );
|
||||
else if (cursor_x > screen_buffer->win.right)
|
||||
screen_buffer->win.left = max( cursor_x, w ) - w + 1;
|
||||
screen_buffer->win.right = screen_buffer->win.left + w - 1;
|
||||
|
||||
if (screen_buffer->cursor_y < screen_buffer->win.top)
|
||||
|
@ -1716,7 +1725,7 @@ static NTSTATUS get_output_info( struct screen_buffer *screen_buffer, size_t *ou
|
|||
|
||||
info->cursor_size = screen_buffer->cursor_size;
|
||||
info->cursor_visible = screen_buffer->cursor_visible;
|
||||
info->cursor_x = screen_buffer->cursor_x;
|
||||
info->cursor_x = get_bounded_cursor_x( screen_buffer );
|
||||
info->cursor_y = screen_buffer->cursor_y;
|
||||
info->width = screen_buffer->width;
|
||||
info->height = screen_buffer->height;
|
||||
|
@ -1917,10 +1926,12 @@ static NTSTATUS write_console( struct screen_buffer *screen_buffer, const WCHAR
|
|||
switch (buffer[i])
|
||||
{
|
||||
case '\b':
|
||||
screen_buffer->cursor_x = get_bounded_cursor_x( screen_buffer );
|
||||
if (screen_buffer->cursor_x) screen_buffer->cursor_x--;
|
||||
continue;
|
||||
case '\t':
|
||||
j = min( screen_buffer->width - screen_buffer->cursor_x, 8 - (screen_buffer->cursor_x % 8) );
|
||||
if (!j) j = 8;
|
||||
while (j--) write_char( screen_buffer, ' ', &update_rect, NULL );
|
||||
continue;
|
||||
case '\n':
|
||||
|
@ -1956,7 +1967,6 @@ static NTSTATUS write_console( struct screen_buffer *screen_buffer, const WCHAR
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -145,6 +145,11 @@ static inline void empty_update_rect( struct screen_buffer *screen_buffer, RECT
|
|||
SetRect( rect, screen_buffer->width, screen_buffer->height, 0, 0 );
|
||||
}
|
||||
|
||||
static inline unsigned int get_bounded_cursor_x( struct screen_buffer *screen_buffer )
|
||||
{
|
||||
return min( screen_buffer->cursor_x, screen_buffer->width - 1 );
|
||||
}
|
||||
|
||||
#endif /* RC_INVOKED */
|
||||
|
||||
/* strings */
|
||||
|
|
|
@ -654,7 +654,7 @@ static void test_write_console(void)
|
|||
child_string_request(REQ_WRITE_CONSOLE, L"xy");
|
||||
skip_hide_cursor();
|
||||
expect_output_sequence("xy");
|
||||
if (!skip_sequence("\b")) expect_output_sequence("\r\n");
|
||||
if (!skip_sequence("\b")) skip_sequence("\r\n");
|
||||
skip_sequence("\x1b[?25h"); /* show cursor */
|
||||
expect_empty_output();
|
||||
|
||||
|
@ -712,10 +712,9 @@ static void test_write_console(void)
|
|||
expect_output_sequence("XY");
|
||||
skip_sequence("\x1b[40;29H"); /* set cursor */
|
||||
if (skip_sequence("\x1b[?25h")) /* show cursor */
|
||||
expect_output_sequence("\x1b[?25l"); /* hide cursor */
|
||||
if (!skip_sequence("\b"))
|
||||
skip_sequence("\x1b[?25l"); /* hide cursor */
|
||||
if (!skip_sequence("\b") && skip_sequence("\r\n"))
|
||||
{
|
||||
expect_output_sequence("\r\n");
|
||||
expect_output_sequence("\x1b[30X"); /* erase the line */
|
||||
expect_output_sequence("\x1b[30C"); /* move cursor to the end of the line */
|
||||
expect_output_sequence("\r"); /* set cursor */
|
||||
|
@ -783,6 +782,79 @@ static void test_write_console(void)
|
|||
skip_sequence("\x1b[?25h"); /* show cursor */
|
||||
expect_empty_output();
|
||||
|
||||
child_set_output_mode(ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
||||
|
||||
child_set_cursor(28, 12);
|
||||
skip_hide_cursor();
|
||||
expect_output_sequence("\x1b[28C"); /* move cursor to the end of the line */
|
||||
skip_sequence("\x1b[?25h"); /* show cursor */
|
||||
expect_empty_output();
|
||||
|
||||
child_string_request(REQ_WRITE_CONSOLE, L"ab");
|
||||
skip_hide_cursor();
|
||||
expect_output_sequence("ab");
|
||||
skip_sequence("\b");
|
||||
skip_sequence("\x1b[?25h"); /* show cursor */
|
||||
expect_empty_output();
|
||||
test_cursor_pos(29, 12);
|
||||
|
||||
child_string_request(REQ_WRITE_CONSOLE, L"c");
|
||||
skip_hide_cursor();
|
||||
expect_output_sequence("\r\n");
|
||||
expect_output_sequence("c");
|
||||
skip_sequence("\x1b[?25h"); /* show cursor */
|
||||
expect_empty_output();
|
||||
test_cursor_pos(1, 13);
|
||||
|
||||
child_set_cursor(28, 14);
|
||||
skip_hide_cursor();
|
||||
expect_output_sequence("\x1b[15;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, 14);
|
||||
|
||||
child_string_request(REQ_WRITE_CONSOLE, L"y");
|
||||
skip_hide_cursor();
|
||||
expect_output_sequence("y");
|
||||
skip_sequence("\x1b[?25h"); /* show cursor */
|
||||
expect_empty_output();
|
||||
test_cursor_pos(29, 14);
|
||||
|
||||
child_string_request(REQ_WRITE_CONSOLE, L"\b");
|
||||
skip_hide_cursor();
|
||||
expect_output_sequence("\b");
|
||||
skip_sequence("\x1b[?25h"); /* show cursor */
|
||||
expect_empty_output();
|
||||
test_cursor_pos(28, 14);
|
||||
|
||||
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(29, 14);
|
||||
|
||||
child_string_request(REQ_WRITE_CONSOLE, L"w");
|
||||
skip_hide_cursor();
|
||||
expect_output_sequence("w");
|
||||
skip_sequence("\x1b[?25h"); /* show cursor */
|
||||
expect_empty_output();
|
||||
test_cursor_pos(29, 14);
|
||||
|
||||
child_string_request(REQ_WRITE_CONSOLE, L"X");
|
||||
skip_hide_cursor();
|
||||
expect_output_sequence("\r\n");
|
||||
expect_output_sequence("X");
|
||||
skip_sequence("\x1b[?25h"); /* show cursor */
|
||||
expect_empty_output();
|
||||
test_cursor_pos(1, 15);
|
||||
|
||||
child_set_output_mode(ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT);
|
||||
|
||||
child_set_cursor(28, 20);
|
||||
|
|
|
@ -430,7 +430,7 @@ static void update_window_cursor( struct console *console )
|
|||
{
|
||||
if (console->win != GetFocus() || !console->active->cursor_visible) return;
|
||||
|
||||
SetCaretPos( (console->active->cursor_x - console->active->win.left) * console->active->font.width,
|
||||
SetCaretPos( (get_bounded_cursor_x( console->active ) - console->active->win.left) * console->active->font.width,
|
||||
(console->active->cursor_y - console->active->win.top) * console->active->font.height );
|
||||
ShowCaret( console->win );
|
||||
}
|
||||
|
@ -607,10 +607,10 @@ static void update_window( struct console *console )
|
|||
}
|
||||
}
|
||||
|
||||
if (update_all || console->active->cursor_x != console->window->cursor_pos.X ||
|
||||
if (update_all || get_bounded_cursor_x( console->active ) != console->window->cursor_pos.X ||
|
||||
console->active->cursor_y != console->window->cursor_pos.Y)
|
||||
{
|
||||
console->window->cursor_pos.X = console->active->cursor_x;
|
||||
console->window->cursor_pos.X = get_bounded_cursor_x( console->active );
|
||||
console->window->cursor_pos.Y = console->active->cursor_y;
|
||||
update_window_cursor( console );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue