public inbox for cygwin-cvs@sourceware.org
help / color / mirror / Atom feed
From: Corinna Vinschen <corinna@sourceware.org>
To: cygwin-cvs@sourceware.org
Subject: [newlib-cygwin] Cygwin: pty: Avoid screen distortion on slave read.
Date: Mon, 10 Feb 2020 10:04:00 -0000	[thread overview]
Message-ID: <20200210100435.118563.qmail@sourceware.org> (raw)

https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=b0474b704aa0b0924da9b28d6310ccc1a55de675

commit b0474b704aa0b0924da9b28d6310ccc1a55de675
Author: Takashi Yano <takashi.yano@nifty.ne.jp>
Date:   Sun Feb 9 23:46:01 2020 +0900

    Cygwin: pty: Avoid screen distortion on slave read.
    
    - Echo back print is distorted when the cygwin program which calls
      Win32 console API directly calls slave read(). This patch fixes
      the issue.

Diff:
---
 winsup/cygwin/fhandler.h      |  3 ++-
 winsup/cygwin/fhandler_tty.cc | 51 +++++++++++++++++++++++++------------------
 2 files changed, 32 insertions(+), 22 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 53b6c2c..a22f3a1 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2206,7 +2206,7 @@ class fhandler_pty_slave: public fhandler_pty_common
   }
   void set_switch_to_pcon (int fd);
   void reset_switch_to_pcon (void);
-  void push_to_pcon_screenbuffer (const char *ptr, size_t len);
+  void push_to_pcon_screenbuffer (const char *ptr, size_t len, bool is_echo);
   void mask_switch_to_pcon_in (bool mask);
   void fixup_after_attach (bool native_maybe, int fd);
   bool is_line_input (void)
@@ -2215,6 +2215,7 @@ class fhandler_pty_slave: public fhandler_pty_common
   }
   void setup_locale (void);
   void set_freeconsole_on_close (bool val);
+  void trigger_redraw_screen (void);
   void wait_pcon_fwd (void);
 };
 
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index a92bcfc..f883827 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -80,7 +80,13 @@ set_switch_to_pcon (void)
 	fhandler_base *fh = cfd;
 	fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
 	if (ptys->get_pseudo_console ())
-	  ptys->set_switch_to_pcon (fd);
+	  {
+	    ptys->set_switch_to_pcon (fd);
+	    ptys->trigger_redraw_screen ();
+	    DWORD mode =
+	      ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT;
+	    SetConsoleMode (ptys->get_handle (), mode);
+	  }
       }
 }
 
@@ -1097,9 +1103,6 @@ fhandler_pty_slave::set_switch_to_pcon (int fd_set)
 	if (!try_reattach_pcon ())
 	  goto skip_console_setting;
       FlushConsoleInputBuffer (get_handle ());
-      DWORD mode;
-      mode = ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT;
-      SetConsoleMode (get_handle (), mode);
 skip_console_setting:
       restore_reattach_pcon ();
       if (get_ttyp ()->pcon_pid == 0 ||
@@ -1160,7 +1163,8 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
 }
 
 void
-fhandler_pty_slave::push_to_pcon_screenbuffer (const char *ptr, size_t len)
+fhandler_pty_slave::push_to_pcon_screenbuffer (const char *ptr, size_t len,
+					       bool is_echo)
 {
   bool attached =
     !!fhandler_console::get_console_process_id (get_helper_process_id (), true);
@@ -1231,7 +1235,7 @@ fhandler_pty_slave::push_to_pcon_screenbuffer (const char *ptr, size_t len)
     }
   if (!nlen) /* Nothing to be synchronized */
     goto cleanup;
-  if (get_ttyp ()->switch_to_pcon_out)
+  if (get_ttyp ()->switch_to_pcon_out && !is_echo)
     goto cleanup;
   /* Remove ESC sequence which returns results to console
      input buffer. Without this, cursor position report
@@ -1388,7 +1392,7 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
   if (get_pseudo_console ())
     {
       acquire_output_mutex (INFINITE);
-      push_to_pcon_screenbuffer ((char *)ptr, len);
+      push_to_pcon_screenbuffer ((char *)ptr, len, false);
       release_output_mutex ();
     }
 
@@ -1716,7 +1720,9 @@ out:
   if (get_pseudo_console () && ptr0 && (get_ttyp ()->ti.c_lflag & ECHO))
     {
       acquire_output_mutex (INFINITE);
-      push_to_pcon_screenbuffer (ptr0, len);
+      push_to_pcon_screenbuffer (ptr0, len, true);
+      if (get_ttyp ()->switch_to_pcon_out)
+	trigger_redraw_screen ();
       release_output_mutex ();
     }
   mask_switch_to_pcon_in (false);
@@ -2701,6 +2707,21 @@ fhandler_pty_slave::wait_pcon_fwd (void)
 }
 
 void
+fhandler_pty_slave::trigger_redraw_screen (void)
+{
+  /* Forcibly redraw screen based on console screen buffer. */
+  /* The following code triggers redrawing the screen. */
+  CONSOLE_SCREEN_BUFFER_INFO sbi;
+  GetConsoleScreenBufferInfo (get_output_handle (), &sbi);
+  SMALL_RECT rect = {0, 0,
+    (SHORT) (sbi.dwSize.X -1), (SHORT) (sbi.dwSize.Y - 1)};
+  COORD dest = {0, 0};
+  CHAR_INFO fill = {' ', 0};
+  ScrollConsoleScreenBuffer (get_output_handle (), &rect, NULL, dest, &fill);
+  get_ttyp ()->need_redraw_screen = false;
+}
+
+void
 fhandler_pty_slave::fixup_after_attach (bool native_maybe, int fd_set)
 {
   if (fd < 0)
@@ -2754,19 +2775,7 @@ fhandler_pty_slave::fixup_after_attach (bool native_maybe, int fd_set)
 	      get_ttyp ()->switch_to_pcon_out = true;
 
 	      if (get_ttyp ()->need_redraw_screen)
-		{
-		  /* Forcibly redraw screen based on console screen buffer. */
-		  /* The following code triggers redrawing the screen. */
-		  CONSOLE_SCREEN_BUFFER_INFO sbi;
-		  GetConsoleScreenBufferInfo (get_output_handle (), &sbi);
-		  SMALL_RECT rect = {0, 0,
-		    (SHORT) (sbi.dwSize.X -1), (SHORT) (sbi.dwSize.Y - 1)};
-		  COORD dest = {0, 0};
-		  CHAR_INFO fill = {' ', 0};
-		  ScrollConsoleScreenBuffer (get_output_handle (),
-					     &rect, NULL, dest, &fill);
-		  get_ttyp ()->need_redraw_screen = false;
-		}
+		trigger_redraw_screen ();
 	    }
 	  init_console_handler (false);
 	}


                 reply	other threads:[~2020-02-10 10:04 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200210100435.118563.qmail@sourceware.org \
    --to=corinna@sourceware.org \
    --cc=cygwin-cvs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).