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