1 /* TUI support I/O functions. 2 3 Copyright (C) 1998-2020 Free Software Foundation, Inc. 4 5 Contributed by Hewlett-Packard Company. 6 7 This file is part of GDB. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 22 #include "defs.h" 23 #include "target.h" 24 #include "gdbsupport/event-loop.h" 25 #include "event-top.h" 26 #include "command.h" 27 #include "top.h" 28 #include "tui/tui.h" 29 #include "tui/tui-data.h" 30 #include "tui/tui-io.h" 31 #include "tui/tui-command.h" 32 #include "tui/tui-win.h" 33 #include "tui/tui-wingeneral.h" 34 #include "tui/tui-file.h" 35 #include "tui/tui-out.h" 36 #include "ui-out.h" 37 #include "cli-out.h" 38 #include <fcntl.h> 39 #include <signal.h> 40 #ifdef __MINGW32__ 41 #include <windows.h> 42 #endif 43 #include "gdbsupport/filestuff.h" 44 #include "completer.h" 45 #include "gdb_curses.h" 46 #include <map> 47 48 /* This redefines CTRL if it is not already defined, so it must come 49 after terminal state releated include files like <term.h> and 50 "gdb_curses.h". */ 51 #include "readline/readline.h" 52 53 #ifdef __MINGW32__ 54 static SHORT ncurses_norm_attr; 55 #endif 56 57 static int tui_getc (FILE *fp); 58 59 static int 60 key_is_start_sequence (int ch) 61 { 62 return (ch == 27); 63 } 64 65 /* Use definition from readline 4.3. */ 66 #undef CTRL_CHAR 67 #define CTRL_CHAR(c) \ 68 ((c) < control_character_threshold && (((c) & 0x80) == 0)) 69 70 /* This file controls the IO interactions between gdb and curses. 71 When the TUI is enabled, gdb has two modes a curses and a standard 72 mode. 73 74 In curses mode, the gdb outputs are made in a curses command 75 window. For this, the gdb_stdout and gdb_stderr are redirected to 76 the specific ui_file implemented by TUI. The output is handled by 77 tui_puts(). The input is also controlled by curses with 78 tui_getc(). The readline library uses this function to get its 79 input. Several readline hooks are installed to redirect readline 80 output to the TUI (see also the note below). 81 82 In normal mode, the gdb outputs are restored to their origin, that 83 is as if TUI is not used. Readline also uses its original getc() 84 function with stdin. 85 86 Note SCz/2001-07-21: the current readline is not clean in its 87 management of the output. Even if we install a redisplay handler, 88 it sometimes writes on a stdout file. It is important to redirect 89 every output produced by readline, otherwise the curses window will 90 be garbled. This is implemented with a pipe that TUI reads and 91 readline writes to. A gdb input handler is created so that reading 92 the pipe is handled automatically. This will probably not work on 93 non-Unix platforms. The best fix is to make readline clean enough 94 so that is never write on stdout. 95 96 Note SCz/2002-09-01: we now use more readline hooks and it seems 97 that with them we don't need the pipe anymore (verified by creating 98 the pipe and closing its end so that write causes a SIGPIPE). The 99 old pipe code is still there and can be conditionally removed by 100 #undef TUI_USE_PIPE_FOR_READLINE. */ 101 102 /* For gdb 5.3, prefer to continue the pipe hack as a backup wheel. */ 103 #ifdef HAVE_PIPE 104 #define TUI_USE_PIPE_FOR_READLINE 105 #endif 106 /* #undef TUI_USE_PIPE_FOR_READLINE */ 107 108 /* TUI output files. */ 109 static struct ui_file *tui_stdout; 110 static struct ui_file *tui_stderr; 111 struct ui_out *tui_out; 112 113 /* GDB output files in non-curses mode. */ 114 static struct ui_file *tui_old_stdout; 115 static struct ui_file *tui_old_stderr; 116 cli_ui_out *tui_old_uiout; 117 118 /* Readline previous hooks. */ 119 static rl_getc_func_t *tui_old_rl_getc_function; 120 static rl_voidfunc_t *tui_old_rl_redisplay_function; 121 static rl_vintfunc_t *tui_old_rl_prep_terminal; 122 static rl_voidfunc_t *tui_old_rl_deprep_terminal; 123 static rl_compdisp_func_t *tui_old_rl_display_matches_hook; 124 static int tui_old_rl_echoing_p; 125 126 /* Readline output stream. 127 Should be removed when readline is clean. */ 128 static FILE *tui_rl_outstream; 129 static FILE *tui_old_rl_outstream; 130 #ifdef TUI_USE_PIPE_FOR_READLINE 131 static int tui_readline_pipe[2]; 132 #endif 133 134 /* Print a character in the curses command window. The output is 135 buffered. It is up to the caller to refresh the screen if 136 necessary. */ 137 138 static void 139 do_tui_putc (WINDOW *w, char c) 140 { 141 /* Expand TABs, since ncurses on MS-Windows doesn't. */ 142 if (c == '\t') 143 { 144 int col; 145 146 col = getcurx (w); 147 do 148 { 149 waddch (w, ' '); 150 col++; 151 } 152 while ((col % 8) != 0); 153 } 154 else 155 waddch (w, c); 156 } 157 158 /* Update the cached value of the command window's start line based on 159 the window's current Y coordinate. */ 160 161 static void 162 update_cmdwin_start_line () 163 { 164 TUI_CMD_WIN->start_line = getcury (TUI_CMD_WIN->handle.get ()); 165 } 166 167 /* Print a character in the curses command window. The output is 168 buffered. It is up to the caller to refresh the screen if 169 necessary. */ 170 171 static void 172 tui_putc (char c) 173 { 174 do_tui_putc (TUI_CMD_WIN->handle.get (), c); 175 update_cmdwin_start_line (); 176 } 177 178 /* This maps colors to their corresponding color index. */ 179 180 static std::map<ui_file_style::color, int> color_map; 181 182 /* This holds a pair of colors and is used to track the mapping 183 between a color pair index and the actual colors. */ 184 185 struct color_pair 186 { 187 int fg; 188 int bg; 189 190 bool operator< (const color_pair &o) const 191 { 192 return fg < o.fg || (fg == o.fg && bg < o.bg); 193 } 194 }; 195 196 /* This maps pairs of colors to their corresponding color pair 197 index. */ 198 199 static std::map<color_pair, int> color_pair_map; 200 201 /* This is indexed by ANSI color offset from the base color, and holds 202 the corresponding curses color constant. */ 203 204 static const int curses_colors[] = { 205 COLOR_BLACK, 206 COLOR_RED, 207 COLOR_GREEN, 208 COLOR_YELLOW, 209 COLOR_BLUE, 210 COLOR_MAGENTA, 211 COLOR_CYAN, 212 COLOR_WHITE 213 }; 214 215 /* Given a color, find its index. */ 216 217 static bool 218 get_color (const ui_file_style::color &color, int *result) 219 { 220 if (color.is_none ()) 221 *result = -1; 222 else if (color.is_basic ()) 223 *result = curses_colors[color.get_value ()]; 224 else 225 { 226 auto it = color_map.find (color); 227 if (it == color_map.end ()) 228 { 229 /* The first 8 colors are standard. */ 230 int next = color_map.size () + 8; 231 if (next >= COLORS) 232 return false; 233 uint8_t rgb[3]; 234 color.get_rgb (rgb); 235 /* We store RGB as 0..255, but curses wants 0..1000. */ 236 if (init_color (next, rgb[0] * 1000 / 255, rgb[1] * 1000 / 255, 237 rgb[2] * 1000 / 255) == ERR) 238 return false; 239 color_map[color] = next; 240 *result = next; 241 } 242 else 243 *result = it->second; 244 } 245 return true; 246 } 247 248 /* The most recently emitted color pair. */ 249 250 static int last_color_pair = -1; 251 252 /* The most recently applied style. */ 253 254 static ui_file_style last_style; 255 256 /* If true, we're highlighting the current source line in reverse 257 video mode. */ 258 static bool reverse_mode_p = false; 259 260 /* The background/foreground colors before we entered reverse 261 mode. */ 262 static ui_file_style::color reverse_save_bg (ui_file_style::NONE); 263 static ui_file_style::color reverse_save_fg (ui_file_style::NONE); 264 265 /* Given two colors, return their color pair index; making a new one 266 if necessary. */ 267 268 static int 269 get_color_pair (int fg, int bg) 270 { 271 color_pair c = { fg, bg }; 272 auto it = color_pair_map.find (c); 273 if (it == color_pair_map.end ()) 274 { 275 /* Color pair 0 is our default color, so new colors start at 276 1. */ 277 int next = color_pair_map.size () + 1; 278 /* Curses has a limited number of available color pairs. Fall 279 back to the default if we've used too many. */ 280 if (next >= COLOR_PAIRS) 281 return 0; 282 init_pair (next, fg, bg); 283 color_pair_map[c] = next; 284 return next; 285 } 286 return it->second; 287 } 288 289 /* Apply STYLE to W. */ 290 291 void 292 tui_apply_style (WINDOW *w, ui_file_style style) 293 { 294 /* Reset. */ 295 wattron (w, A_NORMAL); 296 wattroff (w, A_BOLD); 297 wattroff (w, A_DIM); 298 wattroff (w, A_REVERSE); 299 if (last_color_pair != -1) 300 wattroff (w, COLOR_PAIR (last_color_pair)); 301 wattron (w, COLOR_PAIR (0)); 302 303 const ui_file_style::color &fg = style.get_foreground (); 304 const ui_file_style::color &bg = style.get_background (); 305 if (!fg.is_none () || !bg.is_none ()) 306 { 307 int fgi, bgi; 308 if (get_color (fg, &fgi) && get_color (bg, &bgi)) 309 { 310 #ifdef __MINGW32__ 311 /* MS-Windows port of ncurses doesn't support implicit 312 default foreground and background colors, so we must 313 specify them explicitly when needed, using the colors we 314 saw at startup. */ 315 if (fgi == -1) 316 fgi = ncurses_norm_attr & 15; 317 if (bgi == -1) 318 bgi = (ncurses_norm_attr >> 4) & 15; 319 #endif 320 int pair = get_color_pair (fgi, bgi); 321 if (last_color_pair != -1) 322 wattroff (w, COLOR_PAIR (last_color_pair)); 323 wattron (w, COLOR_PAIR (pair)); 324 last_color_pair = pair; 325 } 326 } 327 328 switch (style.get_intensity ()) 329 { 330 case ui_file_style::NORMAL: 331 break; 332 333 case ui_file_style::BOLD: 334 wattron (w, A_BOLD); 335 break; 336 337 case ui_file_style::DIM: 338 wattron (w, A_DIM); 339 break; 340 341 default: 342 gdb_assert_not_reached ("invalid intensity"); 343 } 344 345 if (style.is_reverse ()) 346 wattron (w, A_REVERSE); 347 348 last_style = style; 349 } 350 351 /* Apply an ANSI escape sequence from BUF to W. BUF must start with 352 the ESC character. If BUF does not start with an ANSI escape, 353 return 0. Otherwise, apply the sequence if it is recognized, or 354 simply ignore it if not. In this case, the number of bytes read 355 from BUF is returned. */ 356 357 static size_t 358 apply_ansi_escape (WINDOW *w, const char *buf) 359 { 360 ui_file_style style = last_style; 361 size_t n_read; 362 363 if (!style.parse (buf, &n_read)) 364 return n_read; 365 366 if (reverse_mode_p) 367 { 368 /* We want to reverse _only_ the default foreground/background 369 colors. If the foreground color is not the default (because 370 the text was styled), we want to leave it as is. If e.g., 371 the terminal is fg=BLACK, and bg=WHITE, and the style wants 372 to print text in RED, we want to reverse the background color 373 (print in BLACK), but still print the text in RED. To do 374 that, we enable the A_REVERSE attribute, and re-reverse the 375 parsed-style's fb/bg colors. 376 377 Notes on the approach: 378 379 - there's no portable way to know which colors the default 380 fb/bg colors map to. 381 382 - this approach does the right thing even if you change the 383 terminal colors while GDB is running -- the reversed 384 colors automatically adapt. 385 */ 386 if (!style.is_default ()) 387 { 388 ui_file_style::color bg = style.get_background (); 389 ui_file_style::color fg = style.get_foreground (); 390 style.set_fg (bg); 391 style.set_bg (fg); 392 } 393 394 /* Enable A_REVERSE. */ 395 style.set_reverse (true); 396 } 397 398 tui_apply_style (w, style); 399 return n_read; 400 } 401 402 /* See tui.io.h. */ 403 404 void 405 tui_set_reverse_mode (WINDOW *w, bool reverse) 406 { 407 ui_file_style style = last_style; 408 409 reverse_mode_p = reverse; 410 style.set_reverse (reverse); 411 412 if (reverse) 413 { 414 reverse_save_bg = style.get_background (); 415 reverse_save_fg = style.get_foreground (); 416 } 417 else 418 { 419 style.set_bg (reverse_save_bg); 420 style.set_fg (reverse_save_fg); 421 } 422 423 tui_apply_style (w, style); 424 } 425 426 /* Print LENGTH characters from the buffer pointed to by BUF to the 427 curses command window. The output is buffered. It is up to the 428 caller to refresh the screen if necessary. */ 429 430 void 431 tui_write (const char *buf, size_t length) 432 { 433 /* We need this to be \0-terminated for the regexp matching. */ 434 std::string copy (buf, length); 435 tui_puts (copy.c_str ()); 436 } 437 438 static void 439 tui_puts_internal (WINDOW *w, const char *string, int *height) 440 { 441 char c; 442 int prev_col = 0; 443 bool saw_nl = false; 444 445 while ((c = *string++) != 0) 446 { 447 if (c == '\n') 448 saw_nl = true; 449 450 if (c == '\1' || c == '\2') 451 { 452 /* Ignore these, they are readline escape-marking 453 sequences. */ 454 } 455 else 456 { 457 if (c == '\033') 458 { 459 size_t bytes_read = apply_ansi_escape (w, string - 1); 460 if (bytes_read > 0) 461 { 462 string = string + bytes_read - 1; 463 continue; 464 } 465 } 466 do_tui_putc (w, c); 467 468 if (height != nullptr) 469 { 470 int col = getcurx (w); 471 if (col <= prev_col) 472 ++*height; 473 prev_col = col; 474 } 475 } 476 } 477 if (TUI_CMD_WIN != nullptr && w == TUI_CMD_WIN->handle.get ()) 478 update_cmdwin_start_line (); 479 if (saw_nl) 480 wrefresh (w); 481 } 482 483 /* Print a string in the curses command window. The output is 484 buffered. It is up to the caller to refresh the screen if 485 necessary. */ 486 487 void 488 tui_puts (const char *string, WINDOW *w) 489 { 490 if (w == nullptr) 491 w = TUI_CMD_WIN->handle.get (); 492 tui_puts_internal (w, string, nullptr); 493 } 494 495 /* Readline callback. 496 Redisplay the command line with its prompt after readline has 497 changed the edited text. */ 498 void 499 tui_redisplay_readline (void) 500 { 501 int prev_col; 502 int height; 503 int col; 504 int c_pos; 505 int c_line; 506 int in; 507 WINDOW *w; 508 const char *prompt; 509 int start_line; 510 511 /* Detect when we temporarily left SingleKey and now the readline 512 edit buffer is empty, automatically restore the SingleKey 513 mode. The restore must only be done if the command has finished. 514 The command could call prompt_for_continue and we must not 515 restore SingleKey so that the prompt and normal keymap are used. */ 516 if (tui_current_key_mode == TUI_ONE_COMMAND_MODE && rl_end == 0 517 && !gdb_in_secondary_prompt_p (current_ui)) 518 tui_set_key_mode (TUI_SINGLE_KEY_MODE); 519 520 if (tui_current_key_mode == TUI_SINGLE_KEY_MODE) 521 prompt = ""; 522 else 523 prompt = rl_display_prompt; 524 525 c_pos = -1; 526 c_line = -1; 527 w = TUI_CMD_WIN->handle.get (); 528 start_line = TUI_CMD_WIN->start_line; 529 wmove (w, start_line, 0); 530 prev_col = 0; 531 height = 1; 532 if (prompt != nullptr) 533 tui_puts_internal (w, prompt, &height); 534 535 prev_col = getcurx (w); 536 for (in = 0; in <= rl_end; in++) 537 { 538 unsigned char c; 539 540 if (in == rl_point) 541 { 542 getyx (w, c_line, c_pos); 543 } 544 545 if (in == rl_end) 546 break; 547 548 c = (unsigned char) rl_line_buffer[in]; 549 if (CTRL_CHAR (c) || c == RUBOUT) 550 { 551 waddch (w, '^'); 552 waddch (w, CTRL_CHAR (c) ? UNCTRL (c) : '?'); 553 } 554 else if (c == '\t') 555 { 556 /* Expand TABs, since ncurses on MS-Windows doesn't. */ 557 col = getcurx (w); 558 do 559 { 560 waddch (w, ' '); 561 col++; 562 } while ((col % 8) != 0); 563 } 564 else 565 { 566 waddch (w, c); 567 } 568 if (c == '\n') 569 TUI_CMD_WIN->start_line = getcury (w); 570 col = getcurx (w); 571 if (col < prev_col) 572 height++; 573 prev_col = col; 574 } 575 wclrtobot (w); 576 TUI_CMD_WIN->start_line = getcury (w); 577 if (c_line >= 0) 578 wmove (w, c_line, c_pos); 579 TUI_CMD_WIN->start_line -= height - 1; 580 581 wrefresh (w); 582 fflush(stdout); 583 } 584 585 /* Readline callback to prepare the terminal. It is called once each 586 time we enter readline. Terminal is already setup in curses 587 mode. */ 588 static void 589 tui_prep_terminal (int notused1) 590 { 591 } 592 593 /* Readline callback to restore the terminal. It is called once each 594 time we leave readline. There is nothing to do in curses mode. */ 595 static void 596 tui_deprep_terminal (void) 597 { 598 } 599 600 #ifdef TUI_USE_PIPE_FOR_READLINE 601 /* Read readline output pipe and feed the command window with it. 602 Should be removed when readline is clean. */ 603 static void 604 tui_readline_output (int error, gdb_client_data data) 605 { 606 int size; 607 char buf[256]; 608 609 size = read (tui_readline_pipe[0], buf, sizeof (buf) - 1); 610 if (size > 0 && tui_active) 611 { 612 buf[size] = 0; 613 tui_puts (buf); 614 } 615 } 616 #endif 617 618 /* TUI version of displayer.crlf. */ 619 620 static void 621 tui_mld_crlf (const struct match_list_displayer *displayer) 622 { 623 tui_putc ('\n'); 624 } 625 626 /* TUI version of displayer.putch. */ 627 628 static void 629 tui_mld_putch (const struct match_list_displayer *displayer, int ch) 630 { 631 tui_putc (ch); 632 } 633 634 /* TUI version of displayer.puts. */ 635 636 static void 637 tui_mld_puts (const struct match_list_displayer *displayer, const char *s) 638 { 639 tui_puts (s); 640 } 641 642 /* TUI version of displayer.flush. */ 643 644 static void 645 tui_mld_flush (const struct match_list_displayer *displayer) 646 { 647 wrefresh (TUI_CMD_WIN->handle.get ()); 648 } 649 650 /* TUI version of displayer.erase_entire_line. */ 651 652 static void 653 tui_mld_erase_entire_line (const struct match_list_displayer *displayer) 654 { 655 WINDOW *w = TUI_CMD_WIN->handle.get (); 656 int cur_y = getcury (w); 657 658 wmove (w, cur_y, 0); 659 wclrtoeol (w); 660 wmove (w, cur_y, 0); 661 } 662 663 /* TUI version of displayer.beep. */ 664 665 static void 666 tui_mld_beep (const struct match_list_displayer *displayer) 667 { 668 beep (); 669 } 670 671 /* A wrapper for wgetch that enters nonl mode. We We normally want 672 curses' "nl" mode, but when reading from the user, we'd like to 673 differentiate between C-j and C-m, because some users bind these 674 keys differently in their .inputrc. So, put curses into nonl mode 675 just when reading from the user. See PR tui/20819. */ 676 677 static int 678 gdb_wgetch (WINDOW *win) 679 { 680 nonl (); 681 int r = wgetch (win); 682 nl (); 683 return r; 684 } 685 686 /* Helper function for tui_mld_read_key. 687 This temporarily replaces tui_getc for use during tab-completion 688 match list display. */ 689 690 static int 691 tui_mld_getc (FILE *fp) 692 { 693 WINDOW *w = TUI_CMD_WIN->handle.get (); 694 int c = gdb_wgetch (w); 695 696 return c; 697 } 698 699 /* TUI version of displayer.read_key. */ 700 701 static int 702 tui_mld_read_key (const struct match_list_displayer *displayer) 703 { 704 rl_getc_func_t *prev = rl_getc_function; 705 int c; 706 707 /* We can't use tui_getc as we need NEWLINE to not get emitted. */ 708 rl_getc_function = tui_mld_getc; 709 c = rl_read_key (); 710 rl_getc_function = prev; 711 return c; 712 } 713 714 /* TUI version of rl_completion_display_matches_hook. 715 See gdb_display_match_list for a description of the arguments. */ 716 717 static void 718 tui_rl_display_match_list (char **matches, int len, int max) 719 { 720 struct match_list_displayer displayer; 721 722 rl_get_screen_size (&displayer.height, &displayer.width); 723 displayer.crlf = tui_mld_crlf; 724 displayer.putch = tui_mld_putch; 725 displayer.puts = tui_mld_puts; 726 displayer.flush = tui_mld_flush; 727 displayer.erase_entire_line = tui_mld_erase_entire_line; 728 displayer.beep = tui_mld_beep; 729 displayer.read_key = tui_mld_read_key; 730 731 gdb_display_match_list (matches, len, max, &displayer); 732 } 733 734 /* Setup the IO for curses or non-curses mode. 735 - In non-curses mode, readline and gdb use the standard input and 736 standard output/error directly. 737 - In curses mode, the standard output/error is controlled by TUI 738 with the tui_stdout and tui_stderr. The output is redirected in 739 the curses command window. Several readline callbacks are installed 740 so that readline asks for its input to the curses command window 741 with wgetch(). */ 742 void 743 tui_setup_io (int mode) 744 { 745 extern int _rl_echoing_p; 746 747 if (mode) 748 { 749 /* Ensure that readline has been initialized before saving any 750 of its variables. */ 751 tui_ensure_readline_initialized (); 752 753 /* Redirect readline to TUI. */ 754 tui_old_rl_redisplay_function = rl_redisplay_function; 755 tui_old_rl_deprep_terminal = rl_deprep_term_function; 756 tui_old_rl_prep_terminal = rl_prep_term_function; 757 tui_old_rl_getc_function = rl_getc_function; 758 tui_old_rl_display_matches_hook = rl_completion_display_matches_hook; 759 tui_old_rl_outstream = rl_outstream; 760 tui_old_rl_echoing_p = _rl_echoing_p; 761 rl_redisplay_function = tui_redisplay_readline; 762 rl_deprep_term_function = tui_deprep_terminal; 763 rl_prep_term_function = tui_prep_terminal; 764 rl_getc_function = tui_getc; 765 _rl_echoing_p = 0; 766 rl_outstream = tui_rl_outstream; 767 rl_prompt = 0; 768 rl_completion_display_matches_hook = tui_rl_display_match_list; 769 rl_already_prompted = 0; 770 771 /* Keep track of previous gdb output. */ 772 tui_old_stdout = gdb_stdout; 773 tui_old_stderr = gdb_stderr; 774 tui_old_uiout = dynamic_cast<cli_ui_out *> (current_uiout); 775 gdb_assert (tui_old_uiout != nullptr); 776 777 /* Reconfigure gdb output. */ 778 gdb_stdout = tui_stdout; 779 gdb_stderr = tui_stderr; 780 gdb_stdlog = gdb_stdout; /* for moment */ 781 gdb_stdtarg = gdb_stderr; /* for moment */ 782 gdb_stdtargerr = gdb_stderr; /* for moment */ 783 current_uiout = tui_out; 784 785 /* Save tty for SIGCONT. */ 786 savetty (); 787 } 788 else 789 { 790 /* Restore gdb output. */ 791 gdb_stdout = tui_old_stdout; 792 gdb_stderr = tui_old_stderr; 793 gdb_stdlog = gdb_stdout; /* for moment */ 794 gdb_stdtarg = gdb_stderr; /* for moment */ 795 gdb_stdtargerr = gdb_stderr; /* for moment */ 796 current_uiout = tui_old_uiout; 797 798 /* Restore readline. */ 799 rl_redisplay_function = tui_old_rl_redisplay_function; 800 rl_deprep_term_function = tui_old_rl_deprep_terminal; 801 rl_prep_term_function = tui_old_rl_prep_terminal; 802 rl_getc_function = tui_old_rl_getc_function; 803 rl_completion_display_matches_hook = tui_old_rl_display_matches_hook; 804 rl_outstream = tui_old_rl_outstream; 805 _rl_echoing_p = tui_old_rl_echoing_p; 806 rl_already_prompted = 0; 807 808 /* Save tty for SIGCONT. */ 809 savetty (); 810 811 /* Clean up color information. */ 812 last_color_pair = -1; 813 last_style = ui_file_style (); 814 color_map.clear (); 815 color_pair_map.clear (); 816 } 817 } 818 819 #ifdef SIGCONT 820 /* Catch SIGCONT to restore the terminal and refresh the screen. */ 821 static void 822 tui_cont_sig (int sig) 823 { 824 if (tui_active) 825 { 826 /* Restore the terminal setting because another process (shell) 827 might have changed it. */ 828 resetty (); 829 830 /* Force a refresh of the screen. */ 831 tui_refresh_all_win (); 832 } 833 signal (sig, tui_cont_sig); 834 } 835 #endif 836 837 /* Initialize the IO for gdb in curses mode. */ 838 void 839 tui_initialize_io (void) 840 { 841 #ifdef SIGCONT 842 signal (SIGCONT, tui_cont_sig); 843 #endif 844 845 /* Create tui output streams. */ 846 tui_stdout = new tui_file (stdout); 847 tui_stderr = new tui_file (stderr); 848 tui_out = tui_out_new (tui_stdout); 849 850 /* Create the default UI. */ 851 tui_old_uiout = cli_out_new (gdb_stdout); 852 853 #ifdef TUI_USE_PIPE_FOR_READLINE 854 /* Temporary solution for readline writing to stdout: redirect 855 readline output in a pipe, read that pipe and output the content 856 in the curses command window. */ 857 if (gdb_pipe_cloexec (tui_readline_pipe) != 0) 858 error (_("Cannot create pipe for readline")); 859 860 tui_rl_outstream = fdopen (tui_readline_pipe[1], "w"); 861 if (tui_rl_outstream == 0) 862 error (_("Cannot redirect readline output")); 863 864 setvbuf (tui_rl_outstream, NULL, _IOLBF, 0); 865 866 #ifdef O_NONBLOCK 867 (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NONBLOCK); 868 #else 869 #ifdef O_NDELAY 870 (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NDELAY); 871 #endif 872 #endif 873 add_file_handler (tui_readline_pipe[0], tui_readline_output, 0); 874 #else 875 tui_rl_outstream = stdout; 876 #endif 877 878 #ifdef __MINGW32__ 879 /* MS-Windows port of ncurses doesn't support default foreground and 880 background colors, so we must record the default colors at startup. */ 881 HANDLE hstdout = (HANDLE)_get_osfhandle (fileno (stdout)); 882 DWORD cmode; 883 CONSOLE_SCREEN_BUFFER_INFO csbi; 884 885 if (hstdout != INVALID_HANDLE_VALUE 886 && GetConsoleMode (hstdout, &cmode) != 0 887 && GetConsoleScreenBufferInfo (hstdout, &csbi)) 888 ncurses_norm_attr = csbi.wAttributes; 889 #endif 890 } 891 892 /* Dispatch the correct tui function based upon the control 893 character. */ 894 static unsigned int 895 tui_dispatch_ctrl_char (unsigned int ch) 896 { 897 struct tui_win_info *win_info = tui_win_with_focus (); 898 899 /* Handle the CTRL-L refresh for each window. */ 900 if (ch == '\f') 901 tui_refresh_all_win (); 902 903 /* If no window has the focus, or if the focus window can't scroll, 904 just pass the character through. */ 905 if (win_info == NULL || !win_info->can_scroll ()) 906 return ch; 907 908 switch (ch) 909 { 910 case KEY_NPAGE: 911 win_info->forward_scroll (0); 912 break; 913 case KEY_PPAGE: 914 win_info->backward_scroll (0); 915 break; 916 case KEY_DOWN: 917 case KEY_SF: 918 win_info->forward_scroll (1); 919 break; 920 case KEY_UP: 921 case KEY_SR: 922 win_info->backward_scroll (1); 923 break; 924 case KEY_RIGHT: 925 win_info->left_scroll (1); 926 break; 927 case KEY_LEFT: 928 win_info->right_scroll (1); 929 break; 930 case '\f': 931 break; 932 default: 933 /* We didn't recognize the character as a control character, so pass it 934 through. */ 935 return ch; 936 } 937 938 /* We intercepted the control character, so return 0 (which readline 939 will interpret as a no-op). */ 940 return 0; 941 } 942 943 /* Main worker for tui_getc. Get a character from the command window. 944 This is called from the readline package, but wrapped in a 945 try/catch by tui_getc. */ 946 947 static int 948 tui_getc_1 (FILE *fp) 949 { 950 int ch; 951 WINDOW *w; 952 953 w = TUI_CMD_WIN->handle.get (); 954 955 #ifdef TUI_USE_PIPE_FOR_READLINE 956 /* Flush readline output. */ 957 tui_readline_output (0, 0); 958 #endif 959 960 ch = gdb_wgetch (w); 961 962 /* The \n must be echoed because it will not be printed by 963 readline. */ 964 if (ch == '\n' || ch == '\r') 965 { 966 /* When hitting return with an empty input, gdb executes the last 967 command. If we emit a newline, this fills up the command window 968 with empty lines with gdb prompt at beginning. Instead of that, 969 stay on the same line but provide a visual effect to show the 970 user we recognized the command. */ 971 if (rl_end == 0 && !gdb_in_secondary_prompt_p (current_ui)) 972 { 973 wmove (w, getcury (w), 0); 974 975 /* Clear the line. This will blink the gdb prompt since 976 it will be redrawn at the same line. */ 977 wclrtoeol (w); 978 wrefresh (w); 979 napms (20); 980 } 981 else 982 { 983 /* Move cursor to the end of the command line before emitting the 984 newline. We need to do so because when ncurses outputs a newline 985 it truncates any text that appears past the end of the cursor. */ 986 int px, py; 987 getyx (w, py, px); 988 px += rl_end - rl_point; 989 py += px / TUI_CMD_WIN->width; 990 px %= TUI_CMD_WIN->width; 991 wmove (w, py, px); 992 tui_putc ('\n'); 993 } 994 } 995 996 /* Handle prev/next/up/down here. */ 997 ch = tui_dispatch_ctrl_char (ch); 998 999 if (ch == KEY_BACKSPACE) 1000 return '\b'; 1001 1002 if (current_ui->command_editing && key_is_start_sequence (ch)) 1003 { 1004 int ch_pending; 1005 1006 nodelay (w, TRUE); 1007 ch_pending = gdb_wgetch (w); 1008 nodelay (w, FALSE); 1009 1010 /* If we have pending input following a start sequence, call the stdin 1011 event handler again because ncurses may have already read and stored 1012 the input into its internal buffer, meaning that we won't get an stdin 1013 event for it. If we don't compensate for this missed stdin event, key 1014 sequences as Alt_F (^[f) will not behave promptly. 1015 1016 (We only compensates for the missed 2nd byte of a key sequence because 1017 2-byte sequences are by far the most commonly used. ncurses may have 1018 buffered a larger, 3+-byte key sequence though it remains to be seen 1019 whether it is useful to compensate for all the bytes of such 1020 sequences.) */ 1021 if (ch_pending != ERR) 1022 { 1023 ungetch (ch_pending); 1024 call_stdin_event_handler_again_p = 1; 1025 } 1026 } 1027 1028 return ch; 1029 } 1030 1031 /* Get a character from the command window. This is called from the 1032 readline package. */ 1033 1034 static int 1035 tui_getc (FILE *fp) 1036 { 1037 try 1038 { 1039 return tui_getc_1 (fp); 1040 } 1041 catch (const gdb_exception &ex) 1042 { 1043 /* Just in case, don't ever let an exception escape to readline. 1044 This shouldn't ever happen, but if it does, print the 1045 exception instead of just crashing GDB. */ 1046 exception_print (gdb_stderr, ex); 1047 1048 /* If we threw an exception, it's because we recognized the 1049 character. */ 1050 return 0; 1051 } 1052 } 1053