* tui.h (tui_show_assembly): Declare.
[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
SS
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <ctype.h>
25#include <malloc.h>
c906108c
SS
26#ifdef HAVE_TERM_H
27#include <term.h>
28#endif
29#include <signal.h>
30#include <fcntl.h>
31#include <termio.h>
32#include <setjmp.h>
33#include "defs.h"
34#include "gdbcmd.h"
35#include "tui.h"
36#include "tuiData.h"
37#include "tuiLayout.h"
38#include "tuiIO.h"
39#include "tuiRegs.h"
377c38ea 40#include "tuiStack.h"
c906108c 41#include "tuiWin.h"
39db33d6
SC
42#include "readline/readline.h"
43#include "target.h"
44#include "frame.h"
45#include "breakpoint.h"
46
47/* Tells whether the TUI is active or not. */
48int tui_active = 0;
49static int tui_finish_init = 1;
50
51/* Switch the output mode between TUI/standard gdb. */
52static int
53tui_switch_mode (void)
c906108c 54{
39db33d6 55 if (tui_active)
c906108c 56 {
39db33d6
SC
57 tui_disable ();
58 printf_filtered ("Left the TUI mode\n");
59 }
60 else
61 {
62 tui_enable ();
63 printf_filtered ("Entered the TUI mode\n");
c906108c 64 }
c906108c 65
39db33d6
SC
66 /* Clear the readline in case switching occurred in middle of something. */
67 if (rl_end)
68 rl_kill_text (0, rl_end);
69
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. */
76 rl_newline (1, '\n');
77 return 0;
78}
c906108c 79
377c38ea
SC
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). */
84static int
85tui_change_windows (void)
86{
87 if (!tui_active)
88 tui_switch_mode ();
89
90 if (tui_active)
91 {
92 TuiLayoutType new_layout;
93 TuiRegisterDisplayType regs_type = TUI_UNDEFINED_REGS;
94
95 new_layout = currentLayout ();
96
97 /* Select a new layout to have a rolling layout behavior
98 with always two windows (except when undefined). */
99 switch (new_layout)
100 {
101 case SRC_COMMAND:
102 new_layout = SRC_DISASSEM_COMMAND;
103 break;
104
105 case DISASSEM_COMMAND:
106 new_layout = SRC_DISASSEM_COMMAND;
107 break;
108
109 case SRC_DATA_COMMAND:
110 new_layout = SRC_DISASSEM_COMMAND;
111 break;
112
113 case SRC_DISASSEM_COMMAND:
114 new_layout = DISASSEM_DATA_COMMAND;
115 break;
116
117 case DISASSEM_DATA_COMMAND:
118 new_layout = SRC_DATA_COMMAND;
119 break;
120
121 default:
122 new_layout = SRC_COMMAND;
123 break;
124 }
125 tuiSetLayout (new_layout, regs_type);
126 }
127 return 0;
128}
129
130
131/* Delete the second TUI window to only show one. */
132static int
133tui_delete_other_windows (void)
134{
135 if (!tui_active)
136 tui_switch_mode ();
137
138 if (tui_active)
139 {
140 TuiLayoutType new_layout;
141 TuiRegisterDisplayType regs_type = TUI_UNDEFINED_REGS;
142
143 new_layout = currentLayout ();
144
145 /* Kill one window. */
146 switch (new_layout)
147 {
148 case SRC_COMMAND:
149 case SRC_DATA_COMMAND:
150 case SRC_DISASSEM_COMMAND:
151 default:
152 new_layout = SRC_COMMAND;
153 break;
154
155 case DISASSEM_COMMAND:
156 case DISASSEM_DATA_COMMAND:
157 new_layout = DISASSEM_COMMAND;
158 break;
159 }
160 tuiSetLayout (new_layout, regs_type);
161 }
162 return 0;
163}
164
39db33d6
SC
165/* Initialize readline and configure the keymap for the switching
166 key shortcut. */
c906108c 167void
39db33d6 168tui_initialize_readline ()
c906108c 169{
39db33d6 170 rl_initialize ();
c906108c 171
39db33d6
SC
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);
377c38ea
SC
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);
39db33d6 178}
c906108c 179
39db33d6
SC
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. */
c906108c 184void
39db33d6 185tui_enable (void)
c906108c 186{
39db33d6
SC
187 if (tui_active)
188 return;
189
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. */
193 if (tui_finish_init)
c906108c 194 {
39db33d6
SC
195 WINDOW *w;
196
197 w = initscr ();
198
377c38ea
SC
199 cbreak ();
200 noecho ();
39db33d6
SC
201 /*timeout (1);*/
202 nodelay(w, FALSE);
203 nl();
204 keypad (w, TRUE);
205 rl_initialize ();
206 setTermHeightTo (LINES);
207 setTermWidthTo (COLS);
208 def_prog_mode ();
209
210 tuiSetLocatorContent (0);
211 showLayout (SRC_COMMAND);
212 tuiSetWinFocusTo (srcWin);
377c38ea 213 keypad (cmdWin->generic.handle, TRUE);
39db33d6
SC
214 wrefresh (cmdWin->generic.handle);
215 tui_finish_init = 0;
c906108c 216 }
39db33d6
SC
217 else
218 {
219 /* Save the current gdb setting of the terminal.
220 Curses will restore this state when endwin() is called. */
221 def_shell_mode ();
222 clearok (stdscr, TRUE);
223 }
c906108c 224
39db33d6
SC
225 /* Install the TUI specific hooks. */
226 tui_install_hooks ();
c906108c 227
377c38ea
SC
228 tui_update_variables ();
229
39db33d6 230 tui_setup_io (1);
c906108c 231
39db33d6
SC
232 tui_version = 1;
233 tui_active = 1;
234 refresh ();
235}
236
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. */
c906108c 241void
39db33d6 242tui_disable (void)
c906108c 243{
39db33d6
SC
244 if (!tui_active)
245 return;
c906108c 246
39db33d6
SC
247 /* Remove TUI hooks. */
248 tui_remove_hooks ();
c906108c 249
39db33d6
SC
250 /* Leave curses and restore previous gdb terminal setting. */
251 endwin ();
c906108c 252
39db33d6
SC
253 /* gdb terminal has changed, update gdb internal copy of it
254 so that terminal management with the inferior works. */
255 tui_setup_io (0);
c906108c 256
39db33d6
SC
257 tui_version = 0;
258 tui_active = 0;
259}
c906108c 260
39db33d6
SC
261/* Wrapper on top of free() to ensure that input address
262 is greater than 0x0. */
c906108c 263void
eca6576c 264tuiFree (char *ptr)
c906108c
SS
265{
266 if (ptr != (char *) NULL)
267 {
b8c9b27d 268 xfree (ptr);
c906108c 269 }
39db33d6 270}
c906108c 271
39db33d6
SC
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. */
275CORE_ADDR
276tuiGetLowDisassemblyAddress (CORE_ADDR low, CORE_ADDR pc)
c906108c
SS
277{
278 int line;
279 Opaque newLow;
280
39db33d6
SC
281 /* Determine where to start the disassembly so that the pc is about in the
282 middle of the viewport. */
c906108c
SS
283 for (line = 0, newLow = pc;
284 (newLow > low &&
285 line < (tuiDefaultWinViewportHeight (DISASSEM_WIN,
286 DISASSEM_COMMAND) / 2));)
287 {
288 bfd_byte buffer[4];
289
290 newLow -= sizeof (bfd_getb32 (buffer));
291 line++;
292 }
293
294 return newLow;
39db33d6 295}
c906108c 296
c906108c 297void
eca6576c 298strcat_to_buf (char *buf, int buflen, char *itemToAdd)
c906108c
SS
299{
300 if (itemToAdd != (char *) NULL && buf != (char *) NULL)
301 {
302 if ((strlen (buf) + strlen (itemToAdd)) <= buflen)
303 strcat (buf, itemToAdd);
304 else
305 strncat (buf, itemToAdd, (buflen - strlen (buf)));
306 }
c906108c
SS
307}
308
39db33d6
SC
309#if 0
310/* Solaris <sys/termios.h> defines CTRL. */
311#ifndef CTRL
312#define CTRL(x) (x & ~0140)
313#endif
c906108c 314
39db33d6
SC
315#define FILEDES 2
316#define CHK(val, dft) (val<=0 ? dft : val)
c906108c
SS
317
318static void
c906108c 319_tuiReset (void)
c906108c
SS
320{
321 struct termio mode;
322
323 /*
c5aa993b
JM
324 ** reset the teletype mode bits to a sensible state.
325 ** Copied tset.c
326 */
c906108c
SS
327#if ! defined (USG) && defined (TIOCGETC)
328 struct tchars tbuf;
329#endif /* !USG && TIOCGETC */
330#ifdef UCB_NTTY
331 struct ltchars ltc;
332
333 if (ldisc == NTTYDISC)
334 {
335 ioctl (FILEDES, TIOCGLTC, &ltc);
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, &ltc);
343 }
344#endif /* UCB_NTTY */
345#ifndef USG
346#ifdef TIOCGETC
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
357#ifdef CBREAK
358 | CBREAK
359#endif /* CBREAK */
360 | VTDELAY | ALLDELAY);
361 mode.sg_flags |= XTABS | ECHO | CRMOD | ANYP;
c5aa993b 362#else /*USG */
c906108c
SS
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'));
367
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);
374#ifndef hp9000s800
375 mode.c_cflag |= (CS8 | CREAD);
c5aa993b 376#else /*hp9000s800 */
c906108c
SS
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);
382#endif /* USG */
383
384 return;
385} /* _tuiReset */
39db33d6
SC
386#endif
387
1403b519
SC
388
389void
390tui_show_assembly (CORE_ADDR addr)
391{
392 tuiAddWinToLayout (DISASSEM_WIN);
393 tuiUpdateSourceWindowsWithAddr (addr);
394}
395
396int
397tui_is_window_visible (TuiWinType type)
398{
399 if (tui_version == 0)
400 return 0;
401
402 if (winList[type] == 0)
403 return 0;
404
405 return winList[type]->generic.isVisible;
406}
407
408int
409tui_get_command_dimension (int *width, int *height)
410{
411 if (!tui_version || !m_winPtrNotNull (cmdWin))
412 {
413 return 0;
414 }
415
416 *width = cmdWin->generic.width;
417 *height = cmdWin->generic.height;
418 return 1;
419}
This page took 0.140598 seconds and 4 git commands to generate.