1 /* TUI window generic functions.
3 Copyright (C) 1998-2019 Free Software Foundation, Inc.
5 Contributed by Hewlett-Packard Company.
7 This file is part of GDB.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
22 /* This module contains procedures for handling tui window functions
23 like resize, scrolling, scrolling, changing focus, etc.
25 Author: Susan B. Macchia */
30 #include "breakpoint.h"
32 #include "cli/cli-cmds.h"
35 #include "event-loop.h"
38 #include "tui/tui-io.h"
39 #include "tui/tui-data.h"
40 #include "tui/tui-wingeneral.h"
41 #include "tui/tui-stack.h"
42 #include "tui/tui-regs.h"
43 #include "tui/tui-disasm.h"
44 #include "tui/tui-source.h"
45 #include "tui/tui-winsource.h"
46 #include "tui/tui-windata.h"
47 #include "tui/tui-win.h"
49 #include "gdb_curses.h"
51 #include "readline/readline.h"
55 /*******************************
57 ********************************/
58 static void make_invisible_and_set_new_height (struct tui_win_info
*,
60 static enum tui_status
tui_adjust_win_heights (struct tui_win_info
*,
62 static int new_height_ok (struct tui_win_info
*, int);
63 static void tui_set_tab_width_command (const char *, int);
64 static void tui_refresh_all_command (const char *, int);
65 static void tui_all_windows_info (const char *, int);
66 static void tui_scroll_forward_command (const char *, int);
67 static void tui_scroll_backward_command (const char *, int);
68 static void tui_scroll_left_command (const char *, int);
69 static void tui_scroll_right_command (const char *, int);
70 static void parse_scrolling_args (const char *,
71 struct tui_win_info
**,
75 /***************************************
77 ***************************************/
78 #define WIN_HEIGHT_USAGE "Usage: winheight WINDOW-NAME [+ | -] NUM-LINES\n"
79 #define FOCUS_USAGE "Usage: focus [WINDOW-NAME | next | prev]\n"
81 /***************************************
83 ***************************************/
86 # define ACS_LRCORNER '+'
89 # define ACS_LLCORNER '+'
92 # define ACS_ULCORNER '+'
95 # define ACS_URCORNER '+'
98 # define ACS_HLINE '-'
101 # define ACS_VLINE '|'
104 /* Possible values for tui-border-kind variable. */
105 static const char *const tui_border_kind_enums
[] = {
112 /* Possible values for tui-border-mode and tui-active-border-mode. */
113 static const char *const tui_border_mode_enums
[] = {
130 /* Translation table for border-mode variables.
131 The list of values must be terminated by a NULL.
132 After the NULL value, an entry defines the default. */
133 struct tui_translate tui_border_mode_translate
[] = {
134 { "normal", A_NORMAL
},
135 { "standout", A_STANDOUT
},
136 { "reverse", A_REVERSE
},
138 { "half-standout", A_DIM
| A_STANDOUT
},
140 { "bold-standout", A_BOLD
| A_STANDOUT
},
142 { "normal", A_NORMAL
}
145 /* Translation tables for border-kind, one for each border
146 character (see wborder, border curses operations).
147 -1 is used to indicate the ACS because ACS characters
148 are determined at run time by curses (depends on terminal). */
149 struct tui_translate tui_border_kind_translate_vline
[] = {
157 struct tui_translate tui_border_kind_translate_hline
[] = {
165 struct tui_translate tui_border_kind_translate_ulcorner
[] = {
173 struct tui_translate tui_border_kind_translate_urcorner
[] = {
181 struct tui_translate tui_border_kind_translate_llcorner
[] = {
189 struct tui_translate tui_border_kind_translate_lrcorner
[] = {
198 /* Tui configuration variables controlled with set/show command. */
199 const char *tui_active_border_mode
= "bold-standout";
201 show_tui_active_border_mode (struct ui_file
*file
,
203 struct cmd_list_element
*c
,
206 fprintf_filtered (file
, _("\
207 The attribute mode to use for the active TUI window border is \"%s\".\n"),
211 const char *tui_border_mode
= "normal";
213 show_tui_border_mode (struct ui_file
*file
,
215 struct cmd_list_element
*c
,
218 fprintf_filtered (file
, _("\
219 The attribute mode to use for the TUI window borders is \"%s\".\n"),
223 const char *tui_border_kind
= "acs";
225 show_tui_border_kind (struct ui_file
*file
,
227 struct cmd_list_element
*c
,
230 fprintf_filtered (file
, _("The kind of border for TUI windows is \"%s\".\n"),
235 /* Tui internal configuration variables. These variables are updated
236 by tui_update_variables to reflect the tui configuration
238 chtype tui_border_vline
;
239 chtype tui_border_hline
;
240 chtype tui_border_ulcorner
;
241 chtype tui_border_urcorner
;
242 chtype tui_border_llcorner
;
243 chtype tui_border_lrcorner
;
245 int tui_border_attrs
;
246 int tui_active_border_attrs
;
248 /* Identify the item in the translation table.
249 When the item is not recognized, use the default entry. */
250 static struct tui_translate
*
251 translate (const char *name
, struct tui_translate
*table
)
255 if (name
&& strcmp (table
->name
, name
) == 0)
260 /* Not found, return default entry. */
265 /* Update the tui internal configuration according to gdb settings.
266 Returns 1 if the configuration has changed and the screen should
269 tui_update_variables (void)
272 struct tui_translate
*entry
;
274 entry
= translate (tui_border_mode
, tui_border_mode_translate
);
275 if (tui_border_attrs
!= entry
->value
)
277 tui_border_attrs
= entry
->value
;
280 entry
= translate (tui_active_border_mode
, tui_border_mode_translate
);
281 if (tui_active_border_attrs
!= entry
->value
)
283 tui_active_border_attrs
= entry
->value
;
287 /* If one corner changes, all characters are changed.
288 Only check the first one. The ACS characters are determined at
289 run time by curses terminal management. */
290 entry
= translate (tui_border_kind
, tui_border_kind_translate_lrcorner
);
291 if (tui_border_lrcorner
!= (chtype
) entry
->value
)
293 tui_border_lrcorner
= (entry
->value
< 0) ? ACS_LRCORNER
: entry
->value
;
296 entry
= translate (tui_border_kind
, tui_border_kind_translate_llcorner
);
297 tui_border_llcorner
= (entry
->value
< 0) ? ACS_LLCORNER
: entry
->value
;
299 entry
= translate (tui_border_kind
, tui_border_kind_translate_ulcorner
);
300 tui_border_ulcorner
= (entry
->value
< 0) ? ACS_ULCORNER
: entry
->value
;
302 entry
= translate (tui_border_kind
, tui_border_kind_translate_urcorner
);
303 tui_border_urcorner
= (entry
->value
< 0) ? ACS_URCORNER
: entry
->value
;
305 entry
= translate (tui_border_kind
, tui_border_kind_translate_hline
);
306 tui_border_hline
= (entry
->value
< 0) ? ACS_HLINE
: entry
->value
;
308 entry
= translate (tui_border_kind
, tui_border_kind_translate_vline
);
309 tui_border_vline
= (entry
->value
< 0) ? ACS_VLINE
: entry
->value
;
315 set_tui_cmd (const char *args
, int from_tty
)
320 show_tui_cmd (const char *args
, int from_tty
)
324 static struct cmd_list_element
*tuilist
;
327 tui_command (const char *args
, int from_tty
)
329 printf_unfiltered (_("\"tui\" must be followed by the name of a "
331 help_list (tuilist
, "tui ", all_commands
, gdb_stdout
);
334 struct cmd_list_element
**
335 tui_get_cmd_list (void)
338 add_prefix_cmd ("tui", class_tui
, tui_command
,
339 _("Text User Interface commands."),
340 &tuilist
, "tui ", 0, &cmdlist
);
344 /* The set_func hook of "set tui ..." commands that affect the window
345 borders on the TUI display. */
347 tui_set_var_cmd (const char *null_args
,
348 int from_tty
, struct cmd_list_element
*c
)
350 if (tui_update_variables () && tui_active
)
351 tui_rehighlight_all ();
354 /* Generic window name completion function. Complete window name pointed
355 to by TEXT and WORD. If INCLUDE_NEXT_PREV_P is true then the special
356 window names 'next' and 'prev' will also be considered as possible
357 completions of the window name. */
360 window_name_completer (completion_tracker
&tracker
,
361 int include_next_prev_p
,
362 const char *text
, const char *word
)
364 std::vector
<const char *> completion_name_vec
;
366 for (tui_win_info
*win_info
: all_tui_windows ())
368 const char *completion_name
= NULL
;
370 /* We can't focus on an invisible window. */
371 if (!win_info
->is_visible
)
374 completion_name
= win_info
->name ();
375 gdb_assert (completion_name
!= NULL
);
376 completion_name_vec
.push_back (completion_name
);
379 /* If no windows are considered visible then the TUI has not yet been
380 initialized. But still "focus src" and "focus cmd" will work because
381 invoking the focus command will entail initializing the TUI which sets the
382 default layout to SRC_COMMAND. */
383 if (completion_name_vec
.empty ())
385 completion_name_vec
.push_back (SRC_NAME
);
386 completion_name_vec
.push_back (CMD_NAME
);
389 if (include_next_prev_p
)
391 completion_name_vec
.push_back ("next");
392 completion_name_vec
.push_back ("prev");
396 completion_name_vec
.push_back (NULL
);
397 complete_on_enum (tracker
, completion_name_vec
.data (), text
, word
);
400 /* Complete possible window names to focus on. TEXT is the complete text
401 entered so far, WORD is the word currently being completed. */
404 focus_completer (struct cmd_list_element
*ignore
,
405 completion_tracker
&tracker
,
406 const char *text
, const char *word
)
408 window_name_completer (tracker
, 1, text
, word
);
411 /* Complete possible window names for winheight command. TEXT is the
412 complete text entered so far, WORD is the word currently being
416 winheight_completer (struct cmd_list_element
*ignore
,
417 completion_tracker
&tracker
,
418 const char *text
, const char *word
)
420 /* The first word is the window name. That we can complete. Subsequent
421 words can't be completed. */
425 window_name_completer (tracker
, 0, text
, word
);
428 /* Update gdb's knowledge of the terminal size. */
430 tui_update_gdb_sizes (void)
436 width
= TUI_CMD_WIN
->width
;
437 height
= TUI_CMD_WIN
->height
;
441 width
= tui_term_width ();
442 height
= tui_term_height ();
445 set_screen_width_and_height (width
, height
);
449 /* Set the logical focus to win_info. */
451 tui_set_win_focus_to (struct tui_win_info
*win_info
)
453 if (win_info
!= NULL
)
455 struct tui_win_info
*win_with_focus
= tui_win_with_focus ();
457 tui_unhighlight_win (win_with_focus
);
458 tui_set_win_with_focus (win_info
);
459 tui_highlight_win (win_info
);
465 tui_win_info::forward_scroll (int num_to_scroll
)
467 if (num_to_scroll
== 0)
468 num_to_scroll
= height
- 3;
470 do_scroll_vertical (num_to_scroll
);
474 tui_win_info::backward_scroll (int num_to_scroll
)
476 if (num_to_scroll
== 0)
477 num_to_scroll
= height
- 3;
479 do_scroll_vertical (-num_to_scroll
);
484 tui_win_info::left_scroll (int num_to_scroll
)
486 if (num_to_scroll
== 0)
489 do_scroll_horizontal (num_to_scroll
);
494 tui_win_info::right_scroll (int num_to_scroll
)
496 if (num_to_scroll
== 0)
499 do_scroll_horizontal (-num_to_scroll
);
503 /* See tui-data.h. */
506 tui_source_window_base::refresh_all ()
508 tui_show_source_content (this);
509 tui_check_and_display_highlight_if_needed (this);
510 tui_erase_exec_info_content (this);
511 tui_update_exec_info (this);
515 tui_refresh_all_win (void)
517 clearok (curscr
, TRUE
);
519 for (tui_win_info
*win_info
: all_tui_windows ())
521 if (win_info
->is_visible
)
522 win_info
->refresh_all ();
524 tui_show_locator_content ();
528 tui_rehighlight_all (void)
530 for (tui_win_info
*win_info
: all_tui_windows ())
531 tui_check_and_display_highlight_if_needed (win_info
);
534 /* Resize all the windows based on the terminal size. This function
535 gets called from within the readline SIGWINCH handler. */
537 tui_resize_all (void)
539 int height_diff
, width_diff
;
540 int screenheight
, screenwidth
;
542 rl_get_screen_size (&screenheight
, &screenwidth
);
543 width_diff
= screenwidth
- tui_term_width ();
544 height_diff
= screenheight
- tui_term_height ();
545 if (height_diff
|| width_diff
)
547 enum tui_layout_type cur_layout
= tui_current_layout ();
548 struct tui_win_info
*win_with_focus
= tui_win_with_focus ();
549 struct tui_win_info
*first_win
;
550 struct tui_win_info
*second_win
;
551 tui_source_window_base
*src_win
;
552 struct tui_locator_window
*locator
= tui_locator_win_info_ptr ();
554 int new_height
, split_diff
, cmd_split_diff
, num_wins_displayed
= 2;
556 #ifdef HAVE_RESIZE_TERM
557 resize_term (screenheight
, screenwidth
);
559 /* Turn keypad off while we resize. */
560 if (win_with_focus
!= TUI_CMD_WIN
)
561 keypad (TUI_CMD_WIN
->handle
, FALSE
);
562 tui_update_gdb_sizes ();
563 tui_set_term_height_to (screenheight
);
564 tui_set_term_width_to (screenwidth
);
565 if (cur_layout
== SRC_DISASSEM_COMMAND
566 || cur_layout
== SRC_DATA_COMMAND
567 || cur_layout
== DISASSEM_DATA_COMMAND
)
568 num_wins_displayed
++;
569 split_diff
= height_diff
/ num_wins_displayed
;
570 cmd_split_diff
= split_diff
;
571 if (height_diff
% num_wins_displayed
)
578 /* Now adjust each window. */
579 /* erase + clearok are used instead of a straightforward clear as
580 AIX 5.3 does not define clear. */
582 clearok (curscr
, TRUE
);
587 case DISASSEM_COMMAND
:
588 src_win
= tui_source_windows ()[0];
590 first_win
->width
+= width_diff
;
591 locator
->width
+= width_diff
;
592 /* Check for invalid heights. */
593 if (height_diff
== 0)
594 new_height
= first_win
->height
;
595 else if ((first_win
->height
+ split_diff
) >=
596 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
597 new_height
= screenheight
- MIN_CMD_WIN_HEIGHT
- 1;
598 else if ((first_win
->height
+ split_diff
) <= 0)
599 new_height
= MIN_WIN_HEIGHT
;
601 new_height
= first_win
->height
+ split_diff
;
603 locator
->origin
.y
= new_height
+ 1;
604 make_invisible_and_set_new_height (first_win
, new_height
);
605 TUI_CMD_WIN
->origin
.y
= locator
->origin
.y
+ 1;
606 TUI_CMD_WIN
->width
+= width_diff
;
607 new_height
= screenheight
- TUI_CMD_WIN
->origin
.y
;
608 make_invisible_and_set_new_height (TUI_CMD_WIN
, new_height
);
609 first_win
->make_visible_with_new_height ();
610 TUI_CMD_WIN
->make_visible_with_new_height ();
611 if (src_win
->content
.empty ())
612 tui_erase_source_content (src_win
);
615 if (cur_layout
== SRC_DISASSEM_COMMAND
)
617 src_win
= TUI_SRC_WIN
;
619 first_win
->width
+= width_diff
;
620 second_win
= TUI_DISASM_WIN
;
621 second_win
->width
+= width_diff
;
625 first_win
= TUI_DATA_WIN
;
626 first_win
->width
+= width_diff
;
627 src_win
= tui_source_windows ()[0];
628 second_win
= src_win
;
629 second_win
->width
+= width_diff
;
631 /* Change the first window's height/width. */
632 /* Check for invalid heights. */
633 if (height_diff
== 0)
634 new_height
= first_win
->height
;
635 else if ((first_win
->height
+
636 second_win
->height
+ (split_diff
* 2)) >=
637 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
638 new_height
= (screenheight
- MIN_CMD_WIN_HEIGHT
- 1) / 2;
639 else if ((first_win
->height
+ split_diff
) <= 0)
640 new_height
= MIN_WIN_HEIGHT
;
642 new_height
= first_win
->height
+ split_diff
;
643 make_invisible_and_set_new_height (first_win
, new_height
);
645 locator
->width
+= width_diff
;
647 /* Change the second window's height/width. */
648 /* Check for invalid heights. */
649 if (height_diff
== 0)
650 new_height
= second_win
->height
;
651 else if ((first_win
->height
+
652 second_win
->height
+ (split_diff
* 2)) >=
653 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
655 new_height
= screenheight
- MIN_CMD_WIN_HEIGHT
- 1;
657 new_height
= (new_height
/ 2) + 1;
661 else if ((second_win
->height
+ split_diff
) <= 0)
662 new_height
= MIN_WIN_HEIGHT
;
664 new_height
= second_win
->height
+ split_diff
;
665 second_win
->origin
.y
= first_win
->height
- 1;
666 make_invisible_and_set_new_height (second_win
, new_height
);
668 /* Change the command window's height/width. */
669 TUI_CMD_WIN
->origin
.y
= locator
->origin
.y
+ 1;
670 make_invisible_and_set_new_height (TUI_CMD_WIN
,
673 first_win
->make_visible_with_new_height ();
674 second_win
->make_visible_with_new_height ();
675 TUI_CMD_WIN
->make_visible_with_new_height ();
676 if (src_win
->content
.empty ())
677 tui_erase_source_content (src_win
);
680 /* Now remove all invisible windows, and their content so that
681 they get created again when called for with the new size. */
682 for (win_type
= SRC_WIN
; (win_type
< MAX_MAJOR_WINDOWS
); win_type
++)
684 if (win_type
!= CMD_WIN
685 && (tui_win_list
[win_type
] != NULL
)
686 && !tui_win_list
[win_type
]->is_visible
)
688 delete tui_win_list
[win_type
];
689 tui_win_list
[win_type
] = NULL
;
692 /* Turn keypad back on, unless focus is in the command
694 if (win_with_focus
!= TUI_CMD_WIN
)
695 keypad (TUI_CMD_WIN
->handle
, TRUE
);
700 /* Token for use by TUI's asynchronous SIGWINCH handler. */
701 static struct async_signal_handler
*tui_sigwinch_token
;
703 /* TUI's SIGWINCH signal handler. */
705 tui_sigwinch_handler (int signal
)
707 mark_async_signal_handler (tui_sigwinch_token
);
708 tui_set_win_resized_to (TRUE
);
711 /* Callback for asynchronously resizing TUI following a SIGWINCH signal. */
713 tui_async_resize_screen (gdb_client_data arg
)
715 rl_resize_terminal ();
719 int screen_height
, screen_width
;
721 rl_get_screen_size (&screen_height
, &screen_width
);
722 set_screen_width_and_height (screen_width
, screen_height
);
724 /* win_resized is left set so that the next call to tui_enable()
725 resizes the TUI windows. */
729 tui_set_win_resized_to (FALSE
);
731 tui_refresh_all_win ();
732 tui_update_gdb_sizes ();
733 tui_redisplay_readline ();
738 /* Initialize TUI's SIGWINCH signal handler. Note that the handler is not
739 uninstalled when we exit TUI, so the handler should not assume that TUI is
742 tui_initialize_win (void)
746 = create_async_signal_handler (tui_async_resize_screen
, NULL
);
749 #ifdef HAVE_SIGACTION
750 struct sigaction old_winch
;
752 memset (&old_winch
, 0, sizeof (old_winch
));
753 old_winch
.sa_handler
= &tui_sigwinch_handler
;
755 old_winch
.sa_flags
= SA_RESTART
;
757 sigaction (SIGWINCH
, &old_winch
, NULL
);
759 signal (SIGWINCH
, &tui_sigwinch_handler
);
766 /*************************
767 ** STATIC LOCAL FUNCTIONS
768 **************************/
772 tui_scroll_forward_command (const char *arg
, int from_tty
)
774 int num_to_scroll
= 1;
775 struct tui_win_info
*win_to_scroll
;
777 /* Make sure the curses mode is enabled. */
780 parse_scrolling_args (arg
, &win_to_scroll
, NULL
);
782 parse_scrolling_args (arg
, &win_to_scroll
, &num_to_scroll
);
783 win_to_scroll
->forward_scroll (num_to_scroll
);
788 tui_scroll_backward_command (const char *arg
, int from_tty
)
790 int num_to_scroll
= 1;
791 struct tui_win_info
*win_to_scroll
;
793 /* Make sure the curses mode is enabled. */
796 parse_scrolling_args (arg
, &win_to_scroll
, NULL
);
798 parse_scrolling_args (arg
, &win_to_scroll
, &num_to_scroll
);
799 win_to_scroll
->backward_scroll (num_to_scroll
);
804 tui_scroll_left_command (const char *arg
, int from_tty
)
807 struct tui_win_info
*win_to_scroll
;
809 /* Make sure the curses mode is enabled. */
811 parse_scrolling_args (arg
, &win_to_scroll
, &num_to_scroll
);
812 win_to_scroll
->left_scroll (num_to_scroll
);
817 tui_scroll_right_command (const char *arg
, int from_tty
)
820 struct tui_win_info
*win_to_scroll
;
822 /* Make sure the curses mode is enabled. */
824 parse_scrolling_args (arg
, &win_to_scroll
, &num_to_scroll
);
825 win_to_scroll
->right_scroll (num_to_scroll
);
829 /* Set focus to the window named by 'arg'. */
831 tui_set_focus_command (const char *arg
, int from_tty
)
837 char *buf_ptr
= xstrdup (arg
);
839 struct tui_win_info
*win_info
= NULL
;
841 for (i
= 0; (i
< strlen (buf_ptr
)); i
++)
842 buf_ptr
[i
] = tolower (arg
[i
]);
844 if (subset_compare (buf_ptr
, "next"))
845 win_info
= tui_next_win (tui_win_with_focus ());
846 else if (subset_compare (buf_ptr
, "prev"))
847 win_info
= tui_prev_win (tui_win_with_focus ());
849 win_info
= tui_partial_win_by_name (buf_ptr
);
851 if (win_info
== NULL
|| !win_info
->is_visible
)
852 warning (_("Invalid window specified. \n\
853 The window name specified must be valid and visible.\n"));
856 tui_set_win_focus_to (win_info
);
857 keypad (TUI_CMD_WIN
->handle
, (win_info
!= TUI_CMD_WIN
));
860 if (TUI_DATA_WIN
&& TUI_DATA_WIN
->is_visible
)
861 TUI_DATA_WIN
->refresh_all ();
863 printf_filtered (_("Focus set to %s window.\n"),
864 tui_win_with_focus ()->name ());
867 warning (_("Incorrect Number of Arguments.\n%s"), FOCUS_USAGE
);
871 tui_all_windows_info (const char *arg
, int from_tty
)
873 struct tui_win_info
*win_with_focus
= tui_win_with_focus ();
875 for (tui_win_info
*win_info
: all_tui_windows ())
876 if (win_info
->is_visible
)
878 if (win_with_focus
== win_info
)
879 printf_filtered (" %s\t(%d lines) <has focus>\n",
883 printf_filtered (" %s\t(%d lines)\n",
891 tui_refresh_all_command (const char *arg
, int from_tty
)
893 /* Make sure the curses mode is enabled. */
896 tui_refresh_all_win ();
899 /* The tab width that should be used by the TUI. */
901 unsigned int tui_tab_width
= DEFAULT_TAB_LEN
;
903 /* The tab width as set by the user. */
905 static unsigned int internal_tab_width
= DEFAULT_TAB_LEN
;
907 /* See tui-data.h. */
910 tui_source_window_base::update_tab_width ()
912 /* We don't really change the height of any windows, but
913 calling these 2 functions causes a complete regeneration
914 and redisplay of the window's contents, which will take
915 the new tab width into account. */
916 make_invisible_and_set_new_height (this, height
);
917 make_visible_with_new_height ();
920 /* After the tab width is set, call this to update the relevant
926 for (tui_win_info
*win_info
: all_tui_windows ())
928 if (win_info
->is_visible
)
929 win_info
->update_tab_width ();
933 /* Callback for "set tui tab-width". */
936 tui_set_tab_width (const char *ignore
,
937 int from_tty
, struct cmd_list_element
*c
)
939 if (internal_tab_width
== 0)
941 internal_tab_width
= tui_tab_width
;
942 error (_("Tab width must not be 0"));
945 tui_tab_width
= internal_tab_width
;
949 /* Callback for "show tui tab-width". */
952 tui_show_tab_width (struct ui_file
*file
, int from_tty
,
953 struct cmd_list_element
*c
, const char *value
)
955 fprintf_filtered (gdb_stdout
, _("TUI tab width is %s spaces.\n"), value
);
959 /* Set the tab width of the specified window. */
961 tui_set_tab_width_command (const char *arg
, int from_tty
)
963 /* Make sure the curses mode is enabled. */
971 warning (_("Tab widths greater than 0 must be specified."));
974 internal_tab_width
= ts
;
983 /* Set the height of the specified window. */
985 tui_set_win_height_command (const char *arg
, int from_tty
)
987 /* Make sure the curses mode is enabled. */
991 std::string copy
= arg
;
992 char *buf
= ©
[0];
996 struct tui_win_info
*win_info
;
999 buf_ptr
= strchr (buf_ptr
, ' ');
1000 if (buf_ptr
!= NULL
)
1002 *buf_ptr
= (char) 0;
1004 /* Validate the window name. */
1005 for (i
= 0; i
< strlen (wname
); i
++)
1006 wname
[i
] = tolower (wname
[i
]);
1007 win_info
= tui_partial_win_by_name (wname
);
1009 if (win_info
== NULL
|| !win_info
->is_visible
)
1010 warning (_("Invalid window specified. \n\
1011 The window name specified must be valid and visible.\n"));
1014 /* Process the size. */
1015 while (*(++buf_ptr
) == ' ')
1018 if (*buf_ptr
!= (char) 0)
1021 int fixed_size
= TRUE
;
1024 if (*buf_ptr
== '+' || *buf_ptr
== '-')
1026 if (*buf_ptr
== '-')
1031 input_no
= atoi (buf_ptr
);
1037 new_height
= input_no
;
1039 new_height
= win_info
->height
+ input_no
;
1041 /* Now change the window's height, and adjust
1042 all other windows around it. */
1043 if (tui_adjust_win_heights (win_info
,
1044 new_height
) == TUI_FAILURE
)
1045 warning (_("Invalid window height specified.\n%s"),
1048 tui_update_gdb_sizes ();
1051 warning (_("Invalid window height specified.\n%s"),
1057 printf_filtered (WIN_HEIGHT_USAGE
);
1060 printf_filtered (WIN_HEIGHT_USAGE
);
1063 /* Function to adjust all window heights around the primary. */
1064 static enum tui_status
1065 tui_adjust_win_heights (struct tui_win_info
*primary_win_info
,
1068 enum tui_status status
= TUI_FAILURE
;
1070 if (new_height_ok (primary_win_info
, new_height
))
1072 status
= TUI_SUCCESS
;
1073 if (new_height
!= primary_win_info
->height
)
1076 struct tui_win_info
*win_info
;
1077 struct tui_locator_window
*locator
= tui_locator_win_info_ptr ();
1078 enum tui_layout_type cur_layout
= tui_current_layout ();
1080 diff
= (new_height
- primary_win_info
->height
) * (-1);
1081 if (cur_layout
== SRC_COMMAND
1082 || cur_layout
== DISASSEM_COMMAND
)
1084 struct tui_win_info
*src_win_info
;
1086 make_invisible_and_set_new_height (primary_win_info
, new_height
);
1087 if (primary_win_info
->type
== CMD_WIN
)
1089 win_info
= tui_source_windows ()[0];
1090 src_win_info
= win_info
;
1094 win_info
= tui_win_list
[CMD_WIN
];
1095 src_win_info
= primary_win_info
;
1097 make_invisible_and_set_new_height (win_info
,
1098 win_info
->height
+ diff
);
1099 TUI_CMD_WIN
->origin
.y
= locator
->origin
.y
+ 1;
1100 win_info
->make_visible_with_new_height ();
1101 primary_win_info
->make_visible_with_new_height ();
1102 if ((src_win_info
->type
== SRC_WIN
1103 || src_win_info
->type
== DISASSEM_WIN
))
1105 tui_source_window_base
*src_base
1106 = (tui_source_window_base
*) src_win_info
;
1107 if (src_base
->content
.empty ())
1108 tui_erase_source_content (src_base
);
1113 struct tui_win_info
*first_win
;
1114 struct tui_source_window_base
*second_win
;
1115 tui_source_window_base
*src1
;
1117 if (cur_layout
== SRC_DISASSEM_COMMAND
)
1121 second_win
= TUI_DISASM_WIN
;
1126 first_win
= TUI_DATA_WIN
;
1127 second_win
= tui_source_windows ()[0];
1129 if (primary_win_info
== TUI_CMD_WIN
)
1130 { /* Split the change in height accross the 1st & 2nd
1131 windows, adjusting them as well. */
1132 /* Subtract the locator. */
1133 int first_split_diff
= diff
/ 2;
1134 int second_split_diff
= first_split_diff
;
1138 if (first_win
->height
>
1147 second_split_diff
--;
1149 second_split_diff
++;
1152 /* Make sure that the minimum hieghts are
1154 while ((first_win
->height
+ first_split_diff
) < 3)
1157 second_split_diff
--;
1159 while ((second_win
->height
+ second_split_diff
) < 3)
1161 second_split_diff
++;
1164 make_invisible_and_set_new_height (
1166 first_win
->height
+ first_split_diff
);
1167 second_win
->origin
.y
= first_win
->height
- 1;
1168 make_invisible_and_set_new_height (second_win
,
1170 + second_split_diff
);
1171 TUI_CMD_WIN
->origin
.y
= locator
->origin
.y
+ 1;
1172 make_invisible_and_set_new_height (TUI_CMD_WIN
, new_height
);
1176 if ((TUI_CMD_WIN
->height
+ diff
) < 1)
1177 { /* If there is no way to increase the command
1178 window take real estate from the 1st or 2nd
1180 if ((TUI_CMD_WIN
->height
+ diff
) < 1)
1184 for (i
= TUI_CMD_WIN
->height
+ diff
;
1186 if (primary_win_info
== first_win
)
1187 second_win
->height
--;
1189 first_win
->height
--;
1192 if (primary_win_info
== first_win
)
1193 make_invisible_and_set_new_height (first_win
, new_height
);
1195 make_invisible_and_set_new_height (
1198 second_win
->origin
.y
= first_win
->height
- 1;
1199 if (primary_win_info
== second_win
)
1200 make_invisible_and_set_new_height (second_win
, new_height
);
1202 make_invisible_and_set_new_height (
1203 second_win
, second_win
->height
);
1204 TUI_CMD_WIN
->origin
.y
= locator
->origin
.y
+ 1;
1205 if ((TUI_CMD_WIN
->height
+ diff
) < 1)
1206 make_invisible_and_set_new_height (TUI_CMD_WIN
, 1);
1208 make_invisible_and_set_new_height (TUI_CMD_WIN
,
1209 TUI_CMD_WIN
->height
+ diff
);
1211 TUI_CMD_WIN
->make_visible_with_new_height ();
1212 second_win
->make_visible_with_new_height ();
1213 first_win
->make_visible_with_new_height ();
1214 if (src1
!= nullptr && src1
->content
.empty ())
1215 tui_erase_source_content (src1
);
1216 if (second_win
->content
.empty ())
1217 tui_erase_source_content (second_win
);
1226 /* See tui-data.h. */
1229 tui_source_window_base::set_new_height (int height
)
1231 tui_make_invisible (execution_info
);
1232 execution_info
->height
= height
;
1233 execution_info
->origin
.y
= origin
.y
;
1235 execution_info
->viewport_height
= height
- 1;
1237 execution_info
->viewport_height
= height
;
1238 execution_info
->viewport_height
--;
1242 tui_locator_window
*gen_win_info
= tui_locator_win_info_ptr ();
1243 tui_make_invisible (gen_win_info
);
1244 gen_win_info
->origin
.y
= origin
.y
+ height
;
1248 /* See tui-data.h. */
1251 tui_data_window::set_new_height (int height
)
1253 /* Delete all data item windows. */
1254 for (auto &&win
: regs_content
)
1256 tui_delete_win (win
->handle
);
1261 /* Function make the target window (and auxiliary windows associated
1262 with the targer) invisible, and set the new height and
1265 make_invisible_and_set_new_height (struct tui_win_info
*win_info
,
1268 tui_make_invisible (win_info
);
1269 win_info
->height
= height
;
1271 win_info
->viewport_height
= height
- 1;
1273 win_info
->viewport_height
= height
;
1274 if (win_info
!= TUI_CMD_WIN
)
1275 win_info
->viewport_height
--;
1277 /* Now deal with the auxiliary windows associated with win_info. */
1278 win_info
->set_new_height (height
);
1282 /* See tui-data.h. */
1285 tui_win_info::make_visible_with_new_height ()
1287 make_visible (true);
1288 tui_check_and_display_highlight_if_needed (this);
1289 do_make_visible_with_new_height ();
1292 /* See tui-data.h. */
1295 tui_source_window_base::do_make_visible_with_new_height ()
1297 tui_make_visible (execution_info
);
1298 if (!content
.empty ())
1300 struct tui_line_or_address line_or_addr
;
1301 struct symtab_and_line cursal
1302 = get_current_source_symtab_and_line ();
1304 line_or_addr
= start_line_or_addr
;
1305 tui_update_source_window (this, gdbarch
,
1306 cursal
.symtab
, line_or_addr
, TRUE
);
1308 else if (deprecated_safe_get_selected_frame () != NULL
)
1310 struct tui_line_or_address line
;
1311 struct symtab_and_line cursal
1312 = get_current_source_symtab_and_line ();
1313 struct frame_info
*frame
= deprecated_safe_get_selected_frame ();
1314 struct gdbarch
*gdbarch
= get_frame_arch (frame
);
1316 struct symtab
*s
= find_pc_line_symtab (get_frame_pc (frame
));
1317 if (type
== SRC_WIN
)
1319 line
.loa
= LOA_LINE
;
1320 line
.u
.line_no
= cursal
.line
;
1324 line
.loa
= LOA_ADDRESS
;
1325 find_line_pc (s
, cursal
.line
, &line
.u
.addr
);
1327 tui_update_source_window (this, gdbarch
, s
, line
, TRUE
);
1331 tui_make_visible (tui_locator_win_info_ptr ());
1332 tui_show_locator_content ();
1336 /* See tui-data.h. */
1339 tui_data_window::do_make_visible_with_new_height ()
1341 display_all_data ();
1344 /* See tui-data.h. */
1347 tui_cmd_window::do_make_visible_with_new_height ()
1350 wresize (handle
, height
, width
);
1352 mvwin (handle
, origin
.y
, origin
.x
);
1353 wmove (handle
, 0, 0);
1356 /* See tui-data.h. */
1359 tui_win_info::max_height () const
1361 return tui_term_height () - 2;
1364 /* See tui-data.h. */
1367 tui_cmd_window::max_height () const
1369 return tui_term_height () - 4;
1373 new_height_ok (struct tui_win_info
*primary_win_info
,
1376 int ok
= (new_height
< tui_term_height ());
1381 enum tui_layout_type cur_layout
= tui_current_layout ();
1383 diff
= (new_height
- primary_win_info
->height
) * (-1);
1384 if (cur_layout
== SRC_COMMAND
|| cur_layout
== DISASSEM_COMMAND
)
1386 ok
= (new_height
<= primary_win_info
->max_height ()
1387 && new_height
>= MIN_CMD_WIN_HEIGHT
);
1389 { /* Check the total height. */
1390 struct tui_win_info
*win_info
;
1392 if (primary_win_info
== TUI_CMD_WIN
)
1393 win_info
= tui_source_windows ()[0];
1395 win_info
= TUI_CMD_WIN
;
1397 (win_info
->height
+ diff
)) <= tui_term_height ());
1402 int cur_total_height
, total_height
, min_height
= 0;
1403 struct tui_win_info
*first_win
;
1404 struct tui_win_info
*second_win
;
1406 if (cur_layout
== SRC_DISASSEM_COMMAND
)
1408 first_win
= TUI_SRC_WIN
;
1409 second_win
= TUI_DISASM_WIN
;
1413 first_win
= TUI_DATA_WIN
;
1414 second_win
= tui_source_windows ()[0];
1416 /* We could simply add all the heights to obtain the same
1417 result but below is more explicit since we subtract 1 for
1418 the line that the first and second windows share, and add
1419 one for the locator. */
1420 total_height
= cur_total_height
=
1421 (first_win
->height
+ second_win
->height
- 1)
1422 + TUI_CMD_WIN
->height
+ 1; /* Locator. */
1423 if (primary_win_info
== TUI_CMD_WIN
)
1425 /* Locator included since first & second win share a line. */
1426 ok
= ((first_win
->height
+
1427 second_win
->height
+ diff
) >=
1428 (MIN_WIN_HEIGHT
* 2)
1429 && new_height
>= MIN_CMD_WIN_HEIGHT
);
1432 total_height
= new_height
+
1433 (first_win
->height
+
1434 second_win
->height
+ diff
);
1435 min_height
= MIN_CMD_WIN_HEIGHT
;
1440 min_height
= MIN_WIN_HEIGHT
;
1442 /* First see if we can increase/decrease the command
1443 window. And make sure that the command window is at
1445 ok
= ((TUI_CMD_WIN
->height
+ diff
) > 0);
1447 { /* Looks like we have to increase/decrease one of
1448 the other windows. */
1449 if (primary_win_info
== first_win
)
1450 ok
= (second_win
->height
+ diff
) >= min_height
;
1452 ok
= (first_win
->height
+ diff
) >= min_height
;
1456 if (primary_win_info
== first_win
)
1457 total_height
= new_height
+
1458 second_win
->height
+
1459 TUI_CMD_WIN
->height
+ diff
;
1461 total_height
= new_height
+
1463 TUI_CMD_WIN
->height
+ diff
;
1466 /* Now make sure that the proposed total height doesn't
1467 exceed the old total height. */
1469 ok
= (new_height
>= min_height
1470 && total_height
<= cur_total_height
);
1479 parse_scrolling_args (const char *arg
,
1480 struct tui_win_info
**win_to_scroll
,
1485 *win_to_scroll
= tui_win_with_focus ();
1487 /* First set up the default window to scroll, in case there is no
1493 /* Process the number of lines to scroll. */
1494 std::string copy
= arg
;
1496 if (isdigit (*buf_ptr
))
1501 buf_ptr
= strchr (buf_ptr
, ' ');
1502 if (buf_ptr
!= NULL
)
1504 *buf_ptr
= (char) 0;
1506 *num_to_scroll
= atoi (num_str
);
1509 else if (num_to_scroll
)
1510 *num_to_scroll
= atoi (num_str
);
1513 /* Process the window name if one is specified. */
1514 if (buf_ptr
!= NULL
)
1518 if (*buf_ptr
== ' ')
1519 while (*(++buf_ptr
) == ' ')
1522 if (*buf_ptr
!= (char) 0)
1524 /* Validate the window name. */
1525 for (char *p
= buf_ptr
; *p
!= '\0'; p
++)
1533 *win_to_scroll
= tui_partial_win_by_name (wname
);
1535 if (*win_to_scroll
== NULL
1536 || !(*win_to_scroll
)->is_visible
)
1537 error (_("Invalid window specified. \n\
1538 The window name specified must be valid and visible.\n"));
1539 else if (*win_to_scroll
== TUI_CMD_WIN
)
1540 *win_to_scroll
= tui_source_windows ()[0];
1545 /* Function to initialize gdb commands, for tui window
1549 _initialize_tui_win (void)
1551 static struct cmd_list_element
*tui_setlist
;
1552 static struct cmd_list_element
*tui_showlist
;
1553 struct cmd_list_element
*cmd
;
1555 /* Define the classes of commands.
1556 They will appear in the help list in the reverse of this order. */
1557 add_prefix_cmd ("tui", class_tui
, set_tui_cmd
,
1558 _("TUI configuration variables"),
1559 &tui_setlist
, "set tui ",
1560 0 /* allow-unknown */, &setlist
);
1561 add_prefix_cmd ("tui", class_tui
, show_tui_cmd
,
1562 _("TUI configuration variables"),
1563 &tui_showlist
, "show tui ",
1564 0 /* allow-unknown */, &showlist
);
1566 add_com ("refresh", class_tui
, tui_refresh_all_command
,
1567 _("Refresh the terminal display."));
1569 cmd
= add_com ("tabset", class_tui
, tui_set_tab_width_command
, _("\
1570 Set the width (in characters) of tab stops.\n\
1572 deprecate_cmd (cmd
, "set tui tab-width");
1574 cmd
= add_com ("winheight", class_tui
, tui_set_win_height_command
, _("\
1575 Set or modify the height of a specified window.\n"
1577 "Window names are:\n\
1578 src : the source window\n\
1579 cmd : the command window\n\
1580 asm : the disassembly window\n\
1581 regs : the register display"));
1582 add_com_alias ("wh", "winheight", class_tui
, 0);
1583 set_cmd_completer (cmd
, winheight_completer
);
1584 add_info ("win", tui_all_windows_info
,
1585 _("List of all displayed windows."));
1586 cmd
= add_com ("focus", class_tui
, tui_set_focus_command
, _("\
1587 Set focus to named window or next/prev window.\n"
1589 "Valid Window names are:\n\
1590 src : the source window\n\
1591 asm : the disassembly window\n\
1592 regs : the register display\n\
1593 cmd : the command window"));
1594 add_com_alias ("fs", "focus", class_tui
, 0);
1595 set_cmd_completer (cmd
, focus_completer
);
1596 add_com ("+", class_tui
, tui_scroll_forward_command
, _("\
1597 Scroll window forward.\n\
1598 Usage: + [WIN] [N]"));
1599 add_com ("-", class_tui
, tui_scroll_backward_command
, _("\
1600 Scroll window backward.\n\
1601 Usage: - [WIN] [N]"));
1602 add_com ("<", class_tui
, tui_scroll_left_command
, _("\
1603 Scroll window text to the left.\n\
1604 Usage: < [WIN] [N]"));
1605 add_com (">", class_tui
, tui_scroll_right_command
, _("\
1606 Scroll window text to the right.\n\
1607 Usage: > [WIN] [N]"));
1609 /* Define the tui control variables. */
1610 add_setshow_enum_cmd ("border-kind", no_class
, tui_border_kind_enums
,
1611 &tui_border_kind
, _("\
1612 Set the kind of border for TUI windows."), _("\
1613 Show the kind of border for TUI windows."), _("\
1614 This variable controls the border of TUI windows:\n\
1615 space use a white space\n\
1616 ascii use ascii characters + - | for the border\n\
1617 acs use the Alternate Character Set"),
1619 show_tui_border_kind
,
1620 &tui_setlist
, &tui_showlist
);
1622 add_setshow_enum_cmd ("border-mode", no_class
, tui_border_mode_enums
,
1623 &tui_border_mode
, _("\
1624 Set the attribute mode to use for the TUI window borders."), _("\
1625 Show the attribute mode to use for the TUI window borders."), _("\
1626 This variable controls the attributes to use for the window borders:\n\
1627 normal normal display\n\
1628 standout use highlight mode of terminal\n\
1629 reverse use reverse video mode\n\
1630 half use half bright\n\
1631 half-standout use half bright and standout mode\n\
1632 bold use extra bright or bold\n\
1633 bold-standout use extra bright or bold with standout mode"),
1635 show_tui_border_mode
,
1636 &tui_setlist
, &tui_showlist
);
1638 add_setshow_enum_cmd ("active-border-mode", no_class
, tui_border_mode_enums
,
1639 &tui_active_border_mode
, _("\
1640 Set the attribute mode to use for the active TUI window border."), _("\
1641 Show the attribute mode to use for the active TUI window border."), _("\
1642 This variable controls the attributes to use for the active window border:\n\
1643 normal normal display\n\
1644 standout use highlight mode of terminal\n\
1645 reverse use reverse video mode\n\
1646 half use half bright\n\
1647 half-standout use half bright and standout mode\n\
1648 bold use extra bright or bold\n\
1649 bold-standout use extra bright or bold with standout mode"),
1651 show_tui_active_border_mode
,
1652 &tui_setlist
, &tui_showlist
);
1654 add_setshow_zuinteger_cmd ("tab-width", no_class
,
1655 &internal_tab_width
, _("\
1656 Set the tab width, in characters, for the TUI."), _("\
1657 Show the tab witdh, in characters, for the TUI"), _("\
1658 This variable controls how many spaces are used to display a tab character."),
1659 tui_set_tab_width
, tui_show_tab_width
,
1660 &tui_setlist
, &tui_showlist
);