1 /* TUI window generic functions.
3 Copyright (C) 1998-2017 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_visible_with_new_height (struct tui_win_info
*);
59 static void make_invisible_and_set_new_height (struct tui_win_info
*,
61 static enum tui_status
tui_adjust_win_heights (struct tui_win_info
*,
63 static int new_height_ok (struct tui_win_info
*, int);
64 static void tui_set_tab_width_command (char *, int);
65 static void tui_refresh_all_command (char *, int);
66 static void tui_set_win_height_command (char *, int);
67 static void tui_all_windows_info (char *, int);
68 static void tui_set_focus_command (char *, int);
69 static void tui_scroll_forward_command (char *, int);
70 static void tui_scroll_backward_command (char *, int);
71 static void tui_scroll_left_command (char *, int);
72 static void tui_scroll_right_command (char *, int);
73 static void parse_scrolling_args (char *,
74 struct tui_win_info
**,
78 /***************************************
80 ***************************************/
81 #define WIN_HEIGHT_USAGE "Usage: winheight <win_name> [+ | -] <#lines>\n"
82 #define XDBWIN_HEIGHT_USAGE "Usage: w <#lines>\n"
83 #define FOCUS_USAGE "Usage: focus {<win> | next | prev}\n"
85 /***************************************
87 ***************************************/
90 # define ACS_LRCORNER '+'
93 # define ACS_LLCORNER '+'
96 # define ACS_ULCORNER '+'
99 # define ACS_URCORNER '+'
102 # define ACS_HLINE '-'
105 # define ACS_VLINE '|'
108 /* Possible values for tui-border-kind variable. */
109 static const char *const tui_border_kind_enums
[] = {
116 /* Possible values for tui-border-mode and tui-active-border-mode. */
117 static const char *const tui_border_mode_enums
[] = {
134 /* Translation table for border-mode variables.
135 The list of values must be terminated by a NULL.
136 After the NULL value, an entry defines the default. */
137 struct tui_translate tui_border_mode_translate
[] = {
138 { "normal", A_NORMAL
},
139 { "standout", A_STANDOUT
},
140 { "reverse", A_REVERSE
},
142 { "half-standout", A_DIM
| A_STANDOUT
},
144 { "bold-standout", A_BOLD
| A_STANDOUT
},
146 { "normal", A_NORMAL
}
149 /* Translation tables for border-kind, one for each border
150 character (see wborder, border curses operations).
151 -1 is used to indicate the ACS because ACS characters
152 are determined at run time by curses (depends on terminal). */
153 struct tui_translate tui_border_kind_translate_vline
[] = {
161 struct tui_translate tui_border_kind_translate_hline
[] = {
169 struct tui_translate tui_border_kind_translate_ulcorner
[] = {
177 struct tui_translate tui_border_kind_translate_urcorner
[] = {
185 struct tui_translate tui_border_kind_translate_llcorner
[] = {
193 struct tui_translate tui_border_kind_translate_lrcorner
[] = {
202 /* Tui configuration variables controlled with set/show command. */
203 const char *tui_active_border_mode
= "bold-standout";
205 show_tui_active_border_mode (struct ui_file
*file
,
207 struct cmd_list_element
*c
,
210 fprintf_filtered (file
, _("\
211 The attribute mode to use for the active TUI window border is \"%s\".\n"),
215 const char *tui_border_mode
= "normal";
217 show_tui_border_mode (struct ui_file
*file
,
219 struct cmd_list_element
*c
,
222 fprintf_filtered (file
, _("\
223 The attribute mode to use for the TUI window borders is \"%s\".\n"),
227 const char *tui_border_kind
= "acs";
229 show_tui_border_kind (struct ui_file
*file
,
231 struct cmd_list_element
*c
,
234 fprintf_filtered (file
, _("The kind of border for TUI windows is \"%s\".\n"),
239 /* Tui internal configuration variables. These variables are updated
240 by tui_update_variables to reflect the tui configuration
242 chtype tui_border_vline
;
243 chtype tui_border_hline
;
244 chtype tui_border_ulcorner
;
245 chtype tui_border_urcorner
;
246 chtype tui_border_llcorner
;
247 chtype tui_border_lrcorner
;
249 int tui_border_attrs
;
250 int tui_active_border_attrs
;
252 /* Identify the item in the translation table.
253 When the item is not recognized, use the default entry. */
254 static struct tui_translate
*
255 translate (const char *name
, struct tui_translate
*table
)
259 if (name
&& strcmp (table
->name
, name
) == 0)
264 /* Not found, return default entry. */
269 /* Update the tui internal configuration according to gdb settings.
270 Returns 1 if the configuration has changed and the screen should
273 tui_update_variables (void)
276 struct tui_translate
*entry
;
278 entry
= translate (tui_border_mode
, tui_border_mode_translate
);
279 if (tui_border_attrs
!= entry
->value
)
281 tui_border_attrs
= entry
->value
;
284 entry
= translate (tui_active_border_mode
, tui_border_mode_translate
);
285 if (tui_active_border_attrs
!= entry
->value
)
287 tui_active_border_attrs
= entry
->value
;
291 /* If one corner changes, all characters are changed.
292 Only check the first one. The ACS characters are determined at
293 run time by curses terminal management. */
294 entry
= translate (tui_border_kind
, tui_border_kind_translate_lrcorner
);
295 if (tui_border_lrcorner
!= (chtype
) entry
->value
)
297 tui_border_lrcorner
= (entry
->value
< 0) ? ACS_LRCORNER
: entry
->value
;
300 entry
= translate (tui_border_kind
, tui_border_kind_translate_llcorner
);
301 tui_border_llcorner
= (entry
->value
< 0) ? ACS_LLCORNER
: entry
->value
;
303 entry
= translate (tui_border_kind
, tui_border_kind_translate_ulcorner
);
304 tui_border_ulcorner
= (entry
->value
< 0) ? ACS_ULCORNER
: entry
->value
;
306 entry
= translate (tui_border_kind
, tui_border_kind_translate_urcorner
);
307 tui_border_urcorner
= (entry
->value
< 0) ? ACS_URCORNER
: entry
->value
;
309 entry
= translate (tui_border_kind
, tui_border_kind_translate_hline
);
310 tui_border_hline
= (entry
->value
< 0) ? ACS_HLINE
: entry
->value
;
312 entry
= translate (tui_border_kind
, tui_border_kind_translate_vline
);
313 tui_border_vline
= (entry
->value
< 0) ? ACS_VLINE
: entry
->value
;
319 set_tui_cmd (const char *args
, int from_tty
)
324 show_tui_cmd (const char *args
, int from_tty
)
328 static struct cmd_list_element
*tuilist
;
331 tui_command (const char *args
, int from_tty
)
333 printf_unfiltered (_("\"tui\" must be followed by the name of a "
335 help_list (tuilist
, "tui ", all_commands
, gdb_stdout
);
338 struct cmd_list_element
**
339 tui_get_cmd_list (void)
342 add_prefix_cmd ("tui", class_tui
, tui_command
,
343 _("Text User Interface commands."),
344 &tuilist
, "tui ", 0, &cmdlist
);
348 /* The set_func hook of "set tui ..." commands that affect the window
349 borders on the TUI display. */
351 tui_set_var_cmd (char *null_args
, int from_tty
, struct cmd_list_element
*c
)
353 if (tui_update_variables () && tui_active
)
354 tui_rehighlight_all ();
357 /* Generic window name completion function. Complete window name pointed
358 to by TEXT and WORD. If INCLUDE_NEXT_PREV_P is true then the special
359 window names 'next' and 'prev' will also be considered as possible
360 completions of the window name. */
363 window_name_completer (completion_tracker
&tracker
,
364 int include_next_prev_p
,
365 const char *text
, const char *word
)
367 VEC (const_char_ptr
) *completion_name_vec
= NULL
;
370 for (win_type
= SRC_WIN
; win_type
< MAX_MAJOR_WINDOWS
; win_type
++)
372 const char *completion_name
= NULL
;
374 /* We can't focus on an invisible window. */
375 if (tui_win_list
[win_type
] == NULL
376 || !tui_win_list
[win_type
]->generic
.is_visible
)
379 completion_name
= tui_win_name (&tui_win_list
[win_type
]->generic
);
380 gdb_assert (completion_name
!= NULL
);
381 VEC_safe_push (const_char_ptr
, completion_name_vec
, completion_name
);
384 /* If no windows are considered visible then the TUI has not yet been
385 initialized. But still "focus src" and "focus cmd" will work because
386 invoking the focus command will entail initializing the TUI which sets the
387 default layout to SRC_COMMAND. */
388 if (VEC_length (const_char_ptr
, completion_name_vec
) == 0)
390 VEC_safe_push (const_char_ptr
, completion_name_vec
, SRC_NAME
);
391 VEC_safe_push (const_char_ptr
, completion_name_vec
, CMD_NAME
);
394 if (include_next_prev_p
)
396 VEC_safe_push (const_char_ptr
, completion_name_vec
, "next");
397 VEC_safe_push (const_char_ptr
, completion_name_vec
, "prev");
400 VEC_safe_push (const_char_ptr
, completion_name_vec
, NULL
);
401 complete_on_enum (tracker
,
402 VEC_address (const_char_ptr
, completion_name_vec
),
405 VEC_free (const_char_ptr
, completion_name_vec
);
408 /* Complete possible window names to focus on. TEXT is the complete text
409 entered so far, WORD is the word currently being completed. */
412 focus_completer (struct cmd_list_element
*ignore
,
413 completion_tracker
&tracker
,
414 const char *text
, const char *word
)
416 window_name_completer (tracker
, 1, text
, word
);
419 /* Complete possible window names for winheight command. TEXT is the
420 complete text entered so far, WORD is the word currently being
424 winheight_completer (struct cmd_list_element
*ignore
,
425 completion_tracker
&tracker
,
426 const char *text
, const char *word
)
428 /* The first word is the window name. That we can complete. Subsequent
429 words can't be completed. */
433 window_name_completer (tracker
, 0, text
, word
);
436 /* Function to initialize gdb commands, for tui window
440 _initialize_tui_win (void)
442 static struct cmd_list_element
*tui_setlist
;
443 static struct cmd_list_element
*tui_showlist
;
444 struct cmd_list_element
*cmd
;
446 /* Define the classes of commands.
447 They will appear in the help list in the reverse of this order. */
448 add_prefix_cmd ("tui", class_tui
, set_tui_cmd
,
449 _("TUI configuration variables"),
450 &tui_setlist
, "set tui ",
451 0 /* allow-unknown */, &setlist
);
452 add_prefix_cmd ("tui", class_tui
, show_tui_cmd
,
453 _("TUI configuration variables"),
454 &tui_showlist
, "show tui ",
455 0 /* allow-unknown */, &showlist
);
457 add_com ("refresh", class_tui
, tui_refresh_all_command
,
458 _("Refresh the terminal display.\n"));
459 add_com ("tabset", class_tui
, tui_set_tab_width_command
, _("\
460 Set the width (in characters) of tab stops.\n\
461 Usage: tabset <n>\n"));
462 cmd
= add_com ("winheight", class_tui
, tui_set_win_height_command
, _("\
463 Set or modify the height of a specified window.\n\
464 Usage: winheight <win_name> [+ | -] <#lines>\n\
466 src : the source window\n\
467 cmd : the command window\n\
468 asm : the disassembly window\n\
469 regs : the register display\n"));
470 add_com_alias ("wh", "winheight", class_tui
, 0);
471 set_cmd_completer (cmd
, winheight_completer
);
472 add_info ("win", tui_all_windows_info
,
473 _("List of all displayed windows.\n"));
474 cmd
= add_com ("focus", class_tui
, tui_set_focus_command
, _("\
475 Set focus to named window or next/prev window.\n\
476 Usage: focus {<win> | next | prev}\n\
477 Valid Window names are:\n\
478 src : the source window\n\
479 asm : the disassembly window\n\
480 regs : the register display\n\
481 cmd : the command window\n"));
482 add_com_alias ("fs", "focus", class_tui
, 0);
483 set_cmd_completer (cmd
, focus_completer
);
484 add_com ("+", class_tui
, tui_scroll_forward_command
, _("\
485 Scroll window forward.\n\
486 Usage: + [win] [n]\n"));
487 add_com ("-", class_tui
, tui_scroll_backward_command
, _("\
488 Scroll window backward.\n\
489 Usage: - [win] [n]\n"));
490 add_com ("<", class_tui
, tui_scroll_left_command
, _("\
491 Scroll window text to the left.\n\
492 Usage: < [win] [n]\n"));
493 add_com (">", class_tui
, tui_scroll_right_command
, _("\
494 Scroll window text to the right.\n\
495 Usage: > [win] [n]\n"));
497 /* Define the tui control variables. */
498 add_setshow_enum_cmd ("border-kind", no_class
, tui_border_kind_enums
,
499 &tui_border_kind
, _("\
500 Set the kind of border for TUI windows."), _("\
501 Show the kind of border for TUI windows."), _("\
502 This variable controls the border of TUI windows:\n\
503 space use a white space\n\
504 ascii use ascii characters + - | for the border\n\
505 acs use the Alternate Character Set"),
507 show_tui_border_kind
,
508 &tui_setlist
, &tui_showlist
);
510 add_setshow_enum_cmd ("border-mode", no_class
, tui_border_mode_enums
,
511 &tui_border_mode
, _("\
512 Set the attribute mode to use for the TUI window borders."), _("\
513 Show the attribute mode to use for the TUI window borders."), _("\
514 This variable controls the attributes to use for the window borders:\n\
515 normal normal display\n\
516 standout use highlight mode of terminal\n\
517 reverse use reverse video mode\n\
518 half use half bright\n\
519 half-standout use half bright and standout mode\n\
520 bold use extra bright or bold\n\
521 bold-standout use extra bright or bold with standout mode"),
523 show_tui_border_mode
,
524 &tui_setlist
, &tui_showlist
);
526 add_setshow_enum_cmd ("active-border-mode", no_class
, tui_border_mode_enums
,
527 &tui_active_border_mode
, _("\
528 Set the attribute mode to use for the active TUI window border."), _("\
529 Show the attribute mode to use for the active TUI window border."), _("\
530 This variable controls the attributes to use for the active window border:\n\
531 normal normal display\n\
532 standout use highlight mode of terminal\n\
533 reverse use reverse video mode\n\
534 half use half bright\n\
535 half-standout use half bright and standout mode\n\
536 bold use extra bright or bold\n\
537 bold-standout use extra bright or bold with standout mode"),
539 show_tui_active_border_mode
,
540 &tui_setlist
, &tui_showlist
);
543 /* Update gdb's knowledge of the terminal size. */
545 tui_update_gdb_sizes (void)
551 width
= TUI_CMD_WIN
->generic
.width
;
552 height
= TUI_CMD_WIN
->generic
.height
;
556 width
= tui_term_width ();
557 height
= tui_term_height ();
560 set_screen_width_and_height (width
, height
);
564 /* Set the logical focus to win_info. */
566 tui_set_win_focus_to (struct tui_win_info
*win_info
)
568 if (win_info
!= NULL
)
570 struct tui_win_info
*win_with_focus
= tui_win_with_focus ();
572 if (win_with_focus
!= NULL
573 && win_with_focus
->generic
.type
!= CMD_WIN
)
574 tui_unhighlight_win (win_with_focus
);
575 tui_set_win_with_focus (win_info
);
576 if (win_info
->generic
.type
!= CMD_WIN
)
577 tui_highlight_win (win_info
);
583 tui_scroll_forward (struct tui_win_info
*win_to_scroll
,
586 if (win_to_scroll
!= TUI_CMD_WIN
)
588 int _num_to_scroll
= num_to_scroll
;
590 if (num_to_scroll
== 0)
591 _num_to_scroll
= win_to_scroll
->generic
.height
- 3;
593 /* If we are scrolling the source or disassembly window, do a
594 "psuedo" scroll since not all of the source is in memory,
595 only what is in the viewport. If win_to_scroll is the
596 command window do nothing since the term should handle
598 if (win_to_scroll
== TUI_SRC_WIN
)
599 tui_vertical_source_scroll (FORWARD_SCROLL
, _num_to_scroll
);
600 else if (win_to_scroll
== TUI_DISASM_WIN
)
601 tui_vertical_disassem_scroll (FORWARD_SCROLL
, _num_to_scroll
);
602 else if (win_to_scroll
== TUI_DATA_WIN
)
603 tui_vertical_data_scroll (FORWARD_SCROLL
, _num_to_scroll
);
608 tui_scroll_backward (struct tui_win_info
*win_to_scroll
,
611 if (win_to_scroll
!= TUI_CMD_WIN
)
613 int _num_to_scroll
= num_to_scroll
;
615 if (num_to_scroll
== 0)
616 _num_to_scroll
= win_to_scroll
->generic
.height
- 3;
618 /* If we are scrolling the source or disassembly window, do a
619 "psuedo" scroll since not all of the source is in memory,
620 only what is in the viewport. If win_to_scroll is the
621 command window do nothing since the term should handle
623 if (win_to_scroll
== TUI_SRC_WIN
)
624 tui_vertical_source_scroll (BACKWARD_SCROLL
, _num_to_scroll
);
625 else if (win_to_scroll
== TUI_DISASM_WIN
)
626 tui_vertical_disassem_scroll (BACKWARD_SCROLL
, _num_to_scroll
);
627 else if (win_to_scroll
== TUI_DATA_WIN
)
628 tui_vertical_data_scroll (BACKWARD_SCROLL
, _num_to_scroll
);
634 tui_scroll_left (struct tui_win_info
*win_to_scroll
,
637 if (win_to_scroll
!= TUI_CMD_WIN
)
639 int _num_to_scroll
= num_to_scroll
;
641 if (_num_to_scroll
== 0)
644 /* If we are scrolling the source or disassembly window, do a
645 "psuedo" scroll since not all of the source is in memory,
646 only what is in the viewport. If win_to_scroll is the command
647 window do nothing since the term should handle it. */
648 if (win_to_scroll
== TUI_SRC_WIN
649 || win_to_scroll
== TUI_DISASM_WIN
)
650 tui_horizontal_source_scroll (win_to_scroll
, LEFT_SCROLL
,
657 tui_scroll_right (struct tui_win_info
*win_to_scroll
,
660 if (win_to_scroll
!= TUI_CMD_WIN
)
662 int _num_to_scroll
= num_to_scroll
;
664 if (_num_to_scroll
== 0)
667 /* If we are scrolling the source or disassembly window, do a
668 "psuedo" scroll since not all of the source is in memory,
669 only what is in the viewport. If win_to_scroll is the command
670 window do nothing since the term should handle it. */
671 if (win_to_scroll
== TUI_SRC_WIN
672 || win_to_scroll
== TUI_DISASM_WIN
)
673 tui_horizontal_source_scroll (win_to_scroll
, RIGHT_SCROLL
,
679 /* Scroll a window. Arguments are passed through a va_list. */
681 tui_scroll (enum tui_scroll_direction direction
,
682 struct tui_win_info
*win_to_scroll
,
688 tui_scroll_forward (win_to_scroll
, num_to_scroll
);
690 case BACKWARD_SCROLL
:
691 tui_scroll_backward (win_to_scroll
, num_to_scroll
);
694 tui_scroll_left (win_to_scroll
, num_to_scroll
);
697 tui_scroll_right (win_to_scroll
, num_to_scroll
);
706 tui_refresh_all_win (void)
710 clearok (curscr
, TRUE
);
711 tui_refresh_all (tui_win_list
);
712 for (type
= SRC_WIN
; type
< MAX_MAJOR_WINDOWS
; type
++)
714 if (tui_win_list
[type
]
715 && tui_win_list
[type
]->generic
.is_visible
)
721 tui_show_source_content (tui_win_list
[type
]);
722 tui_check_and_display_highlight_if_needed (tui_win_list
[type
]);
723 tui_erase_exec_info_content (tui_win_list
[type
]);
724 tui_update_exec_info (tui_win_list
[type
]);
727 tui_refresh_data_win ();
734 tui_show_locator_content ();
738 tui_rehighlight_all (void)
742 for (type
= SRC_WIN
; type
< MAX_MAJOR_WINDOWS
; type
++)
743 tui_check_and_display_highlight_if_needed (tui_win_list
[type
]);
746 /* Resize all the windows based on the terminal size. This function
747 gets called from within the readline sinwinch handler. */
749 tui_resize_all (void)
751 int height_diff
, width_diff
;
752 int screenheight
, screenwidth
;
754 rl_get_screen_size (&screenheight
, &screenwidth
);
755 width_diff
= screenwidth
- tui_term_width ();
756 height_diff
= screenheight
- tui_term_height ();
757 if (height_diff
|| width_diff
)
759 enum tui_layout_type cur_layout
= tui_current_layout ();
760 struct tui_win_info
*win_with_focus
= tui_win_with_focus ();
761 struct tui_win_info
*first_win
;
762 struct tui_win_info
*second_win
;
763 struct tui_gen_win_info
*locator
= tui_locator_win_info_ptr ();
765 int new_height
, split_diff
, cmd_split_diff
, num_wins_displayed
= 2;
767 #ifdef HAVE_RESIZE_TERM
768 resize_term (screenheight
, screenwidth
);
770 /* Turn keypad off while we resize. */
771 if (win_with_focus
!= TUI_CMD_WIN
)
772 keypad (TUI_CMD_WIN
->generic
.handle
, FALSE
);
773 tui_update_gdb_sizes ();
774 tui_set_term_height_to (screenheight
);
775 tui_set_term_width_to (screenwidth
);
776 if (cur_layout
== SRC_DISASSEM_COMMAND
777 || cur_layout
== SRC_DATA_COMMAND
778 || cur_layout
== DISASSEM_DATA_COMMAND
)
779 num_wins_displayed
++;
780 split_diff
= height_diff
/ num_wins_displayed
;
781 cmd_split_diff
= split_diff
;
782 if (height_diff
% num_wins_displayed
)
789 /* Now adjust each window. */
790 /* erase + clearok are used instead of a straightforward clear as
791 AIX 5.3 does not define clear. */
793 clearok (curscr
, TRUE
);
798 case DISASSEM_COMMAND
:
799 first_win
= (struct tui_win_info
*) (tui_source_windows ())->list
[0];
800 first_win
->generic
.width
+= width_diff
;
801 locator
->width
+= width_diff
;
802 /* Check for invalid heights. */
803 if (height_diff
== 0)
804 new_height
= first_win
->generic
.height
;
805 else if ((first_win
->generic
.height
+ split_diff
) >=
806 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
807 new_height
= screenheight
- MIN_CMD_WIN_HEIGHT
- 1;
808 else if ((first_win
->generic
.height
+ split_diff
) <= 0)
809 new_height
= MIN_WIN_HEIGHT
;
811 new_height
= first_win
->generic
.height
+ split_diff
;
813 locator
->origin
.y
= new_height
+ 1;
814 make_invisible_and_set_new_height (first_win
, new_height
);
815 TUI_CMD_WIN
->generic
.origin
.y
= locator
->origin
.y
+ 1;
816 TUI_CMD_WIN
->generic
.width
+= width_diff
;
817 new_height
= screenheight
- TUI_CMD_WIN
->generic
.origin
.y
;
818 make_invisible_and_set_new_height (TUI_CMD_WIN
, new_height
);
819 make_visible_with_new_height (first_win
);
820 make_visible_with_new_height (TUI_CMD_WIN
);
821 if (first_win
->generic
.content_size
<= 0)
822 tui_erase_source_content (first_win
, EMPTY_SOURCE_PROMPT
);
825 if (cur_layout
== SRC_DISASSEM_COMMAND
)
827 first_win
= TUI_SRC_WIN
;
828 first_win
->generic
.width
+= width_diff
;
829 second_win
= TUI_DISASM_WIN
;
830 second_win
->generic
.width
+= width_diff
;
834 first_win
= TUI_DATA_WIN
;
835 first_win
->generic
.width
+= width_diff
;
836 second_win
= (struct tui_win_info
*)
837 (tui_source_windows ())->list
[0];
838 second_win
->generic
.width
+= width_diff
;
840 /* Change the first window's height/width. */
841 /* Check for invalid heights. */
842 if (height_diff
== 0)
843 new_height
= first_win
->generic
.height
;
844 else if ((first_win
->generic
.height
+
845 second_win
->generic
.height
+ (split_diff
* 2)) >=
846 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
847 new_height
= (screenheight
- MIN_CMD_WIN_HEIGHT
- 1) / 2;
848 else if ((first_win
->generic
.height
+ split_diff
) <= 0)
849 new_height
= MIN_WIN_HEIGHT
;
851 new_height
= first_win
->generic
.height
+ split_diff
;
852 make_invisible_and_set_new_height (first_win
, new_height
);
854 locator
->width
+= width_diff
;
856 /* Change the second window's height/width. */
857 /* Check for invalid heights. */
858 if (height_diff
== 0)
859 new_height
= second_win
->generic
.height
;
860 else if ((first_win
->generic
.height
+
861 second_win
->generic
.height
+ (split_diff
* 2)) >=
862 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
864 new_height
= screenheight
- MIN_CMD_WIN_HEIGHT
- 1;
866 new_height
= (new_height
/ 2) + 1;
870 else if ((second_win
->generic
.height
+ split_diff
) <= 0)
871 new_height
= MIN_WIN_HEIGHT
;
873 new_height
= second_win
->generic
.height
+ split_diff
;
874 second_win
->generic
.origin
.y
= first_win
->generic
.height
- 1;
875 make_invisible_and_set_new_height (second_win
, new_height
);
877 /* Change the command window's height/width. */
878 TUI_CMD_WIN
->generic
.origin
.y
= locator
->origin
.y
+ 1;
879 make_invisible_and_set_new_height (TUI_CMD_WIN
,
880 TUI_CMD_WIN
->generic
.height
882 make_visible_with_new_height (first_win
);
883 make_visible_with_new_height (second_win
);
884 make_visible_with_new_height (TUI_CMD_WIN
);
885 if (first_win
->generic
.content_size
<= 0)
886 tui_erase_source_content (first_win
, EMPTY_SOURCE_PROMPT
);
887 if (second_win
->generic
.content_size
<= 0)
888 tui_erase_source_content (second_win
, EMPTY_SOURCE_PROMPT
);
891 /* Now remove all invisible windows, and their content so that
892 they get created again when called for with the new size. */
893 for (win_type
= SRC_WIN
; (win_type
< MAX_MAJOR_WINDOWS
); win_type
++)
895 if (win_type
!= CMD_WIN
896 && (tui_win_list
[win_type
] != NULL
)
897 && !tui_win_list
[win_type
]->generic
.is_visible
)
899 tui_free_window (tui_win_list
[win_type
]);
900 tui_win_list
[win_type
] = NULL
;
903 /* Turn keypad back on, unless focus is in the command
905 if (win_with_focus
!= TUI_CMD_WIN
)
906 keypad (TUI_CMD_WIN
->generic
.handle
, TRUE
);
911 /* Token for use by TUI's asynchronous SIGWINCH handler. */
912 static struct async_signal_handler
*tui_sigwinch_token
;
914 /* TUI's SIGWINCH signal handler. */
916 tui_sigwinch_handler (int signal
)
918 mark_async_signal_handler (tui_sigwinch_token
);
919 tui_set_win_resized_to (TRUE
);
922 /* Callback for asynchronously resizing TUI following a SIGWINCH signal. */
924 tui_async_resize_screen (gdb_client_data arg
)
926 rl_resize_terminal ();
930 int screen_height
, screen_width
;
932 rl_get_screen_size (&screen_height
, &screen_width
);
933 set_screen_width_and_height (screen_width
, screen_height
);
935 /* win_resized is left set so that the next call to tui_enable()
936 resizes the TUI windows. */
940 tui_set_win_resized_to (FALSE
);
942 tui_refresh_all_win ();
943 tui_update_gdb_sizes ();
944 tui_redisplay_readline ();
949 /* Initialize TUI's SIGWINCH signal handler. Note that the handler is not
950 uninstalled when we exit TUI, so the handler should not assume that TUI is
953 tui_initialize_win (void)
957 = create_async_signal_handler (tui_async_resize_screen
, NULL
);
960 #ifdef HAVE_SIGACTION
961 struct sigaction old_winch
;
963 memset (&old_winch
, 0, sizeof (old_winch
));
964 old_winch
.sa_handler
= &tui_sigwinch_handler
;
966 old_winch
.sa_flags
= SA_RESTART
;
968 sigaction (SIGWINCH
, &old_winch
, NULL
);
970 signal (SIGWINCH
, &tui_sigwinch_handler
);
977 /*************************
978 ** STATIC LOCAL FUNCTIONS
979 **************************/
983 tui_scroll_forward_command (char *arg
, int from_tty
)
985 int num_to_scroll
= 1;
986 struct tui_win_info
*win_to_scroll
;
988 /* Make sure the curses mode is enabled. */
990 if (arg
== (char *) NULL
)
991 parse_scrolling_args (arg
, &win_to_scroll
, (int *) NULL
);
993 parse_scrolling_args (arg
, &win_to_scroll
, &num_to_scroll
);
994 tui_scroll (FORWARD_SCROLL
, win_to_scroll
, num_to_scroll
);
999 tui_scroll_backward_command (char *arg
, int from_tty
)
1001 int num_to_scroll
= 1;
1002 struct tui_win_info
*win_to_scroll
;
1004 /* Make sure the curses mode is enabled. */
1006 if (arg
== (char *) NULL
)
1007 parse_scrolling_args (arg
, &win_to_scroll
, (int *) NULL
);
1009 parse_scrolling_args (arg
, &win_to_scroll
, &num_to_scroll
);
1010 tui_scroll (BACKWARD_SCROLL
, win_to_scroll
, num_to_scroll
);
1015 tui_scroll_left_command (char *arg
, int from_tty
)
1018 struct tui_win_info
*win_to_scroll
;
1020 /* Make sure the curses mode is enabled. */
1022 parse_scrolling_args (arg
, &win_to_scroll
, &num_to_scroll
);
1023 tui_scroll (LEFT_SCROLL
, win_to_scroll
, num_to_scroll
);
1028 tui_scroll_right_command (char *arg
, int from_tty
)
1031 struct tui_win_info
*win_to_scroll
;
1033 /* Make sure the curses mode is enabled. */
1035 parse_scrolling_args (arg
, &win_to_scroll
, &num_to_scroll
);
1036 tui_scroll (RIGHT_SCROLL
, win_to_scroll
, num_to_scroll
);
1040 /* Set focus to the window named by 'arg'. */
1042 tui_set_focus (char *arg
, int from_tty
)
1044 if (arg
!= (char *) NULL
)
1046 char *buf_ptr
= (char *) xstrdup (arg
);
1048 struct tui_win_info
*win_info
= NULL
;
1050 for (i
= 0; (i
< strlen (buf_ptr
)); i
++)
1051 buf_ptr
[i
] = tolower (arg
[i
]);
1053 if (subset_compare (buf_ptr
, "next"))
1054 win_info
= tui_next_win (tui_win_with_focus ());
1055 else if (subset_compare (buf_ptr
, "prev"))
1056 win_info
= tui_prev_win (tui_win_with_focus ());
1058 win_info
= tui_partial_win_by_name (buf_ptr
);
1060 if (win_info
== (struct tui_win_info
*) NULL
1061 || !win_info
->generic
.is_visible
)
1062 warning (_("Invalid window specified. \n\
1063 The window name specified must be valid and visible.\n"));
1066 tui_set_win_focus_to (win_info
);
1067 keypad (TUI_CMD_WIN
->generic
.handle
, (win_info
!= TUI_CMD_WIN
));
1070 if (TUI_DATA_WIN
&& TUI_DATA_WIN
->generic
.is_visible
)
1071 tui_refresh_data_win ();
1073 printf_filtered (_("Focus set to %s window.\n"),
1074 tui_win_name (&tui_win_with_focus ()->generic
));
1077 warning (_("Incorrect Number of Arguments.\n%s"), FOCUS_USAGE
);
1081 tui_set_focus_command (char *arg
, int from_tty
)
1083 /* Make sure the curses mode is enabled. */
1085 tui_set_focus (arg
, from_tty
);
1090 tui_all_windows_info (char *arg
, int from_tty
)
1093 struct tui_win_info
*win_with_focus
= tui_win_with_focus ();
1095 for (type
= SRC_WIN
; (type
< MAX_MAJOR_WINDOWS
); type
++)
1096 if (tui_win_list
[type
]
1097 && tui_win_list
[type
]->generic
.is_visible
)
1099 if (win_with_focus
== tui_win_list
[type
])
1100 printf_filtered (" %s\t(%d lines) <has focus>\n",
1101 tui_win_name (&tui_win_list
[type
]->generic
),
1102 tui_win_list
[type
]->generic
.height
);
1104 printf_filtered (" %s\t(%d lines)\n",
1105 tui_win_name (&tui_win_list
[type
]->generic
),
1106 tui_win_list
[type
]->generic
.height
);
1112 tui_refresh_all_command (char *arg
, int from_tty
)
1114 /* Make sure the curses mode is enabled. */
1117 tui_refresh_all_win ();
1121 /* Set the tab width of the specified window. */
1123 tui_set_tab_width_command (char *arg
, int from_tty
)
1125 /* Make sure the curses mode is enabled. */
1127 if (arg
!= (char *) NULL
)
1134 tui_set_default_tab_len (ts
);
1135 /* We don't really change the height of any windows, but
1136 calling these 2 functions causes a complete regeneration
1137 and redisplay of the window's contents, which will take
1138 the new tab width into account. */
1139 if (tui_win_list
[SRC_WIN
]
1140 && tui_win_list
[SRC_WIN
]->generic
.is_visible
)
1142 make_invisible_and_set_new_height (TUI_SRC_WIN
,
1143 TUI_SRC_WIN
->generic
.height
);
1144 make_visible_with_new_height (TUI_SRC_WIN
);
1146 if (tui_win_list
[DISASSEM_WIN
]
1147 && tui_win_list
[DISASSEM_WIN
]->generic
.is_visible
)
1149 make_invisible_and_set_new_height (TUI_DISASM_WIN
,
1150 TUI_DISASM_WIN
->generic
.height
);
1151 make_visible_with_new_height (TUI_DISASM_WIN
);
1155 warning (_("Tab widths greater than 0 must be specified."));
1160 /* Set the height of the specified window. */
1162 tui_set_win_height (char *arg
, int from_tty
)
1164 /* Make sure the curses mode is enabled. */
1166 if (arg
!= (char *) NULL
)
1168 char *buf
= xstrdup (arg
);
1169 char *buf_ptr
= buf
;
1172 struct tui_win_info
*win_info
;
1173 struct cleanup
*old_chain
;
1175 old_chain
= make_cleanup (xfree
, buf
);
1177 buf_ptr
= strchr (buf_ptr
, ' ');
1178 if (buf_ptr
!= (char *) NULL
)
1180 *buf_ptr
= (char) 0;
1182 /* Validate the window name. */
1183 for (i
= 0; i
< strlen (wname
); i
++)
1184 wname
[i
] = tolower (wname
[i
]);
1185 win_info
= tui_partial_win_by_name (wname
);
1187 if (win_info
== (struct tui_win_info
*) NULL
1188 || !win_info
->generic
.is_visible
)
1189 warning (_("Invalid window specified. \n\
1190 The window name specified must be valid and visible.\n"));
1193 /* Process the size. */
1194 while (*(++buf_ptr
) == ' ')
1197 if (*buf_ptr
!= (char) 0)
1200 int fixed_size
= TRUE
;
1203 if (*buf_ptr
== '+' || *buf_ptr
== '-')
1205 if (*buf_ptr
== '-')
1210 input_no
= atoi (buf_ptr
);
1216 new_height
= input_no
;
1218 new_height
= win_info
->generic
.height
+ input_no
;
1220 /* Now change the window's height, and adjust
1221 all other windows around it. */
1222 if (tui_adjust_win_heights (win_info
,
1223 new_height
) == TUI_FAILURE
)
1224 warning (_("Invalid window height specified.\n%s"),
1227 tui_update_gdb_sizes ();
1230 warning (_("Invalid window height specified.\n%s"),
1236 printf_filtered (WIN_HEIGHT_USAGE
);
1238 do_cleanups (old_chain
);
1241 printf_filtered (WIN_HEIGHT_USAGE
);
1244 /* Set the height of the specified window, with va_list. */
1246 tui_set_win_height_command (char *arg
, int from_tty
)
1248 /* Make sure the curses mode is enabled. */
1250 tui_set_win_height (arg
, from_tty
);
1253 /* Function to adjust all window heights around the primary. */
1254 static enum tui_status
1255 tui_adjust_win_heights (struct tui_win_info
*primary_win_info
,
1258 enum tui_status status
= TUI_FAILURE
;
1260 if (new_height_ok (primary_win_info
, new_height
))
1262 status
= TUI_SUCCESS
;
1263 if (new_height
!= primary_win_info
->generic
.height
)
1266 struct tui_win_info
*win_info
;
1267 struct tui_gen_win_info
*locator
= tui_locator_win_info_ptr ();
1268 enum tui_layout_type cur_layout
= tui_current_layout ();
1270 diff
= (new_height
- primary_win_info
->generic
.height
) * (-1);
1271 if (cur_layout
== SRC_COMMAND
1272 || cur_layout
== DISASSEM_COMMAND
)
1274 struct tui_win_info
*src_win_info
;
1276 make_invisible_and_set_new_height (primary_win_info
, new_height
);
1277 if (primary_win_info
->generic
.type
== CMD_WIN
)
1279 win_info
= (tui_source_windows ())->list
[0];
1280 src_win_info
= win_info
;
1284 win_info
= tui_win_list
[CMD_WIN
];
1285 src_win_info
= primary_win_info
;
1287 make_invisible_and_set_new_height (win_info
,
1288 win_info
->generic
.height
+ diff
);
1289 TUI_CMD_WIN
->generic
.origin
.y
= locator
->origin
.y
+ 1;
1290 make_visible_with_new_height (win_info
);
1291 make_visible_with_new_height (primary_win_info
);
1292 if (src_win_info
->generic
.content_size
<= 0)
1293 tui_erase_source_content (src_win_info
, EMPTY_SOURCE_PROMPT
);
1297 struct tui_win_info
*first_win
;
1298 struct tui_win_info
*second_win
;
1300 if (cur_layout
== SRC_DISASSEM_COMMAND
)
1302 first_win
= TUI_SRC_WIN
;
1303 second_win
= TUI_DISASM_WIN
;
1307 first_win
= TUI_DATA_WIN
;
1308 second_win
= (tui_source_windows ())->list
[0];
1310 if (primary_win_info
== TUI_CMD_WIN
)
1311 { /* Split the change in height accross the 1st & 2nd
1312 windows, adjusting them as well. */
1313 /* Subtract the locator. */
1314 int first_split_diff
= diff
/ 2;
1315 int second_split_diff
= first_split_diff
;
1319 if (first_win
->generic
.height
>
1320 second_win
->generic
.height
)
1328 second_split_diff
--;
1330 second_split_diff
++;
1333 /* Make sure that the minimum hieghts are
1335 while ((first_win
->generic
.height
+ first_split_diff
) < 3)
1338 second_split_diff
--;
1340 while ((second_win
->generic
.height
+ second_split_diff
) < 3)
1342 second_split_diff
++;
1345 make_invisible_and_set_new_height (
1347 first_win
->generic
.height
+ first_split_diff
);
1348 second_win
->generic
.origin
.y
= first_win
->generic
.height
- 1;
1349 make_invisible_and_set_new_height (second_win
,
1350 second_win
->generic
.height
1351 + second_split_diff
);
1352 TUI_CMD_WIN
->generic
.origin
.y
= locator
->origin
.y
+ 1;
1353 make_invisible_and_set_new_height (TUI_CMD_WIN
, new_height
);
1357 if ((TUI_CMD_WIN
->generic
.height
+ diff
) < 1)
1358 { /* If there is no way to increase the command
1359 window take real estate from the 1st or 2nd
1361 if ((TUI_CMD_WIN
->generic
.height
+ diff
) < 1)
1365 for (i
= TUI_CMD_WIN
->generic
.height
+ diff
;
1367 if (primary_win_info
== first_win
)
1368 second_win
->generic
.height
--;
1370 first_win
->generic
.height
--;
1373 if (primary_win_info
== first_win
)
1374 make_invisible_and_set_new_height (first_win
, new_height
);
1376 make_invisible_and_set_new_height (
1378 first_win
->generic
.height
);
1379 second_win
->generic
.origin
.y
= first_win
->generic
.height
- 1;
1380 if (primary_win_info
== second_win
)
1381 make_invisible_and_set_new_height (second_win
, new_height
);
1383 make_invisible_and_set_new_height (
1384 second_win
, second_win
->generic
.height
);
1385 TUI_CMD_WIN
->generic
.origin
.y
= locator
->origin
.y
+ 1;
1386 if ((TUI_CMD_WIN
->generic
.height
+ diff
) < 1)
1387 make_invisible_and_set_new_height (TUI_CMD_WIN
, 1);
1389 make_invisible_and_set_new_height (TUI_CMD_WIN
,
1390 TUI_CMD_WIN
->generic
.height
+ diff
);
1392 make_visible_with_new_height (TUI_CMD_WIN
);
1393 make_visible_with_new_height (second_win
);
1394 make_visible_with_new_height (first_win
);
1395 if (first_win
->generic
.content_size
<= 0)
1396 tui_erase_source_content (first_win
, EMPTY_SOURCE_PROMPT
);
1397 if (second_win
->generic
.content_size
<= 0)
1398 tui_erase_source_content (second_win
, EMPTY_SOURCE_PROMPT
);
1407 /* Function make the target window (and auxillary windows associated
1408 with the targer) invisible, and set the new height and
1411 make_invisible_and_set_new_height (struct tui_win_info
*win_info
,
1415 struct tui_gen_win_info
*gen_win_info
;
1417 tui_make_invisible (&win_info
->generic
);
1418 win_info
->generic
.height
= height
;
1420 win_info
->generic
.viewport_height
= height
- 1;
1422 win_info
->generic
.viewport_height
= height
;
1423 if (win_info
!= TUI_CMD_WIN
)
1424 win_info
->generic
.viewport_height
--;
1426 /* Now deal with the auxillary windows associated with win_info. */
1427 switch (win_info
->generic
.type
)
1431 gen_win_info
= win_info
->detail
.source_info
.execution_info
;
1432 tui_make_invisible (gen_win_info
);
1433 gen_win_info
->height
= height
;
1434 gen_win_info
->origin
.y
= win_info
->generic
.origin
.y
;
1436 gen_win_info
->viewport_height
= height
- 1;
1438 gen_win_info
->viewport_height
= height
;
1439 if (win_info
!= TUI_CMD_WIN
)
1440 gen_win_info
->viewport_height
--;
1442 if (tui_win_has_locator (win_info
))
1444 gen_win_info
= tui_locator_win_info_ptr ();
1445 tui_make_invisible (gen_win_info
);
1446 gen_win_info
->origin
.y
= win_info
->generic
.origin
.y
+ height
;
1450 /* Delete all data item windows. */
1451 for (i
= 0; i
< win_info
->generic
.content_size
; i
++)
1453 gen_win_info
= (struct tui_gen_win_info
*)
1454 &((struct tui_win_element
*)
1455 win_info
->generic
.content
[i
])->which_element
.data_window
;
1456 tui_delete_win (gen_win_info
->handle
);
1457 gen_win_info
->handle
= NULL
;
1466 /* Function to make the windows with new heights visible. This means
1467 re-creating the windows' content since the window had to be
1468 destroyed to be made invisible. */
1470 make_visible_with_new_height (struct tui_win_info
*win_info
)
1474 tui_make_visible (&win_info
->generic
);
1475 tui_check_and_display_highlight_if_needed (win_info
);
1476 switch (win_info
->generic
.type
)
1480 tui_free_win_content (win_info
->detail
.source_info
.execution_info
);
1481 tui_make_visible (win_info
->detail
.source_info
.execution_info
);
1482 if (win_info
->generic
.content
!= NULL
)
1484 struct gdbarch
*gdbarch
= win_info
->detail
.source_info
.gdbarch
;
1485 struct tui_line_or_address line_or_addr
;
1486 struct symtab_and_line cursal
1487 = get_current_source_symtab_and_line ();
1489 line_or_addr
= win_info
->detail
.source_info
.start_line_or_addr
;
1490 tui_free_win_content (&win_info
->generic
);
1491 tui_update_source_window (win_info
, gdbarch
,
1492 cursal
.symtab
, line_or_addr
, TRUE
);
1494 else if (deprecated_safe_get_selected_frame () != NULL
)
1496 struct tui_line_or_address line
;
1497 struct symtab_and_line cursal
1498 = get_current_source_symtab_and_line ();
1499 struct frame_info
*frame
= deprecated_safe_get_selected_frame ();
1500 struct gdbarch
*gdbarch
= get_frame_arch (frame
);
1502 s
= find_pc_line_symtab (get_frame_pc (frame
));
1503 if (win_info
->generic
.type
== SRC_WIN
)
1505 line
.loa
= LOA_LINE
;
1506 line
.u
.line_no
= cursal
.line
;
1510 line
.loa
= LOA_ADDRESS
;
1511 find_line_pc (s
, cursal
.line
, &line
.u
.addr
);
1513 tui_update_source_window (win_info
, gdbarch
, s
, line
, TRUE
);
1515 if (tui_win_has_locator (win_info
))
1517 tui_make_visible (tui_locator_win_info_ptr ());
1518 tui_show_locator_content ();
1522 tui_display_all_data ();
1526 wresize (TUI_CMD_WIN
->generic
.handle
,
1527 TUI_CMD_WIN
->generic
.height
,
1528 TUI_CMD_WIN
->generic
.width
);
1530 mvwin (TUI_CMD_WIN
->generic
.handle
,
1531 TUI_CMD_WIN
->generic
.origin
.y
,
1532 TUI_CMD_WIN
->generic
.origin
.x
);
1533 wmove (win_info
->generic
.handle
, 0, 0);
1542 new_height_ok (struct tui_win_info
*primary_win_info
,
1545 int ok
= (new_height
< tui_term_height ());
1550 enum tui_layout_type cur_layout
= tui_current_layout ();
1552 diff
= (new_height
- primary_win_info
->generic
.height
) * (-1);
1553 if (cur_layout
== SRC_COMMAND
|| cur_layout
== DISASSEM_COMMAND
)
1555 ok
= ((primary_win_info
->generic
.type
== CMD_WIN
1556 && new_height
<= (tui_term_height () - 4)
1557 && new_height
>= MIN_CMD_WIN_HEIGHT
)
1558 || (primary_win_info
->generic
.type
!= CMD_WIN
1559 && new_height
<= (tui_term_height () - 2)
1560 && new_height
>= MIN_WIN_HEIGHT
));
1562 { /* Check the total height. */
1563 struct tui_win_info
*win_info
;
1565 if (primary_win_info
== TUI_CMD_WIN
)
1566 win_info
= (tui_source_windows ())->list
[0];
1568 win_info
= TUI_CMD_WIN
;
1570 (win_info
->generic
.height
+ diff
)) <= tui_term_height ());
1575 int cur_total_height
, total_height
, min_height
= 0;
1576 struct tui_win_info
*first_win
;
1577 struct tui_win_info
*second_win
;
1579 if (cur_layout
== SRC_DISASSEM_COMMAND
)
1581 first_win
= TUI_SRC_WIN
;
1582 second_win
= TUI_DISASM_WIN
;
1586 first_win
= TUI_DATA_WIN
;
1587 second_win
= (tui_source_windows ())->list
[0];
1589 /* We could simply add all the heights to obtain the same
1590 result but below is more explicit since we subtract 1 for
1591 the line that the first and second windows share, and add
1592 one for the locator. */
1593 total_height
= cur_total_height
=
1594 (first_win
->generic
.height
+ second_win
->generic
.height
- 1)
1595 + TUI_CMD_WIN
->generic
.height
+ 1; /* Locator. */
1596 if (primary_win_info
== TUI_CMD_WIN
)
1598 /* Locator included since first & second win share a line. */
1599 ok
= ((first_win
->generic
.height
+
1600 second_win
->generic
.height
+ diff
) >=
1601 (MIN_WIN_HEIGHT
* 2)
1602 && new_height
>= MIN_CMD_WIN_HEIGHT
);
1605 total_height
= new_height
+
1606 (first_win
->generic
.height
+
1607 second_win
->generic
.height
+ diff
);
1608 min_height
= MIN_CMD_WIN_HEIGHT
;
1613 min_height
= MIN_WIN_HEIGHT
;
1615 /* First see if we can increase/decrease the command
1616 window. And make sure that the command window is at
1618 ok
= ((TUI_CMD_WIN
->generic
.height
+ diff
) > 0);
1620 { /* Looks like we have to increase/decrease one of
1621 the other windows. */
1622 if (primary_win_info
== first_win
)
1623 ok
= (second_win
->generic
.height
+ diff
) >= min_height
;
1625 ok
= (first_win
->generic
.height
+ diff
) >= min_height
;
1629 if (primary_win_info
== first_win
)
1630 total_height
= new_height
+
1631 second_win
->generic
.height
+
1632 TUI_CMD_WIN
->generic
.height
+ diff
;
1634 total_height
= new_height
+
1635 first_win
->generic
.height
+
1636 TUI_CMD_WIN
->generic
.height
+ diff
;
1639 /* Now make sure that the proposed total height doesn't
1640 exceed the old total height. */
1642 ok
= (new_height
>= min_height
1643 && total_height
<= cur_total_height
);
1652 parse_scrolling_args (char *arg
,
1653 struct tui_win_info
**win_to_scroll
,
1658 *win_to_scroll
= tui_win_with_focus ();
1660 /* First set up the default window to scroll, in case there is no
1662 if (arg
!= (char *) NULL
)
1664 char *buf
, *buf_ptr
;
1665 struct cleanup
*old_chain
;
1667 /* Process the number of lines to scroll. */
1668 buf
= buf_ptr
= xstrdup (arg
);
1669 old_chain
= make_cleanup (xfree
, buf
);
1670 if (isdigit (*buf_ptr
))
1675 buf_ptr
= strchr (buf_ptr
, ' ');
1676 if (buf_ptr
!= (char *) NULL
)
1678 *buf_ptr
= (char) 0;
1680 *num_to_scroll
= atoi (num_str
);
1683 else if (num_to_scroll
)
1684 *num_to_scroll
= atoi (num_str
);
1687 /* Process the window name if one is specified. */
1688 if (buf_ptr
!= (char *) NULL
)
1692 if (*buf_ptr
== ' ')
1693 while (*(++buf_ptr
) == ' ')
1696 if (*buf_ptr
!= (char) 0)
1698 /* Validate the window name. */
1699 for (char *p
= buf_ptr
; *p
!= '\0'; p
++)
1707 *win_to_scroll
= tui_partial_win_by_name (wname
);
1709 if (*win_to_scroll
== (struct tui_win_info
*) NULL
1710 || !(*win_to_scroll
)->generic
.is_visible
)
1711 error (_("Invalid window specified. \n\
1712 The window name specified must be valid and visible.\n"));
1713 else if (*win_to_scroll
== TUI_CMD_WIN
)
1714 *win_to_scroll
= (tui_source_windows ())->list
[0];
1716 do_cleanups (old_chain
);