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. */
37 #include "tuiLayout.h"
42 #include "tuiSourceWin.h"
43 #include "readline/readline.h"
46 #include "breakpoint.h"
49 /* Tells whether the TUI is active or not. */
51 static int tui_finish_init
= 1;
53 /* Switch the output mode between TUI/standard gdb. */
55 tui_switch_mode (void)
62 printf_filtered ("Left the TUI mode\n");
66 rl_deprep_terminal ();
68 printf_filtered ("Entered the TUI mode\n");
71 /* Clear the readline in case switching occurred in middle of something. */
73 rl_kill_text (0, rl_end
);
75 /* Since we left the curses mode, the terminal mode is restored to
76 some previous state. That state may not be suitable for readline
77 to work correctly (it may be restored in line mode). We force an
78 exit of the current readline so that readline is re-entered and it
79 will be able to setup the terminal for its needs. By re-entering
80 in readline, we also redisplay its prompt in the non-curses mode. */
83 /* Make sure the \n we are returning does not repeat the last command. */
88 /* Change the TUI layout to show a next layout.
89 This function is bound to CTRL-X 2. It is intended to provide
90 a functionality close to the Emacs split-window command. We always
91 show two windows (src+asm), (src+regs) or (asm+regs). */
93 tui_change_windows (void)
100 TuiLayoutType new_layout
;
101 TuiRegisterDisplayType regs_type
= TUI_UNDEFINED_REGS
;
103 new_layout
= currentLayout ();
105 /* Select a new layout to have a rolling layout behavior
106 with always two windows (except when undefined). */
110 new_layout
= SRC_DISASSEM_COMMAND
;
113 case DISASSEM_COMMAND
:
114 new_layout
= SRC_DISASSEM_COMMAND
;
117 case SRC_DATA_COMMAND
:
118 new_layout
= SRC_DISASSEM_COMMAND
;
121 case SRC_DISASSEM_COMMAND
:
122 new_layout
= DISASSEM_DATA_COMMAND
;
125 case DISASSEM_DATA_COMMAND
:
126 new_layout
= SRC_DATA_COMMAND
;
130 new_layout
= SRC_COMMAND
;
133 tuiSetLayout (new_layout
, regs_type
);
139 /* Delete the second TUI window to only show one. */
141 tui_delete_other_windows (void)
148 TuiLayoutType new_layout
;
149 TuiRegisterDisplayType regs_type
= TUI_UNDEFINED_REGS
;
151 new_layout
= currentLayout ();
153 /* Kill one window. */
157 case SRC_DATA_COMMAND
:
158 case SRC_DISASSEM_COMMAND
:
160 new_layout
= SRC_COMMAND
;
163 case DISASSEM_COMMAND
:
164 case DISASSEM_DATA_COMMAND
:
165 new_layout
= DISASSEM_COMMAND
;
168 tuiSetLayout (new_layout
, regs_type
);
173 /* Initialize readline and configure the keymap for the switching
176 tui_initialize_readline ()
180 rl_add_defun ("tui-switch-mode", tui_switch_mode
, -1);
181 rl_bind_key_in_map ('a', tui_switch_mode
, emacs_ctlx_keymap
);
182 rl_bind_key_in_map ('A', tui_switch_mode
, emacs_ctlx_keymap
);
183 rl_bind_key_in_map (CTRL ('A'), tui_switch_mode
, emacs_ctlx_keymap
);
184 rl_bind_key_in_map ('1', tui_delete_other_windows
, emacs_ctlx_keymap
);
185 rl_bind_key_in_map ('2', tui_change_windows
, emacs_ctlx_keymap
);
188 /* Enter in the tui mode (curses).
189 When in normal mode, it installs the tui hooks in gdb, redirects
190 the gdb output, configures the readline to work in tui mode.
191 When in curses mode, it does nothing. */
198 /* To avoid to initialize curses when gdb starts, there is a defered
199 curses initialization. This initialization is made only once
200 and the first time the curses mode is entered. */
214 setTermHeightTo (LINES
);
215 setTermWidthTo (COLS
);
218 tuiSetLocatorContent (0);
219 showLayout (SRC_COMMAND
);
220 tuiSetWinFocusTo (srcWin
);
221 keypad (cmdWin
->generic
.handle
, TRUE
);
222 wrefresh (cmdWin
->generic
.handle
);
227 /* Save the current gdb setting of the terminal.
228 Curses will restore this state when endwin() is called. */
230 clearok (stdscr
, TRUE
);
233 /* Install the TUI specific hooks. */
234 tui_install_hooks ();
236 tui_update_variables ();
244 /* Update gdb's knowledge of its terminal. */
245 terminal_save_ours ();
248 /* Leave the tui mode.
249 Remove the tui hooks and configure the gdb output and readline
250 back to their original state. The curses mode is left so that
251 the terminal setting is restored to the point when we entered. */
258 /* Remove TUI hooks. */
261 /* Leave curses and restore previous gdb terminal setting. */
264 /* gdb terminal has changed, update gdb internal copy of it
265 so that terminal management with the inferior works. */
268 /* Update gdb's knowledge of its terminal. */
269 terminal_save_ours ();
274 /* Wrapper on top of free() to ensure that input address
275 is greater than 0x0. */
279 if (ptr
!= (char *) NULL
)
285 /* Determine what the low address will be to display in the TUI's
286 disassembly window. This may or may not be the same as the
287 low address input. */
289 tuiGetLowDisassemblyAddress (CORE_ADDR low
, CORE_ADDR pc
)
294 /* Determine where to start the disassembly so that the pc is about in the
295 middle of the viewport. */
296 for (line
= 0, newLow
= pc
;
298 line
< (tuiDefaultWinViewportHeight (DISASSEM_WIN
,
299 DISASSEM_COMMAND
) / 2));)
303 newLow
-= sizeof (bfd_getb32 (buffer
));
311 strcat_to_buf (char *buf
, int buflen
, char *itemToAdd
)
313 if (itemToAdd
!= (char *) NULL
&& buf
!= (char *) NULL
)
315 if ((strlen (buf
) + strlen (itemToAdd
)) <= buflen
)
316 strcat (buf
, itemToAdd
);
318 strncat (buf
, itemToAdd
, (buflen
- strlen (buf
)));
323 /* Solaris <sys/termios.h> defines CTRL. */
325 #define CTRL(x) (x & ~0140)
329 #define CHK(val, dft) (val<=0 ? dft : val)
337 ** reset the teletype mode bits to a sensible state.
340 #if ! defined (USG) && defined (TIOCGETC)
342 #endif /* !USG && TIOCGETC */
346 if (ldisc
== NTTYDISC
)
348 ioctl (FILEDES
, TIOCGLTC
, <c
);
349 ltc
.t_suspc
= CHK (ltc
.t_suspc
, CTRL ('Z'));
350 ltc
.t_dsuspc
= CHK (ltc
.t_dsuspc
, CTRL ('Y'));
351 ltc
.t_rprntc
= CHK (ltc
.t_rprntc
, CTRL ('R'));
352 ltc
.t_flushc
= CHK (ltc
.t_flushc
, CTRL ('O'));
353 ltc
.t_werasc
= CHK (ltc
.t_werasc
, CTRL ('W'));
354 ltc
.t_lnextc
= CHK (ltc
.t_lnextc
, CTRL ('V'));
355 ioctl (FILEDES
, TIOCSLTC
, <c
);
357 #endif /* UCB_NTTY */
360 ioctl (FILEDES
, TIOCGETC
, &tbuf
);
361 tbuf
.t_intrc
= CHK (tbuf
.t_intrc
, CTRL ('?'));
362 tbuf
.t_quitc
= CHK (tbuf
.t_quitc
, CTRL ('\\'));
363 tbuf
.t_startc
= CHK (tbuf
.t_startc
, CTRL ('Q'));
364 tbuf
.t_stopc
= CHK (tbuf
.t_stopc
, CTRL ('S'));
365 tbuf
.t_eofc
= CHK (tbuf
.t_eofc
, CTRL ('D'));
366 /* brkc is left alone */
367 ioctl (FILEDES
, TIOCSETC
, &tbuf
);
368 #endif /* TIOCGETC */
369 mode
.sg_flags
&= ~(RAW
373 | VTDELAY
| ALLDELAY
);
374 mode
.sg_flags
|= XTABS
| ECHO
| CRMOD
| ANYP
;
376 ioctl (FILEDES
, TCGETA
, &mode
);
377 mode
.c_cc
[VINTR
] = CHK (mode
.c_cc
[VINTR
], CTRL ('?'));
378 mode
.c_cc
[VQUIT
] = CHK (mode
.c_cc
[VQUIT
], CTRL ('\\'));
379 mode
.c_cc
[VEOF
] = CHK (mode
.c_cc
[VEOF
], CTRL ('D'));
381 mode
.c_iflag
&= ~(IGNBRK
| PARMRK
| INPCK
| INLCR
| IGNCR
| IUCLC
| IXOFF
);
382 mode
.c_iflag
|= (BRKINT
| ISTRIP
| ICRNL
| IXON
);
383 mode
.c_oflag
&= ~(OLCUC
| OCRNL
| ONOCR
| ONLRET
| OFILL
| OFDEL
|
384 NLDLY
| CRDLY
| TABDLY
| BSDLY
| VTDLY
| FFDLY
);
385 mode
.c_oflag
|= (OPOST
| ONLCR
);
386 mode
.c_cflag
&= ~(CSIZE
| PARODD
| CLOCAL
);
388 mode
.c_cflag
|= (CS8
| CREAD
);
389 #else /*hp9000s800 */
390 mode
.c_cflag
|= (CS8
| CSTOPB
| CREAD
);
391 #endif /* hp9000s800 */
392 mode
.c_lflag
&= ~(XCASE
| ECHONL
| NOFLSH
);
393 mode
.c_lflag
|= (ISIG
| ICANON
| ECHO
| ECHOK
);
394 ioctl (FILEDES
, TCSETAW
, &mode
);
402 tui_show_source (const char *file
, int line
)
404 /* make sure that the source window is displayed */
405 tuiAddWinToLayout (SRC_WIN
);
407 tuiUpdateSourceWindowsWithLine (current_source_symtab
, line
);
408 tuiUpdateLocatorFilename (file
);
412 tui_show_assembly (CORE_ADDR addr
)
414 tuiAddWinToLayout (DISASSEM_WIN
);
415 tuiUpdateSourceWindowsWithAddr (addr
);
419 tui_is_window_visible (TuiWinType type
)
421 if (tui_version
== 0)
424 if (winList
[type
] == 0)
427 return winList
[type
]->generic
.isVisible
;
431 tui_get_command_dimension (int *width
, int *height
)
433 if (!tui_version
|| !m_winPtrNotNull (cmdWin
))
438 *width
= cmdWin
->generic
.width
;
439 *height
= cmdWin
->generic
.height
;