TUI window resize should not need invisibility
[deliverable/binutils-gdb.git] / gdb / tui / tui-interp.c
CommitLineData
021e7609
AC
1/* TUI Interpreter definitions for GDB, the GNU debugger.
2
42a4f53d 3 Copyright (C) 2003-2019 Free Software Foundation, Inc.
021e7609
AC
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
021e7609
AC
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/>. */
021e7609
AC
19
20#include "defs.h"
3c216924 21#include "cli/cli-interp.h"
021e7609
AC
22#include "interps.h"
23#include "top.h"
24#include "event-top.h"
25#include "event-loop.h"
26#include "ui-out.h"
95cd630e 27#include "cli-out.h"
d7b2e967 28#include "tui/tui-data.h"
021e7609 29#include "readline/readline.h"
d7b2e967 30#include "tui/tui-win.h"
021e7609 31#include "tui/tui.h"
d7b2e967 32#include "tui/tui-io.h"
fd664c91 33#include "infrun.h"
76727919 34#include "observable.h"
eaae60fd 35#include "gdbthread.h"
00431a78 36#include "inferior.h"
b0be6c91 37#include "main.h"
fd664c91 38
1cc6d956
MS
39/* Set to 1 when the TUI mode must be activated when we first start
40 gdb. */
63858210
SC
41static int tui_start_enabled = 0;
42
d6f9b0fb
PA
43class tui_interp final : public cli_interp_base
44{
45public:
46 explicit tui_interp (const char *name)
47 : cli_interp_base (name)
48 {}
49
50 void init (bool top_level) override;
51 void resume () override;
52 void suspend () override;
53 gdb_exception exec (const char *command_str) override;
54 ui_out *interp_ui_out () override;
55};
56
73ab01a0
PA
57/* Returns the INTERP if the INTERP is a TUI, and returns NULL
58 otherwise. */
59
d6f9b0fb 60static tui_interp *
73ab01a0
PA
61as_tui_interp (struct interp *interp)
62{
716b8bc5 63 return dynamic_cast<tui_interp *> (interp);
73ab01a0 64}
fd664c91 65
021e7609
AC
66/* Cleanup the tui before exiting. */
67
68static void
69tui_exit (void)
70{
1cc6d956
MS
71 /* Disable the tui. Curses mode is left leaving the screen in a
72 clean state (see endwin()). */
021e7609
AC
73 tui_disable ();
74}
75
fd664c91
PA
76/* Observers for several run control events. If the interpreter is
77 quiet (i.e., another interpreter is being run with
78 interpreter-exec), print nothing. */
79
243a9253
PA
80/* Observer for the normal_stop notification. */
81
82static void
83tui_on_normal_stop (struct bpstats *bs, int print_frame)
84{
eaae60fd
PA
85 if (!print_frame)
86 return;
87
0e454242 88 SWITCH_THRU_ALL_UIS ()
243a9253 89 {
eaae60fd
PA
90 struct interp *interp = top_level_interpreter ();
91 struct interp *tui = as_tui_interp (interp);
92 struct thread_info *thread;
73ab01a0
PA
93
94 if (tui == NULL)
95 continue;
96
eaae60fd
PA
97 thread = inferior_thread ();
98 if (should_print_stop_to_console (interp, thread))
d6f9b0fb 99 print_stop_event (tui->interp_ui_out ());
243a9253
PA
100 }
101}
102
fd664c91
PA
103/* Observer for the signal_received notification. */
104
105static void
106tui_on_signal_received (enum gdb_signal siggnal)
107{
0e454242 108 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
109 {
110 struct interp *tui = as_tui_interp (top_level_interpreter ());
111
112 if (tui == NULL)
113 continue;
114
d6f9b0fb 115 print_signal_received_reason (tui->interp_ui_out (), siggnal);
73ab01a0 116 }
fd664c91
PA
117}
118
119/* Observer for the end_stepping_range notification. */
120
121static void
122tui_on_end_stepping_range (void)
123{
0e454242 124 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
125 {
126 struct interp *tui = as_tui_interp (top_level_interpreter ());
127
128 if (tui == NULL)
129 continue;
130
d6f9b0fb 131 print_end_stepping_range_reason (tui->interp_ui_out ());
73ab01a0 132 }
fd664c91
PA
133}
134
135/* Observer for the signal_exited notification. */
136
137static void
138tui_on_signal_exited (enum gdb_signal siggnal)
139{
0e454242 140 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
141 {
142 struct interp *tui = as_tui_interp (top_level_interpreter ());
143
144 if (tui == NULL)
145 continue;
146
d6f9b0fb 147 print_signal_exited_reason (tui->interp_ui_out (), siggnal);
73ab01a0 148 }
fd664c91
PA
149}
150
151/* Observer for the exited notification. */
152
153static void
154tui_on_exited (int exitstatus)
155{
0e454242 156 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
157 {
158 struct interp *tui = as_tui_interp (top_level_interpreter ());
159
160 if (tui == NULL)
161 continue;
162
d6f9b0fb 163 print_exited_reason (tui->interp_ui_out (), exitstatus);
73ab01a0 164 }
fd664c91
PA
165}
166
167/* Observer for the no_history notification. */
168
169static void
170tui_on_no_history (void)
171{
0e454242 172 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
173 {
174 struct interp *tui = as_tui_interp (top_level_interpreter ());
175
176 if (tui == NULL)
177 continue;
178
d6f9b0fb 179 print_no_history_reason (tui->interp_ui_out ());
73ab01a0 180 }
fd664c91
PA
181}
182
92bcb5f9
PA
183/* Observer for the sync_execution_done notification. */
184
185static void
186tui_on_sync_execution_done (void)
187{
73ab01a0
PA
188 struct interp *tui = as_tui_interp (top_level_interpreter ());
189
190 if (tui == NULL)
191 return;
192
193 display_gdb_prompt (NULL);
92bcb5f9
PA
194}
195
196/* Observer for the command_error notification. */
197
198static void
199tui_on_command_error (void)
200{
73ab01a0
PA
201 struct interp *tui = as_tui_interp (top_level_interpreter ());
202
203 if (tui == NULL)
204 return;
205
206 display_gdb_prompt (NULL);
92bcb5f9
PA
207}
208
4034d0ff
AT
209/* Observer for the user_selected_context_changed notification. */
210
211static void
212tui_on_user_selected_context_changed (user_selected_what selection)
213{
4034d0ff
AT
214 /* This event is suppressed. */
215 if (cli_suppress_notification.user_selected_context)
216 return;
217
151bb4a5 218 thread_info *tp = inferior_ptid != null_ptid ? inferior_thread () : NULL;
4034d0ff 219
0e454242 220 SWITCH_THRU_ALL_UIS ()
4034d0ff
AT
221 {
222 struct interp *tui = as_tui_interp (top_level_interpreter ());
223
224 if (tui == NULL)
225 continue;
226
227 if (selection & USER_SELECTED_INFERIOR)
d6f9b0fb 228 print_selected_inferior (tui->interp_ui_out ());
4034d0ff
AT
229
230 if (tp != NULL
231 && ((selection & (USER_SELECTED_THREAD | USER_SELECTED_FRAME))))
d6f9b0fb 232 print_selected_thread_frame (tui->interp_ui_out (), selection);
4034d0ff
AT
233
234 }
235}
236
021e7609
AC
237/* These implement the TUI interpreter. */
238
d6f9b0fb
PA
239void
240tui_interp::init (bool top_level)
021e7609
AC
241{
242 /* Install exit handler to leave the screen in a good shape. */
243 atexit (tui_exit);
244
021e7609 245 tui_initialize_io ();
9612b5ec 246 tui_initialize_win ();
1180b2c8
L
247 if (ui_file_isatty (gdb_stdout))
248 tui_initialize_readline ();
021e7609
AC
249}
250
d6f9b0fb
PA
251void
252tui_interp::resume ()
021e7609 253{
3c216924 254 struct ui *ui = current_ui;
95cd630e
DJ
255 struct ui_file *stream;
256
1cc6d956
MS
257 /* gdb_setup_readline will change gdb_stdout. If the TUI was
258 previously writing to gdb_stdout, then set it to the new
259 gdb_stdout afterwards. */
95cd630e 260
112e8700 261 stream = tui_old_uiout->set_stream (gdb_stdout);
95cd630e
DJ
262 if (stream != gdb_stdout)
263 {
112e8700 264 tui_old_uiout->set_stream (stream);
95cd630e
DJ
265 stream = NULL;
266 }
267
3c216924
PA
268 gdb_setup_readline (1);
269
270 ui->input_handler = command_line_handler;
95cd630e
DJ
271
272 if (stream != NULL)
112e8700 273 tui_old_uiout->set_stream (gdb_stdout);
95cd630e 274
63858210
SC
275 if (tui_start_enabled)
276 tui_enable ();
021e7609
AC
277}
278
d6f9b0fb
PA
279void
280tui_interp::suspend ()
021e7609 281{
63858210 282 tui_start_enabled = tui_active;
021e7609 283 tui_disable ();
021e7609
AC
284}
285
d6f9b0fb
PA
286ui_out *
287tui_interp::interp_ui_out ()
4801a9a3
PA
288{
289 if (tui_active)
290 return tui_out;
291 else
292 return tui_old_uiout;
293}
294
d6f9b0fb
PA
295gdb_exception
296tui_interp::exec (const char *command_str)
021e7609 297{
e2e0b3e5 298 internal_error (__FILE__, __LINE__, _("tui_exec called"));
021e7609
AC
299}
300
8322445e
PA
301
302/* Factory for TUI interpreters. */
303
304static struct interp *
305tui_interp_factory (const char *name)
306{
d6f9b0fb 307 return new tui_interp (name);
8322445e
PA
308}
309
021e7609
AC
310void
311_initialize_tui_interp (void)
312{
8322445e
PA
313 interp_factory_register (INTERP_TUI, tui_interp_factory);
314
cc4349ed 315 if (interpreter_p && strcmp (interpreter_p, INTERP_TUI) == 0)
63858210
SC
316 tui_start_enabled = 1;
317
318 if (interpreter_p && strcmp (interpreter_p, INTERP_CONSOLE) == 0)
319 {
320 xfree (interpreter_p);
cc4349ed 321 interpreter_p = xstrdup (INTERP_TUI);
63858210 322 }
73ab01a0
PA
323
324 /* If changing this, remember to update cli-interp.c as well. */
76727919
TT
325 gdb::observers::normal_stop.attach (tui_on_normal_stop);
326 gdb::observers::signal_received.attach (tui_on_signal_received);
327 gdb::observers::end_stepping_range.attach (tui_on_end_stepping_range);
328 gdb::observers::signal_exited.attach (tui_on_signal_exited);
329 gdb::observers::exited.attach (tui_on_exited);
330 gdb::observers::no_history.attach (tui_on_no_history);
331 gdb::observers::sync_execution_done.attach (tui_on_sync_execution_done);
332 gdb::observers::command_error.attach (tui_on_command_error);
333 gdb::observers::user_selected_context_changed.attach
4034d0ff 334 (tui_on_user_selected_context_changed);
021e7609 335}
This page took 1.736389 seconds and 4 git commands to generate.