/* TUI window generic functions.

   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
   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., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.  */

/* This module contains procedures for handling tui window functions
   like resize, scrolling, scrolling, changing focus, etc.

   Author: Susan B. Macchia  */

#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/tui.h"
#include "tui/tui-data.h"
#include "tui/tui-wingeneral.h"
#include "tui/tui-stack.h"
#include "tui/tui-regs.h"
#include "tui/tui-disasm.h"
#include "tui/tui-source.h"
#include "tui/tui-winsource.h"
#include "tui/tui-windata.h"

#include "gdb_curses.h"

#include "gdb_string.h"
#include <ctype.h>
#include "readline/readline.h"

/*******************************
** Static Local Decls
********************************/
static void make_visible_with_new_height (struct tui_win_info *);
static void make_invisible_and_set_new_height (struct tui_win_info *, int);
static enum tui_status tui_adjust_win_heights (struct tui_win_info *, int);
static int new_height_ok (struct tui_win_info *, int);
static void tui_set_tab_width_command (char *, int);
static void tui_refresh_all_command (char *, int);
static void tui_set_win_height_command (char *, int);
static void tui_xdb_set_win_height_command (char *, int);
static void tui_all_windows_info (char *, int);
static void tui_set_focus_command (char *, int);
static void tui_scroll_forward_command (char *, int);
static void tui_scroll_backward_command (char *, int);
static void tui_scroll_left_command (char *, int);
static void tui_scroll_right_command (char *, int);
static void parse_scrolling_args (char *, struct tui_win_info * *, int *);


/***************************************
** DEFINITIONS
***************************************/
#define WIN_HEIGHT_USAGE      "Usage: winheight <win_name> [+ | -] <#lines>\n"
#define XDBWIN_HEIGHT_USAGE   "Usage: w <#lines>\n"
#define FOCUS_USAGE           "Usage: focus {<win> | next | prev}\n"

/***************************************
** 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";
static void
show_tui_active_border_mode (struct ui_file *file, int from_tty,
			     struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("\
The attribute mode to use for the active TUI window border is \"%s\".\n"),
		    value);
}

const char *tui_border_mode = "normal";
static void
show_tui_border_mode (struct ui_file *file, int from_tty,
		      struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("\
The attribute mode to use for the TUI window borders is \"%s\".\n"),
		    value);
}

const char *tui_border_kind = "acs";
static void
show_tui_border_kind (struct ui_file *file, int from_tty,
		      struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("The kind of border for TUI windows is \"%s\".\n"),
		    value);
}


/* 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 (void)
{
  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)
{
}

static struct cmd_list_element *tuilist;

static void
tui_command (char *args, int from_tty)
{
  printf_unfiltered (_("\"tui\" must be followed by the name of a "
                     "tui command.\n"));
  help_list (tuilist, "tui ", -1, gdb_stdout);
}

struct cmd_list_element **
tui_get_cmd_list (void)
{
  if (tuilist == 0)
    add_prefix_cmd ("tui", class_tui, tui_command,
                    _("Text User Interface commands."),
                    &tuilist, "tui ", 0, &cmdlist);
  return &tuilist;
}

/* Function to initialize gdb commands, for tui window manipulation.  */
void
_initialize_tui_win (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_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, tui_refresh_all_command,
           _("Refresh the terminal display.\n"));
  if (xdb_commands)
    add_com_alias ("U", "refresh", class_tui, 0);
  add_com ("tabset", class_tui, tui_set_tab_width_command, _("\
Set the width (in characters) of tab stops.\n\
Usage: tabset <n>\n"));
  add_com ("winheight", class_tui, tui_set_win_height_command, _("\
Set the height of a specified window.\n\
Usage: winheight <win_name> [+ | -] <#lines>\n\
Window names are:\n\
src  : the source window\n\
cmd  : the command window\n\
asm  : the disassembly window\n\
regs : the register display\n"));
  add_com_alias ("wh", "winheight", class_tui, 0);
  add_info ("win", tui_all_windows_info,
	    _("List of all displayed windows.\n"));
  add_com ("focus", class_tui, tui_set_focus_command, _("\
Set focus to named window or next/prev window.\n\
Usage: focus {<win> | next | prev}\n\
Valid Window names are:\n\
src  : the source window\n\
asm  : the disassembly window\n\
regs : the register display\n\
cmd  : the command window\n"));
  add_com_alias ("fs", "focus", class_tui, 0);
  add_com ("+", class_tui, tui_scroll_forward_command, _("\
Scroll window forward.\n\
Usage: + [win] [n]\n"));
  add_com ("-", class_tui, tui_scroll_backward_command, _("\
Scroll window backward.\n\
Usage: - [win] [n]\n"));
  add_com ("<", class_tui, tui_scroll_left_command, _("\
Scroll window forward.\n\
Usage: < [win] [n]\n"));
  add_com (">", class_tui, tui_scroll_right_command, _("\
Scroll window backward.\n\
Usage: > [win] [n]\n"));
  if (xdb_commands)
    add_com ("w", class_xdb, tui_xdb_set_win_height_command, _("\
XDB compatibility command for setting the height of a command window.\n\
Usage: w <#lines>\n"));

  /* Define the tui control variables.  */
  add_setshow_enum_cmd ("border-kind", no_class, tui_border_kind_enums,
			&tui_border_kind, _("\
Set the kind of border for TUI windows."), _("\
Show the kind of border for TUI windows."), _("\
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"),
			NULL,
			show_tui_border_kind,
			&tui_setlist, &tui_showlist);

  add_setshow_enum_cmd ("border-mode", no_class, tui_border_mode_enums,
			&tui_border_mode, _("\
Set the attribute mode to use for the TUI window borders."), _("\
Show the attribute mode to use for the TUI window borders."), _("\
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"),
			NULL,
			show_tui_border_mode,
			&tui_setlist, &tui_showlist);

  add_setshow_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."), _("\
Show the attribute mode to use for the active TUI window border."), _("\
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"),
			NULL,
			show_tui_active_border_mode,
			&tui_setlist, &tui_showlist);
}

/* Update gdb's knowledge of the terminal size.  */
void
tui_update_gdb_sizes (void)
{
  char cmd[50];

  /* Set to TUI command window dimension or use readline values.  */
  sprintf (cmd, "set width %d",
           tui_active ? TUI_CMD_WIN->generic.width : tui_term_width());
  execute_command (cmd, 0);
  sprintf (cmd, "set height %d",
           tui_active ? TUI_CMD_WIN->generic.height : tui_term_height());
  execute_command (cmd, 0);
}


/* Set the logical focus to win_info.    */
void
tui_set_win_focus_to (struct tui_win_info * win_info)
{
  if (win_info != NULL)
    {
      struct tui_win_info * win_with_focus = tui_win_with_focus ();

      if (win_with_focus != NULL
	  && win_with_focus->generic.type != CMD_WIN)
	tui_unhighlight_win (win_with_focus);
      tui_set_win_with_focus (win_info);
      if (win_info->generic.type != CMD_WIN)
	tui_highlight_win (win_info);
    }
}


void
tui_scroll_forward (struct tui_win_info * win_to_scroll, int num_to_scroll)
{
  if (win_to_scroll != TUI_CMD_WIN)
    {
      int _num_to_scroll = num_to_scroll;

      if (num_to_scroll == 0)
	_num_to_scroll = win_to_scroll->generic.height - 3;
      /*
         ** If we are scrolling the source or disassembly window, do a
         ** "psuedo" scroll since not all of the source is in memory,
         ** only what is in the viewport.  If win_to_scroll is the
         ** command window do nothing since the term should handle it.
       */
      if (win_to_scroll == TUI_SRC_WIN)
	tui_vertical_source_scroll (FORWARD_SCROLL, _num_to_scroll);
      else if (win_to_scroll == TUI_DISASM_WIN)
	tui_vertical_disassem_scroll (FORWARD_SCROLL, _num_to_scroll);
      else if (win_to_scroll == TUI_DATA_WIN)
	tui_vertical_data_scroll (FORWARD_SCROLL, _num_to_scroll);
    }
}

void
tui_scroll_backward (struct tui_win_info * win_to_scroll, int num_to_scroll)
{
  if (win_to_scroll != TUI_CMD_WIN)
    {
      int _num_to_scroll = num_to_scroll;

      if (num_to_scroll == 0)
	_num_to_scroll = win_to_scroll->generic.height - 3;
      /*
         ** If we are scrolling the source or disassembly window, do a
         ** "psuedo" scroll since not all of the source is in memory,
         ** only what is in the viewport.  If win_to_scroll is the
         ** command window do nothing since the term should handle it.
       */
      if (win_to_scroll == TUI_SRC_WIN)
	tui_vertical_source_scroll (BACKWARD_SCROLL, _num_to_scroll);
      else if (win_to_scroll == TUI_DISASM_WIN)
	tui_vertical_disassem_scroll (BACKWARD_SCROLL, _num_to_scroll);
      else if (win_to_scroll == TUI_DATA_WIN)
	tui_vertical_data_scroll (BACKWARD_SCROLL, _num_to_scroll);
    }
}


void
tui_scroll_left (struct tui_win_info * win_to_scroll, int num_to_scroll)
{
  if (win_to_scroll != TUI_CMD_WIN)
    {
      int _num_to_scroll = num_to_scroll;

      if (_num_to_scroll == 0)
	_num_to_scroll = 1;
      /*
         ** If we are scrolling the source or disassembly window, do a
         ** "psuedo" scroll since not all of the source is in memory,
         ** only what is in the viewport. If win_to_scroll is the
         ** command window do nothing since the term should handle it.
       */
      if (win_to_scroll == TUI_SRC_WIN || win_to_scroll == TUI_DISASM_WIN)
	tui_horizontal_source_scroll (win_to_scroll, LEFT_SCROLL, _num_to_scroll);
    }
}


void
tui_scroll_right (struct tui_win_info * win_to_scroll, int num_to_scroll)
{
  if (win_to_scroll != TUI_CMD_WIN)
    {
      int _num_to_scroll = num_to_scroll;

      if (_num_to_scroll == 0)
	_num_to_scroll = 1;
      /*
         ** If we are scrolling the source or disassembly window, do a
         ** "psuedo" scroll since not all of the source is in memory,
         ** only what is in the viewport. If win_to_scroll is the
         ** command window do nothing since the term should handle it.
       */
      if (win_to_scroll == TUI_SRC_WIN || win_to_scroll == TUI_DISASM_WIN)
	tui_horizontal_source_scroll (win_to_scroll, RIGHT_SCROLL, _num_to_scroll);
    }
}


/* Scroll a window.  Arguments are passed through a va_list.    */
void
tui_scroll (enum tui_scroll_direction direction,
	    struct tui_win_info * win_to_scroll,
	    int num_to_scroll)
{
  switch (direction)
    {
    case FORWARD_SCROLL:
      tui_scroll_forward (win_to_scroll, num_to_scroll);
      break;
    case BACKWARD_SCROLL:
      tui_scroll_backward (win_to_scroll, num_to_scroll);
      break;
    case LEFT_SCROLL:
      tui_scroll_left (win_to_scroll, num_to_scroll);
      break;
    case RIGHT_SCROLL:
      tui_scroll_right (win_to_scroll, num_to_scroll);
      break;
    default:
      break;
    }
}


void
tui_refresh_all_win (void)
{
  enum tui_win_type type;

  clearok (curscr, TRUE);
  tui_refresh_all (tui_win_list);
  for (type = SRC_WIN; type < MAX_MAJOR_WINDOWS; type++)
    {
      if (tui_win_list[type] && tui_win_list[type]->generic.is_visible)
	{
	  switch (type)
	    {
	    case SRC_WIN:
	    case DISASSEM_WIN:
	      tui_show_source_content (tui_win_list[type]);
	      tui_check_and_display_highlight_if_needed (tui_win_list[type]);
	      tui_erase_exec_info_content (tui_win_list[type]);
	      tui_update_exec_info (tui_win_list[type]);
	      break;
	    case DATA_WIN:
	      tui_refresh_data_win ();
	      break;
	    default:
	      break;
	    }
	}
    }
  tui_show_locator_content ();
}


/* Resize all the windows based on the the terminal size.  This
   function gets called from within the readline sinwinch handler.  */
void
tui_resize_all (void)
{
  int height_diff, width_diff;
  int screenheight, screenwidth;

  rl_get_screen_size (&screenheight, &screenwidth);
  width_diff = screenwidth - tui_term_width ();
  height_diff = screenheight - tui_term_height ();
  if (height_diff || width_diff)
    {
      enum tui_layout_type cur_layout = tui_current_layout ();
      struct tui_win_info * win_with_focus = tui_win_with_focus ();
      struct tui_win_info *first_win;
      struct tui_win_info *second_win;
      struct tui_gen_win_info * locator = tui_locator_win_info_ptr ();
      enum tui_win_type win_type;
      int new_height, split_diff, cmd_split_diff, num_wins_displayed = 2;

#ifdef HAVE_RESIZE_TERM
      resize_term (screenheight, screenwidth);
#endif      
      /* turn keypad off while we resize */
      if (win_with_focus != TUI_CMD_WIN)
	keypad (TUI_CMD_WIN->generic.handle, FALSE);
      tui_update_gdb_sizes ();
      tui_set_term_height_to (screenheight);
      tui_set_term_width_to (screenwidth);
      if (cur_layout == SRC_DISASSEM_COMMAND ||
	cur_layout == SRC_DATA_COMMAND || cur_layout == DISASSEM_DATA_COMMAND)
	num_wins_displayed++;
      split_diff = height_diff / num_wins_displayed;
      cmd_split_diff = split_diff;
      if (height_diff % num_wins_displayed)
	{
	  if (height_diff < 0)
	    cmd_split_diff--;
	  else
	    cmd_split_diff++;
	}
      /* now adjust each window */
      clear ();
      refresh ();
      switch (cur_layout)
	{
	case SRC_COMMAND:
	case DISASSEM_COMMAND:
	  first_win = (struct tui_win_info *) (tui_source_windows ())->list[0];
	  first_win->generic.width += width_diff;
	  locator->width += width_diff;
	  /* check for invalid heights */
	  if (height_diff == 0)
	    new_height = first_win->generic.height;
	  else if ((first_win->generic.height + split_diff) >=
		   (screenheight - MIN_CMD_WIN_HEIGHT - 1))
	    new_height = screenheight - MIN_CMD_WIN_HEIGHT - 1;
	  else if ((first_win->generic.height + split_diff) <= 0)
	    new_height = MIN_WIN_HEIGHT;
	  else
	    new_height = first_win->generic.height + split_diff;

	  make_invisible_and_set_new_height (first_win, new_height);
	  TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1;
	  TUI_CMD_WIN->generic.width += width_diff;
	  new_height = screenheight - TUI_CMD_WIN->generic.origin.y;
	  make_invisible_and_set_new_height (TUI_CMD_WIN, new_height);
	  make_visible_with_new_height (first_win);
	  make_visible_with_new_height (TUI_CMD_WIN);
	  if (first_win->generic.content_size <= 0)
	    tui_erase_source_content (first_win, EMPTY_SOURCE_PROMPT);
	  break;
	default:
	  if (cur_layout == SRC_DISASSEM_COMMAND)
	    {
	      first_win = TUI_SRC_WIN;
	      first_win->generic.width += width_diff;
	      second_win = TUI_DISASM_WIN;
	      second_win->generic.width += width_diff;
	    }
	  else
	    {
	      first_win = TUI_DATA_WIN;
	      first_win->generic.width += width_diff;
	      second_win = (struct tui_win_info *) (tui_source_windows ())->list[0];
	      second_win->generic.width += width_diff;
	    }
	  /* Change the first window's height/width */
	  /* check for invalid heights */
	  if (height_diff == 0)
	    new_height = first_win->generic.height;
	  else if ((first_win->generic.height +
		    second_win->generic.height + (split_diff * 2)) >=
		   (screenheight - MIN_CMD_WIN_HEIGHT - 1))
	    new_height = (screenheight - MIN_CMD_WIN_HEIGHT - 1) / 2;
	  else if ((first_win->generic.height + split_diff) <= 0)
	    new_height = MIN_WIN_HEIGHT;
	  else
	    new_height = first_win->generic.height + split_diff;
	  make_invisible_and_set_new_height (first_win, new_height);

	  locator->width += width_diff;

	  /* Change the second window's height/width */
	  /* check for invalid heights */
	  if (height_diff == 0)
	    new_height = second_win->generic.height;
	  else if ((first_win->generic.height +
		    second_win->generic.height + (split_diff * 2)) >=
		   (screenheight - MIN_CMD_WIN_HEIGHT - 1))
	    {
	      new_height = screenheight - MIN_CMD_WIN_HEIGHT - 1;
	      if (new_height % 2)
		new_height = (new_height / 2) + 1;
	      else
		new_height /= 2;
	    }
	  else if ((second_win->generic.height + split_diff) <= 0)
	    new_height = MIN_WIN_HEIGHT;
	  else
	    new_height = second_win->generic.height + split_diff;
	  second_win->generic.origin.y = first_win->generic.height - 1;
	  make_invisible_and_set_new_height (second_win, new_height);

	  /* Change the command window's height/width */
	  TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1;
	  make_invisible_and_set_new_height (
			     TUI_CMD_WIN, TUI_CMD_WIN->generic.height + cmd_split_diff);
	  make_visible_with_new_height (first_win);
	  make_visible_with_new_height (second_win);
	  make_visible_with_new_height (TUI_CMD_WIN);
	  if (first_win->generic.content_size <= 0)
	    tui_erase_source_content (first_win, EMPTY_SOURCE_PROMPT);
	  if (second_win->generic.content_size <= 0)
	    tui_erase_source_content (second_win, EMPTY_SOURCE_PROMPT);
	  break;
	}
      /*
         ** Now remove all invisible windows, and their content so that they get
         ** created again when called for with the new size
       */
      for (win_type = SRC_WIN; (win_type < MAX_MAJOR_WINDOWS); win_type++)
	{
	  if (win_type != CMD_WIN && (tui_win_list[win_type] != NULL)
	      && !tui_win_list[win_type]->generic.is_visible)
	    {
	      tui_free_window (tui_win_list[win_type]);
	      tui_win_list[win_type] = (struct tui_win_info *) NULL;
	    }
	}
      tui_set_win_resized_to (TRUE);
      /* turn keypad back on, unless focus is in the command window */
      if (win_with_focus != TUI_CMD_WIN)
	keypad (TUI_CMD_WIN->generic.handle, TRUE);
    }
}


/* SIGWINCH signal handler for the tui.  This signal handler is always
   called, even when the readline package clears signals because it is
   set as the old_sigwinch() (TUI only).  */
void
tui_sigwinch_handler (int signal)
{
  /*
     ** Say that a resize was done so that the readline can do it
     ** later when appropriate.
   */
  tui_set_win_resized_to (TRUE);
}



/*************************
** STATIC LOCAL FUNCTIONS
**************************/


static void
tui_scroll_forward_command (char *arg, int from_tty)
{
  int num_to_scroll = 1;
  struct tui_win_info * win_to_scroll;

  /* Make sure the curses mode is enabled.  */
  tui_enable ();
  if (arg == (char *) NULL)
    parse_scrolling_args (arg, &win_to_scroll, (int *) NULL);
  else
    parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll);
  tui_scroll (FORWARD_SCROLL, win_to_scroll, num_to_scroll);
}


static void
tui_scroll_backward_command (char *arg, int from_tty)
{
  int num_to_scroll = 1;
  struct tui_win_info * win_to_scroll;

  /* Make sure the curses mode is enabled.  */
  tui_enable ();
  if (arg == (char *) NULL)
    parse_scrolling_args (arg, &win_to_scroll, (int *) NULL);
  else
    parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll);
  tui_scroll (BACKWARD_SCROLL, win_to_scroll, num_to_scroll);
}


static void
tui_scroll_left_command (char *arg, int from_tty)
{
  int num_to_scroll;
  struct tui_win_info * win_to_scroll;

  /* Make sure the curses mode is enabled.  */
  tui_enable ();
  parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll);
  tui_scroll (LEFT_SCROLL, win_to_scroll, num_to_scroll);
}


static void
tui_scroll_right_command (char *arg, int from_tty)
{
  int num_to_scroll;
  struct tui_win_info * win_to_scroll;

  /* Make sure the curses mode is enabled.  */
  tui_enable ();
  parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll);
  tui_scroll (RIGHT_SCROLL, win_to_scroll, num_to_scroll);
}


/* Set focus to the window named by 'arg'.  */
static void
tui_set_focus (char *arg, int from_tty)
{
  if (arg != (char *) NULL)
    {
      char *buf_ptr = (char *) xstrdup (arg);
      int i;
      struct tui_win_info * win_info = (struct tui_win_info *) NULL;

      for (i = 0; (i < strlen (buf_ptr)); i++)
	buf_ptr[i] = toupper (arg[i]);

      if (subset_compare (buf_ptr, "NEXT"))
	win_info = tui_next_win (tui_win_with_focus ());
      else if (subset_compare (buf_ptr, "PREV"))
	win_info = tui_prev_win (tui_win_with_focus ());
      else
	win_info = tui_partial_win_by_name (buf_ptr);

      if (win_info == (struct tui_win_info *) NULL || !win_info->generic.is_visible)
	warning (_("Invalid window specified. \n\
The window name specified must be valid and visible.\n"));
      else
	{
	  tui_set_win_focus_to (win_info);
	  keypad (TUI_CMD_WIN->generic.handle, (win_info != TUI_CMD_WIN));
	}

      if (TUI_DATA_WIN && TUI_DATA_WIN->generic.is_visible)
	tui_refresh_data_win ();
      xfree (buf_ptr);
      printf_filtered (_("Focus set to %s window.\n"),
		       tui_win_name ((struct tui_gen_win_info *) tui_win_with_focus ()));
    }
  else
    warning (_("Incorrect Number of Arguments.\n%s"), FOCUS_USAGE);
}

static void
tui_set_focus_command (char *arg, int from_tty)
{
  /* Make sure the curses mode is enabled.  */
  tui_enable ();
  tui_set_focus (arg, from_tty);
}


static void
tui_all_windows_info (char *arg, int from_tty)
{
  enum tui_win_type type;
  struct tui_win_info * win_with_focus = tui_win_with_focus ();

  for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++)
    if (tui_win_list[type] && tui_win_list[type]->generic.is_visible)
      {
	if (win_with_focus == tui_win_list[type])
	  printf_filtered ("        %s\t(%d lines)  <has focus>\n",
			   tui_win_name (&tui_win_list[type]->generic),
			   tui_win_list[type]->generic.height);
	else
	  printf_filtered ("        %s\t(%d lines)\n",
			   tui_win_name (&tui_win_list[type]->generic),
			   tui_win_list[type]->generic.height);
      }
}


static void
tui_refresh_all_command (char *arg, int from_tty)
{
  /* Make sure the curses mode is enabled.  */
  tui_enable ();

  tui_refresh_all_win ();
}


/* Set the height of the specified window.   */
static void
tui_set_tab_width_command (char *arg, int from_tty)
{
  /* Make sure the curses mode is enabled.  */
  tui_enable ();
  if (arg != (char *) NULL)
    {
      int ts;

      ts = atoi (arg);
      if (ts > 0)
	tui_set_default_tab_len (ts);
      else
	warning (_("Tab widths greater than 0 must be specified."));
    }
}


/* Set the height of the specified window.   */
static void
tui_set_win_height (char *arg, int from_tty)
{
  /* Make sure the curses mode is enabled.  */
  tui_enable ();
  if (arg != (char *) NULL)
    {
      char *buf = xstrdup (arg);
      char *buf_ptr = buf;
      char *wname = (char *) NULL;
      int new_height, i;
      struct tui_win_info * win_info;

      wname = buf_ptr;
      buf_ptr = strchr (buf_ptr, ' ');
      if (buf_ptr != (char *) NULL)
	{
	  *buf_ptr = (char) 0;

	  /*
	     ** Validate the window name
	   */
	  for (i = 0; i < strlen (wname); i++)
	    wname[i] = toupper (wname[i]);
	  win_info = tui_partial_win_by_name (wname);

	  if (win_info == (struct tui_win_info *) NULL || !win_info->generic.is_visible)
	    warning (_("Invalid window specified. \n\
The window name specified must be valid and visible.\n"));
	  else
	    {
	      /* Process the size */
	      while (*(++buf_ptr) == ' ')
		;

	      if (*buf_ptr != (char) 0)
		{
		  int negate = FALSE;
		  int fixed_size = TRUE;
		  int input_no;;

		  if (*buf_ptr == '+' || *buf_ptr == '-')
		    {
		      if (*buf_ptr == '-')
			negate = TRUE;
		      fixed_size = FALSE;
		      buf_ptr++;
		    }
		  input_no = atoi (buf_ptr);
		  if (input_no > 0)
		    {
		      if (negate)
			input_no *= (-1);
		      if (fixed_size)
			new_height = input_no;
		      else
			new_height = win_info->generic.height + input_no;
		      /*
		         ** Now change the window's height, and adjust all
		         ** other windows around it
		       */
		      if (tui_adjust_win_heights (win_info,
						new_height) == TUI_FAILURE)
			warning (_("Invalid window height specified.\n%s"),
				 WIN_HEIGHT_USAGE);
		      else
                        tui_update_gdb_sizes ();
		    }
		  else
		    warning (_("Invalid window height specified.\n%s"),
			     WIN_HEIGHT_USAGE);
		}
	    }
	}
      else
	printf_filtered (WIN_HEIGHT_USAGE);

      if (buf != (char *) NULL)
	xfree (buf);
    }
  else
    printf_filtered (WIN_HEIGHT_USAGE);
}

/* Set the height of the specified window, with va_list.    */
static void
tui_set_win_height_command (char *arg, int from_tty)
{
  /* Make sure the curses mode is enabled.  */
  tui_enable ();
  tui_set_win_height (arg, from_tty);
}


/* XDB Compatibility command for setting the window height.  This will
   increase or decrease the command window by the specified amount.  */
static void
tui_xdb_set_win_height (char *arg, int from_tty)
{
  /* Make sure the curses mode is enabled.  */
  tui_enable ();
  if (arg != (char *) NULL)
    {
      int input_no = atoi (arg);

      if (input_no > 0)
	{			/* Add 1 for the locator */
	  int new_height = tui_term_height () - (input_no + 1);

	  if (!new_height_ok (tui_win_list[CMD_WIN], new_height) ||
	      tui_adjust_win_heights (tui_win_list[CMD_WIN],
				    new_height) == TUI_FAILURE)
	    warning (_("Invalid window height specified.\n%s"),
		     XDBWIN_HEIGHT_USAGE);
	}
      else
	warning (_("Invalid window height specified.\n%s"),
		 XDBWIN_HEIGHT_USAGE);
    }
  else
    warning (_("Invalid window height specified.\n%s"), XDBWIN_HEIGHT_USAGE);
}

/* Set the height of the specified window, with va_list.  */
static void
tui_xdb_set_win_height_command (char *arg, int from_tty)
{
  tui_xdb_set_win_height (arg, from_tty);
}


/* Function to adjust all window heights around the primary.   */
static enum tui_status
tui_adjust_win_heights (struct tui_win_info * primary_win_info, int new_height)
{
  enum tui_status status = TUI_FAILURE;

  if (new_height_ok (primary_win_info, new_height))
    {
      status = TUI_SUCCESS;
      if (new_height != primary_win_info->generic.height)
	{
	  int diff;
	  struct tui_win_info * win_info;
	  struct tui_gen_win_info * locator = tui_locator_win_info_ptr ();
	  enum tui_layout_type cur_layout = tui_current_layout ();

	  diff = (new_height - primary_win_info->generic.height) * (-1);
	  if (cur_layout == SRC_COMMAND || cur_layout == DISASSEM_COMMAND)
	    {
	      struct tui_win_info * src_win_info;

	      make_invisible_and_set_new_height (primary_win_info, new_height);
	      if (primary_win_info->generic.type == CMD_WIN)
		{
		  win_info = (tui_source_windows ())->list[0];
		  src_win_info = win_info;
		}
	      else
		{
		  win_info = tui_win_list[CMD_WIN];
		  src_win_info = primary_win_info;
		}
	      make_invisible_and_set_new_height (win_info,
					     win_info->generic.height + diff);
	      TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1;
	      make_visible_with_new_height (win_info);
	      make_visible_with_new_height (primary_win_info);
	      if (src_win_info->generic.content_size <= 0)
		tui_erase_source_content (src_win_info, EMPTY_SOURCE_PROMPT);
	    }
	  else
	    {
	      struct tui_win_info *first_win;
	      struct tui_win_info *second_win;

	      if (cur_layout == SRC_DISASSEM_COMMAND)
		{
		  first_win = TUI_SRC_WIN;
		  second_win = TUI_DISASM_WIN;
		}
	      else
		{
		  first_win = TUI_DATA_WIN;
		  second_win = (tui_source_windows ())->list[0];
		}
	      if (primary_win_info == TUI_CMD_WIN)
		{		/*
				   ** Split the change in height accross the 1st & 2nd windows
				   ** adjusting them as well.
				 */
		  int first_split_diff = diff / 2;	/* subtract the locator */
		  int second_split_diff = first_split_diff;

		  if (diff % 2)
		    {
		      if (first_win->generic.height >
			  second_win->generic.height)
			if (diff < 0)
			  first_split_diff--;
			else
			  first_split_diff++;
		      else
			{
			  if (diff < 0)
			    second_split_diff--;
			  else
			    second_split_diff++;
			}
		    }
		  /* make sure that the minimum hieghts are honored */
		  while ((first_win->generic.height + first_split_diff) < 3)
		    {
		      first_split_diff++;
		      second_split_diff--;
		    }
		  while ((second_win->generic.height + second_split_diff) < 3)
		    {
		      second_split_diff++;
		      first_split_diff--;
		    }
		  make_invisible_and_set_new_height (
						  first_win,
				 first_win->generic.height + first_split_diff);
		  second_win->generic.origin.y = first_win->generic.height - 1;
		  make_invisible_and_set_new_height (
		    second_win, second_win->generic.height + second_split_diff);
		  TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1;
		  make_invisible_and_set_new_height (TUI_CMD_WIN, new_height);
		}
	      else
		{
		  if ((TUI_CMD_WIN->generic.height + diff) < 1)
		    {		/*
				   ** If there is no way to increase the command window
				   ** take real estate from the 1st or 2nd window.
				 */
		      if ((TUI_CMD_WIN->generic.height + diff) < 1)
			{
			  int i;
			  for (i = TUI_CMD_WIN->generic.height + diff;
			       (i < 1); i++)
			    if (primary_win_info == first_win)
			      second_win->generic.height--;
			    else
			      first_win->generic.height--;
			}
		    }
		  if (primary_win_info == first_win)
		    make_invisible_and_set_new_height (first_win, new_height);
		  else
		    make_invisible_and_set_new_height (
						    first_win,
						  first_win->generic.height);
		  second_win->generic.origin.y = first_win->generic.height - 1;
		  if (primary_win_info == second_win)
		    make_invisible_and_set_new_height (second_win, new_height);
		  else
		    make_invisible_and_set_new_height (
				      second_win, second_win->generic.height);
		  TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1;
		  if ((TUI_CMD_WIN->generic.height + diff) < 1)
		    make_invisible_and_set_new_height (TUI_CMD_WIN, 1);
		  else
		    make_invisible_and_set_new_height (
				     TUI_CMD_WIN, TUI_CMD_WIN->generic.height + diff);
		}
	      make_visible_with_new_height (TUI_CMD_WIN);
	      make_visible_with_new_height (second_win);
	      make_visible_with_new_height (first_win);
	      if (first_win->generic.content_size <= 0)
		tui_erase_source_content (first_win, EMPTY_SOURCE_PROMPT);
	      if (second_win->generic.content_size <= 0)
		tui_erase_source_content (second_win, EMPTY_SOURCE_PROMPT);
	    }
	}
    }

  return status;
}


/* Function make the target window (and auxillary windows associated
   with the targer) invisible, and set the new height and location.  */
static void
make_invisible_and_set_new_height (struct tui_win_info * win_info, int height)
{
  int i;
  struct tui_gen_win_info * gen_win_info;

  tui_make_invisible (&win_info->generic);
  win_info->generic.height = height;
  if (height > 1)
    win_info->generic.viewport_height = height - 1;
  else
    win_info->generic.viewport_height = height;
  if (win_info != TUI_CMD_WIN)
    win_info->generic.viewport_height--;

  /* Now deal with the auxillary windows associated with win_info */
  switch (win_info->generic.type)
    {
    case SRC_WIN:
    case DISASSEM_WIN:
      gen_win_info = win_info->detail.source_info.execution_info;
      tui_make_invisible (gen_win_info);
      gen_win_info->height = height;
      gen_win_info->origin.y = win_info->generic.origin.y;
      if (height > 1)
	gen_win_info->viewport_height = height - 1;
      else
	gen_win_info->viewport_height = height;
      if (win_info != TUI_CMD_WIN)
	gen_win_info->viewport_height--;

      if (tui_win_has_locator (win_info))
	{
	  gen_win_info = tui_locator_win_info_ptr ();
	  tui_make_invisible (gen_win_info);
	  gen_win_info->origin.y = win_info->generic.origin.y + height;
	}
      break;
    case DATA_WIN:
      /* delete all data item windows */
      for (i = 0; i < win_info->generic.content_size; i++)
	{
	  gen_win_info = (struct tui_gen_win_info *) & ((struct tui_win_element *)
		      win_info->generic.content[i])->which_element.data_window;
	  tui_delete_win (gen_win_info->handle);
	  gen_win_info->handle = (WINDOW *) NULL;
	}
      break;
    default:
      break;
    }
}


/* Function to make the windows with new heights visible.  This means
   re-creating the windows' content since the window had to be
   destroyed to be made invisible.  */
static void
make_visible_with_new_height (struct tui_win_info * win_info)
{
  struct symtab *s;

  tui_make_visible (&win_info->generic);
  tui_check_and_display_highlight_if_needed (win_info);
  switch (win_info->generic.type)
    {
    case SRC_WIN:
    case DISASSEM_WIN:
      tui_free_win_content (win_info->detail.source_info.execution_info);
      tui_make_visible (win_info->detail.source_info.execution_info);
      if (win_info->generic.content != NULL)
	{
	  struct tui_line_or_address line_or_addr;
	  struct symtab_and_line cursal
	    = get_current_source_symtab_and_line ();

	  line_or_addr = win_info->detail.source_info.start_line_or_addr;
	  tui_free_win_content (&win_info->generic);
	  tui_update_source_window (win_info, cursal.symtab, line_or_addr, TRUE);
	}
      else if (deprecated_selected_frame != (struct frame_info *) NULL)
	{
	  struct tui_line_or_address line;
	  struct symtab_and_line cursal = get_current_source_symtab_and_line ();


	  s = find_pc_symtab (get_frame_pc (deprecated_selected_frame));
	  if (win_info->generic.type == SRC_WIN)
	    {
	      line.loa = LOA_LINE;
	      line.u.line_no = cursal.line;
	    }
	  else
	    {
	      line.loa = LOA_ADDRESS;
	      find_line_pc (s, cursal.line, &line.u.addr);
	    }
	  tui_update_source_window (win_info, s, line, TRUE);
	}
      if (tui_win_has_locator (win_info))
	{
	  tui_make_visible (tui_locator_win_info_ptr ());
	  tui_show_locator_content ();
	}
      break;
    case DATA_WIN:
      tui_display_all_data ();
      break;
    case CMD_WIN:
      win_info->detail.command_info.cur_line = 0;
      win_info->detail.command_info.curch = 0;
      wmove (win_info->generic.handle,
	     win_info->detail.command_info.cur_line,
	     win_info->detail.command_info.curch);
      break;
    default:
      break;
    }
}


static int
new_height_ok (struct tui_win_info * primary_win_info, int new_height)
{
  int ok = (new_height < tui_term_height ());

  if (ok)
    {
      int diff;
      enum tui_layout_type cur_layout = tui_current_layout ();

      diff = (new_height - primary_win_info->generic.height) * (-1);
      if (cur_layout == SRC_COMMAND || cur_layout == DISASSEM_COMMAND)
	{
	  ok = ((primary_win_info->generic.type == CMD_WIN &&
		 new_height <= (tui_term_height () - 4) &&
		 new_height >= MIN_CMD_WIN_HEIGHT) ||
		(primary_win_info->generic.type != CMD_WIN &&
		 new_height <= (tui_term_height () - 2) &&
		 new_height >= MIN_WIN_HEIGHT));
	  if (ok)
	    {			/* check the total height */
	      struct tui_win_info * win_info;

	      if (primary_win_info == TUI_CMD_WIN)
		win_info = (tui_source_windows ())->list[0];
	      else
		win_info = TUI_CMD_WIN;
	      ok = ((new_height +
		     (win_info->generic.height + diff)) <= tui_term_height ());
	    }
	}
      else
	{
	  int cur_total_height, total_height, min_height = 0;
	  struct tui_win_info *first_win;
	  struct tui_win_info *second_win;

	  if (cur_layout == SRC_DISASSEM_COMMAND)
	    {
	      first_win = TUI_SRC_WIN;
	      second_win = TUI_DISASM_WIN;
	    }
	  else
	    {
	      first_win = TUI_DATA_WIN;
	      second_win = (tui_source_windows ())->list[0];
	    }
	  /*
	     ** We could simply add all the heights to obtain the same result
	     ** but below is more explicit since we subtract 1 for the
	     ** line that the first and second windows share, and add one
	     ** for the locator.
	   */
	  total_height = cur_total_height =
	    (first_win->generic.height + second_win->generic.height - 1)
	    + TUI_CMD_WIN->generic.height + 1 /*locator */ ;
	  if (primary_win_info == TUI_CMD_WIN)
	    {
	      /* locator included since first & second win share a line */
	      ok = ((first_win->generic.height +
		     second_win->generic.height + diff) >=
		    (MIN_WIN_HEIGHT * 2) &&
		    new_height >= MIN_CMD_WIN_HEIGHT);
	      if (ok)
		{
		  total_height = new_height + (first_win->generic.height +
					  second_win->generic.height + diff);
		  min_height = MIN_CMD_WIN_HEIGHT;
		}
	    }
	  else
	    {
	      min_height = MIN_WIN_HEIGHT;
	      /*
	         ** First see if we can increase/decrease the command
	         ** window.  And make sure that the command window is
	         ** at least 1 line
	       */
	      ok = ((TUI_CMD_WIN->generic.height + diff) > 0);
	      if (!ok)
		{		/*
				   ** Looks like we have to increase/decrease one of
				   ** the other windows
				 */
		  if (primary_win_info == first_win)
		    ok = (second_win->generic.height + diff) >= min_height;
		  else
		    ok = (first_win->generic.height + diff) >= min_height;
		}
	      if (ok)
		{
		  if (primary_win_info == first_win)
		    total_height = new_height +
		      second_win->generic.height +
		      TUI_CMD_WIN->generic.height + diff;
		  else
		    total_height = new_height +
		      first_win->generic.height +
		      TUI_CMD_WIN->generic.height + diff;
		}
	    }
	  /*
	     ** Now make sure that the proposed total height doesn't exceed
	     ** the old total height.
	   */
	  if (ok)
	    ok = (new_height >= min_height && total_height <= cur_total_height);
	}
    }

  return ok;
}


static void
parse_scrolling_args (char *arg, struct tui_win_info * * win_to_scroll,
		      int *num_to_scroll)
{
  if (num_to_scroll)
    *num_to_scroll = 0;
  *win_to_scroll = tui_win_with_focus ();

  /*
     ** First set up the default window to scroll, in case there is no
     ** window name arg
   */
  if (arg != (char *) NULL)
    {
      char *buf, *buf_ptr;

      /* process the number of lines to scroll */
      buf = buf_ptr = xstrdup (arg);
      if (isdigit (*buf_ptr))
	{
	  char *num_str;

	  num_str = buf_ptr;
	  buf_ptr = strchr (buf_ptr, ' ');
	  if (buf_ptr != (char *) NULL)
	    {
	      *buf_ptr = (char) 0;
	      if (num_to_scroll)
		*num_to_scroll = atoi (num_str);
	      buf_ptr++;
	    }
	  else if (num_to_scroll)
	    *num_to_scroll = atoi (num_str);
	}

      /* process the window name if one is specified */
      if (buf_ptr != (char *) NULL)
	{
	  char *wname;
	  int i;

	  if (*buf_ptr == ' ')
	    while (*(++buf_ptr) == ' ')
	      ;

	  if (*buf_ptr != (char) 0)
	    wname = buf_ptr;
	  else
	    wname = "?";
	  
	  /* Validate the window name */
	  for (i = 0; i < strlen (wname); i++)
	    wname[i] = toupper (wname[i]);
	  *win_to_scroll = tui_partial_win_by_name (wname);

	  if (*win_to_scroll == (struct tui_win_info *) NULL ||
	      !(*win_to_scroll)->generic.is_visible)
	    error (_("Invalid window specified. \n\
The window name specified must be valid and visible.\n"));
	  else if (*win_to_scroll == TUI_CMD_WIN)
	    *win_to_scroll = (tui_source_windows ())->list[0];
	}
      xfree (buf);
    }
}
