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