Home | History | Annotate | Line # | Download | only in tui
tui.c revision 1.3
      1  1.1  christos /* General functions for the WDB TUI.
      2  1.1  christos 
      3  1.3  christos    Copyright (C) 1998-2015 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.1  christos #include "tui/tui-data.h"
     27  1.1  christos #include "tui/tui-layout.h"
     28  1.1  christos #include "tui/tui-io.h"
     29  1.1  christos #include "tui/tui-regs.h"
     30  1.1  christos #include "tui/tui-stack.h"
     31  1.1  christos #include "tui/tui-win.h"
     32  1.1  christos #include "tui/tui-winsource.h"
     33  1.1  christos #include "tui/tui-windata.h"
     34  1.1  christos #include "target.h"
     35  1.1  christos #include "frame.h"
     36  1.1  christos #include "breakpoint.h"
     37  1.1  christos #include "inferior.h"
     38  1.1  christos #include "symtab.h"
     39  1.1  christos #include "source.h"
     40  1.3  christos #include "terminal.h"
     41  1.1  christos 
     42  1.1  christos #include <ctype.h>
     43  1.1  christos #include <signal.h>
     44  1.1  christos #include <fcntl.h>
     45  1.1  christos #if 0
     46  1.1  christos #include <termio.h>
     47  1.1  christos #endif
     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.1  christos int tui_active = 0;
     60  1.1  christos static int tui_finish_init = 1;
     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.1  christos   { 'r', "run" },
     78  1.1  christos   { 's', "step" },
     79  1.1  christos   { 'u', "up" },
     80  1.1  christos   { 'v', "info locals" },
     81  1.1  christos   { 'w', "where" },
     82  1.1  christos   { 0, 0 },
     83  1.1  christos };
     84  1.1  christos 
     85  1.1  christos static Keymap tui_keymap;
     86  1.1  christos static Keymap tui_readline_standard_keymap;
     87  1.1  christos 
     88  1.1  christos /* TUI readline command.
     89  1.1  christos    Switch the output mode between TUI/standard gdb.  */
     90  1.1  christos static int
     91  1.1  christos tui_rl_switch_mode (int notused1, int notused2)
     92  1.1  christos {
     93  1.3  christos   volatile struct gdb_exception ex;
     94  1.3  christos 
     95  1.3  christos   /* Don't let exceptions escape.  We're in the middle of a readline
     96  1.3  christos      callback that isn't prepared for that.  */
     97  1.3  christos   TRY_CATCH (ex, RETURN_MASK_ALL)
     98  1.1  christos     {
     99  1.3  christos       if (tui_active)
    100  1.3  christos 	{
    101  1.3  christos 	  tui_disable ();
    102  1.3  christos 	  rl_prep_terminal (0);
    103  1.3  christos 	}
    104  1.3  christos       else
    105  1.3  christos 	{
    106  1.3  christos 	  /* If tui_enable throws, we'll re-prep below.  */
    107  1.3  christos 	  rl_deprep_terminal ();
    108  1.3  christos 	  tui_enable ();
    109  1.3  christos 	}
    110  1.1  christos     }
    111  1.3  christos   if (ex.reason < 0)
    112  1.1  christos     {
    113  1.3  christos       exception_print (gdb_stderr, ex);
    114  1.3  christos 
    115  1.3  christos       if (!tui_active)
    116  1.3  christos 	rl_prep_terminal (0);
    117  1.1  christos     }
    118  1.1  christos 
    119  1.1  christos   /* Clear the readline in case switching occurred in middle of
    120  1.1  christos      something.  */
    121  1.1  christos   if (rl_end)
    122  1.1  christos     rl_kill_text (0, rl_end);
    123  1.1  christos 
    124  1.1  christos   /* Since we left the curses mode, the terminal mode is restored to
    125  1.1  christos      some previous state.  That state may not be suitable for readline
    126  1.1  christos      to work correctly (it may be restored in line mode).  We force an
    127  1.1  christos      exit of the current readline so that readline is re-entered and
    128  1.1  christos      it will be able to setup the terminal for its needs.  By
    129  1.1  christos      re-entering in readline, we also redisplay its prompt in the
    130  1.1  christos      non-curses mode.  */
    131  1.1  christos   rl_newline (1, '\n');
    132  1.1  christos 
    133  1.1  christos   /* Make sure the \n we are returning does not repeat the last
    134  1.1  christos      command.  */
    135  1.1  christos   dont_repeat ();
    136  1.1  christos   return 0;
    137  1.1  christos }
    138  1.1  christos 
    139  1.1  christos /* TUI readline command.
    140  1.1  christos    Change the TUI layout to show a next layout.
    141  1.1  christos    This function is bound to CTRL-X 2.  It is intended to provide
    142  1.1  christos    a functionality close to the Emacs split-window command.  We
    143  1.1  christos    always show two windows (src+asm), (src+regs) or (asm+regs).  */
    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.1  christos     {
    152  1.1  christos       enum tui_layout_type new_layout;
    153  1.1  christos       enum tui_register_display_type regs_type = TUI_UNDEFINED_REGS;
    154  1.1  christos 
    155  1.1  christos       new_layout = tui_current_layout ();
    156  1.1  christos 
    157  1.1  christos       /* Select a new layout to have a rolling layout behavior with
    158  1.1  christos 	 always two windows (except when undefined).  */
    159  1.1  christos       switch (new_layout)
    160  1.1  christos 	{
    161  1.1  christos 	case SRC_COMMAND:
    162  1.1  christos 	  new_layout = SRC_DISASSEM_COMMAND;
    163  1.1  christos 	  break;
    164  1.1  christos 
    165  1.1  christos 	case DISASSEM_COMMAND:
    166  1.1  christos 	  new_layout = SRC_DISASSEM_COMMAND;
    167  1.1  christos 	  break;
    168  1.1  christos 
    169  1.1  christos 	case SRC_DATA_COMMAND:
    170  1.1  christos 	  new_layout = SRC_DISASSEM_COMMAND;
    171  1.1  christos 	  break;
    172  1.1  christos 
    173  1.1  christos 	case SRC_DISASSEM_COMMAND:
    174  1.1  christos 	  new_layout = DISASSEM_DATA_COMMAND;
    175  1.1  christos 	  break;
    176  1.1  christos 
    177  1.1  christos 	case DISASSEM_DATA_COMMAND:
    178  1.1  christos 	  new_layout = SRC_DATA_COMMAND;
    179  1.1  christos 	  break;
    180  1.1  christos 
    181  1.1  christos 	default:
    182  1.1  christos 	  new_layout = SRC_COMMAND;
    183  1.1  christos 	  break;
    184  1.1  christos 	}
    185  1.1  christos       tui_set_layout (new_layout, regs_type);
    186  1.1  christos     }
    187  1.1  christos   return 0;
    188  1.1  christos }
    189  1.1  christos 
    190  1.1  christos /* TUI readline command.
    191  1.1  christos    Delete the second TUI window to only show one.  */
    192  1.1  christos static int
    193  1.1  christos tui_rl_delete_other_windows (int notused1, int notused2)
    194  1.1  christos {
    195  1.1  christos   if (!tui_active)
    196  1.1  christos     tui_rl_switch_mode (0 /* notused */, 0 /* notused */);
    197  1.1  christos 
    198  1.1  christos   if (tui_active)
    199  1.1  christos     {
    200  1.1  christos       enum tui_layout_type new_layout;
    201  1.1  christos       enum tui_register_display_type regs_type = TUI_UNDEFINED_REGS;
    202  1.1  christos 
    203  1.1  christos       new_layout = tui_current_layout ();
    204  1.1  christos 
    205  1.1  christos       /* Kill one window.  */
    206  1.1  christos       switch (new_layout)
    207  1.1  christos 	{
    208  1.1  christos 	case SRC_COMMAND:
    209  1.1  christos 	case SRC_DATA_COMMAND:
    210  1.1  christos 	case SRC_DISASSEM_COMMAND:
    211  1.1  christos 	default:
    212  1.1  christos 	  new_layout = SRC_COMMAND;
    213  1.1  christos 	  break;
    214  1.1  christos 
    215  1.1  christos 	case DISASSEM_COMMAND:
    216  1.1  christos 	case DISASSEM_DATA_COMMAND:
    217  1.1  christos 	  new_layout = DISASSEM_COMMAND;
    218  1.1  christos 	  break;
    219  1.1  christos 	}
    220  1.1  christos       tui_set_layout (new_layout, regs_type);
    221  1.1  christos     }
    222  1.1  christos   return 0;
    223  1.1  christos }
    224  1.1  christos 
    225  1.1  christos /* TUI readline command.
    226  1.1  christos    Switch the active window to give the focus to a next window.  */
    227  1.1  christos static int
    228  1.1  christos tui_rl_other_window (int count, int key)
    229  1.1  christos {
    230  1.1  christos   struct tui_win_info *win_info;
    231  1.1  christos 
    232  1.1  christos   if (!tui_active)
    233  1.1  christos     tui_rl_switch_mode (0 /* notused */, 0 /* notused */);
    234  1.1  christos 
    235  1.1  christos   win_info = tui_next_win (tui_win_with_focus ());
    236  1.1  christos   if (win_info)
    237  1.1  christos     {
    238  1.1  christos       tui_set_win_focus_to (win_info);
    239  1.1  christos       if (TUI_DATA_WIN && TUI_DATA_WIN->generic.is_visible)
    240  1.1  christos         tui_refresh_data_win ();
    241  1.1  christos       keypad (TUI_CMD_WIN->generic.handle, (win_info != TUI_CMD_WIN));
    242  1.1  christos     }
    243  1.1  christos   return 0;
    244  1.1  christos }
    245  1.1  christos 
    246  1.1  christos /* TUI readline command.
    247  1.1  christos    Execute the gdb command bound to the specified key.  */
    248  1.1  christos static int
    249  1.1  christos tui_rl_command_key (int count, int key)
    250  1.1  christos {
    251  1.1  christos   int i;
    252  1.1  christos 
    253  1.1  christos   reinitialize_more_filter ();
    254  1.1  christos   for (i = 0; tui_commands[i].cmd; i++)
    255  1.1  christos     {
    256  1.1  christos       if (tui_commands[i].key == key)
    257  1.1  christos         {
    258  1.1  christos           /* Insert the command in the readline buffer.
    259  1.1  christos              Avoid calling the gdb command here since it creates
    260  1.1  christos              a possible recursion on readline if prompt_for_continue
    261  1.1  christos              is called (See PR 9584).  The command will also appear
    262  1.1  christos              in the readline history which turns out to be better.  */
    263  1.1  christos           rl_insert_text (tui_commands[i].cmd);
    264  1.1  christos           rl_newline (1, '\n');
    265  1.1  christos 
    266  1.1  christos           /* Switch to gdb command mode while executing the command.
    267  1.1  christos              This way the gdb's continue prompty will be displayed.  */
    268  1.1  christos           tui_set_key_mode (TUI_ONE_COMMAND_MODE);
    269  1.1  christos           return 0;
    270  1.1  christos         }
    271  1.1  christos     }
    272  1.1  christos   return 0;
    273  1.1  christos }
    274  1.1  christos 
    275  1.1  christos /* TUI readline command.
    276  1.1  christos    Temporarily leave the TUI SingleKey mode to allow editing
    277  1.1  christos    a gdb command with the normal readline.  Once the command
    278  1.1  christos    is executed, the TUI SingleKey mode is installed back.  */
    279  1.1  christos static int
    280  1.1  christos tui_rl_command_mode (int count, int key)
    281  1.1  christos {
    282  1.1  christos   tui_set_key_mode (TUI_ONE_COMMAND_MODE);
    283  1.1  christos   return rl_insert (count, key);
    284  1.1  christos }
    285  1.1  christos 
    286  1.1  christos /* TUI readline command.
    287  1.1  christos    Switch between TUI SingleKey mode and gdb readline editing.  */
    288  1.1  christos static int
    289  1.1  christos tui_rl_next_keymap (int notused1, int notused2)
    290  1.1  christos {
    291  1.1  christos   if (!tui_active)
    292  1.1  christos     tui_rl_switch_mode (0 /* notused */, 0 /* notused */);
    293  1.1  christos 
    294  1.1  christos   tui_set_key_mode (tui_current_key_mode == TUI_COMMAND_MODE
    295  1.1  christos                     ? TUI_SINGLE_KEY_MODE : TUI_COMMAND_MODE);
    296  1.1  christos   return 0;
    297  1.1  christos }
    298  1.1  christos 
    299  1.1  christos /* Readline hook to redisplay ourself the gdb prompt.
    300  1.1  christos    In the SingleKey mode, the prompt is not printed so that
    301  1.1  christos    the command window is cleaner.  It will be displayed if
    302  1.1  christos    we temporarily leave the SingleKey mode.  */
    303  1.1  christos static int
    304  1.1  christos tui_rl_startup_hook (void)
    305  1.1  christos {
    306  1.1  christos   rl_already_prompted = 1;
    307  1.1  christos   if (tui_current_key_mode != TUI_COMMAND_MODE && immediate_quit == 0)
    308  1.1  christos     tui_set_key_mode (TUI_SINGLE_KEY_MODE);
    309  1.1  christos   tui_redisplay_readline ();
    310  1.1  christos   return 0;
    311  1.1  christos }
    312  1.1  christos 
    313  1.1  christos /* Change the TUI key mode by installing the appropriate readline
    314  1.1  christos    keymap.  */
    315  1.1  christos void
    316  1.1  christos tui_set_key_mode (enum tui_key_mode mode)
    317  1.1  christos {
    318  1.1  christos   tui_current_key_mode = mode;
    319  1.1  christos   rl_set_keymap (mode == TUI_SINGLE_KEY_MODE
    320  1.1  christos                  ? tui_keymap : tui_readline_standard_keymap);
    321  1.1  christos   tui_show_locator_content ();
    322  1.1  christos }
    323  1.1  christos 
    324  1.1  christos /* Initialize readline and configure the keymap for the switching
    325  1.1  christos    key shortcut.  */
    326  1.1  christos void
    327  1.1  christos tui_initialize_readline (void)
    328  1.1  christos {
    329  1.1  christos   int i;
    330  1.1  christos   Keymap tui_ctlx_keymap;
    331  1.1  christos 
    332  1.1  christos   rl_initialize ();
    333  1.1  christos 
    334  1.1  christos   rl_add_defun ("tui-switch-mode", tui_rl_switch_mode, -1);
    335  1.1  christos   rl_add_defun ("gdb-command", tui_rl_command_key, -1);
    336  1.1  christos   rl_add_defun ("next-keymap", tui_rl_next_keymap, -1);
    337  1.1  christos 
    338  1.1  christos   tui_keymap = rl_make_bare_keymap ();
    339  1.1  christos   tui_ctlx_keymap = rl_make_bare_keymap ();
    340  1.1  christos   tui_readline_standard_keymap = rl_get_keymap ();
    341  1.1  christos 
    342  1.1  christos   for (i = 0; tui_commands[i].cmd; i++)
    343  1.1  christos     rl_bind_key_in_map (tui_commands[i].key, tui_rl_command_key, tui_keymap);
    344  1.1  christos 
    345  1.1  christos   rl_generic_bind (ISKMAP, "\\C-x", (char*) tui_ctlx_keymap, tui_keymap);
    346  1.1  christos 
    347  1.1  christos   /* Bind all other keys to tui_rl_command_mode so that we switch
    348  1.1  christos      temporarily from SingleKey mode and can enter a gdb command.  */
    349  1.1  christos   for (i = ' '; i < 0x7f; i++)
    350  1.1  christos     {
    351  1.1  christos       int j;
    352  1.1  christos 
    353  1.1  christos       for (j = 0; tui_commands[j].cmd; j++)
    354  1.1  christos         if (tui_commands[j].key == i)
    355  1.1  christos           break;
    356  1.1  christos 
    357  1.1  christos       if (tui_commands[j].cmd)
    358  1.1  christos         continue;
    359  1.1  christos 
    360  1.1  christos       rl_bind_key_in_map (i, tui_rl_command_mode, tui_keymap);
    361  1.1  christos     }
    362  1.1  christos 
    363  1.1  christos   rl_bind_key_in_map ('a', tui_rl_switch_mode, emacs_ctlx_keymap);
    364  1.1  christos   rl_bind_key_in_map ('a', tui_rl_switch_mode, tui_ctlx_keymap);
    365  1.1  christos   rl_bind_key_in_map ('A', tui_rl_switch_mode, emacs_ctlx_keymap);
    366  1.1  christos   rl_bind_key_in_map ('A', tui_rl_switch_mode, tui_ctlx_keymap);
    367  1.1  christos   rl_bind_key_in_map (CTRL ('A'), tui_rl_switch_mode, emacs_ctlx_keymap);
    368  1.1  christos   rl_bind_key_in_map (CTRL ('A'), tui_rl_switch_mode, tui_ctlx_keymap);
    369  1.1  christos   rl_bind_key_in_map ('1', tui_rl_delete_other_windows, emacs_ctlx_keymap);
    370  1.1  christos   rl_bind_key_in_map ('1', tui_rl_delete_other_windows, tui_ctlx_keymap);
    371  1.1  christos   rl_bind_key_in_map ('2', tui_rl_change_windows, emacs_ctlx_keymap);
    372  1.1  christos   rl_bind_key_in_map ('2', tui_rl_change_windows, tui_ctlx_keymap);
    373  1.1  christos   rl_bind_key_in_map ('o', tui_rl_other_window, emacs_ctlx_keymap);
    374  1.1  christos   rl_bind_key_in_map ('o', tui_rl_other_window, tui_ctlx_keymap);
    375  1.1  christos   rl_bind_key_in_map ('q', tui_rl_next_keymap, tui_keymap);
    376  1.1  christos   rl_bind_key_in_map ('s', tui_rl_next_keymap, emacs_ctlx_keymap);
    377  1.1  christos   rl_bind_key_in_map ('s', tui_rl_next_keymap, tui_ctlx_keymap);
    378  1.1  christos }
    379  1.1  christos 
    380  1.3  christos /* Return the TERM variable from the environment, or "<unset>"
    381  1.3  christos    if not set.  */
    382  1.3  christos 
    383  1.3  christos static const char *
    384  1.3  christos gdb_getenv_term (void)
    385  1.3  christos {
    386  1.3  christos   const char *term;
    387  1.3  christos 
    388  1.3  christos   term = getenv ("TERM");
    389  1.3  christos   if (term != NULL)
    390  1.3  christos     return term;
    391  1.3  christos   return "<unset>";
    392  1.3  christos }
    393  1.3  christos 
    394  1.1  christos /* Enter in the tui mode (curses).
    395  1.1  christos    When in normal mode, it installs the tui hooks in gdb, redirects
    396  1.1  christos    the gdb output, configures the readline to work in tui mode.
    397  1.1  christos    When in curses mode, it does nothing.  */
    398  1.1  christos void
    399  1.1  christos tui_enable (void)
    400  1.1  christos {
    401  1.3  christos   struct interp *interp;
    402  1.1  christos 
    403  1.1  christos   if (tui_active)
    404  1.1  christos     return;
    405  1.1  christos 
    406  1.1  christos   /* To avoid to initialize curses when gdb starts, there is a defered
    407  1.1  christos      curses initialization.  This initialization is made only once
    408  1.1  christos      and the first time the curses mode is entered.  */
    409  1.1  christos   if (tui_finish_init)
    410  1.1  christos     {
    411  1.1  christos       WINDOW *w;
    412  1.3  christos       SCREEN *s;
    413  1.3  christos       const char *cap;
    414  1.3  christos       const char *interp;
    415  1.3  christos 
    416  1.3  christos       /* If the top level interpreter is not the console/tui (e.g.,
    417  1.3  christos 	 MI), enabling curses will certainly lose.  */
    418  1.3  christos       interp = interp_name (top_level_interpreter ());
    419  1.3  christos       if (strcmp (interp, INTERP_TUI) != 0)
    420  1.3  christos 	error (_("Cannot enable the TUI when the interpreter is '%s'"), interp);
    421  1.3  christos 
    422  1.3  christos       /* Don't try to setup curses (and print funny control
    423  1.3  christos 	 characters) if we're not outputting to a terminal.  */
    424  1.3  christos       if (!ui_file_isatty (gdb_stdout))
    425  1.3  christos 	error (_("Cannot enable the TUI when output is not a terminal"));
    426  1.3  christos 
    427  1.3  christos       s = newterm (NULL, stdout, stdin);
    428  1.3  christos #ifdef __MINGW32__
    429  1.3  christos       /* The MinGW port of ncurses requires $TERM to be unset in order
    430  1.3  christos 	 to activate the Windows console driver.  */
    431  1.3  christos       if (s == NULL)
    432  1.3  christos 	s = newterm ("unknown", stdout, stdin);
    433  1.3  christos #endif
    434  1.3  christos       if (s == NULL)
    435  1.3  christos 	{
    436  1.3  christos 	  error (_("Cannot enable the TUI: error opening terminal [TERM=%s]"),
    437  1.3  christos 		 gdb_getenv_term ());
    438  1.3  christos 	}
    439  1.3  christos       w = stdscr;
    440  1.3  christos 
    441  1.3  christos       /* Check required terminal capabilities.  The MinGW port of
    442  1.3  christos 	 ncurses does have them, but doesn't expose them through "cup".  */
    443  1.3  christos #ifndef __MINGW32__
    444  1.3  christos       cap = tigetstr ("cup");
    445  1.3  christos       if (cap == NULL || cap == (char *) -1 || *cap == '\0')
    446  1.3  christos 	{
    447  1.3  christos 	  endwin ();
    448  1.3  christos 	  delscreen (s);
    449  1.3  christos 	  error (_("Cannot enable the TUI: "
    450  1.3  christos 		   "terminal doesn't support cursor addressing [TERM=%s]"),
    451  1.3  christos 		 gdb_getenv_term ());
    452  1.3  christos 	}
    453  1.3  christos #endif
    454  1.1  christos 
    455  1.1  christos       cbreak ();
    456  1.1  christos       noecho ();
    457  1.1  christos       /* timeout (1); */
    458  1.1  christos       nodelay(w, FALSE);
    459  1.1  christos       nl();
    460  1.1  christos       keypad (w, TRUE);
    461  1.1  christos       rl_initialize ();
    462  1.1  christos       tui_set_term_height_to (LINES);
    463  1.1  christos       tui_set_term_width_to (COLS);
    464  1.1  christos       def_prog_mode ();
    465  1.1  christos 
    466  1.1  christos       tui_show_frame_info (0);
    467  1.1  christos       tui_set_layout (SRC_COMMAND, TUI_UNDEFINED_REGS);
    468  1.1  christos       tui_set_win_focus_to (TUI_SRC_WIN);
    469  1.1  christos       keypad (TUI_CMD_WIN->generic.handle, TRUE);
    470  1.1  christos       wrefresh (TUI_CMD_WIN->generic.handle);
    471  1.1  christos       tui_finish_init = 0;
    472  1.1  christos     }
    473  1.1  christos   else
    474  1.1  christos     {
    475  1.1  christos      /* Save the current gdb setting of the terminal.
    476  1.1  christos         Curses will restore this state when endwin() is called.  */
    477  1.1  christos      def_shell_mode ();
    478  1.1  christos      clearok (stdscr, TRUE);
    479  1.1  christos    }
    480  1.1  christos 
    481  1.1  christos   /* Install the TUI specific hooks.  */
    482  1.1  christos   tui_install_hooks ();
    483  1.1  christos   rl_startup_hook = tui_rl_startup_hook;
    484  1.1  christos 
    485  1.1  christos   tui_update_variables ();
    486  1.1  christos 
    487  1.1  christos   tui_setup_io (1);
    488  1.1  christos 
    489  1.1  christos   tui_active = 1;
    490  1.1  christos   if (deprecated_safe_get_selected_frame ())
    491  1.1  christos      tui_show_frame_info (deprecated_safe_get_selected_frame ());
    492  1.1  christos 
    493  1.1  christos   /* Restore TUI keymap.  */
    494  1.1  christos   tui_set_key_mode (tui_current_key_mode);
    495  1.1  christos   tui_refresh_all_win ();
    496  1.1  christos 
    497  1.1  christos   /* Update gdb's knowledge of its terminal.  */
    498  1.3  christos   gdb_save_tty_state ();
    499  1.1  christos   tui_update_gdb_sizes ();
    500  1.1  christos }
    501  1.1  christos 
    502  1.1  christos /* Leave the tui mode.
    503  1.1  christos    Remove the tui hooks and configure the gdb output and readline
    504  1.1  christos    back to their original state.  The curses mode is left so that
    505  1.1  christos    the terminal setting is restored to the point when we entered.  */
    506  1.1  christos void
    507  1.1  christos tui_disable (void)
    508  1.1  christos {
    509  1.1  christos   if (!tui_active)
    510  1.1  christos     return;
    511  1.1  christos 
    512  1.1  christos   /* Restore initial readline keymap.  */
    513  1.1  christos   rl_set_keymap (tui_readline_standard_keymap);
    514  1.1  christos 
    515  1.1  christos   /* Remove TUI hooks.  */
    516  1.1  christos   tui_remove_hooks ();
    517  1.1  christos   rl_startup_hook = 0;
    518  1.1  christos   rl_already_prompted = 0;
    519  1.1  christos 
    520  1.1  christos   /* Leave curses and restore previous gdb terminal setting.  */
    521  1.1  christos   endwin ();
    522  1.1  christos 
    523  1.1  christos   /* gdb terminal has changed, update gdb internal copy of it
    524  1.1  christos      so that terminal management with the inferior works.  */
    525  1.1  christos   tui_setup_io (0);
    526  1.1  christos 
    527  1.1  christos   /* Update gdb's knowledge of its terminal.  */
    528  1.3  christos   gdb_save_tty_state ();
    529  1.1  christos 
    530  1.1  christos   tui_active = 0;
    531  1.1  christos   tui_update_gdb_sizes ();
    532  1.1  christos }
    533  1.1  christos 
    534  1.1  christos void
    535  1.1  christos strcat_to_buf (char *buf, int buflen,
    536  1.1  christos 	       const char *item_to_add)
    537  1.1  christos {
    538  1.1  christos   if (item_to_add != (char *) NULL && buf != (char *) NULL)
    539  1.1  christos     {
    540  1.1  christos       if ((strlen (buf) + strlen (item_to_add)) <= buflen)
    541  1.1  christos 	strcat (buf, item_to_add);
    542  1.1  christos       else
    543  1.1  christos 	strncat (buf, item_to_add, (buflen - strlen (buf)));
    544  1.1  christos     }
    545  1.1  christos }
    546  1.1  christos 
    547  1.1  christos #if 0
    548  1.1  christos /* Solaris <sys/termios.h> defines CTRL.  */
    549  1.1  christos #ifndef CTRL
    550  1.1  christos #define CTRL(x)         (x & ~0140)
    551  1.1  christos #endif
    552  1.1  christos 
    553  1.1  christos #define FILEDES         2
    554  1.1  christos #define CHK(val, dft)   (val<=0 ? dft : val)
    555  1.1  christos 
    556  1.1  christos static void
    557  1.1  christos tui_reset (void)
    558  1.1  christos {
    559  1.1  christos   struct termio mode;
    560  1.1  christos 
    561  1.1  christos   /* Reset the teletype mode bits to a sensible state.
    562  1.1  christos      Copied tset.c.  */
    563  1.1  christos #if defined (TIOCGETC)
    564  1.1  christos   struct tchars tbuf;
    565  1.1  christos #endif /* TIOCGETC */
    566  1.1  christos #ifdef UCB_NTTY
    567  1.1  christos   struct ltchars ltc;
    568  1.1  christos 
    569  1.1  christos   if (ldisc == NTTYDISC)
    570  1.1  christos     {
    571  1.1  christos       ioctl (FILEDES, TIOCGLTC, &ltc);
    572  1.1  christos       ltc.t_suspc = CHK (ltc.t_suspc, CTRL ('Z'));
    573  1.1  christos       ltc.t_dsuspc = CHK (ltc.t_dsuspc, CTRL ('Y'));
    574  1.1  christos       ltc.t_rprntc = CHK (ltc.t_rprntc, CTRL ('R'));
    575  1.1  christos       ltc.t_flushc = CHK (ltc.t_flushc, CTRL ('O'));
    576  1.1  christos       ltc.t_werasc = CHK (ltc.t_werasc, CTRL ('W'));
    577  1.1  christos       ltc.t_lnextc = CHK (ltc.t_lnextc, CTRL ('V'));
    578  1.1  christos       ioctl (FILEDES, TIOCSLTC, &ltc);
    579  1.1  christos     }
    580  1.1  christos #endif /* UCB_NTTY */
    581  1.1  christos #ifdef TIOCGETC
    582  1.1  christos   ioctl (FILEDES, TIOCGETC, &tbuf);
    583  1.1  christos   tbuf.t_intrc = CHK (tbuf.t_intrc, CTRL ('?'));
    584  1.1  christos   tbuf.t_quitc = CHK (tbuf.t_quitc, CTRL ('\\'));
    585  1.1  christos   tbuf.t_startc = CHK (tbuf.t_startc, CTRL ('Q'));
    586  1.1  christos   tbuf.t_stopc = CHK (tbuf.t_stopc, CTRL ('S'));
    587  1.1  christos   tbuf.t_eofc = CHK (tbuf.t_eofc, CTRL ('D'));
    588  1.1  christos   /* brkc is left alone.  */
    589  1.1  christos   ioctl (FILEDES, TIOCSETC, &tbuf);
    590  1.1  christos #endif /* TIOCGETC */
    591  1.1  christos   mode.sg_flags &= ~(RAW
    592  1.1  christos #ifdef CBREAK
    593  1.1  christos 		     | CBREAK
    594  1.1  christos #endif /* CBREAK */
    595  1.1  christos 		     | VTDELAY | ALLDELAY);
    596  1.1  christos   mode.sg_flags |= XTABS | ECHO | CRMOD | ANYP;
    597  1.1  christos 
    598  1.1  christos   return;
    599  1.1  christos }
    600  1.1  christos #endif
    601  1.1  christos 
    602  1.1  christos void
    603  1.1  christos tui_show_source (const char *fullname, int line)
    604  1.1  christos {
    605  1.1  christos   struct symtab_and_line cursal = get_current_source_symtab_and_line ();
    606  1.1  christos 
    607  1.1  christos   /* Make sure that the source window is displayed.  */
    608  1.1  christos   tui_add_win_to_layout (SRC_WIN);
    609  1.1  christos 
    610  1.1  christos   tui_update_source_windows_with_line (cursal.symtab, line);
    611  1.1  christos   tui_update_locator_fullname (fullname);
    612  1.1  christos }
    613  1.1  christos 
    614  1.1  christos void
    615  1.1  christos tui_show_assembly (struct gdbarch *gdbarch, CORE_ADDR addr)
    616  1.1  christos {
    617  1.1  christos   tui_add_win_to_layout (DISASSEM_WIN);
    618  1.1  christos   tui_update_source_windows_with_addr (gdbarch, addr);
    619  1.1  christos }
    620  1.1  christos 
    621  1.1  christos int
    622  1.1  christos tui_is_window_visible (enum tui_win_type type)
    623  1.1  christos {
    624  1.1  christos   if (tui_active == 0)
    625  1.1  christos     return 0;
    626  1.1  christos 
    627  1.1  christos   if (tui_win_list[type] == 0)
    628  1.1  christos     return 0;
    629  1.1  christos 
    630  1.1  christos   return tui_win_list[type]->generic.is_visible;
    631  1.1  christos }
    632  1.1  christos 
    633  1.1  christos int
    634  1.1  christos tui_get_command_dimension (unsigned int *width,
    635  1.1  christos 			   unsigned int *height)
    636  1.1  christos {
    637  1.1  christos   if (!tui_active || (TUI_CMD_WIN == NULL))
    638  1.1  christos     {
    639  1.1  christos       return 0;
    640  1.1  christos     }
    641  1.1  christos 
    642  1.1  christos   *width = TUI_CMD_WIN->generic.width;
    643  1.1  christos   *height = TUI_CMD_WIN->generic.height;
    644  1.1  christos   return 1;
    645  1.1  christos }
    646