OpenConsole.exe has a bug(?) that the Ctrl-H is translated into
Ctrl-Backspace (not Backspace). This is a workaround for that issue
which pushes the Ctrl-H as a ConsoleInput event.

Signed-off-by: Takashi Yano <[email protected]>
Reviewed-by:
---
 winsup/cygwin/fhandler/pty.cc | 47 ++++++++++++++++++++++++++++++++++-
 1 file changed, 46 insertions(+), 1 deletion(-)

diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc
index 7366eea09..9a175e722 100644
--- a/winsup/cygwin/fhandler/pty.cc
+++ b/winsup/cygwin/fhandler/pty.cc
@@ -2459,8 +2459,53 @@ fhandler_pty_master::write (const void *ptr, size_t len)
            }
        }
 
+      /* OpenConsole.exe has a bug(?) that Ctrl-H is translated into
+        Ctrl-Backspace (not Backspace). The following code is a
+        workaround for that issue. */
+      char *bs_pos = (char *) memchr (buf, '\010' /* ^H */, nlen);
+      HANDLE pcon_owner = NULL;
+      HANDLE h_pcon_in = NULL;
+      DWORD resume_pid = 0;
+      if (bs_pos)
+       {
+         pcon_owner = OpenProcess (PROCESS_DUP_HANDLE, FALSE,
+                                   get_ttyp ()->nat_pipe_owner_pid);
+         DuplicateHandle (pcon_owner, get_ttyp ()->h_pcon_in,
+                          GetCurrentProcess (), &h_pcon_in,
+                          0, FALSE, DUPLICATE_SAME_ACCESS);
+         resume_pid =
+           attach_console_temporarily (get_ttyp()->nat_pipe_owner_pid);
+       }
+
       DWORD n;
-      WriteFile (to_slave_nat, buf, nlen, &n, NULL);
+      while (bs_pos)
+       {
+         if (bs_pos - buf > 0)
+           WriteFile (to_slave_nat, buf, bs_pos - buf, &n, NULL);
+         INPUT_RECORD r;
+         r.EventType = KEY_EVENT;
+         r.Event.KeyEvent.bKeyDown = 1;
+         r.Event.KeyEvent.wRepeatCount = 0;
+         r.Event.KeyEvent.wVirtualKeyCode = 0;
+         r.Event.KeyEvent.wVirtualScanCode = 0;
+         r.Event.KeyEvent.uChar.AsciiChar = '\010'; /* ^H */
+         r.Event.KeyEvent.dwControlKeyState = LEFT_CTRL_PRESSED;
+         WriteConsoleInput(h_pcon_in, &r, 1, &n);
+         r.Event.KeyEvent.bKeyDown = 0;
+         WriteConsoleInput(h_pcon_in, &r, 1, &n);
+         nlen -= bs_pos - buf + 1;
+         buf = bs_pos + 1;
+         bs_pos = (char *) memchr (buf, '\010' /* ^H */, nlen);
+       }
+      if (nlen > 0)
+       WriteFile (to_slave_nat, buf, nlen, &n, NULL);
+
+      if (resume_pid)
+       resume_from_temporarily_attach (resume_pid);
+      if (h_pcon_in)
+       CloseHandle(h_pcon_in);
+      if (pcon_owner)
+       CloseHandle(pcon_owner);
       ReleaseMutex (input_mutex);
 
       return len;
-- 
2.51.0

Reply via email to