]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/tui/tui-win.c
Turn tui_erase_source_content into a method
[thirdparty/binutils-gdb.git] / gdb / tui / tui-win.c
CommitLineData
f377b406 1/* TUI window generic functions.
f33c6cbf 2
42a4f53d 3 Copyright (C) 1998-2019 Free Software Foundation, Inc.
f33c6cbf 4
f377b406 5 Contributed by Hewlett-Packard Company.
c906108c 6
f377b406
SC
7 This file is part of GDB.
8
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
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
f377b406
SC
12 (at your option) any later version.
13
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.
18
19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
f377b406
SC
21
22/* This module contains procedures for handling tui window functions
23 like resize, scrolling, scrolling, changing focus, etc.
24
25 Author: Susan B. Macchia */
c906108c 26
c906108c
SS
27#include "defs.h"
28#include "command.h"
29#include "symtab.h"
30#include "breakpoint.h"
31#include "frame.h"
41783295 32#include "cli/cli-cmds.h"
3e752b04 33#include "top.h"
52575520 34#include "source.h"
c4ef48c6 35#include "event-loop.h"
c906108c 36
d7b2e967 37#include "tui/tui.h"
c4ef48c6 38#include "tui/tui-io.h"
ce38393b 39#include "tui/tui-command.h"
d7b2e967
AC
40#include "tui/tui-data.h"
41#include "tui/tui-wingeneral.h"
42#include "tui/tui-stack.h"
43#include "tui/tui-regs.h"
44#include "tui/tui-disasm.h"
45#include "tui/tui-source.h"
46#include "tui/tui-winsource.h"
2c0b251b 47#include "tui/tui-win.h"
c906108c 48
6a83354a 49#include "gdb_curses.h"
96ec9981 50#include <ctype.h>
dbda9972 51#include "readline/readline.h"
96ec9981 52
9612b5ec
UW
53#include <signal.h>
54
c906108c
SS
55/*******************************
56** Static Local Decls
57********************************/
08ef48c5
MS
58static enum tui_status tui_adjust_win_heights (struct tui_win_info *,
59 int);
6ba8e26f 60static int new_height_ok (struct tui_win_info *, int);
0b39b52e
TT
61static void tui_set_tab_width_command (const char *, int);
62static void tui_refresh_all_command (const char *, int);
1d12d88f 63static void tui_all_windows_info (const char *, int);
0b39b52e
TT
64static void tui_scroll_forward_command (const char *, int);
65static void tui_scroll_backward_command (const char *, int);
66static void tui_scroll_left_command (const char *, int);
67static void tui_scroll_right_command (const char *, int);
68static void parse_scrolling_args (const char *,
08ef48c5
MS
69 struct tui_win_info **,
70 int *);
c906108c
SS
71
72
73/***************************************
74** DEFINITIONS
75***************************************/
57dbb3af 76#define WIN_HEIGHT_USAGE "Usage: winheight WINDOW-NAME [+ | -] NUM-LINES\n"
bf212be1 77#define FOCUS_USAGE "Usage: focus [WINDOW-NAME | next | prev]\n"
c906108c
SS
78
79/***************************************
80** PUBLIC FUNCTIONS
81***************************************/
82
17aae570
SC
83#ifndef ACS_LRCORNER
84# define ACS_LRCORNER '+'
85#endif
86#ifndef ACS_LLCORNER
87# define ACS_LLCORNER '+'
88#endif
89#ifndef ACS_ULCORNER
90# define ACS_ULCORNER '+'
91#endif
92#ifndef ACS_URCORNER
93# define ACS_URCORNER '+'
94#endif
95#ifndef ACS_HLINE
96# define ACS_HLINE '-'
97#endif
98#ifndef ACS_VLINE
99# define ACS_VLINE '|'
100#endif
101
af101512 102/* Possible values for tui-border-kind variable. */
40478521 103static const char *const tui_border_kind_enums[] = {
af101512
SC
104 "space",
105 "ascii",
106 "acs",
107 NULL
108};
109
110/* Possible values for tui-border-mode and tui-active-border-mode. */
40478521 111static const char *const tui_border_mode_enums[] = {
af101512
SC
112 "normal",
113 "standout",
114 "reverse",
115 "half",
116 "half-standout",
117 "bold",
118 "bold-standout",
119 NULL
120};
121
122struct tui_translate
123{
124 const char *name;
125 int value;
126};
127
128/* Translation table for border-mode variables.
129 The list of values must be terminated by a NULL.
130 After the NULL value, an entry defines the default. */
131struct tui_translate tui_border_mode_translate[] = {
132 { "normal", A_NORMAL },
133 { "standout", A_STANDOUT },
134 { "reverse", A_REVERSE },
135 { "half", A_DIM },
136 { "half-standout", A_DIM | A_STANDOUT },
137 { "bold", A_BOLD },
138 { "bold-standout", A_BOLD | A_STANDOUT },
139 { 0, 0 },
140 { "normal", A_NORMAL }
141};
142
143/* Translation tables for border-kind, one for each border
144 character (see wborder, border curses operations).
145 -1 is used to indicate the ACS because ACS characters
146 are determined at run time by curses (depends on terminal). */
147struct tui_translate tui_border_kind_translate_vline[] = {
148 { "space", ' ' },
149 { "ascii", '|' },
150 { "acs", -1 },
151 { 0, 0 },
152 { "ascii", '|' }
153};
154
155struct tui_translate tui_border_kind_translate_hline[] = {
156 { "space", ' ' },
157 { "ascii", '-' },
158 { "acs", -1 },
159 { 0, 0 },
160 { "ascii", '-' }
161};
162
163struct tui_translate tui_border_kind_translate_ulcorner[] = {
164 { "space", ' ' },
165 { "ascii", '+' },
166 { "acs", -1 },
167 { 0, 0 },
168 { "ascii", '+' }
169};
170
171struct tui_translate tui_border_kind_translate_urcorner[] = {
172 { "space", ' ' },
173 { "ascii", '+' },
174 { "acs", -1 },
175 { 0, 0 },
176 { "ascii", '+' }
177};
178
179struct tui_translate tui_border_kind_translate_llcorner[] = {
180 { "space", ' ' },
181 { "ascii", '+' },
182 { "acs", -1 },
183 { 0, 0 },
184 { "ascii", '+' }
185};
186
187struct tui_translate tui_border_kind_translate_lrcorner[] = {
188 { "space", ' ' },
189 { "ascii", '+' },
190 { "acs", -1 },
191 { 0, 0 },
192 { "ascii", '+' }
193};
194
195
196/* Tui configuration variables controlled with set/show command. */
197const char *tui_active_border_mode = "bold-standout";
920d2a44 198static void
08ef48c5
MS
199show_tui_active_border_mode (struct ui_file *file,
200 int from_tty,
201 struct cmd_list_element *c,
202 const char *value)
920d2a44
AC
203{
204 fprintf_filtered (file, _("\
205The attribute mode to use for the active TUI window border is \"%s\".\n"),
206 value);
207}
208
af101512 209const char *tui_border_mode = "normal";
920d2a44 210static void
08ef48c5
MS
211show_tui_border_mode (struct ui_file *file,
212 int from_tty,
213 struct cmd_list_element *c,
214 const char *value)
920d2a44
AC
215{
216 fprintf_filtered (file, _("\
217The attribute mode to use for the TUI window borders is \"%s\".\n"),
218 value);
219}
220
af101512 221const char *tui_border_kind = "acs";
920d2a44 222static void
08ef48c5
MS
223show_tui_border_kind (struct ui_file *file,
224 int from_tty,
225 struct cmd_list_element *c,
226 const char *value)
920d2a44
AC
227{
228 fprintf_filtered (file, _("The kind of border for TUI windows is \"%s\".\n"),
229 value);
230}
231
af101512 232
1cc6d956
MS
233/* Tui internal configuration variables. These variables are updated
234 by tui_update_variables to reflect the tui configuration
af101512
SC
235 variables. */
236chtype tui_border_vline;
237chtype tui_border_hline;
238chtype tui_border_ulcorner;
239chtype tui_border_urcorner;
240chtype tui_border_llcorner;
241chtype tui_border_lrcorner;
242
243int tui_border_attrs;
244int tui_active_border_attrs;
245
246/* Identify the item in the translation table.
247 When the item is not recognized, use the default entry. */
248static struct tui_translate *
249translate (const char *name, struct tui_translate *table)
250{
251 while (table->name)
252 {
253 if (name && strcmp (table->name, name) == 0)
254 return table;
255 table++;
256 }
257
258 /* Not found, return default entry. */
259 table++;
260 return table;
261}
262
263/* Update the tui internal configuration according to gdb settings.
264 Returns 1 if the configuration has changed and the screen should
265 be redrawn. */
266int
d02c80cd 267tui_update_variables (void)
af101512
SC
268{
269 int need_redraw = 0;
270 struct tui_translate *entry;
271
272 entry = translate (tui_border_mode, tui_border_mode_translate);
273 if (tui_border_attrs != entry->value)
274 {
275 tui_border_attrs = entry->value;
276 need_redraw = 1;
277 }
278 entry = translate (tui_active_border_mode, tui_border_mode_translate);
279 if (tui_active_border_attrs != entry->value)
280 {
281 tui_active_border_attrs = entry->value;
282 need_redraw = 1;
283 }
284
285 /* If one corner changes, all characters are changed.
286 Only check the first one. The ACS characters are determined at
287 run time by curses terminal management. */
288 entry = translate (tui_border_kind, tui_border_kind_translate_lrcorner);
289 if (tui_border_lrcorner != (chtype) entry->value)
290 {
291 tui_border_lrcorner = (entry->value < 0) ? ACS_LRCORNER : entry->value;
292 need_redraw = 1;
293 }
294 entry = translate (tui_border_kind, tui_border_kind_translate_llcorner);
295 tui_border_llcorner = (entry->value < 0) ? ACS_LLCORNER : entry->value;
296
297 entry = translate (tui_border_kind, tui_border_kind_translate_ulcorner);
298 tui_border_ulcorner = (entry->value < 0) ? ACS_ULCORNER : entry->value;
299
300 entry = translate (tui_border_kind, tui_border_kind_translate_urcorner);
301 tui_border_urcorner = (entry->value < 0) ? ACS_URCORNER : entry->value;
302
303 entry = translate (tui_border_kind, tui_border_kind_translate_hline);
304 tui_border_hline = (entry->value < 0) ? ACS_HLINE : entry->value;
305
306 entry = translate (tui_border_kind, tui_border_kind_translate_vline);
307 tui_border_vline = (entry->value < 0) ? ACS_VLINE : entry->value;
308
309 return need_redraw;
310}
311
c9684879 312static void
981a3fb3 313set_tui_cmd (const char *args, int from_tty)
c9684879
SC
314{
315}
316
317static void
981a3fb3 318show_tui_cmd (const char *args, int from_tty)
c9684879
SC
319{
320}
af101512 321
10f59415
SC
322static struct cmd_list_element *tuilist;
323
324static void
981a3fb3 325tui_command (const char *args, int from_tty)
10f59415 326{
a3f17187
AC
327 printf_unfiltered (_("\"tui\" must be followed by the name of a "
328 "tui command.\n"));
635c7e8a 329 help_list (tuilist, "tui ", all_commands, gdb_stdout);
10f59415
SC
330}
331
332struct cmd_list_element **
da745b36 333tui_get_cmd_list (void)
10f59415
SC
334{
335 if (tuilist == 0)
336 add_prefix_cmd ("tui", class_tui, tui_command,
1bedd215 337 _("Text User Interface commands."),
10f59415
SC
338 &tuilist, "tui ", 0, &cmdlist);
339 return &tuilist;
340}
341
6cdb25f4
EZ
342/* The set_func hook of "set tui ..." commands that affect the window
343 borders on the TUI display. */
344void
eb4c3f4a
TT
345tui_set_var_cmd (const char *null_args,
346 int from_tty, struct cmd_list_element *c)
6cdb25f4
EZ
347{
348 if (tui_update_variables () && tui_active)
349 tui_rehighlight_all ();
350}
351
97605e61
AB
352/* Generic window name completion function. Complete window name pointed
353 to by TEXT and WORD. If INCLUDE_NEXT_PREV_P is true then the special
354 window names 'next' and 'prev' will also be considered as possible
355 completions of the window name. */
2e52ae68 356
eb3ff9a5
PA
357static void
358window_name_completer (completion_tracker &tracker,
359 int include_next_prev_p,
97605e61 360 const char *text, const char *word)
2e52ae68 361{
625ad440 362 std::vector<const char *> completion_name_vec;
2e52ae68 363
1ce3e844 364 for (tui_win_info *win_info : all_tui_windows ())
2e52ae68
PP
365 {
366 const char *completion_name = NULL;
367
368 /* We can't focus on an invisible window. */
1ce3e844 369 if (!win_info->is_visible)
2e52ae68
PP
370 continue;
371
1ce3e844 372 completion_name = win_info->name ();
150375dc 373 gdb_assert (completion_name != NULL);
625ad440 374 completion_name_vec.push_back (completion_name);
2e52ae68
PP
375 }
376
377 /* If no windows are considered visible then the TUI has not yet been
378 initialized. But still "focus src" and "focus cmd" will work because
379 invoking the focus command will entail initializing the TUI which sets the
380 default layout to SRC_COMMAND. */
625ad440 381 if (completion_name_vec.empty ())
2e52ae68 382 {
625ad440
SM
383 completion_name_vec.push_back (SRC_NAME);
384 completion_name_vec.push_back (CMD_NAME);
2e52ae68
PP
385 }
386
97605e61
AB
387 if (include_next_prev_p)
388 {
625ad440
SM
389 completion_name_vec.push_back ("next");
390 completion_name_vec.push_back ("prev");
97605e61 391 }
2e52ae68 392
2e52ae68 393
625ad440
SM
394 completion_name_vec.push_back (NULL);
395 complete_on_enum (tracker, completion_name_vec.data (), text, word);
2e52ae68
PP
396}
397
97605e61
AB
398/* Complete possible window names to focus on. TEXT is the complete text
399 entered so far, WORD is the word currently being completed. */
400
eb3ff9a5 401static void
97605e61 402focus_completer (struct cmd_list_element *ignore,
eb3ff9a5
PA
403 completion_tracker &tracker,
404 const char *text, const char *word)
97605e61 405{
eb3ff9a5 406 window_name_completer (tracker, 1, text, word);
97605e61
AB
407}
408
409/* Complete possible window names for winheight command. TEXT is the
410 complete text entered so far, WORD is the word currently being
411 completed. */
412
eb3ff9a5 413static void
97605e61 414winheight_completer (struct cmd_list_element *ignore,
eb3ff9a5 415 completion_tracker &tracker,
97605e61
AB
416 const char *text, const char *word)
417{
418 /* The first word is the window name. That we can complete. Subsequent
419 words can't be completed. */
420 if (word != text)
eb3ff9a5 421 return;
97605e61 422
eb3ff9a5 423 window_name_completer (tracker, 0, text, word);
97605e61
AB
424}
425
3e752b04
SC
426/* Update gdb's knowledge of the terminal size. */
427void
d02c80cd 428tui_update_gdb_sizes (void)
3e752b04 429{
d6e5e7f7
PP
430 int width, height;
431
432 if (tui_active)
433 {
cb2ce893
TT
434 width = TUI_CMD_WIN->width;
435 height = TUI_CMD_WIN->height;
d6e5e7f7
PP
436 }
437 else
438 {
439 width = tui_term_width ();
440 height = tui_term_height ();
441 }
442
443 set_screen_width_and_height (width, height);
3e752b04
SC
444}
445
c906108c 446
1cc6d956 447/* Set the logical focus to win_info. */
c906108c 448void
5b6fe301 449tui_set_win_focus_to (struct tui_win_info *win_info)
c906108c 450{
6d012f14 451 if (win_info != NULL)
c906108c 452 {
5b6fe301 453 struct tui_win_info *win_with_focus = tui_win_with_focus ();
c906108c 454
bbc228ee 455 tui_unhighlight_win (win_with_focus);
6d012f14 456 tui_set_win_with_focus (win_info);
bbc228ee 457 tui_highlight_win (win_info);
c906108c 458 }
6ba8e26f 459}
c906108c
SS
460
461
c906108c 462void
13446e05 463tui_win_info::forward_scroll (int num_to_scroll)
c906108c 464{
13446e05 465 if (num_to_scroll == 0)
cb2ce893 466 num_to_scroll = height - 3;
c906108c 467
c3bd716f 468 do_scroll_vertical (num_to_scroll);
a21fcd8f 469}
c906108c 470
c906108c 471void
13446e05 472tui_win_info::backward_scroll (int num_to_scroll)
c906108c 473{
13446e05 474 if (num_to_scroll == 0)
cb2ce893 475 num_to_scroll = height - 3;
13446e05 476
c3bd716f 477 do_scroll_vertical (-num_to_scroll);
a21fcd8f 478}
c906108c
SS
479
480
c906108c 481void
13446e05 482tui_win_info::left_scroll (int num_to_scroll)
c906108c 483{
13446e05
TT
484 if (num_to_scroll == 0)
485 num_to_scroll = 1;
486
c3bd716f 487 do_scroll_horizontal (num_to_scroll);
a21fcd8f 488}
c906108c
SS
489
490
c906108c 491void
13446e05 492tui_win_info::right_scroll (int num_to_scroll)
c906108c 493{
13446e05
TT
494 if (num_to_scroll == 0)
495 num_to_scroll = 1;
496
c3bd716f 497 do_scroll_horizontal (-num_to_scroll);
e8b915dc 498}
c906108c
SS
499
500
c906108c 501void
a21fcd8f 502tui_refresh_all_win (void)
c906108c 503{
3e266828 504 clearok (curscr, TRUE);
1ce3e844
TT
505 tui_refresh_all ();
506 for (tui_win_info *win_info : all_tui_windows ())
c906108c 507 {
1ce3e844
TT
508 if (win_info->is_visible)
509 win_info->refresh_all ();
c906108c 510 }
47d3492a 511 tui_show_locator_content ();
bc712bbf 512}
c906108c 513
6cdb25f4
EZ
514void
515tui_rehighlight_all (void)
516{
1ce3e844 517 for (tui_win_info *win_info : all_tui_windows ())
b4ef5aeb 518 win_info->check_and_display_highlight_if_needed ();
6cdb25f4 519}
c906108c 520
b021a221 521/* Resize all the windows based on the terminal size. This function
ae2b5380 522 gets called from within the readline SIGWINCH handler. */
c906108c 523void
6ba8e26f 524tui_resize_all (void)
c906108c 525{
6ba8e26f 526 int height_diff, width_diff;
9255ee31 527 int screenheight, screenwidth;
c906108c 528
9255ee31 529 rl_get_screen_size (&screenheight, &screenwidth);
6ba8e26f
AC
530 width_diff = screenwidth - tui_term_width ();
531 height_diff = screenheight - tui_term_height ();
532 if (height_diff || width_diff)
c906108c 533 {
6ba8e26f 534 enum tui_layout_type cur_layout = tui_current_layout ();
5b6fe301 535 struct tui_win_info *win_with_focus = tui_win_with_focus ();
6ba8e26f
AC
536 struct tui_win_info *first_win;
537 struct tui_win_info *second_win;
7908abbf 538 tui_source_window_base *src_win;
3add462f 539 struct tui_locator_window *locator = tui_locator_win_info_ptr ();
6ba8e26f 540 int new_height, split_diff, cmd_split_diff, num_wins_displayed = 2;
c906108c 541
10f59415
SC
542#ifdef HAVE_RESIZE_TERM
543 resize_term (screenheight, screenwidth);
544#endif
1cc6d956 545 /* Turn keypad off while we resize. */
6ba8e26f 546 if (win_with_focus != TUI_CMD_WIN)
cb2ce893 547 keypad (TUI_CMD_WIN->handle, FALSE);
3e752b04 548 tui_update_gdb_sizes ();
dd1abb8c
AC
549 tui_set_term_height_to (screenheight);
550 tui_set_term_width_to (screenwidth);
e5908723
MS
551 if (cur_layout == SRC_DISASSEM_COMMAND
552 || cur_layout == SRC_DATA_COMMAND
553 || cur_layout == DISASSEM_DATA_COMMAND)
6ba8e26f
AC
554 num_wins_displayed++;
555 split_diff = height_diff / num_wins_displayed;
556 cmd_split_diff = split_diff;
557 if (height_diff % num_wins_displayed)
c906108c 558 {
6ba8e26f
AC
559 if (height_diff < 0)
560 cmd_split_diff--;
c906108c 561 else
c366c1f0
TT
562 cmd_split_diff++;
563 }
1cc6d956 564 /* Now adjust each window. */
c366c1f0
TT
565 /* erase + clearok are used instead of a straightforward clear as
566 AIX 5.3 does not define clear. */
567 erase ();
568 clearok (curscr, TRUE);
c906108c 569 refresh ();
6ba8e26f 570 switch (cur_layout)
c366c1f0 571 {
c906108c
SS
572 case SRC_COMMAND:
573 case DISASSEM_COMMAND:
7908abbf
TT
574 src_win = tui_source_windows ()[0];
575 first_win = src_win;
cb2ce893 576 first_win->width += width_diff;
6ba8e26f 577 locator->width += width_diff;
1cc6d956 578 /* Check for invalid heights. */
6ba8e26f 579 if (height_diff == 0)
cb2ce893
TT
580 new_height = first_win->height;
581 else if ((first_win->height + split_diff) >=
c906108c 582 (screenheight - MIN_CMD_WIN_HEIGHT - 1))
6ba8e26f 583 new_height = screenheight - MIN_CMD_WIN_HEIGHT - 1;
cb2ce893 584 else if ((first_win->height + split_diff) <= 0)
6ba8e26f 585 new_height = MIN_WIN_HEIGHT;
c906108c 586 else
cb2ce893 587 new_height = first_win->height + split_diff;
c906108c 588
0036e657 589 locator->origin.y = new_height + 1;
daa15dde 590 first_win->make_invisible_and_set_new_height (new_height);
cb2ce893
TT
591 TUI_CMD_WIN->origin.y = locator->origin.y + 1;
592 TUI_CMD_WIN->width += width_diff;
593 new_height = screenheight - TUI_CMD_WIN->origin.y;
daa15dde 594 TUI_CMD_WIN->make_invisible_and_set_new_height (new_height);
5fcee43a
TT
595 first_win->make_visible_with_new_height ();
596 TUI_CMD_WIN->make_visible_with_new_height ();
53e7cdba 597 if (src_win->content.empty ())
e25d2004 598 src_win->erase_source_content ();
c906108c
SS
599 break;
600 default:
6ba8e26f 601 if (cur_layout == SRC_DISASSEM_COMMAND)
c906108c 602 {
7908abbf
TT
603 src_win = TUI_SRC_WIN;
604 first_win = src_win;
cb2ce893 605 first_win->width += width_diff;
6ba8e26f 606 second_win = TUI_DISASM_WIN;
cb2ce893 607 second_win->width += width_diff;
c906108c
SS
608 }
609 else
610 {
6ba8e26f 611 first_win = TUI_DATA_WIN;
cb2ce893 612 first_win->width += width_diff;
7908abbf
TT
613 src_win = tui_source_windows ()[0];
614 second_win = src_win;
cb2ce893 615 second_win->width += width_diff;
c906108c 616 }
1cc6d956
MS
617 /* Change the first window's height/width. */
618 /* Check for invalid heights. */
6ba8e26f 619 if (height_diff == 0)
cb2ce893
TT
620 new_height = first_win->height;
621 else if ((first_win->height +
622 second_win->height + (split_diff * 2)) >=
c906108c 623 (screenheight - MIN_CMD_WIN_HEIGHT - 1))
6ba8e26f 624 new_height = (screenheight - MIN_CMD_WIN_HEIGHT - 1) / 2;
cb2ce893 625 else if ((first_win->height + split_diff) <= 0)
6ba8e26f 626 new_height = MIN_WIN_HEIGHT;
c906108c 627 else
cb2ce893 628 new_height = first_win->height + split_diff;
daa15dde 629 first_win->make_invisible_and_set_new_height (new_height);
c906108c 630
6ba8e26f 631 locator->width += width_diff;
c906108c 632
1cc6d956
MS
633 /* Change the second window's height/width. */
634 /* Check for invalid heights. */
6ba8e26f 635 if (height_diff == 0)
cb2ce893
TT
636 new_height = second_win->height;
637 else if ((first_win->height +
638 second_win->height + (split_diff * 2)) >=
c906108c
SS
639 (screenheight - MIN_CMD_WIN_HEIGHT - 1))
640 {
6ba8e26f
AC
641 new_height = screenheight - MIN_CMD_WIN_HEIGHT - 1;
642 if (new_height % 2)
643 new_height = (new_height / 2) + 1;
c906108c 644 else
6ba8e26f 645 new_height /= 2;
c906108c 646 }
cb2ce893 647 else if ((second_win->height + split_diff) <= 0)
6ba8e26f 648 new_height = MIN_WIN_HEIGHT;
c906108c 649 else
cb2ce893
TT
650 new_height = second_win->height + split_diff;
651 second_win->origin.y = first_win->height - 1;
daa15dde 652 second_win->make_invisible_and_set_new_height (new_height);
c906108c 653
1cc6d956 654 /* Change the command window's height/width. */
cb2ce893 655 TUI_CMD_WIN->origin.y = locator->origin.y + 1;
daa15dde
TT
656 TUI_CMD_WIN->make_invisible_and_set_new_height (TUI_CMD_WIN->height
657 + cmd_split_diff);
5fcee43a
TT
658 first_win->make_visible_with_new_height ();
659 second_win->make_visible_with_new_height ();
660 TUI_CMD_WIN->make_visible_with_new_height ();
53e7cdba 661 if (src_win->content.empty ())
e25d2004 662 src_win->erase_source_content ();
c906108c
SS
663 break;
664 }
fede5273
TT
665
666 tui_delete_invisible_windows ();
1cc6d956
MS
667 /* Turn keypad back on, unless focus is in the command
668 window. */
6ba8e26f 669 if (win_with_focus != TUI_CMD_WIN)
cb2ce893 670 keypad (TUI_CMD_WIN->handle, TRUE);
c906108c 671 }
6ba8e26f 672}
c906108c 673
2c0b251b 674#ifdef SIGWINCH
c4ef48c6
PP
675/* Token for use by TUI's asynchronous SIGWINCH handler. */
676static struct async_signal_handler *tui_sigwinch_token;
677
678/* TUI's SIGWINCH signal handler. */
2c0b251b 679static void
6ba8e26f 680tui_sigwinch_handler (int signal)
c906108c 681{
c4ef48c6 682 mark_async_signal_handler (tui_sigwinch_token);
dd1abb8c 683 tui_set_win_resized_to (TRUE);
6ba8e26f 684}
c4ef48c6
PP
685
686/* Callback for asynchronously resizing TUI following a SIGWINCH signal. */
687static void
688tui_async_resize_screen (gdb_client_data arg)
689{
a88d0bb3
PP
690 rl_resize_terminal ();
691
c4ef48c6 692 if (!tui_active)
a88d0bb3
PP
693 {
694 int screen_height, screen_width;
c4ef48c6 695
a88d0bb3
PP
696 rl_get_screen_size (&screen_height, &screen_width);
697 set_screen_width_and_height (screen_width, screen_height);
698
699 /* win_resized is left set so that the next call to tui_enable()
700 resizes the TUI windows. */
701 }
702 else
703 {
1e04046d 704 tui_set_win_resized_to (FALSE);
a88d0bb3
PP
705 tui_resize_all ();
706 tui_refresh_all_win ();
707 tui_update_gdb_sizes ();
a88d0bb3
PP
708 tui_redisplay_readline ();
709 }
c4ef48c6 710}
2c0b251b 711#endif
c906108c 712
c4ef48c6
PP
713/* Initialize TUI's SIGWINCH signal handler. Note that the handler is not
714 uninstalled when we exit TUI, so the handler should not assume that TUI is
715 always active. */
9612b5ec
UW
716void
717tui_initialize_win (void)
718{
719#ifdef SIGWINCH
c4ef48c6
PP
720 tui_sigwinch_token
721 = create_async_signal_handler (tui_async_resize_screen, NULL);
722
723 {
9612b5ec 724#ifdef HAVE_SIGACTION
c4ef48c6 725 struct sigaction old_winch;
1c5313c5 726
c4ef48c6
PP
727 memset (&old_winch, 0, sizeof (old_winch));
728 old_winch.sa_handler = &tui_sigwinch_handler;
a344fc09 729#ifdef SA_RESTART
c4ef48c6 730 old_winch.sa_flags = SA_RESTART;
a344fc09 731#endif
c4ef48c6 732 sigaction (SIGWINCH, &old_winch, NULL);
9612b5ec 733#else
c4ef48c6 734 signal (SIGWINCH, &tui_sigwinch_handler);
9612b5ec 735#endif
c4ef48c6 736 }
9612b5ec
UW
737#endif
738}
c906108c
SS
739
740
741/*************************
742** STATIC LOCAL FUNCTIONS
743**************************/
744
745
c906108c 746static void
0b39b52e 747tui_scroll_forward_command (const char *arg, int from_tty)
c906108c 748{
6ba8e26f 749 int num_to_scroll = 1;
5b6fe301 750 struct tui_win_info *win_to_scroll;
c906108c 751
1854bb21
SC
752 /* Make sure the curses mode is enabled. */
753 tui_enable ();
63a33118 754 if (arg == NULL)
cafb3438 755 parse_scrolling_args (arg, &win_to_scroll, NULL);
c906108c 756 else
6ba8e26f 757 parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll);
13446e05 758 win_to_scroll->forward_scroll (num_to_scroll);
e8b915dc 759}
c906108c
SS
760
761
c906108c 762static void
0b39b52e 763tui_scroll_backward_command (const char *arg, int from_tty)
c906108c 764{
6ba8e26f 765 int num_to_scroll = 1;
5b6fe301 766 struct tui_win_info *win_to_scroll;
c906108c 767
1854bb21
SC
768 /* Make sure the curses mode is enabled. */
769 tui_enable ();
63a33118 770 if (arg == NULL)
cafb3438 771 parse_scrolling_args (arg, &win_to_scroll, NULL);
c906108c 772 else
6ba8e26f 773 parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll);
13446e05 774 win_to_scroll->backward_scroll (num_to_scroll);
e8b915dc 775}
c906108c
SS
776
777
c906108c 778static void
0b39b52e 779tui_scroll_left_command (const char *arg, int from_tty)
c906108c 780{
6ba8e26f 781 int num_to_scroll;
5b6fe301 782 struct tui_win_info *win_to_scroll;
c906108c 783
1854bb21
SC
784 /* Make sure the curses mode is enabled. */
785 tui_enable ();
6ba8e26f 786 parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll);
13446e05 787 win_to_scroll->left_scroll (num_to_scroll);
e8b915dc 788}
c906108c
SS
789
790
c906108c 791static void
0b39b52e 792tui_scroll_right_command (const char *arg, int from_tty)
c906108c 793{
6ba8e26f 794 int num_to_scroll;
5b6fe301 795 struct tui_win_info *win_to_scroll;
c906108c 796
1854bb21
SC
797 /* Make sure the curses mode is enabled. */
798 tui_enable ();
6ba8e26f 799 parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll);
13446e05 800 win_to_scroll->right_scroll (num_to_scroll);
e8b915dc 801}
c906108c
SS
802
803
6ba8e26f 804/* Set focus to the window named by 'arg'. */
c906108c 805static void
01aeb396 806tui_set_focus_command (const char *arg, int from_tty)
c906108c 807{
01aeb396
TT
808 tui_enable ();
809
63a33118 810 if (arg != NULL)
c906108c 811 {
63a33118 812 char *buf_ptr = xstrdup (arg);
c906108c 813 int i;
e65b5245 814 struct tui_win_info *win_info = NULL;
c906108c 815
6ba8e26f 816 for (i = 0; (i < strlen (buf_ptr)); i++)
6dce28e4 817 buf_ptr[i] = tolower (arg[i]);
c906108c 818
6dce28e4 819 if (subset_compare (buf_ptr, "next"))
6d012f14 820 win_info = tui_next_win (tui_win_with_focus ());
6dce28e4 821 else if (subset_compare (buf_ptr, "prev"))
6d012f14 822 win_info = tui_prev_win (tui_win_with_focus ());
c906108c 823 else
6ba8e26f 824 win_info = tui_partial_win_by_name (buf_ptr);
c906108c 825
cb2ce893 826 if (win_info == NULL || !win_info->is_visible)
8a3fe4f8
AC
827 warning (_("Invalid window specified. \n\
828The window name specified must be valid and visible.\n"));
c906108c
SS
829 else
830 {
6d012f14 831 tui_set_win_focus_to (win_info);
cb2ce893 832 keypad (TUI_CMD_WIN->handle, (win_info != TUI_CMD_WIN));
c906108c
SS
833 }
834
6ba8e26f 835 xfree (buf_ptr);
a3f17187 836 printf_filtered (_("Focus set to %s window.\n"),
152f3f4b 837 tui_win_with_focus ()->name ());
c906108c
SS
838 }
839 else
8a3fe4f8 840 warning (_("Incorrect Number of Arguments.\n%s"), FOCUS_USAGE);
6ba8e26f 841}
c906108c 842
c906108c 843static void
1d12d88f 844tui_all_windows_info (const char *arg, int from_tty)
c906108c 845{
5b6fe301 846 struct tui_win_info *win_with_focus = tui_win_with_focus ();
c906108c 847
1ce3e844
TT
848 for (tui_win_info *win_info : all_tui_windows ())
849 if (win_info->is_visible)
c906108c 850 {
1ce3e844 851 if (win_with_focus == win_info)
c906108c 852 printf_filtered (" %s\t(%d lines) <has focus>\n",
1ce3e844
TT
853 win_info->name (),
854 win_info->height);
c906108c
SS
855 else
856 printf_filtered (" %s\t(%d lines)\n",
1ce3e844
TT
857 win_info->name (),
858 win_info->height);
c906108c 859 }
6ba8e26f 860}
c906108c
SS
861
862
c906108c 863static void
0b39b52e 864tui_refresh_all_command (const char *arg, int from_tty)
c906108c 865{
1854bb21
SC
866 /* Make sure the curses mode is enabled. */
867 tui_enable ();
868
a21fcd8f 869 tui_refresh_all_win ();
c906108c
SS
870}
871
7806cea7
TT
872/* The tab width that should be used by the TUI. */
873
874unsigned int tui_tab_width = DEFAULT_TAB_LEN;
875
876/* The tab width as set by the user. */
877
878static unsigned int internal_tab_width = DEFAULT_TAB_LEN;
879
d83f1fe6
TT
880/* After the tab width is set, call this to update the relevant
881 windows. */
882
883static void
884update_tab_width ()
885{
1ce3e844 886 for (tui_win_info *win_info : all_tui_windows ())
7806cea7 887 {
1ce3e844
TT
888 if (win_info->is_visible)
889 win_info->update_tab_width ();
7806cea7
TT
890 }
891}
892
893/* Callback for "set tui tab-width". */
894
895static void
896tui_set_tab_width (const char *ignore,
897 int from_tty, struct cmd_list_element *c)
898{
899 if (internal_tab_width == 0)
900 {
901 internal_tab_width = tui_tab_width;
902 error (_("Tab width must not be 0"));
903 }
904
905 tui_tab_width = internal_tab_width;
906 update_tab_width ();
907}
908
909/* Callback for "show tui tab-width". */
910
911static void
912tui_show_tab_width (struct ui_file *file, int from_tty,
913 struct cmd_list_element *c, const char *value)
914{
915 fprintf_filtered (gdb_stdout, _("TUI tab width is %s spaces.\n"), value);
916
917}
c906108c 918
c54da50d 919/* Set the tab width of the specified window. */
c906108c 920static void
0b39b52e 921tui_set_tab_width_command (const char *arg, int from_tty)
c906108c 922{
1854bb21
SC
923 /* Make sure the curses mode is enabled. */
924 tui_enable ();
63a33118 925 if (arg != NULL)
c906108c
SS
926 {
927 int ts;
928
929 ts = atoi (arg);
7806cea7
TT
930 if (ts <= 0)
931 warning (_("Tab widths greater than 0 must be specified."));
932 else
cb86fcc1 933 {
7806cea7
TT
934 internal_tab_width = ts;
935 tui_tab_width = ts;
936
937 update_tab_width ();
cb86fcc1 938 }
c906108c 939 }
6ba8e26f 940}
c906108c
SS
941
942
1cc6d956 943/* Set the height of the specified window. */
c906108c 944static void
4dde7b34 945tui_set_win_height_command (const char *arg, int from_tty)
c906108c 946{
1854bb21
SC
947 /* Make sure the curses mode is enabled. */
948 tui_enable ();
63a33118 949 if (arg != NULL)
c906108c 950 {
f71c8822
TT
951 std::string copy = arg;
952 char *buf = &copy[0];
6ba8e26f 953 char *buf_ptr = buf;
e65b5245 954 char *wname = NULL;
6ba8e26f 955 int new_height, i;
5b6fe301 956 struct tui_win_info *win_info;
c906108c 957
6ba8e26f
AC
958 wname = buf_ptr;
959 buf_ptr = strchr (buf_ptr, ' ');
63a33118 960 if (buf_ptr != NULL)
c906108c 961 {
6ba8e26f 962 *buf_ptr = (char) 0;
c906108c 963
ef5eab5a 964 /* Validate the window name. */
c906108c 965 for (i = 0; i < strlen (wname); i++)
6dce28e4 966 wname[i] = tolower (wname[i]);
6d012f14 967 win_info = tui_partial_win_by_name (wname);
c906108c 968
cb2ce893 969 if (win_info == NULL || !win_info->is_visible)
8a3fe4f8
AC
970 warning (_("Invalid window specified. \n\
971The window name specified must be valid and visible.\n"));
c906108c
SS
972 else
973 {
1cc6d956 974 /* Process the size. */
6ba8e26f 975 while (*(++buf_ptr) == ' ')
c906108c
SS
976 ;
977
6ba8e26f 978 if (*buf_ptr != (char) 0)
c906108c
SS
979 {
980 int negate = FALSE;
6ba8e26f
AC
981 int fixed_size = TRUE;
982 int input_no;;
c906108c 983
6ba8e26f 984 if (*buf_ptr == '+' || *buf_ptr == '-')
c906108c 985 {
6ba8e26f 986 if (*buf_ptr == '-')
c906108c 987 negate = TRUE;
6ba8e26f
AC
988 fixed_size = FALSE;
989 buf_ptr++;
c906108c 990 }
6ba8e26f
AC
991 input_no = atoi (buf_ptr);
992 if (input_no > 0)
c906108c
SS
993 {
994 if (negate)
6ba8e26f
AC
995 input_no *= (-1);
996 if (fixed_size)
997 new_height = input_no;
c906108c 998 else
cb2ce893 999 new_height = win_info->height + input_no;
ef5eab5a
MS
1000
1001 /* Now change the window's height, and adjust
1002 all other windows around it. */
6ba8e26f
AC
1003 if (tui_adjust_win_heights (win_info,
1004 new_height) == TUI_FAILURE)
8a3fe4f8 1005 warning (_("Invalid window height specified.\n%s"),
c906108c
SS
1006 WIN_HEIGHT_USAGE);
1007 else
3e752b04 1008 tui_update_gdb_sizes ();
c906108c
SS
1009 }
1010 else
8a3fe4f8 1011 warning (_("Invalid window height specified.\n%s"),
c906108c
SS
1012 WIN_HEIGHT_USAGE);
1013 }
1014 }
1015 }
1016 else
1017 printf_filtered (WIN_HEIGHT_USAGE);
c906108c
SS
1018 }
1019 else
1020 printf_filtered (WIN_HEIGHT_USAGE);
6ba8e26f 1021}
c906108c 1022
6ba8e26f 1023/* Function to adjust all window heights around the primary. */
22940a24 1024static enum tui_status
08ef48c5
MS
1025tui_adjust_win_heights (struct tui_win_info *primary_win_info,
1026 int new_height)
c906108c 1027{
22940a24 1028 enum tui_status status = TUI_FAILURE;
c906108c 1029
6ba8e26f 1030 if (new_height_ok (primary_win_info, new_height))
c906108c
SS
1031 {
1032 status = TUI_SUCCESS;
cb2ce893 1033 if (new_height != primary_win_info->height)
c906108c 1034 {
bc712bbf 1035 int diff;
5b6fe301 1036 struct tui_win_info *win_info;
3add462f 1037 struct tui_locator_window *locator = tui_locator_win_info_ptr ();
6ba8e26f 1038 enum tui_layout_type cur_layout = tui_current_layout ();
c906108c 1039
cb2ce893 1040 diff = (new_height - primary_win_info->height) * (-1);
e5908723
MS
1041 if (cur_layout == SRC_COMMAND
1042 || cur_layout == DISASSEM_COMMAND)
c906108c 1043 {
5b6fe301 1044 struct tui_win_info *src_win_info;
c906108c 1045
daa15dde 1046 primary_win_info->make_invisible_and_set_new_height (new_height);
cb2ce893 1047 if (primary_win_info->type == CMD_WIN)
c906108c 1048 {
b4eb2452 1049 win_info = tui_source_windows ()[0];
6ba8e26f 1050 src_win_info = win_info;
c906108c
SS
1051 }
1052 else
1053 {
6d012f14 1054 win_info = tui_win_list[CMD_WIN];
6ba8e26f 1055 src_win_info = primary_win_info;
c906108c 1056 }
daa15dde
TT
1057 win_info->make_invisible_and_set_new_height
1058 (win_info->height + diff);
cb2ce893 1059 TUI_CMD_WIN->origin.y = locator->origin.y + 1;
5fcee43a
TT
1060 win_info->make_visible_with_new_height ();
1061 primary_win_info->make_visible_with_new_height ();
7908abbf 1062 if ((src_win_info->type == SRC_WIN
53e7cdba
TT
1063 || src_win_info->type == DISASSEM_WIN))
1064 {
1065 tui_source_window_base *src_base
1066 = (tui_source_window_base *) src_win_info;
1067 if (src_base->content.empty ())
e25d2004 1068 src_base->erase_source_content ();
53e7cdba 1069 }
c906108c
SS
1070 }
1071 else
1072 {
6ba8e26f 1073 struct tui_win_info *first_win;
7908abbf
TT
1074 struct tui_source_window_base *second_win;
1075 tui_source_window_base *src1;
c906108c 1076
6ba8e26f 1077 if (cur_layout == SRC_DISASSEM_COMMAND)
c906108c 1078 {
7908abbf
TT
1079 src1 = TUI_SRC_WIN;
1080 first_win = src1;
6ba8e26f 1081 second_win = TUI_DISASM_WIN;
c906108c
SS
1082 }
1083 else
1084 {
7908abbf 1085 src1 = nullptr;
6ba8e26f 1086 first_win = TUI_DATA_WIN;
b4eb2452 1087 second_win = tui_source_windows ()[0];
c906108c 1088 }
6ba8e26f 1089 if (primary_win_info == TUI_CMD_WIN)
ef5eab5a
MS
1090 { /* Split the change in height accross the 1st & 2nd
1091 windows, adjusting them as well. */
1092 /* Subtract the locator. */
1093 int first_split_diff = diff / 2;
6ba8e26f 1094 int second_split_diff = first_split_diff;
c906108c
SS
1095
1096 if (diff % 2)
1097 {
cb2ce893
TT
1098 if (first_win->height >
1099 second_win->height)
c906108c 1100 if (diff < 0)
6ba8e26f 1101 first_split_diff--;
c906108c 1102 else
6ba8e26f 1103 first_split_diff++;
c906108c
SS
1104 else
1105 {
1106 if (diff < 0)
6ba8e26f 1107 second_split_diff--;
c906108c 1108 else
6ba8e26f 1109 second_split_diff++;
c906108c
SS
1110 }
1111 }
1cc6d956
MS
1112 /* Make sure that the minimum hieghts are
1113 honored. */
cb2ce893 1114 while ((first_win->height + first_split_diff) < 3)
c906108c 1115 {
6ba8e26f
AC
1116 first_split_diff++;
1117 second_split_diff--;
c906108c 1118 }
cb2ce893 1119 while ((second_win->height + second_split_diff) < 3)
c906108c 1120 {
6ba8e26f
AC
1121 second_split_diff++;
1122 first_split_diff--;
c906108c 1123 }
daa15dde
TT
1124 first_win->make_invisible_and_set_new_height
1125 (first_win->height + first_split_diff);
cb2ce893 1126 second_win->origin.y = first_win->height - 1;
daa15dde
TT
1127 second_win->make_invisible_and_set_new_height
1128 (second_win->height + second_split_diff);
cb2ce893 1129 TUI_CMD_WIN->origin.y = locator->origin.y + 1;
daa15dde 1130 TUI_CMD_WIN->make_invisible_and_set_new_height (new_height);
c906108c
SS
1131 }
1132 else
1133 {
cb2ce893 1134 if ((TUI_CMD_WIN->height + diff) < 1)
ef5eab5a
MS
1135 { /* If there is no way to increase the command
1136 window take real estate from the 1st or 2nd
1137 window. */
cb2ce893 1138 if ((TUI_CMD_WIN->height + diff) < 1)
c906108c
SS
1139 {
1140 int i;
1c5313c5 1141
cb2ce893 1142 for (i = TUI_CMD_WIN->height + diff;
c906108c 1143 (i < 1); i++)
6ba8e26f 1144 if (primary_win_info == first_win)
cb2ce893 1145 second_win->height--;
c906108c 1146 else
cb2ce893 1147 first_win->height--;
c906108c
SS
1148 }
1149 }
6ba8e26f 1150 if (primary_win_info == first_win)
daa15dde 1151 first_win->make_invisible_and_set_new_height (new_height);
c906108c 1152 else
daa15dde
TT
1153 first_win->make_invisible_and_set_new_height
1154 (first_win->height);
cb2ce893 1155 second_win->origin.y = first_win->height - 1;
6ba8e26f 1156 if (primary_win_info == second_win)
daa15dde 1157 second_win->make_invisible_and_set_new_height (new_height);
c906108c 1158 else
daa15dde
TT
1159 second_win->make_invisible_and_set_new_height
1160 (second_win->height);
cb2ce893
TT
1161 TUI_CMD_WIN->origin.y = locator->origin.y + 1;
1162 if ((TUI_CMD_WIN->height + diff) < 1)
daa15dde 1163 TUI_CMD_WIN->make_invisible_and_set_new_height (1);
c906108c 1164 else
daa15dde
TT
1165 TUI_CMD_WIN->make_invisible_and_set_new_height
1166 (TUI_CMD_WIN->height + diff);
c906108c 1167 }
5fcee43a
TT
1168 TUI_CMD_WIN->make_visible_with_new_height ();
1169 second_win->make_visible_with_new_height ();
1170 first_win->make_visible_with_new_height ();
53e7cdba 1171 if (src1 != nullptr && src1->content.empty ())
e25d2004 1172 src1->erase_source_content ();
53e7cdba 1173 if (second_win->content.empty ())
e25d2004 1174 second_win->erase_source_content ();
c906108c
SS
1175 }
1176 }
1177 }
1178
1179 return status;
6ba8e26f 1180}
c906108c
SS
1181
1182
daa15dde
TT
1183/* See tui-data.h. */
1184
1185void
bfa2a36d 1186tui_win_info::make_invisible_and_set_new_height (int height_)
c906108c 1187{
daa15dde 1188 make_visible (false);
bfa2a36d 1189 height = height_;
c906108c 1190 if (height > 1)
daa15dde 1191 viewport_height = height - 1;
c906108c 1192 else
daa15dde
TT
1193 viewport_height = height;
1194 if (this != TUI_CMD_WIN)
1195 viewport_height--;
c906108c 1196
6658b1bf 1197 /* Now deal with the auxiliary windows associated with win_info. */
daa15dde 1198 set_new_height (height);
bc712bbf 1199}
c906108c
SS
1200
1201
5fcee43a
TT
1202/* See tui-data.h. */
1203
1204void
1205tui_win_info::make_visible_with_new_height ()
c906108c 1206{
5fcee43a 1207 make_visible (true);
b4ef5aeb 1208 check_and_display_highlight_if_needed ();
5fcee43a
TT
1209 do_make_visible_with_new_height ();
1210}
1211
1212/* See tui-data.h. */
c906108c 1213
8903bd8a
TT
1214int
1215tui_win_info::max_height () const
1216{
1217 return tui_term_height () - 2;
1218}
1219
c906108c 1220static int
08ef48c5
MS
1221new_height_ok (struct tui_win_info *primary_win_info,
1222 int new_height)
c906108c 1223{
6ba8e26f 1224 int ok = (new_height < tui_term_height ());
c906108c
SS
1225
1226 if (ok)
1227 {
bc712bbf 1228 int diff;
6d012f14 1229 enum tui_layout_type cur_layout = tui_current_layout ();
c906108c 1230
cb2ce893 1231 diff = (new_height - primary_win_info->height) * (-1);
6d012f14 1232 if (cur_layout == SRC_COMMAND || cur_layout == DISASSEM_COMMAND)
c906108c 1233 {
8903bd8a
TT
1234 ok = (new_height <= primary_win_info->max_height ()
1235 && new_height >= MIN_CMD_WIN_HEIGHT);
c906108c 1236 if (ok)
1cc6d956 1237 { /* Check the total height. */
5b6fe301 1238 struct tui_win_info *win_info;
c906108c 1239
6ba8e26f 1240 if (primary_win_info == TUI_CMD_WIN)
b4eb2452 1241 win_info = tui_source_windows ()[0];
c906108c 1242 else
6d012f14 1243 win_info = TUI_CMD_WIN;
6ba8e26f 1244 ok = ((new_height +
cb2ce893 1245 (win_info->height + diff)) <= tui_term_height ());
c906108c
SS
1246 }
1247 }
1248 else
1249 {
6ba8e26f
AC
1250 int cur_total_height, total_height, min_height = 0;
1251 struct tui_win_info *first_win;
1252 struct tui_win_info *second_win;
c906108c 1253
6d012f14 1254 if (cur_layout == SRC_DISASSEM_COMMAND)
c906108c 1255 {
6ba8e26f
AC
1256 first_win = TUI_SRC_WIN;
1257 second_win = TUI_DISASM_WIN;
c906108c
SS
1258 }
1259 else
1260 {
6ba8e26f 1261 first_win = TUI_DATA_WIN;
b4eb2452 1262 second_win = tui_source_windows ()[0];
c906108c 1263 }
ef5eab5a
MS
1264 /* We could simply add all the heights to obtain the same
1265 result but below is more explicit since we subtract 1 for
1266 the line that the first and second windows share, and add
1267 one for the locator. */
6ba8e26f 1268 total_height = cur_total_height =
cb2ce893
TT
1269 (first_win->height + second_win->height - 1)
1270 + TUI_CMD_WIN->height + 1; /* Locator. */
6ba8e26f 1271 if (primary_win_info == TUI_CMD_WIN)
c906108c 1272 {
1cc6d956 1273 /* Locator included since first & second win share a line. */
cb2ce893
TT
1274 ok = ((first_win->height +
1275 second_win->height + diff) >=
e5908723
MS
1276 (MIN_WIN_HEIGHT * 2)
1277 && new_height >= MIN_CMD_WIN_HEIGHT);
c906108c
SS
1278 if (ok)
1279 {
e5908723 1280 total_height = new_height +
cb2ce893
TT
1281 (first_win->height +
1282 second_win->height + diff);
6ba8e26f 1283 min_height = MIN_CMD_WIN_HEIGHT;
c906108c
SS
1284 }
1285 }
1286 else
1287 {
6ba8e26f 1288 min_height = MIN_WIN_HEIGHT;
ef5eab5a
MS
1289
1290 /* First see if we can increase/decrease the command
1291 window. And make sure that the command window is at
1292 least 1 line. */
cb2ce893 1293 ok = ((TUI_CMD_WIN->height + diff) > 0);
c906108c 1294 if (!ok)
ef5eab5a
MS
1295 { /* Looks like we have to increase/decrease one of
1296 the other windows. */
6ba8e26f 1297 if (primary_win_info == first_win)
cb2ce893 1298 ok = (second_win->height + diff) >= min_height;
c906108c 1299 else
cb2ce893 1300 ok = (first_win->height + diff) >= min_height;
c906108c
SS
1301 }
1302 if (ok)
1303 {
6ba8e26f
AC
1304 if (primary_win_info == first_win)
1305 total_height = new_height +
cb2ce893
TT
1306 second_win->height +
1307 TUI_CMD_WIN->height + diff;
c906108c 1308 else
6ba8e26f 1309 total_height = new_height +
cb2ce893
TT
1310 first_win->height +
1311 TUI_CMD_WIN->height + diff;
c906108c
SS
1312 }
1313 }
ef5eab5a
MS
1314 /* Now make sure that the proposed total height doesn't
1315 exceed the old total height. */
c906108c 1316 if (ok)
e5908723
MS
1317 ok = (new_height >= min_height
1318 && total_height <= cur_total_height);
c906108c
SS
1319 }
1320 }
1321
1322 return ok;
6ba8e26f 1323}
c906108c
SS
1324
1325
c906108c 1326static void
0b39b52e 1327parse_scrolling_args (const char *arg,
08ef48c5 1328 struct tui_win_info **win_to_scroll,
6ba8e26f 1329 int *num_to_scroll)
c906108c 1330{
6ba8e26f
AC
1331 if (num_to_scroll)
1332 *num_to_scroll = 0;
1333 *win_to_scroll = tui_win_with_focus ();
c906108c 1334
ef5eab5a
MS
1335 /* First set up the default window to scroll, in case there is no
1336 window name arg. */
63a33118 1337 if (arg != NULL)
c906108c 1338 {
f71c8822 1339 char *buf_ptr;
c906108c 1340
1cc6d956 1341 /* Process the number of lines to scroll. */
f71c8822
TT
1342 std::string copy = arg;
1343 buf_ptr = &copy[0];
6ba8e26f 1344 if (isdigit (*buf_ptr))
c906108c 1345 {
6ba8e26f 1346 char *num_str;
c906108c 1347
6ba8e26f
AC
1348 num_str = buf_ptr;
1349 buf_ptr = strchr (buf_ptr, ' ');
63a33118 1350 if (buf_ptr != NULL)
c906108c 1351 {
6ba8e26f
AC
1352 *buf_ptr = (char) 0;
1353 if (num_to_scroll)
1354 *num_to_scroll = atoi (num_str);
1355 buf_ptr++;
c906108c 1356 }
6ba8e26f
AC
1357 else if (num_to_scroll)
1358 *num_to_scroll = atoi (num_str);
c906108c
SS
1359 }
1360
1cc6d956 1361 /* Process the window name if one is specified. */
63a33118 1362 if (buf_ptr != NULL)
c906108c 1363 {
a121b7c1 1364 const char *wname;
c906108c 1365
6ba8e26f
AC
1366 if (*buf_ptr == ' ')
1367 while (*(++buf_ptr) == ' ')
c906108c
SS
1368 ;
1369
6ba8e26f 1370 if (*buf_ptr != (char) 0)
c709a7c2 1371 {
c709a7c2 1372 /* Validate the window name. */
a121b7c1
PA
1373 for (char *p = buf_ptr; *p != '\0'; p++)
1374 *p = tolower (*p);
1375
1376 wname = buf_ptr;
c709a7c2 1377 }
a4b99e53
SC
1378 else
1379 wname = "?";
1380
6ba8e26f 1381 *win_to_scroll = tui_partial_win_by_name (wname);
c906108c 1382
ca5af91e
TT
1383 if (*win_to_scroll == NULL)
1384 error (_("Unrecognized window `%s'"), wname);
1385 if (!(*win_to_scroll)->is_visible)
1386 error (_("Window is not visible"));
6ba8e26f 1387 else if (*win_to_scroll == TUI_CMD_WIN)
b4eb2452 1388 *win_to_scroll = tui_source_windows ()[0];
c906108c 1389 }
c906108c 1390 }
6ba8e26f 1391}
7806cea7
TT
1392
1393/* Function to initialize gdb commands, for tui window
1394 manipulation. */
1395
1396void
1397_initialize_tui_win (void)
1398{
1399 static struct cmd_list_element *tui_setlist;
1400 static struct cmd_list_element *tui_showlist;
1401 struct cmd_list_element *cmd;
1402
1403 /* Define the classes of commands.
1404 They will appear in the help list in the reverse of this order. */
1405 add_prefix_cmd ("tui", class_tui, set_tui_cmd,
590042fc 1406 _("TUI configuration variables."),
7806cea7
TT
1407 &tui_setlist, "set tui ",
1408 0 /* allow-unknown */, &setlist);
1409 add_prefix_cmd ("tui", class_tui, show_tui_cmd,
590042fc 1410 _("TUI configuration variables."),
7806cea7
TT
1411 &tui_showlist, "show tui ",
1412 0 /* allow-unknown */, &showlist);
1413
1414 add_com ("refresh", class_tui, tui_refresh_all_command,
89549d7f 1415 _("Refresh the terminal display."));
7806cea7
TT
1416
1417 cmd = add_com ("tabset", class_tui, tui_set_tab_width_command, _("\
1418Set the width (in characters) of tab stops.\n\
89549d7f 1419Usage: tabset N"));
7806cea7
TT
1420 deprecate_cmd (cmd, "set tui tab-width");
1421
1422 cmd = add_com ("winheight", class_tui, tui_set_win_height_command, _("\
1423Set or modify the height of a specified window.\n"
1424WIN_HEIGHT_USAGE
1425"Window names are:\n\
89549d7f
TT
1426 src : the source window\n\
1427 cmd : the command window\n\
1428 asm : the disassembly window\n\
1429 regs : the register display"));
7806cea7
TT
1430 add_com_alias ("wh", "winheight", class_tui, 0);
1431 set_cmd_completer (cmd, winheight_completer);
1432 add_info ("win", tui_all_windows_info,
89549d7f 1433 _("List of all displayed windows."));
7806cea7
TT
1434 cmd = add_com ("focus", class_tui, tui_set_focus_command, _("\
1435Set focus to named window or next/prev window.\n"
1436FOCUS_USAGE
1437"Valid Window names are:\n\
89549d7f
TT
1438 src : the source window\n\
1439 asm : the disassembly window\n\
1440 regs : the register display\n\
1441 cmd : the command window"));
7806cea7
TT
1442 add_com_alias ("fs", "focus", class_tui, 0);
1443 set_cmd_completer (cmd, focus_completer);
1444 add_com ("+", class_tui, tui_scroll_forward_command, _("\
1445Scroll window forward.\n\
89549d7f 1446Usage: + [WIN] [N]"));
7806cea7
TT
1447 add_com ("-", class_tui, tui_scroll_backward_command, _("\
1448Scroll window backward.\n\
89549d7f 1449Usage: - [WIN] [N]"));
7806cea7
TT
1450 add_com ("<", class_tui, tui_scroll_left_command, _("\
1451Scroll window text to the left.\n\
89549d7f 1452Usage: < [WIN] [N]"));
7806cea7
TT
1453 add_com (">", class_tui, tui_scroll_right_command, _("\
1454Scroll window text to the right.\n\
89549d7f 1455Usage: > [WIN] [N]"));
7806cea7
TT
1456
1457 /* Define the tui control variables. */
1458 add_setshow_enum_cmd ("border-kind", no_class, tui_border_kind_enums,
1459 &tui_border_kind, _("\
1460Set the kind of border for TUI windows."), _("\
1461Show the kind of border for TUI windows."), _("\
1462This variable controls the border of TUI windows:\n\
89549d7f
TT
1463 space use a white space\n\
1464 ascii use ascii characters + - | for the border\n\
1465 acs use the Alternate Character Set"),
7806cea7
TT
1466 tui_set_var_cmd,
1467 show_tui_border_kind,
1468 &tui_setlist, &tui_showlist);
1469
1470 add_setshow_enum_cmd ("border-mode", no_class, tui_border_mode_enums,
1471 &tui_border_mode, _("\
1472Set the attribute mode to use for the TUI window borders."), _("\
1473Show the attribute mode to use for the TUI window borders."), _("\
1474This variable controls the attributes to use for the window borders:\n\
89549d7f
TT
1475 normal normal display\n\
1476 standout use highlight mode of terminal\n\
1477 reverse use reverse video mode\n\
1478 half use half bright\n\
1479 half-standout use half bright and standout mode\n\
1480 bold use extra bright or bold\n\
1481 bold-standout use extra bright or bold with standout mode"),
7806cea7
TT
1482 tui_set_var_cmd,
1483 show_tui_border_mode,
1484 &tui_setlist, &tui_showlist);
1485
1486 add_setshow_enum_cmd ("active-border-mode", no_class, tui_border_mode_enums,
1487 &tui_active_border_mode, _("\
1488Set the attribute mode to use for the active TUI window border."), _("\
1489Show the attribute mode to use for the active TUI window border."), _("\
1490This variable controls the attributes to use for the active window border:\n\
89549d7f
TT
1491 normal normal display\n\
1492 standout use highlight mode of terminal\n\
1493 reverse use reverse video mode\n\
1494 half use half bright\n\
1495 half-standout use half bright and standout mode\n\
1496 bold use extra bright or bold\n\
1497 bold-standout use extra bright or bold with standout mode"),
7806cea7
TT
1498 tui_set_var_cmd,
1499 show_tui_active_border_mode,
1500 &tui_setlist, &tui_showlist);
1501
1502 add_setshow_zuinteger_cmd ("tab-width", no_class,
1503 &internal_tab_width, _("\
1504Set the tab width, in characters, for the TUI."), _("\
590042fc 1505Show the tab witdh, in characters, for the TUI."), _("\
7806cea7
TT
1506This variable controls how many spaces are used to display a tab character."),
1507 tui_set_tab_width, tui_show_tab_width,
1508 &tui_setlist, &tui_showlist);
1509}