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
));
861 printf_filtered (_("Focus set to %s window.\n"),
862 tui_win_with_focus ()->name ());
865 warning (_("Incorrect Number of Arguments.\n%s"), FOCUS_USAGE
);
869 tui_all_windows_info (const char *arg
, int from_tty
)
871 struct tui_win_info
*win_with_focus
= tui_win_with_focus ();
873 for (tui_win_info
*win_info
: all_tui_windows ())
874 if (win_info
->is_visible
)
876 if (win_with_focus
== win_info
)
877 printf_filtered (" %s\t(%d lines) <has focus>\n",
881 printf_filtered (" %s\t(%d lines)\n",
889 tui_refresh_all_command (const char *arg
, int from_tty
)
891 /* Make sure the curses mode is enabled. */
894 tui_refresh_all_win ();
897 /* The tab width that should be used by the TUI. */
899 unsigned int tui_tab_width
= DEFAULT_TAB_LEN
;
901 /* The tab width as set by the user. */
903 static unsigned int internal_tab_width
= DEFAULT_TAB_LEN
;
905 /* See tui-data.h. */
908 tui_source_window_base::update_tab_width ()
910 /* We don't really change the height of any windows, but
911 calling these 2 functions causes a complete regeneration
912 and redisplay of the window's contents, which will take
913 the new tab width into account. */
914 make_invisible_and_set_new_height (this, height
);
915 make_visible_with_new_height ();
918 /* After the tab width is set, call this to update the relevant
924 for (tui_win_info
*win_info
: all_tui_windows ())
926 if (win_info
->is_visible
)
927 win_info
->update_tab_width ();
931 /* Callback for "set tui tab-width". */
934 tui_set_tab_width (const char *ignore
,
935 int from_tty
, struct cmd_list_element
*c
)
937 if (internal_tab_width
== 0)
939 internal_tab_width
= tui_tab_width
;
940 error (_("Tab width must not be 0"));
943 tui_tab_width
= internal_tab_width
;
947 /* Callback for "show tui tab-width". */
950 tui_show_tab_width (struct ui_file
*file
, int from_tty
,
951 struct cmd_list_element
*c
, const char *value
)
953 fprintf_filtered (gdb_stdout
, _("TUI tab width is %s spaces.\n"), value
);
957 /* Set the tab width of the specified window. */
959 tui_set_tab_width_command (const char *arg
, int from_tty
)
961 /* Make sure the curses mode is enabled. */
969 warning (_("Tab widths greater than 0 must be specified."));
972 internal_tab_width
= ts
;
981 /* Set the height of the specified window. */
983 tui_set_win_height_command (const char *arg
, int from_tty
)
985 /* Make sure the curses mode is enabled. */
989 std::string copy
= arg
;
990 char *buf
= ©
[0];
994 struct tui_win_info
*win_info
;
997 buf_ptr
= strchr (buf_ptr
, ' ');
1000 *buf_ptr
= (char) 0;
1002 /* Validate the window name. */
1003 for (i
= 0; i
< strlen (wname
); i
++)
1004 wname
[i
] = tolower (wname
[i
]);
1005 win_info
= tui_partial_win_by_name (wname
);
1007 if (win_info
== NULL
|| !win_info
->is_visible
)
1008 warning (_("Invalid window specified. \n\
1009 The window name specified must be valid and visible.\n"));
1012 /* Process the size. */
1013 while (*(++buf_ptr
) == ' ')
1016 if (*buf_ptr
!= (char) 0)
1019 int fixed_size
= TRUE
;
1022 if (*buf_ptr
== '+' || *buf_ptr
== '-')
1024 if (*buf_ptr
== '-')
1029 input_no
= atoi (buf_ptr
);
1035 new_height
= input_no
;
1037 new_height
= win_info
->height
+ input_no
;
1039 /* Now change the window's height, and adjust
1040 all other windows around it. */
1041 if (tui_adjust_win_heights (win_info
,
1042 new_height
) == TUI_FAILURE
)
1043 warning (_("Invalid window height specified.\n%s"),
1046 tui_update_gdb_sizes ();
1049 warning (_("Invalid window height specified.\n%s"),
1055 printf_filtered (WIN_HEIGHT_USAGE
);
1058 printf_filtered (WIN_HEIGHT_USAGE
);
1061 /* Function to adjust all window heights around the primary. */
1062 static enum tui_status
1063 tui_adjust_win_heights (struct tui_win_info
*primary_win_info
,
1066 enum tui_status status
= TUI_FAILURE
;
1068 if (new_height_ok (primary_win_info
, new_height
))
1070 status
= TUI_SUCCESS
;
1071 if (new_height
!= primary_win_info
->height
)
1074 struct tui_win_info
*win_info
;
1075 struct tui_locator_window
*locator
= tui_locator_win_info_ptr ();
1076 enum tui_layout_type cur_layout
= tui_current_layout ();
1078 diff
= (new_height
- primary_win_info
->height
) * (-1);
1079 if (cur_layout
== SRC_COMMAND
1080 || cur_layout
== DISASSEM_COMMAND
)
1082 struct tui_win_info
*src_win_info
;
1084 make_invisible_and_set_new_height (primary_win_info
, new_height
);
1085 if (primary_win_info
->type
== CMD_WIN
)
1087 win_info
= tui_source_windows ()[0];
1088 src_win_info
= win_info
;
1092 win_info
= tui_win_list
[CMD_WIN
];
1093 src_win_info
= primary_win_info
;
1095 make_invisible_and_set_new_height (win_info
,
1096 win_info
->height
+ diff
);
1097 TUI_CMD_WIN
->origin
.y
= locator
->origin
.y
+ 1;
1098 win_info
->make_visible_with_new_height ();
1099 primary_win_info
->make_visible_with_new_height ();
1100 if ((src_win_info
->type
== SRC_WIN
1101 || src_win_info
->type
== DISASSEM_WIN
))
1103 tui_source_window_base
*src_base
1104 = (tui_source_window_base
*) src_win_info
;
1105 if (src_base
->content
.empty ())
1106 tui_erase_source_content (src_base
);
1111 struct tui_win_info
*first_win
;
1112 struct tui_source_window_base
*second_win
;
1113 tui_source_window_base
*src1
;
1115 if (cur_layout
== SRC_DISASSEM_COMMAND
)
1119 second_win
= TUI_DISASM_WIN
;
1124 first_win
= TUI_DATA_WIN
;
1125 second_win
= tui_source_windows ()[0];
1127 if (primary_win_info
== TUI_CMD_WIN
)
1128 { /* Split the change in height accross the 1st & 2nd
1129 windows, adjusting them as well. */
1130 /* Subtract the locator. */
1131 int first_split_diff
= diff
/ 2;
1132 int second_split_diff
= first_split_diff
;
1136 if (first_win
->height
>
1145 second_split_diff
--;
1147 second_split_diff
++;
1150 /* Make sure that the minimum hieghts are
1152 while ((first_win
->height
+ first_split_diff
) < 3)
1155 second_split_diff
--;
1157 while ((second_win
->height
+ second_split_diff
) < 3)
1159 second_split_diff
++;
1162 make_invisible_and_set_new_height (
1164 first_win
->height
+ first_split_diff
);
1165 second_win
->origin
.y
= first_win
->height
- 1;
1166 make_invisible_and_set_new_height (second_win
,
1168 + second_split_diff
);
1169 TUI_CMD_WIN
->origin
.y
= locator
->origin
.y
+ 1;
1170 make_invisible_and_set_new_height (TUI_CMD_WIN
, new_height
);
1174 if ((TUI_CMD_WIN
->height
+ diff
) < 1)
1175 { /* If there is no way to increase the command
1176 window take real estate from the 1st or 2nd
1178 if ((TUI_CMD_WIN
->height
+ diff
) < 1)
1182 for (i
= TUI_CMD_WIN
->height
+ diff
;
1184 if (primary_win_info
== first_win
)
1185 second_win
->height
--;
1187 first_win
->height
--;
1190 if (primary_win_info
== first_win
)
1191 make_invisible_and_set_new_height (first_win
, new_height
);
1193 make_invisible_and_set_new_height (
1196 second_win
->origin
.y
= first_win
->height
- 1;
1197 if (primary_win_info
== second_win
)
1198 make_invisible_and_set_new_height (second_win
, new_height
);
1200 make_invisible_and_set_new_height (
1201 second_win
, second_win
->height
);
1202 TUI_CMD_WIN
->origin
.y
= locator
->origin
.y
+ 1;
1203 if ((TUI_CMD_WIN
->height
+ diff
) < 1)
1204 make_invisible_and_set_new_height (TUI_CMD_WIN
, 1);
1206 make_invisible_and_set_new_height (TUI_CMD_WIN
,
1207 TUI_CMD_WIN
->height
+ diff
);
1209 TUI_CMD_WIN
->make_visible_with_new_height ();
1210 second_win
->make_visible_with_new_height ();
1211 first_win
->make_visible_with_new_height ();
1212 if (src1
!= nullptr && src1
->content
.empty ())
1213 tui_erase_source_content (src1
);
1214 if (second_win
->content
.empty ())
1215 tui_erase_source_content (second_win
);
1224 /* See tui-data.h. */
1227 tui_source_window_base::set_new_height (int height
)
1229 tui_make_invisible (execution_info
);
1230 execution_info
->height
= height
;
1231 execution_info
->origin
.y
= origin
.y
;
1233 execution_info
->viewport_height
= height
- 1;
1235 execution_info
->viewport_height
= height
;
1236 execution_info
->viewport_height
--;
1240 tui_locator_window
*gen_win_info
= tui_locator_win_info_ptr ();
1241 tui_make_invisible (gen_win_info
);
1242 gen_win_info
->origin
.y
= origin
.y
+ height
;
1246 /* See tui-data.h. */
1249 tui_data_window::set_new_height (int height
)
1251 /* Delete all data item windows. */
1252 for (auto &&win
: regs_content
)
1254 tui_delete_win (win
->handle
);
1259 /* Function make the target window (and auxiliary windows associated
1260 with the targer) invisible, and set the new height and
1263 make_invisible_and_set_new_height (struct tui_win_info
*win_info
,
1266 tui_make_invisible (win_info
);
1267 win_info
->height
= height
;
1269 win_info
->viewport_height
= height
- 1;
1271 win_info
->viewport_height
= height
;
1272 if (win_info
!= TUI_CMD_WIN
)
1273 win_info
->viewport_height
--;
1275 /* Now deal with the auxiliary windows associated with win_info. */
1276 win_info
->set_new_height (height
);
1280 /* See tui-data.h. */
1283 tui_win_info::make_visible_with_new_height ()
1285 make_visible (true);
1286 tui_check_and_display_highlight_if_needed (this);
1287 do_make_visible_with_new_height ();
1290 /* See tui-data.h. */
1293 tui_source_window_base::do_make_visible_with_new_height ()
1295 tui_make_visible (execution_info
);
1296 if (!content
.empty ())
1298 struct tui_line_or_address line_or_addr
;
1299 struct symtab_and_line cursal
1300 = get_current_source_symtab_and_line ();
1302 line_or_addr
= start_line_or_addr
;
1303 tui_update_source_window (this, gdbarch
,
1304 cursal
.symtab
, line_or_addr
, TRUE
);
1306 else if (deprecated_safe_get_selected_frame () != NULL
)
1308 struct tui_line_or_address line
;
1309 struct symtab_and_line cursal
1310 = get_current_source_symtab_and_line ();
1311 struct frame_info
*frame
= deprecated_safe_get_selected_frame ();
1312 struct gdbarch
*gdbarch
= get_frame_arch (frame
);
1314 struct symtab
*s
= find_pc_line_symtab (get_frame_pc (frame
));
1315 if (type
== SRC_WIN
)
1317 line
.loa
= LOA_LINE
;
1318 line
.u
.line_no
= cursal
.line
;
1322 line
.loa
= LOA_ADDRESS
;
1323 find_line_pc (s
, cursal
.line
, &line
.u
.addr
);
1325 tui_update_source_window (this, gdbarch
, s
, line
, TRUE
);
1329 tui_make_visible (tui_locator_win_info_ptr ());
1330 tui_show_locator_content ();
1334 /* See tui-data.h. */
1337 tui_data_window::do_make_visible_with_new_height ()
1339 display_all_data ();
1342 /* See tui-data.h. */
1345 tui_cmd_window::do_make_visible_with_new_height ()
1348 wresize (handle
, height
, width
);
1350 mvwin (handle
, origin
.y
, origin
.x
);
1351 wmove (handle
, 0, 0);
1354 /* See tui-data.h. */
1357 tui_win_info::max_height () const
1359 return tui_term_height () - 2;
1362 /* See tui-data.h. */
1365 tui_cmd_window::max_height () const
1367 return tui_term_height () - 4;
1371 new_height_ok (struct tui_win_info
*primary_win_info
,
1374 int ok
= (new_height
< tui_term_height ());
1379 enum tui_layout_type cur_layout
= tui_current_layout ();
1381 diff
= (new_height
- primary_win_info
->height
) * (-1);
1382 if (cur_layout
== SRC_COMMAND
|| cur_layout
== DISASSEM_COMMAND
)
1384 ok
= (new_height
<= primary_win_info
->max_height ()
1385 && new_height
>= MIN_CMD_WIN_HEIGHT
);
1387 { /* Check the total height. */
1388 struct tui_win_info
*win_info
;
1390 if (primary_win_info
== TUI_CMD_WIN
)
1391 win_info
= tui_source_windows ()[0];
1393 win_info
= TUI_CMD_WIN
;
1395 (win_info
->height
+ diff
)) <= tui_term_height ());
1400 int cur_total_height
, total_height
, min_height
= 0;
1401 struct tui_win_info
*first_win
;
1402 struct tui_win_info
*second_win
;
1404 if (cur_layout
== SRC_DISASSEM_COMMAND
)
1406 first_win
= TUI_SRC_WIN
;
1407 second_win
= TUI_DISASM_WIN
;
1411 first_win
= TUI_DATA_WIN
;
1412 second_win
= tui_source_windows ()[0];
1414 /* We could simply add all the heights to obtain the same
1415 result but below is more explicit since we subtract 1 for
1416 the line that the first and second windows share, and add
1417 one for the locator. */
1418 total_height
= cur_total_height
=
1419 (first_win
->height
+ second_win
->height
- 1)
1420 + TUI_CMD_WIN
->height
+ 1; /* Locator. */
1421 if (primary_win_info
== TUI_CMD_WIN
)
1423 /* Locator included since first & second win share a line. */
1424 ok
= ((first_win
->height
+
1425 second_win
->height
+ diff
) >=
1426 (MIN_WIN_HEIGHT
* 2)
1427 && new_height
>= MIN_CMD_WIN_HEIGHT
);
1430 total_height
= new_height
+
1431 (first_win
->height
+
1432 second_win
->height
+ diff
);
1433 min_height
= MIN_CMD_WIN_HEIGHT
;
1438 min_height
= MIN_WIN_HEIGHT
;
1440 /* First see if we can increase/decrease the command
1441 window. And make sure that the command window is at
1443 ok
= ((TUI_CMD_WIN
->height
+ diff
) > 0);
1445 { /* Looks like we have to increase/decrease one of
1446 the other windows. */
1447 if (primary_win_info
== first_win
)
1448 ok
= (second_win
->height
+ diff
) >= min_height
;
1450 ok
= (first_win
->height
+ diff
) >= min_height
;
1454 if (primary_win_info
== first_win
)
1455 total_height
= new_height
+
1456 second_win
->height
+
1457 TUI_CMD_WIN
->height
+ diff
;
1459 total_height
= new_height
+
1461 TUI_CMD_WIN
->height
+ diff
;
1464 /* Now make sure that the proposed total height doesn't
1465 exceed the old total height. */
1467 ok
= (new_height
>= min_height
1468 && total_height
<= cur_total_height
);
1477 parse_scrolling_args (const char *arg
,
1478 struct tui_win_info
**win_to_scroll
,
1483 *win_to_scroll
= tui_win_with_focus ();
1485 /* First set up the default window to scroll, in case there is no
1491 /* Process the number of lines to scroll. */
1492 std::string copy
= arg
;
1494 if (isdigit (*buf_ptr
))
1499 buf_ptr
= strchr (buf_ptr
, ' ');
1500 if (buf_ptr
!= NULL
)
1502 *buf_ptr
= (char) 0;
1504 *num_to_scroll
= atoi (num_str
);
1507 else if (num_to_scroll
)
1508 *num_to_scroll
= atoi (num_str
);
1511 /* Process the window name if one is specified. */
1512 if (buf_ptr
!= NULL
)
1516 if (*buf_ptr
== ' ')
1517 while (*(++buf_ptr
) == ' ')
1520 if (*buf_ptr
!= (char) 0)
1522 /* Validate the window name. */
1523 for (char *p
= buf_ptr
; *p
!= '\0'; p
++)
1531 *win_to_scroll
= tui_partial_win_by_name (wname
);
1533 if (*win_to_scroll
== NULL
1534 || !(*win_to_scroll
)->is_visible
)
1535 error (_("Invalid window specified. \n\
1536 The window name specified must be valid and visible.\n"));
1537 else if (*win_to_scroll
== TUI_CMD_WIN
)
1538 *win_to_scroll
= tui_source_windows ()[0];
1543 /* Function to initialize gdb commands, for tui window
1547 _initialize_tui_win (void)
1549 static struct cmd_list_element
*tui_setlist
;
1550 static struct cmd_list_element
*tui_showlist
;
1551 struct cmd_list_element
*cmd
;
1553 /* Define the classes of commands.
1554 They will appear in the help list in the reverse of this order. */
1555 add_prefix_cmd ("tui", class_tui
, set_tui_cmd
,
1556 _("TUI configuration variables"),
1557 &tui_setlist
, "set tui ",
1558 0 /* allow-unknown */, &setlist
);
1559 add_prefix_cmd ("tui", class_tui
, show_tui_cmd
,
1560 _("TUI configuration variables"),
1561 &tui_showlist
, "show tui ",
1562 0 /* allow-unknown */, &showlist
);
1564 add_com ("refresh", class_tui
, tui_refresh_all_command
,
1565 _("Refresh the terminal display."));
1567 cmd
= add_com ("tabset", class_tui
, tui_set_tab_width_command
, _("\
1568 Set the width (in characters) of tab stops.\n\
1570 deprecate_cmd (cmd
, "set tui tab-width");
1572 cmd
= add_com ("winheight", class_tui
, tui_set_win_height_command
, _("\
1573 Set or modify the height of a specified window.\n"
1575 "Window names are:\n\
1576 src : the source window\n\
1577 cmd : the command window\n\
1578 asm : the disassembly window\n\
1579 regs : the register display"));
1580 add_com_alias ("wh", "winheight", class_tui
, 0);
1581 set_cmd_completer (cmd
, winheight_completer
);
1582 add_info ("win", tui_all_windows_info
,
1583 _("List of all displayed windows."));
1584 cmd
= add_com ("focus", class_tui
, tui_set_focus_command
, _("\
1585 Set focus to named window or next/prev window.\n"
1587 "Valid Window names are:\n\
1588 src : the source window\n\
1589 asm : the disassembly window\n\
1590 regs : the register display\n\
1591 cmd : the command window"));
1592 add_com_alias ("fs", "focus", class_tui
, 0);
1593 set_cmd_completer (cmd
, focus_completer
);
1594 add_com ("+", class_tui
, tui_scroll_forward_command
, _("\
1595 Scroll window forward.\n\
1596 Usage: + [WIN] [N]"));
1597 add_com ("-", class_tui
, tui_scroll_backward_command
, _("\
1598 Scroll window backward.\n\
1599 Usage: - [WIN] [N]"));
1600 add_com ("<", class_tui
, tui_scroll_left_command
, _("\
1601 Scroll window text to the left.\n\
1602 Usage: < [WIN] [N]"));
1603 add_com (">", class_tui
, tui_scroll_right_command
, _("\
1604 Scroll window text to the right.\n\
1605 Usage: > [WIN] [N]"));
1607 /* Define the tui control variables. */
1608 add_setshow_enum_cmd ("border-kind", no_class
, tui_border_kind_enums
,
1609 &tui_border_kind
, _("\
1610 Set the kind of border for TUI windows."), _("\
1611 Show the kind of border for TUI windows."), _("\
1612 This variable controls the border of TUI windows:\n\
1613 space use a white space\n\
1614 ascii use ascii characters + - | for the border\n\
1615 acs use the Alternate Character Set"),
1617 show_tui_border_kind
,
1618 &tui_setlist
, &tui_showlist
);
1620 add_setshow_enum_cmd ("border-mode", no_class
, tui_border_mode_enums
,
1621 &tui_border_mode
, _("\
1622 Set the attribute mode to use for the TUI window borders."), _("\
1623 Show the attribute mode to use for the TUI window borders."), _("\
1624 This variable controls the attributes to use for the window borders:\n\
1625 normal normal display\n\
1626 standout use highlight mode of terminal\n\
1627 reverse use reverse video mode\n\
1628 half use half bright\n\
1629 half-standout use half bright and standout mode\n\
1630 bold use extra bright or bold\n\
1631 bold-standout use extra bright or bold with standout mode"),
1633 show_tui_border_mode
,
1634 &tui_setlist
, &tui_showlist
);
1636 add_setshow_enum_cmd ("active-border-mode", no_class
, tui_border_mode_enums
,
1637 &tui_active_border_mode
, _("\
1638 Set the attribute mode to use for the active TUI window border."), _("\
1639 Show the attribute mode to use for the active TUI window border."), _("\
1640 This variable controls the attributes to use for the active window border:\n\
1641 normal normal display\n\
1642 standout use highlight mode of terminal\n\
1643 reverse use reverse video mode\n\
1644 half use half bright\n\
1645 half-standout use half bright and standout mode\n\
1646 bold use extra bright or bold\n\
1647 bold-standout use extra bright or bold with standout mode"),
1649 show_tui_active_border_mode
,
1650 &tui_setlist
, &tui_showlist
);
1652 add_setshow_zuinteger_cmd ("tab-width", no_class
,
1653 &internal_tab_width
, _("\
1654 Set the tab width, in characters, for the TUI."), _("\
1655 Show the tab witdh, in characters, for the TUI"), _("\
1656 This variable controls how many spaces are used to display a tab character."),
1657 tui_set_tab_width
, tui_show_tab_width
,
1658 &tui_setlist
, &tui_showlist
);