/* TUI window generic functions.

   Copyright (C) 1998-2004, 2006-2012 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 3 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, see <http://www.gnu.org/licenses/>.  */

/* 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 "tui/tui-win.h"

#include "gdb_curses.h"

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

#include <signal.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 *const tui_border_kind_enums[] = {
  "space",
  "ascii",
  "acs",
  NULL
};

/* Possible values for tui-border-mode and tui-active-border-mode.  */
static const char *const 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.  */

/* Provide a prototype to silence -Wmissing-prototypes.  */
extern initialize_file_ftype _initialize_tui_win;

void
_initialize_tui_win (void)
{
  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.  */
  xsnprintf (cmd, sizeof (cmd), "set width %d",
           tui_active ? TUI_CMD_WIN->generic.width : tui_term_width());
  execute_command (cmd, 0);
  xsnprintf (cmd, sizeof (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 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.  */
      /* erase + clearok are used instead of a straightforward clear as
         AIX 5.3 does not define clear.  */
      erase ();
      clearok (curscr, TRUE);
      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;

	  locator->origin.y = new_height + 1;
	  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;
	    }
	}
      /* 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);
    }
}

#ifdef SIGWINCH
/* 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).  */
static 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);
}
#endif

/* Initializes SIGWINCH signal handler for the tui.  */
void
tui_initialize_win (void)
{
#ifdef SIGWINCH
#ifdef HAVE_SIGACTION
  struct sigaction old_winch;

  memset (&old_winch, 0, sizeof (old_winch));
  old_winch.sa_handler = &tui_sigwinch_handler;
  sigaction (SIGWINCH, &old_winch, NULL);
#else
  signal (SIGWINCH, &tui_sigwinch_handler);
#endif
#endif
}


/*************************
** 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.  */
		  /* Subtract the locator.  */
		  int first_split_diff = diff / 2;
		  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 gdbarch *gdbarch = win_info->detail.source_info.gdbarch;
	  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, gdbarch,
				    cursal.symtab, line_or_addr, TRUE);
	}
      else if (deprecated_safe_get_selected_frame () != NULL)
	{
	  struct tui_line_or_address line;
	  struct symtab_and_line cursal
	    = get_current_source_symtab_and_line ();
	  struct frame_info *frame = deprecated_safe_get_selected_frame ();
	  struct gdbarch *gdbarch = get_frame_arch (frame);

	  s = find_pc_symtab (get_frame_pc (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, gdbarch, 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;
#ifdef HAVE_WRESIZE
      wresize (TUI_CMD_WIN->generic.handle,
	       TUI_CMD_WIN->generic.height,
	       TUI_CMD_WIN->generic.width);
#endif
      mvwin (TUI_CMD_WIN->generic.handle,
	     TUI_CMD_WIN->generic.origin.y,
	     TUI_CMD_WIN->generic.origin.x);
      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;

	      /* Validate the window name.  */
	      for (i = 0; i < strlen (wname); i++)
		wname[i] = toupper (wname[i]);
	    }
	  else
	    wname = "?";
	  
	  *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);
    }
}
