From a143efde405d1a093201b7ba7cfa6d5b8140836c Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 1 Jul 2016 21:40:16 -0700 Subject: Console: provide VT100-like end-of-line print behavior. On the majority of VT100-like terminals, when you print a character in the last column, the cursor sits in a kind of "limbo", as if the cursor position were one column past the edge of the screen. Thus when a line feed is output next, the cursor is then at the start of the next line. The Win32 console write doesn't do this; the cursor position wraps to the start of the next line. If a newline is put out, it translates to an extra newline going to the next-next line. This spoils the behavior of programs which depend on the VT100 behavior. In this patch, the VT100 behavior is simulated as follows. A new flag in the dev_console structure is set when a character is output to the last column. This flag is then observed in order to discard a newline (or rather any character which is mapped mapped to the DWN action). * winsup/cygwin/fhandler.h (class dev_console): New boolean data member, eat_newline. This indicates that if a character is output which moves down to the next line, it should be discarded rather than sent to the console. * winsup/cygwin/fhandler_console.cc (fhandler_console::write_normal): Set the eat_newline flag if the text output ends up at column zero. Honor the eat_newline flag when processing a DWN character, and clear it when processing certain other control characters. --- winsup/cygwin/fhandler.h | 1 + winsup/cygwin/fhandler_console.cc | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index cd73e6e87..6deae969e 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1307,6 +1307,7 @@ class dev_console bool iso_2022_G1; bool alternate_charset_active; bool metabit; + bool eat_newline; char backspace_keycode; char my_title_buf [TITLESIZE + 1]; diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 2a978e746..e3d6f606b 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -2104,6 +2104,18 @@ do_print: if (len >= CONVERT_LIMIT) return found + trunc_buf.len; } + + /* If we output something and now x is at the left + * column, it means that we just output to the last column. + * In this case we can pretend we are still in the original + * line and swallow the next character if it is a newline, + * or a newline followed by a carriage return. + */ + { + int x, y; + cursor_get (&x, &y); + con.eat_newline = (x == 0); + } /* If there's still something in the src buffer, but it's not a truncated multibyte sequence, then we stumbled over a control character or an invalid multibyte sequence. Print it. */ @@ -2126,6 +2138,12 @@ do_print: break; case DWN: cursor_get (&x, &y); + + if (con.eat_newline) { + con.eat_newline = false; + break; + } + if (y >= srBottom) { if (y >= con.b.srWindow.Bottom && !con.scroll_region.Top) @@ -2140,8 +2158,10 @@ do_print: break; case BAK: cursor_rel (-1, 0); + con.eat_newline = false; break; case IGN: + con.eat_newline = false; cursor_rel (1, 0); break; case CR: @@ -2170,10 +2190,12 @@ do_print: } break; case TAB: + con.eat_newline = false; cursor_get (&x, &y); cursor_set (false, 8 * (x / 8 + 1), y); break; case NOR: + con.eat_newline = false; write_replacement_char (); break; } -- cgit v1.2.3