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