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