1130803Smarcel/* TUI support I/O functions. 2130803Smarcel 3130803Smarcel Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software 4130803Smarcel Foundation, Inc. 5130803Smarcel 6130803Smarcel Contributed by Hewlett-Packard Company. 7130803Smarcel 8130803Smarcel This file is part of GDB. 9130803Smarcel 10130803Smarcel This program is free software; you can redistribute it and/or modify 11130803Smarcel it under the terms of the GNU General Public License as published by 12130803Smarcel the Free Software Foundation; either version 2 of the License, or 13130803Smarcel (at your option) any later version. 14130803Smarcel 15130803Smarcel This program is distributed in the hope that it will be useful, 16130803Smarcel but WITHOUT ANY WARRANTY; without even the implied warranty of 17130803Smarcel MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18130803Smarcel GNU General Public License for more details. 19130803Smarcel 20130803Smarcel You should have received a copy of the GNU General Public License 21130803Smarcel along with this program; if not, write to the Free Software 22130803Smarcel Foundation, Inc., 59 Temple Place - Suite 330, 23130803Smarcel Boston, MA 02111-1307, USA. */ 24130803Smarcel 25130803Smarcel#include "defs.h" 26130803Smarcel#include "terminal.h" 27130803Smarcel#include "target.h" 28130803Smarcel#include "event-loop.h" 29130803Smarcel#include "event-top.h" 30130803Smarcel#include "command.h" 31130803Smarcel#include "top.h" 32130803Smarcel#include "readline/readline.h" 33130803Smarcel#include "tui/tui.h" 34130803Smarcel#include "tui/tui-data.h" 35130803Smarcel#include "tui/tui-io.h" 36130803Smarcel#include "tui/tui-command.h" 37130803Smarcel#include "tui/tui-win.h" 38130803Smarcel#include "tui/tui-wingeneral.h" 39130803Smarcel#include "tui/tui-file.h" 40130803Smarcel#include "ui-out.h" 41130803Smarcel#include "cli-out.h" 42130803Smarcel#include <fcntl.h> 43130803Smarcel#include <signal.h> 44130803Smarcel#include <stdio.h> 45130803Smarcel 46130803Smarcel#include "gdb_curses.h" 47130803Smarcel 48130803Smarcelint 49130803Smarcelkey_is_start_sequence (int ch) 50130803Smarcel{ 51130803Smarcel return (ch == 27); 52130803Smarcel} 53130803Smarcel 54130803Smarcelint 55130803Smarcelkey_is_end_sequence (int ch) 56130803Smarcel{ 57130803Smarcel return (ch == 126); 58130803Smarcel} 59130803Smarcel 60130803Smarcelint 61130803Smarcelkey_is_backspace (int ch) 62130803Smarcel{ 63130803Smarcel return (ch == 8); 64130803Smarcel} 65130803Smarcel 66130803Smarcelint 67130803Smarcelkey_is_command_char (int ch) 68130803Smarcel{ 69130803Smarcel return ((ch == KEY_NPAGE) || (ch == KEY_PPAGE) 70130803Smarcel || (ch == KEY_LEFT) || (ch == KEY_RIGHT) 71130803Smarcel || (ch == KEY_UP) || (ch == KEY_DOWN) 72130803Smarcel || (ch == KEY_SF) || (ch == KEY_SR) 73130803Smarcel || (ch == (int)'\f') || key_is_start_sequence (ch)); 74130803Smarcel} 75130803Smarcel 76130803Smarcel/* Use definition from readline 4.3. */ 77130803Smarcel#undef CTRL_CHAR 78130803Smarcel#define CTRL_CHAR(c) ((c) < control_character_threshold && (((c) & 0x80) == 0)) 79130803Smarcel 80130803Smarcel/* This file controls the IO interactions between gdb and curses. 81130803Smarcel When the TUI is enabled, gdb has two modes a curses and a standard 82130803Smarcel mode. 83130803Smarcel 84130803Smarcel In curses mode, the gdb outputs are made in a curses command window. 85130803Smarcel For this, the gdb_stdout and gdb_stderr are redirected to the specific 86130803Smarcel ui_file implemented by TUI. The output is handled by tui_puts(). 87130803Smarcel The input is also controlled by curses with tui_getc(). The readline 88130803Smarcel library uses this function to get its input. Several readline hooks 89130803Smarcel are installed to redirect readline output to the TUI (see also the 90130803Smarcel note below). 91130803Smarcel 92130803Smarcel In normal mode, the gdb outputs are restored to their origin, that 93130803Smarcel is as if TUI is not used. Readline also uses its original getc() 94130803Smarcel function with stdin. 95130803Smarcel 96130803Smarcel Note SCz/2001-07-21: the current readline is not clean in its management of 97130803Smarcel the output. Even if we install a redisplay handler, it sometimes writes on 98130803Smarcel a stdout file. It is important to redirect every output produced by 99130803Smarcel readline, otherwise the curses window will be garbled. This is implemented 100130803Smarcel with a pipe that TUI reads and readline writes to. A gdb input handler 101130803Smarcel is created so that reading the pipe is handled automatically. 102130803Smarcel This will probably not work on non-Unix platforms. The best fix is 103130803Smarcel to make readline clean enougth so that is never write on stdout. 104130803Smarcel 105130803Smarcel Note SCz/2002-09-01: we now use more readline hooks and it seems that 106130803Smarcel with them we don't need the pipe anymore (verified by creating the pipe 107130803Smarcel and closing its end so that write causes a SIGPIPE). The old pipe code 108130803Smarcel is still there and can be conditionally removed by 109130803Smarcel #undef TUI_USE_PIPE_FOR_READLINE. */ 110130803Smarcel 111130803Smarcel/* For gdb 5.3, prefer to continue the pipe hack as a backup wheel. */ 112130803Smarcel#define TUI_USE_PIPE_FOR_READLINE 113130803Smarcel/*#undef TUI_USE_PIPE_FOR_READLINE*/ 114130803Smarcel 115130803Smarcel/* TUI output files. */ 116130803Smarcelstatic struct ui_file *tui_stdout; 117130803Smarcelstatic struct ui_file *tui_stderr; 118130803Smarcelstruct ui_out *tui_out; 119130803Smarcel 120130803Smarcel/* GDB output files in non-curses mode. */ 121130803Smarcelstatic struct ui_file *tui_old_stdout; 122130803Smarcelstatic struct ui_file *tui_old_stderr; 123130803Smarcelstruct ui_out *tui_old_uiout; 124130803Smarcel 125130803Smarcel/* Readline previous hooks. */ 126130803Smarcelstatic Function *tui_old_rl_getc_function; 127130803Smarcelstatic VFunction *tui_old_rl_redisplay_function; 128130803Smarcelstatic VFunction *tui_old_rl_prep_terminal; 129130803Smarcelstatic VFunction *tui_old_rl_deprep_terminal; 130130803Smarcelstatic int tui_old_readline_echoing_p; 131130803Smarcel 132130803Smarcel/* Readline output stream. 133130803Smarcel Should be removed when readline is clean. */ 134130803Smarcelstatic FILE *tui_rl_outstream; 135130803Smarcelstatic FILE *tui_old_rl_outstream; 136130803Smarcel#ifdef TUI_USE_PIPE_FOR_READLINE 137130803Smarcelstatic int tui_readline_pipe[2]; 138130803Smarcel#endif 139130803Smarcel 140130803Smarcel/* The last gdb prompt that was registered in readline. 141130803Smarcel This may be the main gdb prompt or a secondary prompt. */ 142130803Smarcelstatic char *tui_rl_saved_prompt; 143130803Smarcel 144130803Smarcelstatic unsigned int tui_handle_resize_during_io (unsigned int); 145130803Smarcel 146130803Smarcelstatic void 147130803Smarceltui_putc (char c) 148130803Smarcel{ 149130803Smarcel char buf[2]; 150130803Smarcel 151130803Smarcel buf[0] = c; 152130803Smarcel buf[1] = 0; 153130803Smarcel tui_puts (buf); 154130803Smarcel} 155130803Smarcel 156130803Smarcel/* Print the string in the curses command window. */ 157130803Smarcelvoid 158130803Smarceltui_puts (const char *string) 159130803Smarcel{ 160130803Smarcel static int tui_skip_line = -1; 161130803Smarcel char c; 162130803Smarcel WINDOW *w; 163130803Smarcel 164130803Smarcel w = TUI_CMD_WIN->generic.handle; 165130803Smarcel while ((c = *string++) != 0) 166130803Smarcel { 167130803Smarcel /* Catch annotation and discard them. We need two \032 and 168130803Smarcel discard until a \n is seen. */ 169130803Smarcel if (c == '\032') 170130803Smarcel { 171130803Smarcel tui_skip_line++; 172130803Smarcel } 173130803Smarcel else if (tui_skip_line != 1) 174130803Smarcel { 175130803Smarcel tui_skip_line = -1; 176130803Smarcel waddch (w, c); 177130803Smarcel } 178130803Smarcel else if (c == '\n') 179130803Smarcel tui_skip_line = -1; 180130803Smarcel } 181130803Smarcel getyx (w, TUI_CMD_WIN->detail.command_info.cur_line, 182130803Smarcel TUI_CMD_WIN->detail.command_info.curch); 183130803Smarcel TUI_CMD_WIN->detail.command_info.start_line = TUI_CMD_WIN->detail.command_info.cur_line; 184130803Smarcel 185130803Smarcel /* We could defer the following. */ 186130803Smarcel wrefresh (w); 187130803Smarcel fflush (stdout); 188130803Smarcel} 189130803Smarcel 190130803Smarcel/* Readline callback. 191130803Smarcel Redisplay the command line with its prompt after readline has 192130803Smarcel changed the edited text. */ 193130803Smarcelvoid 194130803Smarceltui_redisplay_readline (void) 195130803Smarcel{ 196130803Smarcel int prev_col; 197130803Smarcel int height; 198130803Smarcel int col, line; 199130803Smarcel int c_pos; 200130803Smarcel int c_line; 201130803Smarcel int in; 202130803Smarcel WINDOW *w; 203130803Smarcel char *prompt; 204130803Smarcel int start_line; 205130803Smarcel 206130803Smarcel /* Detect when we temporarily left SingleKey and now the readline 207130803Smarcel edit buffer is empty, automatically restore the SingleKey mode. */ 208130803Smarcel if (tui_current_key_mode == TUI_ONE_COMMAND_MODE && rl_end == 0) 209130803Smarcel tui_set_key_mode (TUI_SINGLE_KEY_MODE); 210130803Smarcel 211130803Smarcel if (tui_current_key_mode == TUI_SINGLE_KEY_MODE) 212130803Smarcel prompt = ""; 213130803Smarcel else 214130803Smarcel prompt = tui_rl_saved_prompt; 215130803Smarcel 216130803Smarcel c_pos = -1; 217130803Smarcel c_line = -1; 218130803Smarcel w = TUI_CMD_WIN->generic.handle; 219130803Smarcel start_line = TUI_CMD_WIN->detail.command_info.start_line; 220130803Smarcel wmove (w, start_line, 0); 221130803Smarcel prev_col = 0; 222130803Smarcel height = 1; 223130803Smarcel for (in = 0; prompt && prompt[in]; in++) 224130803Smarcel { 225130803Smarcel waddch (w, prompt[in]); 226130803Smarcel getyx (w, line, col); 227130803Smarcel if (col < prev_col) 228130803Smarcel height++; 229130803Smarcel prev_col = col; 230130803Smarcel } 231130803Smarcel for (in = 0; in < rl_end; in++) 232130803Smarcel { 233130803Smarcel unsigned char c; 234130803Smarcel 235130803Smarcel c = (unsigned char) rl_line_buffer[in]; 236130803Smarcel if (in == rl_point) 237130803Smarcel { 238130803Smarcel getyx (w, c_line, c_pos); 239130803Smarcel } 240130803Smarcel 241130803Smarcel if (CTRL_CHAR (c) || c == RUBOUT) 242130803Smarcel { 243130803Smarcel waddch (w, '^'); 244130803Smarcel waddch (w, CTRL_CHAR (c) ? UNCTRL (c) : '?'); 245130803Smarcel } 246130803Smarcel else 247130803Smarcel { 248130803Smarcel waddch (w, c); 249130803Smarcel } 250130803Smarcel if (c == '\n') 251130803Smarcel { 252130803Smarcel getyx (w, TUI_CMD_WIN->detail.command_info.start_line, 253130803Smarcel TUI_CMD_WIN->detail.command_info.curch); 254130803Smarcel } 255130803Smarcel getyx (w, line, col); 256130803Smarcel if (col < prev_col) 257130803Smarcel height++; 258130803Smarcel prev_col = col; 259130803Smarcel } 260130803Smarcel wclrtobot (w); 261130803Smarcel getyx (w, TUI_CMD_WIN->detail.command_info.start_line, 262130803Smarcel TUI_CMD_WIN->detail.command_info.curch); 263130803Smarcel if (c_line >= 0) 264130803Smarcel { 265130803Smarcel wmove (w, c_line, c_pos); 266130803Smarcel TUI_CMD_WIN->detail.command_info.cur_line = c_line; 267130803Smarcel TUI_CMD_WIN->detail.command_info.curch = c_pos; 268130803Smarcel } 269130803Smarcel TUI_CMD_WIN->detail.command_info.start_line -= height - 1; 270130803Smarcel 271130803Smarcel wrefresh (w); 272130803Smarcel fflush(stdout); 273130803Smarcel} 274130803Smarcel 275130803Smarcel/* Readline callback to prepare the terminal. It is called once 276130803Smarcel each time we enter readline. Terminal is already setup in curses mode. */ 277130803Smarcelstatic void 278130803Smarceltui_prep_terminal (int notused1) 279130803Smarcel{ 280130803Smarcel /* Save the prompt registered in readline to correctly display it. 281130803Smarcel (we can't use gdb_prompt() due to secondary prompts and can't use 282130803Smarcel rl_prompt because it points to an alloca buffer). */ 283130803Smarcel xfree (tui_rl_saved_prompt); 284130803Smarcel tui_rl_saved_prompt = xstrdup (rl_prompt); 285130803Smarcel} 286130803Smarcel 287130803Smarcel/* Readline callback to restore the terminal. It is called once 288130803Smarcel each time we leave readline. There is nothing to do in curses mode. */ 289130803Smarcelstatic void 290130803Smarceltui_deprep_terminal (void) 291130803Smarcel{ 292130803Smarcel} 293130803Smarcel 294130803Smarcel#ifdef TUI_USE_PIPE_FOR_READLINE 295130803Smarcel/* Read readline output pipe and feed the command window with it. 296130803Smarcel Should be removed when readline is clean. */ 297130803Smarcelstatic void 298130803Smarceltui_readline_output (int code, gdb_client_data data) 299130803Smarcel{ 300130803Smarcel int size; 301130803Smarcel char buf[256]; 302130803Smarcel 303130803Smarcel size = read (tui_readline_pipe[0], buf, sizeof (buf) - 1); 304130803Smarcel if (size > 0 && tui_active) 305130803Smarcel { 306130803Smarcel buf[size] = 0; 307130803Smarcel tui_puts (buf); 308130803Smarcel } 309130803Smarcel} 310130803Smarcel#endif 311130803Smarcel 312130803Smarcel/* Return the portion of PATHNAME that should be output when listing 313130803Smarcel possible completions. If we are hacking filename completion, we 314130803Smarcel are only interested in the basename, the portion following the 315130803Smarcel final slash. Otherwise, we return what we were passed. 316130803Smarcel 317130803Smarcel Comes from readline/complete.c */ 318130803Smarcelstatic char * 319130803Smarcelprintable_part (char *pathname) 320130803Smarcel{ 321130803Smarcel char *temp; 322130803Smarcel 323130803Smarcel temp = rl_filename_completion_desired ? strrchr (pathname, '/') : (char *)NULL; 324130803Smarcel#if defined (__MSDOS__) 325130803Smarcel if (rl_filename_completion_desired && temp == 0 && isalpha (pathname[0]) && pathname[1] == ':') 326130803Smarcel temp = pathname + 1; 327130803Smarcel#endif 328130803Smarcel return (temp ? ++temp : pathname); 329130803Smarcel} 330130803Smarcel 331130803Smarcel/* Output TO_PRINT to rl_outstream. If VISIBLE_STATS is defined and we 332130803Smarcel are using it, check for and output a single character for `special' 333130803Smarcel filenames. Return the number of characters we output. */ 334130803Smarcel 335130803Smarcel#define PUTX(c) \ 336130803Smarcel do { \ 337130803Smarcel if (CTRL_CHAR (c)) \ 338130803Smarcel { \ 339130803Smarcel tui_puts ("^"); \ 340130803Smarcel tui_putc (UNCTRL (c)); \ 341130803Smarcel printed_len += 2; \ 342130803Smarcel } \ 343130803Smarcel else if (c == RUBOUT) \ 344130803Smarcel { \ 345130803Smarcel tui_puts ("^?"); \ 346130803Smarcel printed_len += 2; \ 347130803Smarcel } \ 348130803Smarcel else \ 349130803Smarcel { \ 350130803Smarcel tui_putc (c); \ 351130803Smarcel printed_len++; \ 352130803Smarcel } \ 353130803Smarcel } while (0) 354130803Smarcel 355130803Smarcelstatic int 356130803Smarcelprint_filename (char *to_print, char *full_pathname) 357130803Smarcel{ 358130803Smarcel int printed_len = 0; 359130803Smarcel char *s; 360130803Smarcel 361130803Smarcel for (s = to_print; *s; s++) 362130803Smarcel { 363130803Smarcel PUTX (*s); 364130803Smarcel } 365130803Smarcel return printed_len; 366130803Smarcel} 367130803Smarcel 368130803Smarcel/* The user must press "y" or "n". Non-zero return means "y" pressed. 369130803Smarcel Comes from readline/complete.c */ 370130803Smarcelstatic int 371130803Smarcelget_y_or_n (void) 372130803Smarcel{ 373130803Smarcel extern int _rl_abort_internal (); 374130803Smarcel int c; 375130803Smarcel 376130803Smarcel for (;;) 377130803Smarcel { 378130803Smarcel c = rl_read_key (); 379130803Smarcel if (c == 'y' || c == 'Y' || c == ' ') 380130803Smarcel return (1); 381130803Smarcel if (c == 'n' || c == 'N' || c == RUBOUT) 382130803Smarcel return (0); 383130803Smarcel if (c == ABORT_CHAR) 384130803Smarcel _rl_abort_internal (); 385130803Smarcel beep (); 386130803Smarcel } 387130803Smarcel} 388130803Smarcel 389130803Smarcel/* A convenience function for displaying a list of strings in 390130803Smarcel columnar format on readline's output stream. MATCHES is the list 391130803Smarcel of strings, in argv format, LEN is the number of strings in MATCHES, 392130803Smarcel and MAX is the length of the longest string in MATCHES. 393130803Smarcel 394130803Smarcel Comes from readline/complete.c and modified to write in 395130803Smarcel the TUI command window using tui_putc/tui_puts. */ 396130803Smarcelstatic void 397130803Smarceltui_rl_display_match_list (char **matches, int len, int max) 398130803Smarcel{ 399130803Smarcel typedef int QSFUNC (const void *, const void *); 400130803Smarcel extern int _rl_qsort_string_compare (const void*, const void*); 401130803Smarcel extern int _rl_print_completions_horizontally; 402130803Smarcel 403130803Smarcel int count, limit, printed_len; 404130803Smarcel int i, j, k, l; 405130803Smarcel char *temp; 406130803Smarcel 407130803Smarcel /* Screen dimension correspond to the TUI command window. */ 408130803Smarcel int screenwidth = TUI_CMD_WIN->generic.width; 409130803Smarcel 410130803Smarcel /* If there are many items, then ask the user if she really wants to 411130803Smarcel see them all. */ 412130803Smarcel if (len >= rl_completion_query_items) 413130803Smarcel { 414130803Smarcel char msg[256]; 415130803Smarcel 416130803Smarcel sprintf (msg, "\nDisplay all %d possibilities? (y or n)", len); 417130803Smarcel tui_puts (msg); 418130803Smarcel if (get_y_or_n () == 0) 419130803Smarcel { 420130803Smarcel tui_puts ("\n"); 421130803Smarcel return; 422130803Smarcel } 423130803Smarcel } 424130803Smarcel 425130803Smarcel /* How many items of MAX length can we fit in the screen window? */ 426130803Smarcel max += 2; 427130803Smarcel limit = screenwidth / max; 428130803Smarcel if (limit != 1 && (limit * max == screenwidth)) 429130803Smarcel limit--; 430130803Smarcel 431130803Smarcel /* Avoid a possible floating exception. If max > screenwidth, 432130803Smarcel limit will be 0 and a divide-by-zero fault will result. */ 433130803Smarcel if (limit == 0) 434130803Smarcel limit = 1; 435130803Smarcel 436130803Smarcel /* How many iterations of the printing loop? */ 437130803Smarcel count = (len + (limit - 1)) / limit; 438130803Smarcel 439130803Smarcel /* Watch out for special case. If LEN is less than LIMIT, then 440130803Smarcel just do the inner printing loop. 441130803Smarcel 0 < len <= limit implies count = 1. */ 442130803Smarcel 443130803Smarcel /* Sort the items if they are not already sorted. */ 444130803Smarcel if (rl_ignore_completion_duplicates == 0) 445130803Smarcel qsort (matches + 1, len, sizeof (char *), 446130803Smarcel (QSFUNC *)_rl_qsort_string_compare); 447130803Smarcel 448130803Smarcel tui_putc ('\n'); 449130803Smarcel 450130803Smarcel if (_rl_print_completions_horizontally == 0) 451130803Smarcel { 452130803Smarcel /* Print the sorted items, up-and-down alphabetically, like ls. */ 453130803Smarcel for (i = 1; i <= count; i++) 454130803Smarcel { 455130803Smarcel for (j = 0, l = i; j < limit; j++) 456130803Smarcel { 457130803Smarcel if (l > len || matches[l] == 0) 458130803Smarcel break; 459130803Smarcel else 460130803Smarcel { 461130803Smarcel temp = printable_part (matches[l]); 462130803Smarcel printed_len = print_filename (temp, matches[l]); 463130803Smarcel 464130803Smarcel if (j + 1 < limit) 465130803Smarcel for (k = 0; k < max - printed_len; k++) 466130803Smarcel tui_putc (' '); 467130803Smarcel } 468130803Smarcel l += count; 469130803Smarcel } 470130803Smarcel tui_putc ('\n'); 471130803Smarcel } 472130803Smarcel } 473130803Smarcel else 474130803Smarcel { 475130803Smarcel /* Print the sorted items, across alphabetically, like ls -x. */ 476130803Smarcel for (i = 1; matches[i]; i++) 477130803Smarcel { 478130803Smarcel temp = printable_part (matches[i]); 479130803Smarcel printed_len = print_filename (temp, matches[i]); 480130803Smarcel /* Have we reached the end of this line? */ 481130803Smarcel if (matches[i+1]) 482130803Smarcel { 483130803Smarcel if (i && (limit > 1) && (i % limit) == 0) 484130803Smarcel tui_putc ('\n'); 485130803Smarcel else 486130803Smarcel for (k = 0; k < max - printed_len; k++) 487130803Smarcel tui_putc (' '); 488130803Smarcel } 489130803Smarcel } 490130803Smarcel tui_putc ('\n'); 491130803Smarcel } 492130803Smarcel} 493130803Smarcel 494130803Smarcel/* Setup the IO for curses or non-curses mode. 495130803Smarcel - In non-curses mode, readline and gdb use the standard input and 496130803Smarcel standard output/error directly. 497130803Smarcel - In curses mode, the standard output/error is controlled by TUI 498130803Smarcel with the tui_stdout and tui_stderr. The output is redirected in 499130803Smarcel the curses command window. Several readline callbacks are installed 500130803Smarcel so that readline asks for its input to the curses command window 501130803Smarcel with wgetch(). */ 502130803Smarcelvoid 503130803Smarceltui_setup_io (int mode) 504130803Smarcel{ 505130803Smarcel extern int readline_echoing_p; 506130803Smarcel 507130803Smarcel if (mode) 508130803Smarcel { 509130803Smarcel /* Redirect readline to TUI. */ 510130803Smarcel tui_old_rl_redisplay_function = rl_redisplay_function; 511130803Smarcel tui_old_rl_deprep_terminal = rl_deprep_term_function; 512130803Smarcel tui_old_rl_prep_terminal = rl_prep_term_function; 513130803Smarcel tui_old_rl_getc_function = rl_getc_function; 514130803Smarcel tui_old_rl_outstream = rl_outstream; 515130803Smarcel tui_old_readline_echoing_p = readline_echoing_p; 516130803Smarcel rl_redisplay_function = tui_redisplay_readline; 517130803Smarcel rl_deprep_term_function = tui_deprep_terminal; 518130803Smarcel rl_prep_term_function = tui_prep_terminal; 519130803Smarcel rl_getc_function = tui_getc; 520130803Smarcel readline_echoing_p = 0; 521130803Smarcel rl_outstream = tui_rl_outstream; 522130803Smarcel rl_prompt = 0; 523130803Smarcel rl_completion_display_matches_hook = tui_rl_display_match_list; 524130803Smarcel rl_already_prompted = 0; 525130803Smarcel 526130803Smarcel /* Keep track of previous gdb output. */ 527130803Smarcel tui_old_stdout = gdb_stdout; 528130803Smarcel tui_old_stderr = gdb_stderr; 529130803Smarcel tui_old_uiout = uiout; 530130803Smarcel 531130803Smarcel /* Reconfigure gdb output. */ 532130803Smarcel gdb_stdout = tui_stdout; 533130803Smarcel gdb_stderr = tui_stderr; 534130803Smarcel gdb_stdlog = gdb_stdout; /* for moment */ 535130803Smarcel gdb_stdtarg = gdb_stderr; /* for moment */ 536130803Smarcel uiout = tui_out; 537130803Smarcel 538130803Smarcel /* Save tty for SIGCONT. */ 539130803Smarcel savetty (); 540130803Smarcel } 541130803Smarcel else 542130803Smarcel { 543130803Smarcel /* Restore gdb output. */ 544130803Smarcel gdb_stdout = tui_old_stdout; 545130803Smarcel gdb_stderr = tui_old_stderr; 546130803Smarcel gdb_stdlog = gdb_stdout; /* for moment */ 547130803Smarcel gdb_stdtarg = gdb_stderr; /* for moment */ 548130803Smarcel uiout = tui_old_uiout; 549130803Smarcel 550130803Smarcel /* Restore readline. */ 551130803Smarcel rl_redisplay_function = tui_old_rl_redisplay_function; 552130803Smarcel rl_deprep_term_function = tui_old_rl_deprep_terminal; 553130803Smarcel rl_prep_term_function = tui_old_rl_prep_terminal; 554130803Smarcel rl_getc_function = tui_old_rl_getc_function; 555130803Smarcel rl_outstream = tui_old_rl_outstream; 556130803Smarcel rl_completion_display_matches_hook = 0; 557130803Smarcel readline_echoing_p = tui_old_readline_echoing_p; 558130803Smarcel rl_already_prompted = 0; 559130803Smarcel 560130803Smarcel /* Save tty for SIGCONT. */ 561130803Smarcel savetty (); 562130803Smarcel } 563130803Smarcel} 564130803Smarcel 565130803Smarcel#ifdef SIGCONT 566130803Smarcel/* Catch SIGCONT to restore the terminal and refresh the screen. */ 567130803Smarcelstatic void 568130803Smarceltui_cont_sig (int sig) 569130803Smarcel{ 570130803Smarcel if (tui_active) 571130803Smarcel { 572130803Smarcel /* Restore the terminal setting because another process (shell) 573130803Smarcel might have changed it. */ 574130803Smarcel resetty (); 575130803Smarcel 576130803Smarcel /* Force a refresh of the screen. */ 577130803Smarcel tui_refresh_all_win (); 578130803Smarcel 579130803Smarcel /* Update cursor position on the screen. */ 580130803Smarcel wmove (TUI_CMD_WIN->generic.handle, 581130803Smarcel TUI_CMD_WIN->detail.command_info.start_line, 582130803Smarcel TUI_CMD_WIN->detail.command_info.curch); 583130803Smarcel wrefresh (TUI_CMD_WIN->generic.handle); 584130803Smarcel } 585130803Smarcel signal (sig, tui_cont_sig); 586130803Smarcel} 587130803Smarcel#endif 588130803Smarcel 589130803Smarcel/* Initialize the IO for gdb in curses mode. */ 590130803Smarcelvoid 591130803Smarceltui_initialize_io (void) 592130803Smarcel{ 593130803Smarcel#ifdef SIGCONT 594130803Smarcel signal (SIGCONT, tui_cont_sig); 595130803Smarcel#endif 596130803Smarcel 597130803Smarcel /* Create tui output streams. */ 598130803Smarcel tui_stdout = tui_fileopen (stdout); 599130803Smarcel tui_stderr = tui_fileopen (stderr); 600130803Smarcel tui_out = tui_out_new (tui_stdout); 601130803Smarcel 602130803Smarcel /* Create the default UI. It is not created because we installed 603130803Smarcel a init_ui_hook. */ 604130803Smarcel tui_old_uiout = uiout = cli_out_new (gdb_stdout); 605130803Smarcel 606130803Smarcel#ifdef TUI_USE_PIPE_FOR_READLINE 607130803Smarcel /* Temporary solution for readline writing to stdout: 608130803Smarcel redirect readline output in a pipe, read that pipe and 609130803Smarcel output the content in the curses command window. */ 610130803Smarcel if (pipe (tui_readline_pipe) != 0) 611130803Smarcel { 612130803Smarcel fprintf_unfiltered (gdb_stderr, "Cannot create pipe for readline"); 613130803Smarcel exit (1); 614130803Smarcel } 615130803Smarcel tui_rl_outstream = fdopen (tui_readline_pipe[1], "w"); 616130803Smarcel if (tui_rl_outstream == 0) 617130803Smarcel { 618130803Smarcel fprintf_unfiltered (gdb_stderr, "Cannot redirect readline output"); 619130803Smarcel exit (1); 620130803Smarcel } 621130803Smarcel setvbuf (tui_rl_outstream, (char*) NULL, _IOLBF, 0); 622130803Smarcel 623130803Smarcel#ifdef O_NONBLOCK 624130803Smarcel (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NONBLOCK); 625130803Smarcel#else 626130803Smarcel#ifdef O_NDELAY 627130803Smarcel (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NDELAY); 628130803Smarcel#endif 629130803Smarcel#endif 630130803Smarcel add_file_handler (tui_readline_pipe[0], tui_readline_output, 0); 631130803Smarcel#else 632130803Smarcel tui_rl_outstream = stdout; 633130803Smarcel#endif 634130803Smarcel} 635130803Smarcel 636130803Smarcel/* Get a character from the command window. This is called from the readline 637130803Smarcel package. */ 638130803Smarcelint 639130803Smarceltui_getc (FILE *fp) 640130803Smarcel{ 641130803Smarcel int ch; 642130803Smarcel WINDOW *w; 643130803Smarcel 644130803Smarcel w = TUI_CMD_WIN->generic.handle; 645130803Smarcel 646130803Smarcel#ifdef TUI_USE_PIPE_FOR_READLINE 647130803Smarcel /* Flush readline output. */ 648130803Smarcel tui_readline_output (GDB_READABLE, 0); 649130803Smarcel#endif 650130803Smarcel 651130803Smarcel ch = wgetch (w); 652130803Smarcel ch = tui_handle_resize_during_io (ch); 653130803Smarcel 654130803Smarcel /* The \n must be echoed because it will not be printed by readline. */ 655130803Smarcel if (ch == '\n') 656130803Smarcel { 657130803Smarcel /* When hitting return with an empty input, gdb executes the last 658130803Smarcel command. If we emit a newline, this fills up the command window 659130803Smarcel with empty lines with gdb prompt at beginning. Instead of that, 660130803Smarcel stay on the same line but provide a visual effect to show the 661130803Smarcel user we recognized the command. */ 662130803Smarcel if (rl_end == 0) 663130803Smarcel { 664130803Smarcel wmove (w, TUI_CMD_WIN->detail.command_info.cur_line, 0); 665130803Smarcel 666130803Smarcel /* Clear the line. This will blink the gdb prompt since 667130803Smarcel it will be redrawn at the same line. */ 668130803Smarcel wclrtoeol (w); 669130803Smarcel wrefresh (w); 670130803Smarcel napms (20); 671130803Smarcel } 672130803Smarcel else 673130803Smarcel { 674130803Smarcel wmove (w, TUI_CMD_WIN->detail.command_info.cur_line, 675130803Smarcel TUI_CMD_WIN->detail.command_info.curch); 676130803Smarcel waddch (w, ch); 677130803Smarcel } 678130803Smarcel } 679130803Smarcel 680130803Smarcel if (key_is_command_char (ch)) 681130803Smarcel { /* Handle prev/next/up/down here */ 682130803Smarcel ch = tui_dispatch_ctrl_char (ch); 683130803Smarcel } 684130803Smarcel 685130803Smarcel if (ch == '\n' || ch == '\r' || ch == '\f') 686130803Smarcel TUI_CMD_WIN->detail.command_info.curch = 0; 687130803Smarcel if (ch == KEY_BACKSPACE) 688130803Smarcel return '\b'; 689130803Smarcel 690130803Smarcel return ch; 691130803Smarcel} 692130803Smarcel 693130803Smarcel 694130803Smarcel/* Cleanup when a resize has occured. 695130803Smarcel Returns the character that must be processed. */ 696130803Smarcelstatic unsigned int 697130803Smarceltui_handle_resize_during_io (unsigned int original_ch) 698130803Smarcel{ 699130803Smarcel if (tui_win_resized ()) 700130803Smarcel { 701130803Smarcel tui_refresh_all_win (); 702130803Smarcel dont_repeat (); 703130803Smarcel tui_set_win_resized_to (FALSE); 704130803Smarcel return '\n'; 705130803Smarcel } 706130803Smarcel else 707130803Smarcel return original_ch; 708130803Smarcel} 709