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>
49 #include <readline/readline.h>
53 #include "breakpoint.h"
55 #include "cli/cli-cmds.h"
61 #include "tuiGeneralWin.h"
64 #include "tuiDisassem.h"
65 #include "tuiSource.h"
66 #include "tuiSourceWin.h"
67 #include "tuiDataWin.h"
69 /*******************************
71 ********************************/
72 static void _makeVisibleWithNewHeight (TuiWinInfoPtr
);
73 static void _makeInvisibleAndSetNewHeight (TuiWinInfoPtr
, int);
74 static TuiStatus
_tuiAdjustWinHeights (TuiWinInfoPtr
, int);
75 static int _newHeightOk (TuiWinInfoPtr
, int);
76 static void _tuiSetTabWidth_command (char *, int);
77 static void _tuiRefreshAll_command (char *, int);
78 static void _tuiSetWinHeight_command (char *, int);
79 static void _tuiXDBsetWinHeight_command (char *, int);
80 static void _tuiAllWindowsInfo (char *, int);
81 static void _tuiSetFocus_command (char *, int);
82 static void _tuiScrollForward_command (char *, int);
83 static void _tuiScrollBackward_command (char *, int);
84 static void _tuiScrollLeft_command (char *, int);
85 static void _tuiScrollRight_command (char *, int);
86 static void _parseScrollingArgs (char *, TuiWinInfoPtr
*, int *);
89 /***************************************
91 ***************************************/
92 #define WIN_HEIGHT_USAGE "Usage: winheight <win_name> [+ | -] <#lines>\n"
93 #define XDBWIN_HEIGHT_USAGE "Usage: w <#lines>\n"
94 #define FOCUS_USAGE "Usage: focus {<win> | next | prev}\n"
96 /***************************************
98 ***************************************/
101 # define ACS_LRCORNER '+'
104 # define ACS_LLCORNER '+'
107 # define ACS_ULCORNER '+'
110 # define ACS_URCORNER '+'
113 # define ACS_HLINE '-'
116 # define ACS_VLINE '|'
119 /* Possible values for tui-border-kind variable. */
120 static const char *tui_border_kind_enums
[] = {
127 /* Possible values for tui-border-mode and tui-active-border-mode. */
128 static const char *tui_border_mode_enums
[] = {
145 /* Translation table for border-mode variables.
146 The list of values must be terminated by a NULL.
147 After the NULL value, an entry defines the default. */
148 struct tui_translate tui_border_mode_translate
[] = {
149 { "normal", A_NORMAL
},
150 { "standout", A_STANDOUT
},
151 { "reverse", A_REVERSE
},
153 { "half-standout", A_DIM
| A_STANDOUT
},
155 { "bold-standout", A_BOLD
| A_STANDOUT
},
157 { "normal", A_NORMAL
}
160 /* Translation tables for border-kind, one for each border
161 character (see wborder, border curses operations).
162 -1 is used to indicate the ACS because ACS characters
163 are determined at run time by curses (depends on terminal). */
164 struct tui_translate tui_border_kind_translate_vline
[] = {
172 struct tui_translate tui_border_kind_translate_hline
[] = {
180 struct tui_translate tui_border_kind_translate_ulcorner
[] = {
188 struct tui_translate tui_border_kind_translate_urcorner
[] = {
196 struct tui_translate tui_border_kind_translate_llcorner
[] = {
204 struct tui_translate tui_border_kind_translate_lrcorner
[] = {
213 /* Tui configuration variables controlled with set/show command. */
214 const char *tui_active_border_mode
= "bold-standout";
215 const char *tui_border_mode
= "normal";
216 const char *tui_border_kind
= "acs";
218 /* Tui internal configuration variables. These variables are
219 updated by tui_update_variables to reflect the tui configuration
221 chtype tui_border_vline
;
222 chtype tui_border_hline
;
223 chtype tui_border_ulcorner
;
224 chtype tui_border_urcorner
;
225 chtype tui_border_llcorner
;
226 chtype tui_border_lrcorner
;
228 int tui_border_attrs
;
229 int tui_active_border_attrs
;
231 /* Identify the item in the translation table.
232 When the item is not recognized, use the default entry. */
233 static struct tui_translate
*
234 translate (const char *name
, struct tui_translate
*table
)
238 if (name
&& strcmp (table
->name
, name
) == 0)
243 /* Not found, return default entry. */
248 /* Update the tui internal configuration according to gdb settings.
249 Returns 1 if the configuration has changed and the screen should
252 tui_update_variables ()
255 struct tui_translate
*entry
;
257 entry
= translate (tui_border_mode
, tui_border_mode_translate
);
258 if (tui_border_attrs
!= entry
->value
)
260 tui_border_attrs
= entry
->value
;
263 entry
= translate (tui_active_border_mode
, tui_border_mode_translate
);
264 if (tui_active_border_attrs
!= entry
->value
)
266 tui_active_border_attrs
= entry
->value
;
270 /* If one corner changes, all characters are changed.
271 Only check the first one. The ACS characters are determined at
272 run time by curses terminal management. */
273 entry
= translate (tui_border_kind
, tui_border_kind_translate_lrcorner
);
274 if (tui_border_lrcorner
!= (chtype
) entry
->value
)
276 tui_border_lrcorner
= (entry
->value
< 0) ? ACS_LRCORNER
: entry
->value
;
279 entry
= translate (tui_border_kind
, tui_border_kind_translate_llcorner
);
280 tui_border_llcorner
= (entry
->value
< 0) ? ACS_LLCORNER
: entry
->value
;
282 entry
= translate (tui_border_kind
, tui_border_kind_translate_ulcorner
);
283 tui_border_ulcorner
= (entry
->value
< 0) ? ACS_ULCORNER
: entry
->value
;
285 entry
= translate (tui_border_kind
, tui_border_kind_translate_urcorner
);
286 tui_border_urcorner
= (entry
->value
< 0) ? ACS_URCORNER
: entry
->value
;
288 entry
= translate (tui_border_kind
, tui_border_kind_translate_hline
);
289 tui_border_hline
= (entry
->value
< 0) ? ACS_HLINE
: entry
->value
;
291 entry
= translate (tui_border_kind
, tui_border_kind_translate_vline
);
292 tui_border_vline
= (entry
->value
< 0) ? ACS_VLINE
: entry
->value
;
298 set_tui_cmd (char *args
, int from_tty
)
303 show_tui_cmd (char *args
, int from_tty
)
308 ** _initialize_tuiWin().
309 ** Function to initialize gdb commands, for tui window manipulation.
312 _initialize_tuiWin (void)
314 struct cmd_list_element
*c
;
315 static struct cmd_list_element
*tui_setlist
;
316 static struct cmd_list_element
*tui_showlist
;
318 /* Define the classes of commands.
319 They will appear in the help list in the reverse of this order. */
320 add_cmd ("tui", class_tui
, NULL
,
321 "Text User Interface commands.",
324 add_prefix_cmd ("tui", class_tui
, set_tui_cmd
,
325 "TUI configuration variables",
326 &tui_setlist
, "set tui ",
327 0/*allow-unknown*/, &setlist
);
328 add_prefix_cmd ("tui", class_tui
, show_tui_cmd
,
329 "TUI configuration variables",
330 &tui_showlist
, "show tui ",
331 0/*allow-unknown*/, &showlist
);
333 add_com ("refresh", class_tui
, _tuiRefreshAll_command
,
334 "Refresh the terminal display.\n");
336 add_com_alias ("U", "refresh", class_tui
, 0);
337 add_com ("tabset", class_tui
, _tuiSetTabWidth_command
,
338 "Set the width (in characters) of tab stops.\n\
339 Usage: tabset <n>\n");
340 add_com ("winheight", class_tui
, _tuiSetWinHeight_command
,
341 "Set the height of a specified window.\n\
342 Usage: winheight <win_name> [+ | -] <#lines>\n\
344 src : the source window\n\
345 cmd : the command window\n\
346 asm : the disassembly window\n\
347 regs : the register display\n");
348 add_com_alias ("wh", "winheight", class_tui
, 0);
349 add_info ("win", _tuiAllWindowsInfo
,
350 "List of all displayed windows.\n");
351 add_com ("focus", class_tui
, _tuiSetFocus_command
,
352 "Set focus to named window or next/prev window.\n\
353 Usage: focus {<win> | next | prev}\n\
354 Valid Window names are:\n\
355 src : the source window\n\
356 asm : the disassembly window\n\
357 regs : the register display\n\
358 cmd : the command window\n");
359 add_com_alias ("fs", "focus", class_tui
, 0);
360 add_com ("+", class_tui
, _tuiScrollForward_command
,
361 "Scroll window forward.\nUsage: + [win] [n]\n");
362 add_com ("-", class_tui
, _tuiScrollBackward_command
,
363 "Scroll window backward.\nUsage: - [win] [n]\n");
364 add_com ("<", class_tui
, _tuiScrollLeft_command
,
365 "Scroll window forward.\nUsage: < [win] [n]\n");
366 add_com (">", class_tui
, _tuiScrollRight_command
,
367 "Scroll window backward.\nUsage: > [win] [n]\n");
369 add_com ("w", class_xdb
, _tuiXDBsetWinHeight_command
,
370 "XDB compatibility command for setting the height of a command window.\n\
371 Usage: w <#lines>\n");
373 /* Define the tui control variables. */
375 ("border-kind", no_class
,
376 tui_border_kind_enums
, &tui_border_kind
,
377 "Set the kind of border for TUI windows.\n"
378 "This variable controls the border of TUI windows:\n"
379 "space use a white space\n"
380 "ascii use ascii characters + - | for the border\n"
381 "acs use the Alternate Character Set\n",
383 add_show_from_set (c
, &tui_showlist
);
386 ("border-mode", no_class
,
387 tui_border_mode_enums
, &tui_border_mode
,
388 "Set the attribute mode to use for the TUI window borders.\n"
389 "This variable controls the attributes to use for the window borders:\n"
390 "normal normal display\n"
391 "standout use highlight mode of terminal\n"
392 "reverse use reverse video mode\n"
393 "half use half bright\n"
394 "half-standout use half bright and standout mode\n"
395 "bold use extra bright or bold\n"
396 "bold-standout use extra bright or bold with standout mode\n",
398 add_show_from_set (c
, &tui_showlist
);
401 ("active-border-mode", no_class
,
402 tui_border_mode_enums
, &tui_active_border_mode
,
403 "Set the attribute mode to use for the active TUI window border.\n"
404 "This variable controls the attributes to use for the active window border:\n"
405 "normal normal display\n"
406 "standout use highlight mode of terminal\n"
407 "reverse use reverse video mode\n"
408 "half use half bright\n"
409 "half-standout use half bright and standout mode\n"
410 "bold use extra bright or bold\n"
411 "bold-standout use extra bright or bold with standout mode\n",
413 add_show_from_set (c
, &tui_showlist
);
416 /* Update gdb's knowledge of the terminal size. */
418 tui_update_gdb_sizes ()
421 int screenheight
, screenwidth
;
423 rl_get_screen_size (&screenheight
, &screenwidth
);
424 /* Set to TUI command window dimension or use readline values. */
425 sprintf (cmd
, "set width %d",
426 tui_active
? cmdWin
->generic
.width
: screenwidth
);
427 execute_command (cmd
, 0);
428 sprintf (cmd
, "set height %d",
429 tui_active
? cmdWin
->generic
.height
: screenheight
);
430 execute_command (cmd
, 0);
436 ** Set the logical focus to winInfo
439 tuiSetWinFocusTo (TuiWinInfoPtr winInfo
)
441 if (m_winPtrNotNull (winInfo
))
443 TuiWinInfoPtr winWithFocus
= tuiWinWithFocus ();
445 if (m_winPtrNotNull (winWithFocus
) &&
446 winWithFocus
->generic
.type
!= CMD_WIN
)
447 unhighlightWin (winWithFocus
);
448 tuiSetWinWithFocus (winInfo
);
449 if (winInfo
->generic
.type
!= CMD_WIN
)
450 highlightWin (winInfo
);
454 } /* tuiSetWinFocusTo */
458 ** tuiScrollForward().
461 tuiScrollForward (TuiWinInfoPtr winToScroll
, int numToScroll
)
463 if (winToScroll
!= cmdWin
)
465 int _numToScroll
= numToScroll
;
467 if (numToScroll
== 0)
468 _numToScroll
= winToScroll
->generic
.height
- 3;
470 ** If we are scrolling the source or disassembly window, do a
471 ** "psuedo" scroll since not all of the source is in memory,
472 ** only what is in the viewport. If winToScroll is the
473 ** command window do nothing since the term should handle it.
475 if (winToScroll
== srcWin
)
476 tuiVerticalSourceScroll (FORWARD_SCROLL
, _numToScroll
);
477 else if (winToScroll
== disassemWin
)
478 tuiVerticalDisassemScroll (FORWARD_SCROLL
, _numToScroll
);
479 else if (winToScroll
== dataWin
)
480 tuiVerticalDataScroll (FORWARD_SCROLL
, _numToScroll
);
484 } /* tuiScrollForward */
488 ** tuiScrollBackward().
491 tuiScrollBackward (TuiWinInfoPtr winToScroll
, int numToScroll
)
493 if (winToScroll
!= cmdWin
)
495 int _numToScroll
= numToScroll
;
497 if (numToScroll
== 0)
498 _numToScroll
= winToScroll
->generic
.height
- 3;
500 ** If we are scrolling the source or disassembly window, do a
501 ** "psuedo" scroll since not all of the source is in memory,
502 ** only what is in the viewport. If winToScroll is the
503 ** command window do nothing since the term should handle it.
505 if (winToScroll
== srcWin
)
506 tuiVerticalSourceScroll (BACKWARD_SCROLL
, _numToScroll
);
507 else if (winToScroll
== disassemWin
)
508 tuiVerticalDisassemScroll (BACKWARD_SCROLL
, _numToScroll
);
509 else if (winToScroll
== dataWin
)
510 tuiVerticalDataScroll (BACKWARD_SCROLL
, _numToScroll
);
513 } /* tuiScrollBackward */
520 tuiScrollLeft (TuiWinInfoPtr winToScroll
, int numToScroll
)
522 if (winToScroll
!= cmdWin
)
524 int _numToScroll
= numToScroll
;
526 if (_numToScroll
== 0)
529 ** If we are scrolling the source or disassembly window, do a
530 ** "psuedo" scroll since not all of the source is in memory,
531 ** only what is in the viewport. If winToScroll is the
532 ** command window do nothing since the term should handle it.
534 if (winToScroll
== srcWin
|| winToScroll
== disassemWin
)
535 tuiHorizontalSourceScroll (winToScroll
, LEFT_SCROLL
, _numToScroll
);
538 } /* tuiScrollLeft */
545 tuiScrollRight (TuiWinInfoPtr winToScroll
, int numToScroll
)
547 if (winToScroll
!= cmdWin
)
549 int _numToScroll
= numToScroll
;
551 if (_numToScroll
== 0)
554 ** If we are scrolling the source or disassembly window, do a
555 ** "psuedo" scroll since not all of the source is in memory,
556 ** only what is in the viewport. If winToScroll is the
557 ** command window do nothing since the term should handle it.
559 if (winToScroll
== srcWin
|| winToScroll
== disassemWin
)
560 tuiHorizontalSourceScroll (winToScroll
, RIGHT_SCROLL
, _numToScroll
);
563 } /* tuiScrollRight */
568 ** Scroll a window. Arguments are passed through a va_list.
571 tui_scroll (TuiScrollDirection direction
,
572 TuiWinInfoPtr winToScroll
,
578 tuiScrollForward (winToScroll
, numToScroll
);
580 case BACKWARD_SCROLL
:
581 tuiScrollBackward (winToScroll
, numToScroll
);
584 tuiScrollLeft (winToScroll
, numToScroll
);
587 tuiScrollRight (winToScroll
, numToScroll
);
603 clearok (curscr
, TRUE
);
604 refreshAll (winList
);
605 for (type
= SRC_WIN
; type
< MAX_MAJOR_WINDOWS
; type
++)
607 if (winList
[type
] && winList
[type
]->generic
.isVisible
)
613 tuiShowSourceContent (winList
[type
]);
614 checkAndDisplayHighlightIfNeeded (winList
[type
]);
615 tuiEraseExecInfoContent (winList
[type
]);
616 tuiUpdateExecInfo (winList
[type
]);
619 tuiRefreshDataWin ();
626 tuiShowLocatorContent ();
632 ** Resize all the windows based on the the terminal size. This
633 ** function gets called from within the readline sinwinch handler.
638 int heightDiff
, widthDiff
;
639 int screenheight
, screenwidth
;
641 rl_get_screen_size (&screenheight
, &screenwidth
);
642 widthDiff
= screenwidth
- termWidth ();
643 heightDiff
= screenheight
- termHeight ();
644 if (heightDiff
|| widthDiff
)
646 TuiLayoutType curLayout
= currentLayout ();
647 TuiWinInfoPtr winWithFocus
= tuiWinWithFocus ();
648 TuiWinInfoPtr firstWin
, secondWin
;
649 TuiGenWinInfoPtr locator
= locatorWinInfoPtr ();
651 int newHeight
, splitDiff
, cmdSplitDiff
, numWinsDisplayed
= 2;
653 /* turn keypad off while we resize */
654 if (winWithFocus
!= cmdWin
)
655 keypad (cmdWin
->generic
.handle
, FALSE
);
656 tui_update_gdb_sizes ();
657 setTermHeightTo (screenheight
);
658 setTermWidthTo (screenwidth
);
659 if (curLayout
== SRC_DISASSEM_COMMAND
||
660 curLayout
== SRC_DATA_COMMAND
|| curLayout
== DISASSEM_DATA_COMMAND
)
662 splitDiff
= heightDiff
/ numWinsDisplayed
;
663 cmdSplitDiff
= splitDiff
;
664 if (heightDiff
% numWinsDisplayed
)
671 /* now adjust each window */
677 case DISASSEM_COMMAND
:
678 firstWin
= (TuiWinInfoPtr
) (sourceWindows ())->list
[0];
679 firstWin
->generic
.width
+= widthDiff
;
680 locator
->width
+= widthDiff
;
681 /* check for invalid heights */
683 newHeight
= firstWin
->generic
.height
;
684 else if ((firstWin
->generic
.height
+ splitDiff
) >=
685 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
686 newHeight
= screenheight
- MIN_CMD_WIN_HEIGHT
- 1;
687 else if ((firstWin
->generic
.height
+ splitDiff
) <= 0)
688 newHeight
= MIN_WIN_HEIGHT
;
690 newHeight
= firstWin
->generic
.height
+ splitDiff
;
692 _makeInvisibleAndSetNewHeight (firstWin
, newHeight
);
693 cmdWin
->generic
.origin
.y
= locator
->origin
.y
+ 1;
694 cmdWin
->generic
.width
+= widthDiff
;
695 newHeight
= screenheight
- cmdWin
->generic
.origin
.y
;
696 _makeInvisibleAndSetNewHeight (cmdWin
, newHeight
);
697 _makeVisibleWithNewHeight (firstWin
);
698 _makeVisibleWithNewHeight (cmdWin
);
699 if (firstWin
->generic
.contentSize
<= 0)
700 tuiEraseSourceContent (firstWin
, EMPTY_SOURCE_PROMPT
);
703 if (curLayout
== SRC_DISASSEM_COMMAND
)
706 firstWin
->generic
.width
+= widthDiff
;
707 secondWin
= disassemWin
;
708 secondWin
->generic
.width
+= widthDiff
;
713 firstWin
->generic
.width
+= widthDiff
;
714 secondWin
= (TuiWinInfoPtr
) (sourceWindows ())->list
[0];
715 secondWin
->generic
.width
+= widthDiff
;
717 /* Change the first window's height/width */
718 /* check for invalid heights */
720 newHeight
= firstWin
->generic
.height
;
721 else if ((firstWin
->generic
.height
+
722 secondWin
->generic
.height
+ (splitDiff
* 2)) >=
723 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
724 newHeight
= (screenheight
- MIN_CMD_WIN_HEIGHT
- 1) / 2;
725 else if ((firstWin
->generic
.height
+ splitDiff
) <= 0)
726 newHeight
= MIN_WIN_HEIGHT
;
728 newHeight
= firstWin
->generic
.height
+ splitDiff
;
729 _makeInvisibleAndSetNewHeight (firstWin
, newHeight
);
731 if (firstWin
== dataWin
&& widthDiff
!= 0)
732 firstWin
->detail
.dataDisplayInfo
.regsColumnCount
=
733 tuiCalculateRegsColumnCount (
734 firstWin
->detail
.dataDisplayInfo
.regsDisplayType
);
735 locator
->width
+= widthDiff
;
737 /* Change the second window's height/width */
738 /* check for invalid heights */
740 newHeight
= secondWin
->generic
.height
;
741 else if ((firstWin
->generic
.height
+
742 secondWin
->generic
.height
+ (splitDiff
* 2)) >=
743 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
745 newHeight
= screenheight
- MIN_CMD_WIN_HEIGHT
- 1;
747 newHeight
= (newHeight
/ 2) + 1;
751 else if ((secondWin
->generic
.height
+ splitDiff
) <= 0)
752 newHeight
= MIN_WIN_HEIGHT
;
754 newHeight
= secondWin
->generic
.height
+ splitDiff
;
755 secondWin
->generic
.origin
.y
= firstWin
->generic
.height
- 1;
756 _makeInvisibleAndSetNewHeight (secondWin
, newHeight
);
758 /* Change the command window's height/width */
759 cmdWin
->generic
.origin
.y
= locator
->origin
.y
+ 1;
760 _makeInvisibleAndSetNewHeight (
761 cmdWin
, cmdWin
->generic
.height
+ cmdSplitDiff
);
762 _makeVisibleWithNewHeight (firstWin
);
763 _makeVisibleWithNewHeight (secondWin
);
764 _makeVisibleWithNewHeight (cmdWin
);
765 if (firstWin
->generic
.contentSize
<= 0)
766 tuiEraseSourceContent (firstWin
, EMPTY_SOURCE_PROMPT
);
767 if (secondWin
->generic
.contentSize
<= 0)
768 tuiEraseSourceContent (secondWin
, EMPTY_SOURCE_PROMPT
);
772 ** Now remove all invisible windows, and their content so that they get
773 ** created again when called for with the new size
775 for (winType
= SRC_WIN
; (winType
< MAX_MAJOR_WINDOWS
); winType
++)
777 if (winType
!= CMD_WIN
&& m_winPtrNotNull (winList
[winType
]) &&
778 !winList
[winType
]->generic
.isVisible
)
780 freeWindow (winList
[winType
]);
781 winList
[winType
] = (TuiWinInfoPtr
) NULL
;
784 tuiSetWinResizedTo (TRUE
);
785 /* turn keypad back on, unless focus is in the command window */
786 if (winWithFocus
!= cmdWin
)
787 keypad (cmdWin
->generic
.handle
, TRUE
);
794 ** tuiSigwinchHandler()
795 ** SIGWINCH signal handler for the tui. This signal handler is
796 ** always called, even when the readline package clears signals
797 ** because it is set as the old_sigwinch() (TUI only)
800 tuiSigwinchHandler (int signal
)
803 ** Say that a resize was done so that the readline can do it
804 ** later when appropriate.
806 tuiSetWinResizedTo (TRUE
);
809 } /* tuiSigwinchHandler */
813 /*************************
814 ** STATIC LOCAL FUNCTIONS
815 **************************/
819 ** _tuiScrollForward_command().
822 _tuiScrollForward_command (char *arg
, int fromTTY
)
825 TuiWinInfoPtr winToScroll
;
827 /* Make sure the curses mode is enabled. */
829 if (arg
== (char *) NULL
)
830 _parseScrollingArgs (arg
, &winToScroll
, (int *) NULL
);
832 _parseScrollingArgs (arg
, &winToScroll
, &numToScroll
);
833 tui_scroll (FORWARD_SCROLL
, winToScroll
, numToScroll
);
838 ** _tuiScrollBackward_command().
841 _tuiScrollBackward_command (char *arg
, int fromTTY
)
844 TuiWinInfoPtr winToScroll
;
846 /* Make sure the curses mode is enabled. */
848 if (arg
== (char *) NULL
)
849 _parseScrollingArgs (arg
, &winToScroll
, (int *) NULL
);
851 _parseScrollingArgs (arg
, &winToScroll
, &numToScroll
);
852 tui_scroll (BACKWARD_SCROLL
, winToScroll
, numToScroll
);
857 ** _tuiScrollLeft_command().
860 _tuiScrollLeft_command (char *arg
, int fromTTY
)
863 TuiWinInfoPtr winToScroll
;
865 /* Make sure the curses mode is enabled. */
867 _parseScrollingArgs (arg
, &winToScroll
, &numToScroll
);
868 tui_scroll (LEFT_SCROLL
, winToScroll
, numToScroll
);
873 ** _tuiScrollRight_command().
876 _tuiScrollRight_command (char *arg
, int fromTTY
)
879 TuiWinInfoPtr winToScroll
;
881 /* Make sure the curses mode is enabled. */
883 _parseScrollingArgs (arg
, &winToScroll
, &numToScroll
);
884 tui_scroll (RIGHT_SCROLL
, winToScroll
, numToScroll
);
890 ** Set focus to the window named by 'arg'
893 _tuiSetFocus (char *arg
, int fromTTY
)
895 if (arg
!= (char *) NULL
)
897 char *bufPtr
= (char *) xstrdup (arg
);
899 TuiWinInfoPtr winInfo
= (TuiWinInfoPtr
) NULL
;
901 for (i
= 0; (i
< strlen (bufPtr
)); i
++)
902 bufPtr
[i
] = toupper (arg
[i
]);
904 if (subset_compare (bufPtr
, "NEXT"))
905 winInfo
= tuiNextWin (tuiWinWithFocus ());
906 else if (subset_compare (bufPtr
, "PREV"))
907 winInfo
= tuiPrevWin (tuiWinWithFocus ());
909 winInfo
= partialWinByName (bufPtr
);
911 if (winInfo
== (TuiWinInfoPtr
) NULL
|| !winInfo
->generic
.isVisible
)
912 warning ("Invalid window specified. \n\
913 The window name specified must be valid and visible.\n");
916 tuiSetWinFocusTo (winInfo
);
917 keypad (cmdWin
->generic
.handle
, (winInfo
!= cmdWin
));
920 if (dataWin
&& dataWin
->generic
.isVisible
)
921 tuiRefreshDataWin ();
923 printf_filtered ("Focus set to %s window.\n",
924 winName ((TuiGenWinInfoPtr
) tuiWinWithFocus ()));
927 warning ("Incorrect Number of Arguments.\n%s", FOCUS_USAGE
);
933 ** _tuiSetFocus_command()
936 _tuiSetFocus_command (char *arg
, int fromTTY
)
938 /* Make sure the curses mode is enabled. */
940 _tuiSetFocus (arg
, fromTTY
);
945 ** _tuiAllWindowsInfo().
948 _tuiAllWindowsInfo (char *arg
, int fromTTY
)
951 TuiWinInfoPtr winWithFocus
= tuiWinWithFocus ();
953 for (type
= SRC_WIN
; (type
< MAX_MAJOR_WINDOWS
); type
++)
954 if (winList
[type
] && winList
[type
]->generic
.isVisible
)
956 if (winWithFocus
== winList
[type
])
957 printf_filtered (" %s\t(%d lines) <has focus>\n",
958 winName (&winList
[type
]->generic
),
959 winList
[type
]->generic
.height
);
961 printf_filtered (" %s\t(%d lines)\n",
962 winName (&winList
[type
]->generic
),
963 winList
[type
]->generic
.height
);
967 } /* _tuiAllWindowsInfo */
971 ** _tuiRefreshAll_command().
974 _tuiRefreshAll_command (char *arg
, int fromTTY
)
976 /* Make sure the curses mode is enabled. */
984 ** _tuiSetWinTabWidth_command().
985 ** Set the height of the specified window.
988 _tuiSetTabWidth_command (char *arg
, int fromTTY
)
990 /* Make sure the curses mode is enabled. */
992 if (arg
!= (char *) NULL
)
998 tuiSetDefaultTabLen (ts
);
1000 warning ("Tab widths greater than 0 must be specified.\n");
1004 } /* _tuiSetTabWidth_command */
1008 ** _tuiSetWinHeight().
1009 ** Set the height of the specified window.
1012 _tuiSetWinHeight (char *arg
, int fromTTY
)
1014 /* Make sure the curses mode is enabled. */
1016 if (arg
!= (char *) NULL
)
1018 char *buf
= xstrdup (arg
);
1020 char *wname
= (char *) NULL
;
1022 TuiWinInfoPtr winInfo
;
1025 bufPtr
= strchr (bufPtr
, ' ');
1026 if (bufPtr
!= (char *) NULL
)
1031 ** Validate the window name
1033 for (i
= 0; i
< strlen (wname
); i
++)
1034 wname
[i
] = toupper (wname
[i
]);
1035 winInfo
= partialWinByName (wname
);
1037 if (winInfo
== (TuiWinInfoPtr
) NULL
|| !winInfo
->generic
.isVisible
)
1038 warning ("Invalid window specified. \n\
1039 The window name specified must be valid and visible.\n");
1042 /* Process the size */
1043 while (*(++bufPtr
) == ' ')
1046 if (*bufPtr
!= (char) 0)
1049 int fixedSize
= TRUE
;
1052 if (*bufPtr
== '+' || *bufPtr
== '-')
1059 inputNo
= atoi (bufPtr
);
1065 newHeight
= inputNo
;
1067 newHeight
= winInfo
->generic
.height
+ inputNo
;
1069 ** Now change the window's height, and adjust all
1070 ** other windows around it
1072 if (_tuiAdjustWinHeights (winInfo
,
1073 newHeight
) == TUI_FAILURE
)
1074 warning ("Invalid window height specified.\n%s",
1077 tui_update_gdb_sizes ();
1080 warning ("Invalid window height specified.\n%s",
1086 printf_filtered (WIN_HEIGHT_USAGE
);
1088 if (buf
!= (char *) NULL
)
1092 printf_filtered (WIN_HEIGHT_USAGE
);
1095 } /* _tuiSetWinHeight */
1098 ** _tuiSetWinHeight_command().
1099 ** Set the height of the specified window, with va_list.
1102 _tuiSetWinHeight_command (char *arg
, int fromTTY
)
1104 /* Make sure the curses mode is enabled. */
1106 _tuiSetWinHeight (arg
, fromTTY
);
1111 ** _tuiXDBsetWinHeight().
1112 ** XDB Compatibility command for setting the window height. This will
1113 ** increase or decrease the command window by the specified amount.
1116 _tuiXDBsetWinHeight (char *arg
, int fromTTY
)
1118 /* Make sure the curses mode is enabled. */
1120 if (arg
!= (char *) NULL
)
1122 int inputNo
= atoi (arg
);
1125 { /* Add 1 for the locator */
1126 int newHeight
= termHeight () - (inputNo
+ 1);
1128 if (!_newHeightOk (winList
[CMD_WIN
], newHeight
) ||
1129 _tuiAdjustWinHeights (winList
[CMD_WIN
],
1130 newHeight
) == TUI_FAILURE
)
1131 warning ("Invalid window height specified.\n%s",
1132 XDBWIN_HEIGHT_USAGE
);
1135 warning ("Invalid window height specified.\n%s",
1136 XDBWIN_HEIGHT_USAGE
);
1139 warning ("Invalid window height specified.\n%s", XDBWIN_HEIGHT_USAGE
);
1142 } /* _tuiXDBsetWinHeight */
1145 ** _tuiSetWinHeight_command().
1146 ** Set the height of the specified window, with va_list.
1149 _tuiXDBsetWinHeight_command (char *arg
, int fromTTY
)
1151 _tuiXDBsetWinHeight (arg
, fromTTY
);
1156 ** _tuiAdjustWinHeights().
1157 ** Function to adjust all window heights around the primary
1160 _tuiAdjustWinHeights (TuiWinInfoPtr primaryWinInfo
, int newHeight
)
1162 TuiStatus status
= TUI_FAILURE
;
1164 if (_newHeightOk (primaryWinInfo
, newHeight
))
1166 status
= TUI_SUCCESS
;
1167 if (newHeight
!= primaryWinInfo
->generic
.height
)
1170 TuiWinInfoPtr winInfo
;
1171 TuiGenWinInfoPtr locator
= locatorWinInfoPtr ();
1172 TuiLayoutType curLayout
= currentLayout ();
1174 diff
= (newHeight
- primaryWinInfo
->generic
.height
) * (-1);
1175 if (curLayout
== SRC_COMMAND
|| curLayout
== DISASSEM_COMMAND
)
1177 TuiWinInfoPtr srcWinInfo
;
1179 _makeInvisibleAndSetNewHeight (primaryWinInfo
, newHeight
);
1180 if (primaryWinInfo
->generic
.type
== CMD_WIN
)
1182 winInfo
= (TuiWinInfoPtr
) (sourceWindows ())->list
[0];
1183 srcWinInfo
= winInfo
;
1187 winInfo
= winList
[CMD_WIN
];
1188 srcWinInfo
= primaryWinInfo
;
1190 _makeInvisibleAndSetNewHeight (winInfo
,
1191 winInfo
->generic
.height
+ diff
);
1192 cmdWin
->generic
.origin
.y
= locator
->origin
.y
+ 1;
1193 _makeVisibleWithNewHeight (winInfo
);
1194 _makeVisibleWithNewHeight (primaryWinInfo
);
1195 if (srcWinInfo
->generic
.contentSize
<= 0)
1196 tuiEraseSourceContent (srcWinInfo
, EMPTY_SOURCE_PROMPT
);
1200 TuiWinInfoPtr firstWin
, secondWin
;
1202 if (curLayout
== SRC_DISASSEM_COMMAND
)
1205 secondWin
= disassemWin
;
1210 secondWin
= (TuiWinInfoPtr
) (sourceWindows ())->list
[0];
1212 if (primaryWinInfo
== cmdWin
)
1214 ** Split the change in height accross the 1st & 2nd windows
1215 ** adjusting them as well.
1217 int firstSplitDiff
= diff
/ 2; /* subtract the locator */
1218 int secondSplitDiff
= firstSplitDiff
;
1222 if (firstWin
->generic
.height
>
1223 secondWin
->generic
.height
)
1236 /* make sure that the minimum hieghts are honored */
1237 while ((firstWin
->generic
.height
+ firstSplitDiff
) < 3)
1242 while ((secondWin
->generic
.height
+ secondSplitDiff
) < 3)
1247 _makeInvisibleAndSetNewHeight (
1249 firstWin
->generic
.height
+ firstSplitDiff
);
1250 secondWin
->generic
.origin
.y
= firstWin
->generic
.height
- 1;
1251 _makeInvisibleAndSetNewHeight (
1252 secondWin
, secondWin
->generic
.height
+ secondSplitDiff
);
1253 cmdWin
->generic
.origin
.y
= locator
->origin
.y
+ 1;
1254 _makeInvisibleAndSetNewHeight (cmdWin
, newHeight
);
1258 if ((cmdWin
->generic
.height
+ diff
) < 1)
1260 ** If there is no way to increase the command window
1261 ** take real estate from the 1st or 2nd window.
1263 if ((cmdWin
->generic
.height
+ diff
) < 1)
1266 for (i
= cmdWin
->generic
.height
+ diff
;
1268 if (primaryWinInfo
== firstWin
)
1269 secondWin
->generic
.height
--;
1271 firstWin
->generic
.height
--;
1274 if (primaryWinInfo
== firstWin
)
1275 _makeInvisibleAndSetNewHeight (firstWin
, newHeight
);
1277 _makeInvisibleAndSetNewHeight (
1279 firstWin
->generic
.height
);
1280 secondWin
->generic
.origin
.y
= firstWin
->generic
.height
- 1;
1281 if (primaryWinInfo
== secondWin
)
1282 _makeInvisibleAndSetNewHeight (secondWin
, newHeight
);
1284 _makeInvisibleAndSetNewHeight (
1285 secondWin
, secondWin
->generic
.height
);
1286 cmdWin
->generic
.origin
.y
= locator
->origin
.y
+ 1;
1287 if ((cmdWin
->generic
.height
+ diff
) < 1)
1288 _makeInvisibleAndSetNewHeight (cmdWin
, 1);
1290 _makeInvisibleAndSetNewHeight (
1291 cmdWin
, cmdWin
->generic
.height
+ diff
);
1293 _makeVisibleWithNewHeight (cmdWin
);
1294 _makeVisibleWithNewHeight (secondWin
);
1295 _makeVisibleWithNewHeight (firstWin
);
1296 if (firstWin
->generic
.contentSize
<= 0)
1297 tuiEraseSourceContent (firstWin
, EMPTY_SOURCE_PROMPT
);
1298 if (secondWin
->generic
.contentSize
<= 0)
1299 tuiEraseSourceContent (secondWin
, EMPTY_SOURCE_PROMPT
);
1305 } /* _tuiAdjustWinHeights */
1309 ** _makeInvisibleAndSetNewHeight().
1310 ** Function make the target window (and auxillary windows associated
1311 ** with the targer) invisible, and set the new height and location.
1314 _makeInvisibleAndSetNewHeight (TuiWinInfoPtr winInfo
, int height
)
1317 TuiGenWinInfoPtr genWinInfo
;
1320 m_beInvisible (&winInfo
->generic
);
1321 winInfo
->generic
.height
= height
;
1323 winInfo
->generic
.viewportHeight
= height
- 1;
1325 winInfo
->generic
.viewportHeight
= height
;
1326 if (winInfo
!= cmdWin
)
1327 winInfo
->generic
.viewportHeight
--;
1329 /* Now deal with the auxillary windows associated with winInfo */
1330 switch (winInfo
->generic
.type
)
1334 genWinInfo
= winInfo
->detail
.sourceInfo
.executionInfo
;
1335 m_beInvisible (genWinInfo
);
1336 genWinInfo
->height
= height
;
1337 genWinInfo
->origin
.y
= winInfo
->generic
.origin
.y
;
1339 genWinInfo
->viewportHeight
= height
- 1;
1341 genWinInfo
->viewportHeight
= height
;
1342 if (winInfo
!= cmdWin
)
1343 genWinInfo
->viewportHeight
--;
1345 if (m_hasLocator (winInfo
))
1347 genWinInfo
= locatorWinInfoPtr ();
1348 m_beInvisible (genWinInfo
);
1349 genWinInfo
->origin
.y
= winInfo
->generic
.origin
.y
+ height
;
1353 /* delete all data item windows */
1354 for (i
= 0; i
< winInfo
->generic
.contentSize
; i
++)
1356 genWinInfo
= (TuiGenWinInfoPtr
) & ((TuiWinElementPtr
)
1357 winInfo
->generic
.content
[i
])->whichElement
.dataWindow
;
1358 tuiDelwin (genWinInfo
->handle
);
1359 genWinInfo
->handle
= (WINDOW
*) NULL
;
1369 ** _makeVisibleWithNewHeight().
1370 ** Function to make the windows with new heights visible.
1371 ** This means re-creating the windows' content since the window
1372 ** had to be destroyed to be made invisible.
1375 _makeVisibleWithNewHeight (TuiWinInfoPtr winInfo
)
1379 m_beVisible (&winInfo
->generic
);
1380 checkAndDisplayHighlightIfNeeded (winInfo
);
1381 switch (winInfo
->generic
.type
)
1385 freeWinContent (winInfo
->detail
.sourceInfo
.executionInfo
);
1386 m_beVisible (winInfo
->detail
.sourceInfo
.executionInfo
);
1387 if (winInfo
->generic
.content
!= (OpaquePtr
) NULL
)
1389 TuiLineOrAddress lineOrAddr
;
1390 struct symtab_and_line cursal
1391 = get_current_source_symtab_and_line ();
1393 if (winInfo
->generic
.type
== SRC_WIN
)
1395 winInfo
->detail
.sourceInfo
.startLineOrAddr
.lineNo
;
1398 winInfo
->detail
.sourceInfo
.startLineOrAddr
.addr
;
1399 freeWinContent (&winInfo
->generic
);
1400 tuiUpdateSourceWindow (winInfo
,
1401 cursal
.symtab
, lineOrAddr
, TRUE
);
1403 else if (deprecated_selected_frame
!= (struct frame_info
*) NULL
)
1405 TuiLineOrAddress line
;
1406 struct symtab_and_line cursal
= get_current_source_symtab_and_line ();
1409 s
= find_pc_symtab (deprecated_selected_frame
->pc
);
1410 if (winInfo
->generic
.type
== SRC_WIN
)
1411 line
.lineNo
= cursal
.line
;
1414 find_line_pc (s
, cursal
.line
, &line
.addr
);
1416 tuiUpdateSourceWindow (winInfo
, s
, line
, TRUE
);
1418 if (m_hasLocator (winInfo
))
1420 m_beVisible (locatorWinInfoPtr ());
1421 tuiShowLocatorContent ();
1425 tuiDisplayAllData ();
1428 winInfo
->detail
.commandInfo
.curLine
= 0;
1429 winInfo
->detail
.commandInfo
.curch
= 0;
1430 wmove (winInfo
->generic
.handle
,
1431 winInfo
->detail
.commandInfo
.curLine
,
1432 winInfo
->detail
.commandInfo
.curch
);
1439 } /* _makeVisibleWithNewHeight */
1443 _newHeightOk (TuiWinInfoPtr primaryWinInfo
, int newHeight
)
1445 int ok
= (newHeight
< termHeight ());
1450 TuiLayoutType curLayout
= currentLayout ();
1452 diff
= (newHeight
- primaryWinInfo
->generic
.height
) * (-1);
1453 if (curLayout
== SRC_COMMAND
|| curLayout
== DISASSEM_COMMAND
)
1455 ok
= ((primaryWinInfo
->generic
.type
== CMD_WIN
&&
1456 newHeight
<= (termHeight () - 4) &&
1457 newHeight
>= MIN_CMD_WIN_HEIGHT
) ||
1458 (primaryWinInfo
->generic
.type
!= CMD_WIN
&&
1459 newHeight
<= (termHeight () - 2) &&
1460 newHeight
>= MIN_WIN_HEIGHT
));
1462 { /* check the total height */
1463 TuiWinInfoPtr winInfo
;
1465 if (primaryWinInfo
== cmdWin
)
1466 winInfo
= (TuiWinInfoPtr
) (sourceWindows ())->list
[0];
1470 (winInfo
->generic
.height
+ diff
)) <= termHeight ());
1475 int curTotalHeight
, totalHeight
, minHeight
= 0;
1476 TuiWinInfoPtr firstWin
, secondWin
;
1478 if (curLayout
== SRC_DISASSEM_COMMAND
)
1481 secondWin
= disassemWin
;
1486 secondWin
= (TuiWinInfoPtr
) (sourceWindows ())->list
[0];
1489 ** We could simply add all the heights to obtain the same result
1490 ** but below is more explicit since we subtract 1 for the
1491 ** line that the first and second windows share, and add one
1494 totalHeight
= curTotalHeight
=
1495 (firstWin
->generic
.height
+ secondWin
->generic
.height
- 1)
1496 + cmdWin
->generic
.height
+ 1 /*locator */ ;
1497 if (primaryWinInfo
== cmdWin
)
1499 /* locator included since first & second win share a line */
1500 ok
= ((firstWin
->generic
.height
+
1501 secondWin
->generic
.height
+ diff
) >=
1502 (MIN_WIN_HEIGHT
* 2) &&
1503 newHeight
>= MIN_CMD_WIN_HEIGHT
);
1506 totalHeight
= newHeight
+ (firstWin
->generic
.height
+
1507 secondWin
->generic
.height
+ diff
);
1508 minHeight
= MIN_CMD_WIN_HEIGHT
;
1513 minHeight
= MIN_WIN_HEIGHT
;
1515 ** First see if we can increase/decrease the command
1516 ** window. And make sure that the command window is
1519 ok
= ((cmdWin
->generic
.height
+ diff
) > 0);
1522 ** Looks like we have to increase/decrease one of
1523 ** the other windows
1525 if (primaryWinInfo
== firstWin
)
1526 ok
= (secondWin
->generic
.height
+ diff
) >= minHeight
;
1528 ok
= (firstWin
->generic
.height
+ diff
) >= minHeight
;
1532 if (primaryWinInfo
== firstWin
)
1533 totalHeight
= newHeight
+
1534 secondWin
->generic
.height
+
1535 cmdWin
->generic
.height
+ diff
;
1537 totalHeight
= newHeight
+
1538 firstWin
->generic
.height
+
1539 cmdWin
->generic
.height
+ diff
;
1543 ** Now make sure that the proposed total height doesn't exceed
1544 ** the old total height.
1547 ok
= (newHeight
>= minHeight
&& totalHeight
<= curTotalHeight
);
1552 } /* _newHeightOk */
1556 ** _parseScrollingArgs().
1559 _parseScrollingArgs (char *arg
, TuiWinInfoPtr
* winToScroll
, int *numToScroll
)
1563 *winToScroll
= tuiWinWithFocus ();
1566 ** First set up the default window to scroll, in case there is no
1569 if (arg
!= (char *) NULL
)
1573 /* process the number of lines to scroll */
1574 buf
= bufPtr
= xstrdup (arg
);
1575 if (isdigit (*bufPtr
))
1580 bufPtr
= strchr (bufPtr
, ' ');
1581 if (bufPtr
!= (char *) NULL
)
1585 *numToScroll
= atoi (numStr
);
1588 else if (numToScroll
)
1589 *numToScroll
= atoi (numStr
);
1592 /* process the window name if one is specified */
1593 if (bufPtr
!= (char *) NULL
)
1599 while (*(++bufPtr
) == ' ')
1602 if (*bufPtr
!= (char) 0)
1607 /* Validate the window name */
1608 for (i
= 0; i
< strlen (wname
); i
++)
1609 wname
[i
] = toupper (wname
[i
]);
1610 *winToScroll
= partialWinByName (wname
);
1612 if (*winToScroll
== (TuiWinInfoPtr
) NULL
||
1613 !(*winToScroll
)->generic
.isVisible
)
1614 warning ("Invalid window specified. \n\
1615 The window name specified must be valid and visible.\n");
1616 else if (*winToScroll
== cmdWin
)
1617 *winToScroll
= (TuiWinInfoPtr
) (sourceWindows ())->list
[0];
1623 } /* _parseScrollingArgs */