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>
57 #include "tuiLayout.h"
62 #include "tuiSourceWin.h"
63 #include "readline/readline.h"
66 #include "breakpoint.h"
69 /* Tells whether the TUI is active or not. */
71 static int tui_finish_init
= 1;
73 /* Switch the output mode between TUI/standard gdb. */
75 tui_switch_mode (void)
82 printf_filtered ("Left the TUI mode\n");
86 rl_deprep_terminal ();
88 printf_filtered ("Entered the TUI mode\n");
91 /* Clear the readline in case switching occurred in middle of something. */
93 rl_kill_text (0, rl_end
);
95 /* Since we left the curses mode, the terminal mode is restored to
96 some previous state. That state may not be suitable for readline
97 to work correctly (it may be restored in line mode). We force an
98 exit of the current readline so that readline is re-entered and it
99 will be able to setup the terminal for its needs. By re-entering
100 in readline, we also redisplay its prompt in the non-curses mode. */
101 rl_newline (1, '\n');
103 /* Make sure the \n we are returning does not repeat the last command. */
108 /* Change the TUI layout to show a next layout.
109 This function is bound to CTRL-X 2. It is intended to provide
110 a functionality close to the Emacs split-window command. We always
111 show two windows (src+asm), (src+regs) or (asm+regs). */
113 tui_change_windows (void)
120 TuiLayoutType new_layout
;
121 TuiRegisterDisplayType regs_type
= TUI_UNDEFINED_REGS
;
123 new_layout
= currentLayout ();
125 /* Select a new layout to have a rolling layout behavior
126 with always two windows (except when undefined). */
130 new_layout
= SRC_DISASSEM_COMMAND
;
133 case DISASSEM_COMMAND
:
134 new_layout
= SRC_DISASSEM_COMMAND
;
137 case SRC_DATA_COMMAND
:
138 new_layout
= SRC_DISASSEM_COMMAND
;
141 case SRC_DISASSEM_COMMAND
:
142 new_layout
= DISASSEM_DATA_COMMAND
;
145 case DISASSEM_DATA_COMMAND
:
146 new_layout
= SRC_DATA_COMMAND
;
150 new_layout
= SRC_COMMAND
;
153 tuiSetLayout (new_layout
, regs_type
);
159 /* Delete the second TUI window to only show one. */
161 tui_delete_other_windows (void)
168 TuiLayoutType new_layout
;
169 TuiRegisterDisplayType regs_type
= TUI_UNDEFINED_REGS
;
171 new_layout
= currentLayout ();
173 /* Kill one window. */
177 case SRC_DATA_COMMAND
:
178 case SRC_DISASSEM_COMMAND
:
180 new_layout
= SRC_COMMAND
;
183 case DISASSEM_COMMAND
:
184 case DISASSEM_DATA_COMMAND
:
185 new_layout
= DISASSEM_COMMAND
;
188 tuiSetLayout (new_layout
, regs_type
);
193 /* Initialize readline and configure the keymap for the switching
196 tui_initialize_readline ()
200 rl_add_defun ("tui-switch-mode", tui_switch_mode
, -1);
201 rl_bind_key_in_map ('a', tui_switch_mode
, emacs_ctlx_keymap
);
202 rl_bind_key_in_map ('A', tui_switch_mode
, emacs_ctlx_keymap
);
203 rl_bind_key_in_map (CTRL ('A'), tui_switch_mode
, emacs_ctlx_keymap
);
204 rl_bind_key_in_map ('1', tui_delete_other_windows
, emacs_ctlx_keymap
);
205 rl_bind_key_in_map ('2', tui_change_windows
, emacs_ctlx_keymap
);
208 /* Enter in the tui mode (curses).
209 When in normal mode, it installs the tui hooks in gdb, redirects
210 the gdb output, configures the readline to work in tui mode.
211 When in curses mode, it does nothing. */
218 /* To avoid to initialize curses when gdb starts, there is a defered
219 curses initialization. This initialization is made only once
220 and the first time the curses mode is entered. */
234 setTermHeightTo (LINES
);
235 setTermWidthTo (COLS
);
238 tuiSetLocatorContent (0);
239 showLayout (SRC_COMMAND
);
240 tuiSetWinFocusTo (srcWin
);
241 keypad (cmdWin
->generic
.handle
, TRUE
);
242 wrefresh (cmdWin
->generic
.handle
);
247 /* Save the current gdb setting of the terminal.
248 Curses will restore this state when endwin() is called. */
250 clearok (stdscr
, TRUE
);
253 /* Install the TUI specific hooks. */
254 tui_install_hooks ();
256 tui_update_variables ();
265 /* Leave the tui mode.
266 Remove the tui hooks and configure the gdb output and readline
267 back to their original state. The curses mode is left so that
268 the terminal setting is restored to the point when we entered. */
275 /* Remove TUI hooks. */
278 /* Leave curses and restore previous gdb terminal setting. */
281 /* gdb terminal has changed, update gdb internal copy of it
282 so that terminal management with the inferior works. */
289 /* Wrapper on top of free() to ensure that input address
290 is greater than 0x0. */
294 if (ptr
!= (char *) NULL
)
300 /* Determine what the low address will be to display in the TUI's
301 disassembly window. This may or may not be the same as the
302 low address input. */
304 tuiGetLowDisassemblyAddress (CORE_ADDR low
, CORE_ADDR pc
)
309 /* Determine where to start the disassembly so that the pc is about in the
310 middle of the viewport. */
311 for (line
= 0, newLow
= pc
;
313 line
< (tuiDefaultWinViewportHeight (DISASSEM_WIN
,
314 DISASSEM_COMMAND
) / 2));)
318 newLow
-= sizeof (bfd_getb32 (buffer
));
326 strcat_to_buf (char *buf
, int buflen
, char *itemToAdd
)
328 if (itemToAdd
!= (char *) NULL
&& buf
!= (char *) NULL
)
330 if ((strlen (buf
) + strlen (itemToAdd
)) <= buflen
)
331 strcat (buf
, itemToAdd
);
333 strncat (buf
, itemToAdd
, (buflen
- strlen (buf
)));
338 /* Solaris <sys/termios.h> defines CTRL. */
340 #define CTRL(x) (x & ~0140)
344 #define CHK(val, dft) (val<=0 ? dft : val)
352 ** reset the teletype mode bits to a sensible state.
355 #if ! defined (USG) && defined (TIOCGETC)
357 #endif /* !USG && TIOCGETC */
361 if (ldisc
== NTTYDISC
)
363 ioctl (FILEDES
, TIOCGLTC
, <c
);
364 ltc
.t_suspc
= CHK (ltc
.t_suspc
, CTRL ('Z'));
365 ltc
.t_dsuspc
= CHK (ltc
.t_dsuspc
, CTRL ('Y'));
366 ltc
.t_rprntc
= CHK (ltc
.t_rprntc
, CTRL ('R'));
367 ltc
.t_flushc
= CHK (ltc
.t_flushc
, CTRL ('O'));
368 ltc
.t_werasc
= CHK (ltc
.t_werasc
, CTRL ('W'));
369 ltc
.t_lnextc
= CHK (ltc
.t_lnextc
, CTRL ('V'));
370 ioctl (FILEDES
, TIOCSLTC
, <c
);
372 #endif /* UCB_NTTY */
375 ioctl (FILEDES
, TIOCGETC
, &tbuf
);
376 tbuf
.t_intrc
= CHK (tbuf
.t_intrc
, CTRL ('?'));
377 tbuf
.t_quitc
= CHK (tbuf
.t_quitc
, CTRL ('\\'));
378 tbuf
.t_startc
= CHK (tbuf
.t_startc
, CTRL ('Q'));
379 tbuf
.t_stopc
= CHK (tbuf
.t_stopc
, CTRL ('S'));
380 tbuf
.t_eofc
= CHK (tbuf
.t_eofc
, CTRL ('D'));
381 /* brkc is left alone */
382 ioctl (FILEDES
, TIOCSETC
, &tbuf
);
383 #endif /* TIOCGETC */
384 mode
.sg_flags
&= ~(RAW
388 | VTDELAY
| ALLDELAY
);
389 mode
.sg_flags
|= XTABS
| ECHO
| CRMOD
| ANYP
;
391 ioctl (FILEDES
, TCGETA
, &mode
);
392 mode
.c_cc
[VINTR
] = CHK (mode
.c_cc
[VINTR
], CTRL ('?'));
393 mode
.c_cc
[VQUIT
] = CHK (mode
.c_cc
[VQUIT
], CTRL ('\\'));
394 mode
.c_cc
[VEOF
] = CHK (mode
.c_cc
[VEOF
], CTRL ('D'));
396 mode
.c_iflag
&= ~(IGNBRK
| PARMRK
| INPCK
| INLCR
| IGNCR
| IUCLC
| IXOFF
);
397 mode
.c_iflag
|= (BRKINT
| ISTRIP
| ICRNL
| IXON
);
398 mode
.c_oflag
&= ~(OLCUC
| OCRNL
| ONOCR
| ONLRET
| OFILL
| OFDEL
|
399 NLDLY
| CRDLY
| TABDLY
| BSDLY
| VTDLY
| FFDLY
);
400 mode
.c_oflag
|= (OPOST
| ONLCR
);
401 mode
.c_cflag
&= ~(CSIZE
| PARODD
| CLOCAL
);
403 mode
.c_cflag
|= (CS8
| CREAD
);
404 #else /*hp9000s800 */
405 mode
.c_cflag
|= (CS8
| CSTOPB
| CREAD
);
406 #endif /* hp9000s800 */
407 mode
.c_lflag
&= ~(XCASE
| ECHONL
| NOFLSH
);
408 mode
.c_lflag
|= (ISIG
| ICANON
| ECHO
| ECHOK
);
409 ioctl (FILEDES
, TCSETAW
, &mode
);
417 tui_show_source (const char *file
, int line
)
419 /* make sure that the source window is displayed */
420 tuiAddWinToLayout (SRC_WIN
);
422 tuiUpdateSourceWindowsWithLine (current_source_symtab
, line
);
423 tuiUpdateLocatorFilename (file
);
427 tui_show_assembly (CORE_ADDR addr
)
429 tuiAddWinToLayout (DISASSEM_WIN
);
430 tuiUpdateSourceWindowsWithAddr (addr
);
434 tui_is_window_visible (TuiWinType type
)
436 if (tui_version
== 0)
439 if (winList
[type
] == 0)
442 return winList
[type
]->generic
.isVisible
;
446 tui_get_command_dimension (int *width
, int *height
)
448 if (!tui_version
|| !m_winPtrNotNull (cmdWin
))
453 *width
= cmdWin
->generic
.width
;
454 *height
= cmdWin
->generic
.height
;