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