1 /* General functions for the WDB TUI.
2 Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3 Contributed by Hewlett-Packard Company.
5 This file is part of GDB.
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.
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.
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. */
22 /* If we need <curses.h>, we must include it before we get "bfd.h". */
47 #include "tuiLayout.h"
52 #include "tuiSourceWin.h"
53 #include "readline/readline.h"
56 #include "breakpoint.h"
59 /* Tells whether the TUI is active or not. */
61 static int tui_finish_init
= 1;
63 /* Switch the output mode between TUI/standard gdb. */
65 tui_switch_mode (void)
72 printf_filtered ("Left the TUI mode\n");
76 rl_deprep_terminal ();
78 printf_filtered ("Entered the TUI mode\n");
81 /* Clear the readline in case switching occurred in middle of something. */
83 rl_kill_text (0, rl_end
);
85 /* Since we left the curses mode, the terminal mode is restored to
86 some previous state. That state may not be suitable for readline
87 to work correctly (it may be restored in line mode). We force an
88 exit of the current readline so that readline is re-entered and it
89 will be able to setup the terminal for its needs. By re-entering
90 in readline, we also redisplay its prompt in the non-curses mode. */
93 /* Make sure the \n we are returning does not repeat the last command. */
98 /* Change the TUI layout to show a next layout.
99 This function is bound to CTRL-X 2. It is intended to provide
100 a functionality close to the Emacs split-window command. We always
101 show two windows (src+asm), (src+regs) or (asm+regs). */
103 tui_change_windows (void)
110 TuiLayoutType new_layout
;
111 TuiRegisterDisplayType regs_type
= TUI_UNDEFINED_REGS
;
113 new_layout
= currentLayout ();
115 /* Select a new layout to have a rolling layout behavior
116 with always two windows (except when undefined). */
120 new_layout
= SRC_DISASSEM_COMMAND
;
123 case DISASSEM_COMMAND
:
124 new_layout
= SRC_DISASSEM_COMMAND
;
127 case SRC_DATA_COMMAND
:
128 new_layout
= SRC_DISASSEM_COMMAND
;
131 case SRC_DISASSEM_COMMAND
:
132 new_layout
= DISASSEM_DATA_COMMAND
;
135 case DISASSEM_DATA_COMMAND
:
136 new_layout
= SRC_DATA_COMMAND
;
140 new_layout
= SRC_COMMAND
;
143 tuiSetLayout (new_layout
, regs_type
);
149 /* Delete the second TUI window to only show one. */
151 tui_delete_other_windows (void)
158 TuiLayoutType new_layout
;
159 TuiRegisterDisplayType regs_type
= TUI_UNDEFINED_REGS
;
161 new_layout
= currentLayout ();
163 /* Kill one window. */
167 case SRC_DATA_COMMAND
:
168 case SRC_DISASSEM_COMMAND
:
170 new_layout
= SRC_COMMAND
;
173 case DISASSEM_COMMAND
:
174 case DISASSEM_DATA_COMMAND
:
175 new_layout
= DISASSEM_COMMAND
;
178 tuiSetLayout (new_layout
, regs_type
);
183 /* Initialize readline and configure the keymap for the switching
186 tui_initialize_readline ()
190 rl_add_defun ("tui-switch-mode", tui_switch_mode
, -1);
191 rl_bind_key_in_map ('a', tui_switch_mode
, emacs_ctlx_keymap
);
192 rl_bind_key_in_map ('A', tui_switch_mode
, emacs_ctlx_keymap
);
193 rl_bind_key_in_map (CTRL ('A'), tui_switch_mode
, emacs_ctlx_keymap
);
194 rl_bind_key_in_map ('1', tui_delete_other_windows
, emacs_ctlx_keymap
);
195 rl_bind_key_in_map ('2', tui_change_windows
, emacs_ctlx_keymap
);
198 /* Enter in the tui mode (curses).
199 When in normal mode, it installs the tui hooks in gdb, redirects
200 the gdb output, configures the readline to work in tui mode.
201 When in curses mode, it does nothing. */
208 /* To avoid to initialize curses when gdb starts, there is a defered
209 curses initialization. This initialization is made only once
210 and the first time the curses mode is entered. */
224 setTermHeightTo (LINES
);
225 setTermWidthTo (COLS
);
228 tuiSetLocatorContent (0);
229 showLayout (SRC_COMMAND
);
230 tuiSetWinFocusTo (srcWin
);
231 keypad (cmdWin
->generic
.handle
, TRUE
);
232 wrefresh (cmdWin
->generic
.handle
);
237 /* Save the current gdb setting of the terminal.
238 Curses will restore this state when endwin() is called. */
240 clearok (stdscr
, TRUE
);
243 /* Install the TUI specific hooks. */
244 tui_install_hooks ();
246 tui_update_variables ();
255 /* Leave the tui mode.
256 Remove the tui hooks and configure the gdb output and readline
257 back to their original state. The curses mode is left so that
258 the terminal setting is restored to the point when we entered. */
265 /* Remove TUI hooks. */
268 /* Leave curses and restore previous gdb terminal setting. */
271 /* gdb terminal has changed, update gdb internal copy of it
272 so that terminal management with the inferior works. */
279 /* Wrapper on top of free() to ensure that input address
280 is greater than 0x0. */
284 if (ptr
!= (char *) NULL
)
290 /* Determine what the low address will be to display in the TUI's
291 disassembly window. This may or may not be the same as the
292 low address input. */
294 tuiGetLowDisassemblyAddress (CORE_ADDR low
, CORE_ADDR pc
)
299 /* Determine where to start the disassembly so that the pc is about in the
300 middle of the viewport. */
301 for (line
= 0, newLow
= pc
;
303 line
< (tuiDefaultWinViewportHeight (DISASSEM_WIN
,
304 DISASSEM_COMMAND
) / 2));)
308 newLow
-= sizeof (bfd_getb32 (buffer
));
316 strcat_to_buf (char *buf
, int buflen
, char *itemToAdd
)
318 if (itemToAdd
!= (char *) NULL
&& buf
!= (char *) NULL
)
320 if ((strlen (buf
) + strlen (itemToAdd
)) <= buflen
)
321 strcat (buf
, itemToAdd
);
323 strncat (buf
, itemToAdd
, (buflen
- strlen (buf
)));
328 /* Solaris <sys/termios.h> defines CTRL. */
330 #define CTRL(x) (x & ~0140)
334 #define CHK(val, dft) (val<=0 ? dft : val)
342 ** reset the teletype mode bits to a sensible state.
345 #if ! defined (USG) && defined (TIOCGETC)
347 #endif /* !USG && TIOCGETC */
351 if (ldisc
== NTTYDISC
)
353 ioctl (FILEDES
, TIOCGLTC
, <c
);
354 ltc
.t_suspc
= CHK (ltc
.t_suspc
, CTRL ('Z'));
355 ltc
.t_dsuspc
= CHK (ltc
.t_dsuspc
, CTRL ('Y'));
356 ltc
.t_rprntc
= CHK (ltc
.t_rprntc
, CTRL ('R'));
357 ltc
.t_flushc
= CHK (ltc
.t_flushc
, CTRL ('O'));
358 ltc
.t_werasc
= CHK (ltc
.t_werasc
, CTRL ('W'));
359 ltc
.t_lnextc
= CHK (ltc
.t_lnextc
, CTRL ('V'));
360 ioctl (FILEDES
, TIOCSLTC
, <c
);
362 #endif /* UCB_NTTY */
365 ioctl (FILEDES
, TIOCGETC
, &tbuf
);
366 tbuf
.t_intrc
= CHK (tbuf
.t_intrc
, CTRL ('?'));
367 tbuf
.t_quitc
= CHK (tbuf
.t_quitc
, CTRL ('\\'));
368 tbuf
.t_startc
= CHK (tbuf
.t_startc
, CTRL ('Q'));
369 tbuf
.t_stopc
= CHK (tbuf
.t_stopc
, CTRL ('S'));
370 tbuf
.t_eofc
= CHK (tbuf
.t_eofc
, CTRL ('D'));
371 /* brkc is left alone */
372 ioctl (FILEDES
, TIOCSETC
, &tbuf
);
373 #endif /* TIOCGETC */
374 mode
.sg_flags
&= ~(RAW
378 | VTDELAY
| ALLDELAY
);
379 mode
.sg_flags
|= XTABS
| ECHO
| CRMOD
| ANYP
;
381 ioctl (FILEDES
, TCGETA
, &mode
);
382 mode
.c_cc
[VINTR
] = CHK (mode
.c_cc
[VINTR
], CTRL ('?'));
383 mode
.c_cc
[VQUIT
] = CHK (mode
.c_cc
[VQUIT
], CTRL ('\\'));
384 mode
.c_cc
[VEOF
] = CHK (mode
.c_cc
[VEOF
], CTRL ('D'));
386 mode
.c_iflag
&= ~(IGNBRK
| PARMRK
| INPCK
| INLCR
| IGNCR
| IUCLC
| IXOFF
);
387 mode
.c_iflag
|= (BRKINT
| ISTRIP
| ICRNL
| IXON
);
388 mode
.c_oflag
&= ~(OLCUC
| OCRNL
| ONOCR
| ONLRET
| OFILL
| OFDEL
|
389 NLDLY
| CRDLY
| TABDLY
| BSDLY
| VTDLY
| FFDLY
);
390 mode
.c_oflag
|= (OPOST
| ONLCR
);
391 mode
.c_cflag
&= ~(CSIZE
| PARODD
| CLOCAL
);
393 mode
.c_cflag
|= (CS8
| CREAD
);
394 #else /*hp9000s800 */
395 mode
.c_cflag
|= (CS8
| CSTOPB
| CREAD
);
396 #endif /* hp9000s800 */
397 mode
.c_lflag
&= ~(XCASE
| ECHONL
| NOFLSH
);
398 mode
.c_lflag
|= (ISIG
| ICANON
| ECHO
| ECHOK
);
399 ioctl (FILEDES
, TCSETAW
, &mode
);
407 tui_show_source (const char *file
, int line
)
409 /* make sure that the source window is displayed */
410 tuiAddWinToLayout (SRC_WIN
);
412 tuiUpdateSourceWindowsWithLine (current_source_symtab
, line
);
413 tuiUpdateLocatorFilename (file
);
417 tui_show_assembly (CORE_ADDR addr
)
419 tuiAddWinToLayout (DISASSEM_WIN
);
420 tuiUpdateSourceWindowsWithAddr (addr
);
424 tui_is_window_visible (TuiWinType type
)
426 if (tui_version
== 0)
429 if (winList
[type
] == 0)
432 return winList
[type
]->generic
.isVisible
;
436 tui_get_command_dimension (int *width
, int *height
)
438 if (!tui_version
|| !m_winPtrNotNull (cmdWin
))
443 *width
= cmdWin
->generic
.width
;
444 *height
= cmdWin
->generic
.height
;