/* GDB hooks for TUI.
- Copyright (C) 2001-2014 Free Software Foundation, Inc.
+ Copyright (C) 2001-2015 Free Software Foundation, Inc.
This file is part of GDB.
tui_display_main ();
}
-static int ATTRIBUTE_PRINTF (1, 0)
-tui_query_hook (const char *msg, va_list argp)
-{
- int retval;
- int ans2;
- int answer;
- char *question;
- struct cleanup *old_chain;
-
- /* Format the question outside of the loop, to avoid reusing
- ARGP. */
- question = xstrvprintf (msg, argp);
- old_chain = make_cleanup (xfree, question);
-
- echo ();
- while (1)
- {
- wrap_here (""); /* Flush any buffered output. */
- gdb_flush (gdb_stdout);
-
- fputs_filtered (question, gdb_stdout);
- printf_filtered (_("(y or n) "));
-
- wrap_here ("");
- gdb_flush (gdb_stdout);
-
- answer = tui_getc (stdin);
- clearerr (stdin); /* in case of C-d */
- if (answer == EOF) /* C-d */
- {
- retval = 1;
- break;
- }
- /* Eat rest of input line, to EOF or newline. */
- if (answer != '\n')
- do
- {
- ans2 = tui_getc (stdin);
- clearerr (stdin);
- }
- while (ans2 != EOF && ans2 != '\n' && ans2 != '\r');
-
- if (answer >= 'a')
- answer -= 040;
- if (answer == 'Y')
- {
- retval = 1;
- break;
- }
- if (answer == 'N')
- {
- retval = 0;
- break;
- }
- printf_filtered (_("Please answer y or n.\n"));
- }
- noecho ();
-
- do_cleanups (old_chain);
- return retval;
-}
-
/* Prevent recursion of deprecated_register_changed_hook(). */
static int tui_refreshing_registers = 0;
+/* Observer for the register_changed notification. */
+
static void
-tui_register_changed_hook (int regno)
+tui_register_changed (struct frame_info *frame, int regno)
{
struct frame_info *fi;
+ /* The frame of the register that was changed may differ from the selected
+ frame, but we only want to show the register values of the selected frame.
+ And even if the frames differ a register change made in one can still show
+ up in the other. So we always use the selected frame here, and ignore
+ FRAME. */
fi = get_selected_frame (NULL);
if (tui_refreshing_registers == 0)
{
tui_target_has_run = 1;
}
-/* The selected frame has changed. This is happens after a target
- stop or when the user explicitly changes the frame
- (up/down/thread/...). */
+/* Refresh TUI's frame and register information. This is a hook intended to be
+ used to update the screen after potential frame and register changes.
+
+ REGISTERS_TOO_P controls whether to refresh our register information even
+ if frame information hasn't changed. */
+
static void
-tui_selected_frame_level_changed_hook (int level)
+tui_refresh_frame_and_register_information (int registers_too_p)
{
struct frame_info *fi;
CORE_ADDR pc;
+ struct cleanup *old_chain;
+ int frame_info_changed_p;
- /* Negative level means that the selected frame was cleared. */
- if (level < 0)
+ if (!has_stack_frames ())
return;
+ old_chain = make_cleanup_restore_target_terminal ();
+ target_terminal_ours_for_output ();
+
fi = get_selected_frame (NULL);
/* Ensure that symbols for this frame are read in. Also, determine
the source language of this frame, and switch to it if
{
struct symtab *s;
- s = find_pc_symtab (pc);
+ s = find_pc_line_symtab (pc);
/* elz: This if here fixes the problem with the pc not being
displayed in the tui asm layout, with no debug symbols. The
value of s would be 0 here, and select_source_symtab would
/* Display the frame position (even if there is no symbols or the PC
is not known). */
- tui_show_frame_info (fi);
+ frame_info_changed_p = tui_show_frame_info (fi);
/* Refresh the register window if it's visible. */
- if (tui_is_window_visible (DATA_WIN))
+ if (tui_is_window_visible (DATA_WIN)
+ && (frame_info_changed_p || registers_too_p))
{
tui_refreshing_registers = 1;
tui_check_data_values (fi);
tui_refreshing_registers = 0;
}
+
+ do_cleanups (old_chain);
}
-/* Called from print_frame_info to list the line we stopped in. */
+/* Dummy callback for deprecated_print_frame_info_listing_hook which is called
+ from print_frame_info. */
+
static void
-tui_print_frame_info_listing_hook (struct symtab *s,
- int line,
- int stopline,
- int noerror)
+tui_dummy_print_frame_info_listing_hook (struct symtab *s,
+ int line,
+ int stopline,
+ int noerror)
{
- select_source_symtab (s);
- tui_show_frame_info (get_selected_frame (NULL));
}
/* Perform all necessary cleanups regarding our module's inferior data
tui_display_main ();
}
+/* Observer for the before_prompt notification. */
+
+static void
+tui_before_prompt (const char *current_gdb_prompt)
+{
+ /* This refresh is intended to catch changes to the selected frame following
+ a call to "up", "down" or "frame". As such we don't necessarily want to
+ refresh registers here unless the frame actually changed by one of these
+ commands. Registers will otherwise be refreshed after a normal stop or by
+ our tui_register_changed_hook. */
+ tui_refresh_frame_and_register_information (/*registers_too_p=*/0);
+}
+
+/* Observer for the normal_stop notification. */
+
+static void
+tui_normal_stop (struct bpstats *bs, int print_frame)
+{
+ /* This refresh is intended to catch changes to the selected frame and to
+ registers following a normal stop. */
+ tui_refresh_frame_and_register_information (/*registers_too_p=*/1);
+}
+
/* Observers created when installing TUI hooks. */
static struct observer *tui_bp_created_observer;
static struct observer *tui_bp_deleted_observer;
static struct observer *tui_bp_modified_observer;
static struct observer *tui_inferior_exit_observer;
static struct observer *tui_about_to_proceed_observer;
+static struct observer *tui_before_prompt_observer;
+static struct observer *tui_normal_stop_observer;
+static struct observer *tui_register_changed_observer;
/* Install the TUI specific hooks. */
void
tui_install_hooks (void)
{
- deprecated_selected_frame_level_changed_hook
- = tui_selected_frame_level_changed_hook;
+ /* If this hook is not set to something then print_frame_info will
+ assume that the CLI, not the TUI, is active, and will print the frame info
+ for us in such a way that we are not prepared to handle. This hook is
+ otherwise effectively obsolete. */
deprecated_print_frame_info_listing_hook
- = tui_print_frame_info_listing_hook;
-
- deprecated_query_hook = tui_query_hook;
+ = tui_dummy_print_frame_info_listing_hook;
/* Install the event hooks. */
tui_bp_created_observer
= observer_attach_inferior_exit (tui_inferior_exit);
tui_about_to_proceed_observer
= observer_attach_about_to_proceed (tui_about_to_proceed);
-
- deprecated_register_changed_hook = tui_register_changed_hook;
+ tui_before_prompt_observer
+ = observer_attach_before_prompt (tui_before_prompt);
+ tui_normal_stop_observer
+ = observer_attach_normal_stop (tui_normal_stop);
+ tui_register_changed_observer
+ = observer_attach_register_changed (tui_register_changed);
}
/* Remove the TUI specific hooks. */
void
tui_remove_hooks (void)
{
- deprecated_selected_frame_level_changed_hook = 0;
deprecated_print_frame_info_listing_hook = 0;
deprecated_query_hook = 0;
- deprecated_register_changed_hook = 0;
-
/* Remove our observers. */
observer_detach_breakpoint_created (tui_bp_created_observer);
tui_bp_created_observer = NULL;
tui_inferior_exit_observer = NULL;
observer_detach_about_to_proceed (tui_about_to_proceed_observer);
tui_about_to_proceed_observer = NULL;
+ observer_detach_before_prompt (tui_before_prompt_observer);
+ tui_before_prompt_observer = NULL;
+ observer_detach_normal_stop (tui_normal_stop_observer);
+ tui_normal_stop_observer = NULL;
+ observer_detach_register_changed (tui_register_changed_observer);
+ tui_register_changed_observer = NULL;
}
void _initialize_tui_hooks (void);