2004-02-07 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 (struct tui_win_info *);
65 static void _makeInvisibleAndSetNewHeight (struct tui_win_info *, int);
66 static TuiStatus _tuiAdjustWinHeights (struct tui_win_info *, int);
67 static int _newHeightOk (struct tui_win_info *, 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 *, struct tui_win_info * *, 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 /* Set the logical focus to winInfo.    */
427 void
428 tui_set_win_focus_to (struct tui_win_info * winInfo)
429 {
430   if (m_winPtrNotNull (winInfo))
431     {
432       struct tui_win_info * winWithFocus = tui_win_with_focus ();
433
434       if (m_winPtrNotNull (winWithFocus) &&
435           winWithFocus->generic.type != CMD_WIN)
436         tui_unhighlight_win (winWithFocus);
437       tui_set_win_with_focus (winInfo);
438       if (winInfo->generic.type != CMD_WIN)
439         tui_highlight_win (winInfo);
440     }
441
442   return;
443 }                               /* tuiSetWinFocusTo */
444
445
446 void
447 tui_scroll_forward (struct tui_win_info * winToScroll, int numToScroll)
448 {
449   if (winToScroll != cmdWin)
450     {
451       int _numToScroll = numToScroll;
452
453       if (numToScroll == 0)
454         _numToScroll = winToScroll->generic.height - 3;
455       /*
456          ** If we are scrolling the source or disassembly window, do a
457          ** "psuedo" scroll since not all of the source is in memory,
458          ** only what is in the viewport.  If winToScroll is the
459          ** command window do nothing since the term should handle it.
460        */
461       if (winToScroll == srcWin)
462         tui_vertical_source_scroll (FORWARD_SCROLL, _numToScroll);
463       else if (winToScroll == disassemWin)
464         tui_vertical_disassem_scroll (FORWARD_SCROLL, _numToScroll);
465       else if (winToScroll == dataWin)
466         tui_vertical_data_scroll (FORWARD_SCROLL, _numToScroll);
467     }
468 }
469
470 void
471 tui_scroll_backward (struct tui_win_info * winToScroll, int numToScroll)
472 {
473   if (winToScroll != cmdWin)
474     {
475       int _numToScroll = numToScroll;
476
477       if (numToScroll == 0)
478         _numToScroll = winToScroll->generic.height - 3;
479       /*
480          ** If we are scrolling the source or disassembly window, do a
481          ** "psuedo" scroll since not all of the source is in memory,
482          ** only what is in the viewport.  If winToScroll is the
483          ** command window do nothing since the term should handle it.
484        */
485       if (winToScroll == srcWin)
486         tui_vertical_source_scroll (BACKWARD_SCROLL, _numToScroll);
487       else if (winToScroll == disassemWin)
488         tui_vertical_disassem_scroll (BACKWARD_SCROLL, _numToScroll);
489       else if (winToScroll == dataWin)
490         tui_vertical_data_scroll (BACKWARD_SCROLL, _numToScroll);
491     }
492 }
493
494
495 void
496 tui_scroll_left (struct tui_win_info * winToScroll, int numToScroll)
497 {
498   if (winToScroll != cmdWin)
499     {
500       int _numToScroll = numToScroll;
501
502       if (_numToScroll == 0)
503         _numToScroll = 1;
504       /*
505          ** If we are scrolling the source or disassembly window, do a
506          ** "psuedo" scroll since not all of the source is in memory,
507          ** only what is in the viewport. If winToScroll is the
508          ** command window do nothing since the term should handle it.
509        */
510       if (winToScroll == srcWin || winToScroll == disassemWin)
511         tui_horizontal_source_scroll (winToScroll, LEFT_SCROLL, _numToScroll);
512     }
513 }
514
515
516 void
517 tui_scroll_right (struct tui_win_info * winToScroll, int numToScroll)
518 {
519   if (winToScroll != cmdWin)
520     {
521       int _numToScroll = numToScroll;
522
523       if (_numToScroll == 0)
524         _numToScroll = 1;
525       /*
526          ** If we are scrolling the source or disassembly window, do a
527          ** "psuedo" scroll since not all of the source is in memory,
528          ** only what is in the viewport. If winToScroll is the
529          ** command window do nothing since the term should handle it.
530        */
531       if (winToScroll == srcWin || winToScroll == disassemWin)
532         tui_horizontal_source_scroll (winToScroll, RIGHT_SCROLL, _numToScroll);
533     }
534 }
535
536
537 /* Scroll a window.  Arguments are passed through a va_list.    */
538 void
539 tui_scroll (enum tui_scroll_direction direction,
540             struct tui_win_info * winToScroll,
541             int numToScroll)
542 {
543   switch (direction)
544     {
545     case FORWARD_SCROLL:
546       tui_scroll_forward (winToScroll, numToScroll);
547       break;
548     case BACKWARD_SCROLL:
549       tui_scroll_backward (winToScroll, numToScroll);
550       break;
551     case LEFT_SCROLL:
552       tui_scroll_left (winToScroll, numToScroll);
553       break;
554     case RIGHT_SCROLL:
555       tui_scroll_right (winToScroll, numToScroll);
556       break;
557     default:
558       break;
559     }
560 }
561
562
563 void
564 tui_refresh_all_win (void)
565 {
566   TuiWinType type;
567
568   clearok (curscr, TRUE);
569   tui_refresh_all (winList);
570   for (type = SRC_WIN; type < MAX_MAJOR_WINDOWS; type++)
571     {
572       if (winList[type] && winList[type]->generic.isVisible)
573         {
574           switch (type)
575             {
576             case SRC_WIN:
577             case DISASSEM_WIN:
578               tui_show_source_content (winList[type]);
579               tui_check_and_display_highlight_if_needed (winList[type]);
580               tui_erase_exec_info_content (winList[type]);
581               tui_update_exec_info (winList[type]);
582               break;
583             case DATA_WIN:
584               tui_refresh_data_win ();
585               break;
586             default:
587               break;
588             }
589         }
590     }
591   tui_show_locator_content ();
592 }
593
594
595 /*
596    ** tuiResizeAll().
597    **      Resize all the windows based on the the terminal size.  This
598    **      function gets called from within the readline sinwinch handler.
599  */
600 void
601 tuiResizeAll (void)
602 {
603   int heightDiff, widthDiff;
604   int screenheight, screenwidth;
605
606   rl_get_screen_size (&screenheight, &screenwidth);
607   widthDiff = screenwidth - tui_term_width ();
608   heightDiff = screenheight - tui_term_height ();
609   if (heightDiff || widthDiff)
610     {
611       enum tui_layout_type curLayout = tui_current_layout ();
612       struct tui_win_info * winWithFocus = tui_win_with_focus ();
613       struct tui_win_info *firstWin;
614       struct tui_win_info *secondWin;
615       struct tui_gen_win_info * locator = tui_locator_win_info_ptr ();
616       TuiWinType winType;
617       int newHeight, splitDiff, cmdSplitDiff, numWinsDisplayed = 2;
618
619       /* turn keypad off while we resize */
620       if (winWithFocus != cmdWin)
621         keypad (cmdWin->generic.handle, FALSE);
622       tui_update_gdb_sizes ();
623       tui_set_term_height_to (screenheight);
624       tui_set_term_width_to (screenwidth);
625       if (curLayout == SRC_DISASSEM_COMMAND ||
626         curLayout == SRC_DATA_COMMAND || curLayout == DISASSEM_DATA_COMMAND)
627         numWinsDisplayed++;
628       splitDiff = heightDiff / numWinsDisplayed;
629       cmdSplitDiff = splitDiff;
630       if (heightDiff % numWinsDisplayed)
631         {
632           if (heightDiff < 0)
633             cmdSplitDiff--;
634           else
635             cmdSplitDiff++;
636         }
637       /* now adjust each window */
638       clear ();
639       refresh ();
640       switch (curLayout)
641         {
642         case SRC_COMMAND:
643         case DISASSEM_COMMAND:
644           firstWin = (struct tui_win_info *) (tui_source_windows ())->list[0];
645           firstWin->generic.width += widthDiff;
646           locator->width += widthDiff;
647           /* check for invalid heights */
648           if (heightDiff == 0)
649             newHeight = firstWin->generic.height;
650           else if ((firstWin->generic.height + splitDiff) >=
651                    (screenheight - MIN_CMD_WIN_HEIGHT - 1))
652             newHeight = screenheight - MIN_CMD_WIN_HEIGHT - 1;
653           else if ((firstWin->generic.height + splitDiff) <= 0)
654             newHeight = MIN_WIN_HEIGHT;
655           else
656             newHeight = firstWin->generic.height + splitDiff;
657
658           _makeInvisibleAndSetNewHeight (firstWin, newHeight);
659           cmdWin->generic.origin.y = locator->origin.y + 1;
660           cmdWin->generic.width += widthDiff;
661           newHeight = screenheight - cmdWin->generic.origin.y;
662           _makeInvisibleAndSetNewHeight (cmdWin, newHeight);
663           _makeVisibleWithNewHeight (firstWin);
664           _makeVisibleWithNewHeight (cmdWin);
665           if (firstWin->generic.contentSize <= 0)
666             tui_erase_source_content (firstWin, EMPTY_SOURCE_PROMPT);
667           break;
668         default:
669           if (curLayout == SRC_DISASSEM_COMMAND)
670             {
671               firstWin = srcWin;
672               firstWin->generic.width += widthDiff;
673               secondWin = disassemWin;
674               secondWin->generic.width += widthDiff;
675             }
676           else
677             {
678               firstWin = dataWin;
679               firstWin->generic.width += widthDiff;
680               secondWin = (struct tui_win_info *) (tui_source_windows ())->list[0];
681               secondWin->generic.width += widthDiff;
682             }
683           /* Change the first window's height/width */
684           /* check for invalid heights */
685           if (heightDiff == 0)
686             newHeight = firstWin->generic.height;
687           else if ((firstWin->generic.height +
688                     secondWin->generic.height + (splitDiff * 2)) >=
689                    (screenheight - MIN_CMD_WIN_HEIGHT - 1))
690             newHeight = (screenheight - MIN_CMD_WIN_HEIGHT - 1) / 2;
691           else if ((firstWin->generic.height + splitDiff) <= 0)
692             newHeight = MIN_WIN_HEIGHT;
693           else
694             newHeight = firstWin->generic.height + splitDiff;
695           _makeInvisibleAndSetNewHeight (firstWin, newHeight);
696
697           if (firstWin == dataWin && widthDiff != 0)
698             firstWin->detail.dataDisplayInfo.regsColumnCount =
699               tui_calculate_regs_column_count (
700                           firstWin->detail.dataDisplayInfo.regsDisplayType);
701           locator->width += widthDiff;
702
703           /* Change the second window's height/width */
704           /* check for invalid heights */
705           if (heightDiff == 0)
706             newHeight = secondWin->generic.height;
707           else if ((firstWin->generic.height +
708                     secondWin->generic.height + (splitDiff * 2)) >=
709                    (screenheight - MIN_CMD_WIN_HEIGHT - 1))
710             {
711               newHeight = screenheight - MIN_CMD_WIN_HEIGHT - 1;
712               if (newHeight % 2)
713                 newHeight = (newHeight / 2) + 1;
714               else
715                 newHeight /= 2;
716             }
717           else if ((secondWin->generic.height + splitDiff) <= 0)
718             newHeight = MIN_WIN_HEIGHT;
719           else
720             newHeight = secondWin->generic.height + splitDiff;
721           secondWin->generic.origin.y = firstWin->generic.height - 1;
722           _makeInvisibleAndSetNewHeight (secondWin, newHeight);
723
724           /* Change the command window's height/width */
725           cmdWin->generic.origin.y = locator->origin.y + 1;
726           _makeInvisibleAndSetNewHeight (
727                              cmdWin, cmdWin->generic.height + cmdSplitDiff);
728           _makeVisibleWithNewHeight (firstWin);
729           _makeVisibleWithNewHeight (secondWin);
730           _makeVisibleWithNewHeight (cmdWin);
731           if (firstWin->generic.contentSize <= 0)
732             tui_erase_source_content (firstWin, EMPTY_SOURCE_PROMPT);
733           if (secondWin->generic.contentSize <= 0)
734             tui_erase_source_content (secondWin, EMPTY_SOURCE_PROMPT);
735           break;
736         }
737       /*
738          ** Now remove all invisible windows, and their content so that they get
739          ** created again when called for with the new size
740        */
741       for (winType = SRC_WIN; (winType < MAX_MAJOR_WINDOWS); winType++)
742         {
743           if (winType != CMD_WIN && m_winPtrNotNull (winList[winType]) &&
744               !winList[winType]->generic.isVisible)
745             {
746               tui_free_window (winList[winType]);
747               winList[winType] = (struct tui_win_info *) NULL;
748             }
749         }
750       tui_set_win_resized_to (TRUE);
751       /* turn keypad back on, unless focus is in the command window */
752       if (winWithFocus != cmdWin)
753         keypad (cmdWin->generic.handle, TRUE);
754     }
755   return;
756 }                               /* tuiResizeAll */
757
758
759 /*
760    ** tuiSigwinchHandler()
761    **    SIGWINCH signal handler for the tui.  This signal handler is
762    **    always called, even when the readline package clears signals
763    **    because it is set as the old_sigwinch() (TUI only)
764  */
765 void
766 tuiSigwinchHandler (int signal)
767 {
768   /*
769      ** Say that a resize was done so that the readline can do it
770      ** later when appropriate.
771    */
772   tui_set_win_resized_to (TRUE);
773
774   return;
775 }                               /* tuiSigwinchHandler */
776
777
778
779 /*************************
780 ** STATIC LOCAL FUNCTIONS
781 **************************/
782
783
784 /*
785    ** _tuiScrollForward_command().
786  */
787 static void
788 _tuiScrollForward_command (char *arg, int fromTTY)
789 {
790   int numToScroll = 1;
791   struct tui_win_info * winToScroll;
792
793   /* Make sure the curses mode is enabled.  */
794   tui_enable ();
795   if (arg == (char *) NULL)
796     _parseScrollingArgs (arg, &winToScroll, (int *) NULL);
797   else
798     _parseScrollingArgs (arg, &winToScroll, &numToScroll);
799   tui_scroll (FORWARD_SCROLL, winToScroll, numToScroll);
800 }
801
802
803 /*
804    ** _tuiScrollBackward_command().
805  */
806 static void
807 _tuiScrollBackward_command (char *arg, int fromTTY)
808 {
809   int numToScroll = 1;
810   struct tui_win_info * winToScroll;
811
812   /* Make sure the curses mode is enabled.  */
813   tui_enable ();
814   if (arg == (char *) NULL)
815     _parseScrollingArgs (arg, &winToScroll, (int *) NULL);
816   else
817     _parseScrollingArgs (arg, &winToScroll, &numToScroll);
818   tui_scroll (BACKWARD_SCROLL, winToScroll, numToScroll);
819 }
820
821
822 /*
823    ** _tuiScrollLeft_command().
824  */
825 static void
826 _tuiScrollLeft_command (char *arg, int fromTTY)
827 {
828   int numToScroll;
829   struct tui_win_info * winToScroll;
830
831   /* Make sure the curses mode is enabled.  */
832   tui_enable ();
833   _parseScrollingArgs (arg, &winToScroll, &numToScroll);
834   tui_scroll (LEFT_SCROLL, winToScroll, numToScroll);
835 }
836
837
838 /*
839    ** _tuiScrollRight_command().
840  */
841 static void
842 _tuiScrollRight_command (char *arg, int fromTTY)
843 {
844   int numToScroll;
845   struct tui_win_info * winToScroll;
846
847   /* Make sure the curses mode is enabled.  */
848   tui_enable ();
849   _parseScrollingArgs (arg, &winToScroll, &numToScroll);
850   tui_scroll (RIGHT_SCROLL, winToScroll, numToScroll);
851 }
852
853
854 /*
855    ** _tuiSetFocus().
856    **     Set focus to the window named by 'arg'
857  */
858 static void
859 _tuiSetFocus (char *arg, int fromTTY)
860 {
861   if (arg != (char *) NULL)
862     {
863       char *bufPtr = (char *) xstrdup (arg);
864       int i;
865       struct tui_win_info * winInfo = (struct tui_win_info *) NULL;
866
867       for (i = 0; (i < strlen (bufPtr)); i++)
868         bufPtr[i] = toupper (arg[i]);
869
870       if (subset_compare (bufPtr, "NEXT"))
871         winInfo = tui_next_win (tui_win_with_focus ());
872       else if (subset_compare (bufPtr, "PREV"))
873         winInfo = tui_prev_win (tui_win_with_focus ());
874       else
875         winInfo = tui_partial_win_by_name (bufPtr);
876
877       if (winInfo == (struct tui_win_info *) NULL || !winInfo->generic.isVisible)
878         warning ("Invalid window specified. \n\
879 The window name specified must be valid and visible.\n");
880       else
881         {
882           tui_set_win_focus_to (winInfo);
883           keypad (cmdWin->generic.handle, (winInfo != cmdWin));
884         }
885
886       if (dataWin && dataWin->generic.isVisible)
887         tui_refresh_data_win ();
888       tuiFree (bufPtr);
889       printf_filtered ("Focus set to %s window.\n",
890                        tui_win_name ((struct tui_gen_win_info *) tui_win_with_focus ()));
891     }
892   else
893     warning ("Incorrect Number of Arguments.\n%s", FOCUS_USAGE);
894
895   return;
896 }                               /* _tuiSetFocus */
897
898 /*
899    ** _tuiSetFocus_command()
900  */
901 static void
902 _tuiSetFocus_command (char *arg, int fromTTY)
903 {
904   /* Make sure the curses mode is enabled.  */
905   tui_enable ();
906   _tuiSetFocus (arg, fromTTY);
907 }
908
909
910 /*
911    ** _tuiAllWindowsInfo().
912  */
913 static void
914 _tuiAllWindowsInfo (char *arg, int fromTTY)
915 {
916   TuiWinType type;
917   struct tui_win_info * winWithFocus = tui_win_with_focus ();
918
919   for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++)
920     if (winList[type] && winList[type]->generic.isVisible)
921       {
922         if (winWithFocus == winList[type])
923           printf_filtered ("        %s\t(%d lines)  <has focus>\n",
924                            tui_win_name (&winList[type]->generic),
925                            winList[type]->generic.height);
926         else
927           printf_filtered ("        %s\t(%d lines)\n",
928                            tui_win_name (&winList[type]->generic),
929                            winList[type]->generic.height);
930       }
931
932   return;
933 }                               /* _tuiAllWindowsInfo */
934
935
936 /*
937    ** _tuiRefreshAll_command().
938  */
939 static void
940 _tuiRefreshAll_command (char *arg, int fromTTY)
941 {
942   /* Make sure the curses mode is enabled.  */
943   tui_enable ();
944
945   tui_refresh_all_win ();
946 }
947
948
949 /*
950    ** _tuiSetWinTabWidth_command().
951    **        Set the height of the specified window.
952  */
953 static void
954 _tuiSetTabWidth_command (char *arg, int fromTTY)
955 {
956   /* Make sure the curses mode is enabled.  */
957   tui_enable ();
958   if (arg != (char *) NULL)
959     {
960       int ts;
961
962       ts = atoi (arg);
963       if (ts > 0)
964         tui_set_default_tab_len (ts);
965       else
966         warning ("Tab widths greater than 0 must be specified.\n");
967     }
968
969   return;
970 }                               /* _tuiSetTabWidth_command */
971
972
973 /*
974    ** _tuiSetWinHeight().
975    **        Set the height of the specified window.
976  */
977 static void
978 _tuiSetWinHeight (char *arg, int fromTTY)
979 {
980   /* Make sure the curses mode is enabled.  */
981   tui_enable ();
982   if (arg != (char *) NULL)
983     {
984       char *buf = xstrdup (arg);
985       char *bufPtr = buf;
986       char *wname = (char *) NULL;
987       int newHeight, i;
988       struct tui_win_info * winInfo;
989
990       wname = bufPtr;
991       bufPtr = strchr (bufPtr, ' ');
992       if (bufPtr != (char *) NULL)
993         {
994           *bufPtr = (char) 0;
995
996           /*
997              ** Validate the window name
998            */
999           for (i = 0; i < strlen (wname); i++)
1000             wname[i] = toupper (wname[i]);
1001           winInfo = tui_partial_win_by_name (wname);
1002
1003           if (winInfo == (struct tui_win_info *) NULL || !winInfo->generic.isVisible)
1004             warning ("Invalid window specified. \n\
1005 The window name specified must be valid and visible.\n");
1006           else
1007             {
1008               /* Process the size */
1009               while (*(++bufPtr) == ' ')
1010                 ;
1011
1012               if (*bufPtr != (char) 0)
1013                 {
1014                   int negate = FALSE;
1015                   int fixedSize = TRUE;
1016                   int inputNo;;
1017
1018                   if (*bufPtr == '+' || *bufPtr == '-')
1019                     {
1020                       if (*bufPtr == '-')
1021                         negate = TRUE;
1022                       fixedSize = FALSE;
1023                       bufPtr++;
1024                     }
1025                   inputNo = atoi (bufPtr);
1026                   if (inputNo > 0)
1027                     {
1028                       if (negate)
1029                         inputNo *= (-1);
1030                       if (fixedSize)
1031                         newHeight = inputNo;
1032                       else
1033                         newHeight = winInfo->generic.height + inputNo;
1034                       /*
1035                          ** Now change the window's height, and adjust all
1036                          ** other windows around it
1037                        */
1038                       if (_tuiAdjustWinHeights (winInfo,
1039                                                 newHeight) == TUI_FAILURE)
1040                         warning ("Invalid window height specified.\n%s",
1041                                  WIN_HEIGHT_USAGE);
1042                       else
1043                         tui_update_gdb_sizes ();
1044                     }
1045                   else
1046                     warning ("Invalid window height specified.\n%s",
1047                              WIN_HEIGHT_USAGE);
1048                 }
1049             }
1050         }
1051       else
1052         printf_filtered (WIN_HEIGHT_USAGE);
1053
1054       if (buf != (char *) NULL)
1055         tuiFree (buf);
1056     }
1057   else
1058     printf_filtered (WIN_HEIGHT_USAGE);
1059
1060   return;
1061 }                               /* _tuiSetWinHeight */
1062
1063 /*
1064    ** _tuiSetWinHeight_command().
1065    **        Set the height of the specified window, with va_list.
1066  */
1067 static void
1068 _tuiSetWinHeight_command (char *arg, int fromTTY)
1069 {
1070   /* Make sure the curses mode is enabled.  */
1071   tui_enable ();
1072   _tuiSetWinHeight (arg, fromTTY);
1073 }
1074
1075
1076 /*
1077    ** _tuiXDBsetWinHeight().
1078    **        XDB Compatibility command for setting the window height.  This will
1079    **        increase or decrease the command window by the specified amount.
1080  */
1081 static void
1082 _tuiXDBsetWinHeight (char *arg, int fromTTY)
1083 {
1084   /* Make sure the curses mode is enabled.  */
1085   tui_enable ();
1086   if (arg != (char *) NULL)
1087     {
1088       int inputNo = atoi (arg);
1089
1090       if (inputNo > 0)
1091         {                       /* Add 1 for the locator */
1092           int newHeight = tui_term_height () - (inputNo + 1);
1093
1094           if (!_newHeightOk (winList[CMD_WIN], newHeight) ||
1095               _tuiAdjustWinHeights (winList[CMD_WIN],
1096                                     newHeight) == TUI_FAILURE)
1097             warning ("Invalid window height specified.\n%s",
1098                      XDBWIN_HEIGHT_USAGE);
1099         }
1100       else
1101         warning ("Invalid window height specified.\n%s",
1102                  XDBWIN_HEIGHT_USAGE);
1103     }
1104   else
1105     warning ("Invalid window height specified.\n%s", XDBWIN_HEIGHT_USAGE);
1106
1107   return;
1108 }                               /* _tuiXDBsetWinHeight */
1109
1110 /*
1111    ** _tuiSetWinHeight_command().
1112    **        Set the height of the specified window, with va_list.
1113  */
1114 static void
1115 _tuiXDBsetWinHeight_command (char *arg, int fromTTY)
1116 {
1117   _tuiXDBsetWinHeight (arg, fromTTY);
1118 }
1119
1120
1121 /*
1122    ** _tuiAdjustWinHeights().
1123    **        Function to adjust all window heights around the primary
1124  */
1125 static TuiStatus
1126 _tuiAdjustWinHeights (struct tui_win_info * primaryWinInfo, int newHeight)
1127 {
1128   TuiStatus status = TUI_FAILURE;
1129
1130   if (_newHeightOk (primaryWinInfo, newHeight))
1131     {
1132       status = TUI_SUCCESS;
1133       if (newHeight != primaryWinInfo->generic.height)
1134         {
1135           int diff;
1136           struct tui_win_info * winInfo;
1137           struct tui_gen_win_info * locator = tui_locator_win_info_ptr ();
1138           enum tui_layout_type curLayout = tui_current_layout ();
1139
1140           diff = (newHeight - primaryWinInfo->generic.height) * (-1);
1141           if (curLayout == SRC_COMMAND || curLayout == DISASSEM_COMMAND)
1142             {
1143               struct tui_win_info * srcWinInfo;
1144
1145               _makeInvisibleAndSetNewHeight (primaryWinInfo, newHeight);
1146               if (primaryWinInfo->generic.type == CMD_WIN)
1147                 {
1148                   winInfo = (struct tui_win_info *) (tui_source_windows ())->list[0];
1149                   srcWinInfo = winInfo;
1150                 }
1151               else
1152                 {
1153                   winInfo = winList[CMD_WIN];
1154                   srcWinInfo = primaryWinInfo;
1155                 }
1156               _makeInvisibleAndSetNewHeight (winInfo,
1157                                              winInfo->generic.height + diff);
1158               cmdWin->generic.origin.y = locator->origin.y + 1;
1159               _makeVisibleWithNewHeight (winInfo);
1160               _makeVisibleWithNewHeight (primaryWinInfo);
1161               if (srcWinInfo->generic.contentSize <= 0)
1162                 tui_erase_source_content (srcWinInfo, EMPTY_SOURCE_PROMPT);
1163             }
1164           else
1165             {
1166               struct tui_win_info *firstWin;
1167               struct tui_win_info *secondWin;
1168
1169               if (curLayout == SRC_DISASSEM_COMMAND)
1170                 {
1171                   firstWin = srcWin;
1172                   secondWin = disassemWin;
1173                 }
1174               else
1175                 {
1176                   firstWin = dataWin;
1177                   secondWin = (struct tui_win_info *) (tui_source_windows ())->list[0];
1178                 }
1179               if (primaryWinInfo == cmdWin)
1180                 {               /*
1181                                    ** Split the change in height accross the 1st & 2nd windows
1182                                    ** adjusting them as well.
1183                                  */
1184                   int firstSplitDiff = diff / 2;        /* subtract the locator */
1185                   int secondSplitDiff = firstSplitDiff;
1186
1187                   if (diff % 2)
1188                     {
1189                       if (firstWin->generic.height >
1190                           secondWin->generic.height)
1191                         if (diff < 0)
1192                           firstSplitDiff--;
1193                         else
1194                           firstSplitDiff++;
1195                       else
1196                         {
1197                           if (diff < 0)
1198                             secondSplitDiff--;
1199                           else
1200                             secondSplitDiff++;
1201                         }
1202                     }
1203                   /* make sure that the minimum hieghts are honored */
1204                   while ((firstWin->generic.height + firstSplitDiff) < 3)
1205                     {
1206                       firstSplitDiff++;
1207                       secondSplitDiff--;
1208                     }
1209                   while ((secondWin->generic.height + secondSplitDiff) < 3)
1210                     {
1211                       secondSplitDiff++;
1212                       firstSplitDiff--;
1213                     }
1214                   _makeInvisibleAndSetNewHeight (
1215                                                   firstWin,
1216                                  firstWin->generic.height + firstSplitDiff);
1217                   secondWin->generic.origin.y = firstWin->generic.height - 1;
1218                   _makeInvisibleAndSetNewHeight (
1219                     secondWin, secondWin->generic.height + secondSplitDiff);
1220                   cmdWin->generic.origin.y = locator->origin.y + 1;
1221                   _makeInvisibleAndSetNewHeight (cmdWin, newHeight);
1222                 }
1223               else
1224                 {
1225                   if ((cmdWin->generic.height + diff) < 1)
1226                     {           /*
1227                                    ** If there is no way to increase the command window
1228                                    ** take real estate from the 1st or 2nd window.
1229                                  */
1230                       if ((cmdWin->generic.height + diff) < 1)
1231                         {
1232                           int i;
1233                           for (i = cmdWin->generic.height + diff;
1234                                (i < 1); i++)
1235                             if (primaryWinInfo == firstWin)
1236                               secondWin->generic.height--;
1237                             else
1238                               firstWin->generic.height--;
1239                         }
1240                     }
1241                   if (primaryWinInfo == firstWin)
1242                     _makeInvisibleAndSetNewHeight (firstWin, newHeight);
1243                   else
1244                     _makeInvisibleAndSetNewHeight (
1245                                                     firstWin,
1246                                                   firstWin->generic.height);
1247                   secondWin->generic.origin.y = firstWin->generic.height - 1;
1248                   if (primaryWinInfo == secondWin)
1249                     _makeInvisibleAndSetNewHeight (secondWin, newHeight);
1250                   else
1251                     _makeInvisibleAndSetNewHeight (
1252                                       secondWin, secondWin->generic.height);
1253                   cmdWin->generic.origin.y = locator->origin.y + 1;
1254                   if ((cmdWin->generic.height + diff) < 1)
1255                     _makeInvisibleAndSetNewHeight (cmdWin, 1);
1256                   else
1257                     _makeInvisibleAndSetNewHeight (
1258                                      cmdWin, cmdWin->generic.height + diff);
1259                 }
1260               _makeVisibleWithNewHeight (cmdWin);
1261               _makeVisibleWithNewHeight (secondWin);
1262               _makeVisibleWithNewHeight (firstWin);
1263               if (firstWin->generic.contentSize <= 0)
1264                 tui_erase_source_content (firstWin, EMPTY_SOURCE_PROMPT);
1265               if (secondWin->generic.contentSize <= 0)
1266                 tui_erase_source_content (secondWin, EMPTY_SOURCE_PROMPT);
1267             }
1268         }
1269     }
1270
1271   return status;
1272 }                               /* _tuiAdjustWinHeights */
1273
1274
1275 /*
1276    ** _makeInvisibleAndSetNewHeight().
1277    **        Function make the target window (and auxillary windows associated
1278    **        with the targer) invisible, and set the new height and location.
1279  */
1280 static void
1281 _makeInvisibleAndSetNewHeight (struct tui_win_info * winInfo, int height)
1282 {
1283   int i;
1284   struct tui_gen_win_info * genWinInfo;
1285
1286   tui_make_invisible (&winInfo->generic);
1287   winInfo->generic.height = height;
1288   if (height > 1)
1289     winInfo->generic.viewportHeight = height - 1;
1290   else
1291     winInfo->generic.viewportHeight = height;
1292   if (winInfo != cmdWin)
1293     winInfo->generic.viewportHeight--;
1294
1295   /* Now deal with the auxillary windows associated with winInfo */
1296   switch (winInfo->generic.type)
1297     {
1298     case SRC_WIN:
1299     case DISASSEM_WIN:
1300       genWinInfo = winInfo->detail.sourceInfo.executionInfo;
1301       tui_make_invisible (genWinInfo);
1302       genWinInfo->height = height;
1303       genWinInfo->origin.y = winInfo->generic.origin.y;
1304       if (height > 1)
1305         genWinInfo->viewportHeight = height - 1;
1306       else
1307         genWinInfo->viewportHeight = height;
1308       if (winInfo != cmdWin)
1309         genWinInfo->viewportHeight--;
1310
1311       if (m_hasLocator (winInfo))
1312         {
1313           genWinInfo = tui_locator_win_info_ptr ();
1314           tui_make_invisible (genWinInfo);
1315           genWinInfo->origin.y = winInfo->generic.origin.y + height;
1316         }
1317       break;
1318     case DATA_WIN:
1319       /* delete all data item windows */
1320       for (i = 0; i < winInfo->generic.contentSize; i++)
1321         {
1322           genWinInfo = (struct tui_gen_win_info *) & ((struct tui_win_element *)
1323                       winInfo->generic.content[i])->whichElement.dataWindow;
1324           tui_delete_win (genWinInfo->handle);
1325           genWinInfo->handle = (WINDOW *) NULL;
1326         }
1327       break;
1328     default:
1329       break;
1330     }
1331 }
1332
1333
1334 /*
1335    ** _makeVisibleWithNewHeight().
1336    **        Function to make the windows with new heights visible.
1337    **        This means re-creating the windows' content since the window
1338    **        had to be destroyed to be made invisible.
1339  */
1340 static void
1341 _makeVisibleWithNewHeight (struct tui_win_info * winInfo)
1342 {
1343   struct symtab *s;
1344
1345   tui_make_visible (&winInfo->generic);
1346   tui_check_and_display_highlight_if_needed (winInfo);
1347   switch (winInfo->generic.type)
1348     {
1349     case SRC_WIN:
1350     case DISASSEM_WIN:
1351       tui_free_win_content (winInfo->detail.sourceInfo.executionInfo);
1352       tui_make_visible (winInfo->detail.sourceInfo.executionInfo);
1353       if (winInfo->generic.content != (OpaquePtr) NULL)
1354         {
1355           union tui_line_or_address lineOrAddr;
1356           struct symtab_and_line cursal
1357             = get_current_source_symtab_and_line ();
1358
1359           if (winInfo->generic.type == SRC_WIN)
1360             lineOrAddr.lineNo =
1361               winInfo->detail.sourceInfo.startLineOrAddr.lineNo;
1362           else
1363             lineOrAddr.addr =
1364               winInfo->detail.sourceInfo.startLineOrAddr.addr;
1365           tui_free_win_content (&winInfo->generic);
1366           tui_update_source_window (winInfo, cursal.symtab, lineOrAddr, TRUE);
1367         }
1368       else if (deprecated_selected_frame != (struct frame_info *) NULL)
1369         {
1370           union tui_line_or_address line;
1371           struct symtab_and_line cursal = get_current_source_symtab_and_line ();
1372
1373
1374           s = find_pc_symtab (get_frame_pc (deprecated_selected_frame));
1375           if (winInfo->generic.type == SRC_WIN)
1376             line.lineNo = cursal.line;
1377           else
1378             {
1379               find_line_pc (s, cursal.line, &line.addr);
1380             }
1381           tui_update_source_window (winInfo, s, line, TRUE);
1382         }
1383       if (m_hasLocator (winInfo))
1384         {
1385           tui_make_visible (tui_locator_win_info_ptr ());
1386           tui_show_locator_content ();
1387         }
1388       break;
1389     case DATA_WIN:
1390       tui_display_all_data ();
1391       break;
1392     case CMD_WIN:
1393       winInfo->detail.commandInfo.curLine = 0;
1394       winInfo->detail.commandInfo.curch = 0;
1395       wmove (winInfo->generic.handle,
1396              winInfo->detail.commandInfo.curLine,
1397              winInfo->detail.commandInfo.curch);
1398       break;
1399     default:
1400       break;
1401     }
1402
1403   return;
1404 }                               /* _makeVisibleWithNewHeight */
1405
1406
1407 static int
1408 _newHeightOk (struct tui_win_info * primaryWinInfo, int newHeight)
1409 {
1410   int ok = (newHeight < tui_term_height ());
1411
1412   if (ok)
1413     {
1414       int diff;
1415       enum tui_layout_type curLayout = tui_current_layout ();
1416
1417       diff = (newHeight - primaryWinInfo->generic.height) * (-1);
1418       if (curLayout == SRC_COMMAND || curLayout == DISASSEM_COMMAND)
1419         {
1420           ok = ((primaryWinInfo->generic.type == CMD_WIN &&
1421                  newHeight <= (tui_term_height () - 4) &&
1422                  newHeight >= MIN_CMD_WIN_HEIGHT) ||
1423                 (primaryWinInfo->generic.type != CMD_WIN &&
1424                  newHeight <= (tui_term_height () - 2) &&
1425                  newHeight >= MIN_WIN_HEIGHT));
1426           if (ok)
1427             {                   /* check the total height */
1428               struct tui_win_info * winInfo;
1429
1430               if (primaryWinInfo == cmdWin)
1431                 winInfo = (struct tui_win_info *) (tui_source_windows ())->list[0];
1432               else
1433                 winInfo = cmdWin;
1434               ok = ((newHeight +
1435                      (winInfo->generic.height + diff)) <= tui_term_height ());
1436             }
1437         }
1438       else
1439         {
1440           int curTotalHeight, totalHeight, minHeight = 0;
1441           struct tui_win_info *firstWin;
1442           struct tui_win_info *secondWin;
1443
1444           if (curLayout == SRC_DISASSEM_COMMAND)
1445             {
1446               firstWin = srcWin;
1447               secondWin = disassemWin;
1448             }
1449           else
1450             {
1451               firstWin = dataWin;
1452               secondWin = (struct tui_win_info *) (tui_source_windows ())->list[0];
1453             }
1454           /*
1455              ** We could simply add all the heights to obtain the same result
1456              ** but below is more explicit since we subtract 1 for the
1457              ** line that the first and second windows share, and add one
1458              ** for the locator.
1459            */
1460           totalHeight = curTotalHeight =
1461             (firstWin->generic.height + secondWin->generic.height - 1)
1462             + cmdWin->generic.height + 1 /*locator */ ;
1463           if (primaryWinInfo == cmdWin)
1464             {
1465               /* locator included since first & second win share a line */
1466               ok = ((firstWin->generic.height +
1467                      secondWin->generic.height + diff) >=
1468                     (MIN_WIN_HEIGHT * 2) &&
1469                     newHeight >= MIN_CMD_WIN_HEIGHT);
1470               if (ok)
1471                 {
1472                   totalHeight = newHeight + (firstWin->generic.height +
1473                                           secondWin->generic.height + diff);
1474                   minHeight = MIN_CMD_WIN_HEIGHT;
1475                 }
1476             }
1477           else
1478             {
1479               minHeight = MIN_WIN_HEIGHT;
1480               /*
1481                  ** First see if we can increase/decrease the command
1482                  ** window.  And make sure that the command window is
1483                  ** at least 1 line
1484                */
1485               ok = ((cmdWin->generic.height + diff) > 0);
1486               if (!ok)
1487                 {               /*
1488                                    ** Looks like we have to increase/decrease one of
1489                                    ** the other windows
1490                                  */
1491                   if (primaryWinInfo == firstWin)
1492                     ok = (secondWin->generic.height + diff) >= minHeight;
1493                   else
1494                     ok = (firstWin->generic.height + diff) >= minHeight;
1495                 }
1496               if (ok)
1497                 {
1498                   if (primaryWinInfo == firstWin)
1499                     totalHeight = newHeight +
1500                       secondWin->generic.height +
1501                       cmdWin->generic.height + diff;
1502                   else
1503                     totalHeight = newHeight +
1504                       firstWin->generic.height +
1505                       cmdWin->generic.height + diff;
1506                 }
1507             }
1508           /*
1509              ** Now make sure that the proposed total height doesn't exceed
1510              ** the old total height.
1511            */
1512           if (ok)
1513             ok = (newHeight >= minHeight && totalHeight <= curTotalHeight);
1514         }
1515     }
1516
1517   return ok;
1518 }                               /* _newHeightOk */
1519
1520
1521 /*
1522    ** _parseScrollingArgs().
1523  */
1524 static void
1525 _parseScrollingArgs (char *arg, struct tui_win_info * * winToScroll, int *numToScroll)
1526 {
1527   if (numToScroll)
1528     *numToScroll = 0;
1529   *winToScroll = tui_win_with_focus ();
1530
1531   /*
1532      ** First set up the default window to scroll, in case there is no
1533      ** window name arg
1534    */
1535   if (arg != (char *) NULL)
1536     {
1537       char *buf, *bufPtr;
1538
1539       /* process the number of lines to scroll */
1540       buf = bufPtr = xstrdup (arg);
1541       if (isdigit (*bufPtr))
1542         {
1543           char *numStr;
1544
1545           numStr = bufPtr;
1546           bufPtr = strchr (bufPtr, ' ');
1547           if (bufPtr != (char *) NULL)
1548             {
1549               *bufPtr = (char) 0;
1550               if (numToScroll)
1551                 *numToScroll = atoi (numStr);
1552               bufPtr++;
1553             }
1554           else if (numToScroll)
1555             *numToScroll = atoi (numStr);
1556         }
1557
1558       /* process the window name if one is specified */
1559       if (bufPtr != (char *) NULL)
1560         {
1561           char *wname;
1562           int i;
1563
1564           if (*bufPtr == ' ')
1565             while (*(++bufPtr) == ' ')
1566               ;
1567
1568           if (*bufPtr != (char) 0)
1569             wname = bufPtr;
1570           else
1571             wname = "?";
1572           
1573           /* Validate the window name */
1574           for (i = 0; i < strlen (wname); i++)
1575             wname[i] = toupper (wname[i]);
1576           *winToScroll = tui_partial_win_by_name (wname);
1577
1578           if (*winToScroll == (struct tui_win_info *) NULL ||
1579               !(*winToScroll)->generic.isVisible)
1580             warning ("Invalid window specified. \n\
1581 The window name specified must be valid and visible.\n");
1582           else if (*winToScroll == cmdWin)
1583             *winToScroll = (struct tui_win_info *) (tui_source_windows ())->list[0];
1584         }
1585       tuiFree (buf);
1586     }
1587
1588   return;
1589 }                               /* _parseScrollingArgs */