1 /* TUI window generic functions.
3 Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
6 Contributed by Hewlett-Packard Company.
8 This file is part of GDB.
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.
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.
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. */
25 /* This module contains procedures for handling tui window functions
26 like resize, scrolling, scrolling, changing focus, etc.
28 Author: Susan B. Macchia */
30 /* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
31 "defs.h" should be included first. Unfortunatly some systems
32 (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
33 and they clash with "bfd.h"'s definiton of true/false. The correct
34 fix is to remove true/false from "bfd.h", however, until that
35 happens, hack around it by including "config.h" and <curses.h>
52 #include "breakpoint.h"
54 #include "cli/cli-cmds.h"
60 #include "tuiGeneralWin.h"
63 #include "tuiDisassem.h"
64 #include "tuiSource.h"
65 #include "tuiSourceWin.h"
66 #include "tuiDataWin.h"
68 /*******************************
70 ********************************/
71 static void _makeVisibleWithNewHeight (TuiWinInfoPtr
);
72 static void _makeInvisibleAndSetNewHeight (TuiWinInfoPtr
, int);
73 static TuiStatus
_tuiAdjustWinHeights (TuiWinInfoPtr
, int);
74 static int _newHeightOk (TuiWinInfoPtr
, int);
75 static void _tuiSetTabWidth_command (char *, int);
76 static void _tuiRefreshAll_command (char *, int);
77 static void _tuiSetWinHeight_command (char *, int);
78 static void _tuiXDBsetWinHeight_command (char *, int);
79 static void _tuiAllWindowsInfo (char *, int);
80 static void _tuiSetFocus_command (char *, int);
81 static void _tuiScrollForward_command (char *, int);
82 static void _tuiScrollBackward_command (char *, int);
83 static void _tuiScrollLeft_command (char *, int);
84 static void _tuiScrollRight_command (char *, int);
85 static void _parseScrollingArgs (char *, TuiWinInfoPtr
*, int *);
88 /***************************************
90 ***************************************/
91 #define WIN_HEIGHT_USAGE "Usage: winheight <win_name> [+ | -] <#lines>\n"
92 #define XDBWIN_HEIGHT_USAGE "Usage: w <#lines>\n"
93 #define FOCUS_USAGE "Usage: focus {<win> | next | prev}\n"
95 /***************************************
97 ***************************************/
99 /* Possible values for tui-border-kind variable. */
100 static const char *tui_border_kind_enums
[] = {
107 /* Possible values for tui-border-mode and tui-active-border-mode. */
108 static const char *tui_border_mode_enums
[] = {
125 /* Translation table for border-mode variables.
126 The list of values must be terminated by a NULL.
127 After the NULL value, an entry defines the default. */
128 struct tui_translate tui_border_mode_translate
[] = {
129 { "normal", A_NORMAL
},
130 { "standout", A_STANDOUT
},
131 { "reverse", A_REVERSE
},
133 { "half-standout", A_DIM
| A_STANDOUT
},
135 { "bold-standout", A_BOLD
| A_STANDOUT
},
137 { "normal", A_NORMAL
}
140 /* Translation tables for border-kind, one for each border
141 character (see wborder, border curses operations).
142 -1 is used to indicate the ACS because ACS characters
143 are determined at run time by curses (depends on terminal). */
144 struct tui_translate tui_border_kind_translate_vline
[] = {
152 struct tui_translate tui_border_kind_translate_hline
[] = {
160 struct tui_translate tui_border_kind_translate_ulcorner
[] = {
168 struct tui_translate tui_border_kind_translate_urcorner
[] = {
176 struct tui_translate tui_border_kind_translate_llcorner
[] = {
184 struct tui_translate tui_border_kind_translate_lrcorner
[] = {
193 /* Tui configuration variables controlled with set/show command. */
194 const char *tui_active_border_mode
= "bold-standout";
195 const char *tui_border_mode
= "normal";
196 const char *tui_border_kind
= "acs";
198 /* Tui internal configuration variables. These variables are
199 updated by tui_update_variables to reflect the tui configuration
201 chtype tui_border_vline
;
202 chtype tui_border_hline
;
203 chtype tui_border_ulcorner
;
204 chtype tui_border_urcorner
;
205 chtype tui_border_llcorner
;
206 chtype tui_border_lrcorner
;
208 int tui_border_attrs
;
209 int tui_active_border_attrs
;
211 /* Identify the item in the translation table.
212 When the item is not recognized, use the default entry. */
213 static struct tui_translate
*
214 translate (const char *name
, struct tui_translate
*table
)
218 if (name
&& strcmp (table
->name
, name
) == 0)
223 /* Not found, return default entry. */
228 /* Update the tui internal configuration according to gdb settings.
229 Returns 1 if the configuration has changed and the screen should
232 tui_update_variables ()
235 struct tui_translate
*entry
;
237 entry
= translate (tui_border_mode
, tui_border_mode_translate
);
238 if (tui_border_attrs
!= entry
->value
)
240 tui_border_attrs
= entry
->value
;
243 entry
= translate (tui_active_border_mode
, tui_border_mode_translate
);
244 if (tui_active_border_attrs
!= entry
->value
)
246 tui_active_border_attrs
= entry
->value
;
250 /* If one corner changes, all characters are changed.
251 Only check the first one. The ACS characters are determined at
252 run time by curses terminal management. */
253 entry
= translate (tui_border_kind
, tui_border_kind_translate_lrcorner
);
254 if (tui_border_lrcorner
!= (chtype
) entry
->value
)
256 tui_border_lrcorner
= (entry
->value
< 0) ? ACS_LRCORNER
: entry
->value
;
259 entry
= translate (tui_border_kind
, tui_border_kind_translate_llcorner
);
260 tui_border_llcorner
= (entry
->value
< 0) ? ACS_LLCORNER
: entry
->value
;
262 entry
= translate (tui_border_kind
, tui_border_kind_translate_ulcorner
);
263 tui_border_ulcorner
= (entry
->value
< 0) ? ACS_ULCORNER
: entry
->value
;
265 entry
= translate (tui_border_kind
, tui_border_kind_translate_urcorner
);
266 tui_border_urcorner
= (entry
->value
< 0) ? ACS_URCORNER
: entry
->value
;
268 entry
= translate (tui_border_kind
, tui_border_kind_translate_hline
);
269 tui_border_hline
= (entry
->value
< 0) ? ACS_HLINE
: entry
->value
;
271 entry
= translate (tui_border_kind
, tui_border_kind_translate_vline
);
272 tui_border_vline
= (entry
->value
< 0) ? ACS_VLINE
: entry
->value
;
278 set_tui_cmd (char *args
, int from_tty
)
283 show_tui_cmd (char *args
, int from_tty
)
288 ** _initialize_tuiWin().
289 ** Function to initialize gdb commands, for tui window manipulation.
292 _initialize_tuiWin (void)
294 struct cmd_list_element
*c
;
295 static struct cmd_list_element
*tui_setlist
;
296 static struct cmd_list_element
*tui_showlist
;
298 /* Define the classes of commands.
299 They will appear in the help list in the reverse of this order. */
300 add_cmd ("tui", class_tui
, NULL
,
301 "Text User Interface commands.",
304 add_prefix_cmd ("tui", class_tui
, set_tui_cmd
,
305 "TUI configuration variables",
306 &tui_setlist
, "set tui ",
307 0/*allow-unknown*/, &setlist
);
308 add_prefix_cmd ("tui", class_tui
, show_tui_cmd
,
309 "TUI configuration variables",
310 &tui_showlist
, "show tui ",
311 0/*allow-unknown*/, &showlist
);
313 add_com ("refresh", class_tui
, _tuiRefreshAll_command
,
314 "Refresh the terminal display.\n");
316 add_com_alias ("U", "refresh", class_tui
, 0);
317 add_com ("tabset", class_tui
, _tuiSetTabWidth_command
,
318 "Set the width (in characters) of tab stops.\n\
319 Usage: tabset <n>\n");
320 add_com ("winheight", class_tui
, _tuiSetWinHeight_command
,
321 "Set the height of a specified window.\n\
322 Usage: winheight <win_name> [+ | -] <#lines>\n\
324 src : the source window\n\
325 cmd : the command window\n\
326 asm : the disassembly window\n\
327 regs : the register display\n");
328 add_com_alias ("wh", "winheight", class_tui
, 0);
329 add_info ("win", _tuiAllWindowsInfo
,
330 "List of all displayed windows.\n");
331 add_com ("focus", class_tui
, _tuiSetFocus_command
,
332 "Set focus to named window or next/prev window.\n\
333 Usage: focus {<win> | next | prev}\n\
334 Valid Window names are:\n\
335 src : the source window\n\
336 asm : the disassembly window\n\
337 regs : the register display\n\
338 cmd : the command window\n");
339 add_com_alias ("fs", "focus", class_tui
, 0);
340 add_com ("+", class_tui
, _tuiScrollForward_command
,
341 "Scroll window forward.\nUsage: + [win] [n]\n");
342 add_com ("-", class_tui
, _tuiScrollBackward_command
,
343 "Scroll window backward.\nUsage: - [win] [n]\n");
344 add_com ("<", class_tui
, _tuiScrollLeft_command
,
345 "Scroll window forward.\nUsage: < [win] [n]\n");
346 add_com (">", class_tui
, _tuiScrollRight_command
,
347 "Scroll window backward.\nUsage: > [win] [n]\n");
349 add_com ("w", class_xdb
, _tuiXDBsetWinHeight_command
,
350 "XDB compatibility command for setting the height of a command window.\n\
351 Usage: w <#lines>\n");
353 /* Define the tui control variables. */
355 ("border-kind", no_class
,
356 tui_border_kind_enums
, &tui_border_kind
,
357 "Set the kind of border for TUI windows.\n"
358 "This variable controls the border of TUI windows:\n"
359 "space use a white space\n"
360 "ascii use ascii characters + - | for the border\n"
361 "acs use the Alternate Character Set\n",
363 add_show_from_set (c
, &tui_showlist
);
366 ("border-mode", no_class
,
367 tui_border_mode_enums
, &tui_border_mode
,
368 "Set the attribute mode to use for the TUI window borders.\n"
369 "This variable controls the attributes to use for the window borders:\n"
370 "normal normal display\n"
371 "standout use highlight mode of terminal\n"
372 "reverse use reverse video mode\n"
373 "half use half bright\n"
374 "half-standout use half bright and standout mode\n"
375 "bold use extra bright or bold\n"
376 "bold-standout use extra bright or bold with standout mode\n",
378 add_show_from_set (c
, &tui_showlist
);
381 ("active-border-mode", no_class
,
382 tui_border_mode_enums
, &tui_active_border_mode
,
383 "Set the attribute mode to use for the active TUI window border.\n"
384 "This variable controls the attributes to use for the active window border:\n"
385 "normal normal display\n"
386 "standout use highlight mode of terminal\n"
387 "reverse use reverse video mode\n"
388 "half use half bright\n"
389 "half-standout use half bright and standout mode\n"
390 "bold use extra bright or bold\n"
391 "bold-standout use extra bright or bold with standout mode\n",
393 add_show_from_set (c
, &tui_showlist
);
396 /* Update gdb's knowledge of the terminal size. */
398 tui_update_gdb_sizes ()
401 extern int screenheight
, screenwidth
; /* in readline */
403 /* Set to TUI command window dimension or use readline values. */
404 sprintf (cmd
, "set width %d",
405 tui_active
? cmdWin
->generic
.width
: screenwidth
);
406 execute_command (cmd
, 0);
407 sprintf (cmd
, "set height %d",
408 tui_active
? cmdWin
->generic
.height
: screenheight
);
409 execute_command (cmd
, 0);
415 ** Set the logical focus to winInfo
418 tuiSetWinFocusTo (TuiWinInfoPtr winInfo
)
420 if (m_winPtrNotNull (winInfo
))
422 TuiWinInfoPtr winWithFocus
= tuiWinWithFocus ();
424 if (m_winPtrNotNull (winWithFocus
) &&
425 winWithFocus
->generic
.type
!= CMD_WIN
)
426 unhighlightWin (winWithFocus
);
427 tuiSetWinWithFocus (winInfo
);
428 if (winInfo
->generic
.type
!= CMD_WIN
)
429 highlightWin (winInfo
);
433 } /* tuiSetWinFocusTo */
437 ** tuiScrollForward().
440 tuiScrollForward (TuiWinInfoPtr winToScroll
, int numToScroll
)
442 if (winToScroll
!= cmdWin
)
444 int _numToScroll
= numToScroll
;
446 if (numToScroll
== 0)
447 _numToScroll
= winToScroll
->generic
.height
- 3;
449 ** If we are scrolling the source or disassembly window, do a
450 ** "psuedo" scroll since not all of the source is in memory,
451 ** only what is in the viewport. If winToScroll is the
452 ** command window do nothing since the term should handle it.
454 if (winToScroll
== srcWin
)
455 tuiVerticalSourceScroll (FORWARD_SCROLL
, _numToScroll
);
456 else if (winToScroll
== disassemWin
)
457 tuiVerticalDisassemScroll (FORWARD_SCROLL
, _numToScroll
);
458 else if (winToScroll
== dataWin
)
459 tuiVerticalDataScroll (FORWARD_SCROLL
, _numToScroll
);
463 } /* tuiScrollForward */
467 ** tuiScrollBackward().
470 tuiScrollBackward (TuiWinInfoPtr winToScroll
, int numToScroll
)
472 if (winToScroll
!= cmdWin
)
474 int _numToScroll
= numToScroll
;
476 if (numToScroll
== 0)
477 _numToScroll
= winToScroll
->generic
.height
- 3;
479 ** If we are scrolling the source or disassembly window, do a
480 ** "psuedo" scroll since not all of the source is in memory,
481 ** only what is in the viewport. If winToScroll is the
482 ** command window do nothing since the term should handle it.
484 if (winToScroll
== srcWin
)
485 tuiVerticalSourceScroll (BACKWARD_SCROLL
, _numToScroll
);
486 else if (winToScroll
== disassemWin
)
487 tuiVerticalDisassemScroll (BACKWARD_SCROLL
, _numToScroll
);
488 else if (winToScroll
== dataWin
)
489 tuiVerticalDataScroll (BACKWARD_SCROLL
, _numToScroll
);
492 } /* tuiScrollBackward */
499 tuiScrollLeft (TuiWinInfoPtr winToScroll
, int numToScroll
)
501 if (winToScroll
!= cmdWin
)
503 int _numToScroll
= numToScroll
;
505 if (_numToScroll
== 0)
508 ** If we are scrolling the source or disassembly window, do a
509 ** "psuedo" scroll since not all of the source is in memory,
510 ** only what is in the viewport. If winToScroll is the
511 ** command window do nothing since the term should handle it.
513 if (winToScroll
== srcWin
|| winToScroll
== disassemWin
)
514 tuiHorizontalSourceScroll (winToScroll
, LEFT_SCROLL
, _numToScroll
);
517 } /* tuiScrollLeft */
524 tuiScrollRight (TuiWinInfoPtr winToScroll
, int numToScroll
)
526 if (winToScroll
!= cmdWin
)
528 int _numToScroll
= numToScroll
;
530 if (_numToScroll
== 0)
533 ** If we are scrolling the source or disassembly window, do a
534 ** "psuedo" scroll since not all of the source is in memory,
535 ** only what is in the viewport. If winToScroll is the
536 ** command window do nothing since the term should handle it.
538 if (winToScroll
== srcWin
|| winToScroll
== disassemWin
)
539 tuiHorizontalSourceScroll (winToScroll
, RIGHT_SCROLL
, _numToScroll
);
542 } /* tuiScrollRight */
547 ** Scroll a window. Arguments are passed through a va_list.
550 tui_scroll (TuiScrollDirection direction
,
551 TuiWinInfoPtr winToScroll
,
557 tuiScrollForward (winToScroll
, numToScroll
);
559 case BACKWARD_SCROLL
:
560 tuiScrollBackward (winToScroll
, numToScroll
);
563 tuiScrollLeft (winToScroll
, numToScroll
);
566 tuiScrollRight (winToScroll
, numToScroll
);
582 clearok (curscr
, TRUE
);
583 refreshAll (winList
);
584 for (type
= SRC_WIN
; type
< MAX_MAJOR_WINDOWS
; type
++)
586 if (winList
[type
] && winList
[type
]->generic
.isVisible
)
592 tuiShowSourceContent (winList
[type
]);
593 checkAndDisplayHighlightIfNeeded (winList
[type
]);
594 tuiEraseExecInfoContent (winList
[type
]);
595 tuiUpdateExecInfo (winList
[type
]);
598 tuiRefreshDataWin ();
605 tuiShowLocatorContent ();
611 ** Resize all the windows based on the the terminal size. This
612 ** function gets called from within the readline sinwinch handler.
617 int heightDiff
, widthDiff
;
618 extern int screenheight
, screenwidth
; /* in readline */
620 widthDiff
= screenwidth
- termWidth ();
621 heightDiff
= screenheight
- termHeight ();
622 if (heightDiff
|| widthDiff
)
624 TuiLayoutType curLayout
= currentLayout ();
625 TuiWinInfoPtr winWithFocus
= tuiWinWithFocus ();
626 TuiWinInfoPtr firstWin
, secondWin
;
627 TuiGenWinInfoPtr locator
= locatorWinInfoPtr ();
629 int newHeight
, splitDiff
, cmdSplitDiff
, numWinsDisplayed
= 2;
631 /* turn keypad off while we resize */
632 if (winWithFocus
!= cmdWin
)
633 keypad (cmdWin
->generic
.handle
, FALSE
);
634 tui_update_gdb_sizes ();
635 setTermHeightTo (screenheight
);
636 setTermWidthTo (screenwidth
);
637 if (curLayout
== SRC_DISASSEM_COMMAND
||
638 curLayout
== SRC_DATA_COMMAND
|| curLayout
== DISASSEM_DATA_COMMAND
)
640 splitDiff
= heightDiff
/ numWinsDisplayed
;
641 cmdSplitDiff
= splitDiff
;
642 if (heightDiff
% numWinsDisplayed
)
649 /* now adjust each window */
655 case DISASSEM_COMMAND
:
656 firstWin
= (TuiWinInfoPtr
) (sourceWindows ())->list
[0];
657 firstWin
->generic
.width
+= widthDiff
;
658 locator
->width
+= widthDiff
;
659 /* check for invalid heights */
661 newHeight
= firstWin
->generic
.height
;
662 else if ((firstWin
->generic
.height
+ splitDiff
) >=
663 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
664 newHeight
= screenheight
- MIN_CMD_WIN_HEIGHT
- 1;
665 else if ((firstWin
->generic
.height
+ splitDiff
) <= 0)
666 newHeight
= MIN_WIN_HEIGHT
;
668 newHeight
= firstWin
->generic
.height
+ splitDiff
;
670 _makeInvisibleAndSetNewHeight (firstWin
, newHeight
);
671 cmdWin
->generic
.origin
.y
= locator
->origin
.y
+ 1;
672 cmdWin
->generic
.width
+= widthDiff
;
673 newHeight
= screenheight
- cmdWin
->generic
.origin
.y
;
674 _makeInvisibleAndSetNewHeight (cmdWin
, newHeight
);
675 _makeVisibleWithNewHeight (firstWin
);
676 _makeVisibleWithNewHeight (cmdWin
);
677 if (firstWin
->generic
.contentSize
<= 0)
678 tuiEraseSourceContent (firstWin
, EMPTY_SOURCE_PROMPT
);
681 if (curLayout
== SRC_DISASSEM_COMMAND
)
684 firstWin
->generic
.width
+= widthDiff
;
685 secondWin
= disassemWin
;
686 secondWin
->generic
.width
+= widthDiff
;
691 firstWin
->generic
.width
+= widthDiff
;
692 secondWin
= (TuiWinInfoPtr
) (sourceWindows ())->list
[0];
693 secondWin
->generic
.width
+= widthDiff
;
695 /* Change the first window's height/width */
696 /* check for invalid heights */
698 newHeight
= firstWin
->generic
.height
;
699 else if ((firstWin
->generic
.height
+
700 secondWin
->generic
.height
+ (splitDiff
* 2)) >=
701 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
702 newHeight
= (screenheight
- MIN_CMD_WIN_HEIGHT
- 1) / 2;
703 else if ((firstWin
->generic
.height
+ splitDiff
) <= 0)
704 newHeight
= MIN_WIN_HEIGHT
;
706 newHeight
= firstWin
->generic
.height
+ splitDiff
;
707 _makeInvisibleAndSetNewHeight (firstWin
, newHeight
);
709 if (firstWin
== dataWin
&& widthDiff
!= 0)
710 firstWin
->detail
.dataDisplayInfo
.regsColumnCount
=
711 tuiCalculateRegsColumnCount (
712 firstWin
->detail
.dataDisplayInfo
.regsDisplayType
);
713 locator
->width
+= widthDiff
;
715 /* Change the second window's height/width */
716 /* check for invalid heights */
718 newHeight
= secondWin
->generic
.height
;
719 else if ((firstWin
->generic
.height
+
720 secondWin
->generic
.height
+ (splitDiff
* 2)) >=
721 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
723 newHeight
= screenheight
- MIN_CMD_WIN_HEIGHT
- 1;
725 newHeight
= (newHeight
/ 2) + 1;
729 else if ((secondWin
->generic
.height
+ splitDiff
) <= 0)
730 newHeight
= MIN_WIN_HEIGHT
;
732 newHeight
= secondWin
->generic
.height
+ splitDiff
;
733 secondWin
->generic
.origin
.y
= firstWin
->generic
.height
- 1;
734 _makeInvisibleAndSetNewHeight (secondWin
, newHeight
);
736 /* Change the command window's height/width */
737 cmdWin
->generic
.origin
.y
= locator
->origin
.y
+ 1;
738 _makeInvisibleAndSetNewHeight (
739 cmdWin
, cmdWin
->generic
.height
+ cmdSplitDiff
);
740 _makeVisibleWithNewHeight (firstWin
);
741 _makeVisibleWithNewHeight (secondWin
);
742 _makeVisibleWithNewHeight (cmdWin
);
743 if (firstWin
->generic
.contentSize
<= 0)
744 tuiEraseSourceContent (firstWin
, EMPTY_SOURCE_PROMPT
);
745 if (secondWin
->generic
.contentSize
<= 0)
746 tuiEraseSourceContent (secondWin
, EMPTY_SOURCE_PROMPT
);
750 ** Now remove all invisible windows, and their content so that they get
751 ** created again when called for with the new size
753 for (winType
= SRC_WIN
; (winType
< MAX_MAJOR_WINDOWS
); winType
++)
755 if (winType
!= CMD_WIN
&& m_winPtrNotNull (winList
[winType
]) &&
756 !winList
[winType
]->generic
.isVisible
)
758 freeWindow (winList
[winType
]);
759 winList
[winType
] = (TuiWinInfoPtr
) NULL
;
762 tuiSetWinResizedTo (TRUE
);
763 /* turn keypad back on, unless focus is in the command window */
764 if (winWithFocus
!= cmdWin
)
765 keypad (cmdWin
->generic
.handle
, TRUE
);
772 ** tuiSigwinchHandler()
773 ** SIGWINCH signal handler for the tui. This signal handler is
774 ** always called, even when the readline package clears signals
775 ** because it is set as the old_sigwinch() (TUI only)
778 tuiSigwinchHandler (int signal
)
781 ** Say that a resize was done so that the readline can do it
782 ** later when appropriate.
784 tuiSetWinResizedTo (TRUE
);
787 } /* tuiSigwinchHandler */
791 /*************************
792 ** STATIC LOCAL FUNCTIONS
793 **************************/
797 ** _tuiScrollForward_command().
800 _tuiScrollForward_command (char *arg
, int fromTTY
)
803 TuiWinInfoPtr winToScroll
;
805 /* Make sure the curses mode is enabled. */
807 if (arg
== (char *) NULL
)
808 _parseScrollingArgs (arg
, &winToScroll
, (int *) NULL
);
810 _parseScrollingArgs (arg
, &winToScroll
, &numToScroll
);
811 tui_scroll (FORWARD_SCROLL
, winToScroll
, numToScroll
);
816 ** _tuiScrollBackward_command().
819 _tuiScrollBackward_command (char *arg
, int fromTTY
)
822 TuiWinInfoPtr winToScroll
;
824 /* Make sure the curses mode is enabled. */
826 if (arg
== (char *) NULL
)
827 _parseScrollingArgs (arg
, &winToScroll
, (int *) NULL
);
829 _parseScrollingArgs (arg
, &winToScroll
, &numToScroll
);
830 tui_scroll (BACKWARD_SCROLL
, winToScroll
, numToScroll
);
835 ** _tuiScrollLeft_command().
838 _tuiScrollLeft_command (char *arg
, int fromTTY
)
841 TuiWinInfoPtr winToScroll
;
843 /* Make sure the curses mode is enabled. */
845 _parseScrollingArgs (arg
, &winToScroll
, &numToScroll
);
846 tui_scroll (LEFT_SCROLL
, winToScroll
, numToScroll
);
851 ** _tuiScrollRight_command().
854 _tuiScrollRight_command (char *arg
, int fromTTY
)
857 TuiWinInfoPtr winToScroll
;
859 /* Make sure the curses mode is enabled. */
861 _parseScrollingArgs (arg
, &winToScroll
, &numToScroll
);
862 tui_scroll (RIGHT_SCROLL
, winToScroll
, numToScroll
);
868 ** Set focus to the window named by 'arg'
871 _tuiSetFocus (char *arg
, int fromTTY
)
873 if (arg
!= (char *) NULL
)
875 char *bufPtr
= (char *) xstrdup (arg
);
877 TuiWinInfoPtr winInfo
= (TuiWinInfoPtr
) NULL
;
879 for (i
= 0; (i
< strlen (bufPtr
)); i
++)
880 bufPtr
[i
] = toupper (arg
[i
]);
882 if (subset_compare (bufPtr
, "NEXT"))
883 winInfo
= tuiNextWin (tuiWinWithFocus ());
884 else if (subset_compare (bufPtr
, "PREV"))
885 winInfo
= tuiPrevWin (tuiWinWithFocus ());
887 winInfo
= partialWinByName (bufPtr
);
889 if (winInfo
== (TuiWinInfoPtr
) NULL
|| !winInfo
->generic
.isVisible
)
890 warning ("Invalid window specified. \n\
891 The window name specified must be valid and visible.\n");
894 tuiSetWinFocusTo (winInfo
);
895 keypad (cmdWin
->generic
.handle
, (winInfo
!= cmdWin
));
898 if (dataWin
&& dataWin
->generic
.isVisible
)
899 tuiRefreshDataWin ();
901 printf_filtered ("Focus set to %s window.\n",
902 winName ((TuiGenWinInfoPtr
) tuiWinWithFocus ()));
905 warning ("Incorrect Number of Arguments.\n%s", FOCUS_USAGE
);
911 ** _tuiSetFocus_command()
914 _tuiSetFocus_command (char *arg
, int fromTTY
)
916 /* Make sure the curses mode is enabled. */
918 _tuiSetFocus (arg
, fromTTY
);
923 ** _tuiAllWindowsInfo().
926 _tuiAllWindowsInfo (char *arg
, int fromTTY
)
929 TuiWinInfoPtr winWithFocus
= tuiWinWithFocus ();
931 for (type
= SRC_WIN
; (type
< MAX_MAJOR_WINDOWS
); type
++)
932 if (winList
[type
] && winList
[type
]->generic
.isVisible
)
934 if (winWithFocus
== winList
[type
])
935 printf_filtered (" %s\t(%d lines) <has focus>\n",
936 winName (&winList
[type
]->generic
),
937 winList
[type
]->generic
.height
);
939 printf_filtered (" %s\t(%d lines)\n",
940 winName (&winList
[type
]->generic
),
941 winList
[type
]->generic
.height
);
945 } /* _tuiAllWindowsInfo */
949 ** _tuiRefreshAll_command().
952 _tuiRefreshAll_command (char *arg
, int fromTTY
)
954 /* Make sure the curses mode is enabled. */
962 ** _tuiSetWinTabWidth_command().
963 ** Set the height of the specified window.
966 _tuiSetTabWidth_command (char *arg
, int fromTTY
)
968 /* Make sure the curses mode is enabled. */
970 if (arg
!= (char *) NULL
)
976 tuiSetDefaultTabLen (ts
);
978 warning ("Tab widths greater than 0 must be specified.\n");
982 } /* _tuiSetTabWidth_command */
986 ** _tuiSetWinHeight().
987 ** Set the height of the specified window.
990 _tuiSetWinHeight (char *arg
, int fromTTY
)
992 /* Make sure the curses mode is enabled. */
994 if (arg
!= (char *) NULL
)
996 char *buf
= xstrdup (arg
);
998 char *wname
= (char *) NULL
;
1000 TuiWinInfoPtr winInfo
;
1003 bufPtr
= strchr (bufPtr
, ' ');
1004 if (bufPtr
!= (char *) NULL
)
1009 ** Validate the window name
1011 for (i
= 0; i
< strlen (wname
); i
++)
1012 wname
[i
] = toupper (wname
[i
]);
1013 winInfo
= partialWinByName (wname
);
1015 if (winInfo
== (TuiWinInfoPtr
) NULL
|| !winInfo
->generic
.isVisible
)
1016 warning ("Invalid window specified. \n\
1017 The window name specified must be valid and visible.\n");
1020 /* Process the size */
1021 while (*(++bufPtr
) == ' ')
1024 if (*bufPtr
!= (char) 0)
1027 int fixedSize
= TRUE
;
1030 if (*bufPtr
== '+' || *bufPtr
== '-')
1037 inputNo
= atoi (bufPtr
);
1043 newHeight
= inputNo
;
1045 newHeight
= winInfo
->generic
.height
+ inputNo
;
1047 ** Now change the window's height, and adjust all
1048 ** other windows around it
1050 if (_tuiAdjustWinHeights (winInfo
,
1051 newHeight
) == TUI_FAILURE
)
1052 warning ("Invalid window height specified.\n%s",
1055 tui_update_gdb_sizes ();
1058 warning ("Invalid window height specified.\n%s",
1064 printf_filtered (WIN_HEIGHT_USAGE
);
1066 if (buf
!= (char *) NULL
)
1070 printf_filtered (WIN_HEIGHT_USAGE
);
1073 } /* _tuiSetWinHeight */
1076 ** _tuiSetWinHeight_command().
1077 ** Set the height of the specified window, with va_list.
1080 _tuiSetWinHeight_command (char *arg
, int fromTTY
)
1082 /* Make sure the curses mode is enabled. */
1084 _tuiSetWinHeight (arg
, fromTTY
);
1089 ** _tuiXDBsetWinHeight().
1090 ** XDB Compatibility command for setting the window height. This will
1091 ** increase or decrease the command window by the specified amount.
1094 _tuiXDBsetWinHeight (char *arg
, int fromTTY
)
1096 /* Make sure the curses mode is enabled. */
1098 if (arg
!= (char *) NULL
)
1100 int inputNo
= atoi (arg
);
1103 { /* Add 1 for the locator */
1104 int newHeight
= termHeight () - (inputNo
+ 1);
1106 if (!_newHeightOk (winList
[CMD_WIN
], newHeight
) ||
1107 _tuiAdjustWinHeights (winList
[CMD_WIN
],
1108 newHeight
) == TUI_FAILURE
)
1109 warning ("Invalid window height specified.\n%s",
1110 XDBWIN_HEIGHT_USAGE
);
1113 warning ("Invalid window height specified.\n%s",
1114 XDBWIN_HEIGHT_USAGE
);
1117 warning ("Invalid window height specified.\n%s", XDBWIN_HEIGHT_USAGE
);
1120 } /* _tuiXDBsetWinHeight */
1123 ** _tuiSetWinHeight_command().
1124 ** Set the height of the specified window, with va_list.
1127 _tuiXDBsetWinHeight_command (char *arg
, int fromTTY
)
1129 _tuiXDBsetWinHeight (arg
, fromTTY
);
1134 ** _tuiAdjustWinHeights().
1135 ** Function to adjust all window heights around the primary
1138 _tuiAdjustWinHeights (TuiWinInfoPtr primaryWinInfo
, int newHeight
)
1140 TuiStatus status
= TUI_FAILURE
;
1142 if (_newHeightOk (primaryWinInfo
, newHeight
))
1144 status
= TUI_SUCCESS
;
1145 if (newHeight
!= primaryWinInfo
->generic
.height
)
1148 TuiWinInfoPtr winInfo
;
1149 TuiGenWinInfoPtr locator
= locatorWinInfoPtr ();
1150 TuiLayoutType curLayout
= currentLayout ();
1152 diff
= (newHeight
- primaryWinInfo
->generic
.height
) * (-1);
1153 if (curLayout
== SRC_COMMAND
|| curLayout
== DISASSEM_COMMAND
)
1155 TuiWinInfoPtr srcWinInfo
;
1157 _makeInvisibleAndSetNewHeight (primaryWinInfo
, newHeight
);
1158 if (primaryWinInfo
->generic
.type
== CMD_WIN
)
1160 winInfo
= (TuiWinInfoPtr
) (sourceWindows ())->list
[0];
1161 srcWinInfo
= winInfo
;
1165 winInfo
= winList
[CMD_WIN
];
1166 srcWinInfo
= primaryWinInfo
;
1168 _makeInvisibleAndSetNewHeight (winInfo
,
1169 winInfo
->generic
.height
+ diff
);
1170 cmdWin
->generic
.origin
.y
= locator
->origin
.y
+ 1;
1171 _makeVisibleWithNewHeight (winInfo
);
1172 _makeVisibleWithNewHeight (primaryWinInfo
);
1173 if (srcWinInfo
->generic
.contentSize
<= 0)
1174 tuiEraseSourceContent (srcWinInfo
, EMPTY_SOURCE_PROMPT
);
1178 TuiWinInfoPtr firstWin
, secondWin
;
1180 if (curLayout
== SRC_DISASSEM_COMMAND
)
1183 secondWin
= disassemWin
;
1188 secondWin
= (TuiWinInfoPtr
) (sourceWindows ())->list
[0];
1190 if (primaryWinInfo
== cmdWin
)
1192 ** Split the change in height accross the 1st & 2nd windows
1193 ** adjusting them as well.
1195 int firstSplitDiff
= diff
/ 2; /* subtract the locator */
1196 int secondSplitDiff
= firstSplitDiff
;
1200 if (firstWin
->generic
.height
>
1201 secondWin
->generic
.height
)
1214 /* make sure that the minimum hieghts are honored */
1215 while ((firstWin
->generic
.height
+ firstSplitDiff
) < 3)
1220 while ((secondWin
->generic
.height
+ secondSplitDiff
) < 3)
1225 _makeInvisibleAndSetNewHeight (
1227 firstWin
->generic
.height
+ firstSplitDiff
);
1228 secondWin
->generic
.origin
.y
= firstWin
->generic
.height
- 1;
1229 _makeInvisibleAndSetNewHeight (
1230 secondWin
, secondWin
->generic
.height
+ secondSplitDiff
);
1231 cmdWin
->generic
.origin
.y
= locator
->origin
.y
+ 1;
1232 _makeInvisibleAndSetNewHeight (cmdWin
, newHeight
);
1236 if ((cmdWin
->generic
.height
+ diff
) < 1)
1238 ** If there is no way to increase the command window
1239 ** take real estate from the 1st or 2nd window.
1241 if ((cmdWin
->generic
.height
+ diff
) < 1)
1244 for (i
= cmdWin
->generic
.height
+ diff
;
1246 if (primaryWinInfo
== firstWin
)
1247 secondWin
->generic
.height
--;
1249 firstWin
->generic
.height
--;
1252 if (primaryWinInfo
== firstWin
)
1253 _makeInvisibleAndSetNewHeight (firstWin
, newHeight
);
1255 _makeInvisibleAndSetNewHeight (
1257 firstWin
->generic
.height
);
1258 secondWin
->generic
.origin
.y
= firstWin
->generic
.height
- 1;
1259 if (primaryWinInfo
== secondWin
)
1260 _makeInvisibleAndSetNewHeight (secondWin
, newHeight
);
1262 _makeInvisibleAndSetNewHeight (
1263 secondWin
, secondWin
->generic
.height
);
1264 cmdWin
->generic
.origin
.y
= locator
->origin
.y
+ 1;
1265 if ((cmdWin
->generic
.height
+ diff
) < 1)
1266 _makeInvisibleAndSetNewHeight (cmdWin
, 1);
1268 _makeInvisibleAndSetNewHeight (
1269 cmdWin
, cmdWin
->generic
.height
+ diff
);
1271 _makeVisibleWithNewHeight (cmdWin
);
1272 _makeVisibleWithNewHeight (secondWin
);
1273 _makeVisibleWithNewHeight (firstWin
);
1274 if (firstWin
->generic
.contentSize
<= 0)
1275 tuiEraseSourceContent (firstWin
, EMPTY_SOURCE_PROMPT
);
1276 if (secondWin
->generic
.contentSize
<= 0)
1277 tuiEraseSourceContent (secondWin
, EMPTY_SOURCE_PROMPT
);
1283 } /* _tuiAdjustWinHeights */
1287 ** _makeInvisibleAndSetNewHeight().
1288 ** Function make the target window (and auxillary windows associated
1289 ** with the targer) invisible, and set the new height and location.
1292 _makeInvisibleAndSetNewHeight (TuiWinInfoPtr winInfo
, int height
)
1295 TuiGenWinInfoPtr genWinInfo
;
1298 m_beInvisible (&winInfo
->generic
);
1299 winInfo
->generic
.height
= height
;
1301 winInfo
->generic
.viewportHeight
= height
- 1;
1303 winInfo
->generic
.viewportHeight
= height
;
1304 if (winInfo
!= cmdWin
)
1305 winInfo
->generic
.viewportHeight
--;
1307 /* Now deal with the auxillary windows associated with winInfo */
1308 switch (winInfo
->generic
.type
)
1312 genWinInfo
= winInfo
->detail
.sourceInfo
.executionInfo
;
1313 m_beInvisible (genWinInfo
);
1314 genWinInfo
->height
= height
;
1315 genWinInfo
->origin
.y
= winInfo
->generic
.origin
.y
;
1317 genWinInfo
->viewportHeight
= height
- 1;
1319 genWinInfo
->viewportHeight
= height
;
1320 if (winInfo
!= cmdWin
)
1321 genWinInfo
->viewportHeight
--;
1323 if (m_hasLocator (winInfo
))
1325 genWinInfo
= locatorWinInfoPtr ();
1326 m_beInvisible (genWinInfo
);
1327 genWinInfo
->origin
.y
= winInfo
->generic
.origin
.y
+ height
;
1331 /* delete all data item windows */
1332 for (i
= 0; i
< winInfo
->generic
.contentSize
; i
++)
1334 genWinInfo
= (TuiGenWinInfoPtr
) & ((TuiWinElementPtr
)
1335 winInfo
->generic
.content
[i
])->whichElement
.dataWindow
;
1336 tuiDelwin (genWinInfo
->handle
);
1337 genWinInfo
->handle
= (WINDOW
*) NULL
;
1347 ** _makeVisibleWithNewHeight().
1348 ** Function to make the windows with new heights visible.
1349 ** This means re-creating the windows' content since the window
1350 ** had to be destroyed to be made invisible.
1353 _makeVisibleWithNewHeight (TuiWinInfoPtr winInfo
)
1357 m_beVisible (&winInfo
->generic
);
1358 checkAndDisplayHighlightIfNeeded (winInfo
);
1359 switch (winInfo
->generic
.type
)
1363 freeWinContent (winInfo
->detail
.sourceInfo
.executionInfo
);
1364 m_beVisible (winInfo
->detail
.sourceInfo
.executionInfo
);
1365 if (winInfo
->generic
.content
!= (OpaquePtr
) NULL
)
1367 TuiLineOrAddress lineOrAddr
;
1368 struct symtab_and_line cursal
1369 = get_current_source_symtab_and_line ();
1371 if (winInfo
->generic
.type
== SRC_WIN
)
1373 winInfo
->detail
.sourceInfo
.startLineOrAddr
.lineNo
;
1376 winInfo
->detail
.sourceInfo
.startLineOrAddr
.addr
;
1377 freeWinContent (&winInfo
->generic
);
1378 tuiUpdateSourceWindow (winInfo
,
1379 cursal
.symtab
, lineOrAddr
, TRUE
);
1381 else if (selected_frame
!= (struct frame_info
*) NULL
)
1383 TuiLineOrAddress line
;
1384 struct symtab_and_line cursal
= get_current_source_symtab_and_line ();
1387 s
= find_pc_symtab (selected_frame
->pc
);
1388 if (winInfo
->generic
.type
== SRC_WIN
)
1389 line
.lineNo
= cursal
.line
;
1392 find_line_pc (s
, cursal
.line
, &line
.addr
);
1394 tuiUpdateSourceWindow (winInfo
, s
, line
, TRUE
);
1396 if (m_hasLocator (winInfo
))
1398 m_beVisible (locatorWinInfoPtr ());
1399 tuiShowLocatorContent ();
1403 tuiDisplayAllData ();
1406 winInfo
->detail
.commandInfo
.curLine
= 0;
1407 winInfo
->detail
.commandInfo
.curch
= 0;
1408 wmove (winInfo
->generic
.handle
,
1409 winInfo
->detail
.commandInfo
.curLine
,
1410 winInfo
->detail
.commandInfo
.curch
);
1417 } /* _makeVisibleWithNewHeight */
1421 _newHeightOk (TuiWinInfoPtr primaryWinInfo
, int newHeight
)
1423 int ok
= (newHeight
< termHeight ());
1428 TuiLayoutType curLayout
= currentLayout ();
1430 diff
= (newHeight
- primaryWinInfo
->generic
.height
) * (-1);
1431 if (curLayout
== SRC_COMMAND
|| curLayout
== DISASSEM_COMMAND
)
1433 ok
= ((primaryWinInfo
->generic
.type
== CMD_WIN
&&
1434 newHeight
<= (termHeight () - 4) &&
1435 newHeight
>= MIN_CMD_WIN_HEIGHT
) ||
1436 (primaryWinInfo
->generic
.type
!= CMD_WIN
&&
1437 newHeight
<= (termHeight () - 2) &&
1438 newHeight
>= MIN_WIN_HEIGHT
));
1440 { /* check the total height */
1441 TuiWinInfoPtr winInfo
;
1443 if (primaryWinInfo
== cmdWin
)
1444 winInfo
= (TuiWinInfoPtr
) (sourceWindows ())->list
[0];
1448 (winInfo
->generic
.height
+ diff
)) <= termHeight ());
1453 int curTotalHeight
, totalHeight
, minHeight
= 0;
1454 TuiWinInfoPtr firstWin
, secondWin
;
1456 if (curLayout
== SRC_DISASSEM_COMMAND
)
1459 secondWin
= disassemWin
;
1464 secondWin
= (TuiWinInfoPtr
) (sourceWindows ())->list
[0];
1467 ** We could simply add all the heights to obtain the same result
1468 ** but below is more explicit since we subtract 1 for the
1469 ** line that the first and second windows share, and add one
1472 totalHeight
= curTotalHeight
=
1473 (firstWin
->generic
.height
+ secondWin
->generic
.height
- 1)
1474 + cmdWin
->generic
.height
+ 1 /*locator */ ;
1475 if (primaryWinInfo
== cmdWin
)
1477 /* locator included since first & second win share a line */
1478 ok
= ((firstWin
->generic
.height
+
1479 secondWin
->generic
.height
+ diff
) >=
1480 (MIN_WIN_HEIGHT
* 2) &&
1481 newHeight
>= MIN_CMD_WIN_HEIGHT
);
1484 totalHeight
= newHeight
+ (firstWin
->generic
.height
+
1485 secondWin
->generic
.height
+ diff
);
1486 minHeight
= MIN_CMD_WIN_HEIGHT
;
1491 minHeight
= MIN_WIN_HEIGHT
;
1493 ** First see if we can increase/decrease the command
1494 ** window. And make sure that the command window is
1497 ok
= ((cmdWin
->generic
.height
+ diff
) > 0);
1500 ** Looks like we have to increase/decrease one of
1501 ** the other windows
1503 if (primaryWinInfo
== firstWin
)
1504 ok
= (secondWin
->generic
.height
+ diff
) >= minHeight
;
1506 ok
= (firstWin
->generic
.height
+ diff
) >= minHeight
;
1510 if (primaryWinInfo
== firstWin
)
1511 totalHeight
= newHeight
+
1512 secondWin
->generic
.height
+
1513 cmdWin
->generic
.height
+ diff
;
1515 totalHeight
= newHeight
+
1516 firstWin
->generic
.height
+
1517 cmdWin
->generic
.height
+ diff
;
1521 ** Now make sure that the proposed total height doesn't exceed
1522 ** the old total height.
1525 ok
= (newHeight
>= minHeight
&& totalHeight
<= curTotalHeight
);
1530 } /* _newHeightOk */
1534 ** _parseScrollingArgs().
1537 _parseScrollingArgs (char *arg
, TuiWinInfoPtr
* winToScroll
, int *numToScroll
)
1541 *winToScroll
= tuiWinWithFocus ();
1544 ** First set up the default window to scroll, in case there is no
1547 if (arg
!= (char *) NULL
)
1551 /* process the number of lines to scroll */
1552 buf
= bufPtr
= xstrdup (arg
);
1553 if (isdigit (*bufPtr
))
1558 bufPtr
= strchr (bufPtr
, ' ');
1559 if (bufPtr
!= (char *) NULL
)
1563 *numToScroll
= atoi (numStr
);
1566 else if (numToScroll
)
1567 *numToScroll
= atoi (numStr
);
1570 /* process the window name if one is specified */
1571 if (bufPtr
!= (char *) NULL
)
1577 while (*(++bufPtr
) == ' ')
1580 if (*bufPtr
!= (char) 0)
1585 /* Validate the window name */
1586 for (i
= 0; i
< strlen (wname
); i
++)
1587 wname
[i
] = toupper (wname
[i
]);
1588 *winToScroll
= partialWinByName (wname
);
1590 if (*winToScroll
== (TuiWinInfoPtr
) NULL
||
1591 !(*winToScroll
)->generic
.isVisible
)
1592 warning ("Invalid window specified. \n\
1593 The window name specified must be valid and visible.\n");
1594 else if (*winToScroll
== cmdWin
)
1595 *winToScroll
= (TuiWinInfoPtr
) (sourceWindows ())->list
[0];
1601 } /* _parseScrollingArgs */