/* TUI support I/O functions.
- Copyright (C) 1998-2019 Free Software Foundation, Inc.
+ Copyright (C) 1998-2020 Free Software Foundation, Inc.
Contributed by Hewlett-Packard Company.
#include "defs.h"
#include "target.h"
-#include "event-loop.h"
+#include "gdbsupport/event-loop.h"
#include "event-top.h"
#include "command.h"
#include "top.h"
#ifdef __MINGW32__
#include <windows.h>
#endif
-#include "common/filestuff.h"
+#include "gdbsupport/filestuff.h"
#include "completer.h"
#include "gdb_curses.h"
#include <map>
be garbled. This is implemented with a pipe that TUI reads and
readline writes to. A gdb input handler is created so that reading
the pipe is handled automatically. This will probably not work on
- non-Unix platforms. The best fix is to make readline clean enougth
+ non-Unix platforms. The best fix is to make readline clean enough
so that is never write on stdout.
Note SCz/2002-09-01: we now use more readline hooks and it seems
static int tui_readline_pipe[2];
#endif
-/* 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;
-
/* Print a character in the curses command window. The output is
buffered. It is up to the caller to refresh the screen if
necessary. */
static void
do_tui_putc (WINDOW *w, char c)
{
- static int tui_skip_line = -1;
-
- /* Catch annotation and discard them. We need two \032 and discard
- until a \n is seen. */
- if (c == '\032')
- {
- tui_skip_line++;
- }
- else if (tui_skip_line != 1)
+ /* Expand TABs, since ncurses on MS-Windows doesn't. */
+ if (c == '\t')
{
- tui_skip_line = -1;
- /* Expand TABs, since ncurses on MS-Windows doesn't. */
- if (c == '\t')
- {
- int col;
+ int col;
- col = getcurx (w);
- do
- {
- waddch (w, ' ');
- col++;
- }
- while ((col % 8) != 0);
+ col = getcurx (w);
+ do
+ {
+ waddch (w, ' ');
+ col++;
}
- else
- waddch (w, c);
+ while ((col % 8) != 0);
}
- else if (c == '\n')
- tui_skip_line = -1;
+ else
+ waddch (w, c);
}
/* Update the cached value of the command window's start line based on
static void
update_cmdwin_start_line ()
{
- TUI_CMD_WIN->start_line
- = getcury (TUI_CMD_WIN->handle);
+ TUI_CMD_WIN->start_line = getcury (TUI_CMD_WIN->handle.get ());
}
/* Print a character in the curses command window. The output is
static void
tui_putc (char c)
{
- WINDOW *w = TUI_CMD_WIN->handle;
-
- do_tui_putc (w, c);
+ do_tui_putc (TUI_CMD_WIN->handle.get (), c);
update_cmdwin_start_line ();
}
/* Apply STYLE to W. */
-static void
-apply_style (WINDOW *w, ui_file_style style)
+void
+tui_apply_style (WINDOW *w, ui_file_style style)
{
/* Reset. */
wattron (w, A_NORMAL);
style.set_reverse (true);
}
- apply_style (w, style);
+ tui_apply_style (w, style);
return n_read;
}
style.set_fg (reverse_save_fg);
}
- apply_style (w, style);
+ tui_apply_style (w, style);
}
/* Print LENGTH characters from the buffer pointed to by BUF to the
{
char c;
int prev_col = 0;
+ bool saw_nl = false;
while ((c = *string++) != 0)
{
+ if (c == '\n')
+ saw_nl = true;
+
if (c == '\1' || c == '\2')
{
/* Ignore these, they are readline escape-marking
}
}
}
- update_cmdwin_start_line ();
+ if (TUI_CMD_WIN != nullptr && w == TUI_CMD_WIN->handle.get ())
+ update_cmdwin_start_line ();
+ if (saw_nl)
+ wrefresh (w);
}
/* Print a string in the curses command window. The output is
tui_puts (const char *string, WINDOW *w)
{
if (w == nullptr)
- w = TUI_CMD_WIN->handle;
+ w = TUI_CMD_WIN->handle.get ();
tui_puts_internal (w, string, nullptr);
}
if (tui_current_key_mode == TUI_SINGLE_KEY_MODE)
prompt = "";
else
- prompt = tui_rl_saved_prompt;
+ prompt = rl_display_prompt;
c_pos = -1;
c_line = -1;
- w = TUI_CMD_WIN->handle;
+ w = TUI_CMD_WIN->handle.get ();
start_line = TUI_CMD_WIN->start_line;
wmove (w, start_line, 0);
prev_col = 0;
height = 1;
if (prompt != nullptr)
- tui_puts_internal (TUI_CMD_WIN->handle, prompt, &height);
+ tui_puts_internal (w, prompt, &height);
prev_col = getcurx (w);
for (in = 0; in <= rl_end; in++)
static void
tui_prep_terminal (int notused1)
{
- /* Save the prompt registered in readline to correctly display it.
- (we can't use gdb_prompt() due to secondary prompts and can't use
- rl_prompt because it points to an alloca buffer). */
- xfree (tui_rl_saved_prompt);
- tui_rl_saved_prompt = rl_prompt != NULL ? xstrdup (rl_prompt) : NULL;
}
/* Readline callback to restore the terminal. It is called once each
static void
tui_mld_flush (const struct match_list_displayer *displayer)
{
- wrefresh (TUI_CMD_WIN->handle);
+ wrefresh (TUI_CMD_WIN->handle.get ());
}
/* TUI version of displayer.erase_entire_line. */
static void
tui_mld_erase_entire_line (const struct match_list_displayer *displayer)
{
- WINDOW *w = TUI_CMD_WIN->handle;
+ WINDOW *w = TUI_CMD_WIN->handle.get ();
int cur_y = getcury (w);
wmove (w, cur_y, 0);
static int
tui_mld_getc (FILE *fp)
{
- WINDOW *w = TUI_CMD_WIN->handle;
+ WINDOW *w = TUI_CMD_WIN->handle.get ();
int c = gdb_wgetch (w);
return c;
/* Force a refresh of the screen. */
tui_refresh_all_win ();
-
- wrefresh (TUI_CMD_WIN->handle);
}
signal (sig, tui_cont_sig);
}
#endif
}
-/* Get a character from the command window. This is called from the
- readline package. */
+/* Dispatch the correct tui function based upon the control
+ character. */
+static unsigned int
+tui_dispatch_ctrl_char (unsigned int ch)
+{
+ struct tui_win_info *win_info = tui_win_with_focus ();
+
+ /* Handle the CTRL-L refresh for each window. */
+ if (ch == '\f')
+ tui_refresh_all_win ();
+
+ /* If no window has the focus, or if the focus window can't scroll,
+ just pass the character through. */
+ if (win_info == NULL || !win_info->can_scroll ())
+ return ch;
+
+ switch (ch)
+ {
+ case KEY_NPAGE:
+ win_info->forward_scroll (0);
+ break;
+ case KEY_PPAGE:
+ win_info->backward_scroll (0);
+ break;
+ case KEY_DOWN:
+ case KEY_SF:
+ win_info->forward_scroll (1);
+ break;
+ case KEY_UP:
+ case KEY_SR:
+ win_info->backward_scroll (1);
+ break;
+ case KEY_RIGHT:
+ win_info->left_scroll (1);
+ break;
+ case KEY_LEFT:
+ win_info->right_scroll (1);
+ break;
+ case '\f':
+ break;
+ default:
+ /* We didn't recognize the character as a control character, so pass it
+ through. */
+ return ch;
+ }
+
+ /* We intercepted the control character, so return 0 (which readline
+ will interpret as a no-op). */
+ return 0;
+}
+
+/* Main worker for tui_getc. Get a character from the command window.
+ This is called from the readline package, but wrapped in a
+ try/catch by tui_getc. */
+
static int
-tui_getc (FILE *fp)
+tui_getc_1 (FILE *fp)
{
int ch;
WINDOW *w;
- w = TUI_CMD_WIN->handle;
+ w = TUI_CMD_WIN->handle.get ();
#ifdef TUI_USE_PIPE_FOR_READLINE
/* Flush readline output. */
return ch;
}
-/* Utility function to expand TABs in a STRING into spaces. STRING
- will be displayed starting at column COL, and is assumed to include
- no newlines. The returned expanded string is malloc'ed. */
+/* Get a character from the command window. This is called from the
+ readline package. */
+
+static int
+tui_getc (FILE *fp)
+{
+ try
+ {
+ return tui_getc_1 (fp);
+ }
+ catch (const gdb_exception &ex)
+ {
+ /* Just in case, don't ever let an exception escape to readline.
+ This shouldn't ever happen, but if it does, print the
+ exception instead of just crashing GDB. */
+ exception_print (gdb_stderr, ex);
+
+ /* If we threw an exception, it's because we recognized the
+ character. */
+ return 0;
+ }
+}
+
+/* See tui-io.h. */
-char *
-tui_expand_tabs (const char *string, int col)
+gdb::unique_xmalloc_ptr<char>
+tui_expand_tabs (const char *string)
{
int n_adjust, ncol;
const char *s;
char *ret, *q;
/* 1. How many additional characters do we need? */
- for (ncol = col, n_adjust = 0, s = string; s; )
+ for (ncol = 0, n_adjust = 0, s = string; s; )
{
s = strpbrk (s, "\t");
if (s)
ret = q = (char *) xmalloc (strlen (string) + n_adjust + 1);
/* 2. Copy the original string while replacing TABs with spaces. */
- for (ncol = col, s = string; s; )
+ for (ncol = 0, s = string; s; )
{
const char *s1 = strpbrk (s, "\t");
if (s1)
s = s1;
}
- return ret;
+ return gdb::unique_xmalloc_ptr<char> (ret);
}