/* TUI layout window management.

   Copyright (C) 1998-2023 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/>.  */

#include "defs.h"
#include "arch-utils.h"
#include "command.h"
#include "symtab.h"
#include "frame.h"
#include "source.h"
#include "cli/cli-cmds.h"
#include "cli/cli-decode.h"
#include "cli/cli-utils.h"
#include <ctype.h>
#include <unordered_set>

#include "tui/tui.h"
#include "tui/tui-command.h"
#include "tui/tui-data.h"
#include "tui/tui-wingeneral.h"
#include "tui/tui-stack.h"
#include "tui/tui-regs.h"
#include "tui/tui-win.h"
#include "tui/tui-winsource.h"
#include "tui/tui-disasm.h"
#include "tui/tui-layout.h"
#include "tui/tui-source.h"
#include "gdb_curses.h"
#include "gdbsupport/gdb-safe-ctype.h"

static void extract_display_start_addr (struct gdbarch **, CORE_ADDR *);

/* The layouts.  */
static std::vector<std::unique_ptr<tui_layout_split>> layouts;

/* The layout that is currently applied.  */
static std::unique_ptr<tui_layout_base> applied_layout;

/* The "skeleton" version of the layout that is currently applied.  */
static tui_layout_split *applied_skeleton;

/* The two special "regs" layouts.  Note that these aren't registered
   as commands and so can never be deleted.  */
static tui_layout_split *src_regs_layout;
static tui_layout_split *asm_regs_layout;

/* See tui-data.h.  */
std::vector<tui_win_info *> tui_windows;

/* See tui-layout.h.  */

void
tui_apply_current_layout (bool preserve_cmd_win_size_p)
{
  struct gdbarch *gdbarch;
  CORE_ADDR addr;

  extract_display_start_addr (&gdbarch, &addr);

  for (tui_win_info *win_info : tui_windows)
    win_info->make_visible (false);

  applied_layout->apply (0, 0, tui_term_width (), tui_term_height (),
			 preserve_cmd_win_size_p);

  /* Keep the list of internal windows up-to-date.  */
  for (int win_type = SRC_WIN; (win_type < MAX_MAJOR_WINDOWS); win_type++)
    if (tui_win_list[win_type] != nullptr
	&& !tui_win_list[win_type]->is_visible ())
      tui_win_list[win_type] = nullptr;

  /* This should always be made visible by a layout.  */
  gdb_assert (TUI_CMD_WIN != nullptr);
  gdb_assert (TUI_CMD_WIN->is_visible ());

  /* Get the new list of currently visible windows.  */
  std::vector<tui_win_info *> new_tui_windows;
  applied_layout->get_windows (&new_tui_windows);

  /* Now delete any window that was not re-applied.  */
  tui_win_info *focus = tui_win_with_focus ();
  for (tui_win_info *win_info : tui_windows)
    {
      if (!win_info->is_visible ())
	{
	  if (focus == win_info)
	    tui_set_win_focus_to (new_tui_windows[0]);
	  delete win_info;
	}
    }

  /* Replace the global list of active windows.  */
  tui_windows = std::move (new_tui_windows);

  if (gdbarch == nullptr && TUI_DISASM_WIN != nullptr)
    tui_get_begin_asm_address (&gdbarch, &addr);
  tui_update_source_windows_with_addr (gdbarch, addr);
}

/* See tui-layout.  */

void
tui_adjust_window_height (struct tui_win_info *win, int new_height)
{
  applied_layout->set_height (win->name (), new_height);
}

/* See tui-layout.  */

void
tui_adjust_window_width (struct tui_win_info *win, int new_width)
{
  applied_layout->set_width (win->name (), new_width);
}

/* Set the current layout to LAYOUT.  */

static void
tui_set_layout (tui_layout_split *layout)
{
  std::string old_fingerprint;
  if (applied_layout != nullptr)
    old_fingerprint = applied_layout->layout_fingerprint ();

  applied_skeleton = layout;
  applied_layout = layout->clone ();

  std::string new_fingerprint = applied_layout->layout_fingerprint ();
  bool preserve_command_window_size
    = (TUI_CMD_WIN != nullptr && old_fingerprint == new_fingerprint);

  tui_apply_current_layout (preserve_command_window_size);
}

/* See tui-layout.h.  */

void
tui_add_win_to_layout (enum tui_win_type type)
{
  gdb_assert (type == SRC_WIN || type == DISASSEM_WIN);

  /* If the window already exists, no need to add it.  */
  if (tui_win_list[type] != nullptr)
    return;

  /* If the window we are trying to replace doesn't exist, we're
     done.  */
  enum tui_win_type other = type == SRC_WIN ? DISASSEM_WIN : SRC_WIN;
  if (tui_win_list[other] == nullptr)
    return;

  const char *name = type == SRC_WIN ? SRC_NAME : DISASSEM_NAME;
  applied_layout->replace_window (tui_win_list[other]->name (), name);
  tui_apply_current_layout (true);
}

/* Find LAYOUT in the "layouts" global and return its index.  */

static size_t
find_layout (tui_layout_split *layout)
{
  for (size_t i = 0; i < layouts.size (); ++i)
    {
      if (layout == layouts[i].get ())
	return i;
    }
  gdb_assert_not_reached ("layout not found!?");
}

/* Function to set the layout. */

static void
tui_apply_layout (const char *args, int from_tty, cmd_list_element *command)
{
  tui_layout_split *layout = (tui_layout_split *) command->context ();

  /* Make sure the curses mode is enabled.  */
  tui_enable ();
  tui_set_layout (layout);
}

/* See tui-layout.h.  */

void
tui_next_layout ()
{
  size_t index = find_layout (applied_skeleton);
  ++index;
  if (index == layouts.size ())
    index = 0;
  tui_set_layout (layouts[index].get ());
}

/* Implement the "layout next" command.  */

static void
tui_next_layout_command (const char *arg, int from_tty)
{
  tui_enable ();
  tui_next_layout ();
}

/* See tui-layout.h.  */

void
tui_set_initial_layout ()
{
  tui_set_layout (layouts[0].get ());
}

/* Implement the "layout prev" command.  */

static void
tui_prev_layout_command (const char *arg, int from_tty)
{
  tui_enable ();
  size_t index = find_layout (applied_skeleton);
  if (index == 0)
    index = layouts.size ();
  --index;
  tui_set_layout (layouts[index].get ());
}


/* See tui-layout.h.  */

void
tui_regs_layout ()
{
  /* If there's already a register window, we're done.  */
  if (TUI_DATA_WIN != nullptr)
    return;

  tui_set_layout (TUI_DISASM_WIN != nullptr
		  ? asm_regs_layout
		  : src_regs_layout);
}

/* Implement the "layout regs" command.  */

static void
tui_regs_layout_command (const char *arg, int from_tty)
{
  tui_enable ();
  tui_regs_layout ();
}

/* See tui-layout.h.  */

void
tui_remove_some_windows ()
{
  tui_win_info *focus = tui_win_with_focus ();

  if (strcmp (focus->name (), CMD_NAME) == 0)
    {
      /* Try leaving the source or disassembly window.  If neither
	 exists, just do nothing.  */
      focus = TUI_SRC_WIN;
      if (focus == nullptr)
	focus = TUI_DISASM_WIN;
      if (focus == nullptr)
	return;
    }

  applied_layout->remove_windows (focus->name ());
  tui_apply_current_layout (true);
}

static void
extract_display_start_addr (struct gdbarch **gdbarch_p, CORE_ADDR *addr_p)
{
  if (TUI_SRC_WIN != nullptr)
    TUI_SRC_WIN->display_start_addr (gdbarch_p, addr_p);
  else if (TUI_DISASM_WIN != nullptr)
    TUI_DISASM_WIN->display_start_addr (gdbarch_p, addr_p);
  else
    {
      *gdbarch_p = nullptr;
      *addr_p = 0;
    }
}

void
tui_win_info::resize (int height_, int width_,
		      int origin_x_, int origin_y_)
{
  if (width == width_ && height == height_
      && x == origin_x_ && y == origin_y_
      && handle != nullptr)
    return;

  width = width_;
  height = height_;
  x = origin_x_;
  y = origin_y_;

  if (handle != nullptr)
    {
#ifdef HAVE_WRESIZE
      wresize (handle.get (), height, width);
      mvwin (handle.get (), y, x);
      wmove (handle.get (), 0, 0);
#else
      handle.reset (nullptr);
#endif
    }

  if (handle == nullptr)
    make_window ();

  rerender ();
}



/* Helper function to create one of the built-in (non-locator)
   windows.  */

template<enum tui_win_type V, class T>
static tui_win_info *
make_standard_window (const char *)
{
  if (tui_win_list[V] == nullptr)
    tui_win_list[V] = new T ();
  return tui_win_list[V];
}

/* A map holding all the known window types, keyed by name.  */

static window_types_map known_window_types;

/* See tui-layout.h.  */

known_window_names_range
all_known_window_names ()
{
  auto begin = known_window_names_iterator (known_window_types.begin ());
  auto end = known_window_names_iterator (known_window_types.end ());
  return known_window_names_range (begin, end);
}

/* Helper function that returns a TUI window, given its name.  */

static tui_win_info *
tui_get_window_by_name (const std::string &name)
{
  for (tui_win_info *window : tui_windows)
    if (name == window->name ())
      return window;

  auto iter = known_window_types.find (name);
  if (iter == known_window_types.end ())
    error (_("Unknown window type \"%s\""), name.c_str ());

  tui_win_info *result = iter->second (name.c_str ());
  if (result == nullptr)
    error (_("Could not create window \"%s\""), name.c_str ());
  return result;
}

/* Initialize the known window types.  */

static void
initialize_known_windows ()
{
  known_window_types.emplace (SRC_NAME,
			       make_standard_window<SRC_WIN,
						    tui_source_window>);
  known_window_types.emplace (CMD_NAME,
			       make_standard_window<CMD_WIN, tui_cmd_window>);
  known_window_types.emplace (DATA_NAME,
			       make_standard_window<DATA_WIN,
						    tui_data_window>);
  known_window_types.emplace (DISASSEM_NAME,
			       make_standard_window<DISASSEM_WIN,
						    tui_disasm_window>);
  known_window_types.emplace (STATUS_NAME,
			       make_standard_window<STATUS_WIN,
						    tui_locator_window>);
}

/* See tui-layout.h.  */

void
tui_register_window (const char *name, window_factory &&factory)
{
  std::string name_copy = name;

  if (name_copy == SRC_NAME || name_copy == CMD_NAME || name_copy == DATA_NAME
      || name_copy == DISASSEM_NAME || name_copy == STATUS_NAME)
    error (_("Window type \"%s\" is built-in"), name);

  for (const char &c : name_copy)
    {
      if (ISSPACE (c))
	error (_("invalid whitespace character in window name"));

      if (!ISALNUM (c) && strchr ("-_.", c) == nullptr)
	error (_("invalid character '%c' in window name"), c);
    }

  if (!ISALPHA (name_copy[0]))
    error (_("window name must start with a letter, not '%c'"), name_copy[0]);

  /* We already check above for all the builtin window names.  If we get
     this far then NAME must be a user defined window.  Remove any existing
     factory and replace it with this new version.  */

  auto iter = known_window_types.find (name);
  if (iter != known_window_types.end ())
    known_window_types.erase (iter);

  known_window_types.emplace (std::move (name_copy),
			       std::move (factory));
}

/* See tui-layout.h.  */

std::unique_ptr<tui_layout_base>
tui_layout_window::clone () const
{
  tui_layout_window *result = new tui_layout_window (m_contents.c_str ());
  return std::unique_ptr<tui_layout_base> (result);
}

/* See tui-layout.h.  */

void
tui_layout_window::apply (int x_, int y_, int width_, int height_,
			  bool preserve_cmd_win_size_p)
{
  x = x_;
  y = y_;
  width = width_;
  height = height_;
  gdb_assert (m_window != nullptr);
  m_window->resize (height, width, x, y);
}

/* See tui-layout.h.  */

void
tui_layout_window::get_sizes (bool height, int *min_value, int *max_value)
{
  TUI_SCOPED_DEBUG_ENTER_EXIT;

  if (m_window == nullptr)
    m_window = tui_get_window_by_name (m_contents);

  tui_debug_printf ("window = %s, getting %s",
		    m_window->name (), (height ? "height" : "width"));

  if (height)
    {
      *min_value = m_window->min_height ();
      *max_value = m_window->max_height ();
    }
  else
    {
      *min_value = m_window->min_width ();
      *max_value = m_window->max_width ();
    }

  tui_debug_printf ("min = %d, max = %d", *min_value, *max_value);
}

/* See tui-layout.h.  */

bool
tui_layout_window::first_edge_has_border_p () const
{
  gdb_assert (m_window != nullptr);
  return m_window->can_box ();
}

/* See tui-layout.h.  */

bool
tui_layout_window::last_edge_has_border_p () const
{
  gdb_assert (m_window != nullptr);
  return m_window->can_box ();
}

/* See tui-layout.h.  */

void
tui_layout_window::replace_window (const char *name, const char *new_window)
{
  if (m_contents == name)
    {
      m_contents = new_window;
      if (m_window != nullptr)
	{
	  m_window->make_visible (false);
	  m_window = tui_get_window_by_name (m_contents);
	}
    }
}

/* See tui-layout.h.  */

void
tui_layout_window::specification (ui_file *output, int depth)
{
  gdb_puts (get_name (), output);
}

/* See tui-layout.h.  */

std::string
tui_layout_window::layout_fingerprint () const
{
  if (strcmp (get_name (), "cmd") == 0)
    return "C";
  else
    return "";
}

/* See tui-layout.h.  */

void
tui_layout_split::add_split (std::unique_ptr<tui_layout_split> &&layout,
			     int weight)
{
  split s = {weight, std::move (layout)};
  m_splits.push_back (std::move (s));
}

/* See tui-layout.h.  */

void
tui_layout_split::add_window (const char *name, int weight)
{
  tui_layout_window *result = new tui_layout_window (name);
  split s = {weight, std::unique_ptr<tui_layout_base> (result)};
  m_splits.push_back (std::move (s));
}

/* See tui-layout.h.  */

std::unique_ptr<tui_layout_base>
tui_layout_split::clone () const
{
  tui_layout_split *result = new tui_layout_split (m_vertical);
  for (const split &item : m_splits)
    {
      std::unique_ptr<tui_layout_base> next = item.layout->clone ();
      split s = {item.weight, std::move (next)};
      result->m_splits.push_back (std::move (s));
    }
  return std::unique_ptr<tui_layout_base> (result);
}

/* See tui-layout.h.  */

void
tui_layout_split::get_sizes (bool height, int *min_value, int *max_value)
{
  TUI_SCOPED_DEBUG_ENTER_EXIT;

  *min_value = 0;
  *max_value = 0;
  bool first_time = true;
  for (const split &item : m_splits)
    {
      int new_min, new_max;
      item.layout->get_sizes (height, &new_min, &new_max);
      /* For the mismatch case, the first time through we want to set
	 the min and max to the computed values -- the "first_time"
	 check here is just a funny way of doing that.  */
      if (height == m_vertical || first_time)
	{
	  *min_value += new_min;
	  *max_value += new_max;
	}
      else
	{
	  *min_value = std::max (*min_value, new_min);
	  *max_value = std::min (*max_value, new_max);
	}
      first_time = false;
    }

  tui_debug_printf ("min_value = %d, max_value = %d", *min_value, *max_value);
}

/* See tui-layout.h.  */

bool
tui_layout_split::first_edge_has_border_p () const
{
  if (m_splits.empty ())
    return false;
  return m_splits[0].layout->first_edge_has_border_p ();
}

/* See tui-layout.h.  */

bool
tui_layout_split::last_edge_has_border_p () const
{
  if (m_splits.empty ())
    return false;
  return m_splits.back ().layout->last_edge_has_border_p ();
}

/* See tui-layout.h.  */

void
tui_layout_split::set_weights_from_sizes ()
{
  for (int i = 0; i < m_splits.size (); ++i)
    m_splits[i].weight
      = m_vertical ? m_splits[i].layout->height : m_splits[i].layout->width;
}

/* See tui-layout.h.  */

std::string
tui_layout_split::tui_debug_weights_to_string () const
{
  std::string str;

  for (int i = 0; i < m_splits.size (); ++i)
    {
      if (i > 0)
       str += ", ";
      str += string_printf ("[%d] %d", i, m_splits[i].weight);
    }

  return str;
}

/* See tui-layout.h.  */

void
tui_layout_split::tui_debug_print_size_info
  (const std::vector<tui_layout_split::size_info> &info)
{
  gdb_assert (debug_tui);

  tui_debug_printf ("current size info data:");
  for (int i = 0; i < info.size (); ++i)
    tui_debug_printf ("  [%d] { size = %d, min = %d, max = %d, share_box = %d }",
		      i, info[i].size, info[i].min_size,
		      info[i].max_size, info[i].share_box);
}

/* See tui-layout.h.  */

tui_adjust_result
tui_layout_split::set_size (const char *name, int new_size, bool set_width_p)
{
  TUI_SCOPED_DEBUG_ENTER_EXIT;

  tui_debug_printf ("this = %p, name = %s, new_size = %d",
		    this, name, new_size);

  /* Look through the children.  If one is a layout holding the named
     window, we're done; or if one actually is the named window,
     update it.  */
  int found_index = -1;
  for (int i = 0; i < m_splits.size (); ++i)
    {
      tui_adjust_result adjusted;
      if (set_width_p)
	adjusted = m_splits[i].layout->set_width (name, new_size);
      else
	adjusted = m_splits[i].layout->set_height (name, new_size);
      if (adjusted == HANDLED)
	return HANDLED;
      if (adjusted == FOUND)
	{
	  if (set_width_p ? m_vertical : !m_vertical)
	    return FOUND;
	  found_index = i;
	  break;
	}
    }

  if (found_index == -1)
    return NOT_FOUND;
  int curr_size = (set_width_p
		   ? m_splits[found_index].layout->width
		   : m_splits[found_index].layout->height);
  if (curr_size == new_size)
    return HANDLED;

  tui_debug_printf ("found window %s at index %d", name, found_index);

  set_weights_from_sizes ();
  int delta = m_splits[found_index].weight - new_size;
  m_splits[found_index].weight = new_size;

  tui_debug_printf ("before delta (%d) distribution, weights: %s",
		    delta, tui_debug_weights_to_string ().c_str ());

  /* Distribute the "delta" over all other windows, while respecting their
     min/max sizes.  We grow each window by 1 line at a time continually
     looping over all the windows.  However, skip the window that the user
     just resized, obviously we don't want to readjust that window.  */
  bool found_window_that_can_grow_p = true;
  for (int i = 0; delta != 0; i = (i + 1) % m_splits.size ())
    {
      int index = (found_index + 1 + i) % m_splits.size ();
      if (index == found_index)
	{
	  if (!found_window_that_can_grow_p)
	    break;
	  found_window_that_can_grow_p = false;
	  continue;
	}

      int new_min, new_max;
      m_splits[index].layout->get_sizes (m_vertical, &new_min, &new_max);

      if (delta < 0)
	{
	  /* The primary window grew, so we are trying to shrink other
	     windows.  */
	  if (m_splits[index].weight > new_min)
	    {
	      m_splits[index].weight -= 1;
	      delta += 1;
	      found_window_that_can_grow_p = true;
	    }
	}
      else
	{
	  /* The primary window shrank, so we are trying to grow other
	     windows.  */
	  if (m_splits[index].weight < new_max)
	    {
	      m_splits[index].weight += 1;
	      delta -= 1;
	      found_window_that_can_grow_p = true;
	    }
	}

      tui_debug_printf ("index = %d, weight now: %d",
			index, m_splits[index].weight);
    }

  tui_debug_printf ("after delta (%d) distribution, weights: %s",
		    delta, tui_debug_weights_to_string ().c_str ());

  if (delta != 0)
    {
      if (set_width_p)
	warning (_("Invalid window width specified"));
      else
	warning (_("Invalid window height specified"));
      /* Effectively undo any modifications made here.  */
      set_weights_from_sizes ();
    }
  else
    {
      /* Simply re-apply the updated layout.  We pass false here so that
	 the cmd window can be resized.  However, we should have already
	 resized everything above to be "just right", so the apply call
	 here should not end up changing the sizes at all.  */
      apply (x, y, width, height, false);
    }

  return HANDLED;
}

/* See tui-layout.h.  */

void
tui_layout_split::apply (int x_, int y_, int width_, int height_,
			 bool preserve_cmd_win_size_p)
{
  TUI_SCOPED_DEBUG_ENTER_EXIT;

  x = x_;
  y = y_;
  width = width_;
  height = height_;

  /* In some situations we fix the size of the cmd window.  However,
     occasionally this turns out to be a mistake.  This struct is used to
     hold the original information about the cmd window, so we can restore
     it if needed.  */
  struct old_size_info
  {
    /* Constructor.  */
    old_size_info (int index_, int min_size_, int max_size_)
      : index (index_),
	min_size (min_size_),
	max_size (max_size_)
    { /* Nothing.  */ }

    /* The index in m_splits where the cmd window was found.  */
    int index;

    /* The previous min/max size.  */
    int min_size;
    int max_size;
  };

  /* This is given a value only if we fix the size of the cmd window.  */
  gdb::optional<old_size_info> old_cmd_info;

  std::vector<size_info> info (m_splits.size ());

  tui_debug_printf ("weights are: %s",
		    tui_debug_weights_to_string ().c_str ());

  /* Step 1: Find the min and max size of each sub-layout.
     Fixed-sized layouts are given their desired size, and then the
     remaining space is distributed among the remaining windows
     according to the weights given.  */
  int available_size = m_vertical ? height : width;
  int last_index = -1;
  int total_weight = 0;
  for (int i = 0; i < m_splits.size (); ++i)
    {
      bool cmd_win_already_exists = TUI_CMD_WIN != nullptr;

      /* Always call get_sizes, to ensure that the window is
	 instantiated.  This is a bit gross but less gross than adding
	 special cases for this in other places.  */
      m_splits[i].layout->get_sizes (m_vertical, &info[i].min_size,
				     &info[i].max_size);

      if (preserve_cmd_win_size_p
	  && cmd_win_already_exists
	  && m_splits[i].layout->get_name () != nullptr
	  && strcmp (m_splits[i].layout->get_name (), "cmd") == 0)
	{
	  /* Save the old cmd window information, in case we need to
	     restore it later.  */
	  old_cmd_info.emplace (i, info[i].min_size, info[i].max_size);

	  /* If this layout has never been applied, then it means the
	     user just changed the layout.  In this situation, it's
	     desirable to keep the size of the command window the
	     same.  Setting the min and max sizes this way ensures
	     that the resizing step, below, does the right thing with
	     this window.  */
	  info[i].min_size = (m_vertical
			      ? TUI_CMD_WIN->height
			      : TUI_CMD_WIN->width);
	  info[i].max_size = info[i].min_size;
	}

      if (info[i].min_size == info[i].max_size)
	available_size -= info[i].min_size;
      else
	{
	  last_index = i;
	  total_weight += m_splits[i].weight;
	}

      /* Two adjacent boxed windows will share a border, making a bit
	 more size available.  */
      if (i > 0
	  && m_splits[i - 1].layout->last_edge_has_border_p ()
	  && m_splits[i].layout->first_edge_has_border_p ())
	info[i].share_box = true;
    }

  /* If last_index is set then we have a window that is not of a fixed
     size.  This window will have its size calculated below, which requires
     that the total_weight not be zero (we divide by total_weight, so don't
     want a floating-point exception).  */
  gdb_assert (last_index == -1 || total_weight > 0);

  /* Step 2: Compute the size of each sub-layout.  Fixed-sized items
     are given their fixed size, while others are resized according to
     their weight.  */
  int used_size = 0;
  for (int i = 0; i < m_splits.size (); ++i)
    {
      if (info[i].min_size != info[i].max_size)
	{
	  /* Compute the height and clamp to the allowable range.  */
	  info[i].size = available_size * m_splits[i].weight / total_weight;
	  if (info[i].size > info[i].max_size)
	    info[i].size = info[i].max_size;
	  if (info[i].size < info[i].min_size)
	    info[i].size = info[i].min_size;
	  /* Keep a total of all the size we've used so far (we gain some
	     size back if this window can share a border with a preceding
	     window).  Any unused space will be distributed between all of
	     the other windows (while respecting min/max sizes) later in
	     this function.  */
	  used_size += info[i].size;
	  if (info[i].share_box)
	    --used_size;
	}
      else
	info[i].size = info[i].min_size;
    }

  if (debug_tui)
    {
      tui_debug_printf ("after initial size calculation");
      tui_debug_printf ("available_size = %d, used_size = %d",
			available_size, used_size);
      tui_debug_printf ("total_weight = %d, last_index = %d",
			total_weight, last_index);
      tui_debug_print_size_info (info);
    }

  /* If we didn't find any sub-layouts that were of a non-fixed size, but
     we did find the cmd window, then we can consider that a sort-of
     non-fixed size sub-layout.

     The cmd window might, initially, be of a fixed size (see above), but,
     we are willing to relax this constraint if required to correctly apply
     this layout (see below).  */
  if (last_index == -1 && old_cmd_info.has_value ())
    last_index = old_cmd_info->index;

  /* Allocate any leftover size.  */
  if (available_size != used_size && last_index != -1)
    {
      /* Loop over all windows until the amount of used space is equal to
	 the amount of available space.  There's an escape hatch within
	 the loop in case we can't find any sub-layouts to resize.  */
      bool found_window_that_can_grow_p = true;
      for (int idx = last_index;
	   available_size != used_size;
	   idx = (idx + 1) % m_splits.size ())
	{
	  /* Every time we get back to last_index, which is where the loop
	     started, we check to make sure that we did assign some space
	     to a window, bringing used_size closer to available_size.

	     If we didn't, but the cmd window is of a fixed size, then we
	     can make the console window non-fixed-size, and continue
	     around the loop, hopefully, this will allow the layout to be
	     applied correctly.

	     If we still make it around the loop without moving used_size
	     closer to available_size, then there's nothing more we can do,
	     and we break out of the loop.  */
	  if (idx == last_index)
	    {
	      /* If the used_size is greater than the available_size then
		 this indicates that the fixed-sized sub-layouts claimed
		 more space than is available.  This layout is not going to
		 work.  Our only hope at this point is to make the cmd
		 window non-fixed-size (if possible), and hope we can
		 shrink this enough to fit the rest of the sub-layouts in.

		 Alternatively, we've made it around the loop without
		 adjusting any window's size.  This likely means all
		 windows have hit their min or max size.  Again, our only
		 hope is to make the cmd window non-fixed-size, and hope
		 this fixes all our problems.  */
	      if (old_cmd_info.has_value ()
		  && ((available_size < used_size)
		      || !found_window_that_can_grow_p))
		{
		  info[old_cmd_info->index].min_size = old_cmd_info->min_size;
		  info[old_cmd_info->index].max_size = old_cmd_info->max_size;
		  tui_debug_printf
		    ("restoring index %d (cmd) size limits, min = %d, max = %d",
		     old_cmd_info->index, old_cmd_info->min_size,
		     old_cmd_info->max_size);
		  old_cmd_info.reset ();
		}
	      else if (!found_window_that_can_grow_p)
		break;
	      found_window_that_can_grow_p = false;
	    }

	  if (available_size > used_size
	      && info[idx].size < info[idx].max_size)
	    {
	      found_window_that_can_grow_p = true;
	      info[idx].size += 1;
	      used_size += 1;
	    }
	  else if (available_size < used_size
		   && info[idx].size > info[idx].min_size)
	    {
	      found_window_that_can_grow_p = true;
	      info[idx].size -= 1;
	      used_size -= 1;
	    }
	}

      if (debug_tui)
	{
	  tui_debug_printf ("after final size calculation");
	  tui_debug_printf ("available_size = %d, used_size = %d",
			    available_size, used_size);
	  tui_debug_printf ("total_weight = %d, last_index = %d",
			    total_weight, last_index);
	  tui_debug_print_size_info (info);
	}
    }

  /* Step 3: Resize.  */
  int size_accum = 0;
  const int maximum = m_vertical ? height : width;
  for (int i = 0; i < m_splits.size (); ++i)
    {
      /* If we fall off the bottom, just make allocations overlap.
	 GIGO.  */
      if (size_accum + info[i].size > maximum)
	size_accum = maximum - info[i].size;
      else if (info[i].share_box)
	--size_accum;
      if (m_vertical)
	m_splits[i].layout->apply (x, y + size_accum, width, info[i].size,
				   preserve_cmd_win_size_p);
      else
	m_splits[i].layout->apply (x + size_accum, y, info[i].size, height,
				   preserve_cmd_win_size_p);
      size_accum += info[i].size;
    }
}

/* See tui-layout.h.  */

void
tui_layout_split::remove_windows (const char *name)
{
  for (int i = 0; i < m_splits.size (); ++i)
    {
      const char *this_name = m_splits[i].layout->get_name ();
      if (this_name == nullptr)
	m_splits[i].layout->remove_windows (name);
      else if (strcmp (this_name, name) == 0
	       || strcmp (this_name, CMD_NAME) == 0
	       || strcmp (this_name, STATUS_NAME) == 0)
	{
	  /* Keep.  */
	}
      else
	{
	  m_splits.erase (m_splits.begin () + i);
	  --i;
	}
    }
}

/* See tui-layout.h.  */

void
tui_layout_split::replace_window (const char *name, const char *new_window)
{
  for (auto &item : m_splits)
    item.layout->replace_window (name, new_window);
}

/* See tui-layout.h.  */

void
tui_layout_split::specification (ui_file *output, int depth)
{
  if (depth > 0)
    gdb_puts ("{", output);

  if (!m_vertical)
    gdb_puts ("-horizontal ", output);

  bool first = true;
  for (auto &item : m_splits)
    {
      if (!first)
	gdb_puts (" ", output);
      first = false;
      item.layout->specification (output, depth + 1);
      gdb_printf (output, " %d", item.weight);
    }

  if (depth > 0)
    gdb_puts ("}", output);
}

/* See tui-layout.h.  */

std::string
tui_layout_split::layout_fingerprint () const
{
  for (auto &item : m_splits)
    {
      std::string fp = item.layout->layout_fingerprint ();
      if (!fp.empty () && m_splits.size () != 1)
	return std::string (m_vertical ? "V" : "H") + fp;
    }

  return "";
}

/* Destroy the layout associated with SELF.  */

static void
destroy_layout (struct cmd_list_element *self, void *context)
{
  tui_layout_split *layout = (tui_layout_split *) context;
  size_t index = find_layout (layout);
  layouts.erase (layouts.begin () + index);
}

/* List holding the sub-commands of "layout".  */

static struct cmd_list_element *layout_list;

/* Called to implement 'tui layout'.  */

static void
tui_layout_command (const char *args, int from_tty)
{
  help_list (layout_list, "tui layout ", all_commands, gdb_stdout);
}

/* Add a "layout" command with name NAME that switches to LAYOUT.  */

static struct cmd_list_element *
add_layout_command (const char *name, tui_layout_split *layout)
{
  struct cmd_list_element *cmd;

  string_file spec;
  layout->specification (&spec, 0);

  gdb::unique_xmalloc_ptr<char> doc
    = xstrprintf (_("Apply the \"%s\" layout.\n\
This layout was created using:\n\
  tui new-layout %s %s"),
		  name, name, spec.c_str ());

  cmd = add_cmd (name, class_tui, nullptr, doc.get (), &layout_list);
  cmd->set_context (layout);
  /* There is no API to set this.  */
  cmd->func = tui_apply_layout;
  cmd->destroyer = destroy_layout;
  cmd->doc_allocated = 1;
  doc.release ();
  layouts.emplace_back (layout);

  return cmd;
}

/* Initialize the standard layouts.  */

static void
initialize_layouts ()
{
  tui_layout_split *layout;

  layout = new tui_layout_split ();
  layout->add_window (SRC_NAME, 2);
  layout->add_window (STATUS_NAME, 0);
  layout->add_window (CMD_NAME, 1);
  add_layout_command (SRC_NAME, layout);

  layout = new tui_layout_split ();
  layout->add_window (DISASSEM_NAME, 2);
  layout->add_window (STATUS_NAME, 0);
  layout->add_window (CMD_NAME, 1);
  add_layout_command (DISASSEM_NAME, layout);

  layout = new tui_layout_split ();
  layout->add_window (SRC_NAME, 1);
  layout->add_window (DISASSEM_NAME, 1);
  layout->add_window (STATUS_NAME, 0);
  layout->add_window (CMD_NAME, 1);
  add_layout_command ("split", layout);

  layout = new tui_layout_split ();
  layout->add_window (DATA_NAME, 1);
  layout->add_window (SRC_NAME, 1);
  layout->add_window (STATUS_NAME, 0);
  layout->add_window (CMD_NAME, 1);
  layouts.emplace_back (layout);
  src_regs_layout = layout;

  layout = new tui_layout_split ();
  layout->add_window (DATA_NAME, 1);
  layout->add_window (DISASSEM_NAME, 1);
  layout->add_window (STATUS_NAME, 0);
  layout->add_window (CMD_NAME, 1);
  layouts.emplace_back (layout);
  asm_regs_layout = layout;
}



/* A helper function that returns true if NAME is the name of an
   available window.  */

static bool
validate_window_name (const std::string &name)
{
  auto iter = known_window_types.find (name);
  return iter != known_window_types.end ();
}

/* Implementation of the "tui new-layout" command.  */

static void
tui_new_layout_command (const char *spec, int from_tty)
{
  std::string new_name = extract_arg (&spec);
  if (new_name.empty ())
    error (_("No layout name specified"));
  if (new_name[0] == '-')
    error (_("Layout name cannot start with '-'"));

  bool is_vertical = true;
  spec = skip_spaces (spec);
  if (check_for_argument (&spec, "-horizontal"))
    is_vertical = false;

  std::vector<std::unique_ptr<tui_layout_split>> splits;
  splits.emplace_back (new tui_layout_split (is_vertical));
  std::unordered_set<std::string> seen_windows;
  while (true)
    {
      spec = skip_spaces (spec);
      if (spec[0] == '\0')
	break;

      if (spec[0] == '{')
	{
	  is_vertical = true;
	  spec = skip_spaces (spec + 1);
	  if (check_for_argument (&spec, "-horizontal"))
	    is_vertical = false;
	  splits.emplace_back (new tui_layout_split (is_vertical));
	  continue;
	}

      bool is_close = false;
      std::string name;
      if (spec[0] == '}')
	{
	  is_close = true;
	  ++spec;
	  if (splits.size () == 1)
	    error (_("Extra '}' in layout specification"));
	}
      else
	{
	  name = extract_arg (&spec);
	  if (name.empty ())
	    break;
	  if (!validate_window_name (name))
	    error (_("Unknown window \"%s\""), name.c_str ());
	  if (seen_windows.find (name) != seen_windows.end ())
	    error (_("Window \"%s\" seen twice in layout"), name.c_str ());
	}

      ULONGEST weight = get_ulongest (&spec, '}');
      if ((int) weight != weight)
	error (_("Weight out of range: %s"), pulongest (weight));
      if (is_close)
	{
	  std::unique_ptr<tui_layout_split> last_split
	    = std::move (splits.back ());
	  splits.pop_back ();
	  splits.back ()->add_split (std::move (last_split), weight);
	}
      else
	{
	  splits.back ()->add_window (name.c_str (), weight);
	  seen_windows.insert (name);
	}
    }
  if (splits.size () > 1)
    error (_("Missing '}' in layout specification"));
  if (seen_windows.empty ())
    error (_("New layout does not contain any windows"));
  if (seen_windows.find (CMD_NAME) == seen_windows.end ())
    error (_("New layout does not contain the \"" CMD_NAME "\" window"));

  gdb::unique_xmalloc_ptr<char> cmd_name
    = make_unique_xstrdup (new_name.c_str ());
  std::unique_ptr<tui_layout_split> new_layout = std::move (splits.back ());
  struct cmd_list_element *cmd
    = add_layout_command (cmd_name.get (), new_layout.get ());
  cmd->name_allocated = 1;
  cmd_name.release ();
  new_layout.release ();
}

/* Function to initialize gdb commands, for tui window layout
   manipulation.  */

void _initialize_tui_layout ();
void
_initialize_tui_layout ()
{
  struct cmd_list_element *layout_cmd
    = add_prefix_cmd ("layout", class_tui, tui_layout_command, _("\
Change the layout of windows.\n\
Usage: tui layout prev | next | LAYOUT-NAME"),
		      &layout_list, 0, tui_get_cmd_list ());
  add_com_alias ("layout", layout_cmd, class_tui, 0);

  add_cmd ("next", class_tui, tui_next_layout_command,
	   _("Apply the next TUI layout."),
	   &layout_list);
  add_cmd ("prev", class_tui, tui_prev_layout_command,
	   _("Apply the previous TUI layout."),
	   &layout_list);
  add_cmd ("regs", class_tui, tui_regs_layout_command,
	   _("Apply the TUI register layout."),
	   &layout_list);

  add_cmd ("new-layout", class_tui, tui_new_layout_command,
	   _("Create a new TUI layout.\n\
Usage: tui new-layout [-horizontal] NAME WINDOW WEIGHT [WINDOW WEIGHT]...\n\
Create a new TUI layout.  The new layout will be named NAME,\n\
and can be accessed using \"layout NAME\".\n\
The windows will be displayed in the specified order.\n\
A WINDOW can also be of the form:\n\
  { [-horizontal] NAME WEIGHT [NAME WEIGHT]... }\n\
This form indicates a sub-frame.\n\
Each WEIGHT is an integer, which holds the relative size\n\
to be allocated to the window."),
	   tui_get_cmd_list ());

  initialize_layouts ();
  initialize_known_windows ();
}
