From 734656818aa571c8f0d8d3e73e391c8ae26d79f1 Mon Sep 17 00:00:00 2001 From: Thomas Wolff Date: Wed, 16 Mar 2016 10:25:16 +0100 Subject: [PATCH] Make requested console reports work cf https://cygwin.com/ml/cygwin-patches/2012-q3/msg00019.html This enables the following ESC sequences: ESC[c sends primary device attributes ESC[>c sends secondary device attributes ESC[6n sends cursor position report * fhandler.h (class dev_console): Add console read-ahead buffer. (class fhandler_console): Add peek function for it (for select). * fhandler_console.cc (fhandler_console::setup): Init buffer. (fhandler_console::read): Check console read-aheader buffer. (fhandler_console::char_command): Put responses to terminal requests (device status and cursor position reports) into common console buffer (shared between CONOUT/CONIN) instead of fhandler buffer (separated). * select.cc (peek_console): Check console read-ahead buffer. --- winsup/cygwin/fhandler.h | 6 ++++++ winsup/cygwin/fhandler_console.cc | 22 ++++++++++++++++++---- winsup/cygwin/select.cc | 6 ++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 134fd716b..1c1862b59 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1352,6 +1352,8 @@ class dev_console bool ext_mouse_mode15; bool use_focus; bool raw_win32_keyboard_mode; + char cons_rabuf[40]; // cannot get longer than char buf[40] in char_command + char *cons_rapoi; inline UINT get_console_cp (); DWORD con_to_str (char *d, int dlen, WCHAR w); @@ -1449,6 +1451,10 @@ private: int init (HANDLE, DWORD, mode_t); bool mouse_aware (MOUSE_EVENT_RECORD& mouse_event); bool focus_aware () {return shared_console_info->con.use_focus;} + bool get_cons_readahead_valid () + { + return shared_console_info->con.cons_rapoi != NULL; + } select_record *select_read (select_stuff *); select_record *select_write (select_stuff *); diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index a52449ea6..ef2d1c5a3 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -196,6 +196,7 @@ fhandler_console::setup () con.meta_mask |= RIGHT_ALT_PRESSED; con.set_default_attr (); con.backspace_keycode = CERASE; + con.cons_rapoi = NULL; shared_console_info->tty_min_state.is_console = true; } } @@ -310,6 +311,14 @@ fhandler_console::read (void *pv, size_t& buflen) int ch; set_input_state (); + /* Check console read-ahead buffer filled from terminal requests */ + if (con.cons_rapoi && *con.cons_rapoi) + { + *buf = *con.cons_rapoi++; + buflen = 1; + return; + } + int copied_chars = get_readahead_into_buffer (buf, buflen); if (copied_chars) @@ -1899,8 +1908,11 @@ fhandler_console::char_command (char c) strcpy (buf, "\033[?6c"); /* The generated report needs to be injected for read-ahead into the fhandler_console object associated with standard input. - The current call does not work. */ - puts_readahead (buf); + So puts_readahead does not work. + Use a common console read-ahead buffer instead. */ + con.cons_rapoi = NULL; + strcpy (con.cons_rabuf, buf); + con.cons_rapoi = con.cons_rabuf; break; case 'n': switch (con.args[0]) @@ -1910,9 +1922,11 @@ fhandler_console::char_command (char c) y -= con.b.srWindow.Top; /* x -= con.b.srWindow.Left; // not available yet */ __small_sprintf (buf, "\033[%d;%dR", y + 1, x + 1); - puts_readahead (buf); + con.cons_rapoi = NULL; + strcpy (con.cons_rabuf, buf); + con.cons_rapoi = con.cons_rabuf; break; - default: + default: goto bad_escape; } break; diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index e1d48a386..1f3276ca2 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -845,6 +845,12 @@ peek_console (select_record *me, bool) if (!me->read_selected) return me->write_ready; + if (fh->get_cons_readahead_valid ()) + { + select_printf ("cons_readahead"); + return me->read_ready = true; + } + if (fh->get_readahead_valid ()) { select_printf ("readahead");