* gdb.base/maint.exp: Treat $EXEEXT as optional in output.
[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"
c6f60bcd 42#include "tuiSourceWin.h"
39db33d6
SC
43#include "readline/readline.h"
44#include "target.h"
45#include "frame.h"
46#include "breakpoint.h"
c6f60bcd 47#include "inferior.h"
39db33d6
SC
48
49/* Tells whether the TUI is active or not. */
50int tui_active = 0;
51static int tui_finish_init = 1;
52
53/* Switch the output mode between TUI/standard gdb. */
54static int
55tui_switch_mode (void)
c906108c 56{
39db33d6 57 if (tui_active)
c906108c 58 {
39db33d6 59 tui_disable ();
c6f60bcd
SC
60 rl_prep_terminal (0);
61
39db33d6
SC
62 printf_filtered ("Left the TUI mode\n");
63 }
64 else
65 {
c6f60bcd 66 rl_deprep_terminal ();
39db33d6
SC
67 tui_enable ();
68 printf_filtered ("Entered the TUI mode\n");
c906108c 69 }
c906108c 70
39db33d6
SC
71 /* Clear the readline in case switching occurred in middle of something. */
72 if (rl_end)
73 rl_kill_text (0, rl_end);
74
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. */
81 rl_newline (1, '\n');
c6f60bcd
SC
82
83 /* Make sure the \n we are returning does not repeat the last command. */
84 dont_repeat ();
39db33d6
SC
85 return 0;
86}
c906108c 87
377c38ea
SC
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). */
92static int
93tui_change_windows (void)
94{
95 if (!tui_active)
96 tui_switch_mode ();
97
98 if (tui_active)
99 {
100 TuiLayoutType new_layout;
101 TuiRegisterDisplayType regs_type = TUI_UNDEFINED_REGS;
102
103 new_layout = currentLayout ();
104
105 /* Select a new layout to have a rolling layout behavior
106 with always two windows (except when undefined). */
107 switch (new_layout)
108 {
109 case SRC_COMMAND:
110 new_layout = SRC_DISASSEM_COMMAND;
111 break;
112
113 case DISASSEM_COMMAND:
114 new_layout = SRC_DISASSEM_COMMAND;
115 break;
116
117 case SRC_DATA_COMMAND:
118 new_layout = SRC_DISASSEM_COMMAND;
119 break;
120
121 case SRC_DISASSEM_COMMAND:
122 new_layout = DISASSEM_DATA_COMMAND;
123 break;
124
125 case DISASSEM_DATA_COMMAND:
126 new_layout = SRC_DATA_COMMAND;
127 break;
128
129 default:
130 new_layout = SRC_COMMAND;
131 break;
132 }
133 tuiSetLayout (new_layout, regs_type);
134 }
135 return 0;
136}
137
138
139/* Delete the second TUI window to only show one. */
140static int
141tui_delete_other_windows (void)
142{
143 if (!tui_active)
144 tui_switch_mode ();
145
146 if (tui_active)
147 {
148 TuiLayoutType new_layout;
149 TuiRegisterDisplayType regs_type = TUI_UNDEFINED_REGS;
150
151 new_layout = currentLayout ();
152
153 /* Kill one window. */
154 switch (new_layout)
155 {
156 case SRC_COMMAND:
157 case SRC_DATA_COMMAND:
158 case SRC_DISASSEM_COMMAND:
159 default:
160 new_layout = SRC_COMMAND;
161 break;
162
163 case DISASSEM_COMMAND:
164 case DISASSEM_DATA_COMMAND:
165 new_layout = DISASSEM_COMMAND;
166 break;
167 }
168 tuiSetLayout (new_layout, regs_type);
169 }
170 return 0;
171}
172
39db33d6
SC
173/* Initialize readline and configure the keymap for the switching
174 key shortcut. */
c906108c 175void
39db33d6 176tui_initialize_readline ()
c906108c 177{
39db33d6 178 rl_initialize ();
c906108c 179
39db33d6
SC
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);
377c38ea
SC
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);
39db33d6 186}
c906108c 187
39db33d6
SC
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. */
c906108c 192void
39db33d6 193tui_enable (void)
c906108c 194{
39db33d6
SC
195 if (tui_active)
196 return;
197
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. */
201 if (tui_finish_init)
c906108c 202 {
39db33d6
SC
203 WINDOW *w;
204
205 w = initscr ();
206
377c38ea
SC
207 cbreak ();
208 noecho ();
39db33d6
SC
209 /*timeout (1);*/
210 nodelay(w, FALSE);
211 nl();
212 keypad (w, TRUE);
213 rl_initialize ();
214 setTermHeightTo (LINES);
215 setTermWidthTo (COLS);
216 def_prog_mode ();
217
218 tuiSetLocatorContent (0);
219 showLayout (SRC_COMMAND);
220 tuiSetWinFocusTo (srcWin);
377c38ea 221 keypad (cmdWin->generic.handle, TRUE);
39db33d6
SC
222 wrefresh (cmdWin->generic.handle);
223 tui_finish_init = 0;
c906108c 224 }
39db33d6
SC
225 else
226 {
227 /* Save the current gdb setting of the terminal.
228 Curses will restore this state when endwin() is called. */
229 def_shell_mode ();
230 clearok (stdscr, TRUE);
231 }
c906108c 232
39db33d6
SC
233 /* Install the TUI specific hooks. */
234 tui_install_hooks ();
c906108c 235
377c38ea
SC
236 tui_update_variables ();
237
39db33d6 238 tui_setup_io (1);
c906108c 239
39db33d6
SC
240 tui_version = 1;
241 tui_active = 1;
242 refresh ();
243}
244
245/* Leave the tui mode.
246 Remove the tui hooks and configure the gdb output and readline
247 back to their original state. The curses mode is left so that
248 the terminal setting is restored to the point when we entered. */
c906108c 249void
39db33d6 250tui_disable (void)
c906108c 251{
39db33d6
SC
252 if (!tui_active)
253 return;
c906108c 254
39db33d6
SC
255 /* Remove TUI hooks. */
256 tui_remove_hooks ();
c906108c 257
39db33d6
SC
258 /* Leave curses and restore previous gdb terminal setting. */
259 endwin ();
c906108c 260
39db33d6
SC
261 /* gdb terminal has changed, update gdb internal copy of it
262 so that terminal management with the inferior works. */
263 tui_setup_io (0);
c906108c 264
39db33d6
SC
265 tui_version = 0;
266 tui_active = 0;
267}
c906108c 268
39db33d6
SC
269/* Wrapper on top of free() to ensure that input address
270 is greater than 0x0. */
c906108c 271void
eca6576c 272tuiFree (char *ptr)
c906108c
SS
273{
274 if (ptr != (char *) NULL)
275 {
b8c9b27d 276 xfree (ptr);
c906108c 277 }
39db33d6 278}
c906108c 279
39db33d6
SC
280/* Determine what the low address will be to display in the TUI's
281 disassembly window. This may or may not be the same as the
282 low address input. */
283CORE_ADDR
284tuiGetLowDisassemblyAddress (CORE_ADDR low, CORE_ADDR pc)
c906108c
SS
285{
286 int line;
c6f60bcd 287 CORE_ADDR newLow;
c906108c 288
39db33d6
SC
289 /* Determine where to start the disassembly so that the pc is about in the
290 middle of the viewport. */
c906108c
SS
291 for (line = 0, newLow = pc;
292 (newLow > low &&
293 line < (tuiDefaultWinViewportHeight (DISASSEM_WIN,
294 DISASSEM_COMMAND) / 2));)
295 {
296 bfd_byte buffer[4];
297
298 newLow -= sizeof (bfd_getb32 (buffer));
299 line++;
300 }
301
302 return newLow;
39db33d6 303}
c906108c 304
c906108c 305void
eca6576c 306strcat_to_buf (char *buf, int buflen, char *itemToAdd)
c906108c
SS
307{
308 if (itemToAdd != (char *) NULL && buf != (char *) NULL)
309 {
310 if ((strlen (buf) + strlen (itemToAdd)) <= buflen)
311 strcat (buf, itemToAdd);
312 else
313 strncat (buf, itemToAdd, (buflen - strlen (buf)));
314 }
c906108c
SS
315}
316
39db33d6
SC
317#if 0
318/* Solaris <sys/termios.h> defines CTRL. */
319#ifndef CTRL
320#define CTRL(x) (x & ~0140)
321#endif
c906108c 322
39db33d6
SC
323#define FILEDES 2
324#define CHK(val, dft) (val<=0 ? dft : val)
c906108c
SS
325
326static void
c906108c 327_tuiReset (void)
c906108c
SS
328{
329 struct termio mode;
330
331 /*
c5aa993b
JM
332 ** reset the teletype mode bits to a sensible state.
333 ** Copied tset.c
334 */
c906108c
SS
335#if ! defined (USG) && defined (TIOCGETC)
336 struct tchars tbuf;
337#endif /* !USG && TIOCGETC */
338#ifdef UCB_NTTY
339 struct ltchars ltc;
340
341 if (ldisc == NTTYDISC)
342 {
343 ioctl (FILEDES, TIOCGLTC, &ltc);
344 ltc.t_suspc = CHK (ltc.t_suspc, CTRL ('Z'));
345 ltc.t_dsuspc = CHK (ltc.t_dsuspc, CTRL ('Y'));
346 ltc.t_rprntc = CHK (ltc.t_rprntc, CTRL ('R'));
347 ltc.t_flushc = CHK (ltc.t_flushc, CTRL ('O'));
348 ltc.t_werasc = CHK (ltc.t_werasc, CTRL ('W'));
349 ltc.t_lnextc = CHK (ltc.t_lnextc, CTRL ('V'));
350 ioctl (FILEDES, TIOCSLTC, &ltc);
351 }
352#endif /* UCB_NTTY */
353#ifndef USG
354#ifdef TIOCGETC
355 ioctl (FILEDES, TIOCGETC, &tbuf);
356 tbuf.t_intrc = CHK (tbuf.t_intrc, CTRL ('?'));
357 tbuf.t_quitc = CHK (tbuf.t_quitc, CTRL ('\\'));
358 tbuf.t_startc = CHK (tbuf.t_startc, CTRL ('Q'));
359 tbuf.t_stopc = CHK (tbuf.t_stopc, CTRL ('S'));
360 tbuf.t_eofc = CHK (tbuf.t_eofc, CTRL ('D'));
361 /* brkc is left alone */
362 ioctl (FILEDES, TIOCSETC, &tbuf);
363#endif /* TIOCGETC */
364 mode.sg_flags &= ~(RAW
365#ifdef CBREAK
366 | CBREAK
367#endif /* CBREAK */
368 | VTDELAY | ALLDELAY);
369 mode.sg_flags |= XTABS | ECHO | CRMOD | ANYP;
c5aa993b 370#else /*USG */
c906108c
SS
371 ioctl (FILEDES, TCGETA, &mode);
372 mode.c_cc[VINTR] = CHK (mode.c_cc[VINTR], CTRL ('?'));
373 mode.c_cc[VQUIT] = CHK (mode.c_cc[VQUIT], CTRL ('\\'));
374 mode.c_cc[VEOF] = CHK (mode.c_cc[VEOF], CTRL ('D'));
375
376 mode.c_iflag &= ~(IGNBRK | PARMRK | INPCK | INLCR | IGNCR | IUCLC | IXOFF);
377 mode.c_iflag |= (BRKINT | ISTRIP | ICRNL | IXON);
378 mode.c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL |
379 NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY);
380 mode.c_oflag |= (OPOST | ONLCR);
381 mode.c_cflag &= ~(CSIZE | PARODD | CLOCAL);
382#ifndef hp9000s800
383 mode.c_cflag |= (CS8 | CREAD);
c5aa993b 384#else /*hp9000s800 */
c906108c
SS
385 mode.c_cflag |= (CS8 | CSTOPB | CREAD);
386#endif /* hp9000s800 */
387 mode.c_lflag &= ~(XCASE | ECHONL | NOFLSH);
388 mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOK);
389 ioctl (FILEDES, TCSETAW, &mode);
390#endif /* USG */
391
392 return;
393} /* _tuiReset */
39db33d6
SC
394#endif
395
c6f60bcd
SC
396void
397tui_show_source (const char *file, int line)
398{
399 /* make sure that the source window is displayed */
400 tuiAddWinToLayout (SRC_WIN);
401
402 tuiUpdateSourceWindowsWithLine (current_source_symtab, line);
403 tuiUpdateLocatorFilename (file);
404}
1403b519
SC
405
406void
407tui_show_assembly (CORE_ADDR addr)
408{
409 tuiAddWinToLayout (DISASSEM_WIN);
410 tuiUpdateSourceWindowsWithAddr (addr);
411}
412
413int
414tui_is_window_visible (TuiWinType type)
415{
416 if (tui_version == 0)
417 return 0;
418
419 if (winList[type] == 0)
420 return 0;
421
422 return winList[type]->generic.isVisible;
423}
424
425int
426tui_get_command_dimension (int *width, int *height)
427{
428 if (!tui_version || !m_winPtrNotNull (cmdWin))
429 {
430 return 0;
431 }
432
433 *width = cmdWin->generic.width;
434 *height = cmdWin->generic.height;
435 return 1;
436}
This page took 0.160107 seconds and 4 git commands to generate.