/* TUI window generic functions.

   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008,
   2009, 2010 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 *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.  */

/* 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.  */
  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);
    }
}

#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;
      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);
    }
}
