2004-01-18 Michael Chastain <mec.gnu@mindspring.com>
[deliverable/binutils-gdb.git] / gdb / tui / tuiWin.c
index 07555e53964b613d08c5dd13435894139c943f70..ecd4920601b797c6dddfe1398daefa1682b8f71f 100644 (file)
@@ -1,5 +1,8 @@
 /* TUI window generic functions.
-   Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+   Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation,
+   Inc.
+
    Contributed by Hewlett-Packard Company.
 
    This file is part of GDB.
 
    Author: Susan B. Macchia  */
 
-#include <string.h>
-#include <ctype.h>
 #include "defs.h"
 #include "command.h"
 #include "symtab.h"
 #include "breakpoint.h"
 #include "frame.h"
 #include "cli/cli-cmds.h"
+#include "top.h"
+#include "source.h"
 
 #include "tui.h"
 #include "tuiData.h"
 #include "tuiSourceWin.h"
 #include "tuiDataWin.h"
 
-/*******************************
-** External Declarations
-********************************/
-extern void init_page_info ();
+#ifdef HAVE_NCURSES_H       
+#include <ncurses.h>
+#else
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+#endif
+
+#include <string.h>
+#include <ctype.h>
+#include <readline/readline.h>
 
 /*******************************
 ** Static Local Decls
@@ -79,6 +89,213 @@ static void _parseScrollingArgs (char *, TuiWinInfoPtr *, int *);
 ** PUBLIC FUNCTIONS
 ***************************************/
 
+#ifndef ACS_LRCORNER
+#  define ACS_LRCORNER '+'
+#endif
+#ifndef ACS_LLCORNER
+#  define ACS_LLCORNER '+'
+#endif
+#ifndef ACS_ULCORNER
+#  define ACS_ULCORNER '+'
+#endif
+#ifndef ACS_URCORNER
+#  define ACS_URCORNER '+'
+#endif
+#ifndef ACS_HLINE
+#  define ACS_HLINE '-'
+#endif
+#ifndef ACS_VLINE
+#  define ACS_VLINE '|'
+#endif
+
+/* Possible values for tui-border-kind variable.  */
+static const char *tui_border_kind_enums[] = {
+  "space",
+  "ascii",
+  "acs",
+  NULL
+};
+
+/* Possible values for tui-border-mode and tui-active-border-mode.  */
+static const char *tui_border_mode_enums[] = {
+  "normal",
+  "standout",
+  "reverse",
+  "half",
+  "half-standout",
+  "bold",
+  "bold-standout",
+  NULL
+};
+
+struct tui_translate
+{
+  const char *name;
+  int value;
+};
+
+/* Translation table for border-mode variables.
+   The list of values must be terminated by a NULL.
+   After the NULL value, an entry defines the default.  */
+struct tui_translate tui_border_mode_translate[] = {
+  { "normal",          A_NORMAL },
+  { "standout",                A_STANDOUT },
+  { "reverse",         A_REVERSE },
+  { "half",            A_DIM },
+  { "half-standout",   A_DIM | A_STANDOUT },
+  { "bold",            A_BOLD },
+  { "bold-standout",   A_BOLD | A_STANDOUT },
+  { 0, 0 },
+  { "normal",          A_NORMAL }
+};
+
+/* Translation tables for border-kind, one for each border
+   character (see wborder, border curses operations).
+   -1 is used to indicate the ACS because ACS characters
+   are determined at run time by curses (depends on terminal).  */
+struct tui_translate tui_border_kind_translate_vline[] = {
+  { "space",    ' ' },
+  { "ascii",    '|' },
+  { "acs",      -1 },
+  { 0, 0 },
+  { "ascii",    '|' }
+};
+
+struct tui_translate tui_border_kind_translate_hline[] = {
+  { "space",    ' ' },
+  { "ascii",    '-' },
+  { "acs",      -1 },
+  { 0, 0 },
+  { "ascii",    '-' }
+};
+
+struct tui_translate tui_border_kind_translate_ulcorner[] = {
+  { "space",    ' ' },
+  { "ascii",    '+' },
+  { "acs",      -1 },
+  { 0, 0 },
+  { "ascii",    '+' }
+};
+
+struct tui_translate tui_border_kind_translate_urcorner[] = {
+  { "space",    ' ' },
+  { "ascii",    '+' },
+  { "acs",      -1 },
+  { 0, 0 },
+  { "ascii",    '+' }
+};
+
+struct tui_translate tui_border_kind_translate_llcorner[] = {
+  { "space",    ' ' },
+  { "ascii",    '+' },
+  { "acs",      -1 },
+  { 0, 0 },
+  { "ascii",    '+' }
+};
+
+struct tui_translate tui_border_kind_translate_lrcorner[] = {
+  { "space",    ' ' },
+  { "ascii",    '+' },
+  { "acs",      -1 },
+  { 0, 0 },
+  { "ascii",    '+' }
+};
+
+
+/* Tui configuration variables controlled with set/show command.  */
+const char *tui_active_border_mode = "bold-standout";
+const char *tui_border_mode = "normal";
+const char *tui_border_kind = "acs";
+
+/* Tui internal configuration variables.  These variables are
+   updated by tui_update_variables to reflect the tui configuration
+   variables.  */
+chtype tui_border_vline;
+chtype tui_border_hline;
+chtype tui_border_ulcorner;
+chtype tui_border_urcorner;
+chtype tui_border_llcorner;
+chtype tui_border_lrcorner;
+
+int tui_border_attrs;
+int tui_active_border_attrs;
+
+/* Identify the item in the translation table.
+   When the item is not recognized, use the default entry.  */
+static struct tui_translate *
+translate (const char *name, struct tui_translate *table)
+{
+  while (table->name)
+    {
+      if (name && strcmp (table->name, name) == 0)
+        return table;
+      table++;
+    }
+
+  /* Not found, return default entry.  */
+  table++;
+  return table;
+}
+
+/* Update the tui internal configuration according to gdb settings.
+   Returns 1 if the configuration has changed and the screen should
+   be redrawn.  */
+int
+tui_update_variables ()
+{
+  int need_redraw = 0;
+  struct tui_translate *entry;
+
+  entry = translate (tui_border_mode, tui_border_mode_translate);
+  if (tui_border_attrs != entry->value)
+    {
+      tui_border_attrs = entry->value;
+      need_redraw = 1;
+    }
+  entry = translate (tui_active_border_mode, tui_border_mode_translate);
+  if (tui_active_border_attrs != entry->value)
+    {
+      tui_active_border_attrs = entry->value;
+      need_redraw = 1;
+    }
+
+  /* If one corner changes, all characters are changed.
+     Only check the first one.  The ACS characters are determined at
+     run time by curses terminal management.  */
+  entry = translate (tui_border_kind, tui_border_kind_translate_lrcorner);
+  if (tui_border_lrcorner != (chtype) entry->value)
+    {
+      tui_border_lrcorner = (entry->value < 0) ? ACS_LRCORNER : entry->value;
+      need_redraw = 1;
+    }
+  entry = translate (tui_border_kind, tui_border_kind_translate_llcorner);
+  tui_border_llcorner = (entry->value < 0) ? ACS_LLCORNER : entry->value;
+
+  entry = translate (tui_border_kind, tui_border_kind_translate_ulcorner);
+  tui_border_ulcorner = (entry->value < 0) ? ACS_ULCORNER : entry->value;
+
+  entry = translate (tui_border_kind, tui_border_kind_translate_urcorner);
+  tui_border_urcorner = (entry->value < 0) ? ACS_URCORNER : entry->value;
+
+  entry = translate (tui_border_kind, tui_border_kind_translate_hline);
+  tui_border_hline = (entry->value < 0) ? ACS_HLINE : entry->value;
+
+  entry = translate (tui_border_kind, tui_border_kind_translate_vline);
+  tui_border_vline = (entry->value < 0) ? ACS_VLINE : entry->value;
+
+  return need_redraw;
+}
+
+static void
+set_tui_cmd (char *args, int from_tty)
+{
+}
+
+static void
+show_tui_cmd (char *args, int from_tty)
+{
+}
+
 /*
    ** _initialize_tuiWin().
    **        Function to initialize gdb commands, for tui window manipulation.
@@ -86,13 +303,25 @@ static void _parseScrollingArgs (char *, TuiWinInfoPtr *, int *);
 void
 _initialize_tuiWin (void)
 {
+  struct cmd_list_element *c;
+  static struct cmd_list_element *tui_setlist;
+  static struct cmd_list_element *tui_showlist;
+
   /* Define the classes of commands.
      They will appear in the help list in the reverse of this order.  */
-
-  add_cmd ("tui", class_tui, NO_FUNCTION,
+  add_cmd ("tui", class_tui, NULL,
           "Text User Interface commands.",
           &cmdlist);
 
+  add_prefix_cmd ("tui", class_tui, set_tui_cmd,
+                  "TUI configuration variables",
+                 &tui_setlist, "set tui ",
+                 0/*allow-unknown*/, &setlist);
+  add_prefix_cmd ("tui", class_tui, show_tui_cmd,
+                  "TUI configuration variables",
+                 &tui_showlist, "show tui ",
+                 0/*allow-unknown*/, &showlist);
+
   add_com ("refresh", class_tui, _tuiRefreshAll_command,
            "Refresh the terminal display.\n");
   if (xdb_commands)
@@ -132,38 +361,66 @@ cmd  : the command window\n");
     add_com ("w", class_xdb, _tuiXDBsetWinHeight_command,
              "XDB compatibility command for setting the height of a command window.\n\
 Usage: w <#lines>\n");
-}
-
-
-/*
-   ** tuiClearWinFocusFrom
-   **        Clear the logical focus from winInfo
- */
-void
-tuiClearWinFocusFrom (TuiWinInfoPtr winInfo)
-{
-  if (m_winPtrNotNull (winInfo))
-    {
-      if (winInfo->generic.type != CMD_WIN)
-       unhighlightWin (winInfo);
-      tuiSetWinWithFocus ((TuiWinInfoPtr) NULL);
-    }
-
-  return;
-}                              /* tuiClearWinFocusFrom */
 
+  /* Define the tui control variables.  */
+  c = add_set_enum_cmd
+    ("border-kind", no_class,
+     tui_border_kind_enums, &tui_border_kind,
+     "Set the kind of border for TUI windows.\n"
+     "This variable controls the border of TUI windows:\n"
+     "space           use a white space\n"
+     "ascii           use ascii characters + - | for the border\n"
+     "acs             use the Alternate Character Set\n",
+     &tui_setlist);
+  add_show_from_set (c, &tui_showlist);
+
+  c = add_set_enum_cmd
+    ("border-mode", no_class,
+     tui_border_mode_enums, &tui_border_mode,
+     "Set the attribute mode to use for the TUI window borders.\n"
+     "This variable controls the attributes to use for the window borders:\n"
+     "normal          normal display\n"
+     "standout        use highlight mode of terminal\n"
+     "reverse         use reverse video mode\n"
+     "half            use half bright\n"
+     "half-standout   use half bright and standout mode\n"
+     "bold            use extra bright or bold\n"
+     "bold-standout   use extra bright or bold with standout mode\n",
+     &tui_setlist);
+  add_show_from_set (c, &tui_showlist);
+
+  c = add_set_enum_cmd
+    ("active-border-mode", no_class,
+     tui_border_mode_enums, &tui_active_border_mode,
+     "Set the attribute mode to use for the active TUI window border.\n"
+     "This variable controls the attributes to use for the active window border:\n"
+     "normal          normal display\n"
+     "standout        use highlight mode of terminal\n"
+     "reverse         use reverse video mode\n"
+     "half            use half bright\n"
+     "half-standout   use half bright and standout mode\n"
+     "bold            use extra bright or bold\n"
+     "bold-standout   use extra bright or bold with standout mode\n",
+     &tui_setlist);
+  add_show_from_set (c, &tui_showlist);
+}
 
-/*
-   ** tuiClearWinFocus().
-   **        Clear the window that has focus.
- */
+/* Update gdb's knowledge of the terminal size.  */
 void
-tuiClearWinFocus (void)
+tui_update_gdb_sizes ()
 {
-  tuiClearWinFocusFrom (tuiWinWithFocus ());
-
-  return;
-}                              /* tuiClearWinFocus */
+  char cmd[50];
+  int screenheight, screenwidth;
+
+  rl_get_screen_size (&screenheight, &screenwidth);
+  /* Set to TUI command window dimension or use readline values.  */
+  sprintf (cmd, "set width %d",
+           tui_active ? cmdWin->generic.width : screenwidth);
+  execute_command (cmd, 0);
+  sprintf (cmd, "set height %d",
+           tui_active ? cmdWin->generic.height : screenheight);
+  execute_command (cmd, 0);
+}
 
 
 /*
@@ -335,6 +592,7 @@ tuiRefreshAll (void)
 {
   TuiWinType type;
 
+  clearok (curscr, TRUE);
   refreshAll (winList);
   for (type = SRC_WIN; type < MAX_MAJOR_WINDOWS; type++)
     {
@@ -344,9 +602,6 @@ tuiRefreshAll (void)
            {
            case SRC_WIN:
            case DISASSEM_WIN:
-             tuiClearWin (&winList[type]->generic);
-             if (winList[type]->detail.sourceInfo.hasLocator)
-               tuiClearLocatorDisplay ();
              tuiShowSourceContent (winList[type]);
              checkAndDisplayHighlightIfNeeded (winList[type]);
              tuiEraseExecInfoContent (winList[type]);
@@ -360,11 +615,8 @@ tuiRefreshAll (void)
            }
        }
     }
-  tuiClearLocatorDisplay ();
   tuiShowLocatorContent ();
-
-  return;
-}                              /* tuiRefreshAll */
+}
 
 
 /*
@@ -376,8 +628,9 @@ void
 tuiResizeAll (void)
 {
   int heightDiff, widthDiff;
-  extern int screenheight, screenwidth;                /* in readline */
+  int screenheight, screenwidth;
 
+  rl_get_screen_size (&screenheight, &screenwidth);
   widthDiff = screenwidth - termWidth ();
   heightDiff = screenheight - termHeight ();
   if (heightDiff || widthDiff)
@@ -387,12 +640,12 @@ tuiResizeAll (void)
       TuiWinInfoPtr firstWin, secondWin;
       TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
       TuiWinType winType;
-      int i, newHeight, splitDiff, cmdSplitDiff, numWinsDisplayed = 2;
+      int newHeight, splitDiff, cmdSplitDiff, numWinsDisplayed = 2;
 
       /* turn keypad off while we resize */
       if (winWithFocus != cmdWin)
        keypad (cmdWin->generic.handle, FALSE);
-      init_page_info ();
+      tui_update_gdb_sizes ();
       setTermHeightTo (screenheight);
       setTermWidthTo (screenwidth);
       if (curLayout == SRC_DISASSEM_COMMAND ||
@@ -690,7 +943,7 @@ _tuiAllWindowsInfo (char *arg, int fromTTY)
   TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
 
   for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++)
-    if (winList[type]->generic.isVisible)
+    if (winList[type] && winList[type]->generic.isVisible)
       {
        if (winWithFocus == winList[type])
          printf_filtered ("        %s\t(%d lines)  <has focus>\n",
@@ -813,7 +1066,7 @@ The window name specified must be valid and visible.\n");
                        warning ("Invalid window height specified.\n%s",
                                 WIN_HEIGHT_USAGE);
                      else
-                       init_page_info ();
+                        tui_update_gdb_sizes ();
                    }
                  else
                    warning ("Invalid window height specified.\n%s",
@@ -905,7 +1158,7 @@ _tuiAdjustWinHeights (TuiWinInfoPtr primaryWinInfo, int newHeight)
       status = TUI_SUCCESS;
       if (newHeight != primaryWinInfo->generic.height)
        {
-         int i, diff;
+         int diff;
          TuiWinInfoPtr winInfo;
          TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
          TuiLayoutType curLayout = currentLayout ();
@@ -1053,7 +1306,6 @@ static void
 _makeInvisibleAndSetNewHeight (TuiWinInfoPtr winInfo, int height)
 {
   int i;
-  struct symtab *s;
   TuiGenWinInfoPtr genWinInfo;
 
 
@@ -1102,9 +1354,7 @@ _makeInvisibleAndSetNewHeight (TuiWinInfoPtr winInfo, int height)
     default:
       break;
     }
-
-  return;
-}                              /* _makeInvisibleAndSetNewHeight */
+}
 
 
 /*
@@ -1116,7 +1366,6 @@ _makeInvisibleAndSetNewHeight (TuiWinInfoPtr winInfo, int height)
 static void
 _makeVisibleWithNewHeight (TuiWinInfoPtr winInfo)
 {
-  int i;
   struct symtab *s;
 
   m_beVisible (&winInfo->generic);
@@ -1130,6 +1379,8 @@ _makeVisibleWithNewHeight (TuiWinInfoPtr winInfo)
       if (winInfo->generic.content != (OpaquePtr) NULL)
        {
          TuiLineOrAddress lineOrAddr;
+         struct symtab_and_line cursal
+           = get_current_source_symtab_and_line ();
 
          if (winInfo->generic.type == SRC_WIN)
            lineOrAddr.lineNo =
@@ -1139,26 +1390,26 @@ _makeVisibleWithNewHeight (TuiWinInfoPtr winInfo)
              winInfo->detail.sourceInfo.startLineOrAddr.addr;
          freeWinContent (&winInfo->generic);
          tuiUpdateSourceWindow (winInfo,
-                                current_source_symtab, lineOrAddr, TRUE);
+                                cursal.symtab, lineOrAddr, TRUE);
        }
-      else if (selected_frame != (struct frame_info *) NULL)
+      else if (deprecated_selected_frame != (struct frame_info *) NULL)
        {
          TuiLineOrAddress line;
-         extern int current_source_line;
+         struct symtab_and_line cursal = get_current_source_symtab_and_line ();
+
 
-         s = find_pc_symtab (selected_frame->pc);
+         s = find_pc_symtab (get_frame_pc (deprecated_selected_frame));
          if (winInfo->generic.type == SRC_WIN)
-           line.lineNo = current_source_line;
+           line.lineNo = cursal.line;
          else
            {
-             find_line_pc (s, current_source_line, &line.addr);
+             find_line_pc (s, cursal.line, &line.addr);
            }
          tuiUpdateSourceWindow (winInfo, s, line, TRUE);
        }
       if (m_hasLocator (winInfo))
        {
          m_beVisible (locatorWinInfoPtr ());
-         tuiClearLocatorDisplay ();
          tuiShowLocatorContent ();
        }
       break;
@@ -1187,7 +1438,7 @@ _newHeightOk (TuiWinInfoPtr primaryWinInfo, int newHeight)
 
   if (ok)
     {
-      int diff, curHeight;
+      int diff;
       TuiLayoutType curLayout = currentLayout ();
 
       diff = (newHeight - primaryWinInfo->generic.height) * (-1);
@@ -1213,7 +1464,7 @@ _newHeightOk (TuiWinInfoPtr primaryWinInfo, int newHeight)
        }
       else
        {
-         int curTotalHeight, totalHeight, minHeight;
+         int curTotalHeight, totalHeight, minHeight = 0;
          TuiWinInfoPtr firstWin, secondWin;
 
          if (curLayout == SRC_DISASSEM_COMMAND)
@@ -1232,7 +1483,7 @@ _newHeightOk (TuiWinInfoPtr primaryWinInfo, int newHeight)
             ** line that the first and second windows share, and add one
             ** for the locator.
           */
-         curTotalHeight =
+         totalHeight = curTotalHeight =
            (firstWin->generic.height + secondWin->generic.height - 1)
            + cmdWin->generic.height + 1 /*locator */ ;
          if (primaryWinInfo == cmdWin)
This page took 0.066564 seconds and 4 git commands to generate.