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