OSDN Git Service

b82ce2f153dab84b0c07d730eb8ad38d8f14b320
[pf3gnuchains/pf3gnuchains4x.git] / gdb / tui / tuiWin.c
1 /* TUI window generic functions.
2
3    Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
4    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 /* This module contains procedures for handling tui window functions
26    like resize, scrolling, scrolling, changing focus, etc.
27
28    Author: Susan B. Macchia  */
29
30 /* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
31    "defs.h" should be included first.  Unfortunatly some systems
32    (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
33    and they clash with "bfd.h"'s definiton of true/false.  The correct
34    fix is to remove true/false from "bfd.h", however, until that
35    happens, hack around it by including "config.h" and <curses.h>
36    first.  */
37
38 #include "config.h"
39 #ifdef HAVE_NCURSES_H       
40 #include <ncurses.h>
41 #else
42 #ifdef HAVE_CURSES_H
43 #include <curses.h>
44 #endif
45 #endif
46
47 #include <string.h>
48 #include <ctype.h>
49 #include "defs.h"
50 #include "command.h"
51 #include "symtab.h"
52 #include "breakpoint.h"
53 #include "frame.h"
54 #include "cli/cli-cmds.h"
55 #include "top.h"
56 #include "source.h"
57
58 #include "tui.h"
59 #include "tuiData.h"
60 #include "tuiGeneralWin.h"
61 #include "tuiStack.h"
62 #include "tuiRegs.h"
63 #include "tuiDisassem.h"
64 #include "tuiSource.h"
65 #include "tuiSourceWin.h"
66 #include "tuiDataWin.h"
67
68 /*******************************
69 ** Static Local Decls
70 ********************************/
71 static void _makeVisibleWithNewHeight (TuiWinInfoPtr);
72 static void _makeInvisibleAndSetNewHeight (TuiWinInfoPtr, int);
73 static TuiStatus _tuiAdjustWinHeights (TuiWinInfoPtr, int);
74 static int _newHeightOk (TuiWinInfoPtr, int);
75 static void _tuiSetTabWidth_command (char *, int);
76 static void _tuiRefreshAll_command (char *, int);
77 static void _tuiSetWinHeight_command (char *, int);
78 static void _tuiXDBsetWinHeight_command (char *, int);
79 static void _tuiAllWindowsInfo (char *, int);
80 static void _tuiSetFocus_command (char *, int);
81 static void _tuiScrollForward_command (char *, int);
82 static void _tuiScrollBackward_command (char *, int);
83 static void _tuiScrollLeft_command (char *, int);
84 static void _tuiScrollRight_command (char *, int);
85 static void _parseScrollingArgs (char *, TuiWinInfoPtr *, int *);
86
87
88 /***************************************
89 ** DEFINITIONS
90 ***************************************/
91 #define WIN_HEIGHT_USAGE      "Usage: winheight <win_name> [+ | -] <#lines>\n"
92 #define XDBWIN_HEIGHT_USAGE   "Usage: w <#lines>\n"
93 #define FOCUS_USAGE           "Usage: focus {<win> | next | prev}\n"
94
95 /***************************************
96 ** PUBLIC FUNCTIONS
97 ***************************************/
98
99 #ifndef ACS_LRCORNER
100 #  define ACS_LRCORNER '+'
101 #endif
102 #ifndef ACS_LLCORNER
103 #  define ACS_LLCORNER '+'
104 #endif
105 #ifndef ACS_ULCORNER
106 #  define ACS_ULCORNER '+'
107 #endif
108 #ifndef ACS_URCORNER
109 #  define ACS_URCORNER '+'
110 #endif
111 #ifndef ACS_HLINE
112 #  define ACS_HLINE '-'
113 #endif
114 #ifndef ACS_VLINE
115 #  define ACS_VLINE '|'
116 #endif
117
118 /* Possible values for tui-border-kind variable.  */
119 static const char *tui_border_kind_enums[] = {
120   "space",
121   "ascii",
122   "acs",
123   NULL
124 };
125
126 /* Possible values for tui-border-mode and tui-active-border-mode.  */
127 static const char *tui_border_mode_enums[] = {
128   "normal",
129   "standout",
130   "reverse",
131   "half",
132   "half-standout",
133   "bold",
134   "bold-standout",
135   NULL
136 };
137
138 struct tui_translate
139 {
140   const char *name;
141   int value;
142 };
143
144 /* Translation table for border-mode variables.
145    The list of values must be terminated by a NULL.
146    After the NULL value, an entry defines the default.  */
147 struct tui_translate tui_border_mode_translate[] = {
148   { "normal",           A_NORMAL },
149   { "standout",         A_STANDOUT },
150   { "reverse",          A_REVERSE },
151   { "half",             A_DIM },
152   { "half-standout",    A_DIM | A_STANDOUT },
153   { "bold",             A_BOLD },
154   { "bold-standout",    A_BOLD | A_STANDOUT },
155   { 0, 0 },
156   { "normal",           A_NORMAL }
157 };
158
159 /* Translation tables for border-kind, one for each border
160    character (see wborder, border curses operations).
161    -1 is used to indicate the ACS because ACS characters
162    are determined at run time by curses (depends on terminal).  */
163 struct tui_translate tui_border_kind_translate_vline[] = {
164   { "space",    ' ' },
165   { "ascii",    '|' },
166   { "acs",      -1 },
167   { 0, 0 },
168   { "ascii",    '|' }
169 };
170
171 struct tui_translate tui_border_kind_translate_hline[] = {
172   { "space",    ' ' },
173   { "ascii",    '-' },
174   { "acs",      -1 },
175   { 0, 0 },
176   { "ascii",    '-' }
177 };
178
179 struct tui_translate tui_border_kind_translate_ulcorner[] = {
180   { "space",    ' ' },
181   { "ascii",    '+' },
182   { "acs",      -1 },
183   { 0, 0 },
184   { "ascii",    '+' }
185 };
186
187 struct tui_translate tui_border_kind_translate_urcorner[] = {
188   { "space",    ' ' },
189   { "ascii",    '+' },
190   { "acs",      -1 },
191   { 0, 0 },
192   { "ascii",    '+' }
193 };
194
195 struct tui_translate tui_border_kind_translate_llcorner[] = {
196   { "space",    ' ' },
197   { "ascii",    '+' },
198   { "acs",      -1 },
199   { 0, 0 },
200   { "ascii",    '+' }
201 };
202
203 struct tui_translate tui_border_kind_translate_lrcorner[] = {
204   { "space",    ' ' },
205   { "ascii",    '+' },
206   { "acs",      -1 },
207   { 0, 0 },
208   { "ascii",    '+' }
209 };
210
211
212 /* Tui configuration variables controlled with set/show command.  */
213 const char *tui_active_border_mode = "bold-standout";
214 const char *tui_border_mode = "normal";
215 const char *tui_border_kind = "acs";
216
217 /* Tui internal configuration variables.  These variables are
218    updated by tui_update_variables to reflect the tui configuration
219    variables.  */
220 chtype tui_border_vline;
221 chtype tui_border_hline;
222 chtype tui_border_ulcorner;
223 chtype tui_border_urcorner;
224 chtype tui_border_llcorner;
225 chtype tui_border_lrcorner;
226
227 int tui_border_attrs;
228 int tui_active_border_attrs;
229
230 /* Identify the item in the translation table.
231    When the item is not recognized, use the default entry.  */
232 static struct tui_translate *
233 translate (const char *name, struct tui_translate *table)
234 {
235   while (table->name)
236     {
237       if (name && strcmp (table->name, name) == 0)
238         return table;
239       table++;
240     }
241
242   /* Not found, return default entry.  */
243   table++;
244   return table;
245 }
246
247 /* Update the tui internal configuration according to gdb settings.
248    Returns 1 if the configuration has changed and the screen should
249    be redrawn.  */
250 int
251 tui_update_variables ()
252 {
253   int need_redraw = 0;
254   struct tui_translate *entry;
255
256   entry = translate (tui_border_mode, tui_border_mode_translate);
257   if (tui_border_attrs != entry->value)
258     {
259       tui_border_attrs = entry->value;
260       need_redraw = 1;
261     }
262   entry = translate (tui_active_border_mode, tui_border_mode_translate);
263   if (tui_active_border_attrs != entry->value)
264     {
265       tui_active_border_attrs = entry->value;
266       need_redraw = 1;
267     }
268
269   /* If one corner changes, all characters are changed.
270      Only check the first one.  The ACS characters are determined at
271      run time by curses terminal management.  */
272   entry = translate (tui_border_kind, tui_border_kind_translate_lrcorner);
273   if (tui_border_lrcorner != (chtype) entry->value)
274     {
275       tui_border_lrcorner = (entry->value < 0) ? ACS_LRCORNER : entry->value;
276       need_redraw = 1;
277     }
278   entry = translate (tui_border_kind, tui_border_kind_translate_llcorner);
279   tui_border_llcorner = (entry->value < 0) ? ACS_LLCORNER : entry->value;
280
281   entry = translate (tui_border_kind, tui_border_kind_translate_ulcorner);
282   tui_border_ulcorner = (entry->value < 0) ? ACS_ULCORNER : entry->value;
283
284   entry = translate (tui_border_kind, tui_border_kind_translate_urcorner);
285   tui_border_urcorner = (entry->value < 0) ? ACS_URCORNER : entry->value;
286
287   entry = translate (tui_border_kind, tui_border_kind_translate_hline);
288   tui_border_hline = (entry->value < 0) ? ACS_HLINE : entry->value;
289
290   entry = translate (tui_border_kind, tui_border_kind_translate_vline);
291   tui_border_vline = (entry->value < 0) ? ACS_VLINE : entry->value;
292
293   return need_redraw;
294 }
295
296 static void
297 set_tui_cmd (char *args, int from_tty)
298 {
299 }
300
301 static void
302 show_tui_cmd (char *args, int from_tty)
303 {
304 }
305
306 /*
307    ** _initialize_tuiWin().
308    **        Function to initialize gdb commands, for tui window manipulation.
309  */
310 void
311 _initialize_tuiWin (void)
312 {
313   struct cmd_list_element *c;
314   static struct cmd_list_element *tui_setlist;
315   static struct cmd_list_element *tui_showlist;
316
317   /* Define the classes of commands.
318      They will appear in the help list in the reverse of this order.  */
319   add_cmd ("tui", class_tui, NULL,
320            "Text User Interface commands.",
321            &cmdlist);
322
323   add_prefix_cmd ("tui", class_tui, set_tui_cmd,
324                   "TUI configuration variables",
325                   &tui_setlist, "set tui ",
326                   0/*allow-unknown*/, &setlist);
327   add_prefix_cmd ("tui", class_tui, show_tui_cmd,
328                   "TUI configuration variables",
329                   &tui_showlist, "show tui ",
330                   0/*allow-unknown*/, &showlist);
331
332   add_com ("refresh", class_tui, _tuiRefreshAll_command,
333            "Refresh the terminal display.\n");
334   if (xdb_commands)
335     add_com_alias ("U", "refresh", class_tui, 0);
336   add_com ("tabset", class_tui, _tuiSetTabWidth_command,
337            "Set the width (in characters) of tab stops.\n\
338 Usage: tabset <n>\n");
339   add_com ("winheight", class_tui, _tuiSetWinHeight_command,
340            "Set the height of a specified window.\n\
341 Usage: winheight <win_name> [+ | -] <#lines>\n\
342 Window names are:\n\
343 src  : the source window\n\
344 cmd  : the command window\n\
345 asm  : the disassembly window\n\
346 regs : the register display\n");
347   add_com_alias ("wh", "winheight", class_tui, 0);
348   add_info ("win", _tuiAllWindowsInfo,
349             "List of all displayed windows.\n");
350   add_com ("focus", class_tui, _tuiSetFocus_command,
351            "Set focus to named window or next/prev window.\n\
352 Usage: focus {<win> | next | prev}\n\
353 Valid Window names are:\n\
354 src  : the source window\n\
355 asm  : the disassembly window\n\
356 regs : the register display\n\
357 cmd  : the command window\n");
358   add_com_alias ("fs", "focus", class_tui, 0);
359   add_com ("+", class_tui, _tuiScrollForward_command,
360            "Scroll window forward.\nUsage: + [win] [n]\n");
361   add_com ("-", class_tui, _tuiScrollBackward_command,
362            "Scroll window backward.\nUsage: - [win] [n]\n");
363   add_com ("<", class_tui, _tuiScrollLeft_command,
364            "Scroll window forward.\nUsage: < [win] [n]\n");
365   add_com (">", class_tui, _tuiScrollRight_command,
366            "Scroll window backward.\nUsage: > [win] [n]\n");
367   if (xdb_commands)
368     add_com ("w", class_xdb, _tuiXDBsetWinHeight_command,
369              "XDB compatibility command for setting the height of a command window.\n\
370 Usage: w <#lines>\n");
371
372   /* Define the tui control variables.  */
373   c = add_set_enum_cmd
374     ("border-kind", no_class,
375      tui_border_kind_enums, &tui_border_kind,
376      "Set the kind of border for TUI windows.\n"
377      "This variable controls the border of TUI windows:\n"
378      "space           use a white space\n"
379      "ascii           use ascii characters + - | for the border\n"
380      "acs             use the Alternate Character Set\n",
381      &tui_setlist);
382   add_show_from_set (c, &tui_showlist);
383
384   c = add_set_enum_cmd
385     ("border-mode", no_class,
386      tui_border_mode_enums, &tui_border_mode,
387      "Set the attribute mode to use for the TUI window borders.\n"
388      "This variable controls the attributes to use for the window borders:\n"
389      "normal          normal display\n"
390      "standout        use highlight mode of terminal\n"
391      "reverse         use reverse video mode\n"
392      "half            use half bright\n"
393      "half-standout   use half bright and standout mode\n"
394      "bold            use extra bright or bold\n"
395      "bold-standout   use extra bright or bold with standout mode\n",
396      &tui_setlist);
397   add_show_from_set (c, &tui_showlist);
398
399   c = add_set_enum_cmd
400     ("active-border-mode", no_class,
401      tui_border_mode_enums, &tui_active_border_mode,
402      "Set the attribute mode to use for the active TUI window border.\n"
403      "This variable controls the attributes to use for the active window border:\n"
404      "normal          normal display\n"
405      "standout        use highlight mode of terminal\n"
406      "reverse         use reverse video mode\n"
407      "half            use half bright\n"
408      "half-standout   use half bright and standout mode\n"
409      "bold            use extra bright or bold\n"
410      "bold-standout   use extra bright or bold with standout mode\n",
411      &tui_setlist);
412   add_show_from_set (c, &tui_showlist);
413 }
414
415 /* Update gdb's knowledge of the terminal size.  */
416 void
417 tui_update_gdb_sizes ()
418 {
419   char cmd[50];
420   extern int screenheight, screenwidth;         /* in readline */
421
422   /* Set to TUI command window dimension or use readline values.  */
423   sprintf (cmd, "set width %d",
424            tui_active ? cmdWin->generic.width : screenwidth);
425   execute_command (cmd, 0);
426   sprintf (cmd, "set height %d",
427            tui_active ? cmdWin->generic.height : screenheight);
428   execute_command (cmd, 0);
429 }
430
431
432 /*
433    ** tuiSetWinFocusTo
434    **        Set the logical focus to winInfo
435  */
436 void
437 tuiSetWinFocusTo (TuiWinInfoPtr winInfo)
438 {
439   if (m_winPtrNotNull (winInfo))
440     {
441       TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
442
443       if (m_winPtrNotNull (winWithFocus) &&
444           winWithFocus->generic.type != CMD_WIN)
445         unhighlightWin (winWithFocus);
446       tuiSetWinWithFocus (winInfo);
447       if (winInfo->generic.type != CMD_WIN)
448         highlightWin (winInfo);
449     }
450
451   return;
452 }                               /* tuiSetWinFocusTo */
453
454
455 /*
456    ** tuiScrollForward().
457  */
458 void
459 tuiScrollForward (TuiWinInfoPtr winToScroll, int numToScroll)
460 {
461   if (winToScroll != cmdWin)
462     {
463       int _numToScroll = numToScroll;
464
465       if (numToScroll == 0)
466         _numToScroll = winToScroll->generic.height - 3;
467       /*
468          ** If we are scrolling the source or disassembly window, do a
469          ** "psuedo" scroll since not all of the source is in memory,
470          ** only what is in the viewport.  If winToScroll is the
471          ** command window do nothing since the term should handle it.
472        */
473       if (winToScroll == srcWin)
474         tuiVerticalSourceScroll (FORWARD_SCROLL, _numToScroll);
475       else if (winToScroll == disassemWin)
476         tuiVerticalDisassemScroll (FORWARD_SCROLL, _numToScroll);
477       else if (winToScroll == dataWin)
478         tuiVerticalDataScroll (FORWARD_SCROLL, _numToScroll);
479     }
480
481   return;
482 }                               /* tuiScrollForward */
483
484
485 /*
486    ** tuiScrollBackward().
487  */
488 void
489 tuiScrollBackward (TuiWinInfoPtr winToScroll, int numToScroll)
490 {
491   if (winToScroll != cmdWin)
492     {
493       int _numToScroll = numToScroll;
494
495       if (numToScroll == 0)
496         _numToScroll = winToScroll->generic.height - 3;
497       /*
498          ** If we are scrolling the source or disassembly window, do a
499          ** "psuedo" scroll since not all of the source is in memory,
500          ** only what is in the viewport.  If winToScroll is the
501          ** command window do nothing since the term should handle it.
502        */
503       if (winToScroll == srcWin)
504         tuiVerticalSourceScroll (BACKWARD_SCROLL, _numToScroll);
505       else if (winToScroll == disassemWin)
506         tuiVerticalDisassemScroll (BACKWARD_SCROLL, _numToScroll);
507       else if (winToScroll == dataWin)
508         tuiVerticalDataScroll (BACKWARD_SCROLL, _numToScroll);
509     }
510   return;
511 }                               /* tuiScrollBackward */
512
513
514 /*
515    ** tuiScrollLeft().
516  */
517 void
518 tuiScrollLeft (TuiWinInfoPtr winToScroll, int numToScroll)
519 {
520   if (winToScroll != cmdWin)
521     {
522       int _numToScroll = numToScroll;
523
524       if (_numToScroll == 0)
525         _numToScroll = 1;
526       /*
527          ** If we are scrolling the source or disassembly window, do a
528          ** "psuedo" scroll since not all of the source is in memory,
529          ** only what is in the viewport. If winToScroll is the
530          ** command window do nothing since the term should handle it.
531        */
532       if (winToScroll == srcWin || winToScroll == disassemWin)
533         tuiHorizontalSourceScroll (winToScroll, LEFT_SCROLL, _numToScroll);
534     }
535   return;
536 }                               /* tuiScrollLeft */
537
538
539 /*
540    ** tuiScrollRight().
541  */
542 void
543 tuiScrollRight (TuiWinInfoPtr winToScroll, int numToScroll)
544 {
545   if (winToScroll != cmdWin)
546     {
547       int _numToScroll = numToScroll;
548
549       if (_numToScroll == 0)
550         _numToScroll = 1;
551       /*
552          ** If we are scrolling the source or disassembly window, do a
553          ** "psuedo" scroll since not all of the source is in memory,
554          ** only what is in the viewport. If winToScroll is the
555          ** command window do nothing since the term should handle it.
556        */
557       if (winToScroll == srcWin || winToScroll == disassemWin)
558         tuiHorizontalSourceScroll (winToScroll, RIGHT_SCROLL, _numToScroll);
559     }
560   return;
561 }                               /* tuiScrollRight */
562
563
564 /*
565    ** tui_scroll().
566    **    Scroll a window.  Arguments are passed through a va_list.
567  */
568 void
569 tui_scroll (TuiScrollDirection direction,
570             TuiWinInfoPtr winToScroll,
571             int numToScroll)
572 {
573   switch (direction)
574     {
575     case FORWARD_SCROLL:
576       tuiScrollForward (winToScroll, numToScroll);
577       break;
578     case BACKWARD_SCROLL:
579       tuiScrollBackward (winToScroll, numToScroll);
580       break;
581     case LEFT_SCROLL:
582       tuiScrollLeft (winToScroll, numToScroll);
583       break;
584     case RIGHT_SCROLL:
585       tuiScrollRight (winToScroll, numToScroll);
586       break;
587     default:
588       break;
589     }
590 }
591
592
593 /*
594    ** tuiRefreshAll().
595  */
596 void
597 tuiRefreshAll (void)
598 {
599   TuiWinType type;
600
601   clearok (curscr, TRUE);
602   refreshAll (winList);
603   for (type = SRC_WIN; type < MAX_MAJOR_WINDOWS; type++)
604     {
605       if (winList[type] && winList[type]->generic.isVisible)
606         {
607           switch (type)
608             {
609             case SRC_WIN:
610             case DISASSEM_WIN:
611               tuiShowSourceContent (winList[type]);
612               checkAndDisplayHighlightIfNeeded (winList[type]);
613               tuiEraseExecInfoContent (winList[type]);
614               tuiUpdateExecInfo (winList[type]);
615               break;
616             case DATA_WIN:
617               tuiRefreshDataWin ();
618               break;
619             default:
620               break;
621             }
622         }
623     }
624   tuiShowLocatorContent ();
625 }
626
627
628 /*
629    ** tuiResizeAll().
630    **      Resize all the windows based on the the terminal size.  This
631    **      function gets called from within the readline sinwinch handler.
632  */
633 void
634 tuiResizeAll (void)
635 {
636   int heightDiff, widthDiff;
637   extern int screenheight, screenwidth;         /* in readline */
638
639   widthDiff = screenwidth - termWidth ();
640   heightDiff = screenheight - termHeight ();
641   if (heightDiff || widthDiff)
642     {
643       TuiLayoutType curLayout = currentLayout ();
644       TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
645       TuiWinInfoPtr firstWin, secondWin;
646       TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
647       TuiWinType winType;
648       int newHeight, splitDiff, cmdSplitDiff, numWinsDisplayed = 2;
649
650       /* turn keypad off while we resize */
651       if (winWithFocus != cmdWin)
652         keypad (cmdWin->generic.handle, FALSE);
653       tui_update_gdb_sizes ();
654       setTermHeightTo (screenheight);
655       setTermWidthTo (screenwidth);
656       if (curLayout == SRC_DISASSEM_COMMAND ||
657         curLayout == SRC_DATA_COMMAND || curLayout == DISASSEM_DATA_COMMAND)
658         numWinsDisplayed++;
659       splitDiff = heightDiff / numWinsDisplayed;
660       cmdSplitDiff = splitDiff;
661       if (heightDiff % numWinsDisplayed)
662         {
663           if (heightDiff < 0)
664             cmdSplitDiff--;
665           else
666             cmdSplitDiff++;
667         }
668       /* now adjust each window */
669       clear ();
670       refresh ();
671       switch (curLayout)
672         {
673         case SRC_COMMAND:
674         case DISASSEM_COMMAND:
675           firstWin = (TuiWinInfoPtr) (sourceWindows ())->list[0];
676           firstWin->generic.width += widthDiff;
677           locator->width += widthDiff;
678           /* check for invalid heights */
679           if (heightDiff == 0)
680             newHeight = firstWin->generic.height;
681           else if ((firstWin->generic.height + splitDiff) >=
682                    (screenheight - MIN_CMD_WIN_HEIGHT - 1))
683             newHeight = screenheight - MIN_CMD_WIN_HEIGHT - 1;
684           else if ((firstWin->generic.height + splitDiff) <= 0)
685             newHeight = MIN_WIN_HEIGHT;
686           else
687             newHeight = firstWin->generic.height + splitDiff;
688
689           _makeInvisibleAndSetNewHeight (firstWin, newHeight);
690           cmdWin->generic.origin.y = locator->origin.y + 1;
691           cmdWin->generic.width += widthDiff;
692           newHeight = screenheight - cmdWin->generic.origin.y;
693           _makeInvisibleAndSetNewHeight (cmdWin, newHeight);
694           _makeVisibleWithNewHeight (firstWin);
695           _makeVisibleWithNewHeight (cmdWin);
696           if (firstWin->generic.contentSize <= 0)
697             tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT);
698           break;
699         default:
700           if (curLayout == SRC_DISASSEM_COMMAND)
701             {
702               firstWin = srcWin;
703               firstWin->generic.width += widthDiff;
704               secondWin = disassemWin;
705               secondWin->generic.width += widthDiff;
706             }
707           else
708             {
709               firstWin = dataWin;
710               firstWin->generic.width += widthDiff;
711               secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0];
712               secondWin->generic.width += widthDiff;
713             }
714           /* Change the first window's height/width */
715           /* check for invalid heights */
716           if (heightDiff == 0)
717             newHeight = firstWin->generic.height;
718           else if ((firstWin->generic.height +
719                     secondWin->generic.height + (splitDiff * 2)) >=
720                    (screenheight - MIN_CMD_WIN_HEIGHT - 1))
721             newHeight = (screenheight - MIN_CMD_WIN_HEIGHT - 1) / 2;
722           else if ((firstWin->generic.height + splitDiff) <= 0)
723             newHeight = MIN_WIN_HEIGHT;
724           else
725             newHeight = firstWin->generic.height + splitDiff;
726           _makeInvisibleAndSetNewHeight (firstWin, newHeight);
727
728           if (firstWin == dataWin && widthDiff != 0)
729             firstWin->detail.dataDisplayInfo.regsColumnCount =
730               tuiCalculateRegsColumnCount (
731                           firstWin->detail.dataDisplayInfo.regsDisplayType);
732           locator->width += widthDiff;
733
734           /* Change the second window's height/width */
735           /* check for invalid heights */
736           if (heightDiff == 0)
737             newHeight = secondWin->generic.height;
738           else if ((firstWin->generic.height +
739                     secondWin->generic.height + (splitDiff * 2)) >=
740                    (screenheight - MIN_CMD_WIN_HEIGHT - 1))
741             {
742               newHeight = screenheight - MIN_CMD_WIN_HEIGHT - 1;
743               if (newHeight % 2)
744                 newHeight = (newHeight / 2) + 1;
745               else
746                 newHeight /= 2;
747             }
748           else if ((secondWin->generic.height + splitDiff) <= 0)
749             newHeight = MIN_WIN_HEIGHT;
750           else
751             newHeight = secondWin->generic.height + splitDiff;
752           secondWin->generic.origin.y = firstWin->generic.height - 1;
753           _makeInvisibleAndSetNewHeight (secondWin, newHeight);
754
755           /* Change the command window's height/width */
756           cmdWin->generic.origin.y = locator->origin.y + 1;
757           _makeInvisibleAndSetNewHeight (
758                              cmdWin, cmdWin->generic.height + cmdSplitDiff);
759           _makeVisibleWithNewHeight (firstWin);
760           _makeVisibleWithNewHeight (secondWin);
761           _makeVisibleWithNewHeight (cmdWin);
762           if (firstWin->generic.contentSize <= 0)
763             tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT);
764           if (secondWin->generic.contentSize <= 0)
765             tuiEraseSourceContent (secondWin, EMPTY_SOURCE_PROMPT);
766           break;
767         }
768       /*
769          ** Now remove all invisible windows, and their content so that they get
770          ** created again when called for with the new size
771        */
772       for (winType = SRC_WIN; (winType < MAX_MAJOR_WINDOWS); winType++)
773         {
774           if (winType != CMD_WIN && m_winPtrNotNull (winList[winType]) &&
775               !winList[winType]->generic.isVisible)
776             {
777               freeWindow (winList[winType]);
778               winList[winType] = (TuiWinInfoPtr) NULL;
779             }
780         }
781       tuiSetWinResizedTo (TRUE);
782       /* turn keypad back on, unless focus is in the command window */
783       if (winWithFocus != cmdWin)
784         keypad (cmdWin->generic.handle, TRUE);
785     }
786   return;
787 }                               /* tuiResizeAll */
788
789
790 /*
791    ** tuiSigwinchHandler()
792    **    SIGWINCH signal handler for the tui.  This signal handler is
793    **    always called, even when the readline package clears signals
794    **    because it is set as the old_sigwinch() (TUI only)
795  */
796 void
797 tuiSigwinchHandler (int signal)
798 {
799   /*
800      ** Say that a resize was done so that the readline can do it
801      ** later when appropriate.
802    */
803   tuiSetWinResizedTo (TRUE);
804
805   return;
806 }                               /* tuiSigwinchHandler */
807
808
809
810 /*************************
811 ** STATIC LOCAL FUNCTIONS
812 **************************/
813
814
815 /*
816    ** _tuiScrollForward_command().
817  */
818 static void
819 _tuiScrollForward_command (char *arg, int fromTTY)
820 {
821   int numToScroll = 1;
822   TuiWinInfoPtr winToScroll;
823
824   /* Make sure the curses mode is enabled.  */
825   tui_enable ();
826   if (arg == (char *) NULL)
827     _parseScrollingArgs (arg, &winToScroll, (int *) NULL);
828   else
829     _parseScrollingArgs (arg, &winToScroll, &numToScroll);
830   tui_scroll (FORWARD_SCROLL, winToScroll, numToScroll);
831 }
832
833
834 /*
835    ** _tuiScrollBackward_command().
836  */
837 static void
838 _tuiScrollBackward_command (char *arg, int fromTTY)
839 {
840   int numToScroll = 1;
841   TuiWinInfoPtr winToScroll;
842
843   /* Make sure the curses mode is enabled.  */
844   tui_enable ();
845   if (arg == (char *) NULL)
846     _parseScrollingArgs (arg, &winToScroll, (int *) NULL);
847   else
848     _parseScrollingArgs (arg, &winToScroll, &numToScroll);
849   tui_scroll (BACKWARD_SCROLL, winToScroll, numToScroll);
850 }
851
852
853 /*
854    ** _tuiScrollLeft_command().
855  */
856 static void
857 _tuiScrollLeft_command (char *arg, int fromTTY)
858 {
859   int numToScroll;
860   TuiWinInfoPtr winToScroll;
861
862   /* Make sure the curses mode is enabled.  */
863   tui_enable ();
864   _parseScrollingArgs (arg, &winToScroll, &numToScroll);
865   tui_scroll (LEFT_SCROLL, winToScroll, numToScroll);
866 }
867
868
869 /*
870    ** _tuiScrollRight_command().
871  */
872 static void
873 _tuiScrollRight_command (char *arg, int fromTTY)
874 {
875   int numToScroll;
876   TuiWinInfoPtr winToScroll;
877
878   /* Make sure the curses mode is enabled.  */
879   tui_enable ();
880   _parseScrollingArgs (arg, &winToScroll, &numToScroll);
881   tui_scroll (RIGHT_SCROLL, winToScroll, numToScroll);
882 }
883
884
885 /*
886    ** _tuiSetFocus().
887    **     Set focus to the window named by 'arg'
888  */
889 static void
890 _tuiSetFocus (char *arg, int fromTTY)
891 {
892   if (arg != (char *) NULL)
893     {
894       char *bufPtr = (char *) xstrdup (arg);
895       int i;
896       TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL;
897
898       for (i = 0; (i < strlen (bufPtr)); i++)
899         bufPtr[i] = toupper (arg[i]);
900
901       if (subset_compare (bufPtr, "NEXT"))
902         winInfo = tuiNextWin (tuiWinWithFocus ());
903       else if (subset_compare (bufPtr, "PREV"))
904         winInfo = tuiPrevWin (tuiWinWithFocus ());
905       else
906         winInfo = partialWinByName (bufPtr);
907
908       if (winInfo == (TuiWinInfoPtr) NULL || !winInfo->generic.isVisible)
909         warning ("Invalid window specified. \n\
910 The window name specified must be valid and visible.\n");
911       else
912         {
913           tuiSetWinFocusTo (winInfo);
914           keypad (cmdWin->generic.handle, (winInfo != cmdWin));
915         }
916
917       if (dataWin && dataWin->generic.isVisible)
918         tuiRefreshDataWin ();
919       tuiFree (bufPtr);
920       printf_filtered ("Focus set to %s window.\n",
921                        winName ((TuiGenWinInfoPtr) tuiWinWithFocus ()));
922     }
923   else
924     warning ("Incorrect Number of Arguments.\n%s", FOCUS_USAGE);
925
926   return;
927 }                               /* _tuiSetFocus */
928
929 /*
930    ** _tuiSetFocus_command()
931  */
932 static void
933 _tuiSetFocus_command (char *arg, int fromTTY)
934 {
935   /* Make sure the curses mode is enabled.  */
936   tui_enable ();
937   _tuiSetFocus (arg, fromTTY);
938 }
939
940
941 /*
942    ** _tuiAllWindowsInfo().
943  */
944 static void
945 _tuiAllWindowsInfo (char *arg, int fromTTY)
946 {
947   TuiWinType type;
948   TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
949
950   for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++)
951     if (winList[type] && winList[type]->generic.isVisible)
952       {
953         if (winWithFocus == winList[type])
954           printf_filtered ("        %s\t(%d lines)  <has focus>\n",
955                            winName (&winList[type]->generic),
956                            winList[type]->generic.height);
957         else
958           printf_filtered ("        %s\t(%d lines)\n",
959                            winName (&winList[type]->generic),
960                            winList[type]->generic.height);
961       }
962
963   return;
964 }                               /* _tuiAllWindowsInfo */
965
966
967 /*
968    ** _tuiRefreshAll_command().
969  */
970 static void
971 _tuiRefreshAll_command (char *arg, int fromTTY)
972 {
973   /* Make sure the curses mode is enabled.  */
974   tui_enable ();
975
976   tuiRefreshAll ();
977 }
978
979
980 /*
981    ** _tuiSetWinTabWidth_command().
982    **        Set the height of the specified window.
983  */
984 static void
985 _tuiSetTabWidth_command (char *arg, int fromTTY)
986 {
987   /* Make sure the curses mode is enabled.  */
988   tui_enable ();
989   if (arg != (char *) NULL)
990     {
991       int ts;
992
993       ts = atoi (arg);
994       if (ts > 0)
995         tuiSetDefaultTabLen (ts);
996       else
997         warning ("Tab widths greater than 0 must be specified.\n");
998     }
999
1000   return;
1001 }                               /* _tuiSetTabWidth_command */
1002
1003
1004 /*
1005    ** _tuiSetWinHeight().
1006    **        Set the height of the specified window.
1007  */
1008 static void
1009 _tuiSetWinHeight (char *arg, int fromTTY)
1010 {
1011   /* Make sure the curses mode is enabled.  */
1012   tui_enable ();
1013   if (arg != (char *) NULL)
1014     {
1015       char *buf = xstrdup (arg);
1016       char *bufPtr = buf;
1017       char *wname = (char *) NULL;
1018       int newHeight, i;
1019       TuiWinInfoPtr winInfo;
1020
1021       wname = bufPtr;
1022       bufPtr = strchr (bufPtr, ' ');
1023       if (bufPtr != (char *) NULL)
1024         {
1025           *bufPtr = (char) 0;
1026
1027           /*
1028              ** Validate the window name
1029            */
1030           for (i = 0; i < strlen (wname); i++)
1031             wname[i] = toupper (wname[i]);
1032           winInfo = partialWinByName (wname);
1033
1034           if (winInfo == (TuiWinInfoPtr) NULL || !winInfo->generic.isVisible)
1035             warning ("Invalid window specified. \n\
1036 The window name specified must be valid and visible.\n");
1037           else
1038             {
1039               /* Process the size */
1040               while (*(++bufPtr) == ' ')
1041                 ;
1042
1043               if (*bufPtr != (char) 0)
1044                 {
1045                   int negate = FALSE;
1046                   int fixedSize = TRUE;
1047                   int inputNo;;
1048
1049                   if (*bufPtr == '+' || *bufPtr == '-')
1050                     {
1051                       if (*bufPtr == '-')
1052                         negate = TRUE;
1053                       fixedSize = FALSE;
1054                       bufPtr++;
1055                     }
1056                   inputNo = atoi (bufPtr);
1057                   if (inputNo > 0)
1058                     {
1059                       if (negate)
1060                         inputNo *= (-1);
1061                       if (fixedSize)
1062                         newHeight = inputNo;
1063                       else
1064                         newHeight = winInfo->generic.height + inputNo;
1065                       /*
1066                          ** Now change the window's height, and adjust all
1067                          ** other windows around it
1068                        */
1069                       if (_tuiAdjustWinHeights (winInfo,
1070                                                 newHeight) == TUI_FAILURE)
1071                         warning ("Invalid window height specified.\n%s",
1072                                  WIN_HEIGHT_USAGE);
1073                       else
1074                         tui_update_gdb_sizes ();
1075                     }
1076                   else
1077                     warning ("Invalid window height specified.\n%s",
1078                              WIN_HEIGHT_USAGE);
1079                 }
1080             }
1081         }
1082       else
1083         printf_filtered (WIN_HEIGHT_USAGE);
1084
1085       if (buf != (char *) NULL)
1086         tuiFree (buf);
1087     }
1088   else
1089     printf_filtered (WIN_HEIGHT_USAGE);
1090
1091   return;
1092 }                               /* _tuiSetWinHeight */
1093
1094 /*
1095    ** _tuiSetWinHeight_command().
1096    **        Set the height of the specified window, with va_list.
1097  */
1098 static void
1099 _tuiSetWinHeight_command (char *arg, int fromTTY)
1100 {
1101   /* Make sure the curses mode is enabled.  */
1102   tui_enable ();
1103   _tuiSetWinHeight (arg, fromTTY);
1104 }
1105
1106
1107 /*
1108    ** _tuiXDBsetWinHeight().
1109    **        XDB Compatibility command for setting the window height.  This will
1110    **        increase or decrease the command window by the specified amount.
1111  */
1112 static void
1113 _tuiXDBsetWinHeight (char *arg, int fromTTY)
1114 {
1115   /* Make sure the curses mode is enabled.  */
1116   tui_enable ();
1117   if (arg != (char *) NULL)
1118     {
1119       int inputNo = atoi (arg);
1120
1121       if (inputNo > 0)
1122         {                       /* Add 1 for the locator */
1123           int newHeight = termHeight () - (inputNo + 1);
1124
1125           if (!_newHeightOk (winList[CMD_WIN], newHeight) ||
1126               _tuiAdjustWinHeights (winList[CMD_WIN],
1127                                     newHeight) == TUI_FAILURE)
1128             warning ("Invalid window height specified.\n%s",
1129                      XDBWIN_HEIGHT_USAGE);
1130         }
1131       else
1132         warning ("Invalid window height specified.\n%s",
1133                  XDBWIN_HEIGHT_USAGE);
1134     }
1135   else
1136     warning ("Invalid window height specified.\n%s", XDBWIN_HEIGHT_USAGE);
1137
1138   return;
1139 }                               /* _tuiXDBsetWinHeight */
1140
1141 /*
1142    ** _tuiSetWinHeight_command().
1143    **        Set the height of the specified window, with va_list.
1144  */
1145 static void
1146 _tuiXDBsetWinHeight_command (char *arg, int fromTTY)
1147 {
1148   _tuiXDBsetWinHeight (arg, fromTTY);
1149 }
1150
1151
1152 /*
1153    ** _tuiAdjustWinHeights().
1154    **        Function to adjust all window heights around the primary
1155  */
1156 static TuiStatus
1157 _tuiAdjustWinHeights (TuiWinInfoPtr primaryWinInfo, int newHeight)
1158 {
1159   TuiStatus status = TUI_FAILURE;
1160
1161   if (_newHeightOk (primaryWinInfo, newHeight))
1162     {
1163       status = TUI_SUCCESS;
1164       if (newHeight != primaryWinInfo->generic.height)
1165         {
1166           int diff;
1167           TuiWinInfoPtr winInfo;
1168           TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
1169           TuiLayoutType curLayout = currentLayout ();
1170
1171           diff = (newHeight - primaryWinInfo->generic.height) * (-1);
1172           if (curLayout == SRC_COMMAND || curLayout == DISASSEM_COMMAND)
1173             {
1174               TuiWinInfoPtr srcWinInfo;
1175
1176               _makeInvisibleAndSetNewHeight (primaryWinInfo, newHeight);
1177               if (primaryWinInfo->generic.type == CMD_WIN)
1178                 {
1179                   winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[0];
1180                   srcWinInfo = winInfo;
1181                 }
1182               else
1183                 {
1184                   winInfo = winList[CMD_WIN];
1185                   srcWinInfo = primaryWinInfo;
1186                 }
1187               _makeInvisibleAndSetNewHeight (winInfo,
1188                                              winInfo->generic.height + diff);
1189               cmdWin->generic.origin.y = locator->origin.y + 1;
1190               _makeVisibleWithNewHeight (winInfo);
1191               _makeVisibleWithNewHeight (primaryWinInfo);
1192               if (srcWinInfo->generic.contentSize <= 0)
1193                 tuiEraseSourceContent (srcWinInfo, EMPTY_SOURCE_PROMPT);
1194             }
1195           else
1196             {
1197               TuiWinInfoPtr firstWin, secondWin;
1198
1199               if (curLayout == SRC_DISASSEM_COMMAND)
1200                 {
1201                   firstWin = srcWin;
1202                   secondWin = disassemWin;
1203                 }
1204               else
1205                 {
1206                   firstWin = dataWin;
1207                   secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0];
1208                 }
1209               if (primaryWinInfo == cmdWin)
1210                 {               /*
1211                                    ** Split the change in height accross the 1st & 2nd windows
1212                                    ** adjusting them as well.
1213                                  */
1214                   int firstSplitDiff = diff / 2;        /* subtract the locator */
1215                   int secondSplitDiff = firstSplitDiff;
1216
1217                   if (diff % 2)
1218                     {
1219                       if (firstWin->generic.height >
1220                           secondWin->generic.height)
1221                         if (diff < 0)
1222                           firstSplitDiff--;
1223                         else
1224                           firstSplitDiff++;
1225                       else
1226                         {
1227                           if (diff < 0)
1228                             secondSplitDiff--;
1229                           else
1230                             secondSplitDiff++;
1231                         }
1232                     }
1233                   /* make sure that the minimum hieghts are honored */
1234                   while ((firstWin->generic.height + firstSplitDiff) < 3)
1235                     {
1236                       firstSplitDiff++;
1237                       secondSplitDiff--;
1238                     }
1239                   while ((secondWin->generic.height + secondSplitDiff) < 3)
1240                     {
1241                       secondSplitDiff++;
1242                       firstSplitDiff--;
1243                     }
1244                   _makeInvisibleAndSetNewHeight (
1245                                                   firstWin,
1246                                  firstWin->generic.height + firstSplitDiff);
1247                   secondWin->generic.origin.y = firstWin->generic.height - 1;
1248                   _makeInvisibleAndSetNewHeight (
1249                     secondWin, secondWin->generic.height + secondSplitDiff);
1250                   cmdWin->generic.origin.y = locator->origin.y + 1;
1251                   _makeInvisibleAndSetNewHeight (cmdWin, newHeight);
1252                 }
1253               else
1254                 {
1255                   if ((cmdWin->generic.height + diff) < 1)
1256                     {           /*
1257                                    ** If there is no way to increase the command window
1258                                    ** take real estate from the 1st or 2nd window.
1259                                  */
1260                       if ((cmdWin->generic.height + diff) < 1)
1261                         {
1262                           int i;
1263                           for (i = cmdWin->generic.height + diff;
1264                                (i < 1); i++)
1265                             if (primaryWinInfo == firstWin)
1266                               secondWin->generic.height--;
1267                             else
1268                               firstWin->generic.height--;
1269                         }
1270                     }
1271                   if (primaryWinInfo == firstWin)
1272                     _makeInvisibleAndSetNewHeight (firstWin, newHeight);
1273                   else
1274                     _makeInvisibleAndSetNewHeight (
1275                                                     firstWin,
1276                                                   firstWin->generic.height);
1277                   secondWin->generic.origin.y = firstWin->generic.height - 1;
1278                   if (primaryWinInfo == secondWin)
1279                     _makeInvisibleAndSetNewHeight (secondWin, newHeight);
1280                   else
1281                     _makeInvisibleAndSetNewHeight (
1282                                       secondWin, secondWin->generic.height);
1283                   cmdWin->generic.origin.y = locator->origin.y + 1;
1284                   if ((cmdWin->generic.height + diff) < 1)
1285                     _makeInvisibleAndSetNewHeight (cmdWin, 1);
1286                   else
1287                     _makeInvisibleAndSetNewHeight (
1288                                      cmdWin, cmdWin->generic.height + diff);
1289                 }
1290               _makeVisibleWithNewHeight (cmdWin);
1291               _makeVisibleWithNewHeight (secondWin);
1292               _makeVisibleWithNewHeight (firstWin);
1293               if (firstWin->generic.contentSize <= 0)
1294                 tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT);
1295               if (secondWin->generic.contentSize <= 0)
1296                 tuiEraseSourceContent (secondWin, EMPTY_SOURCE_PROMPT);
1297             }
1298         }
1299     }
1300
1301   return status;
1302 }                               /* _tuiAdjustWinHeights */
1303
1304
1305 /*
1306    ** _makeInvisibleAndSetNewHeight().
1307    **        Function make the target window (and auxillary windows associated
1308    **        with the targer) invisible, and set the new height and location.
1309  */
1310 static void
1311 _makeInvisibleAndSetNewHeight (TuiWinInfoPtr winInfo, int height)
1312 {
1313   int i;
1314   TuiGenWinInfoPtr genWinInfo;
1315
1316
1317   m_beInvisible (&winInfo->generic);
1318   winInfo->generic.height = height;
1319   if (height > 1)
1320     winInfo->generic.viewportHeight = height - 1;
1321   else
1322     winInfo->generic.viewportHeight = height;
1323   if (winInfo != cmdWin)
1324     winInfo->generic.viewportHeight--;
1325
1326   /* Now deal with the auxillary windows associated with winInfo */
1327   switch (winInfo->generic.type)
1328     {
1329     case SRC_WIN:
1330     case DISASSEM_WIN:
1331       genWinInfo = winInfo->detail.sourceInfo.executionInfo;
1332       m_beInvisible (genWinInfo);
1333       genWinInfo->height = height;
1334       genWinInfo->origin.y = winInfo->generic.origin.y;
1335       if (height > 1)
1336         genWinInfo->viewportHeight = height - 1;
1337       else
1338         genWinInfo->viewportHeight = height;
1339       if (winInfo != cmdWin)
1340         genWinInfo->viewportHeight--;
1341
1342       if (m_hasLocator (winInfo))
1343         {
1344           genWinInfo = locatorWinInfoPtr ();
1345           m_beInvisible (genWinInfo);
1346           genWinInfo->origin.y = winInfo->generic.origin.y + height;
1347         }
1348       break;
1349     case DATA_WIN:
1350       /* delete all data item windows */
1351       for (i = 0; i < winInfo->generic.contentSize; i++)
1352         {
1353           genWinInfo = (TuiGenWinInfoPtr) & ((TuiWinElementPtr)
1354                       winInfo->generic.content[i])->whichElement.dataWindow;
1355           tuiDelwin (genWinInfo->handle);
1356           genWinInfo->handle = (WINDOW *) NULL;
1357         }
1358       break;
1359     default:
1360       break;
1361     }
1362 }
1363
1364
1365 /*
1366    ** _makeVisibleWithNewHeight().
1367    **        Function to make the windows with new heights visible.
1368    **        This means re-creating the windows' content since the window
1369    **        had to be destroyed to be made invisible.
1370  */
1371 static void
1372 _makeVisibleWithNewHeight (TuiWinInfoPtr winInfo)
1373 {
1374   struct symtab *s;
1375
1376   m_beVisible (&winInfo->generic);
1377   checkAndDisplayHighlightIfNeeded (winInfo);
1378   switch (winInfo->generic.type)
1379     {
1380     case SRC_WIN:
1381     case DISASSEM_WIN:
1382       freeWinContent (winInfo->detail.sourceInfo.executionInfo);
1383       m_beVisible (winInfo->detail.sourceInfo.executionInfo);
1384       if (winInfo->generic.content != (OpaquePtr) NULL)
1385         {
1386           TuiLineOrAddress lineOrAddr;
1387           struct symtab_and_line cursal
1388             = get_current_source_symtab_and_line ();
1389
1390           if (winInfo->generic.type == SRC_WIN)
1391             lineOrAddr.lineNo =
1392               winInfo->detail.sourceInfo.startLineOrAddr.lineNo;
1393           else
1394             lineOrAddr.addr =
1395               winInfo->detail.sourceInfo.startLineOrAddr.addr;
1396           freeWinContent (&winInfo->generic);
1397           tuiUpdateSourceWindow (winInfo,
1398                                  cursal.symtab, lineOrAddr, TRUE);
1399         }
1400       else if (deprecated_selected_frame != (struct frame_info *) NULL)
1401         {
1402           TuiLineOrAddress line;
1403           struct symtab_and_line cursal = get_current_source_symtab_and_line ();
1404
1405
1406           s = find_pc_symtab (deprecated_selected_frame->pc);
1407           if (winInfo->generic.type == SRC_WIN)
1408             line.lineNo = cursal.line;
1409           else
1410             {
1411               find_line_pc (s, cursal.line, &line.addr);
1412             }
1413           tuiUpdateSourceWindow (winInfo, s, line, TRUE);
1414         }
1415       if (m_hasLocator (winInfo))
1416         {
1417           m_beVisible (locatorWinInfoPtr ());
1418           tuiShowLocatorContent ();
1419         }
1420       break;
1421     case DATA_WIN:
1422       tuiDisplayAllData ();
1423       break;
1424     case CMD_WIN:
1425       winInfo->detail.commandInfo.curLine = 0;
1426       winInfo->detail.commandInfo.curch = 0;
1427       wmove (winInfo->generic.handle,
1428              winInfo->detail.commandInfo.curLine,
1429              winInfo->detail.commandInfo.curch);
1430       break;
1431     default:
1432       break;
1433     }
1434
1435   return;
1436 }                               /* _makeVisibleWithNewHeight */
1437
1438
1439 static int
1440 _newHeightOk (TuiWinInfoPtr primaryWinInfo, int newHeight)
1441 {
1442   int ok = (newHeight < termHeight ());
1443
1444   if (ok)
1445     {
1446       int diff;
1447       TuiLayoutType curLayout = currentLayout ();
1448
1449       diff = (newHeight - primaryWinInfo->generic.height) * (-1);
1450       if (curLayout == SRC_COMMAND || curLayout == DISASSEM_COMMAND)
1451         {
1452           ok = ((primaryWinInfo->generic.type == CMD_WIN &&
1453                  newHeight <= (termHeight () - 4) &&
1454                  newHeight >= MIN_CMD_WIN_HEIGHT) ||
1455                 (primaryWinInfo->generic.type != CMD_WIN &&
1456                  newHeight <= (termHeight () - 2) &&
1457                  newHeight >= MIN_WIN_HEIGHT));
1458           if (ok)
1459             {                   /* check the total height */
1460               TuiWinInfoPtr winInfo;
1461
1462               if (primaryWinInfo == cmdWin)
1463                 winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[0];
1464               else
1465                 winInfo = cmdWin;
1466               ok = ((newHeight +
1467                      (winInfo->generic.height + diff)) <= termHeight ());
1468             }
1469         }
1470       else
1471         {
1472           int curTotalHeight, totalHeight, minHeight = 0;
1473           TuiWinInfoPtr firstWin, secondWin;
1474
1475           if (curLayout == SRC_DISASSEM_COMMAND)
1476             {
1477               firstWin = srcWin;
1478               secondWin = disassemWin;
1479             }
1480           else
1481             {
1482               firstWin = dataWin;
1483               secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0];
1484             }
1485           /*
1486              ** We could simply add all the heights to obtain the same result
1487              ** but below is more explicit since we subtract 1 for the
1488              ** line that the first and second windows share, and add one
1489              ** for the locator.
1490            */
1491           totalHeight = curTotalHeight =
1492             (firstWin->generic.height + secondWin->generic.height - 1)
1493             + cmdWin->generic.height + 1 /*locator */ ;
1494           if (primaryWinInfo == cmdWin)
1495             {
1496               /* locator included since first & second win share a line */
1497               ok = ((firstWin->generic.height +
1498                      secondWin->generic.height + diff) >=
1499                     (MIN_WIN_HEIGHT * 2) &&
1500                     newHeight >= MIN_CMD_WIN_HEIGHT);
1501               if (ok)
1502                 {
1503                   totalHeight = newHeight + (firstWin->generic.height +
1504                                           secondWin->generic.height + diff);
1505                   minHeight = MIN_CMD_WIN_HEIGHT;
1506                 }
1507             }
1508           else
1509             {
1510               minHeight = MIN_WIN_HEIGHT;
1511               /*
1512                  ** First see if we can increase/decrease the command
1513                  ** window.  And make sure that the command window is
1514                  ** at least 1 line
1515                */
1516               ok = ((cmdWin->generic.height + diff) > 0);
1517               if (!ok)
1518                 {               /*
1519                                    ** Looks like we have to increase/decrease one of
1520                                    ** the other windows
1521                                  */
1522                   if (primaryWinInfo == firstWin)
1523                     ok = (secondWin->generic.height + diff) >= minHeight;
1524                   else
1525                     ok = (firstWin->generic.height + diff) >= minHeight;
1526                 }
1527               if (ok)
1528                 {
1529                   if (primaryWinInfo == firstWin)
1530                     totalHeight = newHeight +
1531                       secondWin->generic.height +
1532                       cmdWin->generic.height + diff;
1533                   else
1534                     totalHeight = newHeight +
1535                       firstWin->generic.height +
1536                       cmdWin->generic.height + diff;
1537                 }
1538             }
1539           /*
1540              ** Now make sure that the proposed total height doesn't exceed
1541              ** the old total height.
1542            */
1543           if (ok)
1544             ok = (newHeight >= minHeight && totalHeight <= curTotalHeight);
1545         }
1546     }
1547
1548   return ok;
1549 }                               /* _newHeightOk */
1550
1551
1552 /*
1553    ** _parseScrollingArgs().
1554  */
1555 static void
1556 _parseScrollingArgs (char *arg, TuiWinInfoPtr * winToScroll, int *numToScroll)
1557 {
1558   if (numToScroll)
1559     *numToScroll = 0;
1560   *winToScroll = tuiWinWithFocus ();
1561
1562   /*
1563      ** First set up the default window to scroll, in case there is no
1564      ** window name arg
1565    */
1566   if (arg != (char *) NULL)
1567     {
1568       char *buf, *bufPtr;
1569
1570       /* process the number of lines to scroll */
1571       buf = bufPtr = xstrdup (arg);
1572       if (isdigit (*bufPtr))
1573         {
1574           char *numStr;
1575
1576           numStr = bufPtr;
1577           bufPtr = strchr (bufPtr, ' ');
1578           if (bufPtr != (char *) NULL)
1579             {
1580               *bufPtr = (char) 0;
1581               if (numToScroll)
1582                 *numToScroll = atoi (numStr);
1583               bufPtr++;
1584             }
1585           else if (numToScroll)
1586             *numToScroll = atoi (numStr);
1587         }
1588
1589       /* process the window name if one is specified */
1590       if (bufPtr != (char *) NULL)
1591         {
1592           char *wname;
1593           int i;
1594
1595           if (*bufPtr == ' ')
1596             while (*(++bufPtr) == ' ')
1597               ;
1598
1599           if (*bufPtr != (char) 0)
1600             wname = bufPtr;
1601           else
1602             wname = "?";
1603           
1604           /* Validate the window name */
1605           for (i = 0; i < strlen (wname); i++)
1606             wname[i] = toupper (wname[i]);
1607           *winToScroll = partialWinByName (wname);
1608
1609           if (*winToScroll == (TuiWinInfoPtr) NULL ||
1610               !(*winToScroll)->generic.isVisible)
1611             warning ("Invalid window specified. \n\
1612 The window name specified must be valid and visible.\n");
1613           else if (*winToScroll == cmdWin)
1614             *winToScroll = (TuiWinInfoPtr) (sourceWindows ())->list[0];
1615         }
1616       tuiFree (buf);
1617     }
1618
1619   return;
1620 }                               /* _parseScrollingArgs */