* gdb.base/display.c (do_loops): Add float variable `f'.
[deliverable/binutils-gdb.git] / gdb / tui / tui-hooks.c
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
47 int tui_target_has_run = 0;
48
49 static void (* tui_target_new_objfile_chain) (struct objfile*);
50 extern void (*selected_frame_level_changed_hook) (int);
51
52 static void
53 tui_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
64 static int
65 tui_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(). */
122 static int tui_refreshing_registers = 0;
123
124 static void
125 tui_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
140 static void
141 tui_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
154 extern struct breakpoint *breakpoint_chain;
155
156 /* Find a breakpoint given its number. Returns null if not found. */
157 static struct breakpoint *
158 get_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. */
172 static void
173 tui_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. */
196 static void
197 tui_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
224 static void
225 tui_event_modify_breakpoint (int number)
226 {
227 ;
228 }
229
230 static void
231 tui_event_default (int number)
232 {
233 ;
234 }
235
236 static struct gdb_events *tui_old_event_hooks;
237
238 static 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. */
250 static ptid_t
251 tui_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/...). */
276 static void
277 tui_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. */
310 static void
311 tui_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. */
319 void
320 tui_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. */
336 void
337 tui_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. */
351 static void
352 tui_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. */
361 static void
362 tui_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. */
384 void
385 _initialize_tui (void)
386 {
387 /* Setup initialization hook. */
388 init_ui_hook = tui_init_hook;
389 }
390
This page took 0.039941 seconds and 4 git commands to generate.