1 /* General functions for the WDB TUI.
3 Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
6 Contributed by Hewlett-Packard Company.
8 This file is part of GDB.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
25 /* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
26 "defs.h" should be included first. Unfortunatly some systems
27 (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
28 and they clash with "bfd.h"'s definiton of true/false. The correct
29 fix is to remove true/false from "bfd.h", however, until that
30 happens, hack around it by including "config.h" and <curses.h>
59 #include "tuiLayout.h"
64 #include "tuiSourceWin.h"
65 #include "readline/readline.h"
68 #include "breakpoint.h"
71 /* Tells whether the TUI is active or not. */
73 static int tui_finish_init
= 1;
75 /* Switch the output mode between TUI/standard gdb. */
77 tui_switch_mode (void)
84 printf_filtered ("Left the TUI mode\n");
88 rl_deprep_terminal ();
90 printf_filtered ("Entered the TUI mode\n");
93 /* Clear the readline in case switching occurred in middle of something. */
95 rl_kill_text (0, rl_end
);
97 /* Since we left the curses mode, the terminal mode is restored to
98 some previous state. That state may not be suitable for readline
99 to work correctly (it may be restored in line mode). We force an
100 exit of the current readline so that readline is re-entered and it
101 will be able to setup the terminal for its needs. By re-entering
102 in readline, we also redisplay its prompt in the non-curses mode. */
103 rl_newline (1, '\n');
105 /* Make sure the \n we are returning does not repeat the last command. */
110 /* Change the TUI layout to show a next layout.
111 This function is bound to CTRL-X 2. It is intended to provide
112 a functionality close to the Emacs split-window command. We always
113 show two windows (src+asm), (src+regs) or (asm+regs). */
115 tui_change_windows (void)
122 TuiLayoutType new_layout
;
123 TuiRegisterDisplayType regs_type
= TUI_UNDEFINED_REGS
;
125 new_layout
= currentLayout ();
127 /* Select a new layout to have a rolling layout behavior
128 with always two windows (except when undefined). */
132 new_layout
= SRC_DISASSEM_COMMAND
;
135 case DISASSEM_COMMAND
:
136 new_layout
= SRC_DISASSEM_COMMAND
;
139 case SRC_DATA_COMMAND
:
140 new_layout
= SRC_DISASSEM_COMMAND
;
143 case SRC_DISASSEM_COMMAND
:
144 new_layout
= DISASSEM_DATA_COMMAND
;
147 case DISASSEM_DATA_COMMAND
:
148 new_layout
= SRC_DATA_COMMAND
;
152 new_layout
= SRC_COMMAND
;
155 tuiSetLayout (new_layout
, regs_type
);
161 /* Delete the second TUI window to only show one. */
163 tui_delete_other_windows (void)
170 TuiLayoutType new_layout
;
171 TuiRegisterDisplayType regs_type
= TUI_UNDEFINED_REGS
;
173 new_layout
= currentLayout ();
175 /* Kill one window. */
179 case SRC_DATA_COMMAND
:
180 case SRC_DISASSEM_COMMAND
:
182 new_layout
= SRC_COMMAND
;
185 case DISASSEM_COMMAND
:
186 case DISASSEM_DATA_COMMAND
:
187 new_layout
= DISASSEM_COMMAND
;
190 tuiSetLayout (new_layout
, regs_type
);
195 /* Initialize readline and configure the keymap for the switching
198 tui_initialize_readline ()
202 rl_add_defun ("tui-switch-mode", tui_switch_mode
, -1);
203 rl_bind_key_in_map ('a', tui_switch_mode
, emacs_ctlx_keymap
);
204 rl_bind_key_in_map ('A', tui_switch_mode
, emacs_ctlx_keymap
);
205 rl_bind_key_in_map (CTRL ('A'), tui_switch_mode
, emacs_ctlx_keymap
);
206 rl_bind_key_in_map ('1', tui_delete_other_windows
, emacs_ctlx_keymap
);
207 rl_bind_key_in_map ('2', tui_change_windows
, emacs_ctlx_keymap
);
210 /* Enter in the tui mode (curses).
211 When in normal mode, it installs the tui hooks in gdb, redirects
212 the gdb output, configures the readline to work in tui mode.
213 When in curses mode, it does nothing. */
220 /* To avoid to initialize curses when gdb starts, there is a defered
221 curses initialization. This initialization is made only once
222 and the first time the curses mode is entered. */
236 setTermHeightTo (LINES
);
237 setTermWidthTo (COLS
);
240 tuiShowFrameInfo (0);
241 tuiSetLayout (SRC_COMMAND
, TUI_UNDEFINED_REGS
);
242 tuiSetWinFocusTo (srcWin
);
243 keypad (cmdWin
->generic
.handle
, TRUE
);
244 wrefresh (cmdWin
->generic
.handle
);
249 /* Save the current gdb setting of the terminal.
250 Curses will restore this state when endwin() is called. */
252 clearok (stdscr
, TRUE
);
255 /* Install the TUI specific hooks. */
256 tui_install_hooks ();
258 tui_update_variables ();
265 tuiShowFrameInfo (selected_frame
);
268 tui_update_gdb_sizes ();
271 /* Leave the tui mode.
272 Remove the tui hooks and configure the gdb output and readline
273 back to their original state. The curses mode is left so that
274 the terminal setting is restored to the point when we entered. */
281 /* Remove TUI hooks. */
284 /* Leave curses and restore previous gdb terminal setting. */
287 /* gdb terminal has changed, update gdb internal copy of it
288 so that terminal management with the inferior works. */
293 tui_update_gdb_sizes ();
296 /* Wrapper on top of free() to ensure that input address
297 is greater than 0x0. */
301 if (ptr
!= (char *) NULL
)
307 /* Determine what the low address will be to display in the TUI's
308 disassembly window. This may or may not be the same as the
309 low address input. */
311 tuiGetLowDisassemblyAddress (CORE_ADDR low
, CORE_ADDR pc
)
316 /* Determine where to start the disassembly so that the pc is about in the
317 middle of the viewport. */
318 for (line
= 0, newLow
= pc
;
320 line
< (tuiDefaultWinViewportHeight (DISASSEM_WIN
,
321 DISASSEM_COMMAND
) / 2));)
325 newLow
-= sizeof (bfd_getb32 (buffer
));
333 strcat_to_buf (char *buf
, int buflen
, const char *itemToAdd
)
335 if (itemToAdd
!= (char *) NULL
&& buf
!= (char *) NULL
)
337 if ((strlen (buf
) + strlen (itemToAdd
)) <= buflen
)
338 strcat (buf
, itemToAdd
);
340 strncat (buf
, itemToAdd
, (buflen
- strlen (buf
)));
345 /* Solaris <sys/termios.h> defines CTRL. */
347 #define CTRL(x) (x & ~0140)
351 #define CHK(val, dft) (val<=0 ? dft : val)
359 ** reset the teletype mode bits to a sensible state.
362 #if ! defined (USG) && defined (TIOCGETC)
364 #endif /* !USG && TIOCGETC */
368 if (ldisc
== NTTYDISC
)
370 ioctl (FILEDES
, TIOCGLTC
, <c
);
371 ltc
.t_suspc
= CHK (ltc
.t_suspc
, CTRL ('Z'));
372 ltc
.t_dsuspc
= CHK (ltc
.t_dsuspc
, CTRL ('Y'));
373 ltc
.t_rprntc
= CHK (ltc
.t_rprntc
, CTRL ('R'));
374 ltc
.t_flushc
= CHK (ltc
.t_flushc
, CTRL ('O'));
375 ltc
.t_werasc
= CHK (ltc
.t_werasc
, CTRL ('W'));
376 ltc
.t_lnextc
= CHK (ltc
.t_lnextc
, CTRL ('V'));
377 ioctl (FILEDES
, TIOCSLTC
, <c
);
379 #endif /* UCB_NTTY */
382 ioctl (FILEDES
, TIOCGETC
, &tbuf
);
383 tbuf
.t_intrc
= CHK (tbuf
.t_intrc
, CTRL ('?'));
384 tbuf
.t_quitc
= CHK (tbuf
.t_quitc
, CTRL ('\\'));
385 tbuf
.t_startc
= CHK (tbuf
.t_startc
, CTRL ('Q'));
386 tbuf
.t_stopc
= CHK (tbuf
.t_stopc
, CTRL ('S'));
387 tbuf
.t_eofc
= CHK (tbuf
.t_eofc
, CTRL ('D'));
388 /* brkc is left alone */
389 ioctl (FILEDES
, TIOCSETC
, &tbuf
);
390 #endif /* TIOCGETC */
391 mode
.sg_flags
&= ~(RAW
395 | VTDELAY
| ALLDELAY
);
396 mode
.sg_flags
|= XTABS
| ECHO
| CRMOD
| ANYP
;
398 ioctl (FILEDES
, TCGETA
, &mode
);
399 mode
.c_cc
[VINTR
] = CHK (mode
.c_cc
[VINTR
], CTRL ('?'));
400 mode
.c_cc
[VQUIT
] = CHK (mode
.c_cc
[VQUIT
], CTRL ('\\'));
401 mode
.c_cc
[VEOF
] = CHK (mode
.c_cc
[VEOF
], CTRL ('D'));
403 mode
.c_iflag
&= ~(IGNBRK
| PARMRK
| INPCK
| INLCR
| IGNCR
| IUCLC
| IXOFF
);
404 mode
.c_iflag
|= (BRKINT
| ISTRIP
| ICRNL
| IXON
);
405 mode
.c_oflag
&= ~(OLCUC
| OCRNL
| ONOCR
| ONLRET
| OFILL
| OFDEL
|
406 NLDLY
| CRDLY
| TABDLY
| BSDLY
| VTDLY
| FFDLY
);
407 mode
.c_oflag
|= (OPOST
| ONLCR
);
408 mode
.c_cflag
&= ~(CSIZE
| PARODD
| CLOCAL
);
410 mode
.c_cflag
|= (CS8
| CREAD
);
411 #else /*hp9000s800 */
412 mode
.c_cflag
|= (CS8
| CSTOPB
| CREAD
);
413 #endif /* hp9000s800 */
414 mode
.c_lflag
&= ~(XCASE
| ECHONL
| NOFLSH
);
415 mode
.c_lflag
|= (ISIG
| ICANON
| ECHO
| ECHOK
);
416 ioctl (FILEDES
, TCSETAW
, &mode
);
424 tui_show_source (const char *file
, int line
)
426 /* make sure that the source window is displayed */
427 tuiAddWinToLayout (SRC_WIN
);
429 tuiUpdateSourceWindowsWithLine (current_source_symtab
, line
);
430 tuiUpdateLocatorFilename (file
);
434 tui_show_assembly (CORE_ADDR addr
)
436 tuiAddWinToLayout (DISASSEM_WIN
);
437 tuiUpdateSourceWindowsWithAddr (addr
);
441 tui_is_window_visible (TuiWinType type
)
443 if (tui_version
== 0)
446 if (winList
[type
] == 0)
449 return winList
[type
]->generic
.isVisible
;
453 tui_get_command_dimension (int *width
, int *height
)
455 if (!tui_version
|| !m_winPtrNotNull (cmdWin
))
460 *width
= cmdWin
->generic
.width
;
461 *height
= cmdWin
->generic
.height
;