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 "readline/readline.h"
45 #include "breakpoint.h"
47 /* Tells whether the TUI is active or not. */
49 static int tui_finish_init
= 1;
51 /* Switch the output mode between TUI/standard gdb. */
53 tui_switch_mode (void)
58 printf_filtered ("Left the TUI mode\n");
63 printf_filtered ("Entered the TUI mode\n");
66 /* Clear the readline in case switching occurred in middle of something. */
68 rl_kill_text (0, rl_end
);
70 /* Since we left the curses mode, the terminal mode is restored to
71 some previous state. That state may not be suitable for readline
72 to work correctly (it may be restored in line mode). We force an
73 exit of the current readline so that readline is re-entered and it
74 will be able to setup the terminal for its needs. By re-entering
75 in readline, we also redisplay its prompt in the non-curses mode. */
80 /* Change the TUI layout to show a next layout.
81 This function is bound to CTRL-X 2. It is intended to provide
82 a functionality close to the Emacs split-window command. We always
83 show two windows (src+asm), (src+regs) or (asm+regs). */
85 tui_change_windows (void)
92 TuiLayoutType new_layout
;
93 TuiRegisterDisplayType regs_type
= TUI_UNDEFINED_REGS
;
95 new_layout
= currentLayout ();
97 /* Select a new layout to have a rolling layout behavior
98 with always two windows (except when undefined). */
102 new_layout
= SRC_DISASSEM_COMMAND
;
105 case DISASSEM_COMMAND
:
106 new_layout
= SRC_DISASSEM_COMMAND
;
109 case SRC_DATA_COMMAND
:
110 new_layout
= SRC_DISASSEM_COMMAND
;
113 case SRC_DISASSEM_COMMAND
:
114 new_layout
= DISASSEM_DATA_COMMAND
;
117 case DISASSEM_DATA_COMMAND
:
118 new_layout
= SRC_DATA_COMMAND
;
122 new_layout
= SRC_COMMAND
;
125 tuiSetLayout (new_layout
, regs_type
);
131 /* Delete the second TUI window to only show one. */
133 tui_delete_other_windows (void)
140 TuiLayoutType new_layout
;
141 TuiRegisterDisplayType regs_type
= TUI_UNDEFINED_REGS
;
143 new_layout
= currentLayout ();
145 /* Kill one window. */
149 case SRC_DATA_COMMAND
:
150 case SRC_DISASSEM_COMMAND
:
152 new_layout
= SRC_COMMAND
;
155 case DISASSEM_COMMAND
:
156 case DISASSEM_DATA_COMMAND
:
157 new_layout
= DISASSEM_COMMAND
;
160 tuiSetLayout (new_layout
, regs_type
);
165 /* Initialize readline and configure the keymap for the switching
168 tui_initialize_readline ()
172 rl_add_defun ("tui-switch-mode", tui_switch_mode
, -1);
173 rl_bind_key_in_map ('a', tui_switch_mode
, emacs_ctlx_keymap
);
174 rl_bind_key_in_map ('A', tui_switch_mode
, emacs_ctlx_keymap
);
175 rl_bind_key_in_map (CTRL ('A'), tui_switch_mode
, emacs_ctlx_keymap
);
176 rl_bind_key_in_map ('1', tui_delete_other_windows
, emacs_ctlx_keymap
);
177 rl_bind_key_in_map ('2', tui_change_windows
, emacs_ctlx_keymap
);
180 /* Enter in the tui mode (curses).
181 When in normal mode, it installs the tui hooks in gdb, redirects
182 the gdb output, configures the readline to work in tui mode.
183 When in curses mode, it does nothing. */
190 /* To avoid to initialize curses when gdb starts, there is a defered
191 curses initialization. This initialization is made only once
192 and the first time the curses mode is entered. */
206 setTermHeightTo (LINES
);
207 setTermWidthTo (COLS
);
210 tuiSetLocatorContent (0);
211 showLayout (SRC_COMMAND
);
212 tuiSetWinFocusTo (srcWin
);
213 keypad (cmdWin
->generic
.handle
, TRUE
);
214 wrefresh (cmdWin
->generic
.handle
);
219 /* Save the current gdb setting of the terminal.
220 Curses will restore this state when endwin() is called. */
222 clearok (stdscr
, TRUE
);
225 /* Install the TUI specific hooks. */
226 tui_install_hooks ();
228 tui_update_variables ();
237 /* Leave the tui mode.
238 Remove the tui hooks and configure the gdb output and readline
239 back to their original state. The curses mode is left so that
240 the terminal setting is restored to the point when we entered. */
247 /* Remove TUI hooks. */
250 /* Leave curses and restore previous gdb terminal setting. */
253 /* gdb terminal has changed, update gdb internal copy of it
254 so that terminal management with the inferior works. */
261 /* Wrapper on top of free() to ensure that input address
262 is greater than 0x0. */
266 if (ptr
!= (char *) NULL
)
272 /* Determine what the low address will be to display in the TUI's
273 disassembly window. This may or may not be the same as the
274 low address input. */
276 tuiGetLowDisassemblyAddress (CORE_ADDR low
, CORE_ADDR pc
)
281 /* Determine where to start the disassembly so that the pc is about in the
282 middle of the viewport. */
283 for (line
= 0, newLow
= pc
;
285 line
< (tuiDefaultWinViewportHeight (DISASSEM_WIN
,
286 DISASSEM_COMMAND
) / 2));)
290 newLow
-= sizeof (bfd_getb32 (buffer
));
298 strcat_to_buf (char *buf
, int buflen
, char *itemToAdd
)
300 if (itemToAdd
!= (char *) NULL
&& buf
!= (char *) NULL
)
302 if ((strlen (buf
) + strlen (itemToAdd
)) <= buflen
)
303 strcat (buf
, itemToAdd
);
305 strncat (buf
, itemToAdd
, (buflen
- strlen (buf
)));
310 /* Solaris <sys/termios.h> defines CTRL. */
312 #define CTRL(x) (x & ~0140)
316 #define CHK(val, dft) (val<=0 ? dft : val)
324 ** reset the teletype mode bits to a sensible state.
327 #if ! defined (USG) && defined (TIOCGETC)
329 #endif /* !USG && TIOCGETC */
333 if (ldisc
== NTTYDISC
)
335 ioctl (FILEDES
, TIOCGLTC
, <c
);
336 ltc
.t_suspc
= CHK (ltc
.t_suspc
, CTRL ('Z'));
337 ltc
.t_dsuspc
= CHK (ltc
.t_dsuspc
, CTRL ('Y'));
338 ltc
.t_rprntc
= CHK (ltc
.t_rprntc
, CTRL ('R'));
339 ltc
.t_flushc
= CHK (ltc
.t_flushc
, CTRL ('O'));
340 ltc
.t_werasc
= CHK (ltc
.t_werasc
, CTRL ('W'));
341 ltc
.t_lnextc
= CHK (ltc
.t_lnextc
, CTRL ('V'));
342 ioctl (FILEDES
, TIOCSLTC
, <c
);
344 #endif /* UCB_NTTY */
347 ioctl (FILEDES
, TIOCGETC
, &tbuf
);
348 tbuf
.t_intrc
= CHK (tbuf
.t_intrc
, CTRL ('?'));
349 tbuf
.t_quitc
= CHK (tbuf
.t_quitc
, CTRL ('\\'));
350 tbuf
.t_startc
= CHK (tbuf
.t_startc
, CTRL ('Q'));
351 tbuf
.t_stopc
= CHK (tbuf
.t_stopc
, CTRL ('S'));
352 tbuf
.t_eofc
= CHK (tbuf
.t_eofc
, CTRL ('D'));
353 /* brkc is left alone */
354 ioctl (FILEDES
, TIOCSETC
, &tbuf
);
355 #endif /* TIOCGETC */
356 mode
.sg_flags
&= ~(RAW
360 | VTDELAY
| ALLDELAY
);
361 mode
.sg_flags
|= XTABS
| ECHO
| CRMOD
| ANYP
;
363 ioctl (FILEDES
, TCGETA
, &mode
);
364 mode
.c_cc
[VINTR
] = CHK (mode
.c_cc
[VINTR
], CTRL ('?'));
365 mode
.c_cc
[VQUIT
] = CHK (mode
.c_cc
[VQUIT
], CTRL ('\\'));
366 mode
.c_cc
[VEOF
] = CHK (mode
.c_cc
[VEOF
], CTRL ('D'));
368 mode
.c_iflag
&= ~(IGNBRK
| PARMRK
| INPCK
| INLCR
| IGNCR
| IUCLC
| IXOFF
);
369 mode
.c_iflag
|= (BRKINT
| ISTRIP
| ICRNL
| IXON
);
370 mode
.c_oflag
&= ~(OLCUC
| OCRNL
| ONOCR
| ONLRET
| OFILL
| OFDEL
|
371 NLDLY
| CRDLY
| TABDLY
| BSDLY
| VTDLY
| FFDLY
);
372 mode
.c_oflag
|= (OPOST
| ONLCR
);
373 mode
.c_cflag
&= ~(CSIZE
| PARODD
| CLOCAL
);
375 mode
.c_cflag
|= (CS8
| CREAD
);
376 #else /*hp9000s800 */
377 mode
.c_cflag
|= (CS8
| CSTOPB
| CREAD
);
378 #endif /* hp9000s800 */
379 mode
.c_lflag
&= ~(XCASE
| ECHONL
| NOFLSH
);
380 mode
.c_lflag
|= (ISIG
| ICANON
| ECHO
| ECHOK
);
381 ioctl (FILEDES
, TCSETAW
, &mode
);