Home | History | Annotate | Line # | Download | only in tui
tui-layout.c revision 1.5
      1 /* TUI layout window management.
      2 
      3    Copyright (C) 1998-2015 Free Software Foundation, Inc.
      4 
      5    Contributed by Hewlett-Packard Company.
      6 
      7    This file is part of GDB.
      8 
      9    This program is free software; you can redistribute it and/or modify
     10    it under the terms of the GNU General Public License as published by
     11    the Free Software Foundation; either version 3 of the License, or
     12    (at your option) any later version.
     13 
     14    This program is distributed in the hope that it will be useful,
     15    but WITHOUT ANY WARRANTY; without even the implied warranty of
     16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17    GNU General Public License for more details.
     18 
     19    You should have received a copy of the GNU General Public License
     20    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     21 
     22 #include "defs.h"
     23 #include "arch-utils.h"
     24 #include "command.h"
     25 #include "symtab.h"
     26 #include "frame.h"
     27 #include "source.h"
     28 #include <ctype.h>
     29 
     30 #include "tui/tui.h"
     31 #include "tui/tui-data.h"
     32 #include "tui/tui-windata.h"
     33 #include "tui/tui-wingeneral.h"
     34 #include "tui/tui-stack.h"
     35 #include "tui/tui-regs.h"
     36 #include "tui/tui-win.h"
     37 #include "tui/tui-winsource.h"
     38 #include "tui/tui-disasm.h"
     39 #include "tui/tui-layout.h"
     40 #include "gdb_curses.h"
     41 
     42 /*******************************
     43 ** Static Local Decls
     44 ********************************/
     45 static void show_layout (enum tui_layout_type);
     46 static void init_gen_win_info (struct tui_gen_win_info *,
     47 			       enum tui_win_type,
     48 			       int, int, int, int);
     49 static void *init_and_make_win (void *, enum tui_win_type,
     50 				int, int, int, int, int);
     51 static void show_source_or_disasm_and_command (enum tui_layout_type);
     52 static void make_source_or_disasm_window (struct tui_win_info **,
     53 					  enum tui_win_type,
     54 					  int, int);
     55 static void make_command_window (struct tui_win_info **, int, int);
     56 static void make_source_window (struct tui_win_info **, int, int);
     57 static void make_disasm_window (struct tui_win_info **, int, int);
     58 static void make_data_window (struct tui_win_info **, int, int);
     59 static void show_source_command (void);
     60 static void show_disasm_command (void);
     61 static void show_source_disasm_command (void);
     62 static void show_data (enum tui_layout_type);
     63 static enum tui_layout_type next_layout (void);
     64 static enum tui_layout_type prev_layout (void);
     65 static void tui_layout_command (char *, int);
     66 static void extract_display_start_addr (struct gdbarch **, CORE_ADDR *);
     67 
     68 
     69 /***************************************
     70 ** DEFINITIONS
     71 ***************************************/
     72 
     73 #define LAYOUT_USAGE     "Usage: layout prev | next | <layout_name> \n"
     74 
     75 /* Show the screen layout defined.  */
     76 static void
     77 show_layout (enum tui_layout_type layout)
     78 {
     79   enum tui_layout_type cur_layout = tui_current_layout ();
     80 
     81   if (layout != cur_layout)
     82     {
     83       /* Since the new layout may cause changes in window size, we
     84          should free the content and reallocate on next display of
     85          source/asm.  */
     86       tui_free_all_source_wins_content ();
     87       tui_clear_source_windows ();
     88       if (layout == SRC_DATA_COMMAND
     89 	  || layout == DISASSEM_DATA_COMMAND)
     90 	{
     91 	  show_data (layout);
     92 	  tui_refresh_all (tui_win_list);
     93 	}
     94       else
     95 	{
     96 	  /* First make the current layout be invisible.  */
     97 	  tui_make_all_invisible ();
     98 	  tui_make_invisible (tui_locator_win_info_ptr ());
     99 
    100 	  switch (layout)
    101 	    {
    102 	      /* Now show the new layout.  */
    103 	    case SRC_COMMAND:
    104 	      show_source_command ();
    105 	      tui_add_to_source_windows (TUI_SRC_WIN);
    106 	      break;
    107 	    case DISASSEM_COMMAND:
    108 	      show_disasm_command ();
    109 	      tui_add_to_source_windows (TUI_DISASM_WIN);
    110 	      break;
    111 	    case SRC_DISASSEM_COMMAND:
    112 	      show_source_disasm_command ();
    113 	      tui_add_to_source_windows (TUI_SRC_WIN);
    114 	      tui_add_to_source_windows (TUI_DISASM_WIN);
    115 	      break;
    116 	    default:
    117 	      break;
    118 	    }
    119 	}
    120     }
    121 }
    122 
    123 
    124 /* Function to set the layout to SRC_COMMAND, DISASSEM_COMMAND,
    125    SRC_DISASSEM_COMMAND, SRC_DATA_COMMAND, or DISASSEM_DATA_COMMAND.  */
    126 enum tui_status
    127 tui_set_layout (enum tui_layout_type layout_type)
    128 {
    129   enum tui_status status = TUI_SUCCESS;
    130 
    131   if (layout_type != UNDEFINED_LAYOUT)
    132     {
    133       enum tui_layout_type cur_layout = tui_current_layout (),
    134 	new_layout = UNDEFINED_LAYOUT;
    135       int regs_populate = FALSE;
    136       struct gdbarch *gdbarch;
    137       CORE_ADDR addr;
    138       struct tui_win_info *win_with_focus = tui_win_with_focus ();
    139       struct tui_layout_def *layout_def = tui_layout_def ();
    140 
    141       extract_display_start_addr (&gdbarch, &addr);
    142 
    143       new_layout = layout_type;
    144 
    145       regs_populate = (new_layout == SRC_DATA_COMMAND
    146 		       || new_layout == DISASSEM_DATA_COMMAND);
    147       if (new_layout != cur_layout)
    148 	{
    149 	  show_layout (new_layout);
    150 
    151 	  /* Now determine where focus should be.  */
    152 	  if (win_with_focus != TUI_CMD_WIN)
    153 	    {
    154 	      switch (new_layout)
    155 		{
    156 		case SRC_COMMAND:
    157 		  tui_set_win_focus_to (TUI_SRC_WIN);
    158 		  layout_def->display_mode = SRC_WIN;
    159 		  layout_def->split = FALSE;
    160 		  break;
    161 		case DISASSEM_COMMAND:
    162 		  /* The previous layout was not showing code.
    163 		     This can happen if there is no source
    164 		     available:
    165 
    166 		     1. if the source file is in another dir OR
    167 		     2. if target was compiled without -g
    168 		     We still want to show the assembly though!  */
    169 
    170 		  tui_get_begin_asm_address (&gdbarch, &addr);
    171 		  tui_set_win_focus_to (TUI_DISASM_WIN);
    172 		  layout_def->display_mode = DISASSEM_WIN;
    173 		  layout_def->split = FALSE;
    174 		  break;
    175 		case SRC_DISASSEM_COMMAND:
    176 		  /* The previous layout was not showing code.
    177 		     This can happen if there is no source
    178 		     available:
    179 
    180 		     1. if the source file is in another dir OR
    181 		     2. if target was compiled without -g
    182 		     We still want to show the assembly though!  */
    183 
    184 		  tui_get_begin_asm_address (&gdbarch, &addr);
    185 		  if (win_with_focus == TUI_SRC_WIN)
    186 		    tui_set_win_focus_to (TUI_SRC_WIN);
    187 		  else
    188 		    tui_set_win_focus_to (TUI_DISASM_WIN);
    189 		  layout_def->split = TRUE;
    190 		  break;
    191 		case SRC_DATA_COMMAND:
    192 		  if (win_with_focus != TUI_DATA_WIN)
    193 		    tui_set_win_focus_to (TUI_SRC_WIN);
    194 		  else
    195 		    tui_set_win_focus_to (TUI_DATA_WIN);
    196 		  layout_def->display_mode = SRC_WIN;
    197 		  layout_def->split = FALSE;
    198 		  break;
    199 		case DISASSEM_DATA_COMMAND:
    200 		  /* The previous layout was not showing code.
    201 		     This can happen if there is no source
    202 		     available:
    203 
    204 		     1. if the source file is in another dir OR
    205 		     2. if target was compiled without -g
    206 		     We still want to show the assembly though!  */
    207 
    208 		  tui_get_begin_asm_address (&gdbarch, &addr);
    209 		  if (win_with_focus != TUI_DATA_WIN)
    210 		    tui_set_win_focus_to (TUI_DISASM_WIN);
    211 		  else
    212 		    tui_set_win_focus_to (TUI_DATA_WIN);
    213 		  layout_def->display_mode = DISASSEM_WIN;
    214 		  layout_def->split = FALSE;
    215 		  break;
    216 		default:
    217 		  break;
    218 		}
    219 	    }
    220 	  /*
    221 	   * Now update the window content.
    222 	   */
    223 	  if (!regs_populate
    224 	      && (new_layout == SRC_DATA_COMMAND
    225 		  || new_layout == DISASSEM_DATA_COMMAND))
    226 	    tui_display_all_data ();
    227 
    228 	  tui_update_source_windows_with_addr (gdbarch, addr);
    229 
    230 	  if (regs_populate)
    231 	    {
    232 	      struct reggroup *group =
    233 		TUI_DATA_WIN->detail.data_display_info.current_group;
    234 	      tui_show_registers (group);
    235 	    }
    236 	}
    237     }
    238   else
    239     status = TUI_FAILURE;
    240 
    241   return status;
    242 }
    243 
    244 /* Add the specified window to the layout in a logical way.  This
    245    means setting up the most logical layout given the window to be
    246    added.  */
    247 void
    248 tui_add_win_to_layout (enum tui_win_type type)
    249 {
    250   enum tui_layout_type cur_layout = tui_current_layout ();
    251 
    252   switch (type)
    253     {
    254     case SRC_WIN:
    255       if (cur_layout != SRC_COMMAND
    256 	  && cur_layout != SRC_DISASSEM_COMMAND
    257 	  && cur_layout != SRC_DATA_COMMAND)
    258 	{
    259 	  tui_clear_source_windows_detail ();
    260 	  if (cur_layout == DISASSEM_DATA_COMMAND)
    261 	    show_layout (SRC_DATA_COMMAND);
    262 	  else
    263 	    show_layout (SRC_COMMAND);
    264 	}
    265       break;
    266     case DISASSEM_WIN:
    267       if (cur_layout != DISASSEM_COMMAND
    268 	  && cur_layout != SRC_DISASSEM_COMMAND
    269 	  && cur_layout != DISASSEM_DATA_COMMAND)
    270 	{
    271 	  tui_clear_source_windows_detail ();
    272 	  if (cur_layout == SRC_DATA_COMMAND)
    273 	    show_layout (DISASSEM_DATA_COMMAND);
    274 	  else
    275 	    show_layout (DISASSEM_COMMAND);
    276 	}
    277       break;
    278     case DATA_WIN:
    279       if (cur_layout != SRC_DATA_COMMAND
    280 	  && cur_layout != DISASSEM_DATA_COMMAND)
    281 	{
    282 	  if (cur_layout == DISASSEM_COMMAND)
    283 	    show_layout (DISASSEM_DATA_COMMAND);
    284 	  else
    285 	    show_layout (SRC_DATA_COMMAND);
    286 	}
    287       break;
    288     default:
    289       break;
    290     }
    291 }
    292 
    293 
    294 /* Answer the height of a window.  If it hasn't been created yet,
    295    answer what the height of a window would be based upon its type and
    296    the layout.  */
    297 int
    298 tui_default_win_height (enum tui_win_type type,
    299 			enum tui_layout_type layout)
    300 {
    301   int h;
    302 
    303   if (tui_win_list[type] != (struct tui_win_info *) NULL)
    304     h = tui_win_list[type]->generic.height;
    305   else
    306     {
    307       switch (layout)
    308 	{
    309 	case SRC_COMMAND:
    310 	case DISASSEM_COMMAND:
    311 	  if (TUI_CMD_WIN == NULL)
    312 	    h = tui_term_height () / 2;
    313 	  else
    314 	    h = tui_term_height () - TUI_CMD_WIN->generic.height;
    315 	  break;
    316 	case SRC_DISASSEM_COMMAND:
    317 	case SRC_DATA_COMMAND:
    318 	case DISASSEM_DATA_COMMAND:
    319 	  if (TUI_CMD_WIN == NULL)
    320 	    h = tui_term_height () / 3;
    321 	  else
    322 	    h = (tui_term_height () - TUI_CMD_WIN->generic.height) / 2;
    323 	  break;
    324 	default:
    325 	  h = 0;
    326 	  break;
    327 	}
    328     }
    329 
    330   return h;
    331 }
    332 
    333 
    334 /* Answer the height of a window.  If it hasn't been created yet,
    335    answer what the height of a window would be based upon its type and
    336    the layout.  */
    337 int
    338 tui_default_win_viewport_height (enum tui_win_type type,
    339 				 enum tui_layout_type layout)
    340 {
    341   int h;
    342 
    343   h = tui_default_win_height (type, layout);
    344 
    345   if (tui_win_list[type] == TUI_CMD_WIN)
    346     h -= 1;
    347   else
    348     h -= 2;
    349 
    350   return h;
    351 }
    352 
    353 /* Complete possible layout names.  TEXT is the complete text entered so
    354    far, WORD is the word currently being completed.  */
    355 
    356 static VEC (char_ptr) *
    357 layout_completer (struct cmd_list_element *ignore,
    358 		  const char *text, const char *word)
    359 {
    360   static const char *layout_names [] =
    361     { "src", "asm", "split", "regs", "next", "prev", NULL };
    362 
    363   return complete_on_enum (layout_names, text, word);
    364 }
    365 
    366 /* Function to initialize gdb commands, for tui window layout
    367    manipulation.  */
    368 
    369 /* Provide a prototype to silence -Wmissing-prototypes.  */
    370 extern initialize_file_ftype _initialize_tui_layout;
    371 
    372 void
    373 _initialize_tui_layout (void)
    374 {
    375   struct cmd_list_element *cmd;
    376 
    377   cmd = add_com ("layout", class_tui, tui_layout_command, _("\
    378 Change the layout of windows.\n\
    379 Usage: layout prev | next | <layout_name> \n\
    380 Layout names are:\n\
    381    src   : Displays source and command windows.\n\
    382    asm   : Displays disassembly and command windows.\n\
    383    split : Displays source, disassembly and command windows.\n\
    384    regs  : Displays register window. If existing layout\n\
    385            is source/command or assembly/command, the \n\
    386            register window is displayed. If the\n\
    387            source/assembly/command (split) is displayed, \n\
    388            the register window is displayed with \n\
    389            the window that has current logical focus.\n"));
    390   set_cmd_completer (cmd, layout_completer);
    391 }
    392 
    393 
    394 /*************************
    395 ** STATIC LOCAL FUNCTIONS
    396 **************************/
    397 
    398 
    399 /* Function to set the layout to SRC, ASM, SPLIT, NEXT, PREV, DATA, or
    400    REGS. */
    401 enum tui_status
    402 tui_set_layout_by_name (const char *layout_name)
    403 {
    404   enum tui_status status = TUI_SUCCESS;
    405 
    406   if (layout_name != (char *) NULL)
    407     {
    408       int i;
    409       char *buf_ptr;
    410       enum tui_layout_type new_layout = UNDEFINED_LAYOUT;
    411       enum tui_layout_type cur_layout = tui_current_layout ();
    412       struct cleanup *old_chain;
    413 
    414       buf_ptr = (char *) xstrdup (layout_name);
    415       for (i = 0; (i < strlen (layout_name)); i++)
    416 	buf_ptr[i] = toupper (buf_ptr[i]);
    417       old_chain = make_cleanup (xfree, buf_ptr);
    418 
    419       /* First check for ambiguous input.  */
    420       if (strlen (buf_ptr) <= 1 && *buf_ptr == 'S')
    421 	{
    422 	  warning (_("Ambiguous command input."));
    423 	  status = TUI_FAILURE;
    424 	}
    425       else
    426 	{
    427 	  if (subset_compare (buf_ptr, "SRC"))
    428 	    new_layout = SRC_COMMAND;
    429 	  else if (subset_compare (buf_ptr, "ASM"))
    430 	    new_layout = DISASSEM_COMMAND;
    431 	  else if (subset_compare (buf_ptr, "SPLIT"))
    432 	    new_layout = SRC_DISASSEM_COMMAND;
    433 	  else if (subset_compare (buf_ptr, "REGS"))
    434 	    {
    435 	      if (cur_layout == SRC_COMMAND
    436 		  || cur_layout == SRC_DATA_COMMAND)
    437 		new_layout = SRC_DATA_COMMAND;
    438 	      else
    439 		new_layout = DISASSEM_DATA_COMMAND;
    440 	    }
    441 	  else if (subset_compare (buf_ptr, "NEXT"))
    442 	    new_layout = next_layout ();
    443 	  else if (subset_compare (buf_ptr, "PREV"))
    444 	    new_layout = prev_layout ();
    445 	  else
    446 	    status = TUI_FAILURE;
    447 
    448 	  if (status == TUI_SUCCESS)
    449 	    {
    450 	      /* Make sure the curses mode is enabled.  */
    451 	      tui_enable ();
    452 	      tui_set_layout (new_layout);
    453 	    }
    454 	}
    455       do_cleanups (old_chain);
    456     }
    457   else
    458     status = TUI_FAILURE;
    459 
    460   return status;
    461 }
    462 
    463 
    464 static void
    465 extract_display_start_addr (struct gdbarch **gdbarch_p, CORE_ADDR *addr_p)
    466 {
    467   enum tui_layout_type cur_layout = tui_current_layout ();
    468   struct gdbarch *gdbarch = get_current_arch ();
    469   CORE_ADDR addr;
    470   CORE_ADDR pc;
    471   struct symtab_and_line cursal = get_current_source_symtab_and_line ();
    472 
    473   switch (cur_layout)
    474     {
    475     case SRC_COMMAND:
    476     case SRC_DATA_COMMAND:
    477       gdbarch = TUI_SRC_WIN->detail.source_info.gdbarch;
    478       find_line_pc (cursal.symtab,
    479 		    TUI_SRC_WIN->detail.source_info.start_line_or_addr.u.line_no,
    480 		    &pc);
    481       addr = pc;
    482       break;
    483     case DISASSEM_COMMAND:
    484     case SRC_DISASSEM_COMMAND:
    485     case DISASSEM_DATA_COMMAND:
    486       gdbarch = TUI_DISASM_WIN->detail.source_info.gdbarch;
    487       addr = TUI_DISASM_WIN->detail.source_info.start_line_or_addr.u.addr;
    488       break;
    489     default:
    490       addr = 0;
    491       break;
    492     }
    493 
    494   *gdbarch_p = gdbarch;
    495   *addr_p = addr;
    496 }
    497 
    498 
    499 static void
    500 tui_layout_command (char *arg, int from_tty)
    501 {
    502   /* Switch to the selected layout.  */
    503   if (tui_set_layout_by_name (arg) != TUI_SUCCESS)
    504     warning (_("Invalid layout specified.\n%s"), LAYOUT_USAGE);
    505 
    506 }
    507 
    508 /* Answer the previous layout to cycle to.  */
    509 static enum tui_layout_type
    510 next_layout (void)
    511 {
    512   int new_layout;
    513 
    514   new_layout = tui_current_layout ();
    515   if (new_layout == UNDEFINED_LAYOUT)
    516     new_layout = SRC_COMMAND;
    517   else
    518     {
    519       new_layout++;
    520       if (new_layout == UNDEFINED_LAYOUT)
    521 	new_layout = SRC_COMMAND;
    522     }
    523 
    524   return (enum tui_layout_type) new_layout;
    525 }
    526 
    527 
    528 /* Answer the next layout to cycle to.  */
    529 static enum tui_layout_type
    530 prev_layout (void)
    531 {
    532   int new_layout;
    533 
    534   new_layout = tui_current_layout ();
    535   if (new_layout == SRC_COMMAND)
    536     new_layout = DISASSEM_DATA_COMMAND;
    537   else
    538     {
    539       new_layout--;
    540       if (new_layout == UNDEFINED_LAYOUT)
    541 	new_layout = DISASSEM_DATA_COMMAND;
    542     }
    543 
    544   return (enum tui_layout_type) new_layout;
    545 }
    546 
    547 
    548 
    549 static void
    550 make_command_window (struct tui_win_info **win_info_ptr,
    551 		     int height, int origin_y)
    552 {
    553   *win_info_ptr = init_and_make_win (*win_info_ptr,
    554 				     CMD_WIN,
    555 				     height,
    556 				     tui_term_width (),
    557 				     0,
    558 				     origin_y,
    559 				     DONT_BOX_WINDOW);
    560 
    561   (*win_info_ptr)->can_highlight = FALSE;
    562 }
    563 
    564 
    565 /* make_source_window().
    566  */
    567 static void
    568 make_source_window (struct tui_win_info **win_info_ptr,
    569 		    int height, int origin_y)
    570 {
    571   make_source_or_disasm_window (win_info_ptr, SRC_WIN, height, origin_y);
    572 
    573   return;
    574 }				/* make_source_window */
    575 
    576 
    577 /* make_disasm_window().
    578  */
    579 static void
    580 make_disasm_window (struct tui_win_info **win_info_ptr,
    581 		    int height, int origin_y)
    582 {
    583   make_source_or_disasm_window (win_info_ptr, DISASSEM_WIN, height, origin_y);
    584 
    585   return;
    586 }				/* make_disasm_window */
    587 
    588 
    589 static void
    590 make_data_window (struct tui_win_info **win_info_ptr,
    591 		  int height, int origin_y)
    592 {
    593   *win_info_ptr = init_and_make_win (*win_info_ptr,
    594 				     DATA_WIN,
    595 				     height,
    596 				     tui_term_width (),
    597 				     0,
    598 				     origin_y,
    599 				     BOX_WINDOW);
    600 }
    601 
    602 
    603 
    604 /* Show the Source/Command layout.  */
    605 static void
    606 show_source_command (void)
    607 {
    608   show_source_or_disasm_and_command (SRC_COMMAND);
    609 }
    610 
    611 
    612 /* Show the Dissassem/Command layout.  */
    613 static void
    614 show_disasm_command (void)
    615 {
    616   show_source_or_disasm_and_command (DISASSEM_COMMAND);
    617 }
    618 
    619 
    620 /* Show the Source/Disassem/Command layout.  */
    621 static void
    622 show_source_disasm_command (void)
    623 {
    624   if (tui_current_layout () != SRC_DISASSEM_COMMAND)
    625     {
    626       int cmd_height, src_height, asm_height;
    627 
    628       if (TUI_CMD_WIN != NULL)
    629 	cmd_height = TUI_CMD_WIN->generic.height;
    630       else
    631 	cmd_height = tui_term_height () / 3;
    632 
    633       src_height = (tui_term_height () - cmd_height) / 2;
    634       asm_height = tui_term_height () - (src_height + cmd_height);
    635 
    636       if (TUI_SRC_WIN == NULL)
    637 	make_source_window (&TUI_SRC_WIN, src_height, 0);
    638       else
    639 	{
    640 	  init_gen_win_info (&TUI_SRC_WIN->generic,
    641 			     TUI_SRC_WIN->generic.type,
    642 			     src_height,
    643 			     TUI_SRC_WIN->generic.width,
    644 			     TUI_SRC_WIN->detail.source_info.execution_info->width,
    645 			     0);
    646 	  TUI_SRC_WIN->can_highlight = TRUE;
    647 	  init_gen_win_info (TUI_SRC_WIN->detail.source_info.execution_info,
    648 			     EXEC_INFO_WIN,
    649 			     src_height,
    650 			     3,
    651 			     0,
    652 			     0);
    653 	  tui_make_visible (&TUI_SRC_WIN->generic);
    654 	  tui_make_visible (TUI_SRC_WIN->detail.source_info.execution_info);
    655 	  TUI_SRC_WIN->detail.source_info.has_locator = FALSE;;
    656 	}
    657       if (TUI_SRC_WIN != NULL)
    658 	{
    659 	  struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
    660 
    661 	  tui_show_source_content (TUI_SRC_WIN);
    662 	  if (TUI_DISASM_WIN == NULL)
    663 	    {
    664 	      make_disasm_window (&TUI_DISASM_WIN, asm_height, src_height - 1);
    665 	      locator = init_and_make_win (locator,
    666 					   LOCATOR_WIN,
    667 					   2 /* 1 */ ,
    668 					   tui_term_width (),
    669 					   0,
    670 					   (src_height + asm_height) - 1,
    671 					   DONT_BOX_WINDOW);
    672 	    }
    673 	  else
    674 	    {
    675 	      init_gen_win_info (locator,
    676 				 LOCATOR_WIN,
    677 				 2 /* 1 */ ,
    678 				 tui_term_width (),
    679 				 0,
    680 				 (src_height + asm_height) - 1);
    681 	      TUI_DISASM_WIN->detail.source_info.has_locator = TRUE;
    682 	      init_gen_win_info (&TUI_DISASM_WIN->generic,
    683 				 TUI_DISASM_WIN->generic.type,
    684 				 asm_height,
    685 				 TUI_DISASM_WIN->generic.width,
    686 				 TUI_DISASM_WIN->detail.source_info.execution_info->width,
    687 				 src_height - 1);
    688 	      init_gen_win_info (TUI_DISASM_WIN->detail.source_info.execution_info,
    689 				 EXEC_INFO_WIN,
    690 				 asm_height,
    691 				 3,
    692 				 0,
    693 				 src_height - 1);
    694 	      TUI_DISASM_WIN->can_highlight = TRUE;
    695 	      tui_make_visible (&TUI_DISASM_WIN->generic);
    696 	      tui_make_visible (TUI_DISASM_WIN->detail.source_info.execution_info);
    697 	    }
    698 	  if (TUI_DISASM_WIN != NULL)
    699 	    {
    700 	      TUI_SRC_WIN->detail.source_info.has_locator = FALSE;
    701 	      TUI_DISASM_WIN->detail.source_info.has_locator = TRUE;
    702 	      tui_make_visible (locator);
    703 	      tui_show_locator_content ();
    704 	      tui_show_source_content (TUI_DISASM_WIN);
    705 
    706 	      if (TUI_CMD_WIN == NULL)
    707 		make_command_window (&TUI_CMD_WIN,
    708 				     cmd_height,
    709 				     tui_term_height () - cmd_height);
    710 	      else
    711 		{
    712 		  init_gen_win_info (&TUI_CMD_WIN->generic,
    713 				     TUI_CMD_WIN->generic.type,
    714 				     TUI_CMD_WIN->generic.height,
    715 				     TUI_CMD_WIN->generic.width,
    716 				     0,
    717 				     TUI_CMD_WIN->generic.origin.y);
    718 		  TUI_CMD_WIN->can_highlight = FALSE;
    719 		  tui_make_visible (&TUI_CMD_WIN->generic);
    720 		}
    721 	      if (TUI_CMD_WIN != NULL)
    722 		tui_refresh_win (&TUI_CMD_WIN->generic);
    723 	    }
    724 	}
    725       tui_set_current_layout_to (SRC_DISASSEM_COMMAND);
    726     }
    727 }
    728 
    729 
    730 /* Show the Source/Data/Command or the Dissassembly/Data/Command
    731    layout.  */
    732 static void
    733 show_data (enum tui_layout_type new_layout)
    734 {
    735   int total_height = (tui_term_height () - TUI_CMD_WIN->generic.height);
    736   int src_height, data_height;
    737   enum tui_win_type win_type;
    738   struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
    739 
    740 
    741   data_height = total_height / 2;
    742   src_height = total_height - data_height;
    743   tui_make_all_invisible ();
    744   tui_make_invisible (locator);
    745   make_data_window (&TUI_DATA_WIN, data_height, 0);
    746   TUI_DATA_WIN->can_highlight = TRUE;
    747   if (new_layout == SRC_DATA_COMMAND)
    748     win_type = SRC_WIN;
    749   else
    750     win_type = DISASSEM_WIN;
    751   if (tui_win_list[win_type] == NULL)
    752     {
    753       if (win_type == SRC_WIN)
    754 	make_source_window (&tui_win_list[win_type], src_height, data_height - 1);
    755       else
    756 	make_disasm_window (&tui_win_list[win_type], src_height, data_height - 1);
    757       locator = init_and_make_win (locator,
    758 				   LOCATOR_WIN,
    759 				   2 /* 1 */ ,
    760 				   tui_term_width (),
    761 				   0,
    762 				   total_height - 1,
    763 				   DONT_BOX_WINDOW);
    764     }
    765   else
    766     {
    767       init_gen_win_info (&tui_win_list[win_type]->generic,
    768 			 tui_win_list[win_type]->generic.type,
    769 			 src_height,
    770 			 tui_win_list[win_type]->generic.width,
    771 			 tui_win_list[win_type]->detail.source_info.execution_info->width,
    772 			 data_height - 1);
    773       init_gen_win_info (tui_win_list[win_type]->detail.source_info.execution_info,
    774 			 EXEC_INFO_WIN,
    775 			 src_height,
    776 			 3,
    777 			 0,
    778 			 data_height - 1);
    779       tui_make_visible (&tui_win_list[win_type]->generic);
    780       tui_make_visible (tui_win_list[win_type]->detail.source_info.execution_info);
    781       init_gen_win_info (locator,
    782 			 LOCATOR_WIN,
    783 			 2 /* 1 */ ,
    784 			 tui_term_width (),
    785 			 0,
    786 			 total_height - 1);
    787     }
    788   tui_win_list[win_type]->detail.source_info.has_locator = TRUE;
    789   tui_make_visible (locator);
    790   tui_show_locator_content ();
    791   tui_add_to_source_windows (tui_win_list[win_type]);
    792   tui_set_current_layout_to (new_layout);
    793 }
    794 
    795 /* init_gen_win_info().
    796  */
    797 static void
    798 init_gen_win_info (struct tui_gen_win_info *win_info,
    799 		   enum tui_win_type type,
    800 		   int height, int width,
    801 		   int origin_x, int origin_y)
    802 {
    803   int h = height;
    804 
    805   win_info->type = type;
    806   win_info->width = width;
    807   win_info->height = h;
    808   if (h > 1)
    809     {
    810       win_info->viewport_height = h - 1;
    811       if (win_info->type != CMD_WIN)
    812 	win_info->viewport_height--;
    813     }
    814   else
    815     win_info->viewport_height = 1;
    816   win_info->origin.x = origin_x;
    817   win_info->origin.y = origin_y;
    818 
    819   return;
    820 }				/* init_gen_win_info */
    821 
    822 /* init_and_make_win().
    823  */
    824 static void *
    825 init_and_make_win (void *opaque_win_info,
    826 		   enum tui_win_type win_type,
    827 		   int height, int width,
    828 		   int origin_x, int origin_y,
    829 		   int box_it)
    830 {
    831   struct tui_gen_win_info *generic;
    832 
    833   if (opaque_win_info == NULL)
    834     {
    835       if (tui_win_is_auxillary (win_type))
    836 	opaque_win_info = (void *) tui_alloc_generic_win_info ();
    837       else
    838 	opaque_win_info = (void *) tui_alloc_win_info (win_type);
    839     }
    840   if (tui_win_is_auxillary (win_type))
    841     generic = (struct tui_gen_win_info *) opaque_win_info;
    842   else
    843     generic = &((struct tui_win_info *) opaque_win_info)->generic;
    844 
    845   if (opaque_win_info != NULL)
    846     {
    847       init_gen_win_info (generic, win_type, height, width, origin_x, origin_y);
    848       if (!tui_win_is_auxillary (win_type))
    849 	{
    850 	  if (generic->type == CMD_WIN)
    851 	    ((struct tui_win_info *) opaque_win_info)->can_highlight = FALSE;
    852 	  else
    853 	    ((struct tui_win_info *) opaque_win_info)->can_highlight = TRUE;
    854 	}
    855       tui_make_window (generic, box_it);
    856     }
    857   return opaque_win_info;
    858 }
    859 
    860 
    861 static void
    862 make_source_or_disasm_window (struct tui_win_info **win_info_ptr,
    863 			      enum tui_win_type type,
    864 			      int height, int origin_y)
    865 {
    866   struct tui_gen_win_info *execution_info = (struct tui_gen_win_info *) NULL;
    867 
    868   /* Create the exeuction info window.  */
    869   if (type == SRC_WIN)
    870     execution_info = tui_source_exec_info_win_ptr ();
    871   else
    872     execution_info = tui_disassem_exec_info_win_ptr ();
    873   execution_info = init_and_make_win (execution_info,
    874 				      EXEC_INFO_WIN,
    875 				      height,
    876 				      3,
    877 				      0,
    878 				      origin_y,
    879 				      DONT_BOX_WINDOW);
    880 
    881   /* Now create the source window.  */
    882   *win_info_ptr = init_and_make_win (*win_info_ptr,
    883 				     type,
    884 				     height,
    885 				     tui_term_width () - execution_info->width,
    886 				     execution_info->width,
    887 				     origin_y,
    888 				     BOX_WINDOW);
    889 
    890   (*win_info_ptr)->detail.source_info.execution_info = execution_info;
    891 }
    892 
    893 
    894 /* Show the Source/Command or the Disassem layout.  */
    895 static void
    896 show_source_or_disasm_and_command (enum tui_layout_type layout_type)
    897 {
    898   if (tui_current_layout () != layout_type)
    899     {
    900       struct tui_win_info **win_info_ptr;
    901       int src_height, cmd_height;
    902       struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
    903 
    904       if (TUI_CMD_WIN != NULL)
    905 	cmd_height = TUI_CMD_WIN->generic.height;
    906       else
    907 	cmd_height = tui_term_height () / 3;
    908       src_height = tui_term_height () - cmd_height;
    909 
    910       if (layout_type == SRC_COMMAND)
    911 	win_info_ptr = &TUI_SRC_WIN;
    912       else
    913 	win_info_ptr = &TUI_DISASM_WIN;
    914 
    915       if ((*win_info_ptr) == NULL)
    916 	{
    917 	  if (layout_type == SRC_COMMAND)
    918 	    make_source_window (win_info_ptr, src_height - 1, 0);
    919 	  else
    920 	    make_disasm_window (win_info_ptr, src_height - 1, 0);
    921 	  locator = init_and_make_win (locator,
    922 				       LOCATOR_WIN,
    923 				       2 /* 1 */ ,
    924 				       tui_term_width (),
    925 				       0,
    926 				       src_height - 1,
    927 				       DONT_BOX_WINDOW);
    928 	}
    929       else
    930 	{
    931 	  init_gen_win_info (locator,
    932 			     LOCATOR_WIN,
    933 			     2 /* 1 */ ,
    934 			     tui_term_width (),
    935 			     0,
    936 			     src_height - 1);
    937 	  (*win_info_ptr)->detail.source_info.has_locator = TRUE;
    938 	  init_gen_win_info (&(*win_info_ptr)->generic,
    939 			     (*win_info_ptr)->generic.type,
    940 			     src_height - 1,
    941 			     (*win_info_ptr)->generic.width,
    942 			     (*win_info_ptr)->detail.source_info.execution_info->width,
    943 			     0);
    944 	  init_gen_win_info ((*win_info_ptr)->detail.source_info.execution_info,
    945 			     EXEC_INFO_WIN,
    946 			     src_height - 1,
    947 			     3,
    948 			     0,
    949 			     0);
    950 	  (*win_info_ptr)->can_highlight = TRUE;
    951 	  tui_make_visible (&(*win_info_ptr)->generic);
    952 	  tui_make_visible ((*win_info_ptr)->detail.source_info.execution_info);
    953 	}
    954       if ((*win_info_ptr) != NULL)
    955 	{
    956 	  (*win_info_ptr)->detail.source_info.has_locator = TRUE;
    957 	  tui_make_visible (locator);
    958 	  tui_show_locator_content ();
    959 	  tui_show_source_content (*win_info_ptr);
    960 
    961 	  if (TUI_CMD_WIN == NULL)
    962 	    {
    963 	      make_command_window (&TUI_CMD_WIN, cmd_height, src_height);
    964 	      tui_refresh_win (&TUI_CMD_WIN->generic);
    965 	    }
    966 	  else
    967 	    {
    968 	      init_gen_win_info (&TUI_CMD_WIN->generic,
    969 				 TUI_CMD_WIN->generic.type,
    970 				 TUI_CMD_WIN->generic.height,
    971 				 TUI_CMD_WIN->generic.width,
    972 				 TUI_CMD_WIN->generic.origin.x,
    973 				 TUI_CMD_WIN->generic.origin.y);
    974 	      TUI_CMD_WIN->can_highlight = FALSE;
    975 	      tui_make_visible (&TUI_CMD_WIN->generic);
    976 	    }
    977 	}
    978       tui_set_current_layout_to (layout_type);
    979     }
    980 }
    981