summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-07-01 21:40:16 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-07-26 21:52:22 -0700
commit28402bd4de6a1f46eec0d3519d9cb2eb63d59a5b (patch)
treede3f1d5f30122186b4afa67ef14817093d7b9a32
parent5bd0a181871a99960ecf96e821dab6de4aa2136f (diff)
downloadcygnal-28402bd4de6a1f46eec0d3519d9cb2eb63d59a5b.tar.gz
cygnal-28402bd4de6a1f46eec0d3519d9cb2eb63d59a5b.tar.bz2
cygnal-28402bd4de6a1f46eec0d3519d9cb2eb63d59a5b.zip
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.
-rw-r--r--winsup/cygwin/fhandler.h1
-rw-r--r--winsup/cygwin/fhandler_console.cc23
2 files changed, 24 insertions, 0 deletions
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 4da35b7f5..53798d047 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2020,6 +2020,7 @@ class dev_console
bool iso_2022_G1;
bool alternate_charset_active;
bool metabit;
+ bool eat_newline;
char backspace_keycode;
bool screen_alternated; /* For xterm compatible mode only */
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index 0b33a1370..815b952e6 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -2971,6 +2971,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. */
@@ -2994,6 +3006,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)
@@ -3009,11 +3027,14 @@ do_print:
break;
case BAK:
cursor_rel (-1, 0);
+ con.eat_newline = false;
break;
case IGN:
/* Up to release 3.1.3 we called cursor_rel (1, 0); to move the cursor
one step to the right. However, that neither matches the terminfo
for the cygwin terminal, nor the one for the xterm terminal. */
+ con.eat_newline = false;
+ cursor_rel (1, 0);
break;
case CR:
cursor_get (&x, &y);
@@ -3041,10 +3062,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;
}