2007-08-14 Michael Snyder <msnyder@access-company.com>
[platform/upstream/binutils.git] / gdb / tui / tui-hooks.c
1 /* GDB hooks for TUI.
2
3    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
4    Free Software Foundation, Inc.
5
6    This file is part of GDB.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor,
21    Boston, MA 02110-1301, USA.  */
22
23 #include "defs.h"
24 #include "symtab.h"
25 #include "inferior.h"
26 #include "command.h"
27 #include "bfd.h"
28 #include "symfile.h"
29 #include "objfiles.h"
30 #include "target.h"
31 #include "gdbcore.h"
32 #include "event-loop.h"
33 #include "event-top.h"
34 #include "frame.h"
35 #include "breakpoint.h"
36 #include "gdb-events.h"
37 #include "ui-out.h"
38 #include "top.h"
39 #include "observer.h"
40 #include <unistd.h>
41 #include <fcntl.h>
42
43 #include "tui/tui.h"
44 #include "tui/tui-hooks.h"
45 #include "tui/tui-data.h"
46 #include "tui/tui-layout.h"
47 #include "tui/tui-io.h"
48 #include "tui/tui-regs.h"
49 #include "tui/tui-win.h"
50 #include "tui/tui-stack.h"
51 #include "tui/tui-windata.h"
52 #include "tui/tui-winsource.h"
53
54 #include "gdb_curses.h"
55
56 /* This redefines CTRL if it is not already defined, so it must come
57    after terminal state releated include files like <term.h> and
58    "gdb_curses.h".  */
59 #include "readline/readline.h"
60
61 int tui_target_has_run = 0;
62
63 static void
64 tui_new_objfile_hook (struct objfile* objfile)
65 {
66   if (tui_active)
67     tui_display_main ();
68 }
69
70 static int ATTR_FORMAT (printf, 1, 0)
71 tui_query_hook (const char *msg, va_list argp)
72 {
73   int retval;
74   int ans2;
75   int answer;
76
77   echo ();
78   while (1)
79     {
80       wrap_here ("");           /* Flush any buffered output.  */
81       gdb_flush (gdb_stdout);
82
83       vfprintf_filtered (gdb_stdout, msg, argp);
84       printf_filtered (_("(y or n) "));
85
86       wrap_here ("");
87       gdb_flush (gdb_stdout);
88
89       answer = tui_getc (stdin);
90       clearerr (stdin);         /* in case of C-d */
91       if (answer == EOF)        /* C-d */
92         {
93           retval = 1;
94           break;
95         }
96       /* Eat rest of input line, to EOF or newline.  */
97       if (answer != '\n')
98         do
99           {
100             ans2 = tui_getc (stdin);
101             clearerr (stdin);
102           }
103         while (ans2 != EOF && ans2 != '\n' && ans2 != '\r');
104
105       if (answer >= 'a')
106         answer -= 040;
107       if (answer == 'Y')
108         {
109           retval = 1;
110           break;
111         }
112       if (answer == 'N')
113         {
114           retval = 0;
115           break;
116         }
117       printf_filtered (_("Please answer y or n.\n"));
118     }
119   noecho ();
120   return retval;
121 }
122
123 /* Prevent recursion of deprecated_register_changed_hook().  */
124 static int tui_refreshing_registers = 0;
125
126 static void
127 tui_register_changed_hook (int regno)
128 {
129   struct frame_info *fi;
130
131   fi = get_selected_frame (NULL);
132   if (tui_refreshing_registers == 0)
133     {
134       tui_refreshing_registers = 1;
135       tui_check_data_values (fi);
136       tui_refreshing_registers = 0;
137     }
138 }
139
140 /* Breakpoint creation hook.
141    Update the screen to show the new breakpoint.  */
142 static void
143 tui_event_create_breakpoint (int number)
144 {
145   tui_update_all_breakpoint_info ();
146 }
147
148 /* Breakpoint deletion hook.
149    Refresh the screen to update the breakpoint marks.  */
150 static void
151 tui_event_delete_breakpoint (int number)
152 {
153   tui_update_all_breakpoint_info ();
154 }
155
156 static void
157 tui_event_modify_breakpoint (int number)
158 {
159   tui_update_all_breakpoint_info ();
160 }
161
162 static void
163 tui_event_default (int number)
164 {
165   ;
166 }
167
168 static struct gdb_events *tui_old_event_hooks;
169
170 static struct gdb_events tui_event_hooks =
171 {
172   tui_event_create_breakpoint,
173   tui_event_delete_breakpoint,
174   tui_event_modify_breakpoint,
175   tui_event_default,
176   tui_event_default,
177   tui_event_default
178 };
179
180 /* Called when going to wait for the target.
181    Leave curses mode and setup program mode.  */
182 static ptid_t
183 tui_target_wait_hook (ptid_t pid, struct target_waitstatus *status)
184 {
185   ptid_t res;
186
187   /* Leave tui mode (optional).  */
188 #if 0
189   if (tui_active)
190     {
191       target_terminal_ours ();
192       endwin ();
193       target_terminal_inferior ();
194     }
195 #endif
196   tui_target_has_run = 1;
197   res = target_wait (pid, status);
198
199   if (tui_active)
200     {
201       /* TODO: need to refresh (optional).  */
202     }
203   return res;
204 }
205
206 /* The selected frame has changed.  This is happens after a target
207    stop or when the user explicitly changes the frame
208    (up/down/thread/...).  */
209 static void
210 tui_selected_frame_level_changed_hook (int level)
211 {
212   struct frame_info *fi;
213
214   /* Negative level means that the selected frame was cleared.  */
215   if (level < 0)
216     return;
217
218   fi = get_selected_frame (NULL);
219   /* Ensure that symbols for this frame are read in.  Also, determine
220      the source language of this frame, and switch to it if
221      desired.  */
222   if (fi)
223     {
224       struct symtab *s;
225       
226       s = find_pc_symtab (get_frame_pc (fi));
227       /* elz: This if here fixes the problem with the pc not being
228          displayed in the tui asm layout, with no debug symbols.  The
229          value of s would be 0 here, and select_source_symtab would
230          abort the command by calling the 'error' function.  */
231       if (s)
232         select_source_symtab (s);
233
234       /* Display the frame position (even if there is no symbols).  */
235       tui_show_frame_info (fi);
236
237       /* Refresh the register window if it's visible.  */
238       if (tui_is_window_visible (DATA_WIN))
239         {
240           tui_refreshing_registers = 1;
241           tui_check_data_values (fi);
242           tui_refreshing_registers = 0;
243         }
244     }
245 }
246
247 /* Called from print_frame_info to list the line we stopped in.  */
248 static void
249 tui_print_frame_info_listing_hook (struct symtab *s, int line,
250                                    int stopline, int noerror)
251 {
252   select_source_symtab (s);
253   tui_show_frame_info (get_selected_frame (NULL));
254 }
255
256 /* Called when the target process died or is detached.
257    Update the status line.  */
258 static void
259 tui_detach_hook (void)
260 {
261   tui_show_frame_info (0);
262   tui_display_main ();
263 }
264
265 /* Install the TUI specific hooks.  */
266 void
267 tui_install_hooks (void)
268 {
269   deprecated_target_wait_hook = tui_target_wait_hook;
270   deprecated_selected_frame_level_changed_hook = tui_selected_frame_level_changed_hook;
271   deprecated_print_frame_info_listing_hook = tui_print_frame_info_listing_hook;
272
273   deprecated_query_hook = tui_query_hook;
274
275   /* Install the event hooks.  */
276   tui_old_event_hooks = deprecated_set_gdb_event_hooks (&tui_event_hooks);
277
278   deprecated_register_changed_hook = tui_register_changed_hook;
279   deprecated_detach_hook = tui_detach_hook;
280 }
281
282 /* Remove the TUI specific hooks.  */
283 void
284 tui_remove_hooks (void)
285 {
286   deprecated_target_wait_hook = 0;
287   deprecated_selected_frame_level_changed_hook = 0;
288   deprecated_print_frame_info_listing_hook = 0;
289   deprecated_query_hook = 0;
290   deprecated_register_changed_hook = 0;
291   deprecated_detach_hook = 0;
292
293   /* Restore the previous event hooks.  */
294   deprecated_set_gdb_event_hooks (tui_old_event_hooks);
295 }
296
297 void _initialize_tui_hooks (void);
298
299 void
300 _initialize_tui_hooks (void)
301 {
302   /* Install the permanent hooks.  */
303   observer_attach_new_objfile (tui_new_objfile_hook);
304 }