public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/5] An attempt to provide "scrolling" functionality to TUI (PR tui/14584)
@ 2015-07-05 21:03 Patrick Palka
  2015-07-05 21:04 ` [PATCH 1/5] tui: reset start_line whenever cur_line is reset Patrick Palka
  0 siblings, 1 reply; 6+ messages in thread
From: Patrick Palka @ 2015-07-05 21:03 UTC (permalink / raw)
  To: gdb-patches; +Cc: Patrick Palka

The first 3 patches are bug fixes/cleanups that are useful in themselves.  The
4th patch is a fix which is only useful if the 5th patch is accepted.  The 5th
patch implements the actual "scrolling" functionality, and fixes the PR.

Patrick Palka (5):
  tui: reset start_line whenever cur_line is reset
  tui: use tui_putc to output newline entered by the user
  tui: simplify and fix up handling of start_line in
    tui_redisplay_readline
  tui: make updating of start_line in tui_puts more consistent
  tui: maintain a scrollback buffer and dump it upon exit (PR tui/14584)

 gdb/tui/tui-data.c |   6 ++--
 gdb/tui/tui-io.c   | 100 +++++++++++++++++++++++++++++++++++++++++++++++------
 gdb/tui/tui-io.h   |   5 +++
 gdb/tui/tui-win.c  |   1 +
 gdb/tui/tui.c      |   3 ++
 5 files changed, 102 insertions(+), 13 deletions(-)

-- 
2.5.0.rc0.5.g91e10c5.dirty

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/5] tui: reset start_line whenever cur_line is reset
  2015-07-05 21:03 [PATCH 0/5] An attempt to provide "scrolling" functionality to TUI (PR tui/14584) Patrick Palka
@ 2015-07-05 21:04 ` Patrick Palka
  2015-07-05 21:04   ` [PATCH 4/5] tui: make updating of start_line in tui_puts more consistent Patrick Palka
                     ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Patrick Palka @ 2015-07-05 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Patrick Palka

Whenever the command window's cur_line is reset to 0, so should
start_line.  This is because there is an implicit invariant that
0 <= start_line <= cur_line.

gdb/ChangeLog:

	* tui/tui-data.c (tui_clear_win_detail) [CMD_WIN]: Also reset
	start_line.
	(init_win_info) [CMD_WIN]: Ditto.
	* tui/tui-win.c (make_visible_with_new_height) [CMD_WIN]: Ditto.
---
 gdb/tui/tui-data.c | 6 ++++--
 gdb/tui/tui-win.c  | 1 +
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/gdb/tui/tui-data.c b/gdb/tui/tui-data.c
index ed42c8d..e9aa7b3 100644
--- a/gdb/tui/tui-data.c
+++ b/gdb/tui/tui-data.c
@@ -212,8 +212,9 @@ tui_clear_win_detail (struct tui_win_info *win_info)
 	  win_info->detail.source_info.horizontal_offset = 0;
 	  break;
 	case CMD_WIN:
-	  win_info->detail.command_info.cur_line =
-	    win_info->detail.command_info.curch = 0;
+	  win_info->detail.command_info.start_line = 0;
+	  win_info->detail.command_info.cur_line = 0;
+	  win_info->detail.command_info.curch = 0;
 	  break;
 	case DATA_WIN:
 	  win_info->detail.data_display_info.data_content =
@@ -545,6 +546,7 @@ init_win_info (struct tui_win_info *win_info)
       win_info->detail.data_display_info.current_group = 0;
       break;
     case CMD_WIN:
+      win_info->detail.command_info.start_line = 0;
       win_info->detail.command_info.cur_line = 0;
       win_info->detail.command_info.curch = 0;
       break;
diff --git a/gdb/tui/tui-win.c b/gdb/tui/tui-win.c
index feb360b..0150900 100644
--- a/gdb/tui/tui-win.c
+++ b/gdb/tui/tui-win.c
@@ -1510,6 +1510,7 @@ make_visible_with_new_height (struct tui_win_info *win_info)
       tui_display_all_data ();
       break;
     case CMD_WIN:
+      win_info->detail.command_info.start_line = 0;
       win_info->detail.command_info.cur_line = 0;
       win_info->detail.command_info.curch = 0;
 #ifdef HAVE_WRESIZE
-- 
2.5.0.rc0.5.g91e10c5.dirty

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/5] tui: use tui_putc to output newline entered by the user
  2015-07-05 21:04 ` [PATCH 1/5] tui: reset start_line whenever cur_line is reset Patrick Palka
  2015-07-05 21:04   ` [PATCH 4/5] tui: make updating of start_line in tui_puts more consistent Patrick Palka
  2015-07-05 21:04   ` [PATCH 3/5] tui: simplify and fix up handling of start_line in tui_redisplay_readline Patrick Palka
@ 2015-07-05 21:04   ` Patrick Palka
  2015-07-05 21:04   ` [PATCH 5/5] tui: maintain a scrollback buffer and dump it upon exit (PR tui/14584) Patrick Palka
  3 siblings, 0 replies; 6+ messages in thread
From: Patrick Palka @ 2015-07-05 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Patrick Palka

This is necessary to make sure that start_line and cur_line are set
properly right after a command has been entered.  We usually get away
with not doing so because most commands output text, and when they do
they do it through tui_putc/tui_puts which makes start_line and cur_line
get updated.  However if a command does not output text, then start_line
will not get updated in time.

This fixes the following bug in the TUI:

(gdb) break foo
No symbol table is loaded.  Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n]) n<Enter>

After typing n followed by pressing Enter, the last line starting with
"Make breakpoint pending ..." (i.e. the subprompt) will get overwritten
by the next prompt.  With this patch, the last line does not get
overwritten.  (That the subprompt gets overwritten when no text is
entered at all is mostly a separate issue.)

gdb/ChangeLog:

	* tui/tui-io.c (tui_getc): Use tui_putc instead of waddch to
	emit the newline.
---
 gdb/tui/tui-io.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c
index 97906ce..ba42c18 100644
--- a/gdb/tui/tui-io.c
+++ b/gdb/tui/tui-io.c
@@ -620,7 +620,7 @@ tui_getc (FILE *fp)
 	  py += px / TUI_CMD_WIN->generic.width;
 	  px %= TUI_CMD_WIN->generic.width;
 	  wmove (w, py, px);
-	  waddch (w, ch);
+	  tui_putc ('\n');
         }
     }
   
-- 
2.5.0.rc0.5.g91e10c5.dirty

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 3/5] tui: simplify and fix up handling of start_line in tui_redisplay_readline
  2015-07-05 21:04 ` [PATCH 1/5] tui: reset start_line whenever cur_line is reset Patrick Palka
  2015-07-05 21:04   ` [PATCH 4/5] tui: make updating of start_line in tui_puts more consistent Patrick Palka
@ 2015-07-05 21:04   ` Patrick Palka
  2015-07-05 21:04   ` [PATCH 2/5] tui: use tui_putc to output newline entered by the user Patrick Palka
  2015-07-05 21:04   ` [PATCH 5/5] tui: maintain a scrollback buffer and dump it upon exit (PR tui/14584) Patrick Palka
  3 siblings, 0 replies; 6+ messages in thread
From: Patrick Palka @ 2015-07-05 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Patrick Palka

This patch makes three small changes:

The code guarded by the c == '\n' condition is dead code because
whatever value start_line and curch get set to will be overwritten after
the while-loop finishes anyway.  So this patch removes this dead code.

Besides that, the remaining two writes to start_line are combined into
one write.

Finally, if start_line ever falls below 0, which can happen if the
command line is so long that it wraps along the height of the entire
command window, just reset it to 0 so that we avoid passing an invalid y
parameter to wmove() later, and emit a beep to "warn" the user that the
command line is too long.

gdb/ChangeLog:

	* tui/tui-io.c (tui_redisplay_readline): Simplify the updating
	of start_line.  If start_line is negative, re-set it to 0 and
	emit a beep.
---
 gdb/tui/tui-io.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c
index ba42c18..5b9ca20 100644
--- a/gdb/tui/tui-io.c
+++ b/gdb/tui/tui-io.c
@@ -270,26 +270,33 @@ tui_redisplay_readline (void)
 	{
           waddch (w, c);
 	}
-      if (c == '\n')
-        {
-          getyx (w, TUI_CMD_WIN->detail.command_info.start_line,
-                 TUI_CMD_WIN->detail.command_info.curch);
-        }
       getyx (w, line, col);
       if (col < prev_col)
         height++;
       prev_col = col;
     }
+
   wclrtobot (w);
-  getyx (w, TUI_CMD_WIN->detail.command_info.start_line,
-         TUI_CMD_WIN->detail.command_info.curch);
+
+  TUI_CMD_WIN->detail.command_info.start_line
+    = getcury (w) - (height - 1);
+  TUI_CMD_WIN->detail.command_info.curch
+    = getcurx (w);
+
+  /* This can happen if the command line is so long that it wraps along the
+     height of the entire window.  */
+  if (TUI_CMD_WIN->detail.command_info.start_line < 0)
+    {
+      beep ();
+      TUI_CMD_WIN->detail.command_info.start_line = 0;
+    }
+
   if (c_line >= 0)
     {
       wmove (w, c_line, c_pos);
       TUI_CMD_WIN->detail.command_info.cur_line = c_line;
       TUI_CMD_WIN->detail.command_info.curch = c_pos;
     }
-  TUI_CMD_WIN->detail.command_info.start_line -= height - 1;
 
   wrefresh (w);
   fflush(stdout);
-- 
2.5.0.rc0.5.g91e10c5.dirty

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 4/5] tui: make updating of start_line in tui_puts more consistent
  2015-07-05 21:04 ` [PATCH 1/5] tui: reset start_line whenever cur_line is reset Patrick Palka
@ 2015-07-05 21:04   ` Patrick Palka
  2015-07-05 21:04   ` [PATCH 3/5] tui: simplify and fix up handling of start_line in tui_redisplay_readline Patrick Palka
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Patrick Palka @ 2015-07-05 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Patrick Palka

The command window's start_line field is used by tui_redisplay_readline
to figure out on which window line to start redrawing the (possibly
multi-line) command line.  It differs from cur_line only when the length
of the line being outputted is longer than the width of the window.  In
this case, start_line will not equal to cur_line.  Instead, start_line
will be equal to cur_line - N where N is the number of times the current
line was wrapped around the width of the command window.  start_line
takes into consideration whether line wrapping has occurred, and
cur_line does not.

The function tui_puts however currently does not respect this property
of start_line.  After a call to tui_puts, start_line will always be
equal to cur_line even when the outputted line may have wrapped a few
times.  This patch makes tui_puts properly update start_line.  It must
only be updated if a newline is emitted, or if ncurses scrolls the
command window (thus shifting all the line numbers).

gdb/ChangeLog:

	* tui/tui-io.c (tui_puts): Fix the updating of start_line.
---
 gdb/tui/tui-io.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c
index 5b9ca20..9302391 100644
--- a/gdb/tui/tui-io.c
+++ b/gdb/tui/tui-io.c
@@ -168,7 +168,12 @@ tui_puts (const char *string)
         }
       else if (tui_skip_line != 1)
         {
+	  int prev_line, prev_col;
+
           tui_skip_line = -1;
+
+	  getyx (w, prev_line, prev_col);
+
 	  /* Expand TABs, since ncurses on MS-Windows doesn't.  */
 	  if (c == '\t')
 	    {
@@ -183,14 +188,23 @@ tui_puts (const char *string)
 	    }
 	  else
 	    waddch (w, c);
+
+	  if (c == '\n')
+	    TUI_CMD_WIN->detail.command_info.start_line = getcury (w);
+	  else if (getcurx (w) <= prev_col && getcury (w) == prev_line)
+	    {
+	      /* If the cursor is on the last line of the command window and the
+		 added character caused the line to wrap, then we have to adjust
+		 start_line to compensate for the scrolling up of each line that
+		 the line wrapping caused.  */
+	      TUI_CMD_WIN->detail.command_info.start_line--;
+	    }
         }
       else if (c == '\n')
         tui_skip_line = -1;
     }
   getyx (w, TUI_CMD_WIN->detail.command_info.cur_line,
          TUI_CMD_WIN->detail.command_info.curch);
-  TUI_CMD_WIN->detail.command_info.start_line
-    = TUI_CMD_WIN->detail.command_info.cur_line;
 }
 
 /* Readline callback.
-- 
2.5.0.rc0.5.g91e10c5.dirty

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 5/5] tui: maintain a scrollback buffer and dump it upon exit (PR tui/14584)
  2015-07-05 21:04 ` [PATCH 1/5] tui: reset start_line whenever cur_line is reset Patrick Palka
                     ` (2 preceding siblings ...)
  2015-07-05 21:04   ` [PATCH 2/5] tui: use tui_putc to output newline entered by the user Patrick Palka
@ 2015-07-05 21:04   ` Patrick Palka
  3 siblings, 0 replies; 6+ messages in thread
From: Patrick Palka @ 2015-07-05 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Patrick Palka

It is currently impossible to scroll through the text emitted in the
TUI's command window.  If some output leaves the top of the window then it
is effectively gone forever.

This patch attempts to laterally work around this deficiency not by
implementing command-window scrolling within the TUI, but rather by
accumulating a scrollback buffer of command-window output while the TUI
is active and dumping it into the CLI when the TUI gets disabled.  So
when the user wants to scroll through the output emitted under the TUI,
with this patch the user can just temporarily switch to the CLI
(triggering the verbatim dumping of the window's contents) and then use
their terminal emulator/multiplexer to scroll/search through the output
as if it came from the CLI itself.  This gives the impression that the
TUI command-window and the CLI output are unified (although the
synchronization only goes one way).

The implementation is pretty straightforward.  Whenever a newline is
emitted in the command window, the current line gets copied from the
screen into a scrollback buffer.  (Care must be taken to account for
long, wrapped lines.  Now that start_line is always valid, this is easy
enough.)  And when the TUI is disabled, the buffer is dumped and emptied
verbatim.

Is this a good approach to addressing the lack of scrolling capabilities
in the TUI command window?  I don't see much advantage to having a
direct implementation of command-window scrolling compared to this
approach of piggybacking on the underlying terminal
emulator/multiplexer.

gdb/ChangeLog:

	* tui/tui-io.h (tui_dump_scrollback_buffer): Declare.
	* tui/tui-io.c (tui_dump_scrollback_buffer): Define.
	(tui_scrollback_buffer): Define.
	(tui_add_current_line_to_scrollback_buffer): Define.
	(tui_puts): Call it before emitting a newline.
	* tui/tui.c (tui_disable): Call tui_dump_scrollback_buffer.
---
 gdb/tui/tui-io.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/tui/tui-io.h |  5 +++++
 gdb/tui/tui.c    |  3 +++
 3 files changed, 65 insertions(+)

diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c
index 9302391..c3718be 100644
--- a/gdb/tui/tui-io.c
+++ b/gdb/tui/tui-io.c
@@ -132,6 +132,11 @@ static FILE *tui_old_rl_outstream;
 static int tui_readline_pipe[2];
 #endif
 
+/* The scrollback buffer containing a line-by-line copy of all that's been
+   outputted to the command window during the current TUI session.  */
+
+static VEC (char_ptr) *tui_scrollback_buffer = NULL;
+
 /* The last gdb prompt that was registered in readline.
    This may be the main gdb prompt or a secondary prompt.  */
 static char *tui_rl_saved_prompt;
@@ -146,6 +151,55 @@ tui_putc (char c)
   tui_puts (buf);
 }
 
+/* See tui-io.h.  */
+
+void
+tui_dump_scrollback_buffer (void)
+{
+  int i;
+  for (i = 0; i < VEC_length (char_ptr, tui_scrollback_buffer); i++)
+    {
+      char *line = VEC_index (char_ptr, tui_scrollback_buffer, i);
+      fputs_unfiltered (line, gdb_stdout);
+      fputc_unfiltered ('\n', gdb_stdout);
+      xfree (line);
+    }
+
+  VEC_free (char_ptr, tui_scrollback_buffer);
+}
+
+/* Copy the current line, delimited by the screen coordinates
+   (START_LINE, 0) to (CUR_LINE, CURCH), to the scrollback buffer.  */
+
+static void
+tui_add_current_line_to_scrollback_buffer (void)
+{
+  WINDOW *w = TUI_CMD_WIN->generic.handle;
+  const int start_line = TUI_CMD_WIN->detail.command_info.start_line;
+  const int cur_line = TUI_CMD_WIN->detail.command_info.cur_line;
+  const int curch = TUI_CMD_WIN->detail.command_info.curch;
+  const int max_x = getmaxx (w);
+  int i, j, k;
+  char *line;
+
+  wmove (w, cur_line, curch);
+
+  /* Allocate enough space to hold the entire (possibly wrapped) line.  */
+  line = xcalloc ((cur_line - start_line) * max_x + curch + 2, sizeof (*line));
+
+  k = 0;
+  for (j = start_line; j < cur_line; j++)
+    for (i = 0; i < max_x; i++)
+      line[k++] = mvwinch (w, j, i);
+
+  for (i = 0; i < curch; i++)
+    line[k++] = mvwinch (w, cur_line, i);
+  line[k++] = '\0';
+
+  VEC_safe_push (char_ptr, tui_scrollback_buffer, line);
+  wmove (w, cur_line, curch);
+}
+
 /* Print the string in the curses command window.
    The output is buffered.  It is up to the caller to refresh the screen
    if necessary.  */
@@ -172,6 +226,9 @@ tui_puts (const char *string)
 
           tui_skip_line = -1;
 
+	  if (c == '\n')
+	    tui_add_current_line_to_scrollback_buffer ();
+
 	  getyx (w, prev_line, prev_col);
 
 	  /* Expand TABs, since ncurses on MS-Windows doesn't.  */
diff --git a/gdb/tui/tui-io.h b/gdb/tui/tui-io.h
index 3154eee..e61ed14 100644
--- a/gdb/tui/tui-io.h
+++ b/gdb/tui/tui-io.h
@@ -44,6 +44,11 @@ extern void tui_redisplay_readline (void);
 /* Expand TABs into spaces.  */
 extern char *tui_expand_tabs (const char *, int);
 
+/* Emit the scrollback buffer accumulated by the command window in its
+   entirety, and then clear it.  */
+
+extern void tui_dump_scrollback_buffer (void);
+
 extern struct ui_out *tui_out;
 extern struct ui_out *tui_old_uiout;
 
diff --git a/gdb/tui/tui.c b/gdb/tui/tui.c
index 838471d..69ed60b 100644
--- a/gdb/tui/tui.c
+++ b/gdb/tui/tui.c
@@ -538,6 +538,9 @@ tui_disable (void)
 
   tui_active = 0;
   tui_update_gdb_sizes ();
+
+  /* Dump the command window's scrollback buffer.  */
+  tui_dump_scrollback_buffer ();
 }
 
 /* Command wrapper for enabling tui mode.  */
-- 
2.5.0.rc0.5.g91e10c5.dirty

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-07-05 21:04 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-05 21:03 [PATCH 0/5] An attempt to provide "scrolling" functionality to TUI (PR tui/14584) Patrick Palka
2015-07-05 21:04 ` [PATCH 1/5] tui: reset start_line whenever cur_line is reset Patrick Palka
2015-07-05 21:04   ` [PATCH 4/5] tui: make updating of start_line in tui_puts more consistent Patrick Palka
2015-07-05 21:04   ` [PATCH 3/5] tui: simplify and fix up handling of start_line in tui_redisplay_readline Patrick Palka
2015-07-05 21:04   ` [PATCH 2/5] tui: use tui_putc to output newline entered by the user Patrick Palka
2015-07-05 21:04   ` [PATCH 5/5] tui: maintain a scrollback buffer and dump it upon exit (PR tui/14584) Patrick Palka

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).