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