1 /* TUI window generic functions.
3 Copyright (C) 1998-2015 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 (char *args
, int from_tty
)
324 show_tui_cmd (char *args
, int from_tty
)
328 static struct cmd_list_element
*tuilist
;
331 tui_command (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. */
362 static VEC (char_ptr
) *
363 window_name_completer (int include_next_prev_p
,
364 const char *text
, const char *word
)
366 VEC (const_char_ptr
) *completion_name_vec
= NULL
;
367 VEC (char_ptr
) *matches_vec
;
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
);
402 = complete_on_enum (VEC_address (const_char_ptr
, completion_name_vec
),
405 VEC_free (const_char_ptr
, completion_name_vec
);
410 /* Complete possible window names to focus on. TEXT is the complete text
411 entered so far, WORD is the word currently being completed. */
413 static VEC (char_ptr
) *
414 focus_completer (struct cmd_list_element
*ignore
,
415 const char *text
, const char *word
)
417 return window_name_completer (1, text
, word
);
420 /* Complete possible window names for winheight command. TEXT is the
421 complete text entered so far, WORD is the word currently being
424 static VEC (char_ptr
) *
425 winheight_completer (struct cmd_list_element
*ignore
,
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 return window_name_completer (0, text
, word
);
436 /* Function to initialize gdb commands, for tui window
439 /* Provide a prototype to silence -Wmissing-prototypes. */
440 extern initialize_file_ftype _initialize_tui_win
;
443 _initialize_tui_win (void)
445 static struct cmd_list_element
*tui_setlist
;
446 static struct cmd_list_element
*tui_showlist
;
447 struct cmd_list_element
*cmd
;
449 /* Define the classes of commands.
450 They will appear in the help list in the reverse of this order. */
451 add_prefix_cmd ("tui", class_tui
, set_tui_cmd
,
452 _("TUI configuration variables"),
453 &tui_setlist
, "set tui ",
454 0 /* allow-unknown */, &setlist
);
455 add_prefix_cmd ("tui", class_tui
, show_tui_cmd
,
456 _("TUI configuration variables"),
457 &tui_showlist
, "show tui ",
458 0 /* allow-unknown */, &showlist
);
460 add_com ("refresh", class_tui
, tui_refresh_all_command
,
461 _("Refresh the terminal display.\n"));
462 add_com ("tabset", class_tui
, tui_set_tab_width_command
, _("\
463 Set the width (in characters) of tab stops.\n\
464 Usage: tabset <n>\n"));
465 cmd
= add_com ("winheight", class_tui
, tui_set_win_height_command
, _("\
466 Set or modify the height of a specified window.\n\
467 Usage: winheight <win_name> [+ | -] <#lines>\n\
469 src : the source window\n\
470 cmd : the command window\n\
471 asm : the disassembly window\n\
472 regs : the register display\n"));
473 add_com_alias ("wh", "winheight", class_tui
, 0);
474 set_cmd_completer (cmd
, winheight_completer
);
475 add_info ("win", tui_all_windows_info
,
476 _("List of all displayed windows.\n"));
477 cmd
= add_com ("focus", class_tui
, tui_set_focus_command
, _("\
478 Set focus to named window or next/prev window.\n\
479 Usage: focus {<win> | next | prev}\n\
480 Valid Window names are:\n\
481 src : the source window\n\
482 asm : the disassembly window\n\
483 regs : the register display\n\
484 cmd : the command window\n"));
485 add_com_alias ("fs", "focus", class_tui
, 0);
486 set_cmd_completer (cmd
, focus_completer
);
487 add_com ("+", class_tui
, tui_scroll_forward_command
, _("\
488 Scroll window forward.\n\
489 Usage: + [win] [n]\n"));
490 add_com ("-", class_tui
, tui_scroll_backward_command
, _("\
491 Scroll window backward.\n\
492 Usage: - [win] [n]\n"));
493 add_com ("<", class_tui
, tui_scroll_left_command
, _("\
494 Scroll window text to the left.\n\
495 Usage: < [win] [n]\n"));
496 add_com (">", class_tui
, tui_scroll_right_command
, _("\
497 Scroll window text to the right.\n\
498 Usage: > [win] [n]\n"));
500 /* Define the tui control variables. */
501 add_setshow_enum_cmd ("border-kind", no_class
, tui_border_kind_enums
,
502 &tui_border_kind
, _("\
503 Set the kind of border for TUI windows."), _("\
504 Show the kind of border for TUI windows."), _("\
505 This variable controls the border of TUI windows:\n\
506 space use a white space\n\
507 ascii use ascii characters + - | for the border\n\
508 acs use the Alternate Character Set"),
510 show_tui_border_kind
,
511 &tui_setlist
, &tui_showlist
);
513 add_setshow_enum_cmd ("border-mode", no_class
, tui_border_mode_enums
,
514 &tui_border_mode
, _("\
515 Set the attribute mode to use for the TUI window borders."), _("\
516 Show the attribute mode to use for the TUI window borders."), _("\
517 This variable controls the attributes to use for the window borders:\n\
518 normal normal display\n\
519 standout use highlight mode of terminal\n\
520 reverse use reverse video mode\n\
521 half use half bright\n\
522 half-standout use half bright and standout mode\n\
523 bold use extra bright or bold\n\
524 bold-standout use extra bright or bold with standout mode"),
526 show_tui_border_mode
,
527 &tui_setlist
, &tui_showlist
);
529 add_setshow_enum_cmd ("active-border-mode", no_class
, tui_border_mode_enums
,
530 &tui_active_border_mode
, _("\
531 Set the attribute mode to use for the active TUI window border."), _("\
532 Show the attribute mode to use for the active TUI window border."), _("\
533 This variable controls the attributes to use for the active window border:\n\
534 normal normal display\n\
535 standout use highlight mode of terminal\n\
536 reverse use reverse video mode\n\
537 half use half bright\n\
538 half-standout use half bright and standout mode\n\
539 bold use extra bright or bold\n\
540 bold-standout use extra bright or bold with standout mode"),
542 show_tui_active_border_mode
,
543 &tui_setlist
, &tui_showlist
);
546 /* Update gdb's knowledge of the terminal size. */
548 tui_update_gdb_sizes (void)
554 width
= TUI_CMD_WIN
->generic
.width
;
555 height
= TUI_CMD_WIN
->generic
.height
;
559 width
= tui_term_width ();
560 height
= tui_term_height ();
563 set_screen_width_and_height (width
, height
);
567 /* Set the logical focus to win_info. */
569 tui_set_win_focus_to (struct tui_win_info
*win_info
)
571 if (win_info
!= NULL
)
573 struct tui_win_info
*win_with_focus
= tui_win_with_focus ();
575 if (win_with_focus
!= NULL
576 && win_with_focus
->generic
.type
!= CMD_WIN
)
577 tui_unhighlight_win (win_with_focus
);
578 tui_set_win_with_focus (win_info
);
579 if (win_info
->generic
.type
!= CMD_WIN
)
580 tui_highlight_win (win_info
);
586 tui_scroll_forward (struct tui_win_info
*win_to_scroll
,
589 if (win_to_scroll
!= TUI_CMD_WIN
)
591 int _num_to_scroll
= num_to_scroll
;
593 if (num_to_scroll
== 0)
594 _num_to_scroll
= win_to_scroll
->generic
.height
- 3;
596 /* If we are scrolling the source or disassembly window, do a
597 "psuedo" scroll since not all of the source is in memory,
598 only what is in the viewport. If win_to_scroll is the
599 command window do nothing since the term should handle
601 if (win_to_scroll
== TUI_SRC_WIN
)
602 tui_vertical_source_scroll (FORWARD_SCROLL
, _num_to_scroll
);
603 else if (win_to_scroll
== TUI_DISASM_WIN
)
604 tui_vertical_disassem_scroll (FORWARD_SCROLL
, _num_to_scroll
);
605 else if (win_to_scroll
== TUI_DATA_WIN
)
606 tui_vertical_data_scroll (FORWARD_SCROLL
, _num_to_scroll
);
611 tui_scroll_backward (struct tui_win_info
*win_to_scroll
,
614 if (win_to_scroll
!= TUI_CMD_WIN
)
616 int _num_to_scroll
= num_to_scroll
;
618 if (num_to_scroll
== 0)
619 _num_to_scroll
= win_to_scroll
->generic
.height
- 3;
621 /* If we are scrolling the source or disassembly window, do a
622 "psuedo" scroll since not all of the source is in memory,
623 only what is in the viewport. If win_to_scroll is the
624 command window do nothing since the term should handle
626 if (win_to_scroll
== TUI_SRC_WIN
)
627 tui_vertical_source_scroll (BACKWARD_SCROLL
, _num_to_scroll
);
628 else if (win_to_scroll
== TUI_DISASM_WIN
)
629 tui_vertical_disassem_scroll (BACKWARD_SCROLL
, _num_to_scroll
);
630 else if (win_to_scroll
== TUI_DATA_WIN
)
631 tui_vertical_data_scroll (BACKWARD_SCROLL
, _num_to_scroll
);
637 tui_scroll_left (struct tui_win_info
*win_to_scroll
,
640 if (win_to_scroll
!= TUI_CMD_WIN
)
642 int _num_to_scroll
= num_to_scroll
;
644 if (_num_to_scroll
== 0)
647 /* If we are scrolling the source or disassembly window, do a
648 "psuedo" scroll since not all of the source is in memory,
649 only what is in the viewport. If win_to_scroll is the command
650 window do nothing since the term should handle it. */
651 if (win_to_scroll
== TUI_SRC_WIN
652 || win_to_scroll
== TUI_DISASM_WIN
)
653 tui_horizontal_source_scroll (win_to_scroll
, LEFT_SCROLL
,
660 tui_scroll_right (struct tui_win_info
*win_to_scroll
,
663 if (win_to_scroll
!= TUI_CMD_WIN
)
665 int _num_to_scroll
= num_to_scroll
;
667 if (_num_to_scroll
== 0)
670 /* If we are scrolling the source or disassembly window, do a
671 "psuedo" scroll since not all of the source is in memory,
672 only what is in the viewport. If win_to_scroll is the command
673 window do nothing since the term should handle it. */
674 if (win_to_scroll
== TUI_SRC_WIN
675 || win_to_scroll
== TUI_DISASM_WIN
)
676 tui_horizontal_source_scroll (win_to_scroll
, RIGHT_SCROLL
,
682 /* Scroll a window. Arguments are passed through a va_list. */
684 tui_scroll (enum tui_scroll_direction direction
,
685 struct tui_win_info
*win_to_scroll
,
691 tui_scroll_forward (win_to_scroll
, num_to_scroll
);
693 case BACKWARD_SCROLL
:
694 tui_scroll_backward (win_to_scroll
, num_to_scroll
);
697 tui_scroll_left (win_to_scroll
, num_to_scroll
);
700 tui_scroll_right (win_to_scroll
, num_to_scroll
);
709 tui_refresh_all_win (void)
713 clearok (curscr
, TRUE
);
714 tui_refresh_all (tui_win_list
);
715 for (type
= SRC_WIN
; type
< MAX_MAJOR_WINDOWS
; type
++)
717 if (tui_win_list
[type
]
718 && tui_win_list
[type
]->generic
.is_visible
)
724 tui_show_source_content (tui_win_list
[type
]);
725 tui_check_and_display_highlight_if_needed (tui_win_list
[type
]);
726 tui_erase_exec_info_content (tui_win_list
[type
]);
727 tui_update_exec_info (tui_win_list
[type
]);
730 tui_refresh_data_win ();
737 tui_show_locator_content ();
741 tui_rehighlight_all (void)
745 for (type
= SRC_WIN
; type
< MAX_MAJOR_WINDOWS
; type
++)
746 tui_check_and_display_highlight_if_needed (tui_win_list
[type
]);
749 /* Resize all the windows based on the terminal size. This function
750 gets called from within the readline sinwinch handler. */
752 tui_resize_all (void)
754 int height_diff
, width_diff
;
755 int screenheight
, screenwidth
;
757 rl_get_screen_size (&screenheight
, &screenwidth
);
758 width_diff
= screenwidth
- tui_term_width ();
759 height_diff
= screenheight
- tui_term_height ();
760 if (height_diff
|| width_diff
)
762 enum tui_layout_type cur_layout
= tui_current_layout ();
763 struct tui_win_info
*win_with_focus
= tui_win_with_focus ();
764 struct tui_win_info
*first_win
;
765 struct tui_win_info
*second_win
;
766 struct tui_gen_win_info
*locator
= tui_locator_win_info_ptr ();
768 int new_height
, split_diff
, cmd_split_diff
, num_wins_displayed
= 2;
770 #ifdef HAVE_RESIZE_TERM
771 resize_term (screenheight
, screenwidth
);
773 /* Turn keypad off while we resize. */
774 if (win_with_focus
!= TUI_CMD_WIN
)
775 keypad (TUI_CMD_WIN
->generic
.handle
, FALSE
);
776 tui_update_gdb_sizes ();
777 tui_set_term_height_to (screenheight
);
778 tui_set_term_width_to (screenwidth
);
779 if (cur_layout
== SRC_DISASSEM_COMMAND
780 || cur_layout
== SRC_DATA_COMMAND
781 || cur_layout
== DISASSEM_DATA_COMMAND
)
782 num_wins_displayed
++;
783 split_diff
= height_diff
/ num_wins_displayed
;
784 cmd_split_diff
= split_diff
;
785 if (height_diff
% num_wins_displayed
)
792 /* Now adjust each window. */
793 /* erase + clearok are used instead of a straightforward clear as
794 AIX 5.3 does not define clear. */
796 clearok (curscr
, TRUE
);
801 case DISASSEM_COMMAND
:
802 first_win
= (struct tui_win_info
*) (tui_source_windows ())->list
[0];
803 first_win
->generic
.width
+= width_diff
;
804 locator
->width
+= width_diff
;
805 /* Check for invalid heights. */
806 if (height_diff
== 0)
807 new_height
= first_win
->generic
.height
;
808 else if ((first_win
->generic
.height
+ split_diff
) >=
809 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
810 new_height
= screenheight
- MIN_CMD_WIN_HEIGHT
- 1;
811 else if ((first_win
->generic
.height
+ split_diff
) <= 0)
812 new_height
= MIN_WIN_HEIGHT
;
814 new_height
= first_win
->generic
.height
+ split_diff
;
816 locator
->origin
.y
= new_height
+ 1;
817 make_invisible_and_set_new_height (first_win
, new_height
);
818 TUI_CMD_WIN
->generic
.origin
.y
= locator
->origin
.y
+ 1;
819 TUI_CMD_WIN
->generic
.width
+= width_diff
;
820 new_height
= screenheight
- TUI_CMD_WIN
->generic
.origin
.y
;
821 make_invisible_and_set_new_height (TUI_CMD_WIN
, new_height
);
822 make_visible_with_new_height (first_win
);
823 make_visible_with_new_height (TUI_CMD_WIN
);
824 if (first_win
->generic
.content_size
<= 0)
825 tui_erase_source_content (first_win
, EMPTY_SOURCE_PROMPT
);
828 if (cur_layout
== SRC_DISASSEM_COMMAND
)
830 first_win
= TUI_SRC_WIN
;
831 first_win
->generic
.width
+= width_diff
;
832 second_win
= TUI_DISASM_WIN
;
833 second_win
->generic
.width
+= width_diff
;
837 first_win
= TUI_DATA_WIN
;
838 first_win
->generic
.width
+= width_diff
;
839 second_win
= (struct tui_win_info
*)
840 (tui_source_windows ())->list
[0];
841 second_win
->generic
.width
+= width_diff
;
843 /* Change the first window's height/width. */
844 /* Check for invalid heights. */
845 if (height_diff
== 0)
846 new_height
= first_win
->generic
.height
;
847 else if ((first_win
->generic
.height
+
848 second_win
->generic
.height
+ (split_diff
* 2)) >=
849 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
850 new_height
= (screenheight
- MIN_CMD_WIN_HEIGHT
- 1) / 2;
851 else if ((first_win
->generic
.height
+ split_diff
) <= 0)
852 new_height
= MIN_WIN_HEIGHT
;
854 new_height
= first_win
->generic
.height
+ split_diff
;
855 make_invisible_and_set_new_height (first_win
, new_height
);
857 locator
->width
+= width_diff
;
859 /* Change the second window's height/width. */
860 /* Check for invalid heights. */
861 if (height_diff
== 0)
862 new_height
= second_win
->generic
.height
;
863 else if ((first_win
->generic
.height
+
864 second_win
->generic
.height
+ (split_diff
* 2)) >=
865 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
867 new_height
= screenheight
- MIN_CMD_WIN_HEIGHT
- 1;
869 new_height
= (new_height
/ 2) + 1;
873 else if ((second_win
->generic
.height
+ split_diff
) <= 0)
874 new_height
= MIN_WIN_HEIGHT
;
876 new_height
= second_win
->generic
.height
+ split_diff
;
877 second_win
->generic
.origin
.y
= first_win
->generic
.height
- 1;
878 make_invisible_and_set_new_height (second_win
, new_height
);
880 /* Change the command window's height/width. */
881 TUI_CMD_WIN
->generic
.origin
.y
= locator
->origin
.y
+ 1;
882 make_invisible_and_set_new_height (TUI_CMD_WIN
,
883 TUI_CMD_WIN
->generic
.height
885 make_visible_with_new_height (first_win
);
886 make_visible_with_new_height (second_win
);
887 make_visible_with_new_height (TUI_CMD_WIN
);
888 if (first_win
->generic
.content_size
<= 0)
889 tui_erase_source_content (first_win
, EMPTY_SOURCE_PROMPT
);
890 if (second_win
->generic
.content_size
<= 0)
891 tui_erase_source_content (second_win
, EMPTY_SOURCE_PROMPT
);
894 /* Now remove all invisible windows, and their content so that
895 they get created again when called for with the new size. */
896 for (win_type
= SRC_WIN
; (win_type
< MAX_MAJOR_WINDOWS
); win_type
++)
898 if (win_type
!= CMD_WIN
899 && (tui_win_list
[win_type
] != NULL
)
900 && !tui_win_list
[win_type
]->generic
.is_visible
)
902 tui_free_window (tui_win_list
[win_type
]);
903 tui_win_list
[win_type
] = (struct tui_win_info
*) NULL
;
906 /* Turn keypad back on, unless focus is in the command
908 if (win_with_focus
!= TUI_CMD_WIN
)
909 keypad (TUI_CMD_WIN
->generic
.handle
, TRUE
);
914 /* Token for use by TUI's asynchronous SIGWINCH handler. */
915 static struct async_signal_handler
*tui_sigwinch_token
;
917 /* TUI's SIGWINCH signal handler. */
919 tui_sigwinch_handler (int signal
)
921 mark_async_signal_handler (tui_sigwinch_token
);
922 tui_set_win_resized_to (TRUE
);
925 /* Callback for asynchronously resizing TUI following a SIGWINCH signal. */
927 tui_async_resize_screen (gdb_client_data arg
)
929 rl_resize_terminal ();
933 int screen_height
, screen_width
;
935 rl_get_screen_size (&screen_height
, &screen_width
);
936 set_screen_width_and_height (screen_width
, screen_height
);
938 /* win_resized is left set so that the next call to tui_enable()
939 resizes the TUI windows. */
943 tui_set_win_resized_to (FALSE
);
945 tui_refresh_all_win ();
946 tui_update_gdb_sizes ();
947 tui_redisplay_readline ();
952 /* Initialize TUI's SIGWINCH signal handler. Note that the handler is not
953 uninstalled when we exit TUI, so the handler should not assume that TUI is
956 tui_initialize_win (void)
960 = create_async_signal_handler (tui_async_resize_screen
, NULL
);
963 #ifdef HAVE_SIGACTION
964 struct sigaction old_winch
;
966 memset (&old_winch
, 0, sizeof (old_winch
));
967 old_winch
.sa_handler
= &tui_sigwinch_handler
;
969 old_winch
.sa_flags
= SA_RESTART
;
971 sigaction (SIGWINCH
, &old_winch
, NULL
);
973 signal (SIGWINCH
, &tui_sigwinch_handler
);
980 /*************************
981 ** STATIC LOCAL FUNCTIONS
982 **************************/
986 tui_scroll_forward_command (char *arg
, int from_tty
)
988 int num_to_scroll
= 1;
989 struct tui_win_info
*win_to_scroll
;
991 /* Make sure the curses mode is enabled. */
993 if (arg
== (char *) NULL
)
994 parse_scrolling_args (arg
, &win_to_scroll
, (int *) NULL
);
996 parse_scrolling_args (arg
, &win_to_scroll
, &num_to_scroll
);
997 tui_scroll (FORWARD_SCROLL
, win_to_scroll
, num_to_scroll
);
1002 tui_scroll_backward_command (char *arg
, int from_tty
)
1004 int num_to_scroll
= 1;
1005 struct tui_win_info
*win_to_scroll
;
1007 /* Make sure the curses mode is enabled. */
1009 if (arg
== (char *) NULL
)
1010 parse_scrolling_args (arg
, &win_to_scroll
, (int *) NULL
);
1012 parse_scrolling_args (arg
, &win_to_scroll
, &num_to_scroll
);
1013 tui_scroll (BACKWARD_SCROLL
, win_to_scroll
, num_to_scroll
);
1018 tui_scroll_left_command (char *arg
, int from_tty
)
1021 struct tui_win_info
*win_to_scroll
;
1023 /* Make sure the curses mode is enabled. */
1025 parse_scrolling_args (arg
, &win_to_scroll
, &num_to_scroll
);
1026 tui_scroll (LEFT_SCROLL
, win_to_scroll
, num_to_scroll
);
1031 tui_scroll_right_command (char *arg
, int from_tty
)
1034 struct tui_win_info
*win_to_scroll
;
1036 /* Make sure the curses mode is enabled. */
1038 parse_scrolling_args (arg
, &win_to_scroll
, &num_to_scroll
);
1039 tui_scroll (RIGHT_SCROLL
, win_to_scroll
, num_to_scroll
);
1043 /* Set focus to the window named by 'arg'. */
1045 tui_set_focus (char *arg
, int from_tty
)
1047 if (arg
!= (char *) NULL
)
1049 char *buf_ptr
= (char *) xstrdup (arg
);
1051 struct tui_win_info
*win_info
= (struct tui_win_info
*) NULL
;
1053 for (i
= 0; (i
< strlen (buf_ptr
)); i
++)
1054 buf_ptr
[i
] = tolower (arg
[i
]);
1056 if (subset_compare (buf_ptr
, "next"))
1057 win_info
= tui_next_win (tui_win_with_focus ());
1058 else if (subset_compare (buf_ptr
, "prev"))
1059 win_info
= tui_prev_win (tui_win_with_focus ());
1061 win_info
= tui_partial_win_by_name (buf_ptr
);
1063 if (win_info
== (struct tui_win_info
*) NULL
1064 || !win_info
->generic
.is_visible
)
1065 warning (_("Invalid window specified. \n\
1066 The window name specified must be valid and visible.\n"));
1069 tui_set_win_focus_to (win_info
);
1070 keypad (TUI_CMD_WIN
->generic
.handle
, (win_info
!= TUI_CMD_WIN
));
1073 if (TUI_DATA_WIN
&& TUI_DATA_WIN
->generic
.is_visible
)
1074 tui_refresh_data_win ();
1076 printf_filtered (_("Focus set to %s window.\n"),
1077 tui_win_name (&tui_win_with_focus ()->generic
));
1080 warning (_("Incorrect Number of Arguments.\n%s"), FOCUS_USAGE
);
1084 tui_set_focus_command (char *arg
, int from_tty
)
1086 /* Make sure the curses mode is enabled. */
1088 tui_set_focus (arg
, from_tty
);
1093 tui_all_windows_info (char *arg
, int from_tty
)
1096 struct tui_win_info
*win_with_focus
= tui_win_with_focus ();
1098 for (type
= SRC_WIN
; (type
< MAX_MAJOR_WINDOWS
); type
++)
1099 if (tui_win_list
[type
]
1100 && tui_win_list
[type
]->generic
.is_visible
)
1102 if (win_with_focus
== tui_win_list
[type
])
1103 printf_filtered (" %s\t(%d lines) <has focus>\n",
1104 tui_win_name (&tui_win_list
[type
]->generic
),
1105 tui_win_list
[type
]->generic
.height
);
1107 printf_filtered (" %s\t(%d lines)\n",
1108 tui_win_name (&tui_win_list
[type
]->generic
),
1109 tui_win_list
[type
]->generic
.height
);
1115 tui_refresh_all_command (char *arg
, int from_tty
)
1117 /* Make sure the curses mode is enabled. */
1120 tui_refresh_all_win ();
1124 /* Set the tab width of the specified window. */
1126 tui_set_tab_width_command (char *arg
, int from_tty
)
1128 /* Make sure the curses mode is enabled. */
1130 if (arg
!= (char *) NULL
)
1137 tui_set_default_tab_len (ts
);
1138 /* We don't really change the height of any windows, but
1139 calling these 2 functions causes a complete regeneration
1140 and redisplay of the window's contents, which will take
1141 the new tab width into account. */
1142 if (tui_win_list
[SRC_WIN
]
1143 && tui_win_list
[SRC_WIN
]->generic
.is_visible
)
1145 make_invisible_and_set_new_height (TUI_SRC_WIN
,
1146 TUI_SRC_WIN
->generic
.height
);
1147 make_visible_with_new_height (TUI_SRC_WIN
);
1149 if (tui_win_list
[DISASSEM_WIN
]
1150 && tui_win_list
[DISASSEM_WIN
]->generic
.is_visible
)
1152 make_invisible_and_set_new_height (TUI_DISASM_WIN
,
1153 TUI_DISASM_WIN
->generic
.height
);
1154 make_visible_with_new_height (TUI_DISASM_WIN
);
1158 warning (_("Tab widths greater than 0 must be specified."));
1163 /* Set the height of the specified window. */
1165 tui_set_win_height (char *arg
, int from_tty
)
1167 /* Make sure the curses mode is enabled. */
1169 if (arg
!= (char *) NULL
)
1171 char *buf
= xstrdup (arg
);
1172 char *buf_ptr
= buf
;
1173 char *wname
= (char *) NULL
;
1175 struct tui_win_info
*win_info
;
1176 struct cleanup
*old_chain
;
1178 old_chain
= make_cleanup (xfree
, buf
);
1180 buf_ptr
= strchr (buf_ptr
, ' ');
1181 if (buf_ptr
!= (char *) NULL
)
1183 *buf_ptr
= (char) 0;
1185 /* Validate the window name. */
1186 for (i
= 0; i
< strlen (wname
); i
++)
1187 wname
[i
] = tolower (wname
[i
]);
1188 win_info
= tui_partial_win_by_name (wname
);
1190 if (win_info
== (struct tui_win_info
*) NULL
1191 || !win_info
->generic
.is_visible
)
1192 warning (_("Invalid window specified. \n\
1193 The window name specified must be valid and visible.\n"));
1196 /* Process the size. */
1197 while (*(++buf_ptr
) == ' ')
1200 if (*buf_ptr
!= (char) 0)
1203 int fixed_size
= TRUE
;
1206 if (*buf_ptr
== '+' || *buf_ptr
== '-')
1208 if (*buf_ptr
== '-')
1213 input_no
= atoi (buf_ptr
);
1219 new_height
= input_no
;
1221 new_height
= win_info
->generic
.height
+ input_no
;
1223 /* Now change the window's height, and adjust
1224 all other windows around it. */
1225 if (tui_adjust_win_heights (win_info
,
1226 new_height
) == TUI_FAILURE
)
1227 warning (_("Invalid window height specified.\n%s"),
1230 tui_update_gdb_sizes ();
1233 warning (_("Invalid window height specified.\n%s"),
1239 printf_filtered (WIN_HEIGHT_USAGE
);
1241 do_cleanups (old_chain
);
1244 printf_filtered (WIN_HEIGHT_USAGE
);
1247 /* Set the height of the specified window, with va_list. */
1249 tui_set_win_height_command (char *arg
, int from_tty
)
1251 /* Make sure the curses mode is enabled. */
1253 tui_set_win_height (arg
, from_tty
);
1256 /* Function to adjust all window heights around the primary. */
1257 static enum tui_status
1258 tui_adjust_win_heights (struct tui_win_info
*primary_win_info
,
1261 enum tui_status status
= TUI_FAILURE
;
1263 if (new_height_ok (primary_win_info
, new_height
))
1265 status
= TUI_SUCCESS
;
1266 if (new_height
!= primary_win_info
->generic
.height
)
1269 struct tui_win_info
*win_info
;
1270 struct tui_gen_win_info
*locator
= tui_locator_win_info_ptr ();
1271 enum tui_layout_type cur_layout
= tui_current_layout ();
1273 diff
= (new_height
- primary_win_info
->generic
.height
) * (-1);
1274 if (cur_layout
== SRC_COMMAND
1275 || cur_layout
== DISASSEM_COMMAND
)
1277 struct tui_win_info
*src_win_info
;
1279 make_invisible_and_set_new_height (primary_win_info
, new_height
);
1280 if (primary_win_info
->generic
.type
== CMD_WIN
)
1282 win_info
= (tui_source_windows ())->list
[0];
1283 src_win_info
= win_info
;
1287 win_info
= tui_win_list
[CMD_WIN
];
1288 src_win_info
= primary_win_info
;
1290 make_invisible_and_set_new_height (win_info
,
1291 win_info
->generic
.height
+ diff
);
1292 TUI_CMD_WIN
->generic
.origin
.y
= locator
->origin
.y
+ 1;
1293 make_visible_with_new_height (win_info
);
1294 make_visible_with_new_height (primary_win_info
);
1295 if (src_win_info
->generic
.content_size
<= 0)
1296 tui_erase_source_content (src_win_info
, EMPTY_SOURCE_PROMPT
);
1300 struct tui_win_info
*first_win
;
1301 struct tui_win_info
*second_win
;
1303 if (cur_layout
== SRC_DISASSEM_COMMAND
)
1305 first_win
= TUI_SRC_WIN
;
1306 second_win
= TUI_DISASM_WIN
;
1310 first_win
= TUI_DATA_WIN
;
1311 second_win
= (tui_source_windows ())->list
[0];
1313 if (primary_win_info
== TUI_CMD_WIN
)
1314 { /* Split the change in height accross the 1st & 2nd
1315 windows, adjusting them as well. */
1316 /* Subtract the locator. */
1317 int first_split_diff
= diff
/ 2;
1318 int second_split_diff
= first_split_diff
;
1322 if (first_win
->generic
.height
>
1323 second_win
->generic
.height
)
1331 second_split_diff
--;
1333 second_split_diff
++;
1336 /* Make sure that the minimum hieghts are
1338 while ((first_win
->generic
.height
+ first_split_diff
) < 3)
1341 second_split_diff
--;
1343 while ((second_win
->generic
.height
+ second_split_diff
) < 3)
1345 second_split_diff
++;
1348 make_invisible_and_set_new_height (
1350 first_win
->generic
.height
+ first_split_diff
);
1351 second_win
->generic
.origin
.y
= first_win
->generic
.height
- 1;
1352 make_invisible_and_set_new_height (second_win
,
1353 second_win
->generic
.height
1354 + second_split_diff
);
1355 TUI_CMD_WIN
->generic
.origin
.y
= locator
->origin
.y
+ 1;
1356 make_invisible_and_set_new_height (TUI_CMD_WIN
, new_height
);
1360 if ((TUI_CMD_WIN
->generic
.height
+ diff
) < 1)
1361 { /* If there is no way to increase the command
1362 window take real estate from the 1st or 2nd
1364 if ((TUI_CMD_WIN
->generic
.height
+ diff
) < 1)
1368 for (i
= TUI_CMD_WIN
->generic
.height
+ diff
;
1370 if (primary_win_info
== first_win
)
1371 second_win
->generic
.height
--;
1373 first_win
->generic
.height
--;
1376 if (primary_win_info
== first_win
)
1377 make_invisible_and_set_new_height (first_win
, new_height
);
1379 make_invisible_and_set_new_height (
1381 first_win
->generic
.height
);
1382 second_win
->generic
.origin
.y
= first_win
->generic
.height
- 1;
1383 if (primary_win_info
== second_win
)
1384 make_invisible_and_set_new_height (second_win
, new_height
);
1386 make_invisible_and_set_new_height (
1387 second_win
, second_win
->generic
.height
);
1388 TUI_CMD_WIN
->generic
.origin
.y
= locator
->origin
.y
+ 1;
1389 if ((TUI_CMD_WIN
->generic
.height
+ diff
) < 1)
1390 make_invisible_and_set_new_height (TUI_CMD_WIN
, 1);
1392 make_invisible_and_set_new_height (TUI_CMD_WIN
,
1393 TUI_CMD_WIN
->generic
.height
+ diff
);
1395 make_visible_with_new_height (TUI_CMD_WIN
);
1396 make_visible_with_new_height (second_win
);
1397 make_visible_with_new_height (first_win
);
1398 if (first_win
->generic
.content_size
<= 0)
1399 tui_erase_source_content (first_win
, EMPTY_SOURCE_PROMPT
);
1400 if (second_win
->generic
.content_size
<= 0)
1401 tui_erase_source_content (second_win
, EMPTY_SOURCE_PROMPT
);
1410 /* Function make the target window (and auxillary windows associated
1411 with the targer) invisible, and set the new height and
1414 make_invisible_and_set_new_height (struct tui_win_info
*win_info
,
1418 struct tui_gen_win_info
*gen_win_info
;
1420 tui_make_invisible (&win_info
->generic
);
1421 win_info
->generic
.height
= height
;
1423 win_info
->generic
.viewport_height
= height
- 1;
1425 win_info
->generic
.viewport_height
= height
;
1426 if (win_info
!= TUI_CMD_WIN
)
1427 win_info
->generic
.viewport_height
--;
1429 /* Now deal with the auxillary windows associated with win_info. */
1430 switch (win_info
->generic
.type
)
1434 gen_win_info
= win_info
->detail
.source_info
.execution_info
;
1435 tui_make_invisible (gen_win_info
);
1436 gen_win_info
->height
= height
;
1437 gen_win_info
->origin
.y
= win_info
->generic
.origin
.y
;
1439 gen_win_info
->viewport_height
= height
- 1;
1441 gen_win_info
->viewport_height
= height
;
1442 if (win_info
!= TUI_CMD_WIN
)
1443 gen_win_info
->viewport_height
--;
1445 if (tui_win_has_locator (win_info
))
1447 gen_win_info
= tui_locator_win_info_ptr ();
1448 tui_make_invisible (gen_win_info
);
1449 gen_win_info
->origin
.y
= win_info
->generic
.origin
.y
+ height
;
1453 /* Delete all data item windows. */
1454 for (i
= 0; i
< win_info
->generic
.content_size
; i
++)
1456 gen_win_info
= (struct tui_gen_win_info
*)
1457 &((struct tui_win_element
*)
1458 win_info
->generic
.content
[i
])->which_element
.data_window
;
1459 tui_delete_win (gen_win_info
->handle
);
1460 gen_win_info
->handle
= (WINDOW
*) NULL
;
1469 /* Function to make the windows with new heights visible. This means
1470 re-creating the windows' content since the window had to be
1471 destroyed to be made invisible. */
1473 make_visible_with_new_height (struct tui_win_info
*win_info
)
1477 tui_make_visible (&win_info
->generic
);
1478 tui_check_and_display_highlight_if_needed (win_info
);
1479 switch (win_info
->generic
.type
)
1483 tui_free_win_content (win_info
->detail
.source_info
.execution_info
);
1484 tui_make_visible (win_info
->detail
.source_info
.execution_info
);
1485 if (win_info
->generic
.content
!= NULL
)
1487 struct gdbarch
*gdbarch
= win_info
->detail
.source_info
.gdbarch
;
1488 struct tui_line_or_address line_or_addr
;
1489 struct symtab_and_line cursal
1490 = get_current_source_symtab_and_line ();
1492 line_or_addr
= win_info
->detail
.source_info
.start_line_or_addr
;
1493 tui_free_win_content (&win_info
->generic
);
1494 tui_update_source_window (win_info
, gdbarch
,
1495 cursal
.symtab
, line_or_addr
, TRUE
);
1497 else if (deprecated_safe_get_selected_frame () != NULL
)
1499 struct tui_line_or_address line
;
1500 struct symtab_and_line cursal
1501 = get_current_source_symtab_and_line ();
1502 struct frame_info
*frame
= deprecated_safe_get_selected_frame ();
1503 struct gdbarch
*gdbarch
= get_frame_arch (frame
);
1505 s
= find_pc_line_symtab (get_frame_pc (frame
));
1506 if (win_info
->generic
.type
== SRC_WIN
)
1508 line
.loa
= LOA_LINE
;
1509 line
.u
.line_no
= cursal
.line
;
1513 line
.loa
= LOA_ADDRESS
;
1514 find_line_pc (s
, cursal
.line
, &line
.u
.addr
);
1516 tui_update_source_window (win_info
, gdbarch
, s
, line
, TRUE
);
1518 if (tui_win_has_locator (win_info
))
1520 tui_make_visible (tui_locator_win_info_ptr ());
1521 tui_show_locator_content ();
1525 tui_display_all_data ();
1528 win_info
->detail
.command_info
.cur_line
= 0;
1529 win_info
->detail
.command_info
.curch
= 0;
1531 wresize (TUI_CMD_WIN
->generic
.handle
,
1532 TUI_CMD_WIN
->generic
.height
,
1533 TUI_CMD_WIN
->generic
.width
);
1535 mvwin (TUI_CMD_WIN
->generic
.handle
,
1536 TUI_CMD_WIN
->generic
.origin
.y
,
1537 TUI_CMD_WIN
->generic
.origin
.x
);
1538 wmove (win_info
->generic
.handle
,
1539 win_info
->detail
.command_info
.cur_line
,
1540 win_info
->detail
.command_info
.curch
);
1549 new_height_ok (struct tui_win_info
*primary_win_info
,
1552 int ok
= (new_height
< tui_term_height ());
1557 enum tui_layout_type cur_layout
= tui_current_layout ();
1559 diff
= (new_height
- primary_win_info
->generic
.height
) * (-1);
1560 if (cur_layout
== SRC_COMMAND
|| cur_layout
== DISASSEM_COMMAND
)
1562 ok
= ((primary_win_info
->generic
.type
== CMD_WIN
1563 && new_height
<= (tui_term_height () - 4)
1564 && new_height
>= MIN_CMD_WIN_HEIGHT
)
1565 || (primary_win_info
->generic
.type
!= CMD_WIN
1566 && new_height
<= (tui_term_height () - 2)
1567 && new_height
>= MIN_WIN_HEIGHT
));
1569 { /* Check the total height. */
1570 struct tui_win_info
*win_info
;
1572 if (primary_win_info
== TUI_CMD_WIN
)
1573 win_info
= (tui_source_windows ())->list
[0];
1575 win_info
= TUI_CMD_WIN
;
1577 (win_info
->generic
.height
+ diff
)) <= tui_term_height ());
1582 int cur_total_height
, total_height
, min_height
= 0;
1583 struct tui_win_info
*first_win
;
1584 struct tui_win_info
*second_win
;
1586 if (cur_layout
== SRC_DISASSEM_COMMAND
)
1588 first_win
= TUI_SRC_WIN
;
1589 second_win
= TUI_DISASM_WIN
;
1593 first_win
= TUI_DATA_WIN
;
1594 second_win
= (tui_source_windows ())->list
[0];
1596 /* We could simply add all the heights to obtain the same
1597 result but below is more explicit since we subtract 1 for
1598 the line that the first and second windows share, and add
1599 one for the locator. */
1600 total_height
= cur_total_height
=
1601 (first_win
->generic
.height
+ second_win
->generic
.height
- 1)
1602 + TUI_CMD_WIN
->generic
.height
+ 1; /* Locator. */
1603 if (primary_win_info
== TUI_CMD_WIN
)
1605 /* Locator included since first & second win share a line. */
1606 ok
= ((first_win
->generic
.height
+
1607 second_win
->generic
.height
+ diff
) >=
1608 (MIN_WIN_HEIGHT
* 2)
1609 && new_height
>= MIN_CMD_WIN_HEIGHT
);
1612 total_height
= new_height
+
1613 (first_win
->generic
.height
+
1614 second_win
->generic
.height
+ diff
);
1615 min_height
= MIN_CMD_WIN_HEIGHT
;
1620 min_height
= MIN_WIN_HEIGHT
;
1622 /* First see if we can increase/decrease the command
1623 window. And make sure that the command window is at
1625 ok
= ((TUI_CMD_WIN
->generic
.height
+ diff
) > 0);
1627 { /* Looks like we have to increase/decrease one of
1628 the other windows. */
1629 if (primary_win_info
== first_win
)
1630 ok
= (second_win
->generic
.height
+ diff
) >= min_height
;
1632 ok
= (first_win
->generic
.height
+ diff
) >= min_height
;
1636 if (primary_win_info
== first_win
)
1637 total_height
= new_height
+
1638 second_win
->generic
.height
+
1639 TUI_CMD_WIN
->generic
.height
+ diff
;
1641 total_height
= new_height
+
1642 first_win
->generic
.height
+
1643 TUI_CMD_WIN
->generic
.height
+ diff
;
1646 /* Now make sure that the proposed total height doesn't
1647 exceed the old total height. */
1649 ok
= (new_height
>= min_height
1650 && total_height
<= cur_total_height
);
1659 parse_scrolling_args (char *arg
,
1660 struct tui_win_info
**win_to_scroll
,
1665 *win_to_scroll
= tui_win_with_focus ();
1667 /* First set up the default window to scroll, in case there is no
1669 if (arg
!= (char *) NULL
)
1671 char *buf
, *buf_ptr
;
1672 struct cleanup
*old_chain
;
1674 /* Process the number of lines to scroll. */
1675 buf
= buf_ptr
= xstrdup (arg
);
1676 old_chain
= make_cleanup (xfree
, buf
);
1677 if (isdigit (*buf_ptr
))
1682 buf_ptr
= strchr (buf_ptr
, ' ');
1683 if (buf_ptr
!= (char *) NULL
)
1685 *buf_ptr
= (char) 0;
1687 *num_to_scroll
= atoi (num_str
);
1690 else if (num_to_scroll
)
1691 *num_to_scroll
= atoi (num_str
);
1694 /* Process the window name if one is specified. */
1695 if (buf_ptr
!= (char *) NULL
)
1700 if (*buf_ptr
== ' ')
1701 while (*(++buf_ptr
) == ' ')
1704 if (*buf_ptr
!= (char) 0)
1708 /* Validate the window name. */
1709 for (i
= 0; i
< strlen (wname
); i
++)
1710 wname
[i
] = tolower (wname
[i
]);
1715 *win_to_scroll
= tui_partial_win_by_name (wname
);
1717 if (*win_to_scroll
== (struct tui_win_info
*) NULL
1718 || !(*win_to_scroll
)->generic
.is_visible
)
1719 error (_("Invalid window specified. \n\
1720 The window name specified must be valid and visible.\n"));
1721 else if (*win_to_scroll
== TUI_CMD_WIN
)
1722 *win_to_scroll
= (tui_source_windows ())->list
[0];
1724 do_cleanups (old_chain
);