Home | History | Annotate | Line # | Download | only in tui
tui.c revision 1.9
      1  1.1  christos /* General functions for the WDB TUI.
      2  1.1  christos 
      3  1.9  christos    Copyright (C) 1998-2020 Free Software Foundation, Inc.
      4  1.1  christos 
      5  1.1  christos    Contributed by Hewlett-Packard Company.
      6  1.1  christos 
      7  1.1  christos    This file is part of GDB.
      8  1.1  christos 
      9  1.1  christos    This program is free software; you can redistribute it and/or modify
     10  1.1  christos    it under the terms of the GNU General Public License as published by
     11  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     12  1.1  christos    (at your option) any later version.
     13  1.1  christos 
     14  1.1  christos    This program is distributed in the hope that it will be useful,
     15  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     16  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17  1.1  christos    GNU General Public License for more details.
     18  1.1  christos 
     19  1.1  christos    You should have received a copy of the GNU General Public License
     20  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     21  1.1  christos 
     22  1.1  christos #include "defs.h"
     23  1.1  christos #include "gdbcmd.h"
     24  1.1  christos #include "tui/tui.h"
     25  1.1  christos #include "tui/tui-hooks.h"
     26  1.9  christos #include "tui/tui-command.h"
     27  1.1  christos #include "tui/tui-data.h"
     28  1.1  christos #include "tui/tui-layout.h"
     29  1.1  christos #include "tui/tui-io.h"
     30  1.1  christos #include "tui/tui-regs.h"
     31  1.1  christos #include "tui/tui-stack.h"
     32  1.1  christos #include "tui/tui-win.h"
     33  1.9  christos #include "tui/tui-wingeneral.h"
     34  1.1  christos #include "tui/tui-winsource.h"
     35  1.9  christos #include "tui/tui-source.h"
     36  1.1  christos #include "target.h"
     37  1.1  christos #include "frame.h"
     38  1.1  christos #include "breakpoint.h"
     39  1.1  christos #include "inferior.h"
     40  1.1  christos #include "symtab.h"
     41  1.1  christos #include "source.h"
     42  1.3  christos #include "terminal.h"
     43  1.6  christos #include "top.h"
     44  1.1  christos 
     45  1.1  christos #include <ctype.h>
     46  1.1  christos #include <signal.h>
     47  1.1  christos #include <fcntl.h>
     48  1.1  christos #include <setjmp.h>
     49  1.1  christos 
     50  1.1  christos #include "gdb_curses.h"
     51  1.3  christos #include "interps.h"
     52  1.1  christos 
     53  1.1  christos /* This redefines CTRL if it is not already defined, so it must come
     54  1.1  christos    after terminal state releated include files like <term.h> and
     55  1.1  christos    "gdb_curses.h".  */
     56  1.1  christos #include "readline/readline.h"
     57  1.1  christos 
     58  1.1  christos /* Tells whether the TUI is active or not.  */
     59  1.9  christos bool tui_active = false;
     60  1.9  christos static bool tui_finish_init = true;
     61  1.1  christos 
     62  1.1  christos enum tui_key_mode tui_current_key_mode = TUI_COMMAND_MODE;
     63  1.1  christos 
     64  1.1  christos struct tui_char_command
     65  1.1  christos {
     66  1.1  christos   unsigned char key;
     67  1.1  christos   const char *cmd;
     68  1.1  christos };
     69  1.1  christos 
     70  1.1  christos /* Key mapping to gdb commands when the TUI is using the single key
     71  1.1  christos    mode.  */
     72  1.1  christos static const struct tui_char_command tui_commands[] = {
     73  1.1  christos   { 'c', "continue" },
     74  1.1  christos   { 'd', "down" },
     75  1.1  christos   { 'f', "finish" },
     76  1.1  christos   { 'n', "next" },
     77  1.8  christos   { 'o', "nexti" },
     78  1.1  christos   { 'r', "run" },
     79  1.1  christos   { 's', "step" },
     80  1.8  christos   { 'i', "stepi" },
     81  1.1  christos   { 'u', "up" },
     82  1.1  christos   { 'v', "info locals" },
     83  1.1  christos   { 'w', "where" },
     84  1.1  christos   { 0, 0 },
     85  1.1  christos };
     86  1.1  christos 
     87  1.1  christos static Keymap tui_keymap;
     88  1.1  christos static Keymap tui_readline_standard_keymap;
     89  1.1  christos 
     90  1.1  christos /* TUI readline command.
     91  1.1  christos    Switch the output mode between TUI/standard gdb.  */
     92  1.1  christos static int
     93  1.1  christos tui_rl_switch_mode (int notused1, int notused2)
     94  1.1  christos {
     95  1.3  christos 
     96  1.3  christos   /* Don't let exceptions escape.  We're in the middle of a readline
     97  1.3  christos      callback that isn't prepared for that.  */
     98  1.9  christos   try
     99  1.1  christos     {
    100  1.3  christos       if (tui_active)
    101  1.3  christos 	{
    102  1.3  christos 	  tui_disable ();
    103  1.3  christos 	  rl_prep_terminal (0);
    104  1.3  christos 	}
    105  1.3  christos       else
    106  1.3  christos 	{
    107  1.3  christos 	  /* If tui_enable throws, we'll re-prep below.  */
    108  1.3  christos 	  rl_deprep_terminal ();
    109  1.3  christos 	  tui_enable ();
    110  1.3  christos 	}
    111  1.1  christos     }
    112  1.9  christos   catch (const gdb_exception &ex)
    113  1.1  christos     {
    114  1.3  christos       exception_print (gdb_stderr, ex);
    115  1.3  christos 
    116  1.3  christos       if (!tui_active)
    117  1.3  christos 	rl_prep_terminal (0);
    118  1.1  christos     }
    119  1.1  christos 
    120  1.1  christos   /* Clear the readline in case switching occurred in middle of
    121  1.1  christos      something.  */
    122  1.1  christos   if (rl_end)
    123  1.1  christos     rl_kill_text (0, rl_end);
    124  1.1  christos 
    125  1.1  christos   /* Since we left the curses mode, the terminal mode is restored to
    126  1.1  christos      some previous state.  That state may not be suitable for readline
    127  1.1  christos      to work correctly (it may be restored in line mode).  We force an
    128  1.1  christos      exit of the current readline so that readline is re-entered and
    129  1.1  christos      it will be able to setup the terminal for its needs.  By
    130  1.1  christos      re-entering in readline, we also redisplay its prompt in the
    131  1.1  christos      non-curses mode.  */
    132  1.1  christos   rl_newline (1, '\n');
    133  1.1  christos 
    134  1.1  christos   /* Make sure the \n we are returning does not repeat the last
    135  1.1  christos      command.  */
    136  1.1  christos   dont_repeat ();
    137  1.1  christos   return 0;
    138  1.1  christos }
    139  1.1  christos 
    140  1.1  christos /* TUI readline command.
    141  1.1  christos    Change the TUI layout to show a next layout.
    142  1.1  christos    This function is bound to CTRL-X 2.  It is intended to provide
    143  1.9  christos    a functionality close to the Emacs split-window command.  */
    144  1.1  christos static int
    145  1.1  christos tui_rl_change_windows (int notused1, int notused2)
    146  1.1  christos {
    147  1.1  christos   if (!tui_active)
    148  1.1  christos     tui_rl_switch_mode (0 /* notused */, 0 /* notused */);
    149  1.1  christos 
    150  1.1  christos   if (tui_active)
    151  1.9  christos     tui_next_layout ();
    152  1.1  christos 
    153  1.1  christos   return 0;
    154  1.1  christos }
    155  1.1  christos 
    156  1.1  christos /* TUI readline command.
    157  1.1  christos    Delete the second TUI window to only show one.  */
    158  1.1  christos static int
    159  1.1  christos tui_rl_delete_other_windows (int notused1, int notused2)
    160  1.1  christos {
    161  1.1  christos   if (!tui_active)
    162  1.1  christos     tui_rl_switch_mode (0 /* notused */, 0 /* notused */);
    163  1.1  christos 
    164  1.1  christos   if (tui_active)
    165  1.9  christos     tui_remove_some_windows ();
    166  1.1  christos 
    167  1.1  christos   return 0;
    168  1.1  christos }
    169  1.1  christos 
    170  1.1  christos /* TUI readline command.
    171  1.1  christos    Switch the active window to give the focus to a next window.  */
    172  1.1  christos static int
    173  1.1  christos tui_rl_other_window (int count, int key)
    174  1.1  christos {
    175  1.1  christos   struct tui_win_info *win_info;
    176  1.1  christos 
    177  1.1  christos   if (!tui_active)
    178  1.1  christos     tui_rl_switch_mode (0 /* notused */, 0 /* notused */);
    179  1.1  christos 
    180  1.1  christos   win_info = tui_next_win (tui_win_with_focus ());
    181  1.1  christos   if (win_info)
    182  1.1  christos     {
    183  1.1  christos       tui_set_win_focus_to (win_info);
    184  1.9  christos       keypad (TUI_CMD_WIN->handle.get (), win_info != TUI_CMD_WIN);
    185  1.1  christos     }
    186  1.1  christos   return 0;
    187  1.1  christos }
    188  1.1  christos 
    189  1.1  christos /* TUI readline command.
    190  1.1  christos    Execute the gdb command bound to the specified key.  */
    191  1.1  christos static int
    192  1.1  christos tui_rl_command_key (int count, int key)
    193  1.1  christos {
    194  1.1  christos   int i;
    195  1.1  christos 
    196  1.1  christos   reinitialize_more_filter ();
    197  1.1  christos   for (i = 0; tui_commands[i].cmd; i++)
    198  1.1  christos     {
    199  1.1  christos       if (tui_commands[i].key == key)
    200  1.1  christos         {
    201  1.1  christos           /* Insert the command in the readline buffer.
    202  1.1  christos              Avoid calling the gdb command here since it creates
    203  1.1  christos              a possible recursion on readline if prompt_for_continue
    204  1.1  christos              is called (See PR 9584).  The command will also appear
    205  1.1  christos              in the readline history which turns out to be better.  */
    206  1.1  christos           rl_insert_text (tui_commands[i].cmd);
    207  1.1  christos           rl_newline (1, '\n');
    208  1.1  christos 
    209  1.1  christos           /* Switch to gdb command mode while executing the command.
    210  1.1  christos              This way the gdb's continue prompty will be displayed.  */
    211  1.1  christos           tui_set_key_mode (TUI_ONE_COMMAND_MODE);
    212  1.1  christos           return 0;
    213  1.1  christos         }
    214  1.1  christos     }
    215  1.1  christos   return 0;
    216  1.1  christos }
    217  1.1  christos 
    218  1.1  christos /* TUI readline command.
    219  1.1  christos    Temporarily leave the TUI SingleKey mode to allow editing
    220  1.1  christos    a gdb command with the normal readline.  Once the command
    221  1.1  christos    is executed, the TUI SingleKey mode is installed back.  */
    222  1.1  christos static int
    223  1.1  christos tui_rl_command_mode (int count, int key)
    224  1.1  christos {
    225  1.1  christos   tui_set_key_mode (TUI_ONE_COMMAND_MODE);
    226  1.1  christos   return rl_insert (count, key);
    227  1.1  christos }
    228  1.1  christos 
    229  1.1  christos /* TUI readline command.
    230  1.1  christos    Switch between TUI SingleKey mode and gdb readline editing.  */
    231  1.1  christos static int
    232  1.1  christos tui_rl_next_keymap (int notused1, int notused2)
    233  1.1  christos {
    234  1.1  christos   if (!tui_active)
    235  1.1  christos     tui_rl_switch_mode (0 /* notused */, 0 /* notused */);
    236  1.1  christos 
    237  1.1  christos   tui_set_key_mode (tui_current_key_mode == TUI_COMMAND_MODE
    238  1.1  christos                     ? TUI_SINGLE_KEY_MODE : TUI_COMMAND_MODE);
    239  1.1  christos   return 0;
    240  1.1  christos }
    241  1.1  christos 
    242  1.1  christos /* Readline hook to redisplay ourself the gdb prompt.
    243  1.1  christos    In the SingleKey mode, the prompt is not printed so that
    244  1.1  christos    the command window is cleaner.  It will be displayed if
    245  1.1  christos    we temporarily leave the SingleKey mode.  */
    246  1.1  christos static int
    247  1.1  christos tui_rl_startup_hook (void)
    248  1.1  christos {
    249  1.1  christos   rl_already_prompted = 1;
    250  1.6  christos   if (tui_current_key_mode != TUI_COMMAND_MODE
    251  1.6  christos       && !gdb_in_secondary_prompt_p (current_ui))
    252  1.1  christos     tui_set_key_mode (TUI_SINGLE_KEY_MODE);
    253  1.1  christos   tui_redisplay_readline ();
    254  1.1  christos   return 0;
    255  1.1  christos }
    256  1.1  christos 
    257  1.1  christos /* Change the TUI key mode by installing the appropriate readline
    258  1.1  christos    keymap.  */
    259  1.1  christos void
    260  1.1  christos tui_set_key_mode (enum tui_key_mode mode)
    261  1.1  christos {
    262  1.1  christos   tui_current_key_mode = mode;
    263  1.1  christos   rl_set_keymap (mode == TUI_SINGLE_KEY_MODE
    264  1.1  christos                  ? tui_keymap : tui_readline_standard_keymap);
    265  1.1  christos   tui_show_locator_content ();
    266  1.1  christos }
    267  1.1  christos 
    268  1.1  christos /* Initialize readline and configure the keymap for the switching
    269  1.1  christos    key shortcut.  */
    270  1.1  christos void
    271  1.9  christos tui_ensure_readline_initialized ()
    272  1.1  christos {
    273  1.9  christos   static bool initialized;
    274  1.9  christos 
    275  1.9  christos   if (initialized)
    276  1.9  christos     return;
    277  1.9  christos   initialized = true;
    278  1.9  christos 
    279  1.1  christos   int i;
    280  1.1  christos   Keymap tui_ctlx_keymap;
    281  1.1  christos 
    282  1.1  christos   rl_add_defun ("tui-switch-mode", tui_rl_switch_mode, -1);
    283  1.1  christos   rl_add_defun ("next-keymap", tui_rl_next_keymap, -1);
    284  1.9  christos   rl_add_defun ("tui-delete-other-windows", tui_rl_delete_other_windows, -1);
    285  1.9  christos   rl_add_defun ("tui-change-windows", tui_rl_change_windows, -1);
    286  1.9  christos   rl_add_defun ("tui-other-window", tui_rl_other_window, -1);
    287  1.1  christos 
    288  1.1  christos   tui_keymap = rl_make_bare_keymap ();
    289  1.9  christos 
    290  1.9  christos   /* The named keymap feature was added in Readline 8.0.  */
    291  1.9  christos #if RL_READLINE_VERSION >= 0x800
    292  1.9  christos   rl_set_keymap_name ("SingleKey", tui_keymap);
    293  1.9  christos #endif
    294  1.9  christos 
    295  1.1  christos   tui_ctlx_keymap = rl_make_bare_keymap ();
    296  1.1  christos   tui_readline_standard_keymap = rl_get_keymap ();
    297  1.1  christos 
    298  1.1  christos   for (i = 0; tui_commands[i].cmd; i++)
    299  1.1  christos     rl_bind_key_in_map (tui_commands[i].key, tui_rl_command_key, tui_keymap);
    300  1.1  christos 
    301  1.1  christos   rl_generic_bind (ISKMAP, "\\C-x", (char*) tui_ctlx_keymap, tui_keymap);
    302  1.1  christos 
    303  1.1  christos   /* Bind all other keys to tui_rl_command_mode so that we switch
    304  1.1  christos      temporarily from SingleKey mode and can enter a gdb command.  */
    305  1.1  christos   for (i = ' '; i < 0x7f; i++)
    306  1.1  christos     {
    307  1.1  christos       int j;
    308  1.1  christos 
    309  1.1  christos       for (j = 0; tui_commands[j].cmd; j++)
    310  1.1  christos         if (tui_commands[j].key == i)
    311  1.1  christos           break;
    312  1.1  christos 
    313  1.1  christos       if (tui_commands[j].cmd)
    314  1.1  christos         continue;
    315  1.1  christos 
    316  1.1  christos       rl_bind_key_in_map (i, tui_rl_command_mode, tui_keymap);
    317  1.1  christos     }
    318  1.1  christos 
    319  1.1  christos   rl_bind_key_in_map ('a', tui_rl_switch_mode, emacs_ctlx_keymap);
    320  1.1  christos   rl_bind_key_in_map ('a', tui_rl_switch_mode, tui_ctlx_keymap);
    321  1.1  christos   rl_bind_key_in_map ('A', tui_rl_switch_mode, emacs_ctlx_keymap);
    322  1.1  christos   rl_bind_key_in_map ('A', tui_rl_switch_mode, tui_ctlx_keymap);
    323  1.1  christos   rl_bind_key_in_map (CTRL ('A'), tui_rl_switch_mode, emacs_ctlx_keymap);
    324  1.1  christos   rl_bind_key_in_map (CTRL ('A'), tui_rl_switch_mode, tui_ctlx_keymap);
    325  1.1  christos   rl_bind_key_in_map ('1', tui_rl_delete_other_windows, emacs_ctlx_keymap);
    326  1.1  christos   rl_bind_key_in_map ('1', tui_rl_delete_other_windows, tui_ctlx_keymap);
    327  1.1  christos   rl_bind_key_in_map ('2', tui_rl_change_windows, emacs_ctlx_keymap);
    328  1.1  christos   rl_bind_key_in_map ('2', tui_rl_change_windows, tui_ctlx_keymap);
    329  1.1  christos   rl_bind_key_in_map ('o', tui_rl_other_window, emacs_ctlx_keymap);
    330  1.1  christos   rl_bind_key_in_map ('o', tui_rl_other_window, tui_ctlx_keymap);
    331  1.1  christos   rl_bind_key_in_map ('q', tui_rl_next_keymap, tui_keymap);
    332  1.1  christos   rl_bind_key_in_map ('s', tui_rl_next_keymap, emacs_ctlx_keymap);
    333  1.1  christos   rl_bind_key_in_map ('s', tui_rl_next_keymap, tui_ctlx_keymap);
    334  1.9  christos 
    335  1.9  christos   /* Initialize readline after the above.  */
    336  1.9  christos   rl_initialize ();
    337  1.1  christos }
    338  1.1  christos 
    339  1.3  christos /* Return the TERM variable from the environment, or "<unset>"
    340  1.3  christos    if not set.  */
    341  1.3  christos 
    342  1.3  christos static const char *
    343  1.3  christos gdb_getenv_term (void)
    344  1.3  christos {
    345  1.3  christos   const char *term;
    346  1.3  christos 
    347  1.3  christos   term = getenv ("TERM");
    348  1.3  christos   if (term != NULL)
    349  1.3  christos     return term;
    350  1.3  christos   return "<unset>";
    351  1.3  christos }
    352  1.3  christos 
    353  1.1  christos /* Enter in the tui mode (curses).
    354  1.1  christos    When in normal mode, it installs the tui hooks in gdb, redirects
    355  1.1  christos    the gdb output, configures the readline to work in tui mode.
    356  1.1  christos    When in curses mode, it does nothing.  */
    357  1.1  christos void
    358  1.1  christos tui_enable (void)
    359  1.1  christos {
    360  1.1  christos   if (tui_active)
    361  1.1  christos     return;
    362  1.1  christos 
    363  1.9  christos   /* To avoid to initialize curses when gdb starts, there is a deferred
    364  1.1  christos      curses initialization.  This initialization is made only once
    365  1.1  christos      and the first time the curses mode is entered.  */
    366  1.1  christos   if (tui_finish_init)
    367  1.1  christos     {
    368  1.1  christos       WINDOW *w;
    369  1.3  christos       SCREEN *s;
    370  1.8  christos #ifndef __MINGW32__
    371  1.8  christos        const char *cap;
    372  1.8  christos #endif
    373  1.3  christos       const char *interp;
    374  1.3  christos 
    375  1.3  christos       /* If the top level interpreter is not the console/tui (e.g.,
    376  1.3  christos 	 MI), enabling curses will certainly lose.  */
    377  1.8  christos       interp = top_level_interpreter ()->name ();
    378  1.3  christos       if (strcmp (interp, INTERP_TUI) != 0)
    379  1.3  christos 	error (_("Cannot enable the TUI when the interpreter is '%s'"), interp);
    380  1.3  christos 
    381  1.3  christos       /* Don't try to setup curses (and print funny control
    382  1.3  christos 	 characters) if we're not outputting to a terminal.  */
    383  1.9  christos       if (!gdb_stderr->isatty ())
    384  1.3  christos 	error (_("Cannot enable the TUI when output is not a terminal"));
    385  1.3  christos 
    386  1.3  christos       s = newterm (NULL, stdout, stdin);
    387  1.3  christos #ifdef __MINGW32__
    388  1.3  christos       /* The MinGW port of ncurses requires $TERM to be unset in order
    389  1.3  christos 	 to activate the Windows console driver.  */
    390  1.3  christos       if (s == NULL)
    391  1.7  christos 	s = newterm ((char *) "unknown", stdout, stdin);
    392  1.3  christos #endif
    393  1.3  christos       if (s == NULL)
    394  1.3  christos 	{
    395  1.3  christos 	  error (_("Cannot enable the TUI: error opening terminal [TERM=%s]"),
    396  1.3  christos 		 gdb_getenv_term ());
    397  1.3  christos 	}
    398  1.3  christos       w = stdscr;
    399  1.8  christos       if (has_colors ())
    400  1.8  christos 	{
    401  1.8  christos #ifdef HAVE_USE_DEFAULT_COLORS
    402  1.8  christos 	  /* Ncurses extension to help with resetting to the default
    403  1.8  christos 	     color.  */
    404  1.8  christos 	  use_default_colors ();
    405  1.8  christos #endif
    406  1.8  christos 	  start_color ();
    407  1.8  christos 	}
    408  1.3  christos 
    409  1.3  christos       /* Check required terminal capabilities.  The MinGW port of
    410  1.3  christos 	 ncurses does have them, but doesn't expose them through "cup".  */
    411  1.3  christos #ifndef __MINGW32__
    412  1.7  christos       cap = tigetstr ((char *) "cup");
    413  1.3  christos       if (cap == NULL || cap == (char *) -1 || *cap == '\0')
    414  1.3  christos 	{
    415  1.3  christos 	  endwin ();
    416  1.3  christos 	  delscreen (s);
    417  1.3  christos 	  error (_("Cannot enable the TUI: "
    418  1.3  christos 		   "terminal doesn't support cursor addressing [TERM=%s]"),
    419  1.3  christos 		 gdb_getenv_term ());
    420  1.3  christos 	}
    421  1.3  christos #endif
    422  1.1  christos 
    423  1.1  christos       cbreak ();
    424  1.1  christos       noecho ();
    425  1.1  christos       /* timeout (1); */
    426  1.1  christos       nodelay(w, FALSE);
    427  1.1  christos       nl();
    428  1.1  christos       keypad (w, TRUE);
    429  1.1  christos       tui_set_term_height_to (LINES);
    430  1.1  christos       tui_set_term_width_to (COLS);
    431  1.1  christos       def_prog_mode ();
    432  1.1  christos 
    433  1.1  christos       tui_show_frame_info (0);
    434  1.9  christos       tui_set_initial_layout ();
    435  1.1  christos       tui_set_win_focus_to (TUI_SRC_WIN);
    436  1.9  christos       keypad (TUI_CMD_WIN->handle.get (), TRUE);
    437  1.9  christos       wrefresh (TUI_CMD_WIN->handle.get ());
    438  1.9  christos       tui_finish_init = false;
    439  1.1  christos     }
    440  1.1  christos   else
    441  1.1  christos     {
    442  1.1  christos      /* Save the current gdb setting of the terminal.
    443  1.1  christos         Curses will restore this state when endwin() is called.  */
    444  1.1  christos      def_shell_mode ();
    445  1.1  christos      clearok (stdscr, TRUE);
    446  1.1  christos    }
    447  1.1  christos 
    448  1.9  christos   if (tui_update_variables ())
    449  1.9  christos     tui_rehighlight_all ();
    450  1.1  christos 
    451  1.1  christos   tui_setup_io (1);
    452  1.1  christos 
    453  1.9  christos   tui_active = true;
    454  1.5  christos 
    455  1.5  christos   /* Resize windows before anything might display/refresh a
    456  1.5  christos      window.  */
    457  1.5  christos   if (tui_win_resized ())
    458  1.5  christos     {
    459  1.9  christos       tui_set_win_resized_to (false);
    460  1.5  christos       tui_resize_all ();
    461  1.5  christos     }
    462  1.5  christos 
    463  1.1  christos   if (deprecated_safe_get_selected_frame ())
    464  1.5  christos     tui_show_frame_info (deprecated_safe_get_selected_frame ());
    465  1.9  christos   else
    466  1.9  christos     tui_display_main ();
    467  1.9  christos 
    468  1.9  christos   /* Install the TUI specific hooks.  This must be done after the call to
    469  1.9  christos      tui_display_main so that we don't detect the symtab changed event it
    470  1.9  christos      can cause.  */
    471  1.9  christos   tui_install_hooks ();
    472  1.9  christos   rl_startup_hook = tui_rl_startup_hook;
    473  1.1  christos 
    474  1.1  christos   /* Restore TUI keymap.  */
    475  1.1  christos   tui_set_key_mode (tui_current_key_mode);
    476  1.5  christos 
    477  1.5  christos   /* Refresh the screen.  */
    478  1.1  christos   tui_refresh_all_win ();
    479  1.1  christos 
    480  1.1  christos   /* Update gdb's knowledge of its terminal.  */
    481  1.3  christos   gdb_save_tty_state ();
    482  1.1  christos   tui_update_gdb_sizes ();
    483  1.1  christos }
    484  1.1  christos 
    485  1.1  christos /* Leave the tui mode.
    486  1.1  christos    Remove the tui hooks and configure the gdb output and readline
    487  1.1  christos    back to their original state.  The curses mode is left so that
    488  1.1  christos    the terminal setting is restored to the point when we entered.  */
    489  1.1  christos void
    490  1.1  christos tui_disable (void)
    491  1.1  christos {
    492  1.1  christos   if (!tui_active)
    493  1.1  christos     return;
    494  1.1  christos 
    495  1.1  christos   /* Restore initial readline keymap.  */
    496  1.1  christos   rl_set_keymap (tui_readline_standard_keymap);
    497  1.1  christos 
    498  1.1  christos   /* Remove TUI hooks.  */
    499  1.1  christos   tui_remove_hooks ();
    500  1.1  christos   rl_startup_hook = 0;
    501  1.1  christos   rl_already_prompted = 0;
    502  1.1  christos 
    503  1.1  christos   /* Leave curses and restore previous gdb terminal setting.  */
    504  1.1  christos   endwin ();
    505  1.1  christos 
    506  1.1  christos   /* gdb terminal has changed, update gdb internal copy of it
    507  1.1  christos      so that terminal management with the inferior works.  */
    508  1.1  christos   tui_setup_io (0);
    509  1.1  christos 
    510  1.1  christos   /* Update gdb's knowledge of its terminal.  */
    511  1.3  christos   gdb_save_tty_state ();
    512  1.1  christos 
    513  1.9  christos   tui_active = false;
    514  1.1  christos   tui_update_gdb_sizes ();
    515  1.1  christos }
    516  1.1  christos 
    517  1.5  christos /* Command wrapper for enabling tui mode.  */
    518  1.5  christos 
    519  1.5  christos static void
    520  1.8  christos tui_enable_command (const char *args, int from_tty)
    521  1.5  christos {
    522  1.5  christos   tui_enable ();
    523  1.5  christos }
    524  1.5  christos 
    525  1.5  christos /* Command wrapper for leaving tui mode.  */
    526  1.5  christos 
    527  1.5  christos static void
    528  1.8  christos tui_disable_command (const char *args, int from_tty)
    529  1.5  christos {
    530  1.5  christos   tui_disable ();
    531  1.5  christos }
    532  1.5  christos 
    533  1.1  christos void
    534  1.1  christos tui_show_assembly (struct gdbarch *gdbarch, CORE_ADDR addr)
    535  1.1  christos {
    536  1.9  christos   tui_suppress_output suppress;
    537  1.1  christos   tui_add_win_to_layout (DISASSEM_WIN);
    538  1.1  christos   tui_update_source_windows_with_addr (gdbarch, addr);
    539  1.1  christos }
    540  1.1  christos 
    541  1.9  christos bool
    542  1.1  christos tui_is_window_visible (enum tui_win_type type)
    543  1.1  christos {
    544  1.9  christos   if (!tui_active)
    545  1.9  christos     return false;
    546  1.1  christos 
    547  1.1  christos   if (tui_win_list[type] == 0)
    548  1.9  christos     return false;
    549  1.1  christos 
    550  1.9  christos   return tui_win_list[type]->is_visible ();
    551  1.1  christos }
    552  1.1  christos 
    553  1.9  christos bool
    554  1.1  christos tui_get_command_dimension (unsigned int *width,
    555  1.1  christos 			   unsigned int *height)
    556  1.1  christos {
    557  1.1  christos   if (!tui_active || (TUI_CMD_WIN == NULL))
    558  1.9  christos     return false;
    559  1.1  christos 
    560  1.9  christos   *width = TUI_CMD_WIN->width;
    561  1.9  christos   *height = TUI_CMD_WIN->height;
    562  1.9  christos   return true;
    563  1.1  christos }
    564  1.5  christos 
    565  1.9  christos void _initialize_tui ();
    566  1.5  christos void
    567  1.9  christos _initialize_tui ()
    568  1.5  christos {
    569  1.5  christos   struct cmd_list_element **tuicmd;
    570  1.5  christos 
    571  1.5  christos   tuicmd = tui_get_cmd_list ();
    572  1.5  christos 
    573  1.5  christos   add_cmd ("enable", class_tui, tui_enable_command,
    574  1.9  christos 	   _("Enable TUI display mode.\n\
    575  1.9  christos Usage: tui enable"),
    576  1.5  christos 	   tuicmd);
    577  1.5  christos   add_cmd ("disable", class_tui, tui_disable_command,
    578  1.9  christos 	   _("Disable TUI display mode.\n\
    579  1.9  christos Usage: tui disable"),
    580  1.5  christos 	   tuicmd);
    581  1.5  christos }
    582