1 /* TUI window generic functions.
3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
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 */
33 #include "breakpoint.h"
35 #include "cli/cli-cmds.h"
40 #include "tui/tui-data.h"
41 #include "tui/tui-wingeneral.h"
42 #include "tui/tui-stack.h"
43 #include "tui/tui-regs.h"
44 #include "tui/tui-disasm.h"
45 #include "tui/tui-source.h"
46 #include "tui/tui-winsource.h"
47 #include "tui/tui-windata.h"
59 #include <readline/readline.h>
61 /*******************************
63 ********************************/
64 static void _makeVisibleWithNewHeight (struct tui_win_info
*);
65 static void _makeInvisibleAndSetNewHeight (struct tui_win_info
*, int);
66 static enum tui_status
_tuiAdjustWinHeights (struct tui_win_info
*, int);
67 static int _newHeightOk (struct tui_win_info
*, int);
68 static void _tuiSetTabWidth_command (char *, int);
69 static void _tuiRefreshAll_command (char *, int);
70 static void _tuiSetWinHeight_command (char *, int);
71 static void _tuiXDBsetWinHeight_command (char *, int);
72 static void _tuiAllWindowsInfo (char *, int);
73 static void _tuiSetFocus_command (char *, int);
74 static void _tuiScrollForward_command (char *, int);
75 static void _tuiScrollBackward_command (char *, int);
76 static void _tuiScrollLeft_command (char *, int);
77 static void _tuiScrollRight_command (char *, int);
78 static void _parseScrollingArgs (char *, struct tui_win_info
* *, int *);
81 /***************************************
83 ***************************************/
84 #define WIN_HEIGHT_USAGE "Usage: winheight <win_name> [+ | -] <#lines>\n"
85 #define XDBWIN_HEIGHT_USAGE "Usage: w <#lines>\n"
86 #define FOCUS_USAGE "Usage: focus {<win> | next | prev}\n"
88 /***************************************
90 ***************************************/
93 # define ACS_LRCORNER '+'
96 # define ACS_LLCORNER '+'
99 # define ACS_ULCORNER '+'
102 # define ACS_URCORNER '+'
105 # define ACS_HLINE '-'
108 # define ACS_VLINE '|'
111 /* Possible values for tui-border-kind variable. */
112 static const char *tui_border_kind_enums
[] = {
119 /* Possible values for tui-border-mode and tui-active-border-mode. */
120 static const char *tui_border_mode_enums
[] = {
137 /* Translation table for border-mode variables.
138 The list of values must be terminated by a NULL.
139 After the NULL value, an entry defines the default. */
140 struct tui_translate tui_border_mode_translate
[] = {
141 { "normal", A_NORMAL
},
142 { "standout", A_STANDOUT
},
143 { "reverse", A_REVERSE
},
145 { "half-standout", A_DIM
| A_STANDOUT
},
147 { "bold-standout", A_BOLD
| A_STANDOUT
},
149 { "normal", A_NORMAL
}
152 /* Translation tables for border-kind, one for each border
153 character (see wborder, border curses operations).
154 -1 is used to indicate the ACS because ACS characters
155 are determined at run time by curses (depends on terminal). */
156 struct tui_translate tui_border_kind_translate_vline
[] = {
164 struct tui_translate tui_border_kind_translate_hline
[] = {
172 struct tui_translate tui_border_kind_translate_ulcorner
[] = {
180 struct tui_translate tui_border_kind_translate_urcorner
[] = {
188 struct tui_translate tui_border_kind_translate_llcorner
[] = {
196 struct tui_translate tui_border_kind_translate_lrcorner
[] = {
205 /* Tui configuration variables controlled with set/show command. */
206 const char *tui_active_border_mode
= "bold-standout";
207 const char *tui_border_mode
= "normal";
208 const char *tui_border_kind
= "acs";
210 /* Tui internal configuration variables. These variables are
211 updated by tui_update_variables to reflect the tui configuration
213 chtype tui_border_vline
;
214 chtype tui_border_hline
;
215 chtype tui_border_ulcorner
;
216 chtype tui_border_urcorner
;
217 chtype tui_border_llcorner
;
218 chtype tui_border_lrcorner
;
220 int tui_border_attrs
;
221 int tui_active_border_attrs
;
223 /* Identify the item in the translation table.
224 When the item is not recognized, use the default entry. */
225 static struct tui_translate
*
226 translate (const char *name
, struct tui_translate
*table
)
230 if (name
&& strcmp (table
->name
, name
) == 0)
235 /* Not found, return default entry. */
240 /* Update the tui internal configuration according to gdb settings.
241 Returns 1 if the configuration has changed and the screen should
244 tui_update_variables ()
247 struct tui_translate
*entry
;
249 entry
= translate (tui_border_mode
, tui_border_mode_translate
);
250 if (tui_border_attrs
!= entry
->value
)
252 tui_border_attrs
= entry
->value
;
255 entry
= translate (tui_active_border_mode
, tui_border_mode_translate
);
256 if (tui_active_border_attrs
!= entry
->value
)
258 tui_active_border_attrs
= entry
->value
;
262 /* If one corner changes, all characters are changed.
263 Only check the first one. The ACS characters are determined at
264 run time by curses terminal management. */
265 entry
= translate (tui_border_kind
, tui_border_kind_translate_lrcorner
);
266 if (tui_border_lrcorner
!= (chtype
) entry
->value
)
268 tui_border_lrcorner
= (entry
->value
< 0) ? ACS_LRCORNER
: entry
->value
;
271 entry
= translate (tui_border_kind
, tui_border_kind_translate_llcorner
);
272 tui_border_llcorner
= (entry
->value
< 0) ? ACS_LLCORNER
: entry
->value
;
274 entry
= translate (tui_border_kind
, tui_border_kind_translate_ulcorner
);
275 tui_border_ulcorner
= (entry
->value
< 0) ? ACS_ULCORNER
: entry
->value
;
277 entry
= translate (tui_border_kind
, tui_border_kind_translate_urcorner
);
278 tui_border_urcorner
= (entry
->value
< 0) ? ACS_URCORNER
: entry
->value
;
280 entry
= translate (tui_border_kind
, tui_border_kind_translate_hline
);
281 tui_border_hline
= (entry
->value
< 0) ? ACS_HLINE
: entry
->value
;
283 entry
= translate (tui_border_kind
, tui_border_kind_translate_vline
);
284 tui_border_vline
= (entry
->value
< 0) ? ACS_VLINE
: entry
->value
;
290 set_tui_cmd (char *args
, int from_tty
)
295 show_tui_cmd (char *args
, int from_tty
)
300 ** _initialize_tuiWin().
301 ** Function to initialize gdb commands, for tui window manipulation.
304 _initialize_tuiWin (void)
306 struct cmd_list_element
*c
;
307 static struct cmd_list_element
*tui_setlist
;
308 static struct cmd_list_element
*tui_showlist
;
310 /* Define the classes of commands.
311 They will appear in the help list in the reverse of this order. */
312 add_cmd ("tui", class_tui
, NULL
,
313 "Text User Interface commands.",
316 add_prefix_cmd ("tui", class_tui
, set_tui_cmd
,
317 "TUI configuration variables",
318 &tui_setlist
, "set tui ",
319 0/*allow-unknown*/, &setlist
);
320 add_prefix_cmd ("tui", class_tui
, show_tui_cmd
,
321 "TUI configuration variables",
322 &tui_showlist
, "show tui ",
323 0/*allow-unknown*/, &showlist
);
325 add_com ("refresh", class_tui
, _tuiRefreshAll_command
,
326 "Refresh the terminal display.\n");
328 add_com_alias ("U", "refresh", class_tui
, 0);
329 add_com ("tabset", class_tui
, _tuiSetTabWidth_command
,
330 "Set the width (in characters) of tab stops.\n\
331 Usage: tabset <n>\n");
332 add_com ("winheight", class_tui
, _tuiSetWinHeight_command
,
333 "Set the height of a specified window.\n\
334 Usage: winheight <win_name> [+ | -] <#lines>\n\
336 src : the source window\n\
337 cmd : the command window\n\
338 asm : the disassembly window\n\
339 regs : the register display\n");
340 add_com_alias ("wh", "winheight", class_tui
, 0);
341 add_info ("win", _tuiAllWindowsInfo
,
342 "List of all displayed windows.\n");
343 add_com ("focus", class_tui
, _tuiSetFocus_command
,
344 "Set focus to named window or next/prev window.\n\
345 Usage: focus {<win> | next | prev}\n\
346 Valid Window names are:\n\
347 src : the source window\n\
348 asm : the disassembly window\n\
349 regs : the register display\n\
350 cmd : the command window\n");
351 add_com_alias ("fs", "focus", class_tui
, 0);
352 add_com ("+", class_tui
, _tuiScrollForward_command
,
353 "Scroll window forward.\nUsage: + [win] [n]\n");
354 add_com ("-", class_tui
, _tuiScrollBackward_command
,
355 "Scroll window backward.\nUsage: - [win] [n]\n");
356 add_com ("<", class_tui
, _tuiScrollLeft_command
,
357 "Scroll window forward.\nUsage: < [win] [n]\n");
358 add_com (">", class_tui
, _tuiScrollRight_command
,
359 "Scroll window backward.\nUsage: > [win] [n]\n");
361 add_com ("w", class_xdb
, _tuiXDBsetWinHeight_command
,
362 "XDB compatibility command for setting the height of a command window.\n\
363 Usage: w <#lines>\n");
365 /* Define the tui control variables. */
367 ("border-kind", no_class
,
368 tui_border_kind_enums
, &tui_border_kind
,
369 "Set the kind of border for TUI windows.\n"
370 "This variable controls the border of TUI windows:\n"
371 "space use a white space\n"
372 "ascii use ascii characters + - | for the border\n"
373 "acs use the Alternate Character Set\n",
375 add_show_from_set (c
, &tui_showlist
);
378 ("border-mode", no_class
,
379 tui_border_mode_enums
, &tui_border_mode
,
380 "Set the attribute mode to use for the TUI window borders.\n"
381 "This variable controls the attributes to use for the window borders:\n"
382 "normal normal display\n"
383 "standout use highlight mode of terminal\n"
384 "reverse use reverse video mode\n"
385 "half use half bright\n"
386 "half-standout use half bright and standout mode\n"
387 "bold use extra bright or bold\n"
388 "bold-standout use extra bright or bold with standout mode\n",
390 add_show_from_set (c
, &tui_showlist
);
393 ("active-border-mode", no_class
,
394 tui_border_mode_enums
, &tui_active_border_mode
,
395 "Set the attribute mode to use for the active TUI window border.\n"
396 "This variable controls the attributes to use for the active window border:\n"
397 "normal normal display\n"
398 "standout use highlight mode of terminal\n"
399 "reverse use reverse video mode\n"
400 "half use half bright\n"
401 "half-standout use half bright and standout mode\n"
402 "bold use extra bright or bold\n"
403 "bold-standout use extra bright or bold with standout mode\n",
405 add_show_from_set (c
, &tui_showlist
);
408 /* Update gdb's knowledge of the terminal size. */
410 tui_update_gdb_sizes ()
413 int screenheight
, screenwidth
;
415 rl_get_screen_size (&screenheight
, &screenwidth
);
416 /* Set to TUI command window dimension or use readline values. */
417 sprintf (cmd
, "set width %d",
418 tui_active
? cmdWin
->generic
.width
: screenwidth
);
419 execute_command (cmd
, 0);
420 sprintf (cmd
, "set height %d",
421 tui_active
? cmdWin
->generic
.height
: screenheight
);
422 execute_command (cmd
, 0);
426 /* Set the logical focus to winInfo. */
428 tui_set_win_focus_to (struct tui_win_info
* winInfo
)
430 if (m_winPtrNotNull (winInfo
))
432 struct tui_win_info
* winWithFocus
= tui_win_with_focus ();
434 if (m_winPtrNotNull (winWithFocus
) &&
435 winWithFocus
->generic
.type
!= CMD_WIN
)
436 tui_unhighlight_win (winWithFocus
);
437 tui_set_win_with_focus (winInfo
);
438 if (winInfo
->generic
.type
!= CMD_WIN
)
439 tui_highlight_win (winInfo
);
443 } /* tuiSetWinFocusTo */
447 tui_scroll_forward (struct tui_win_info
* winToScroll
, int numToScroll
)
449 if (winToScroll
!= cmdWin
)
451 int _numToScroll
= numToScroll
;
453 if (numToScroll
== 0)
454 _numToScroll
= winToScroll
->generic
.height
- 3;
456 ** If we are scrolling the source or disassembly window, do a
457 ** "psuedo" scroll since not all of the source is in memory,
458 ** only what is in the viewport. If winToScroll is the
459 ** command window do nothing since the term should handle it.
461 if (winToScroll
== srcWin
)
462 tui_vertical_source_scroll (FORWARD_SCROLL
, _numToScroll
);
463 else if (winToScroll
== disassemWin
)
464 tui_vertical_disassem_scroll (FORWARD_SCROLL
, _numToScroll
);
465 else if (winToScroll
== dataWin
)
466 tui_vertical_data_scroll (FORWARD_SCROLL
, _numToScroll
);
471 tui_scroll_backward (struct tui_win_info
* winToScroll
, int numToScroll
)
473 if (winToScroll
!= cmdWin
)
475 int _numToScroll
= numToScroll
;
477 if (numToScroll
== 0)
478 _numToScroll
= winToScroll
->generic
.height
- 3;
480 ** If we are scrolling the source or disassembly window, do a
481 ** "psuedo" scroll since not all of the source is in memory,
482 ** only what is in the viewport. If winToScroll is the
483 ** command window do nothing since the term should handle it.
485 if (winToScroll
== srcWin
)
486 tui_vertical_source_scroll (BACKWARD_SCROLL
, _numToScroll
);
487 else if (winToScroll
== disassemWin
)
488 tui_vertical_disassem_scroll (BACKWARD_SCROLL
, _numToScroll
);
489 else if (winToScroll
== dataWin
)
490 tui_vertical_data_scroll (BACKWARD_SCROLL
, _numToScroll
);
496 tui_scroll_left (struct tui_win_info
* winToScroll
, int numToScroll
)
498 if (winToScroll
!= cmdWin
)
500 int _numToScroll
= numToScroll
;
502 if (_numToScroll
== 0)
505 ** If we are scrolling the source or disassembly window, do a
506 ** "psuedo" scroll since not all of the source is in memory,
507 ** only what is in the viewport. If winToScroll is the
508 ** command window do nothing since the term should handle it.
510 if (winToScroll
== srcWin
|| winToScroll
== disassemWin
)
511 tui_horizontal_source_scroll (winToScroll
, LEFT_SCROLL
, _numToScroll
);
517 tui_scroll_right (struct tui_win_info
* winToScroll
, int numToScroll
)
519 if (winToScroll
!= cmdWin
)
521 int _numToScroll
= numToScroll
;
523 if (_numToScroll
== 0)
526 ** If we are scrolling the source or disassembly window, do a
527 ** "psuedo" scroll since not all of the source is in memory,
528 ** only what is in the viewport. If winToScroll is the
529 ** command window do nothing since the term should handle it.
531 if (winToScroll
== srcWin
|| winToScroll
== disassemWin
)
532 tui_horizontal_source_scroll (winToScroll
, RIGHT_SCROLL
, _numToScroll
);
537 /* Scroll a window. Arguments are passed through a va_list. */
539 tui_scroll (enum tui_scroll_direction direction
,
540 struct tui_win_info
* winToScroll
,
546 tui_scroll_forward (winToScroll
, numToScroll
);
548 case BACKWARD_SCROLL
:
549 tui_scroll_backward (winToScroll
, numToScroll
);
552 tui_scroll_left (winToScroll
, numToScroll
);
555 tui_scroll_right (winToScroll
, numToScroll
);
564 tui_refresh_all_win (void)
566 enum tui_win_type type
;
568 clearok (curscr
, TRUE
);
569 tui_refresh_all (winList
);
570 for (type
= SRC_WIN
; type
< MAX_MAJOR_WINDOWS
; type
++)
572 if (winList
[type
] && winList
[type
]->generic
.isVisible
)
578 tui_show_source_content (winList
[type
]);
579 tui_check_and_display_highlight_if_needed (winList
[type
]);
580 tui_erase_exec_info_content (winList
[type
]);
581 tui_update_exec_info (winList
[type
]);
584 tui_refresh_data_win ();
591 tui_show_locator_content ();
597 ** Resize all the windows based on the the terminal size. This
598 ** function gets called from within the readline sinwinch handler.
603 int heightDiff
, widthDiff
;
604 int screenheight
, screenwidth
;
606 rl_get_screen_size (&screenheight
, &screenwidth
);
607 widthDiff
= screenwidth
- tui_term_width ();
608 heightDiff
= screenheight
- tui_term_height ();
609 if (heightDiff
|| widthDiff
)
611 enum tui_layout_type curLayout
= tui_current_layout ();
612 struct tui_win_info
* winWithFocus
= tui_win_with_focus ();
613 struct tui_win_info
*firstWin
;
614 struct tui_win_info
*secondWin
;
615 struct tui_gen_win_info
* locator
= tui_locator_win_info_ptr ();
616 enum tui_win_type winType
;
617 int newHeight
, splitDiff
, cmdSplitDiff
, numWinsDisplayed
= 2;
619 /* turn keypad off while we resize */
620 if (winWithFocus
!= cmdWin
)
621 keypad (cmdWin
->generic
.handle
, FALSE
);
622 tui_update_gdb_sizes ();
623 tui_set_term_height_to (screenheight
);
624 tui_set_term_width_to (screenwidth
);
625 if (curLayout
== SRC_DISASSEM_COMMAND
||
626 curLayout
== SRC_DATA_COMMAND
|| curLayout
== DISASSEM_DATA_COMMAND
)
628 splitDiff
= heightDiff
/ numWinsDisplayed
;
629 cmdSplitDiff
= splitDiff
;
630 if (heightDiff
% numWinsDisplayed
)
637 /* now adjust each window */
643 case DISASSEM_COMMAND
:
644 firstWin
= (struct tui_win_info
*) (tui_source_windows ())->list
[0];
645 firstWin
->generic
.width
+= widthDiff
;
646 locator
->width
+= widthDiff
;
647 /* check for invalid heights */
649 newHeight
= firstWin
->generic
.height
;
650 else if ((firstWin
->generic
.height
+ splitDiff
) >=
651 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
652 newHeight
= screenheight
- MIN_CMD_WIN_HEIGHT
- 1;
653 else if ((firstWin
->generic
.height
+ splitDiff
) <= 0)
654 newHeight
= MIN_WIN_HEIGHT
;
656 newHeight
= firstWin
->generic
.height
+ splitDiff
;
658 _makeInvisibleAndSetNewHeight (firstWin
, newHeight
);
659 cmdWin
->generic
.origin
.y
= locator
->origin
.y
+ 1;
660 cmdWin
->generic
.width
+= widthDiff
;
661 newHeight
= screenheight
- cmdWin
->generic
.origin
.y
;
662 _makeInvisibleAndSetNewHeight (cmdWin
, newHeight
);
663 _makeVisibleWithNewHeight (firstWin
);
664 _makeVisibleWithNewHeight (cmdWin
);
665 if (firstWin
->generic
.contentSize
<= 0)
666 tui_erase_source_content (firstWin
, EMPTY_SOURCE_PROMPT
);
669 if (curLayout
== SRC_DISASSEM_COMMAND
)
672 firstWin
->generic
.width
+= widthDiff
;
673 secondWin
= disassemWin
;
674 secondWin
->generic
.width
+= widthDiff
;
679 firstWin
->generic
.width
+= widthDiff
;
680 secondWin
= (struct tui_win_info
*) (tui_source_windows ())->list
[0];
681 secondWin
->generic
.width
+= widthDiff
;
683 /* Change the first window's height/width */
684 /* check for invalid heights */
686 newHeight
= firstWin
->generic
.height
;
687 else if ((firstWin
->generic
.height
+
688 secondWin
->generic
.height
+ (splitDiff
* 2)) >=
689 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
690 newHeight
= (screenheight
- MIN_CMD_WIN_HEIGHT
- 1) / 2;
691 else if ((firstWin
->generic
.height
+ splitDiff
) <= 0)
692 newHeight
= MIN_WIN_HEIGHT
;
694 newHeight
= firstWin
->generic
.height
+ splitDiff
;
695 _makeInvisibleAndSetNewHeight (firstWin
, newHeight
);
697 if (firstWin
== dataWin
&& widthDiff
!= 0)
698 firstWin
->detail
.dataDisplayInfo
.regsColumnCount
=
699 tui_calculate_regs_column_count (
700 firstWin
->detail
.dataDisplayInfo
.regsDisplayType
);
701 locator
->width
+= widthDiff
;
703 /* Change the second window's height/width */
704 /* check for invalid heights */
706 newHeight
= secondWin
->generic
.height
;
707 else if ((firstWin
->generic
.height
+
708 secondWin
->generic
.height
+ (splitDiff
* 2)) >=
709 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
711 newHeight
= screenheight
- MIN_CMD_WIN_HEIGHT
- 1;
713 newHeight
= (newHeight
/ 2) + 1;
717 else if ((secondWin
->generic
.height
+ splitDiff
) <= 0)
718 newHeight
= MIN_WIN_HEIGHT
;
720 newHeight
= secondWin
->generic
.height
+ splitDiff
;
721 secondWin
->generic
.origin
.y
= firstWin
->generic
.height
- 1;
722 _makeInvisibleAndSetNewHeight (secondWin
, newHeight
);
724 /* Change the command window's height/width */
725 cmdWin
->generic
.origin
.y
= locator
->origin
.y
+ 1;
726 _makeInvisibleAndSetNewHeight (
727 cmdWin
, cmdWin
->generic
.height
+ cmdSplitDiff
);
728 _makeVisibleWithNewHeight (firstWin
);
729 _makeVisibleWithNewHeight (secondWin
);
730 _makeVisibleWithNewHeight (cmdWin
);
731 if (firstWin
->generic
.contentSize
<= 0)
732 tui_erase_source_content (firstWin
, EMPTY_SOURCE_PROMPT
);
733 if (secondWin
->generic
.contentSize
<= 0)
734 tui_erase_source_content (secondWin
, EMPTY_SOURCE_PROMPT
);
738 ** Now remove all invisible windows, and their content so that they get
739 ** created again when called for with the new size
741 for (winType
= SRC_WIN
; (winType
< MAX_MAJOR_WINDOWS
); winType
++)
743 if (winType
!= CMD_WIN
&& m_winPtrNotNull (winList
[winType
]) &&
744 !winList
[winType
]->generic
.isVisible
)
746 tui_free_window (winList
[winType
]);
747 winList
[winType
] = (struct tui_win_info
*) NULL
;
750 tui_set_win_resized_to (TRUE
);
751 /* turn keypad back on, unless focus is in the command window */
752 if (winWithFocus
!= cmdWin
)
753 keypad (cmdWin
->generic
.handle
, TRUE
);
760 ** tuiSigwinchHandler()
761 ** SIGWINCH signal handler for the tui. This signal handler is
762 ** always called, even when the readline package clears signals
763 ** because it is set as the old_sigwinch() (TUI only)
766 tuiSigwinchHandler (int signal
)
769 ** Say that a resize was done so that the readline can do it
770 ** later when appropriate.
772 tui_set_win_resized_to (TRUE
);
775 } /* tuiSigwinchHandler */
779 /*************************
780 ** STATIC LOCAL FUNCTIONS
781 **************************/
785 ** _tuiScrollForward_command().
788 _tuiScrollForward_command (char *arg
, int fromTTY
)
791 struct tui_win_info
* winToScroll
;
793 /* Make sure the curses mode is enabled. */
795 if (arg
== (char *) NULL
)
796 _parseScrollingArgs (arg
, &winToScroll
, (int *) NULL
);
798 _parseScrollingArgs (arg
, &winToScroll
, &numToScroll
);
799 tui_scroll (FORWARD_SCROLL
, winToScroll
, numToScroll
);
804 ** _tuiScrollBackward_command().
807 _tuiScrollBackward_command (char *arg
, int fromTTY
)
810 struct tui_win_info
* winToScroll
;
812 /* Make sure the curses mode is enabled. */
814 if (arg
== (char *) NULL
)
815 _parseScrollingArgs (arg
, &winToScroll
, (int *) NULL
);
817 _parseScrollingArgs (arg
, &winToScroll
, &numToScroll
);
818 tui_scroll (BACKWARD_SCROLL
, winToScroll
, numToScroll
);
823 ** _tuiScrollLeft_command().
826 _tuiScrollLeft_command (char *arg
, int fromTTY
)
829 struct tui_win_info
* winToScroll
;
831 /* Make sure the curses mode is enabled. */
833 _parseScrollingArgs (arg
, &winToScroll
, &numToScroll
);
834 tui_scroll (LEFT_SCROLL
, winToScroll
, numToScroll
);
839 ** _tuiScrollRight_command().
842 _tuiScrollRight_command (char *arg
, int fromTTY
)
845 struct tui_win_info
* winToScroll
;
847 /* Make sure the curses mode is enabled. */
849 _parseScrollingArgs (arg
, &winToScroll
, &numToScroll
);
850 tui_scroll (RIGHT_SCROLL
, winToScroll
, numToScroll
);
856 ** Set focus to the window named by 'arg'
859 _tuiSetFocus (char *arg
, int fromTTY
)
861 if (arg
!= (char *) NULL
)
863 char *bufPtr
= (char *) xstrdup (arg
);
865 struct tui_win_info
* winInfo
= (struct tui_win_info
*) NULL
;
867 for (i
= 0; (i
< strlen (bufPtr
)); i
++)
868 bufPtr
[i
] = toupper (arg
[i
]);
870 if (subset_compare (bufPtr
, "NEXT"))
871 winInfo
= tui_next_win (tui_win_with_focus ());
872 else if (subset_compare (bufPtr
, "PREV"))
873 winInfo
= tui_prev_win (tui_win_with_focus ());
875 winInfo
= tui_partial_win_by_name (bufPtr
);
877 if (winInfo
== (struct tui_win_info
*) NULL
|| !winInfo
->generic
.isVisible
)
878 warning ("Invalid window specified. \n\
879 The window name specified must be valid and visible.\n");
882 tui_set_win_focus_to (winInfo
);
883 keypad (cmdWin
->generic
.handle
, (winInfo
!= cmdWin
));
886 if (dataWin
&& dataWin
->generic
.isVisible
)
887 tui_refresh_data_win ();
889 printf_filtered ("Focus set to %s window.\n",
890 tui_win_name ((struct tui_gen_win_info
*) tui_win_with_focus ()));
893 warning ("Incorrect Number of Arguments.\n%s", FOCUS_USAGE
);
899 ** _tuiSetFocus_command()
902 _tuiSetFocus_command (char *arg
, int fromTTY
)
904 /* Make sure the curses mode is enabled. */
906 _tuiSetFocus (arg
, fromTTY
);
911 ** _tuiAllWindowsInfo().
914 _tuiAllWindowsInfo (char *arg
, int fromTTY
)
916 enum tui_win_type type
;
917 struct tui_win_info
* winWithFocus
= tui_win_with_focus ();
919 for (type
= SRC_WIN
; (type
< MAX_MAJOR_WINDOWS
); type
++)
920 if (winList
[type
] && winList
[type
]->generic
.isVisible
)
922 if (winWithFocus
== winList
[type
])
923 printf_filtered (" %s\t(%d lines) <has focus>\n",
924 tui_win_name (&winList
[type
]->generic
),
925 winList
[type
]->generic
.height
);
927 printf_filtered (" %s\t(%d lines)\n",
928 tui_win_name (&winList
[type
]->generic
),
929 winList
[type
]->generic
.height
);
933 } /* _tuiAllWindowsInfo */
937 ** _tuiRefreshAll_command().
940 _tuiRefreshAll_command (char *arg
, int fromTTY
)
942 /* Make sure the curses mode is enabled. */
945 tui_refresh_all_win ();
950 ** _tuiSetWinTabWidth_command().
951 ** Set the height of the specified window.
954 _tuiSetTabWidth_command (char *arg
, int fromTTY
)
956 /* Make sure the curses mode is enabled. */
958 if (arg
!= (char *) NULL
)
964 tui_set_default_tab_len (ts
);
966 warning ("Tab widths greater than 0 must be specified.\n");
970 } /* _tuiSetTabWidth_command */
974 ** _tuiSetWinHeight().
975 ** Set the height of the specified window.
978 _tuiSetWinHeight (char *arg
, int fromTTY
)
980 /* Make sure the curses mode is enabled. */
982 if (arg
!= (char *) NULL
)
984 char *buf
= xstrdup (arg
);
986 char *wname
= (char *) NULL
;
988 struct tui_win_info
* winInfo
;
991 bufPtr
= strchr (bufPtr
, ' ');
992 if (bufPtr
!= (char *) NULL
)
997 ** Validate the window name
999 for (i
= 0; i
< strlen (wname
); i
++)
1000 wname
[i
] = toupper (wname
[i
]);
1001 winInfo
= tui_partial_win_by_name (wname
);
1003 if (winInfo
== (struct tui_win_info
*) NULL
|| !winInfo
->generic
.isVisible
)
1004 warning ("Invalid window specified. \n\
1005 The window name specified must be valid and visible.\n");
1008 /* Process the size */
1009 while (*(++bufPtr
) == ' ')
1012 if (*bufPtr
!= (char) 0)
1015 int fixedSize
= TRUE
;
1018 if (*bufPtr
== '+' || *bufPtr
== '-')
1025 inputNo
= atoi (bufPtr
);
1031 newHeight
= inputNo
;
1033 newHeight
= winInfo
->generic
.height
+ inputNo
;
1035 ** Now change the window's height, and adjust all
1036 ** other windows around it
1038 if (_tuiAdjustWinHeights (winInfo
,
1039 newHeight
) == TUI_FAILURE
)
1040 warning ("Invalid window height specified.\n%s",
1043 tui_update_gdb_sizes ();
1046 warning ("Invalid window height specified.\n%s",
1052 printf_filtered (WIN_HEIGHT_USAGE
);
1054 if (buf
!= (char *) NULL
)
1058 printf_filtered (WIN_HEIGHT_USAGE
);
1061 } /* _tuiSetWinHeight */
1064 ** _tuiSetWinHeight_command().
1065 ** Set the height of the specified window, with va_list.
1068 _tuiSetWinHeight_command (char *arg
, int fromTTY
)
1070 /* Make sure the curses mode is enabled. */
1072 _tuiSetWinHeight (arg
, fromTTY
);
1077 ** _tuiXDBsetWinHeight().
1078 ** XDB Compatibility command for setting the window height. This will
1079 ** increase or decrease the command window by the specified amount.
1082 _tuiXDBsetWinHeight (char *arg
, int fromTTY
)
1084 /* Make sure the curses mode is enabled. */
1086 if (arg
!= (char *) NULL
)
1088 int inputNo
= atoi (arg
);
1091 { /* Add 1 for the locator */
1092 int newHeight
= tui_term_height () - (inputNo
+ 1);
1094 if (!_newHeightOk (winList
[CMD_WIN
], newHeight
) ||
1095 _tuiAdjustWinHeights (winList
[CMD_WIN
],
1096 newHeight
) == TUI_FAILURE
)
1097 warning ("Invalid window height specified.\n%s",
1098 XDBWIN_HEIGHT_USAGE
);
1101 warning ("Invalid window height specified.\n%s",
1102 XDBWIN_HEIGHT_USAGE
);
1105 warning ("Invalid window height specified.\n%s", XDBWIN_HEIGHT_USAGE
);
1108 } /* _tuiXDBsetWinHeight */
1111 ** _tuiSetWinHeight_command().
1112 ** Set the height of the specified window, with va_list.
1115 _tuiXDBsetWinHeight_command (char *arg
, int fromTTY
)
1117 _tuiXDBsetWinHeight (arg
, fromTTY
);
1122 ** _tuiAdjustWinHeights().
1123 ** Function to adjust all window heights around the primary
1125 static enum tui_status
1126 _tuiAdjustWinHeights (struct tui_win_info
* primaryWinInfo
, int newHeight
)
1128 enum tui_status status
= TUI_FAILURE
;
1130 if (_newHeightOk (primaryWinInfo
, newHeight
))
1132 status
= TUI_SUCCESS
;
1133 if (newHeight
!= primaryWinInfo
->generic
.height
)
1136 struct tui_win_info
* winInfo
;
1137 struct tui_gen_win_info
* locator
= tui_locator_win_info_ptr ();
1138 enum tui_layout_type curLayout
= tui_current_layout ();
1140 diff
= (newHeight
- primaryWinInfo
->generic
.height
) * (-1);
1141 if (curLayout
== SRC_COMMAND
|| curLayout
== DISASSEM_COMMAND
)
1143 struct tui_win_info
* srcWinInfo
;
1145 _makeInvisibleAndSetNewHeight (primaryWinInfo
, newHeight
);
1146 if (primaryWinInfo
->generic
.type
== CMD_WIN
)
1148 winInfo
= (struct tui_win_info
*) (tui_source_windows ())->list
[0];
1149 srcWinInfo
= winInfo
;
1153 winInfo
= winList
[CMD_WIN
];
1154 srcWinInfo
= primaryWinInfo
;
1156 _makeInvisibleAndSetNewHeight (winInfo
,
1157 winInfo
->generic
.height
+ diff
);
1158 cmdWin
->generic
.origin
.y
= locator
->origin
.y
+ 1;
1159 _makeVisibleWithNewHeight (winInfo
);
1160 _makeVisibleWithNewHeight (primaryWinInfo
);
1161 if (srcWinInfo
->generic
.contentSize
<= 0)
1162 tui_erase_source_content (srcWinInfo
, EMPTY_SOURCE_PROMPT
);
1166 struct tui_win_info
*firstWin
;
1167 struct tui_win_info
*secondWin
;
1169 if (curLayout
== SRC_DISASSEM_COMMAND
)
1172 secondWin
= disassemWin
;
1177 secondWin
= (struct tui_win_info
*) (tui_source_windows ())->list
[0];
1179 if (primaryWinInfo
== cmdWin
)
1181 ** Split the change in height accross the 1st & 2nd windows
1182 ** adjusting them as well.
1184 int firstSplitDiff
= diff
/ 2; /* subtract the locator */
1185 int secondSplitDiff
= firstSplitDiff
;
1189 if (firstWin
->generic
.height
>
1190 secondWin
->generic
.height
)
1203 /* make sure that the minimum hieghts are honored */
1204 while ((firstWin
->generic
.height
+ firstSplitDiff
) < 3)
1209 while ((secondWin
->generic
.height
+ secondSplitDiff
) < 3)
1214 _makeInvisibleAndSetNewHeight (
1216 firstWin
->generic
.height
+ firstSplitDiff
);
1217 secondWin
->generic
.origin
.y
= firstWin
->generic
.height
- 1;
1218 _makeInvisibleAndSetNewHeight (
1219 secondWin
, secondWin
->generic
.height
+ secondSplitDiff
);
1220 cmdWin
->generic
.origin
.y
= locator
->origin
.y
+ 1;
1221 _makeInvisibleAndSetNewHeight (cmdWin
, newHeight
);
1225 if ((cmdWin
->generic
.height
+ diff
) < 1)
1227 ** If there is no way to increase the command window
1228 ** take real estate from the 1st or 2nd window.
1230 if ((cmdWin
->generic
.height
+ diff
) < 1)
1233 for (i
= cmdWin
->generic
.height
+ diff
;
1235 if (primaryWinInfo
== firstWin
)
1236 secondWin
->generic
.height
--;
1238 firstWin
->generic
.height
--;
1241 if (primaryWinInfo
== firstWin
)
1242 _makeInvisibleAndSetNewHeight (firstWin
, newHeight
);
1244 _makeInvisibleAndSetNewHeight (
1246 firstWin
->generic
.height
);
1247 secondWin
->generic
.origin
.y
= firstWin
->generic
.height
- 1;
1248 if (primaryWinInfo
== secondWin
)
1249 _makeInvisibleAndSetNewHeight (secondWin
, newHeight
);
1251 _makeInvisibleAndSetNewHeight (
1252 secondWin
, secondWin
->generic
.height
);
1253 cmdWin
->generic
.origin
.y
= locator
->origin
.y
+ 1;
1254 if ((cmdWin
->generic
.height
+ diff
) < 1)
1255 _makeInvisibleAndSetNewHeight (cmdWin
, 1);
1257 _makeInvisibleAndSetNewHeight (
1258 cmdWin
, cmdWin
->generic
.height
+ diff
);
1260 _makeVisibleWithNewHeight (cmdWin
);
1261 _makeVisibleWithNewHeight (secondWin
);
1262 _makeVisibleWithNewHeight (firstWin
);
1263 if (firstWin
->generic
.contentSize
<= 0)
1264 tui_erase_source_content (firstWin
, EMPTY_SOURCE_PROMPT
);
1265 if (secondWin
->generic
.contentSize
<= 0)
1266 tui_erase_source_content (secondWin
, EMPTY_SOURCE_PROMPT
);
1272 } /* _tuiAdjustWinHeights */
1276 ** _makeInvisibleAndSetNewHeight().
1277 ** Function make the target window (and auxillary windows associated
1278 ** with the targer) invisible, and set the new height and location.
1281 _makeInvisibleAndSetNewHeight (struct tui_win_info
* winInfo
, int height
)
1284 struct tui_gen_win_info
* genWinInfo
;
1286 tui_make_invisible (&winInfo
->generic
);
1287 winInfo
->generic
.height
= height
;
1289 winInfo
->generic
.viewportHeight
= height
- 1;
1291 winInfo
->generic
.viewportHeight
= height
;
1292 if (winInfo
!= cmdWin
)
1293 winInfo
->generic
.viewportHeight
--;
1295 /* Now deal with the auxillary windows associated with winInfo */
1296 switch (winInfo
->generic
.type
)
1300 genWinInfo
= winInfo
->detail
.sourceInfo
.executionInfo
;
1301 tui_make_invisible (genWinInfo
);
1302 genWinInfo
->height
= height
;
1303 genWinInfo
->origin
.y
= winInfo
->generic
.origin
.y
;
1305 genWinInfo
->viewportHeight
= height
- 1;
1307 genWinInfo
->viewportHeight
= height
;
1308 if (winInfo
!= cmdWin
)
1309 genWinInfo
->viewportHeight
--;
1311 if (m_hasLocator (winInfo
))
1313 genWinInfo
= tui_locator_win_info_ptr ();
1314 tui_make_invisible (genWinInfo
);
1315 genWinInfo
->origin
.y
= winInfo
->generic
.origin
.y
+ height
;
1319 /* delete all data item windows */
1320 for (i
= 0; i
< winInfo
->generic
.contentSize
; i
++)
1322 genWinInfo
= (struct tui_gen_win_info
*) & ((struct tui_win_element
*)
1323 winInfo
->generic
.content
[i
])->whichElement
.dataWindow
;
1324 tui_delete_win (genWinInfo
->handle
);
1325 genWinInfo
->handle
= (WINDOW
*) NULL
;
1335 ** _makeVisibleWithNewHeight().
1336 ** Function to make the windows with new heights visible.
1337 ** This means re-creating the windows' content since the window
1338 ** had to be destroyed to be made invisible.
1341 _makeVisibleWithNewHeight (struct tui_win_info
* winInfo
)
1345 tui_make_visible (&winInfo
->generic
);
1346 tui_check_and_display_highlight_if_needed (winInfo
);
1347 switch (winInfo
->generic
.type
)
1351 tui_free_win_content (winInfo
->detail
.sourceInfo
.executionInfo
);
1352 tui_make_visible (winInfo
->detail
.sourceInfo
.executionInfo
);
1353 if (winInfo
->generic
.content
!= NULL
)
1355 union tui_line_or_address lineOrAddr
;
1356 struct symtab_and_line cursal
1357 = get_current_source_symtab_and_line ();
1359 if (winInfo
->generic
.type
== SRC_WIN
)
1361 winInfo
->detail
.sourceInfo
.startLineOrAddr
.lineNo
;
1364 winInfo
->detail
.sourceInfo
.startLineOrAddr
.addr
;
1365 tui_free_win_content (&winInfo
->generic
);
1366 tui_update_source_window (winInfo
, cursal
.symtab
, lineOrAddr
, TRUE
);
1368 else if (deprecated_selected_frame
!= (struct frame_info
*) NULL
)
1370 union tui_line_or_address line
;
1371 struct symtab_and_line cursal
= get_current_source_symtab_and_line ();
1374 s
= find_pc_symtab (get_frame_pc (deprecated_selected_frame
));
1375 if (winInfo
->generic
.type
== SRC_WIN
)
1376 line
.lineNo
= cursal
.line
;
1379 find_line_pc (s
, cursal
.line
, &line
.addr
);
1381 tui_update_source_window (winInfo
, s
, line
, TRUE
);
1383 if (m_hasLocator (winInfo
))
1385 tui_make_visible (tui_locator_win_info_ptr ());
1386 tui_show_locator_content ();
1390 tui_display_all_data ();
1393 winInfo
->detail
.commandInfo
.curLine
= 0;
1394 winInfo
->detail
.commandInfo
.curch
= 0;
1395 wmove (winInfo
->generic
.handle
,
1396 winInfo
->detail
.commandInfo
.curLine
,
1397 winInfo
->detail
.commandInfo
.curch
);
1404 } /* _makeVisibleWithNewHeight */
1408 _newHeightOk (struct tui_win_info
* primaryWinInfo
, int newHeight
)
1410 int ok
= (newHeight
< tui_term_height ());
1415 enum tui_layout_type curLayout
= tui_current_layout ();
1417 diff
= (newHeight
- primaryWinInfo
->generic
.height
) * (-1);
1418 if (curLayout
== SRC_COMMAND
|| curLayout
== DISASSEM_COMMAND
)
1420 ok
= ((primaryWinInfo
->generic
.type
== CMD_WIN
&&
1421 newHeight
<= (tui_term_height () - 4) &&
1422 newHeight
>= MIN_CMD_WIN_HEIGHT
) ||
1423 (primaryWinInfo
->generic
.type
!= CMD_WIN
&&
1424 newHeight
<= (tui_term_height () - 2) &&
1425 newHeight
>= MIN_WIN_HEIGHT
));
1427 { /* check the total height */
1428 struct tui_win_info
* winInfo
;
1430 if (primaryWinInfo
== cmdWin
)
1431 winInfo
= (struct tui_win_info
*) (tui_source_windows ())->list
[0];
1435 (winInfo
->generic
.height
+ diff
)) <= tui_term_height ());
1440 int curTotalHeight
, totalHeight
, minHeight
= 0;
1441 struct tui_win_info
*firstWin
;
1442 struct tui_win_info
*secondWin
;
1444 if (curLayout
== SRC_DISASSEM_COMMAND
)
1447 secondWin
= disassemWin
;
1452 secondWin
= (struct tui_win_info
*) (tui_source_windows ())->list
[0];
1455 ** We could simply add all the heights to obtain the same result
1456 ** but below is more explicit since we subtract 1 for the
1457 ** line that the first and second windows share, and add one
1460 totalHeight
= curTotalHeight
=
1461 (firstWin
->generic
.height
+ secondWin
->generic
.height
- 1)
1462 + cmdWin
->generic
.height
+ 1 /*locator */ ;
1463 if (primaryWinInfo
== cmdWin
)
1465 /* locator included since first & second win share a line */
1466 ok
= ((firstWin
->generic
.height
+
1467 secondWin
->generic
.height
+ diff
) >=
1468 (MIN_WIN_HEIGHT
* 2) &&
1469 newHeight
>= MIN_CMD_WIN_HEIGHT
);
1472 totalHeight
= newHeight
+ (firstWin
->generic
.height
+
1473 secondWin
->generic
.height
+ diff
);
1474 minHeight
= MIN_CMD_WIN_HEIGHT
;
1479 minHeight
= MIN_WIN_HEIGHT
;
1481 ** First see if we can increase/decrease the command
1482 ** window. And make sure that the command window is
1485 ok
= ((cmdWin
->generic
.height
+ diff
) > 0);
1488 ** Looks like we have to increase/decrease one of
1489 ** the other windows
1491 if (primaryWinInfo
== firstWin
)
1492 ok
= (secondWin
->generic
.height
+ diff
) >= minHeight
;
1494 ok
= (firstWin
->generic
.height
+ diff
) >= minHeight
;
1498 if (primaryWinInfo
== firstWin
)
1499 totalHeight
= newHeight
+
1500 secondWin
->generic
.height
+
1501 cmdWin
->generic
.height
+ diff
;
1503 totalHeight
= newHeight
+
1504 firstWin
->generic
.height
+
1505 cmdWin
->generic
.height
+ diff
;
1509 ** Now make sure that the proposed total height doesn't exceed
1510 ** the old total height.
1513 ok
= (newHeight
>= minHeight
&& totalHeight
<= curTotalHeight
);
1518 } /* _newHeightOk */
1522 ** _parseScrollingArgs().
1525 _parseScrollingArgs (char *arg
, struct tui_win_info
* * winToScroll
, int *numToScroll
)
1529 *winToScroll
= tui_win_with_focus ();
1532 ** First set up the default window to scroll, in case there is no
1535 if (arg
!= (char *) NULL
)
1539 /* process the number of lines to scroll */
1540 buf
= bufPtr
= xstrdup (arg
);
1541 if (isdigit (*bufPtr
))
1546 bufPtr
= strchr (bufPtr
, ' ');
1547 if (bufPtr
!= (char *) NULL
)
1551 *numToScroll
= atoi (numStr
);
1554 else if (numToScroll
)
1555 *numToScroll
= atoi (numStr
);
1558 /* process the window name if one is specified */
1559 if (bufPtr
!= (char *) NULL
)
1565 while (*(++bufPtr
) == ' ')
1568 if (*bufPtr
!= (char) 0)
1573 /* Validate the window name */
1574 for (i
= 0; i
< strlen (wname
); i
++)
1575 wname
[i
] = toupper (wname
[i
]);
1576 *winToScroll
= tui_partial_win_by_name (wname
);
1578 if (*winToScroll
== (struct tui_win_info
*) NULL
||
1579 !(*winToScroll
)->generic
.isVisible
)
1580 warning ("Invalid window specified. \n\
1581 The window name specified must be valid and visible.\n");
1582 else if (*winToScroll
== cmdWin
)
1583 *winToScroll
= (struct tui_win_info
*) (tui_source_windows ())->list
[0];
1589 } /* _parseScrollingArgs */