1 /* TUI support I/O functions.
3 Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
6 Contributed by Hewlett-Packard Company.
8 This file is part of GDB.
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.
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.
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. */
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>
46 #include "event-loop.h"
47 #include "event-top.h"
50 #include "readline/readline.h"
54 #include "tuiCommand.h"
56 #include "tuiGeneralWin.h"
63 /* Use definition from readline 4.3. */
65 #define CTRL_CHAR(c) ((c) < control_character_threshold && (((c) & 0x80) == 0))
67 /* This file controls the IO interactions between gdb and curses.
68 When the TUI is enabled, gdb has two modes a curses and a standard
71 In curses mode, the gdb outputs are made in a curses command window.
72 For this, the gdb_stdout and gdb_stderr are redirected to the specific
73 ui_file implemented by TUI. The output is handled by tui_puts().
74 The input is also controlled by curses with tui_getc(). The readline
75 library uses this function to get its input. Several readline hooks
76 are installed to redirect readline output to the TUI (see also the
79 In normal mode, the gdb outputs are restored to their origin, that
80 is as if TUI is not used. Readline also uses its original getc()
83 Note: the current readline is not clean in its management of the output.
84 Even if we install a redisplay handler, it sometimes writes on a stdout
85 file. It is important to redirect every output produced by readline,
86 otherwise the curses window will be garbled. This is implemented with
87 a pipe that TUI reads and readline writes to. A gdb input handler
88 is created so that reading the pipe is handled automatically.
89 This will probably not work on non-Unix platforms. The best fix is
90 to make readline clean enougth so that is never write on stdout. */
92 /* TUI output files. */
93 static struct ui_file *tui_stdout;
94 static struct ui_file *tui_stderr;
95 static struct ui_out *tui_out;
97 /* GDB output files in non-curses mode. */
98 static struct ui_file *tui_old_stdout;
99 static struct ui_file *tui_old_stderr;
100 static struct ui_out *tui_old_uiout;
102 /* Readline previous hooks. */
103 static Function *tui_old_rl_getc_function;
104 static VFunction *tui_old_rl_redisplay_function;
105 static VFunction *tui_old_rl_prep_terminal;
106 static VFunction *tui_old_rl_deprep_terminal;
107 static int tui_old_readline_echoing_p;
109 /* Readline output stream.
110 Should be removed when readline is clean. */
111 static FILE *tui_rl_outstream;
112 static FILE *tui_old_rl_outstream;
113 static int tui_readline_pipe[2];
115 static unsigned int _tuiHandleResizeDuringIO (unsigned int);
118 /* Print the string in the curses command window. */
120 tui_puts (const char *string)
122 static int tui_skip_line = -1;
126 w = cmdWin->generic.handle;
127 while ((c = *string++) != 0)
129 /* Catch annotation and discard them. We need two \032 and
130 discard until a \n is seen. */
135 else if (tui_skip_line != 1)
143 getyx (w, cmdWin->detail.commandInfo.curLine,
144 cmdWin->detail.commandInfo.curch);
145 cmdWin->detail.commandInfo.start_line = cmdWin->detail.commandInfo.curLine;
147 /* We could defer the following. */
152 /* Readline callback.
153 Redisplay the command line with its prompt after readline has
154 changed the edited text. */
156 tui_redisplay_readline (void)
168 if (tui_current_key_mode == tui_single_key_mode)
171 prompt = get_prompt ();
175 w = cmdWin->generic.handle;
176 start_line = cmdWin->detail.commandInfo.start_line;
177 wmove (w, start_line, 0);
180 for (in = 0; prompt && prompt[in]; in++)
182 waddch (w, prompt[in]);
183 getyx (w, line, col);
188 for (in = 0; in < rl_end; in++)
192 c = (unsigned char) rl_line_buffer[in];
195 getyx (w, c_line, c_pos);
198 if (CTRL_CHAR (c) || c == RUBOUT)
201 waddch (w, CTRL_CHAR (c) ? UNCTRL (c) : '?');
209 getyx (w, cmdWin->detail.commandInfo.start_line,
210 cmdWin->detail.commandInfo.curch);
212 getyx (w, line, col);
218 getyx (w, cmdWin->detail.commandInfo.start_line,
219 cmdWin->detail.commandInfo.curch);
222 wmove (w, c_line, c_pos);
223 cmdWin->detail.commandInfo.curLine = c_line;
224 cmdWin->detail.commandInfo.curch = c_pos;
226 cmdWin->detail.commandInfo.start_line -= height - 1;
232 /* Readline callback to prepare the terminal. It is called once
233 each time we enter readline. There is nothing to do in curses mode. */
235 tui_prep_terminal (void)
239 /* Readline callback to restore the terminal. It is called once
240 each time we leave readline. There is nothing to do in curses mode. */
242 tui_deprep_terminal (void)
246 /* Read readline output pipe and feed the command window with it.
247 Should be removed when readline is clean. */
249 tui_readline_output (int code, gdb_client_data data)
254 size = read (tui_readline_pipe[0], buf, sizeof (buf) - 1);
255 if (size > 0 && tui_active)
262 /* Setup the IO for curses or non-curses mode.
263 - In non-curses mode, readline and gdb use the standard input and
264 standard output/error directly.
265 - In curses mode, the standard output/error is controlled by TUI
266 with the tui_stdout and tui_stderr. The output is redirected in
267 the curses command window. Several readline callbacks are installed
268 so that readline asks for its input to the curses command window
271 tui_setup_io (int mode)
273 extern int readline_echoing_p;
277 /* Redirect readline to TUI. */
278 tui_old_rl_redisplay_function = rl_redisplay_function;
279 tui_old_rl_deprep_terminal = rl_deprep_term_function;
280 tui_old_rl_prep_terminal = rl_prep_term_function;
281 tui_old_rl_getc_function = rl_getc_function;
282 tui_old_rl_outstream = rl_outstream;
283 tui_old_readline_echoing_p = readline_echoing_p;
284 rl_redisplay_function = tui_redisplay_readline;
285 rl_deprep_term_function = tui_deprep_terminal;
286 rl_prep_term_function = tui_prep_terminal;
287 rl_getc_function = tui_getc;
288 readline_echoing_p = 0;
289 rl_outstream = tui_rl_outstream;
292 /* Keep track of previous gdb output. */
293 tui_old_stdout = gdb_stdout;
294 tui_old_stderr = gdb_stderr;
295 tui_old_uiout = uiout;
297 /* Reconfigure gdb output. */
298 gdb_stdout = tui_stdout;
299 gdb_stderr = tui_stderr;
300 gdb_stdlog = gdb_stdout; /* for moment */
301 gdb_stdtarg = gdb_stderr; /* for moment */
304 /* Save tty for SIGCONT. */
309 /* Restore gdb output. */
310 gdb_stdout = tui_old_stdout;
311 gdb_stderr = tui_old_stderr;
312 gdb_stdlog = gdb_stdout; /* for moment */
313 gdb_stdtarg = gdb_stderr; /* for moment */
314 uiout = tui_old_uiout;
316 /* Restore readline. */
317 rl_redisplay_function = tui_old_rl_redisplay_function;
318 rl_deprep_term_function = tui_old_rl_deprep_terminal;
319 rl_prep_term_function = tui_old_rl_prep_terminal;
320 rl_getc_function = tui_old_rl_getc_function;
321 rl_outstream = tui_old_rl_outstream;
322 readline_echoing_p = tui_old_readline_echoing_p;
324 /* Save tty for SIGCONT. */
330 /* Catch SIGCONT to restore the terminal and refresh the screen. */
332 tui_cont_sig (int sig)
336 /* Restore the terminal setting because another process (shell)
337 might have changed it. */
340 /* Force a refresh of the screen. */
343 /* Update cursor position on the screen. */
344 wmove (cmdWin->generic.handle,
345 cmdWin->detail.commandInfo.start_line,
346 cmdWin->detail.commandInfo.curch);
347 wrefresh (cmdWin->generic.handle);
349 signal (sig, tui_cont_sig);
353 /* Initialize the IO for gdb in curses mode. */
358 signal (SIGCONT, tui_cont_sig);
361 /* Create tui output streams. */
362 tui_stdout = tui_fileopen (stdout);
363 tui_stderr = tui_fileopen (stderr);
364 tui_out = tui_out_new (tui_stdout);
366 /* Create the default UI. It is not created because we installed
368 uiout = cli_out_new (gdb_stdout);
370 /* Temporary solution for readline writing to stdout:
371 redirect readline output in a pipe, read that pipe and
372 output the content in the curses command window. */
373 if (pipe (tui_readline_pipe) != 0)
375 fprintf_unfiltered (gdb_stderr, "Cannot create pipe for readline");
378 tui_rl_outstream = fdopen (tui_readline_pipe[1], "w");
379 if (tui_rl_outstream == 0)
381 fprintf_unfiltered (gdb_stderr, "Cannot redirect readline output");
384 setlinebuf (tui_rl_outstream);
387 (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NONBLOCK);
390 (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NDELAY);
394 add_file_handler (tui_readline_pipe[0], tui_readline_output, 0);
397 /* Get a character from the command window. This is called from the readline
405 w = cmdWin->generic.handle;
407 /* Flush readline output. */
408 tui_readline_output (GDB_READABLE, 0);
411 ch = _tuiHandleResizeDuringIO (ch);
413 /* The \n must be echoed because it will not be printed by readline. */
416 /* When hitting return with an empty input, gdb executes the last
417 command. If we emit a newline, this fills up the command window
418 with empty lines with gdb prompt at beginning. Instead of that,
419 stay on the same line but provide a visual effect to show the
420 user we recognized the command. */
423 wmove (w, cmdWin->detail.commandInfo.curLine, 0);
425 /* Clear the line. This will blink the gdb prompt since
426 it will be redrawn at the same line. */
433 wmove (w, cmdWin->detail.commandInfo.curLine,
434 cmdWin->detail.commandInfo.curch);
439 if (m_isCommandChar (ch))
440 { /* Handle prev/next/up/down here */
441 ch = tuiDispatchCtrlChar (ch);
444 if (ch == '\n' || ch == '\r' || ch == '\f')
445 cmdWin->detail.commandInfo.curch = 0;
448 tuiIncrCommandCharCountBy (1);
450 if (ch == KEY_BACKSPACE)
457 /* Cleanup when a resize has occured.
458 Returns the character that must be processed. */
460 _tuiHandleResizeDuringIO (unsigned int originalCh)
462 if (tuiWinResized ())
466 tuiSetWinResizedTo (FALSE);