]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/gdb/gdb/tui/tui-hooks.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / gdb / gdb / tui / tui-hooks.c
1 /* GDB hooks for TUI.
2
3    Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
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
9    the Free Software Foundation; either version 2 of the License, or
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
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.  */
21
22 #include "defs.h"
23 #include "symtab.h"
24 #include "inferior.h"
25 #include "command.h"
26 #include "bfd.h"
27 #include "symfile.h"
28 #include "objfiles.h"
29 #include "target.h"
30 #include "gdbcore.h"
31 #include "event-loop.h"
32 #include "event-top.h"
33 #include "frame.h"
34 #include "breakpoint.h"
35 #include "gdb-events.h"
36 #include "ui-out.h"
37 #include "top.h"
38 #include "readline/readline.h"
39 #include <unistd.h>
40 #include <fcntl.h>
41
42 #include "tui/tui.h"
43 #include "tui/tui-hooks.h"
44 #include "tui/tui-data.h"
45 #include "tui/tui-layout.h"
46 #include "tui/tui-io.h"
47 #include "tui/tui-regs.h"
48 #include "tui/tui-win.h"
49 #include "tui/tui-stack.h"
50 #include "tui/tui-windata.h"
51 #include "tui/tui-winsource.h"
52
53 #include "gdb_curses.h"
54
55 int tui_target_has_run = 0;
56
57 static void (* tui_target_new_objfile_chain) (struct objfile*);
58
59 static void
60 tui_new_objfile_hook (struct objfile* objfile)
61 {
62   if (tui_active)
63     tui_display_main ();
64   
65   if (tui_target_new_objfile_chain)
66     tui_target_new_objfile_chain (objfile);
67 }
68
69 static int
70 tui_query_hook (const char * msg, va_list argp)
71 {
72   int retval;
73   int ans2;
74   int answer;
75
76   /* Automatically answer "yes" if input is not from a terminal.  */
77   if (!input_from_terminal_p ())
78     return 1;
79
80   echo ();
81   while (1)
82     {
83       wrap_here ("");           /* Flush any buffered output */
84       gdb_flush (gdb_stdout);
85
86       vfprintf_filtered (gdb_stdout, msg, argp);
87       printf_filtered ("(y or n) ");
88
89       wrap_here ("");
90       gdb_flush (gdb_stdout);
91
92       answer = tui_getc (stdin);
93       clearerr (stdin);         /* in case of C-d */
94       if (answer == EOF)        /* C-d */
95         {
96           retval = 1;
97           break;
98         }
99       /* Eat rest of input line, to EOF or newline */
100       if (answer != '\n')
101         do
102           {
103             ans2 = tui_getc (stdin);
104             clearerr (stdin);
105           }
106         while (ans2 != EOF && ans2 != '\n' && ans2 != '\r');
107
108       if (answer >= 'a')
109         answer -= 040;
110       if (answer == 'Y')
111         {
112           retval = 1;
113           break;
114         }
115       if (answer == 'N')
116         {
117           retval = 0;
118           break;
119         }
120       printf_filtered ("Please answer y or n.\n");
121     }
122   noecho ();
123   return retval;
124 }
125
126 /* Prevent recursion of registers_changed_hook().  */
127 static int tui_refreshing_registers = 0;
128
129 static void
130 tui_registers_changed_hook (void)
131 {
132   struct frame_info *fi;
133
134   fi = deprecated_selected_frame;
135   if (fi && tui_refreshing_registers == 0)
136     {
137       tui_refreshing_registers = 1;
138 #if 0
139       tui_check_data_values (fi);
140 #endif
141       tui_refreshing_registers = 0;
142     }
143 }
144
145 static void
146 tui_register_changed_hook (int regno)
147 {
148   struct frame_info *fi;
149
150   fi = deprecated_selected_frame;
151   if (fi && tui_refreshing_registers == 0)
152     {
153       tui_refreshing_registers = 1;
154       tui_check_data_values (fi);
155       tui_refreshing_registers = 0;
156     }
157 }
158
159 /* Breakpoint creation hook.
160    Update the screen to show the new breakpoint.  */
161 static void
162 tui_event_create_breakpoint (int number)
163 {
164   tui_update_all_breakpoint_info ();
165 }
166
167 /* Breakpoint deletion hook.
168    Refresh the screen to update the breakpoint marks.  */
169 static void
170 tui_event_delete_breakpoint (int number)
171 {
172   tui_update_all_breakpoint_info ();
173 }
174
175 static void
176 tui_event_modify_breakpoint (int number)
177 {
178   tui_update_all_breakpoint_info ();
179 }
180
181 static void
182 tui_event_default (int number)
183 {
184   ;
185 }
186
187 static struct gdb_events *tui_old_event_hooks;
188
189 static struct gdb_events tui_event_hooks =
190 {
191   tui_event_create_breakpoint,
192   tui_event_delete_breakpoint,
193   tui_event_modify_breakpoint,
194   tui_event_default,
195   tui_event_default,
196   tui_event_default
197 };
198
199 /* Called when going to wait for the target.
200    Leave curses mode and setup program mode.  */
201 static ptid_t
202 tui_target_wait_hook (ptid_t pid, struct target_waitstatus *status)
203 {
204   ptid_t res;
205
206   /* Leave tui mode (optional).  */
207 #if 0
208   if (tui_active)
209     {
210       target_terminal_ours ();
211       endwin ();
212       target_terminal_inferior ();
213     }
214 #endif
215   tui_target_has_run = 1;
216   res = target_wait (pid, status);
217
218   if (tui_active)
219     {
220       /* TODO: need to refresh (optional).  */
221     }
222   return res;
223 }
224
225 /* The selected frame has changed.  This is happens after a target
226    stop or when the user explicitly changes the frame (up/down/thread/...).  */
227 static void
228 tui_selected_frame_level_changed_hook (int level)
229 {
230   struct frame_info *fi;
231
232   fi = deprecated_selected_frame;
233   /* Ensure that symbols for this frame are read in.  Also, determine the
234      source language of this frame, and switch to it if desired.  */
235   if (fi)
236     {
237       struct symtab *s;
238       
239       s = find_pc_symtab (get_frame_pc (fi));
240       /* elz: this if here fixes the problem with the pc not being displayed
241          in the tui asm layout, with no debug symbols. The value of s 
242          would be 0 here, and select_source_symtab would abort the
243          command by calling the 'error' function */
244       if (s)
245         select_source_symtab (s);
246
247       /* Display the frame position (even if there is no symbols).  */
248       tui_show_frame_info (fi);
249
250       /* Refresh the register window if it's visible.  */
251       if (tui_is_window_visible (DATA_WIN))
252         {
253           tui_refreshing_registers = 1;
254           tui_check_data_values (fi);
255           tui_refreshing_registers = 0;
256         }
257     }
258 }
259
260 /* Called from print_frame_info to list the line we stopped in.  */
261 static void
262 tui_print_frame_info_listing_hook (struct symtab *s, int line,
263                                    int stopline, int noerror)
264 {
265   select_source_symtab (s);
266   tui_show_frame_info (deprecated_selected_frame);
267 }
268
269 /* Called when the target process died or is detached.
270    Update the status line.  */
271 static void
272 tui_detach_hook (void)
273 {
274   tui_show_frame_info (0);
275   tui_display_main ();
276 }
277
278 /* Install the TUI specific hooks.  */
279 void
280 tui_install_hooks (void)
281 {
282   target_wait_hook = tui_target_wait_hook;
283   selected_frame_level_changed_hook = tui_selected_frame_level_changed_hook;
284   print_frame_info_listing_hook = tui_print_frame_info_listing_hook;
285
286   query_hook = tui_query_hook;
287
288   /* Install the event hooks.  */
289   tui_old_event_hooks = set_gdb_event_hooks (&tui_event_hooks);
290
291   registers_changed_hook = tui_registers_changed_hook;
292   register_changed_hook = tui_register_changed_hook;
293   detach_hook = tui_detach_hook;
294 }
295
296 /* Remove the TUI specific hooks.  */
297 void
298 tui_remove_hooks (void)
299 {
300   target_wait_hook = 0;
301   selected_frame_level_changed_hook = 0;
302   print_frame_info_listing_hook = 0;
303   query_hook = 0;
304   registers_changed_hook = 0;
305   register_changed_hook = 0;
306   detach_hook = 0;
307
308   /* Restore the previous event hooks.  */
309   set_gdb_event_hooks (tui_old_event_hooks);
310 }
311
312 void _initialize_tui_hooks (void);
313
314 void
315 _initialize_tui_hooks (void)
316 {
317   /* Install the permanent hooks.  */
318   tui_target_new_objfile_chain = target_new_objfile_hook;
319   target_new_objfile_hook = tui_new_objfile_hook;
320 }