* tui.c (strcat_to_buf): Use const char* for source item.
[deliverable/binutils-gdb.git] / gdb / tui / tui.c
CommitLineData
f377b406 1/* General functions for the WDB TUI.
f33c6cbf
AC
2
3 Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
4 Inc.
5
f377b406
SC
6 Contributed by Hewlett-Packard Company.
7
8 This file is part of GDB.
9
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.
14
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.
19
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. */
c906108c 24
f33c6cbf
AC
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>
31 first. */
32
4e8f7a8b
DJ
33#include "config.h"
34#ifdef HAVE_NCURSES_H
35#include <ncurses.h>
36#else
37#ifdef HAVE_CURSES_H
38#include <curses.h>
39#endif
40#endif
41
c906108c
SS
42#include <stdio.h>
43#include <stdlib.h>
44#include <ctype.h>
45#include <malloc.h>
c906108c
SS
46#ifdef HAVE_TERM_H
47#include <term.h>
48#endif
49#include <signal.h>
50#include <fcntl.h>
6d7fbb5a 51#if 0
c906108c 52#include <termio.h>
6d7fbb5a 53#endif
c906108c
SS
54#include <setjmp.h>
55#include "defs.h"
56#include "gdbcmd.h"
57#include "tui.h"
58#include "tuiData.h"
59#include "tuiLayout.h"
60#include "tuiIO.h"
61#include "tuiRegs.h"
377c38ea 62#include "tuiStack.h"
c906108c 63#include "tuiWin.h"
c6f60bcd 64#include "tuiSourceWin.h"
39db33d6
SC
65#include "readline/readline.h"
66#include "target.h"
67#include "frame.h"
68#include "breakpoint.h"
c6f60bcd 69#include "inferior.h"
39db33d6
SC
70
71/* Tells whether the TUI is active or not. */
72int tui_active = 0;
73static int tui_finish_init = 1;
74
75/* Switch the output mode between TUI/standard gdb. */
76static int
77tui_switch_mode (void)
c906108c 78{
39db33d6 79 if (tui_active)
c906108c 80 {
39db33d6 81 tui_disable ();
c6f60bcd
SC
82 rl_prep_terminal (0);
83
39db33d6
SC
84 printf_filtered ("Left the TUI mode\n");
85 }
86 else
87 {
c6f60bcd 88 rl_deprep_terminal ();
39db33d6
SC
89 tui_enable ();
90 printf_filtered ("Entered the TUI mode\n");
c906108c 91 }
c906108c 92
39db33d6
SC
93 /* Clear the readline in case switching occurred in middle of something. */
94 if (rl_end)
95 rl_kill_text (0, rl_end);
96
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');
c6f60bcd
SC
104
105 /* Make sure the \n we are returning does not repeat the last command. */
106 dont_repeat ();
39db33d6
SC
107 return 0;
108}
c906108c 109
377c38ea
SC
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). */
114static int
115tui_change_windows (void)
116{
117 if (!tui_active)
118 tui_switch_mode ();
119
120 if (tui_active)
121 {
122 TuiLayoutType new_layout;
123 TuiRegisterDisplayType regs_type = TUI_UNDEFINED_REGS;
124
125 new_layout = currentLayout ();
126
127 /* Select a new layout to have a rolling layout behavior
128 with always two windows (except when undefined). */
129 switch (new_layout)
130 {
131 case SRC_COMMAND:
132 new_layout = SRC_DISASSEM_COMMAND;
133 break;
134
135 case DISASSEM_COMMAND:
136 new_layout = SRC_DISASSEM_COMMAND;
137 break;
138
139 case SRC_DATA_COMMAND:
140 new_layout = SRC_DISASSEM_COMMAND;
141 break;
142
143 case SRC_DISASSEM_COMMAND:
144 new_layout = DISASSEM_DATA_COMMAND;
145 break;
146
147 case DISASSEM_DATA_COMMAND:
148 new_layout = SRC_DATA_COMMAND;
149 break;
150
151 default:
152 new_layout = SRC_COMMAND;
153 break;
154 }
155 tuiSetLayout (new_layout, regs_type);
156 }
157 return 0;
158}
159
160
161/* Delete the second TUI window to only show one. */
162static int
163tui_delete_other_windows (void)
164{
165 if (!tui_active)
166 tui_switch_mode ();
167
168 if (tui_active)
169 {
170 TuiLayoutType new_layout;
171 TuiRegisterDisplayType regs_type = TUI_UNDEFINED_REGS;
172
173 new_layout = currentLayout ();
174
175 /* Kill one window. */
176 switch (new_layout)
177 {
178 case SRC_COMMAND:
179 case SRC_DATA_COMMAND:
180 case SRC_DISASSEM_COMMAND:
181 default:
182 new_layout = SRC_COMMAND;
183 break;
184
185 case DISASSEM_COMMAND:
186 case DISASSEM_DATA_COMMAND:
187 new_layout = DISASSEM_COMMAND;
188 break;
189 }
190 tuiSetLayout (new_layout, regs_type);
191 }
192 return 0;
193}
194
39db33d6
SC
195/* Initialize readline and configure the keymap for the switching
196 key shortcut. */
c906108c 197void
39db33d6 198tui_initialize_readline ()
c906108c 199{
39db33d6 200 rl_initialize ();
c906108c 201
39db33d6
SC
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);
377c38ea
SC
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);
39db33d6 208}
c906108c 209
39db33d6
SC
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. */
c906108c 214void
39db33d6 215tui_enable (void)
c906108c 216{
39db33d6
SC
217 if (tui_active)
218 return;
219
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. */
223 if (tui_finish_init)
c906108c 224 {
39db33d6
SC
225 WINDOW *w;
226
227 w = initscr ();
228
377c38ea
SC
229 cbreak ();
230 noecho ();
39db33d6
SC
231 /*timeout (1);*/
232 nodelay(w, FALSE);
233 nl();
234 keypad (w, TRUE);
235 rl_initialize ();
236 setTermHeightTo (LINES);
237 setTermWidthTo (COLS);
238 def_prog_mode ();
239
c7037be1
SC
240 tuiShowFrameInfo (0);
241 tuiSetLayout (SRC_COMMAND, TUI_UNDEFINED_REGS);
39db33d6 242 tuiSetWinFocusTo (srcWin);
377c38ea 243 keypad (cmdWin->generic.handle, TRUE);
39db33d6
SC
244 wrefresh (cmdWin->generic.handle);
245 tui_finish_init = 0;
c906108c 246 }
39db33d6
SC
247 else
248 {
249 /* Save the current gdb setting of the terminal.
250 Curses will restore this state when endwin() is called. */
251 def_shell_mode ();
252 clearok (stdscr, TRUE);
253 }
c906108c 254
39db33d6
SC
255 /* Install the TUI specific hooks. */
256 tui_install_hooks ();
c906108c 257
377c38ea
SC
258 tui_update_variables ();
259
39db33d6 260 tui_setup_io (1);
c906108c 261
39db33d6
SC
262 tui_version = 1;
263 tui_active = 1;
297d1607
SC
264 if (selected_frame)
265 tuiShowFrameInfo (selected_frame);
266
39db33d6 267 refresh ();
3e752b04 268 tui_update_gdb_sizes ();
39db33d6
SC
269}
270
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. */
c906108c 275void
39db33d6 276tui_disable (void)
c906108c 277{
39db33d6
SC
278 if (!tui_active)
279 return;
c906108c 280
39db33d6
SC
281 /* Remove TUI hooks. */
282 tui_remove_hooks ();
c906108c 283
39db33d6
SC
284 /* Leave curses and restore previous gdb terminal setting. */
285 endwin ();
c906108c 286
39db33d6
SC
287 /* gdb terminal has changed, update gdb internal copy of it
288 so that terminal management with the inferior works. */
289 tui_setup_io (0);
c906108c 290
39db33d6
SC
291 tui_version = 0;
292 tui_active = 0;
3e752b04 293 tui_update_gdb_sizes ();
39db33d6 294}
c906108c 295
39db33d6
SC
296/* Wrapper on top of free() to ensure that input address
297 is greater than 0x0. */
c906108c 298void
eca6576c 299tuiFree (char *ptr)
c906108c
SS
300{
301 if (ptr != (char *) NULL)
302 {
b8c9b27d 303 xfree (ptr);
c906108c 304 }
39db33d6 305}
c906108c 306
39db33d6
SC
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. */
310CORE_ADDR
311tuiGetLowDisassemblyAddress (CORE_ADDR low, CORE_ADDR pc)
c906108c
SS
312{
313 int line;
c6f60bcd 314 CORE_ADDR newLow;
c906108c 315
39db33d6
SC
316 /* Determine where to start the disassembly so that the pc is about in the
317 middle of the viewport. */
c906108c
SS
318 for (line = 0, newLow = pc;
319 (newLow > low &&
320 line < (tuiDefaultWinViewportHeight (DISASSEM_WIN,
321 DISASSEM_COMMAND) / 2));)
322 {
323 bfd_byte buffer[4];
324
325 newLow -= sizeof (bfd_getb32 (buffer));
326 line++;
327 }
328
329 return newLow;
39db33d6 330}
c906108c 331
c906108c 332void
297d1607 333strcat_to_buf (char *buf, int buflen, const char *itemToAdd)
c906108c
SS
334{
335 if (itemToAdd != (char *) NULL && buf != (char *) NULL)
336 {
337 if ((strlen (buf) + strlen (itemToAdd)) <= buflen)
338 strcat (buf, itemToAdd);
339 else
340 strncat (buf, itemToAdd, (buflen - strlen (buf)));
341 }
c906108c
SS
342}
343
39db33d6
SC
344#if 0
345/* Solaris <sys/termios.h> defines CTRL. */
346#ifndef CTRL
347#define CTRL(x) (x & ~0140)
348#endif
c906108c 349
39db33d6
SC
350#define FILEDES 2
351#define CHK(val, dft) (val<=0 ? dft : val)
c906108c
SS
352
353static void
c906108c 354_tuiReset (void)
c906108c
SS
355{
356 struct termio mode;
357
358 /*
c5aa993b
JM
359 ** reset the teletype mode bits to a sensible state.
360 ** Copied tset.c
361 */
c906108c
SS
362#if ! defined (USG) && defined (TIOCGETC)
363 struct tchars tbuf;
364#endif /* !USG && TIOCGETC */
365#ifdef UCB_NTTY
366 struct ltchars ltc;
367
368 if (ldisc == NTTYDISC)
369 {
370 ioctl (FILEDES, TIOCGLTC, &ltc);
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, &ltc);
378 }
379#endif /* UCB_NTTY */
380#ifndef USG
381#ifdef TIOCGETC
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
392#ifdef CBREAK
393 | CBREAK
394#endif /* CBREAK */
395 | VTDELAY | ALLDELAY);
396 mode.sg_flags |= XTABS | ECHO | CRMOD | ANYP;
c5aa993b 397#else /*USG */
c906108c
SS
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'));
402
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);
409#ifndef hp9000s800
410 mode.c_cflag |= (CS8 | CREAD);
c5aa993b 411#else /*hp9000s800 */
c906108c
SS
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);
417#endif /* USG */
418
419 return;
420} /* _tuiReset */
39db33d6
SC
421#endif
422
c6f60bcd
SC
423void
424tui_show_source (const char *file, int line)
425{
426 /* make sure that the source window is displayed */
427 tuiAddWinToLayout (SRC_WIN);
428
429 tuiUpdateSourceWindowsWithLine (current_source_symtab, line);
430 tuiUpdateLocatorFilename (file);
431}
1403b519
SC
432
433void
434tui_show_assembly (CORE_ADDR addr)
435{
436 tuiAddWinToLayout (DISASSEM_WIN);
437 tuiUpdateSourceWindowsWithAddr (addr);
438}
439
440int
441tui_is_window_visible (TuiWinType type)
442{
443 if (tui_version == 0)
444 return 0;
445
446 if (winList[type] == 0)
447 return 0;
448
449 return winList[type]->generic.isVisible;
450}
451
452int
453tui_get_command_dimension (int *width, int *height)
454{
455 if (!tui_version || !m_winPtrNotNull (cmdWin))
456 {
457 return 0;
458 }
459
460 *width = cmdWin->generic.width;
461 *height = cmdWin->generic.height;
462 return 1;
463}
This page took 0.269584 seconds and 4 git commands to generate.