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