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