]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/tui/tui-hooks.c
* tui-hooks.c: New file, gdb hooks for tui.
[thirdparty/binutils-gdb.git] / gdb / tui / tui-hooks.c
CommitLineData
2611b1a5
SC
1/* GDB hooks for TUI.
2 Copyright 2001 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21#include "defs.h"
22#include "symtab.h"
23#include "inferior.h"
24#include "command.h"
25#include "bfd.h"
26#include "symfile.h"
27#include "objfiles.h"
28#include "target.h"
29#include "gdbcore.h"
30#include "event-loop.h"
31#include "frame.h"
32#include "breakpoint.h"
33#include "gdb-events.h"
34#include <unistd.h>
35#include <fcntl.h>
36
37#include "tui.h"
38#include "tuiData.h"
39#include "tuiLayout.h"
40#include "tuiIO.h"
41#include "tuiRegs.h"
42#include "tuiWin.h"
43#include "tuiStack.h"
44#include "tuiDataWin.h"
45#include "tuiSourceWin.h"
46
47int tui_target_has_run = 0;
48
49static void (* tui_target_new_objfile_chain) (struct objfile*);
50extern void (*selected_frame_level_changed_hook) (int);
51
52static void
53tui_new_objfile_hook (struct objfile* objfile)
54{
55 if (tui_active)
56 {
57 tuiDisplayMainFunction ();
58 }
59
60 if (tui_target_new_objfile_chain)
61 tui_target_new_objfile_chain (objfile);
62}
63
64static int
65tui_query_hook (const char * msg, va_list argp)
66{
67 int retval;
68 int ans2;
69 int answer;
70
71 /* Automatically answer "yes" if input is not from a terminal. */
72 if (!input_from_terminal_p ())
73 return 1;
74
75 echo ();
76 while (1)
77 {
78 wrap_here (""); /* Flush any buffered output */
79 gdb_flush (gdb_stdout);
80
81 vfprintf_filtered (gdb_stdout, msg, argp);
82 printf_filtered ("(y or n) ");
83
84 wrap_here ("");
85 gdb_flush (gdb_stdout);
86
87 answer = tui_getc (stdin);
88 clearerr (stdin); /* in case of C-d */
89 if (answer == EOF) /* C-d */
90 {
91 retval = 1;
92 break;
93 }
94 /* Eat rest of input line, to EOF or newline */
95 if (answer != '\n')
96 do
97 {
98 ans2 = tui_getc (stdin);
99 clearerr (stdin);
100 }
101 while (ans2 != EOF && ans2 != '\n' && ans2 != '\r');
102
103 if (answer >= 'a')
104 answer -= 040;
105 if (answer == 'Y')
106 {
107 retval = 1;
108 break;
109 }
110 if (answer == 'N')
111 {
112 retval = 0;
113 break;
114 }
115 printf_filtered ("Please answer y or n.\n");
116 }
117 noecho ();
118 return retval;
119}
120
121/* Prevent recursion of registers_changed_hook(). */
122static int tui_refreshing_registers = 0;
123
124static void
125tui_registers_changed_hook (void)
126{
127 struct frame_info *fi;
128
129 fi = selected_frame;
130 if (fi && tui_refreshing_registers == 0)
131 {
132 tui_refreshing_registers = 1;
133#if 0
134 tuiCheckDataValues (fi);
135#endif
136 tui_refreshing_registers = 0;
137 }
138}
139
140static void
141tui_register_changed_hook (int regno)
142{
143 struct frame_info *fi;
144
145 fi = selected_frame;
146 if (fi && tui_refreshing_registers == 0)
147 {
148 tui_refreshing_registers = 1;
149 tuiCheckDataValues (fi);
150 tui_refreshing_registers = 0;
151 }
152}
153
154extern struct breakpoint *breakpoint_chain;
155
156/* Find a breakpoint given its number. Returns null if not found. */
157static struct breakpoint *
158get_breakpoint (int number)
159{
160 struct breakpoint *bp;
161
162 for (bp = breakpoint_chain; bp; bp = bp->next)
163 {
164 if (bp->number == number)
165 return bp;
166 }
167 return 0;
168}
169
170/* Breakpoint creation hook.
171 Update the screen to show the new breakpoint. */
172static void
173tui_event_create_breakpoint (int number)
174{
175 struct breakpoint *bp;
176
177 bp = get_breakpoint (number);
178 if (bp)
179 {
180 switch (bp->type)
181 {
182 case bp_breakpoint:
183 case bp_hardware_breakpoint:
184 tuiAllSetHasBreakAt (bp, 1);
185 tuiUpdateAllExecInfos ();
186 break;
187
188 default:
189 break;
190 }
191 }
192}
193
194/* Breakpoint deletion hook.
195 Refresh the screen to update the breakpoint marks. */
196static void
197tui_event_delete_breakpoint (int number)
198{
199 struct breakpoint *bp;
200 struct breakpoint *b;
201 int clearIt;
202
203 bp = get_breakpoint (number);
204 if (bp == 0)
205 return;
206
207 /* Before turning off the visuals for the bp, check to see that
208 there are no other bps at the same address. */
209 clearIt = 0;
210 for (b = breakpoint_chain; b; b = b->next)
211 {
212 clearIt = (b == bp || b->address != bp->address);
213 if (!clearIt)
214 break;
215 }
216
217 if (clearIt)
218 {
219 tuiAllSetHasBreakAt (bp, 0);
220 tuiUpdateAllExecInfos ();
221 }
222}
223
224static void
225tui_event_modify_breakpoint (int number)
226{
227 ;
228}
229
230static void
231tui_event_default (int number)
232{
233 ;
234}
235
236static struct gdb_events *tui_old_event_hooks;
237
238static struct gdb_events tui_event_hooks =
239{
240 tui_event_create_breakpoint,
241 tui_event_delete_breakpoint,
242 tui_event_modify_breakpoint,
243 tui_event_default,
244 tui_event_default,
245 tui_event_default
246};
247
248/* Called when going to wait for the target.
249 Leave curses mode and setup program mode. */
250static ptid_t
251tui_target_wait_hook (ptid_t pid, struct target_waitstatus *status)
252{
253 ptid_t res;
254
255 /* Leave tui mode (optional). */
256#if 0
257 if (tui_active)
258 {
259 target_terminal_ours ();
260 endwin ();
261 target_terminal_inferior ();
262 }
263#endif
264 tui_target_has_run = 1;
265 res = target_wait (pid, status);
266
267 if (tui_active)
268 {
269 /* TODO: need to refresh (optional). */
270 }
271 return res;
272}
273
274/* The selected frame has changed. This is happens after a target
275 stop or when the user explicitly changes the frame (up/down/thread/...). */
276static void
277tui_selected_frame_level_changed_hook (int level)
278{
279 struct frame_info *fi;
280
281 fi = selected_frame;
282 /* Ensure that symbols for this frame are read in. Also, determine the
283 source language of this frame, and switch to it if desired. */
284 if (fi)
285 {
286 struct symtab *s;
287
288 s = find_pc_symtab (fi->pc);
289 /* elz: this if here fixes the problem with the pc not being displayed
290 in the tui asm layout, with no debug symbols. The value of s
291 would be 0 here, and select_source_symtab would abort the
292 command by calling the 'error' function */
293 if (s)
294 {
295 select_source_symtab (s);
296 tuiShowFrameInfo (fi);
297 }
298
299 /* Refresh the register window if it's visible. */
300 if (tui_is_window_visible (DATA_WIN))
301 {
302 tui_refreshing_registers = 1;
303 tuiCheckDataValues (fi);
304 tui_refreshing_registers = 0;
305 }
306 }
307}
308
309/* Called from print_frame_info to list the line we stopped in. */
310static void
311tui_print_frame_info_listing_hook (struct symtab *s, int line,
312 int stopline, int noerror)
313{
314 select_source_symtab (s);
315 tuiShowFrameInfo (selected_frame);
316}
317
318/* Install the TUI specific hooks. */
319void
320tui_install_hooks (void)
321{
322 target_wait_hook = tui_target_wait_hook;
323 selected_frame_level_changed_hook = tui_selected_frame_level_changed_hook;
324 print_frame_info_listing_hook = tui_print_frame_info_listing_hook;
325
326 query_hook = tui_query_hook;
327
328 /* Install the event hooks. */
329 tui_old_event_hooks = set_gdb_event_hooks (&tui_event_hooks);
330
331 registers_changed_hook = tui_registers_changed_hook;
332 register_changed_hook = tui_register_changed_hook;
333}
334
335/* Remove the TUI specific hooks. */
336void
337tui_remove_hooks (void)
338{
339 target_wait_hook = 0;
340 selected_frame_level_changed_hook = 0;
341 print_frame_info_listing_hook = 0;
342 query_hook = 0;
343 registers_changed_hook = 0;
344 register_changed_hook = 0;
345
346 /* Restore the previous event hooks. */
347 set_gdb_event_hooks (tui_old_event_hooks);
348}
349
350/* Cleanup the tui before exiting. */
351static void
352tui_exit (void)
353{
354 /* Disable the tui. Curses mode is left leaving the screen
355 in a clean state (see endwin()). */
356 tui_disable ();
357}
358
359/* Initialize the tui by installing several gdb hooks, initializing
360 the tui IO and preparing the readline with the kind binding. */
361static void
362tui_init_hook (char *argv0)
363{
364 /* Install exit handler to leave the screen in a good shape. */
365 atexit (tui_exit);
366
367 initializeStaticData ();
368
369 /* Install the permanent hooks. */
370 tui_target_new_objfile_chain = target_new_objfile_hook;
371 target_new_objfile_hook = tui_new_objfile_hook;
372
373 tui_initialize_io ();
374 tui_initialize_readline ();
375
376 /* Decide in which mode to start using GDB (based on -tui). */
377 if (tui_version)
378 {
379 tui_enable ();
380 }
381}
382
383/* Initialize the tui. */
384void
385_initialize_tui (void)
386{
387 /* Setup initialization hook. */
388 init_ui_hook = tui_init_hook;
389}
390