gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / tui / tui-hooks.c
CommitLineData
2611b1a5 1/* GDB hooks for TUI.
f33c6cbf 2
b811d2c2 3 Copyright (C) 2001-2020 Free Software Foundation, Inc.
2611b1a5
SC
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
2611b1a5
SC
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
2611b1a5
SC
19
20#include "defs.h"
21#include "symtab.h"
22#include "inferior.h"
23#include "command.h"
24#include "bfd.h"
25#include "symfile.h"
26#include "objfiles.h"
27#include "target.h"
28#include "gdbcore.h"
400b5eca 29#include "gdbsupport/event-loop.h"
2b68e2c5 30#include "event-top.h"
2611b1a5
SC
31#include "frame.h"
32#include "breakpoint.h"
2b68e2c5
SC
33#include "ui-out.h"
34#include "top.h"
76727919 35#include "observable.h"
583068ca 36#include "source.h"
2611b1a5
SC
37#include <unistd.h>
38#include <fcntl.h>
39
d7b2e967 40#include "tui/tui.h"
6a83354a 41#include "tui/tui-hooks.h"
d7b2e967
AC
42#include "tui/tui-data.h"
43#include "tui/tui-layout.h"
44#include "tui/tui-io.h"
45#include "tui/tui-regs.h"
46#include "tui/tui-win.h"
47#include "tui/tui-stack.h"
d7b2e967 48#include "tui/tui-winsource.h"
2611b1a5 49
6a83354a 50#include "gdb_curses.h"
96ec9981 51
2611b1a5
SC
52static void
53tui_new_objfile_hook (struct objfile* objfile)
54{
55 if (tui_active)
1f393769 56 tui_display_main ();
2611b1a5
SC
57}
58
3adda9d8 59/* Prevent recursion of deprecated_register_changed_hook(). */
87d557ae 60static bool tui_refreshing_registers = false;
2611b1a5 61
a9bd710f
PP
62/* Observer for the register_changed notification. */
63
2611b1a5 64static void
a9bd710f 65tui_register_changed (struct frame_info *frame, int regno)
2611b1a5
SC
66{
67 struct frame_info *fi;
68
63356bfd
TT
69 if (!tui_is_window_visible (DATA_WIN))
70 return;
71
a9bd710f
PP
72 /* The frame of the register that was changed may differ from the selected
73 frame, but we only want to show the register values of the selected frame.
74 And even if the frames differ a register change made in one can still show
75 up in the other. So we always use the selected frame here, and ignore
76 FRAME. */
206415a3 77 fi = get_selected_frame (NULL);
87d557ae 78 if (!tui_refreshing_registers)
2611b1a5 79 {
87d557ae 80 tui_refreshing_registers = true;
63356bfd 81 TUI_DATA_WIN->check_register_values (fi);
87d557ae 82 tui_refreshing_registers = false;
2611b1a5
SC
83 }
84}
85
2611b1a5
SC
86/* Breakpoint creation hook.
87 Update the screen to show the new breakpoint. */
88static void
8d3788bd 89tui_event_create_breakpoint (struct breakpoint *b)
2611b1a5 90{
0807ab7b 91 tui_update_all_breakpoint_info (nullptr);
2611b1a5
SC
92}
93
94/* Breakpoint deletion hook.
95 Refresh the screen to update the breakpoint marks. */
96static void
8d3788bd 97tui_event_delete_breakpoint (struct breakpoint *b)
2611b1a5 98{
0807ab7b 99 tui_update_all_breakpoint_info (b);
2611b1a5
SC
100}
101
102static void
8d3788bd 103tui_event_modify_breakpoint (struct breakpoint *b)
2611b1a5 104{
0807ab7b 105 tui_update_all_breakpoint_info (nullptr);
2611b1a5
SC
106}
107
fc9d2d72
TT
108/* This is set to true if the next window refresh should come from the
109 current stack frame. */
110
111static bool from_stack;
112
113/* This is set to true if the next window refresh should come from the
114 current source symtab. */
0986c744 115
fc9d2d72
TT
116static bool from_source_symtab;
117
118/* Refresh TUI's frame and register information. This is a hook intended to be
119 used to update the screen after potential frame and register changes. */
0986c744 120
2611b1a5 121static void
fc9d2d72 122tui_refresh_frame_and_register_information ()
2611b1a5 123{
fc9d2d72 124 if (!from_stack && !from_source_symtab)
3adda9d8
DJ
125 return;
126
223ffa71
TT
127 target_terminal::scoped_restore_terminal_state term_state;
128 target_terminal::ours_for_output ();
0a75489f 129
fc9d2d72 130 if (from_stack && has_stack_frames ())
2611b1a5 131 {
fc9d2d72
TT
132 struct frame_info *fi = get_selected_frame (NULL);
133
134 /* Display the frame position (even if there is no symbols or
135 the PC is not known). */
eb390f49 136 bool frame_info_changed_p = tui_show_frame_info (fi);
fc9d2d72
TT
137
138 /* Refresh the register window if it's visible. */
139 if (tui_is_window_visible (DATA_WIN)
140 && (frame_info_changed_p || from_stack))
141 {
87d557ae 142 tui_refreshing_registers = true;
fc9d2d72 143 TUI_DATA_WIN->check_register_values (fi);
87d557ae 144 tui_refreshing_registers = false;
fc9d2d72 145 }
f23d1b92 146 }
fc9d2d72 147 else if (!from_stack)
f23d1b92 148 {
fc9d2d72
TT
149 /* Make sure that the source window is displayed. */
150 tui_add_win_to_layout (SRC_WIN);
151
152 struct symtab_and_line sal = get_current_source_symtab_and_line ();
153 tui_update_source_windows_with_line (sal);
2611b1a5
SC
154 }
155}
156
0986c744
PP
157/* Dummy callback for deprecated_print_frame_info_listing_hook which is called
158 from print_frame_info. */
159
2611b1a5 160static void
0986c744
PP
161tui_dummy_print_frame_info_listing_hook (struct symtab *s,
162 int line,
163 int stopline,
164 int noerror)
2611b1a5 165{
2611b1a5
SC
166}
167
d69e6a33
SC
168/* Perform all necessary cleanups regarding our module's inferior data
169 that is required after the inferior INF just exited. */
170
cda8ab40 171static void
d69e6a33 172tui_inferior_exit (struct inferior *inf)
cda8ab40 173{
d69e6a33
SC
174 /* Leave the SingleKey mode to make sure the gdb prompt is visible. */
175 tui_set_key_mode (TUI_COMMAND_MODE);
47d3492a 176 tui_show_frame_info (0);
cda8ab40
SC
177 tui_display_main ();
178}
179
0986c744
PP
180/* Observer for the before_prompt notification. */
181
182static void
183tui_before_prompt (const char *current_gdb_prompt)
184{
fc9d2d72
TT
185 tui_refresh_frame_and_register_information ();
186 from_stack = false;
187 from_source_symtab = false;
0986c744
PP
188}
189
190/* Observer for the normal_stop notification. */
191
192static void
193tui_normal_stop (struct bpstats *bs, int print_frame)
194{
fc9d2d72
TT
195 from_stack = true;
196}
197
198/* Observer for user_selected_context_changed. */
199
200static void
201tui_context_changed (user_selected_what ignore)
202{
203 from_stack = true;
204}
205
206/* Observer for current_source_symtab_and_line_changed. */
207
208static void
209tui_symtab_changed ()
210{
211 from_source_symtab = true;
0986c744
PP
212}
213
76727919
TT
214/* Token associated with observers registered while TUI hooks are
215 installed. */
3dcfdc58 216static const gdb::observers::token tui_observers_token {};
76727919
TT
217
218/* Attach or detach a single observer, according to ATTACH. */
219
220template<typename T>
221static void
222attach_or_detach (T &observable, typename T::func_type func, bool attach)
223{
224 if (attach)
225 observable.attach (func, tui_observers_token);
226 else
227 observable.detach (tui_observers_token);
228}
229
230/* Attach or detach TUI observers, according to ATTACH. */
231
232static void
233tui_attach_detach_observers (bool attach)
234{
235 attach_or_detach (gdb::observers::breakpoint_created,
236 tui_event_create_breakpoint, attach);
237 attach_or_detach (gdb::observers::breakpoint_deleted,
238 tui_event_delete_breakpoint, attach);
239 attach_or_detach (gdb::observers::breakpoint_modified,
240 tui_event_modify_breakpoint, attach);
241 attach_or_detach (gdb::observers::inferior_exit,
242 tui_inferior_exit, attach);
243 attach_or_detach (gdb::observers::before_prompt,
244 tui_before_prompt, attach);
245 attach_or_detach (gdb::observers::normal_stop,
246 tui_normal_stop, attach);
247 attach_or_detach (gdb::observers::register_changed,
248 tui_register_changed, attach);
fc9d2d72
TT
249 attach_or_detach (gdb::observers::user_selected_context_changed,
250 tui_context_changed, attach);
251 attach_or_detach (gdb::observers::current_source_symtab_and_line_changed,
252 tui_symtab_changed, attach);
76727919 253}
383f836e 254
2611b1a5
SC
255/* Install the TUI specific hooks. */
256void
257tui_install_hooks (void)
258{
0986c744
PP
259 /* If this hook is not set to something then print_frame_info will
260 assume that the CLI, not the TUI, is active, and will print the frame info
261 for us in such a way that we are not prepared to handle. This hook is
262 otherwise effectively obsolete. */
9a2b4c1b 263 deprecated_print_frame_info_listing_hook
0986c744 264 = tui_dummy_print_frame_info_listing_hook;
2611b1a5 265
2611b1a5 266 /* Install the event hooks. */
76727919 267 tui_attach_detach_observers (true);
2611b1a5
SC
268}
269
270/* Remove the TUI specific hooks. */
271void
272tui_remove_hooks (void)
273{
9a4105ab 274 deprecated_print_frame_info_listing_hook = 0;
76727919 275
383f836e 276 /* Remove our observers. */
76727919 277 tui_attach_detach_observers (false);
2611b1a5
SC
278}
279
6c265988 280void _initialize_tui_hooks ();
021e7609 281void
6c265988 282_initialize_tui_hooks ()
2611b1a5 283{
2611b1a5 284 /* Install the permanent hooks. */
76727919 285 gdb::observers::new_objfile.attach (tui_new_objfile_hook);
2611b1a5 286}
This page took 3.21144 seconds and 4 git commands to generate.