/* TUI layout window management.

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

#include "defs.h"
#include "arch-utils.h"
#include "command.h"
#include "symtab.h"
#include "frame.h"
#include "source.h"
#include <ctype.h>

#include "tui/tui.h"
#include "tui/tui-data.h"
#include "tui/tui-windata.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 "gdb_string.h"
#include "gdb_curses.h"

/*******************************
** Static Local Decls
********************************/
static void show_layout (enum tui_layout_type);
static void init_gen_win_info (struct tui_gen_win_info *, 
			       enum tui_win_type, 
			       int, int, int, int);
static void *init_and_make_win (void *, enum tui_win_type, 
				int, int, int, int, int);
static void show_source_or_disasm_and_command (enum tui_layout_type);
static void make_source_or_disasm_window (struct tui_win_info **, 
					  enum tui_win_type, 
					  int, int);
static void make_command_window (struct tui_win_info **, int, int);
static void make_source_window (struct tui_win_info **, int, int);
static void make_disasm_window (struct tui_win_info **, int, int);
static void make_data_window (struct tui_win_info **, int, int);
static void show_source_command (void);
static void show_disasm_command (void);
static void show_source_disasm_command (void);
static void show_data (enum tui_layout_type);
static enum tui_layout_type next_layout (void);
static enum tui_layout_type prev_layout (void);
static void tui_layout_command (char *, int);
static void tui_toggle_layout_command (char *, int);
static void tui_toggle_split_layout_command (char *, int);
static void extract_display_start_addr (struct gdbarch **, CORE_ADDR *);
static void tui_handle_xdb_layout (struct tui_layout_def *);


/***************************************
** DEFINITIONS
***************************************/

#define LAYOUT_USAGE     "Usage: layout prev | next | <layout_name> \n"

/* Show the screen layout defined.  */
static void
show_layout (enum tui_layout_type layout)
{
  enum tui_layout_type cur_layout = tui_current_layout ();

  if (layout != cur_layout)
    {
      /* Since the new layout may cause changes in window size, we
         should free the content and reallocate on next display of
         source/asm.  */
      tui_free_all_source_wins_content ();
      tui_clear_source_windows ();
      if (layout == SRC_DATA_COMMAND 
	  || layout == DISASSEM_DATA_COMMAND)
	{
	  show_data (layout);
	  tui_refresh_all (tui_win_list);
	}
      else
	{
	  /* First make the current layout be invisible.  */
	  tui_make_all_invisible ();
	  tui_make_invisible (tui_locator_win_info_ptr ());

	  switch (layout)
	    {
	      /* Now show the new layout.  */
	    case SRC_COMMAND:
	      show_source_command ();
	      tui_add_to_source_windows (TUI_SRC_WIN);
	      break;
	    case DISASSEM_COMMAND:
	      show_disasm_command ();
	      tui_add_to_source_windows (TUI_DISASM_WIN);
	      break;
	    case SRC_DISASSEM_COMMAND:
	      show_source_disasm_command ();
	      tui_add_to_source_windows (TUI_SRC_WIN);
	      tui_add_to_source_windows (TUI_DISASM_WIN);
	      break;
	    default:
	      break;
	    }
	}
    }
}


/* Function to set the layout to SRC_COMMAND, DISASSEM_COMMAND,
   SRC_DISASSEM_COMMAND, SRC_DATA_COMMAND, or DISASSEM_DATA_COMMAND.
   If the layout is SRC_DATA_COMMAND, DISASSEM_DATA_COMMAND, or
   UNDEFINED_LAYOUT, then the data window is populated according to
   regs_display_type.  */
enum tui_status
tui_set_layout (enum tui_layout_type layout_type,
		enum tui_register_display_type regs_display_type)
{
  enum tui_status status = TUI_SUCCESS;

  if (layout_type != UNDEFINED_LAYOUT 
      || regs_display_type != TUI_UNDEFINED_REGS)
    {
      enum tui_layout_type cur_layout = tui_current_layout (),
	new_layout = UNDEFINED_LAYOUT;
      int regs_populate = FALSE;
      struct gdbarch *gdbarch;
      CORE_ADDR addr;
      struct tui_win_info *win_with_focus = tui_win_with_focus ();
      struct tui_layout_def *layout_def = tui_layout_def ();

      extract_display_start_addr (&gdbarch, &addr);

      if (layout_type == UNDEFINED_LAYOUT
	  && regs_display_type != TUI_UNDEFINED_REGS)
	{
	  if (cur_layout == SRC_DISASSEM_COMMAND)
	    new_layout = DISASSEM_DATA_COMMAND;
	  else if (cur_layout == SRC_COMMAND 
		   || cur_layout == SRC_DATA_COMMAND)
	    new_layout = SRC_DATA_COMMAND;
	  else if (cur_layout == DISASSEM_COMMAND 
		   || cur_layout == DISASSEM_DATA_COMMAND)
	    new_layout = DISASSEM_DATA_COMMAND;
	}
      else
	new_layout = layout_type;

      regs_populate = (new_layout == SRC_DATA_COMMAND 
		       || new_layout == DISASSEM_DATA_COMMAND 
		       || regs_display_type != TUI_UNDEFINED_REGS);
      if (new_layout != cur_layout
	  || regs_display_type != TUI_UNDEFINED_REGS)
	{
	  if (new_layout != cur_layout)
	    {
	      show_layout (new_layout);

	      /* Now determine where focus should be.  */
	      if (win_with_focus != TUI_CMD_WIN)
		{
		  switch (new_layout)
		    {
		    case SRC_COMMAND:
		      tui_set_win_focus_to (TUI_SRC_WIN);
		      layout_def->display_mode = SRC_WIN;
		      layout_def->split = FALSE;
		      break;
		    case DISASSEM_COMMAND:
		      /* The previous layout was not showing code.
		         This can happen if there is no source
		         available:

		         1. if the source file is in another dir OR
		         2. if target was compiled without -g
		         We still want to show the assembly though!  */

		      tui_get_begin_asm_address (&gdbarch, &addr);
		      tui_set_win_focus_to (TUI_DISASM_WIN);
		      layout_def->display_mode = DISASSEM_WIN;
		      layout_def->split = FALSE;
		      break;
		    case SRC_DISASSEM_COMMAND:
		      /* The previous layout was not showing code.
		         This can happen if there is no source
		         available:

		         1. if the source file is in another dir OR
		         2. if target was compiled without -g
		         We still want to show the assembly though!  */

		      tui_get_begin_asm_address (&gdbarch, &addr);
		      if (win_with_focus == TUI_SRC_WIN)
			tui_set_win_focus_to (TUI_SRC_WIN);
		      else
			tui_set_win_focus_to (TUI_DISASM_WIN);
		      layout_def->split = TRUE;
		      break;
		    case SRC_DATA_COMMAND:
		      if (win_with_focus != TUI_DATA_WIN)
			tui_set_win_focus_to (TUI_SRC_WIN);
		      else
			tui_set_win_focus_to (TUI_DATA_WIN);
		      layout_def->display_mode = SRC_WIN;
		      layout_def->split = FALSE;
		      break;
		    case DISASSEM_DATA_COMMAND:
		      /* The previous layout was not showing code.
		         This can happen if there is no source
		         available:

			 1. if the source file is in another dir OR
		         2. if target was compiled without -g
		         We still want to show the assembly though!  */

		      tui_get_begin_asm_address (&gdbarch, &addr);
		      if (win_with_focus != TUI_DATA_WIN)
			tui_set_win_focus_to (TUI_DISASM_WIN);
		      else
			tui_set_win_focus_to (TUI_DATA_WIN);
		      layout_def->display_mode = DISASSEM_WIN;
		      layout_def->split = FALSE;
		      break;
		    default:
		      break;
		    }
		}
	      /*
	       * Now update the window content.
	       */
	      if (!regs_populate 
		  && (new_layout == SRC_DATA_COMMAND 
		      || new_layout == DISASSEM_DATA_COMMAND))
		tui_display_all_data ();

	      tui_update_source_windows_with_addr (gdbarch, addr);
	    }
	  if (regs_populate)
	    {
              tui_show_registers (TUI_DATA_WIN->detail.data_display_info.current_group);
	    }
	}
    }
  else
    status = TUI_FAILURE;

  return status;
}

/* Add the specified window to the layout in a logical way.  This
   means setting up the most logical layout given the window to be
   added.  */
void
tui_add_win_to_layout (enum tui_win_type type)
{
  enum tui_layout_type cur_layout = tui_current_layout ();

  switch (type)
    {
    case SRC_WIN:
      if (cur_layout != SRC_COMMAND
	  && cur_layout != SRC_DISASSEM_COMMAND
	  && cur_layout != SRC_DATA_COMMAND)
	{
	  tui_clear_source_windows_detail ();
	  if (cur_layout == DISASSEM_DATA_COMMAND)
	    show_layout (SRC_DATA_COMMAND);
	  else
	    show_layout (SRC_COMMAND);
	}
      break;
    case DISASSEM_WIN:
      if (cur_layout != DISASSEM_COMMAND
	  && cur_layout != SRC_DISASSEM_COMMAND
	  && cur_layout != DISASSEM_DATA_COMMAND)
	{
	  tui_clear_source_windows_detail ();
	  if (cur_layout == SRC_DATA_COMMAND)
	    show_layout (DISASSEM_DATA_COMMAND);
	  else
	    show_layout (DISASSEM_COMMAND);
	}
      break;
    case DATA_WIN:
      if (cur_layout != SRC_DATA_COMMAND
	  && cur_layout != DISASSEM_DATA_COMMAND)
	{
	  if (cur_layout == DISASSEM_COMMAND)
	    show_layout (DISASSEM_DATA_COMMAND);
	  else
	    show_layout (SRC_DATA_COMMAND);
	}
      break;
    default:
      break;
    }
}


/* Answer the height of a window.  If it hasn't been created yet,
   answer what the height of a window would be based upon its type and
   the layout.  */
int
tui_default_win_height (enum tui_win_type type, 
			enum tui_layout_type layout)
{
  int h;

  if (tui_win_list[type] != (struct tui_win_info *) NULL)
    h = tui_win_list[type]->generic.height;
  else
    {
      switch (layout)
	{
	case SRC_COMMAND:
	case DISASSEM_COMMAND:
	  if (TUI_CMD_WIN == NULL)
	    h = tui_term_height () / 2;
	  else
	    h = tui_term_height () - TUI_CMD_WIN->generic.height;
	  break;
	case SRC_DISASSEM_COMMAND:
	case SRC_DATA_COMMAND:
	case DISASSEM_DATA_COMMAND:
	  if (TUI_CMD_WIN == NULL)
	    h = tui_term_height () / 3;
	  else
	    h = (tui_term_height () - TUI_CMD_WIN->generic.height) / 2;
	  break;
	default:
	  h = 0;
	  break;
	}
    }

  return h;
}


/* Answer the height of a window.  If it hasn't been created yet,
   answer what the height of a window would be based upon its type and
   the layout.  */
int
tui_default_win_viewport_height (enum tui_win_type type,
				 enum tui_layout_type layout)
{
  int h;

  h = tui_default_win_height (type, layout);

  if (tui_win_list[type] == TUI_CMD_WIN)
    h -= 1;
  else
    h -= 2;

  return h;
}


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

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

void
_initialize_tui_layout (void)
{
  add_com ("layout", class_tui, tui_layout_command, _("\
Change the layout of windows.\n\
Usage: layout prev | next | <layout_name> \n\
Layout names are:\n\
   src   : Displays source and command windows.\n\
   asm   : Displays disassembly and command windows.\n\
   split : Displays source, disassembly and command windows.\n\
   regs  : Displays register window. If existing layout\n\
           is source/command or assembly/command, the \n\
           register window is displayed. If the\n\
           source/assembly/command (split) is displayed, \n\
           the register window is displayed with \n\
           the window that has current logical focus.\n"));
  if (xdb_commands)
    {
      add_com ("td", class_tui, tui_toggle_layout_command, _("\
Toggle between Source/Command and Disassembly/Command layouts.\n"));
      add_com ("ts", class_tui, tui_toggle_split_layout_command, _("\
Toggle between Source/Command or Disassembly/Command and \n\
Source/Disassembly/Command layouts.\n"));
    }
}


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


/* Function to set the layout to SRC, ASM, SPLIT, NEXT, PREV, DATA,
   REGS, $REGS, $GREGS, $FREGS, $SREGS.  */
enum tui_status
tui_set_layout_for_display_command (const char *layout_name)
{
  enum tui_status status = TUI_SUCCESS;

  if (layout_name != (char *) NULL)
    {
      int i;
      char *buf_ptr;
      enum tui_layout_type new_layout = UNDEFINED_LAYOUT;
      enum tui_register_display_type dpy_type = TUI_UNDEFINED_REGS;
      enum tui_layout_type cur_layout = tui_current_layout ();

      buf_ptr = (char *) xstrdup (layout_name);
      for (i = 0; (i < strlen (layout_name)); i++)
	buf_ptr[i] = toupper (buf_ptr[i]);

      /* First check for ambiguous input.  */
      if (strlen (buf_ptr) <= 1 
	  && (*buf_ptr == 'S' || *buf_ptr == '$'))
	{
	  warning (_("Ambiguous command input."));
	  status = TUI_FAILURE;
	}
      else
	{
	  if (subset_compare (buf_ptr, "SRC"))
	    new_layout = SRC_COMMAND;
	  else if (subset_compare (buf_ptr, "ASM"))
	    new_layout = DISASSEM_COMMAND;
	  else if (subset_compare (buf_ptr, "SPLIT"))
	    new_layout = SRC_DISASSEM_COMMAND;
	  else if (subset_compare (buf_ptr, "REGS") 
		   || subset_compare (buf_ptr, TUI_GENERAL_SPECIAL_REGS_NAME)
		   || subset_compare (buf_ptr, TUI_GENERAL_REGS_NAME)
		   || subset_compare (buf_ptr, TUI_FLOAT_REGS_NAME)
		   || subset_compare (buf_ptr, TUI_SPECIAL_REGS_NAME))
	    {
	      if (cur_layout == SRC_COMMAND 
		  || cur_layout == SRC_DATA_COMMAND)
		new_layout = SRC_DATA_COMMAND;
	      else
		new_layout = DISASSEM_DATA_COMMAND;

	      /* Could ifdef out the following code. when compile with
		 -z, there are null pointer references that cause a
		 core dump if 'layout regs' is the first layout
		 command issued by the user. HP has asked us to hook
		 up this code.  - edie epstein  */
	      if (subset_compare (buf_ptr, TUI_FLOAT_REGS_NAME))
		{
		  if (TUI_DATA_WIN->detail.data_display_info.regs_display_type
		      != TUI_SFLOAT_REGS
		      && TUI_DATA_WIN->detail.data_display_info.regs_display_type
		      != TUI_DFLOAT_REGS)
		    dpy_type = TUI_SFLOAT_REGS;
		  else
		    dpy_type =
		      TUI_DATA_WIN->detail.data_display_info.regs_display_type;
		}
	      else if (subset_compare (buf_ptr,
				      TUI_GENERAL_SPECIAL_REGS_NAME))
		dpy_type = TUI_GENERAL_AND_SPECIAL_REGS;
	      else if (subset_compare (buf_ptr, TUI_GENERAL_REGS_NAME))
		dpy_type = TUI_GENERAL_REGS;
	      else if (subset_compare (buf_ptr, TUI_SPECIAL_REGS_NAME))
		dpy_type = TUI_SPECIAL_REGS;
	      else if (TUI_DATA_WIN)
		{
		  if (TUI_DATA_WIN->detail.data_display_info.regs_display_type
		      != TUI_UNDEFINED_REGS)
		    dpy_type
		      = TUI_DATA_WIN->detail.data_display_info.regs_display_type;
		  else
		    dpy_type = TUI_GENERAL_REGS;
		}

	      /* End of potential ifdef.
	       */

	      /* If ifdefed out code above, then assume that the user
		 wishes to display the general purpose registers .
	      */

	      /* dpy_type = TUI_GENERAL_REGS; */
	    }
	  else if (subset_compare (buf_ptr, "NEXT"))
	    new_layout = next_layout ();
	  else if (subset_compare (buf_ptr, "PREV"))
	    new_layout = prev_layout ();
	  else
	    status = TUI_FAILURE;

	  tui_set_layout (new_layout, dpy_type);
	}
      xfree (buf_ptr);
    }
  else
    status = TUI_FAILURE;

  return status;
}


static void
extract_display_start_addr (struct gdbarch **gdbarch_p, CORE_ADDR *addr_p)
{
  enum tui_layout_type cur_layout = tui_current_layout ();
  struct gdbarch *gdbarch = get_current_arch ();
  CORE_ADDR addr;
  CORE_ADDR pc;
  struct symtab_and_line cursal = get_current_source_symtab_and_line ();

  switch (cur_layout)
    {
    case SRC_COMMAND:
    case SRC_DATA_COMMAND:
      gdbarch = TUI_SRC_WIN->detail.source_info.gdbarch;
      find_line_pc (cursal.symtab,
		    TUI_SRC_WIN->detail.source_info.start_line_or_addr.u.line_no,
		    &pc);
      addr = pc;
      break;
    case DISASSEM_COMMAND:
    case SRC_DISASSEM_COMMAND:
    case DISASSEM_DATA_COMMAND:
      gdbarch = TUI_DISASM_WIN->detail.source_info.gdbarch;
      addr = TUI_DISASM_WIN->detail.source_info.start_line_or_addr.u.addr;
      break;
    default:
      addr = 0;
      break;
    }

  *gdbarch_p = gdbarch;
  *addr_p = addr;
}


static void
tui_handle_xdb_layout (struct tui_layout_def *layout_def)
{
  if (layout_def->split)
    {
      tui_set_layout (SRC_DISASSEM_COMMAND, TUI_UNDEFINED_REGS);
      tui_set_win_focus_to (tui_win_list[layout_def->display_mode]);
    }
  else
    {
      if (layout_def->display_mode == SRC_WIN)
	tui_set_layout (SRC_COMMAND, TUI_UNDEFINED_REGS);
      else
	tui_set_layout (DISASSEM_DATA_COMMAND, layout_def->regs_display_type);
    }
}


static void
tui_toggle_layout_command (char *arg, int from_tty)
{
  struct tui_layout_def *layout_def = tui_layout_def ();

  /* Make sure the curses mode is enabled.  */
  tui_enable ();
  if (layout_def->display_mode == SRC_WIN)
    layout_def->display_mode = DISASSEM_WIN;
  else
    layout_def->display_mode = SRC_WIN;

  if (!layout_def->split)
    tui_handle_xdb_layout (layout_def);
}


static void
tui_toggle_split_layout_command (char *arg, int from_tty)
{
  struct tui_layout_def *layout_def = tui_layout_def ();

  /* Make sure the curses mode is enabled.  */
  tui_enable ();
  layout_def->split = (!layout_def->split);
  tui_handle_xdb_layout (layout_def);
}


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

  /* Switch to the selected layout.  */
  if (tui_set_layout_for_display_command (arg) != TUI_SUCCESS)
    warning (_("Invalid layout specified.\n%s"), LAYOUT_USAGE);

}

/* Answer the previous layout to cycle to.  */
static enum tui_layout_type
next_layout (void)
{
  enum tui_layout_type new_layout;

  new_layout = tui_current_layout ();
  if (new_layout == UNDEFINED_LAYOUT)
    new_layout = SRC_COMMAND;
  else
    {
      new_layout++;
      if (new_layout == UNDEFINED_LAYOUT)
	new_layout = SRC_COMMAND;
    }

  return new_layout;
}


/* Answer the next layout to cycle to.  */
static enum tui_layout_type
prev_layout (void)
{
  enum tui_layout_type new_layout;

  new_layout = tui_current_layout ();
  if (new_layout == SRC_COMMAND)
    new_layout = DISASSEM_DATA_COMMAND;
  else
    {
      new_layout--;
      if (new_layout == UNDEFINED_LAYOUT)
	new_layout = DISASSEM_DATA_COMMAND;
    }

  return new_layout;
}



static void
make_command_window (struct tui_win_info **win_info_ptr, 
		     int height, int origin_y)
{
  *win_info_ptr = init_and_make_win (*win_info_ptr,
				     CMD_WIN,
				     height,
				     tui_term_width (),
				     0,
				     origin_y,
				     DONT_BOX_WINDOW);

  (*win_info_ptr)->can_highlight = FALSE;
}


/* make_source_window().
 */
static void
make_source_window (struct tui_win_info **win_info_ptr, 
		    int height, int origin_y)
{
  make_source_or_disasm_window (win_info_ptr, SRC_WIN, height, origin_y);

  return;
}				/* make_source_window */


/* make_disasm_window().
 */
static void
make_disasm_window (struct tui_win_info **win_info_ptr, 
		    int height, int origin_y)
{
  make_source_or_disasm_window (win_info_ptr, DISASSEM_WIN, height, origin_y);

  return;
}				/* make_disasm_window */


static void
make_data_window (struct tui_win_info **win_info_ptr, 
		  int height, int origin_y)
{
  *win_info_ptr = init_and_make_win (*win_info_ptr,
				     DATA_WIN,
				     height,
				     tui_term_width (),
				     0,
				     origin_y,
				     BOX_WINDOW);
}



/* Show the Source/Command layout.  */
static void
show_source_command (void)
{
  show_source_or_disasm_and_command (SRC_COMMAND);
}


/* Show the Dissassem/Command layout.  */
static void
show_disasm_command (void)
{
  show_source_or_disasm_and_command (DISASSEM_COMMAND);
}


/* Show the Source/Disassem/Command layout.  */
static void
show_source_disasm_command (void)
{
  if (tui_current_layout () != SRC_DISASSEM_COMMAND)
    {
      int cmd_height, src_height, asm_height;

      if (TUI_CMD_WIN != NULL)
	cmd_height = TUI_CMD_WIN->generic.height;
      else
	cmd_height = tui_term_height () / 3;

      src_height = (tui_term_height () - cmd_height) / 2;
      asm_height = tui_term_height () - (src_height + cmd_height);

      if (TUI_SRC_WIN == NULL)
	make_source_window (&TUI_SRC_WIN, src_height, 0);
      else
	{
	  init_gen_win_info (&TUI_SRC_WIN->generic,
			     TUI_SRC_WIN->generic.type,
			     src_height,
			     TUI_SRC_WIN->generic.width,
			     TUI_SRC_WIN->detail.source_info.execution_info->width,
			     0);
	  TUI_SRC_WIN->can_highlight = TRUE;
	  init_gen_win_info (TUI_SRC_WIN->detail.source_info.execution_info,
			     EXEC_INFO_WIN,
			     src_height,
			     3,
			     0,
			     0);
	  tui_make_visible (&TUI_SRC_WIN->generic);
	  tui_make_visible (TUI_SRC_WIN->detail.source_info.execution_info);
	  TUI_SRC_WIN->detail.source_info.has_locator = FALSE;;
	}
      if (TUI_SRC_WIN != NULL)
	{
	  struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();

	  tui_show_source_content (TUI_SRC_WIN);
	  if (TUI_DISASM_WIN == NULL)
	    {
	      make_disasm_window (&TUI_DISASM_WIN, asm_height, src_height - 1);
	      locator = init_and_make_win (locator,
					   LOCATOR_WIN,
					   2 /* 1 */ ,
					   tui_term_width (),
					   0,
					   (src_height + asm_height) - 1,
					   DONT_BOX_WINDOW);
	    }
	  else
	    {
	      init_gen_win_info (locator,
				 LOCATOR_WIN,
				 2 /* 1 */ ,
				 tui_term_width (),
				 0,
				 (src_height + asm_height) - 1);
	      TUI_DISASM_WIN->detail.source_info.has_locator = TRUE;
	      init_gen_win_info (&TUI_DISASM_WIN->generic,
				 TUI_DISASM_WIN->generic.type,
				 asm_height,
				 TUI_DISASM_WIN->generic.width,
				 TUI_DISASM_WIN->detail.source_info.execution_info->width,
				 src_height - 1);
	      init_gen_win_info (TUI_DISASM_WIN->detail.source_info.execution_info,
				 EXEC_INFO_WIN,
				 asm_height,
				 3,
				 0,
				 src_height - 1);
	      TUI_DISASM_WIN->can_highlight = TRUE;
	      tui_make_visible (&TUI_DISASM_WIN->generic);
	      tui_make_visible (TUI_DISASM_WIN->detail.source_info.execution_info);
	    }
	  if (TUI_DISASM_WIN != NULL)
	    {
	      TUI_SRC_WIN->detail.source_info.has_locator = FALSE;
	      TUI_DISASM_WIN->detail.source_info.has_locator = TRUE;
	      tui_make_visible (locator);
	      tui_show_locator_content ();
	      tui_show_source_content (TUI_DISASM_WIN);

	      if (TUI_CMD_WIN == NULL)
		make_command_window (&TUI_CMD_WIN,
				     cmd_height,
				     tui_term_height () - cmd_height);
	      else
		{
		  init_gen_win_info (&TUI_CMD_WIN->generic,
				     TUI_CMD_WIN->generic.type,
				     TUI_CMD_WIN->generic.height,
				     TUI_CMD_WIN->generic.width,
				     0,
				     TUI_CMD_WIN->generic.origin.y);
		  TUI_CMD_WIN->can_highlight = FALSE;
		  tui_make_visible (&TUI_CMD_WIN->generic);
		}
	      if (TUI_CMD_WIN != NULL)
		tui_refresh_win (&TUI_CMD_WIN->generic);
	    }
	}
      tui_set_current_layout_to (SRC_DISASSEM_COMMAND);
    }
}


/* Show the Source/Data/Command or the Dissassembly/Data/Command
   layout.  */
static void
show_data (enum tui_layout_type new_layout)
{
  int total_height = (tui_term_height () - TUI_CMD_WIN->generic.height);
  int src_height, data_height;
  enum tui_win_type win_type;
  struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();


  data_height = total_height / 2;
  src_height = total_height - data_height;
  tui_make_all_invisible ();
  tui_make_invisible (locator);
  make_data_window (&TUI_DATA_WIN, data_height, 0);
  TUI_DATA_WIN->can_highlight = TRUE;
  if (new_layout == SRC_DATA_COMMAND)
    win_type = SRC_WIN;
  else
    win_type = DISASSEM_WIN;
  if (tui_win_list[win_type] == NULL)
    {
      if (win_type == SRC_WIN)
	make_source_window (&tui_win_list[win_type], src_height, data_height - 1);
      else
	make_disasm_window (&tui_win_list[win_type], src_height, data_height - 1);
      locator = init_and_make_win (locator,
				   LOCATOR_WIN,
				   2 /* 1 */ ,
				   tui_term_width (),
				   0,
				   total_height - 1,
				   DONT_BOX_WINDOW);
    }
  else
    {
      init_gen_win_info (&tui_win_list[win_type]->generic,
			 tui_win_list[win_type]->generic.type,
			 src_height,
			 tui_win_list[win_type]->generic.width,
			 tui_win_list[win_type]->detail.source_info.execution_info->width,
			 data_height - 1);
      init_gen_win_info (tui_win_list[win_type]->detail.source_info.execution_info,
			 EXEC_INFO_WIN,
			 src_height,
			 3,
			 0,
			 data_height - 1);
      tui_make_visible (&tui_win_list[win_type]->generic);
      tui_make_visible (tui_win_list[win_type]->detail.source_info.execution_info);
      init_gen_win_info (locator,
			 LOCATOR_WIN,
			 2 /* 1 */ ,
			 tui_term_width (),
			 0,
			 total_height - 1);
    }
  tui_win_list[win_type]->detail.source_info.has_locator = TRUE;
  tui_make_visible (locator);
  tui_show_locator_content ();
  tui_add_to_source_windows (tui_win_list[win_type]);
  tui_set_current_layout_to (new_layout);
}

/* init_gen_win_info().
 */
static void
init_gen_win_info (struct tui_gen_win_info *win_info, 
		   enum tui_win_type type,
		   int height, int width, 
		   int origin_x, int origin_y)
{
  int h = height;

  win_info->type = type;
  win_info->width = width;
  win_info->height = h;
  if (h > 1)
    {
      win_info->viewport_height = h - 1;
      if (win_info->type != CMD_WIN)
	win_info->viewport_height--;
    }
  else
    win_info->viewport_height = 1;
  win_info->origin.x = origin_x;
  win_info->origin.y = origin_y;

  return;
}				/* init_gen_win_info */

/* init_and_make_win().
 */
static void *
init_and_make_win (void *opaque_win_info, 
		   enum tui_win_type win_type,
		   int height, int width, 
		   int origin_x, int origin_y,
		   int box_it)
{
  struct tui_gen_win_info *generic;

  if (opaque_win_info == NULL)
    {
      if (tui_win_is_auxillary (win_type))
	opaque_win_info = (void *) tui_alloc_generic_win_info ();
      else
	opaque_win_info = (void *) tui_alloc_win_info (win_type);
    }
  if (tui_win_is_auxillary (win_type))
    generic = (struct tui_gen_win_info *) opaque_win_info;
  else
    generic = &((struct tui_win_info *) opaque_win_info)->generic;

  if (opaque_win_info != NULL)
    {
      init_gen_win_info (generic, win_type, height, width, origin_x, origin_y);
      if (!tui_win_is_auxillary (win_type))
	{
	  if (generic->type == CMD_WIN)
	    ((struct tui_win_info *) opaque_win_info)->can_highlight = FALSE;
	  else
	    ((struct tui_win_info *) opaque_win_info)->can_highlight = TRUE;
	}
      tui_make_window (generic, box_it);
    }
  return opaque_win_info;
}


static void
make_source_or_disasm_window (struct tui_win_info **win_info_ptr, 
			      enum tui_win_type type,
			      int height, int origin_y)
{
  struct tui_gen_win_info *execution_info = (struct tui_gen_win_info *) NULL;

  /* Create the exeuction info window.  */
  if (type == SRC_WIN)
    execution_info = tui_source_exec_info_win_ptr ();
  else
    execution_info = tui_disassem_exec_info_win_ptr ();
  execution_info = init_and_make_win (execution_info,
				      EXEC_INFO_WIN,
				      height,
				      3,
				      0,
				      origin_y,
				      DONT_BOX_WINDOW);

  /* Now create the source window.  */
  *win_info_ptr = init_and_make_win (*win_info_ptr,
				     type,
				     height,
				     tui_term_width () - execution_info->width,
				     execution_info->width,
				     origin_y,
				     BOX_WINDOW);

  (*win_info_ptr)->detail.source_info.execution_info = execution_info;
}


/* Show the Source/Command or the Disassem layout.  */
static void
show_source_or_disasm_and_command (enum tui_layout_type layout_type)
{
  if (tui_current_layout () != layout_type)
    {
      struct tui_win_info **win_info_ptr;
      int src_height, cmd_height;
      struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();

      if (TUI_CMD_WIN != NULL)
	cmd_height = TUI_CMD_WIN->generic.height;
      else
	cmd_height = tui_term_height () / 3;
      src_height = tui_term_height () - cmd_height;

      if (layout_type == SRC_COMMAND)
	win_info_ptr = &TUI_SRC_WIN;
      else
	win_info_ptr = &TUI_DISASM_WIN;

      if ((*win_info_ptr) == NULL)
	{
	  if (layout_type == SRC_COMMAND)
	    make_source_window (win_info_ptr, src_height - 1, 0);
	  else
	    make_disasm_window (win_info_ptr, src_height - 1, 0);
	  locator = init_and_make_win (locator,
				       LOCATOR_WIN,
				       2 /* 1 */ ,
				       tui_term_width (),
				       0,
				       src_height - 1,
				       DONT_BOX_WINDOW);
	}
      else
	{
	  init_gen_win_info (locator,
			     LOCATOR_WIN,
			     2 /* 1 */ ,
			     tui_term_width (),
			     0,
			     src_height - 1);
	  (*win_info_ptr)->detail.source_info.has_locator = TRUE;
	  init_gen_win_info (&(*win_info_ptr)->generic,
			     (*win_info_ptr)->generic.type,
			     src_height - 1,
			     (*win_info_ptr)->generic.width,
			     (*win_info_ptr)->detail.source_info.execution_info->width,
			     0);
	  init_gen_win_info ((*win_info_ptr)->detail.source_info.execution_info,
			     EXEC_INFO_WIN,
			     src_height - 1,
			     3,
			     0,
			     0);
	  (*win_info_ptr)->can_highlight = TRUE;
	  tui_make_visible (&(*win_info_ptr)->generic);
	  tui_make_visible ((*win_info_ptr)->detail.source_info.execution_info);
	}
      if ((*win_info_ptr) != NULL)
	{
	  (*win_info_ptr)->detail.source_info.has_locator = TRUE;
	  tui_make_visible (locator);
	  tui_show_locator_content ();
	  tui_show_source_content (*win_info_ptr);

	  if (TUI_CMD_WIN == NULL)
	    {
	      make_command_window (&TUI_CMD_WIN, cmd_height, src_height);
	      tui_refresh_win (&TUI_CMD_WIN->generic);
	    }
	  else
	    {
	      init_gen_win_info (&TUI_CMD_WIN->generic,
				 TUI_CMD_WIN->generic.type,
				 TUI_CMD_WIN->generic.height,
				 TUI_CMD_WIN->generic.width,
				 TUI_CMD_WIN->generic.origin.x,
				 TUI_CMD_WIN->generic.origin.y);
	      TUI_CMD_WIN->can_highlight = FALSE;
	      tui_make_visible (&TUI_CMD_WIN->generic);
	    }
	}
      tui_set_current_layout_to (layout_type);
    }
}
