X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Ftui%2Ftui.c;h=a29cf11ad7f5d2b1149308b224808f9cc4b18b28;hb=6ba8e26f707d4fe30bf0ce56f521b7d6509b125b;hp=53b8452df6903a4b8e4b5825de3647222cffc919;hpb=dc9e099fc0eced486ae2b49455c9da113c11f4ff;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/tui/tui.c b/gdb/tui/tui.c index 53b8452df6..a29cf11ad7 100644 --- a/gdb/tui/tui.c +++ b/gdb/tui/tui.c @@ -1,767 +1,484 @@ -/* - ** tui.c - ** General functions for the WDB TUI - */ +/* General functions for the WDB TUI. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ #include #include #include #include -#include #ifdef HAVE_TERM_H #include #endif #include #include +#if 0 #include +#endif #include #include "defs.h" #include "gdbcmd.h" -#include "tui.h" -#include "tuiData.h" -#include "tuiLayout.h" -#include "tuiIO.h" -#include "tuiRegs.h" -#include "tuiWin.h" - -/* The Solaris header files seem to provide no declaration for this at - all when __STDC__ is defined. This shouldn't conflict with - anything. */ -extern char *tgoto (); - -/*********************** -** Local Definitions -************************/ -#define FILEDES 2 -/* Solaris defines CTRL. */ -#ifndef CTRL -#define CTRL(x) (x & ~0140) -#endif -#define CHK(val, dft) (val<=0 ? dft : val) - -#define TOGGLE_USAGE "Usage:toggle breakpoints" -#define TUI_TOGGLE_USAGE "Usage:\ttoggle $fregs\n\ttoggle breakpoints" - -/***************************** -** Local static forward decls -******************************/ -static void _tuiReset PARAMS ((void)); -static void _toggle_command PARAMS ((char *, int)); -static void _tui_vToggle_command PARAMS ((va_list)); -static Opaque _tui_vDo PARAMS ((TuiOpaqueFuncPtr, va_list)); - - - -/*********************** -** Public Functions -************************/ - -/* - ** tuiInit(). - */ -void -#ifdef __STDC__ -tuiInit (char *argv0) +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-layout.h" +#include "tui/tui-io.h" +#include "tui/tui-regs.h" +#include "tui/tui-stack.h" +#include "tui/tui-win.h" +#include "tui/tui-winsource.h" +#include "tui/tui-windata.h" +#include "readline/readline.h" +#include "target.h" +#include "frame.h" +#include "breakpoint.h" +#include "inferior.h" +#include "symtab.h" +#include "source.h" + +#ifdef HAVE_NCURSES_H +#include #else -tuiInit (argv0) - char *argv0; +#ifdef HAVE_CURSES_H +#include #endif -{ - extern void init_page_info (); - extern void initialize_tui_files PARAMS ((void)); - - initialize_tui_files (); - initializeStaticData (); - initscr (); - refresh (); - setTermHeightTo (LINES); - setTermWidthTo (COLS); - tuiInitWindows (); - wrefresh (cmdWin->generic.handle); - init_page_info (); - /* Don't hook debugger output if doing command-window - * the XDB way. However, one thing we do want to do in - * XDB style is set up the scrolling region to be - * the bottom of the screen (tuiTermUnsetup()). - */ - fputs_unfiltered_hook = NULL; - flush_hook = NULL; - rl_initialize (); /* need readline initialization to - * create termcap sequences - */ - tuiTermUnsetup (1, cmdWin->detail.commandInfo.curch); - - return; -} /* tuiInit */ - - -/* - ** tuiInitWindows(). - */ -void -#ifdef __STDC__ -tuiInitWindows (void) -#else -tuiInitWindows () #endif -{ - TuiWinType type; - - tuiSetLocatorContent (0); - showLayout (SRC_COMMAND); - keypad (cmdWin->generic.handle, TRUE); - echo (); - crmode (); - nl (); - tuiSetWinFocusTo (srcWin); - return; -} /* tuiInitWindows */ +/* Tells whether the TUI is active or not. */ +int tui_active = 0; +static int tui_finish_init = 1; +enum tui_key_mode tui_current_key_mode = TUI_COMMAND_MODE; -/* - ** tuiCleanUp(). - ** Kill signal handler and cleanup termination method - */ -void -#ifdef __STDC__ -tuiResetScreen (void) -#else -tuiResetScreen () -#endif +struct tui_char_command { - TuiWinType type = SRC_WIN; - - keypad (cmdWin->generic.handle, FALSE); - for (; type < MAX_MAJOR_WINDOWS; type++) + unsigned char key; + const char* cmd; +}; + +/* Key mapping to gdb commands when the TUI is using the single key mode. */ +static const struct tui_char_command tui_commands[] = { + { 'c', "continue" }, + { 'd', "down" }, + { 'f', "finish" }, + { 'n', "next" }, + { 'r', "run" }, + { 's', "step" }, + { 'u', "up" }, + { 'v', "info locals" }, + { 'w', "where" }, + { 0, 0 }, +}; + +static Keymap tui_keymap; +static Keymap tui_readline_standard_keymap; + +/* TUI readline command. + Switch the output mode between TUI/standard gdb. */ +static int +tui_rl_switch_mode (int notused1, int notused2) +{ + if (tui_active) { - if (m_winPtrNotNull (winList[type]) && - winList[type]->generic.type != UNDEFINED_WIN && - !winList[type]->generic.isVisible) - tuiDelWindow (winList[type]); + tui_disable (); + rl_prep_terminal (0); } - endwin (); - initscr (); - refresh (); - echo (); - crmode (); - nl (); - - return; -} /* tuiResetScreen */ - - -/* - ** tuiCleanUp(). - ** Kill signal handler and cleanup termination method - */ -void -#ifdef __STDC__ -tuiCleanUp (void) -#else -tuiCleanUp () -#endif -{ - char *buffer; - extern char *term_cursor_move; - - signal (SIGINT, SIG_IGN); - tuiTermSetup (0); /* Restore scrolling region to whole screen */ - keypad (cmdWin->generic.handle, FALSE); - freeAllWindows (); - endwin (); - buffer = tgoto (term_cursor_move, 0, termHeight ()); - tputs (buffer, 1, putchar); - _tuiReset (); - - return; -} /* tuiCleanUp */ - - -/* - ** tuiError(). - */ -void -#ifdef __STDC__ -tuiError ( - char *string, - int exitGdb) -#else -tuiError (string, exitGdb) - char *string; - int exitGdb; -#endif -{ - puts_unfiltered (string); - if (exitGdb) + else { - tuiCleanUp (); - exit (-1); + rl_deprep_terminal (); + tui_enable (); } - return; -} /* tuiError */ - + /* Clear the readline in case switching occurred in middle of something. */ + if (rl_end) + rl_kill_text (0, rl_end); + + /* Since we left the curses mode, the terminal mode is restored to + some previous state. That state may not be suitable for readline + to work correctly (it may be restored in line mode). We force an + exit of the current readline so that readline is re-entered and it + will be able to setup the terminal for its needs. By re-entering + in readline, we also redisplay its prompt in the non-curses mode. */ + rl_newline (1, '\n'); + + /* Make sure the \n we are returning does not repeat the last command. */ + dont_repeat (); + return 0; +} -/* - ** tui_vError() - ** tuiError with args in a va_list. - */ -void -#ifdef __STDC__ -tui_vError ( - va_list args) -#else -tui_vError (args) - va_list args; -#endif +/* TUI readline command. + Change the TUI layout to show a next layout. + This function is bound to CTRL-X 2. It is intended to provide + a functionality close to the Emacs split-window command. We always + show two windows (src+asm), (src+regs) or (asm+regs). */ +static int +tui_rl_change_windows (int notused1, int notused2) { - char *string; - int exitGdb; - - string = va_arg (args, char *); - exitGdb = va_arg (args, int); - - tuiError (string, exitGdb); + if (!tui_active) + tui_rl_switch_mode (0/*notused*/, 0/*notused*/); - return; -} /* tui_vError */ - - -/* - ** tuiFree() - ** Wrapper on top of free() to ensure that input address is greater than 0x0 - */ -void -#ifdef __STDC__ -tuiFree ( - char *ptr) -#else -tuiFree (ptr) - char *ptr; -#endif -{ - if (ptr != (char *) NULL) + if (tui_active) { - free (ptr); + enum tui_layout_type new_layout; + enum tui_register_display_type regs_type = TUI_UNDEFINED_REGS; + + new_layout = tui_current_layout (); + + /* Select a new layout to have a rolling layout behavior + with always two windows (except when undefined). */ + switch (new_layout) + { + case SRC_COMMAND: + new_layout = SRC_DISASSEM_COMMAND; + break; + + case DISASSEM_COMMAND: + new_layout = SRC_DISASSEM_COMMAND; + break; + + case SRC_DATA_COMMAND: + new_layout = SRC_DISASSEM_COMMAND; + break; + + case SRC_DISASSEM_COMMAND: + new_layout = DISASSEM_DATA_COMMAND; + break; + + case DISASSEM_DATA_COMMAND: + new_layout = SRC_DATA_COMMAND; + break; + + default: + new_layout = SRC_COMMAND; + break; + } + tui_set_layout (new_layout, regs_type); } + return 0; +} - return; -} /* tuiFree */ - - -/* tuiGetLowDisassemblyAddress(). - ** Determine what the low address will be to display in the TUI's - ** disassembly window. This may or may not be the same as the - ** low address input. - */ -Opaque -#ifdef __STDC__ -tuiGetLowDisassemblyAddress ( - Opaque low, - Opaque pc) -#else -tuiGetLowDisassemblyAddress (low, pc) - Opaque low; - Opaque pc; -#endif +/* TUI readline command. + Delete the second TUI window to only show one. */ +static int +tui_rl_delete_other_windows (int notused1, int notused2) { - int line; - Opaque newLow; + if (!tui_active) + tui_rl_switch_mode (0/*notused*/, 0/*notused*/); - /* - ** Determine where to start the disassembly so that the pc is about in the - ** middle of the viewport. - */ - for (line = 0, newLow = pc; - (newLow > low && - line < (tuiDefaultWinViewportHeight (DISASSEM_WIN, - DISASSEM_COMMAND) / 2));) + if (tui_active) { - bfd_byte buffer[4]; - - newLow -= sizeof (bfd_getb32 (buffer)); - line++; + enum tui_layout_type new_layout; + enum tui_register_display_type regs_type = TUI_UNDEFINED_REGS; + + new_layout = tui_current_layout (); + + /* Kill one window. */ + switch (new_layout) + { + case SRC_COMMAND: + case SRC_DATA_COMMAND: + case SRC_DISASSEM_COMMAND: + default: + new_layout = SRC_COMMAND; + break; + + case DISASSEM_COMMAND: + case DISASSEM_DATA_COMMAND: + new_layout = DISASSEM_COMMAND; + break; + } + tui_set_layout (new_layout, regs_type); } + return 0; +} - return newLow; -} /* tuiGetLowDisassemblyAddress */ - - -/* tui_vGetLowDisassemblyAddress(). - ** Determine what the low address will be to display in the TUI's - ** disassembly window with args in a va_list. - */ -Opaque -#ifdef __STDC__ -tui_vGetLowDisassemblyAddress ( - va_list args) -#else -tui_vGetLowDisassemblyAddress (args) - va_list args; -#endif +/* TUI readline command. + Switch the active window to give the focus to a next window. */ +static int +tui_rl_other_window (int count, int key) { - int line; - Opaque newLow; - Opaque low; - Opaque pc; - - low = va_arg (args, Opaque); - pc = va_arg (args, Opaque); - - return (tuiGetLowDisassemblyAddress (low, pc)); - -} /* tui_vGetLowDisassemblyAddress */ - - -/* - ** tuiDo(). - ** General purpose function to execute a tui function. Transitions - ** between curses and the are handled here. This function is called - ** by non-tui gdb functions. - ** - ** Errors are caught here. - ** If there is no error, the value returned by 'func' is returned. - ** If there is an error, then zero is returned. - ** - ** Must not be called with immediate_quit in effect (bad things might - ** happen, say we got a signal in the middle of a memcpy to quit_return). - ** This is an OK restriction; with very few exceptions immediate_quit can - ** be replaced by judicious use of QUIT. - */ -Opaque -#ifdef __STDC__ -tuiDo ( - TuiOpaqueFuncPtr func,...) -#else -tuiDo (func, va_alist) - TuiOpaqueFuncPtr func; - va_dcl -#endif -{ - extern int terminal_is_ours; - - Opaque ret = (Opaque) NULL; + struct tui_win_info * win_info; - /* It is an error to be tuiDo'ing if we - * don't own the terminal. - */ - if (!terminal_is_ours) - return ret; + if (!tui_active) + tui_rl_switch_mode (0/*notused*/, 0/*notused*/); - if (tui_version) + win_info = tui_next_win (tui_win_with_focus ()); + if (win_info) { - va_list args; - -#ifdef __STDC__ - va_start (args, func); -#else - va_start (args); -#endif - ret = _tui_vDo (func, args); - va_end (args); + tui_set_win_focus_to (win_info); + if (TUI_DATA_WIN && TUI_DATA_WIN->generic.is_visible) + tui_refresh_data_win (); + keypad (TUI_CMD_WIN->generic.handle, (win_info != TUI_CMD_WIN)); } + return 0; +} - return ret; -} /* tuiDo */ - - -/* - ** tuiDoAndReturnToTop(). - ** General purpose function to execute a tui function. Transitions - ** between curses and the are handled here. This function is called - ** by non-tui gdb functions who wish to reset gdb to the top level. - ** After the tuiDo is performed, a return to the top level occurs. - ** - ** Errors are caught here. - ** If there is no error, the value returned by 'func' is returned. - ** If there is an error, then zero is returned. - ** - ** Must not be called with immediate_quit in effect (bad things might - ** happen, say we got a signal in the middle of a memcpy to quit_return). - ** This is an OK restriction; with very few exceptions immediate_quit can - ** be replaced by judicious use of QUIT. - ** - */ -Opaque -#ifdef __STDC__ -tuiDoAndReturnToTop ( - TuiOpaqueFuncPtr func,...) -#else -tuiDoAndReturnToTop (func, va_alist) - TuiOpaqueFuncPtr func; - va_dcl -#endif +/* TUI readline command. + Execute the gdb command bound to the specified key. */ +static int +tui_rl_command_key (int count, int key) { - extern int terminal_is_ours; - - Opaque ret = (Opaque) NULL; - - /* It is an error to be tuiDo'ing if we - * don't own the terminal. - */ - if (!terminal_is_ours) - return ret; + int i; - if (tui_version) + reinitialize_more_filter (); + for (i = 0; tui_commands[i].cmd; i++) { - va_list args; - -#ifdef __STDC__ - va_start (args, func); -#else - va_start (args); -#endif - ret = _tui_vDo (func, args); - - /* force a return to the top level */ - return_to_top_level (RETURN_ERROR); + if (tui_commands[i].key == key) + { + /* Must save the command because it can be modified + by execute_command. */ + char* cmd = alloca (strlen (tui_commands[i].cmd) + 1); + strcpy (cmd, tui_commands[i].cmd); + execute_command (cmd, TRUE); + return 0; + } } + return 0; +} - return ret; -} /* tuiDoAndReturnToTop */ - - -void -#ifdef __STDC__ -tui_vSelectSourceSymtab ( - va_list args) -#else -tui_vSelectSourceSymtab (args) - va_list args; -#endif -{ - struct symtab *s = va_arg (args, struct symtab *); - - select_source_symtab (s); - return; -} /* tui_vSelectSourceSymtab */ - - -/* - ** _initialize_tui(). - ** Function to initialize gdb commands, for tui window manipulation. - */ -void -_initialize_tui () +/* TUI readline command. + Temporarily leave the TUI SingleKey mode to allow editing + a gdb command with the normal readline. Once the command + is executed, the TUI SingleKey mode is installed back. */ +static int +tui_rl_command_mode (int count, int key) { -#if 0 - if (tui_version) - { - add_com ("toggle", class_tui, _toggle_command, - "Toggle Terminal UI Features\n\ -Usage: Toggle $fregs\n\ -\tToggles between single and double precision floating point registers.\n"); - } -#endif - char *helpStr; + tui_set_key_mode (TUI_ONE_COMMAND_MODE); + return rl_insert (count, key); +} - if (tui_version) - helpStr = "Toggle Specified Features\n\ -Usage:\ttoggle $fregs\n\ttoggle breakpoints"; - else - helpStr = "Toggle Specified Features\nUsage:toggle breakpoints"; - add_abbrev_prefix_cmd ("toggle", - class_tui, - _toggle_command, - helpStr, - &togglelist, - "toggle ", - 1, - &cmdlist); -} /* _initialize_tui */ - - -/* - ** va_catch_errors(). - ** General purpose function to execute a function, catching errors. - ** If there is no error, the value returned by 'func' is returned. - ** If there is error, then zero is returned. - ** Note that 'func' must take a variable argument list as well. - ** - ** Must not be called with immediate_quit in effect (bad things might - ** happen, say we got a signal in the middle of a memcpy to quit_return). - ** This is an OK restriction; with very few exceptions immediate_quit can - ** be replaced by judicious use of QUIT. - */ -Opaque -#ifdef __STDC__ -va_catch_errors ( - TuiOpaqueFuncPtr func, - va_list args) -#else -va_catch_errors (func, args) - TuiOpaqueFuncPtr func; - va_list args; -#endif +/* TUI readline command. + Switch between TUI SingleKey mode and gdb readline editing. */ +static int +tui_rl_next_keymap (int notused1, int notused2) { - Opaque ret = (Opaque) NULL; + if (!tui_active) + tui_rl_switch_mode (0/*notused*/, 0/*notused*/); - /* - ** We could have used catch_errors(), but it doesn't handle variable args. - ** Also, for the tui, we always want to catch all errors, so we don't - ** need to pass a mask, or an error string. - */ - jmp_buf saved_error; - jmp_buf saved_quit; - jmp_buf tmp_jmp; - struct cleanup *saved_cleanup_chain; - char *saved_error_pre_print; - char *saved_quit_pre_print; - extern jmp_buf error_return; - extern jmp_buf quit_return; - - saved_cleanup_chain = save_cleanups (); - saved_error_pre_print = error_pre_print; - saved_quit_pre_print = quit_pre_print; - - memcpy ((char *) saved_error, (char *) error_return, sizeof (jmp_buf)); - error_pre_print = ""; - memcpy (saved_quit, quit_return, sizeof (jmp_buf)); - quit_pre_print = ""; - - if (setjmp (tmp_jmp) == 0) - { - va_list argList = args; - memcpy (error_return, tmp_jmp, sizeof (jmp_buf)); - memcpy (quit_return, tmp_jmp, sizeof (jmp_buf)); - ret = func (argList); - } - restore_cleanups (saved_cleanup_chain); - memcpy (error_return, saved_error, sizeof (jmp_buf)); - error_pre_print = saved_error_pre_print; - memcpy (quit_return, saved_quit, sizeof (jmp_buf)); - quit_pre_print = saved_quit_pre_print; - - return ret; + tui_set_key_mode (tui_current_key_mode == TUI_COMMAND_MODE + ? TUI_SINGLE_KEY_MODE : TUI_COMMAND_MODE); + return 0; } -/* - ** vcatch_errors(). - ** Catch errors occurring in tui or non tui function, handling - ** variable param lists. Note that 'func' must take a variable - ** argument list as well. - */ -Opaque -#ifdef __STDC__ -vcatch_errors ( - OpaqueFuncPtr func,...) -#else -vcatch_errors (va_alist) - va_dcl -/* - vcatch_errors(func, va_alist) - OpaqueFuncPtr func; - va_dcl - */ -#endif +/* Readline hook to redisplay ourself the gdb prompt. + In the SingleKey mode, the prompt is not printed so that + the command window is cleaner. It will be displayed if + we temporarily leave the SingleKey mode. */ +static int +tui_rl_startup_hook () { - Opaque ret = (Opaque) NULL; - va_list args; -#ifdef __STDC__ - va_start (args, func); -/* - va_arg(args, OpaqueFuncPtr); - */ -#else - OpaqueFuncPtr func; - - va_start (args); - func = va_arg (args, OpaqueFuncPtr); -#endif - ret = va_catch_errors (func, args); - va_end (args); - - return ret; + rl_already_prompted = 1; + if (tui_current_key_mode != TUI_COMMAND_MODE) + tui_set_key_mode (TUI_SINGLE_KEY_MODE); + tui_redisplay_readline (); + return 0; } - +/* Change the TUI key mode by installing the appropriate readline keymap. */ void -#ifdef __STDC__ -strcat_to_buf ( - char *buf, - int buflen, - char *itemToAdd) -#else -strcat_to_buf (buf, buflen, itemToAdd) - char *buf; - int buflen; - char *itemToAdd; -#endif +tui_set_key_mode (enum tui_key_mode mode) { - if (itemToAdd != (char *) NULL && buf != (char *) NULL) - { - if ((strlen (buf) + strlen (itemToAdd)) <= buflen) - strcat (buf, itemToAdd); - else - strncat (buf, itemToAdd, (buflen - strlen (buf))); - } - - return; -} /* strcat_to_buf */ + tui_current_key_mode = mode; + rl_set_keymap (mode == TUI_SINGLE_KEY_MODE + ? tui_keymap : tui_readline_standard_keymap); + tui_show_locator_content (); +} -/* VARARGS */ +/* Initialize readline and configure the keymap for the switching + key shortcut. */ void -#ifdef ANSI_PROTOTYPES -strcat_to_buf_with_fmt ( - char *buf, - int bufLen, - char *format,...) -#else -strcat_to_buf_with_fmt (va_alist) - va_dcl -#endif +tui_initialize_readline () { - char *linebuffer; - struct cleanup *old_cleanups; - va_list args; -#ifdef ANSI_PROTOTYPES - va_start (args, format); -#else - char *buf; - int bufLen; - char *format; - - va_start (args); - buf = va_arg (args, char *); - bufLen = va_arg (args, int); - format = va_arg (args, char *); -#endif - vasprintf (&linebuffer, format, args); - old_cleanups = make_cleanup (free, linebuffer); - strcat_to_buf (buf, bufLen, linebuffer); - do_cleanups (old_cleanups); - va_end (args); -} + int i; + Keymap tui_ctlx_keymap; + rl_initialize (); + rl_add_defun ("tui-switch-mode", tui_rl_switch_mode, -1); + rl_add_defun ("gdb-command", tui_rl_command_key, -1); + rl_add_defun ("next-keymap", tui_rl_next_keymap, -1); + tui_keymap = rl_make_bare_keymap (); + tui_ctlx_keymap = rl_make_bare_keymap (); + tui_readline_standard_keymap = rl_get_keymap (); + for (i = 0; tui_commands[i].cmd; i++) + rl_bind_key_in_map (tui_commands[i].key, tui_rl_command_key, tui_keymap); -/*********************** -** Static Functions -************************/ + rl_generic_bind (ISKMAP, "\\C-x", (char*) tui_ctlx_keymap, tui_keymap); + /* Bind all other keys to tui_rl_command_mode so that we switch + temporarily from SingleKey mode and can enter a gdb command. */ + for (i = ' '; i < 0x7f; i++) + { + int j; -/* - ** _tui_vDo(). - ** General purpose function to execute a tui function. Transitions - ** between curses and the are handled here. This function is called - ** by non-tui gdb functions. - ** - ** Errors are caught here. - ** If there is no error, the value returned by 'func' is returned. - ** If there is an error, then zero is returned. - ** - ** Must not be called with immediate_quit in effect (bad things might - ** happen, say we got a signal in the middle of a memcpy to quit_return). - ** This is an OK restriction; with very few exceptions immediate_quit can - ** be replaced by judicious use of QUIT. - */ -static Opaque -#ifdef __STDC__ -_tui_vDo ( - TuiOpaqueFuncPtr func, - va_list args) -#else -_tui_vDo (func, args) - TuiOpaqueFuncPtr func; - va_list args; -#endif -{ - extern int terminal_is_ours; + for (j = 0; tui_commands[j].cmd; j++) + if (tui_commands[j].key == i) + break; - Opaque ret = (Opaque) NULL; + if (tui_commands[j].cmd) + continue; - /* It is an error to be tuiDo'ing if we - * don't own the terminal. - */ - if (!terminal_is_ours) - return ret; + rl_bind_key_in_map (i, tui_rl_command_mode, tui_keymap); + } - if (tui_version) - { - /* If doing command window the "XDB way" (command window - * is unmanaged by curses... - */ - /* Set up terminal for TUI */ - tuiTermSetup (1); + rl_bind_key_in_map ('a', tui_rl_switch_mode, emacs_ctlx_keymap); + rl_bind_key_in_map ('a', tui_rl_switch_mode, tui_ctlx_keymap); + rl_bind_key_in_map ('A', tui_rl_switch_mode, emacs_ctlx_keymap); + rl_bind_key_in_map ('A', tui_rl_switch_mode, tui_ctlx_keymap); + rl_bind_key_in_map (CTRL ('A'), tui_rl_switch_mode, emacs_ctlx_keymap); + rl_bind_key_in_map (CTRL ('A'), tui_rl_switch_mode, tui_ctlx_keymap); + rl_bind_key_in_map ('1', tui_rl_delete_other_windows, emacs_ctlx_keymap); + rl_bind_key_in_map ('1', tui_rl_delete_other_windows, tui_ctlx_keymap); + rl_bind_key_in_map ('2', tui_rl_change_windows, emacs_ctlx_keymap); + rl_bind_key_in_map ('2', tui_rl_change_windows, tui_ctlx_keymap); + rl_bind_key_in_map ('o', tui_rl_other_window, emacs_ctlx_keymap); + rl_bind_key_in_map ('o', tui_rl_other_window, tui_ctlx_keymap); + rl_bind_key_in_map ('q', tui_rl_next_keymap, tui_keymap); + rl_bind_key_in_map ('s', tui_rl_next_keymap, emacs_ctlx_keymap); + rl_bind_key_in_map ('s', tui_rl_next_keymap, tui_ctlx_keymap); +} - ret = va_catch_errors (func, args); +/* Enter in the tui mode (curses). + When in normal mode, it installs the tui hooks in gdb, redirects + the gdb output, configures the readline to work in tui mode. + When in curses mode, it does nothing. */ +void +tui_enable (void) +{ + if (tui_active) + return; - /* Set up terminal for command window */ - tuiTermUnsetup (1, cmdWin->detail.commandInfo.curch); + /* To avoid to initialize curses when gdb starts, there is a defered + curses initialization. This initialization is made only once + and the first time the curses mode is entered. */ + if (tui_finish_init) + { + WINDOW *w; + + w = initscr (); + + cbreak (); + noecho (); + /*timeout (1);*/ + nodelay(w, FALSE); + nl(); + keypad (w, TRUE); + rl_initialize (); + tui_set_term_height_to (LINES); + tui_set_term_width_to (COLS); + def_prog_mode (); + + tui_show_frame_info (0); + tui_set_layout (SRC_COMMAND, TUI_UNDEFINED_REGS); + tui_set_win_focus_to (TUI_SRC_WIN); + keypad (TUI_CMD_WIN->generic.handle, TRUE); + wrefresh (TUI_CMD_WIN->generic.handle); + tui_finish_init = 0; } + else + { + /* Save the current gdb setting of the terminal. + Curses will restore this state when endwin() is called. */ + def_shell_mode (); + clearok (stdscr, TRUE); + } + + /* Install the TUI specific hooks. */ + tui_install_hooks (); + rl_startup_hook = tui_rl_startup_hook; + + tui_update_variables (); + + tui_setup_io (1); + + tui_active = 1; + if (deprecated_selected_frame) + tui_show_frame_info (deprecated_selected_frame); + + /* Restore TUI keymap. */ + tui_set_key_mode (tui_current_key_mode); + tui_refresh_all_win (); + + /* Update gdb's knowledge of its terminal. */ + target_terminal_save_ours (); + tui_update_gdb_sizes (); +} - return ret; -} /* _tui_vDo */ +/* Leave the tui mode. + Remove the tui hooks and configure the gdb output and readline + back to their original state. The curses mode is left so that + the terminal setting is restored to the point when we entered. */ +void +tui_disable (void) +{ + if (!tui_active) + return; + /* Restore initial readline keymap. */ + rl_set_keymap (tui_readline_standard_keymap); -static void -#ifdef __STDC__ -_toggle_command ( - char *arg, - int fromTTY) -#else -_toggle_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - printf_filtered ("Specify feature to toggle.\n%s\n", - (tui_version) ? TUI_TOGGLE_USAGE : TOGGLE_USAGE); -/* - tuiDo((TuiOpaqueFuncPtr)_Toggle_command, arg, fromTTY); - */ -} + /* Remove TUI hooks. */ + tui_remove_hooks (); + rl_startup_hook = 0; + rl_already_prompted = 0; -/* - ** _tui_vToggle_command(). - */ -static void -#ifdef __STDC__ -_tui_vToggle_command ( - va_list args) -#else -_tui_vToggle_command (args) - va_list args; -#endif -{ - char *arg; - int fromTTY; + /* Leave curses and restore previous gdb terminal setting. */ + endwin (); - arg = va_arg (args, char *); + /* gdb terminal has changed, update gdb internal copy of it + so that terminal management with the inferior works. */ + tui_setup_io (0); - if (arg == (char *) NULL) - printf_filtered (TOGGLE_USAGE); - else - { - char *ptr = (char *) tuiStrDup (arg); - int i; + /* Update gdb's knowledge of its terminal. */ + target_terminal_save_ours (); - for (i = 0; (ptr[i]); i++) - ptr[i] = toupper (arg[i]); + tui_active = 0; + tui_update_gdb_sizes (); +} - if (subsetCompare (ptr, TUI_FLOAT_REGS_NAME)) - tuiToggleFloatRegs (); -/* else if (subsetCompare(ptr, "ANOTHER TOGGLE OPTION")) - ... - */ +void +strcat_to_buf (char *buf, int buflen, const char *item_to_add) +{ + if (item_to_add != (char *) NULL && buf != (char *) NULL) + { + if ((strlen (buf) + strlen (item_to_add)) <= buflen) + strcat (buf, item_to_add); else - printf_filtered (TOGGLE_USAGE); - tuiFree (ptr); + strncat (buf, item_to_add, (buflen - strlen (buf))); } +} - return; -} /* _tuiToggle_command */ +#if 0 +/* Solaris defines CTRL. */ +#ifndef CTRL +#define CTRL(x) (x & ~0140) +#endif +#define FILEDES 2 +#define CHK(val, dft) (val<=0 ? dft : val) static void -#ifdef __STDC__ -_tuiReset (void) -#else -_tuiReset () -#endif +tui_reset (void) { struct termio mode; @@ -827,4 +544,48 @@ _tuiReset () #endif /* USG */ return; -} /* _tuiReset */ +} +#endif + +void +tui_show_source (const char *file, int line) +{ + struct symtab_and_line cursal = get_current_source_symtab_and_line (); + /* make sure that the source window is displayed */ + tui_add_win_to_layout (SRC_WIN); + + tui_update_source_windows_with_line (cursal.symtab, line); + tui_update_locator_filename (file); +} + +void +tui_show_assembly (CORE_ADDR addr) +{ + tui_add_win_to_layout (DISASSEM_WIN); + tui_update_source_windows_with_addr (addr); +} + +int +tui_is_window_visible (enum tui_win_type type) +{ + if (tui_active == 0) + return 0; + + if (tui_win_list[type] == 0) + return 0; + + return tui_win_list[type]->generic.is_visible; +} + +int +tui_get_command_dimension (int *width, int *height) +{ + if (!tui_active || (TUI_CMD_WIN == NULL)) + { + return 0; + } + + *width = TUI_CMD_WIN->generic.width; + *height = TUI_CMD_WIN->generic.height; + return 1; +}