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