]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/tui/tui-win.c
Make the change of tab size in TUI mode effective immediately
[thirdparty/binutils-gdb.git] / gdb / tui / tui-win.c
CommitLineData
f377b406 1/* TUI window generic functions.
f33c6cbf 2
32d0add0 3 Copyright (C) 1998-2015 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"
c906108c 35
d7b2e967
AC
36#include "tui/tui.h"
37#include "tui/tui-data.h"
38#include "tui/tui-wingeneral.h"
39#include "tui/tui-stack.h"
40#include "tui/tui-regs.h"
41#include "tui/tui-disasm.h"
42#include "tui/tui-source.h"
43#include "tui/tui-winsource.h"
44#include "tui/tui-windata.h"
2c0b251b 45#include "tui/tui-win.h"
c906108c 46
6a83354a 47#include "gdb_curses.h"
96ec9981 48#include <ctype.h>
dbda9972 49#include "readline/readline.h"
96ec9981 50
9612b5ec
UW
51#include <signal.h>
52
c906108c
SS
53/*******************************
54** Static Local Decls
55********************************/
6ba8e26f 56static void make_visible_with_new_height (struct tui_win_info *);
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
AC
61static int new_height_ok (struct tui_win_info *, int);
62static void tui_set_tab_width_command (char *, int);
63static void tui_refresh_all_command (char *, int);
64static void tui_set_win_height_command (char *, int);
65static void tui_xdb_set_win_height_command (char *, int);
66static void tui_all_windows_info (char *, int);
67static void tui_set_focus_command (char *, int);
68static void tui_scroll_forward_command (char *, int);
69static void tui_scroll_backward_command (char *, int);
70static void tui_scroll_left_command (char *, int);
71static void tui_scroll_right_command (char *, int);
08ef48c5
MS
72static void parse_scrolling_args (char *,
73 struct tui_win_info **,
74 int *);
c906108c
SS
75
76
77/***************************************
78** DEFINITIONS
79***************************************/
08ef48c5
MS
80#define WIN_HEIGHT_USAGE "Usage: winheight <win_name> [+ | -] <#lines>\n"
81#define XDBWIN_HEIGHT_USAGE "Usage: w <#lines>\n"
82#define FOCUS_USAGE "Usage: focus {<win> | 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
SC
317static void
318set_tui_cmd (char *args, int from_tty)
319{
320}
321
322static void
323show_tui_cmd (char *args, int from_tty)
324{
325}
af101512 326
10f59415
SC
327static struct cmd_list_element *tuilist;
328
329static void
330tui_command (char *args, int from_tty)
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
08ef48c5
MS
347/* Function to initialize gdb commands, for tui window
348 manipulation. */
2c0b251b
PA
349
350/* Provide a prototype to silence -Wmissing-prototypes. */
351extern initialize_file_ftype _initialize_tui_win;
352
c906108c 353void
6ba8e26f 354_initialize_tui_win (void)
c906108c 355{
c9684879
SC
356 static struct cmd_list_element *tui_setlist;
357 static struct cmd_list_element *tui_showlist;
af101512 358
41783295
SC
359 /* Define the classes of commands.
360 They will appear in the help list in the reverse of this order. */
c9684879 361 add_prefix_cmd ("tui", class_tui, set_tui_cmd,
1bedd215 362 _("TUI configuration variables"),
c9684879 363 &tui_setlist, "set tui ",
1cc6d956 364 0 /* allow-unknown */, &setlist);
c9684879 365 add_prefix_cmd ("tui", class_tui, show_tui_cmd,
1bedd215 366 _("TUI configuration variables"),
c9684879 367 &tui_showlist, "show tui ",
1cc6d956 368 0 /* allow-unknown */, &showlist);
c9684879 369
6ba8e26f 370 add_com ("refresh", class_tui, tui_refresh_all_command,
1bedd215 371 _("Refresh the terminal display.\n"));
41783295
SC
372 if (xdb_commands)
373 add_com_alias ("U", "refresh", class_tui, 0);
1bedd215
AC
374 add_com ("tabset", class_tui, tui_set_tab_width_command, _("\
375Set the width (in characters) of tab stops.\n\
376Usage: tabset <n>\n"));
377 add_com ("winheight", class_tui, tui_set_win_height_command, _("\
378Set the height of a specified window.\n\
c906108c
SS
379Usage: winheight <win_name> [+ | -] <#lines>\n\
380Window names are:\n\
381src : the source window\n\
382cmd : the command window\n\
383asm : the disassembly window\n\
1bedd215 384regs : the register display\n"));
41783295 385 add_com_alias ("wh", "winheight", class_tui, 0);
6ba8e26f 386 add_info ("win", tui_all_windows_info,
1bedd215
AC
387 _("List of all displayed windows.\n"));
388 add_com ("focus", class_tui, tui_set_focus_command, _("\
389Set focus to named window or next/prev window.\n\
c906108c
SS
390Usage: focus {<win> | next | prev}\n\
391Valid Window names are:\n\
392src : the source window\n\
393asm : the disassembly window\n\
394regs : the register display\n\
1bedd215 395cmd : the command window\n"));
41783295 396 add_com_alias ("fs", "focus", class_tui, 0);
1bedd215
AC
397 add_com ("+", class_tui, tui_scroll_forward_command, _("\
398Scroll window forward.\n\
399Usage: + [win] [n]\n"));
400 add_com ("-", class_tui, tui_scroll_backward_command, _("\
401Scroll window backward.\n\
402Usage: - [win] [n]\n"));
403 add_com ("<", class_tui, tui_scroll_left_command, _("\
bf555842 404Scroll window text to the left.\n\
1bedd215
AC
405Usage: < [win] [n]\n"));
406 add_com (">", class_tui, tui_scroll_right_command, _("\
bf555842 407Scroll window text to the right.\n\
1bedd215 408Usage: > [win] [n]\n"));
41783295 409 if (xdb_commands)
1bedd215
AC
410 add_com ("w", class_xdb, tui_xdb_set_win_height_command, _("\
411XDB compatibility command for setting the height of a command window.\n\
412Usage: w <#lines>\n"));
af101512
SC
413
414 /* Define the tui control variables. */
7ab04401
AC
415 add_setshow_enum_cmd ("border-kind", no_class, tui_border_kind_enums,
416 &tui_border_kind, _("\
417Set the kind of border for TUI windows."), _("\
418Show the kind of border for TUI windows."), _("\
419This variable controls the border of TUI windows:\n\
420space use a white space\n\
421ascii use ascii characters + - | for the border\n\
422acs use the Alternate Character Set"),
423 NULL,
920d2a44 424 show_tui_border_kind,
7ab04401
AC
425 &tui_setlist, &tui_showlist);
426
427 add_setshow_enum_cmd ("border-mode", no_class, tui_border_mode_enums,
428 &tui_border_mode, _("\
429Set the attribute mode to use for the TUI window borders."), _("\
430Show the attribute mode to use for the TUI window borders."), _("\
431This variable controls the attributes to use for the window borders:\n\
432normal normal display\n\
433standout use highlight mode of terminal\n\
434reverse use reverse video mode\n\
435half use half bright\n\
436half-standout use half bright and standout mode\n\
437bold use extra bright or bold\n\
438bold-standout use extra bright or bold with standout mode"),
439 NULL,
920d2a44 440 show_tui_border_mode,
7ab04401
AC
441 &tui_setlist, &tui_showlist);
442
443 add_setshow_enum_cmd ("active-border-mode", no_class, tui_border_mode_enums,
444 &tui_active_border_mode, _("\
445Set the attribute mode to use for the active TUI window border."), _("\
446Show the attribute mode to use for the active TUI window border."), _("\
447This variable controls the attributes to use for the active window border:\n\
448normal normal display\n\
449standout use highlight mode of terminal\n\
450reverse use reverse video mode\n\
451half use half bright\n\
452half-standout use half bright and standout mode\n\
453bold use extra bright or bold\n\
454bold-standout use extra bright or bold with standout mode"),
455 NULL,
920d2a44 456 show_tui_active_border_mode,
7ab04401 457 &tui_setlist, &tui_showlist);
41783295 458}
c906108c 459
3e752b04
SC
460/* Update gdb's knowledge of the terminal size. */
461void
d02c80cd 462tui_update_gdb_sizes (void)
3e752b04
SC
463{
464 char cmd[50];
3e752b04
SC
465
466 /* Set to TUI command window dimension or use readline values. */
8c042590 467 xsnprintf (cmd, sizeof (cmd), "set width %d",
fddb59b7 468 tui_active ? TUI_CMD_WIN->generic.width : tui_term_width());
3e752b04 469 execute_command (cmd, 0);
8c042590 470 xsnprintf (cmd, sizeof (cmd), "set height %d",
fddb59b7 471 tui_active ? TUI_CMD_WIN->generic.height : tui_term_height());
3e752b04
SC
472 execute_command (cmd, 0);
473}
474
c906108c 475
1cc6d956 476/* Set the logical focus to win_info. */
c906108c 477void
5b6fe301 478tui_set_win_focus_to (struct tui_win_info *win_info)
c906108c 479{
6d012f14 480 if (win_info != NULL)
c906108c 481 {
5b6fe301 482 struct tui_win_info *win_with_focus = tui_win_with_focus ();
c906108c 483
6ba8e26f
AC
484 if (win_with_focus != NULL
485 && win_with_focus->generic.type != CMD_WIN)
486 tui_unhighlight_win (win_with_focus);
6d012f14
AC
487 tui_set_win_with_focus (win_info);
488 if (win_info->generic.type != CMD_WIN)
489 tui_highlight_win (win_info);
c906108c 490 }
6ba8e26f 491}
c906108c
SS
492
493
c906108c 494void
08ef48c5
MS
495tui_scroll_forward (struct tui_win_info *win_to_scroll,
496 int num_to_scroll)
c906108c 497{
6ba8e26f 498 if (win_to_scroll != TUI_CMD_WIN)
c906108c 499 {
6ba8e26f 500 int _num_to_scroll = num_to_scroll;
c906108c 501
6ba8e26f
AC
502 if (num_to_scroll == 0)
503 _num_to_scroll = win_to_scroll->generic.height - 3;
ef5eab5a
MS
504
505 /* If we are scrolling the source or disassembly window, do a
506 "psuedo" scroll since not all of the source is in memory,
507 only what is in the viewport. If win_to_scroll is the
508 command window do nothing since the term should handle
509 it. */
6ba8e26f
AC
510 if (win_to_scroll == TUI_SRC_WIN)
511 tui_vertical_source_scroll (FORWARD_SCROLL, _num_to_scroll);
512 else if (win_to_scroll == TUI_DISASM_WIN)
513 tui_vertical_disassem_scroll (FORWARD_SCROLL, _num_to_scroll);
514 else if (win_to_scroll == TUI_DATA_WIN)
515 tui_vertical_data_scroll (FORWARD_SCROLL, _num_to_scroll);
c906108c 516 }
a21fcd8f 517}
c906108c 518
c906108c 519void
08ef48c5
MS
520tui_scroll_backward (struct tui_win_info *win_to_scroll,
521 int num_to_scroll)
c906108c 522{
6ba8e26f 523 if (win_to_scroll != TUI_CMD_WIN)
c906108c 524 {
6ba8e26f 525 int _num_to_scroll = num_to_scroll;
c906108c 526
6ba8e26f
AC
527 if (num_to_scroll == 0)
528 _num_to_scroll = win_to_scroll->generic.height - 3;
ef5eab5a
MS
529
530 /* If we are scrolling the source or disassembly window, do a
531 "psuedo" scroll since not all of the source is in memory,
532 only what is in the viewport. If win_to_scroll is the
533 command window do nothing since the term should handle
534 it. */
6ba8e26f
AC
535 if (win_to_scroll == TUI_SRC_WIN)
536 tui_vertical_source_scroll (BACKWARD_SCROLL, _num_to_scroll);
537 else if (win_to_scroll == TUI_DISASM_WIN)
538 tui_vertical_disassem_scroll (BACKWARD_SCROLL, _num_to_scroll);
539 else if (win_to_scroll == TUI_DATA_WIN)
540 tui_vertical_data_scroll (BACKWARD_SCROLL, _num_to_scroll);
c906108c 541 }
a21fcd8f 542}
c906108c
SS
543
544
c906108c 545void
08ef48c5
MS
546tui_scroll_left (struct tui_win_info *win_to_scroll,
547 int num_to_scroll)
c906108c 548{
6ba8e26f 549 if (win_to_scroll != TUI_CMD_WIN)
c906108c 550 {
6ba8e26f 551 int _num_to_scroll = num_to_scroll;
c906108c 552
6ba8e26f
AC
553 if (_num_to_scroll == 0)
554 _num_to_scroll = 1;
ef5eab5a
MS
555
556 /* If we are scrolling the source or disassembly window, do a
557 "psuedo" scroll since not all of the source is in memory,
558 only what is in the viewport. If win_to_scroll is the command
559 window do nothing since the term should handle it. */
e5908723
MS
560 if (win_to_scroll == TUI_SRC_WIN
561 || win_to_scroll == TUI_DISASM_WIN)
9a2b4c1b
MS
562 tui_horizontal_source_scroll (win_to_scroll, LEFT_SCROLL,
563 _num_to_scroll);
c906108c 564 }
a21fcd8f 565}
c906108c
SS
566
567
c906108c 568void
08ef48c5
MS
569tui_scroll_right (struct tui_win_info *win_to_scroll,
570 int num_to_scroll)
c906108c 571{
6ba8e26f 572 if (win_to_scroll != TUI_CMD_WIN)
c906108c 573 {
6ba8e26f 574 int _num_to_scroll = num_to_scroll;
c906108c 575
6ba8e26f
AC
576 if (_num_to_scroll == 0)
577 _num_to_scroll = 1;
ef5eab5a
MS
578
579 /* If we are scrolling the source or disassembly window, do a
580 "psuedo" scroll since not all of the source is in memory,
581 only what is in the viewport. If win_to_scroll is the command
582 window do nothing since the term should handle it. */
e5908723
MS
583 if (win_to_scroll == TUI_SRC_WIN
584 || win_to_scroll == TUI_DISASM_WIN)
9a2b4c1b
MS
585 tui_horizontal_source_scroll (win_to_scroll, RIGHT_SCROLL,
586 _num_to_scroll);
c906108c 587 }
a21fcd8f 588}
c906108c
SS
589
590
1cc6d956 591/* Scroll a window. Arguments are passed through a va_list. */
c906108c 592void
2a8854a7 593tui_scroll (enum tui_scroll_direction direction,
5b6fe301 594 struct tui_win_info *win_to_scroll,
6ba8e26f 595 int num_to_scroll)
c906108c 596{
c906108c
SS
597 switch (direction)
598 {
599 case FORWARD_SCROLL:
6ba8e26f 600 tui_scroll_forward (win_to_scroll, num_to_scroll);
c906108c
SS
601 break;
602 case BACKWARD_SCROLL:
6ba8e26f 603 tui_scroll_backward (win_to_scroll, num_to_scroll);
c906108c
SS
604 break;
605 case LEFT_SCROLL:
6ba8e26f 606 tui_scroll_left (win_to_scroll, num_to_scroll);
c906108c
SS
607 break;
608 case RIGHT_SCROLL:
6ba8e26f 609 tui_scroll_right (win_to_scroll, num_to_scroll);
c906108c
SS
610 break;
611 default:
612 break;
613 }
e8b915dc 614}
c906108c
SS
615
616
c906108c 617void
a21fcd8f 618tui_refresh_all_win (void)
c906108c 619{
22940a24 620 enum tui_win_type type;
c906108c 621
3e266828 622 clearok (curscr, TRUE);
6d012f14 623 tui_refresh_all (tui_win_list);
c906108c
SS
624 for (type = SRC_WIN; type < MAX_MAJOR_WINDOWS; type++)
625 {
e5908723
MS
626 if (tui_win_list[type]
627 && tui_win_list[type]->generic.is_visible)
c906108c
SS
628 {
629 switch (type)
630 {
631 case SRC_WIN:
632 case DISASSEM_WIN:
6d012f14
AC
633 tui_show_source_content (tui_win_list[type]);
634 tui_check_and_display_highlight_if_needed (tui_win_list[type]);
635 tui_erase_exec_info_content (tui_win_list[type]);
636 tui_update_exec_info (tui_win_list[type]);
c906108c
SS
637 break;
638 case DATA_WIN:
edae1ccf 639 tui_refresh_data_win ();
c906108c
SS
640 break;
641 default:
642 break;
643 }
644 }
645 }
47d3492a 646 tui_show_locator_content ();
bc712bbf 647}
c906108c
SS
648
649
b021a221
MS
650/* Resize all the windows based on the terminal size. This function
651 gets called from within the readline sinwinch handler. */
c906108c 652void
6ba8e26f 653tui_resize_all (void)
c906108c 654{
6ba8e26f 655 int height_diff, width_diff;
9255ee31 656 int screenheight, screenwidth;
c906108c 657
9255ee31 658 rl_get_screen_size (&screenheight, &screenwidth);
6ba8e26f
AC
659 width_diff = screenwidth - tui_term_width ();
660 height_diff = screenheight - tui_term_height ();
661 if (height_diff || width_diff)
c906108c 662 {
6ba8e26f 663 enum tui_layout_type cur_layout = tui_current_layout ();
5b6fe301 664 struct tui_win_info *win_with_focus = tui_win_with_focus ();
6ba8e26f
AC
665 struct tui_win_info *first_win;
666 struct tui_win_info *second_win;
5b6fe301 667 struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
6ba8e26f
AC
668 enum tui_win_type win_type;
669 int new_height, split_diff, cmd_split_diff, num_wins_displayed = 2;
c906108c 670
10f59415
SC
671#ifdef HAVE_RESIZE_TERM
672 resize_term (screenheight, screenwidth);
673#endif
1cc6d956 674 /* Turn keypad off while we resize. */
6ba8e26f 675 if (win_with_focus != TUI_CMD_WIN)
6d012f14 676 keypad (TUI_CMD_WIN->generic.handle, FALSE);
3e752b04 677 tui_update_gdb_sizes ();
dd1abb8c
AC
678 tui_set_term_height_to (screenheight);
679 tui_set_term_width_to (screenwidth);
e5908723
MS
680 if (cur_layout == SRC_DISASSEM_COMMAND
681 || cur_layout == SRC_DATA_COMMAND
682 || cur_layout == DISASSEM_DATA_COMMAND)
6ba8e26f
AC
683 num_wins_displayed++;
684 split_diff = height_diff / num_wins_displayed;
685 cmd_split_diff = split_diff;
686 if (height_diff % num_wins_displayed)
c906108c 687 {
6ba8e26f
AC
688 if (height_diff < 0)
689 cmd_split_diff--;
c906108c 690 else
c366c1f0
TT
691 cmd_split_diff++;
692 }
1cc6d956 693 /* Now adjust each window. */
c366c1f0
TT
694 /* erase + clearok are used instead of a straightforward clear as
695 AIX 5.3 does not define clear. */
696 erase ();
697 clearok (curscr, TRUE);
c906108c 698 refresh ();
6ba8e26f 699 switch (cur_layout)
c366c1f0 700 {
c906108c
SS
701 case SRC_COMMAND:
702 case DISASSEM_COMMAND:
6ba8e26f
AC
703 first_win = (struct tui_win_info *) (tui_source_windows ())->list[0];
704 first_win->generic.width += width_diff;
705 locator->width += width_diff;
1cc6d956 706 /* Check for invalid heights. */
6ba8e26f
AC
707 if (height_diff == 0)
708 new_height = first_win->generic.height;
709 else if ((first_win->generic.height + split_diff) >=
c906108c 710 (screenheight - MIN_CMD_WIN_HEIGHT - 1))
6ba8e26f
AC
711 new_height = screenheight - MIN_CMD_WIN_HEIGHT - 1;
712 else if ((first_win->generic.height + split_diff) <= 0)
713 new_height = MIN_WIN_HEIGHT;
c906108c 714 else
6ba8e26f 715 new_height = first_win->generic.height + split_diff;
c906108c 716
0036e657 717 locator->origin.y = new_height + 1;
6ba8e26f 718 make_invisible_and_set_new_height (first_win, new_height);
6d012f14 719 TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1;
6ba8e26f
AC
720 TUI_CMD_WIN->generic.width += width_diff;
721 new_height = screenheight - TUI_CMD_WIN->generic.origin.y;
722 make_invisible_and_set_new_height (TUI_CMD_WIN, new_height);
723 make_visible_with_new_height (first_win);
724 make_visible_with_new_height (TUI_CMD_WIN);
725 if (first_win->generic.content_size <= 0)
726 tui_erase_source_content (first_win, EMPTY_SOURCE_PROMPT);
c906108c
SS
727 break;
728 default:
6ba8e26f 729 if (cur_layout == SRC_DISASSEM_COMMAND)
c906108c 730 {
6ba8e26f
AC
731 first_win = TUI_SRC_WIN;
732 first_win->generic.width += width_diff;
733 second_win = TUI_DISASM_WIN;
734 second_win->generic.width += width_diff;
c906108c
SS
735 }
736 else
737 {
6ba8e26f
AC
738 first_win = TUI_DATA_WIN;
739 first_win->generic.width += width_diff;
9a2b4c1b
MS
740 second_win = (struct tui_win_info *)
741 (tui_source_windows ())->list[0];
6ba8e26f 742 second_win->generic.width += width_diff;
c906108c 743 }
1cc6d956
MS
744 /* Change the first window's height/width. */
745 /* Check for invalid heights. */
6ba8e26f
AC
746 if (height_diff == 0)
747 new_height = first_win->generic.height;
748 else if ((first_win->generic.height +
749 second_win->generic.height + (split_diff * 2)) >=
c906108c 750 (screenheight - MIN_CMD_WIN_HEIGHT - 1))
6ba8e26f
AC
751 new_height = (screenheight - MIN_CMD_WIN_HEIGHT - 1) / 2;
752 else if ((first_win->generic.height + split_diff) <= 0)
753 new_height = MIN_WIN_HEIGHT;
c906108c 754 else
6ba8e26f
AC
755 new_height = first_win->generic.height + split_diff;
756 make_invisible_and_set_new_height (first_win, new_height);
c906108c 757
6ba8e26f 758 locator->width += width_diff;
c906108c 759
1cc6d956
MS
760 /* Change the second window's height/width. */
761 /* Check for invalid heights. */
6ba8e26f
AC
762 if (height_diff == 0)
763 new_height = second_win->generic.height;
764 else if ((first_win->generic.height +
765 second_win->generic.height + (split_diff * 2)) >=
c906108c
SS
766 (screenheight - MIN_CMD_WIN_HEIGHT - 1))
767 {
6ba8e26f
AC
768 new_height = screenheight - MIN_CMD_WIN_HEIGHT - 1;
769 if (new_height % 2)
770 new_height = (new_height / 2) + 1;
c906108c 771 else
6ba8e26f 772 new_height /= 2;
c906108c 773 }
6ba8e26f
AC
774 else if ((second_win->generic.height + split_diff) <= 0)
775 new_height = MIN_WIN_HEIGHT;
c906108c 776 else
6ba8e26f
AC
777 new_height = second_win->generic.height + split_diff;
778 second_win->generic.origin.y = first_win->generic.height - 1;
779 make_invisible_and_set_new_height (second_win, new_height);
c906108c 780
1cc6d956 781 /* Change the command window's height/width. */
6d012f14 782 TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1;
9a2b4c1b
MS
783 make_invisible_and_set_new_height (TUI_CMD_WIN,
784 TUI_CMD_WIN->generic.height
785 + cmd_split_diff);
6ba8e26f
AC
786 make_visible_with_new_height (first_win);
787 make_visible_with_new_height (second_win);
788 make_visible_with_new_height (TUI_CMD_WIN);
789 if (first_win->generic.content_size <= 0)
790 tui_erase_source_content (first_win, EMPTY_SOURCE_PROMPT);
791 if (second_win->generic.content_size <= 0)
792 tui_erase_source_content (second_win, EMPTY_SOURCE_PROMPT);
c906108c
SS
793 break;
794 }
ef5eab5a
MS
795 /* Now remove all invisible windows, and their content so that
796 they get created again when called for with the new size. */
6ba8e26f 797 for (win_type = SRC_WIN; (win_type < MAX_MAJOR_WINDOWS); win_type++)
c906108c 798 {
e5908723
MS
799 if (win_type != CMD_WIN
800 && (tui_win_list[win_type] != NULL)
6ba8e26f 801 && !tui_win_list[win_type]->generic.is_visible)
c906108c 802 {
6ba8e26f
AC
803 tui_free_window (tui_win_list[win_type]);
804 tui_win_list[win_type] = (struct tui_win_info *) NULL;
c906108c
SS
805 }
806 }
1cc6d956
MS
807 /* Turn keypad back on, unless focus is in the command
808 window. */
6ba8e26f 809 if (win_with_focus != TUI_CMD_WIN)
6d012f14 810 keypad (TUI_CMD_WIN->generic.handle, TRUE);
c906108c 811 }
6ba8e26f 812}
c906108c 813
2c0b251b 814#ifdef SIGWINCH
6ba8e26f
AC
815/* SIGWINCH signal handler for the tui. This signal handler is always
816 called, even when the readline package clears signals because it is
817 set as the old_sigwinch() (TUI only). */
2c0b251b 818static void
6ba8e26f 819tui_sigwinch_handler (int signal)
c906108c 820{
ef5eab5a
MS
821 /* Say that a resize was done so that the readline can do it later
822 when appropriate. */
dd1abb8c 823 tui_set_win_resized_to (TRUE);
6ba8e26f 824}
2c0b251b 825#endif
c906108c 826
9612b5ec
UW
827/* Initializes SIGWINCH signal handler for the tui. */
828void
829tui_initialize_win (void)
830{
831#ifdef SIGWINCH
832#ifdef HAVE_SIGACTION
833 struct sigaction old_winch;
1c5313c5 834
9612b5ec
UW
835 memset (&old_winch, 0, sizeof (old_winch));
836 old_winch.sa_handler = &tui_sigwinch_handler;
a344fc09
PP
837#ifdef SA_RESTART
838 old_winch.sa_flags = SA_RESTART;
839#endif
9612b5ec
UW
840 sigaction (SIGWINCH, &old_winch, NULL);
841#else
842 signal (SIGWINCH, &tui_sigwinch_handler);
843#endif
844#endif
845}
c906108c
SS
846
847
848/*************************
849** STATIC LOCAL FUNCTIONS
850**************************/
851
852
c906108c 853static void
6ba8e26f 854tui_scroll_forward_command (char *arg, int from_tty)
c906108c 855{
6ba8e26f 856 int num_to_scroll = 1;
5b6fe301 857 struct tui_win_info *win_to_scroll;
c906108c 858
1854bb21
SC
859 /* Make sure the curses mode is enabled. */
860 tui_enable ();
c906108c 861 if (arg == (char *) NULL)
6ba8e26f 862 parse_scrolling_args (arg, &win_to_scroll, (int *) NULL);
c906108c 863 else
6ba8e26f
AC
864 parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll);
865 tui_scroll (FORWARD_SCROLL, win_to_scroll, num_to_scroll);
e8b915dc 866}
c906108c
SS
867
868
c906108c 869static void
6ba8e26f 870tui_scroll_backward_command (char *arg, int from_tty)
c906108c 871{
6ba8e26f 872 int num_to_scroll = 1;
5b6fe301 873 struct tui_win_info *win_to_scroll;
c906108c 874
1854bb21
SC
875 /* Make sure the curses mode is enabled. */
876 tui_enable ();
c906108c 877 if (arg == (char *) NULL)
6ba8e26f 878 parse_scrolling_args (arg, &win_to_scroll, (int *) NULL);
c906108c 879 else
6ba8e26f
AC
880 parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll);
881 tui_scroll (BACKWARD_SCROLL, win_to_scroll, num_to_scroll);
e8b915dc 882}
c906108c
SS
883
884
c906108c 885static void
6ba8e26f 886tui_scroll_left_command (char *arg, int from_tty)
c906108c 887{
6ba8e26f 888 int num_to_scroll;
5b6fe301 889 struct tui_win_info *win_to_scroll;
c906108c 890
1854bb21
SC
891 /* Make sure the curses mode is enabled. */
892 tui_enable ();
6ba8e26f
AC
893 parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll);
894 tui_scroll (LEFT_SCROLL, win_to_scroll, num_to_scroll);
e8b915dc 895}
c906108c
SS
896
897
c906108c 898static void
6ba8e26f 899tui_scroll_right_command (char *arg, int from_tty)
c906108c 900{
6ba8e26f 901 int num_to_scroll;
5b6fe301 902 struct tui_win_info *win_to_scroll;
c906108c 903
1854bb21
SC
904 /* Make sure the curses mode is enabled. */
905 tui_enable ();
6ba8e26f
AC
906 parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll);
907 tui_scroll (RIGHT_SCROLL, win_to_scroll, num_to_scroll);
e8b915dc 908}
c906108c
SS
909
910
6ba8e26f 911/* Set focus to the window named by 'arg'. */
c906108c 912static void
6ba8e26f 913tui_set_focus (char *arg, int from_tty)
c906108c
SS
914{
915 if (arg != (char *) NULL)
916 {
6ba8e26f 917 char *buf_ptr = (char *) xstrdup (arg);
c906108c 918 int i;
5b6fe301 919 struct tui_win_info *win_info = (struct tui_win_info *) NULL;
c906108c 920
6ba8e26f
AC
921 for (i = 0; (i < strlen (buf_ptr)); i++)
922 buf_ptr[i] = toupper (arg[i]);
c906108c 923
6ba8e26f 924 if (subset_compare (buf_ptr, "NEXT"))
6d012f14 925 win_info = tui_next_win (tui_win_with_focus ());
6ba8e26f 926 else if (subset_compare (buf_ptr, "PREV"))
6d012f14 927 win_info = tui_prev_win (tui_win_with_focus ());
c906108c 928 else
6ba8e26f 929 win_info = tui_partial_win_by_name (buf_ptr);
c906108c 930
e5908723
MS
931 if (win_info == (struct tui_win_info *) NULL
932 || !win_info->generic.is_visible)
8a3fe4f8
AC
933 warning (_("Invalid window specified. \n\
934The window name specified must be valid and visible.\n"));
c906108c
SS
935 else
936 {
6d012f14
AC
937 tui_set_win_focus_to (win_info);
938 keypad (TUI_CMD_WIN->generic.handle, (win_info != TUI_CMD_WIN));
c906108c
SS
939 }
940
6d012f14 941 if (TUI_DATA_WIN && TUI_DATA_WIN->generic.is_visible)
edae1ccf 942 tui_refresh_data_win ();
6ba8e26f 943 xfree (buf_ptr);
a3f17187 944 printf_filtered (_("Focus set to %s window.\n"),
9a2b4c1b
MS
945 tui_win_name ((struct tui_gen_win_info *)
946 tui_win_with_focus ()));
c906108c
SS
947 }
948 else
8a3fe4f8 949 warning (_("Incorrect Number of Arguments.\n%s"), FOCUS_USAGE);
6ba8e26f 950}
c906108c 951
c906108c 952static void
6ba8e26f 953tui_set_focus_command (char *arg, int from_tty)
c906108c 954{
1854bb21
SC
955 /* Make sure the curses mode is enabled. */
956 tui_enable ();
6ba8e26f 957 tui_set_focus (arg, from_tty);
e8b915dc 958}
c906108c
SS
959
960
c906108c 961static void
6ba8e26f 962tui_all_windows_info (char *arg, int from_tty)
c906108c 963{
22940a24 964 enum tui_win_type type;
5b6fe301 965 struct tui_win_info *win_with_focus = tui_win_with_focus ();
c906108c
SS
966
967 for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++)
e5908723
MS
968 if (tui_win_list[type]
969 && tui_win_list[type]->generic.is_visible)
c906108c 970 {
6ba8e26f 971 if (win_with_focus == tui_win_list[type])
c906108c 972 printf_filtered (" %s\t(%d lines) <has focus>\n",
6d012f14
AC
973 tui_win_name (&tui_win_list[type]->generic),
974 tui_win_list[type]->generic.height);
c906108c
SS
975 else
976 printf_filtered (" %s\t(%d lines)\n",
6d012f14
AC
977 tui_win_name (&tui_win_list[type]->generic),
978 tui_win_list[type]->generic.height);
c906108c 979 }
6ba8e26f 980}
c906108c
SS
981
982
c906108c 983static void
6ba8e26f 984tui_refresh_all_command (char *arg, int from_tty)
c906108c 985{
1854bb21
SC
986 /* Make sure the curses mode is enabled. */
987 tui_enable ();
988
a21fcd8f 989 tui_refresh_all_win ();
c906108c
SS
990}
991
992
1cc6d956 993/* Set the height of the specified window. */
c906108c 994static void
6ba8e26f 995tui_set_tab_width_command (char *arg, int from_tty)
c906108c 996{
1854bb21
SC
997 /* Make sure the curses mode is enabled. */
998 tui_enable ();
c906108c
SS
999 if (arg != (char *) NULL)
1000 {
1001 int ts;
1002
1003 ts = atoi (arg);
1004 if (ts > 0)
cb86fcc1
EZ
1005 {
1006 tui_set_default_tab_len (ts);
1007 /* We don't really change the height of any windows, but
1008 calling these 2 functions causes a complete regeneration
1009 and redisplay of the window's contents, which will take
1010 the new tab width into account. */
1011 if (tui_win_list[SRC_WIN]
1012 && tui_win_list[SRC_WIN]->generic.is_visible)
1013 {
1014 make_invisible_and_set_new_height (TUI_SRC_WIN,
1015 TUI_SRC_WIN->generic.height);
1016 make_visible_with_new_height (TUI_SRC_WIN);
1017 }
1018 if (tui_win_list[DISASSEM_WIN]
1019 && tui_win_list[DISASSEM_WIN]->generic.is_visible)
1020 {
1021 make_invisible_and_set_new_height (TUI_DISASM_WIN,
1022 TUI_DISASM_WIN->generic.height);
1023 make_visible_with_new_height (TUI_DISASM_WIN);
1024 }
1025 }
c906108c 1026 else
8a3fe4f8 1027 warning (_("Tab widths greater than 0 must be specified."));
c906108c 1028 }
6ba8e26f 1029}
c906108c
SS
1030
1031
1cc6d956 1032/* Set the height of the specified window. */
c906108c 1033static void
6ba8e26f 1034tui_set_win_height (char *arg, int from_tty)
c906108c 1035{
1854bb21
SC
1036 /* Make sure the curses mode is enabled. */
1037 tui_enable ();
c906108c
SS
1038 if (arg != (char *) NULL)
1039 {
1854bb21 1040 char *buf = xstrdup (arg);
6ba8e26f 1041 char *buf_ptr = buf;
c906108c 1042 char *wname = (char *) NULL;
6ba8e26f 1043 int new_height, i;
5b6fe301 1044 struct tui_win_info *win_info;
c906108c 1045
6ba8e26f
AC
1046 wname = buf_ptr;
1047 buf_ptr = strchr (buf_ptr, ' ');
1048 if (buf_ptr != (char *) NULL)
c906108c 1049 {
6ba8e26f 1050 *buf_ptr = (char) 0;
c906108c 1051
ef5eab5a 1052 /* Validate the window name. */
c906108c
SS
1053 for (i = 0; i < strlen (wname); i++)
1054 wname[i] = toupper (wname[i]);
6d012f14 1055 win_info = tui_partial_win_by_name (wname);
c906108c 1056
e5908723
MS
1057 if (win_info == (struct tui_win_info *) NULL
1058 || !win_info->generic.is_visible)
8a3fe4f8
AC
1059 warning (_("Invalid window specified. \n\
1060The window name specified must be valid and visible.\n"));
c906108c
SS
1061 else
1062 {
1cc6d956 1063 /* Process the size. */
6ba8e26f 1064 while (*(++buf_ptr) == ' ')
c906108c
SS
1065 ;
1066
6ba8e26f 1067 if (*buf_ptr != (char) 0)
c906108c
SS
1068 {
1069 int negate = FALSE;
6ba8e26f
AC
1070 int fixed_size = TRUE;
1071 int input_no;;
c906108c 1072
6ba8e26f 1073 if (*buf_ptr == '+' || *buf_ptr == '-')
c906108c 1074 {
6ba8e26f 1075 if (*buf_ptr == '-')
c906108c 1076 negate = TRUE;
6ba8e26f
AC
1077 fixed_size = FALSE;
1078 buf_ptr++;
c906108c 1079 }
6ba8e26f
AC
1080 input_no = atoi (buf_ptr);
1081 if (input_no > 0)
c906108c
SS
1082 {
1083 if (negate)
6ba8e26f
AC
1084 input_no *= (-1);
1085 if (fixed_size)
1086 new_height = input_no;
c906108c 1087 else
6ba8e26f 1088 new_height = win_info->generic.height + input_no;
ef5eab5a
MS
1089
1090 /* Now change the window's height, and adjust
1091 all other windows around it. */
6ba8e26f
AC
1092 if (tui_adjust_win_heights (win_info,
1093 new_height) == TUI_FAILURE)
8a3fe4f8 1094 warning (_("Invalid window height specified.\n%s"),
c906108c
SS
1095 WIN_HEIGHT_USAGE);
1096 else
3e752b04 1097 tui_update_gdb_sizes ();
c906108c
SS
1098 }
1099 else
8a3fe4f8 1100 warning (_("Invalid window height specified.\n%s"),
c906108c
SS
1101 WIN_HEIGHT_USAGE);
1102 }
1103 }
1104 }
1105 else
1106 printf_filtered (WIN_HEIGHT_USAGE);
1107
1108 if (buf != (char *) NULL)
22940a24 1109 xfree (buf);
c906108c
SS
1110 }
1111 else
1112 printf_filtered (WIN_HEIGHT_USAGE);
6ba8e26f 1113}
c906108c 1114
1cc6d956 1115/* Set the height of the specified window, with va_list. */
c906108c 1116static void
6ba8e26f 1117tui_set_win_height_command (char *arg, int from_tty)
c906108c 1118{
1854bb21
SC
1119 /* Make sure the curses mode is enabled. */
1120 tui_enable ();
6ba8e26f 1121 tui_set_win_height (arg, from_tty);
e8b915dc 1122}
c906108c
SS
1123
1124
6ba8e26f 1125/* XDB Compatibility command for setting the window height. This will
1cc6d956
MS
1126 increase or decrease the command window by the specified
1127 amount. */
c906108c 1128static void
6ba8e26f 1129tui_xdb_set_win_height (char *arg, int from_tty)
c906108c 1130{
1854bb21
SC
1131 /* Make sure the curses mode is enabled. */
1132 tui_enable ();
c906108c
SS
1133 if (arg != (char *) NULL)
1134 {
6ba8e26f 1135 int input_no = atoi (arg);
c906108c 1136
6ba8e26f 1137 if (input_no > 0)
1cc6d956 1138 { /* Add 1 for the locator. */
6ba8e26f 1139 int new_height = tui_term_height () - (input_no + 1);
c906108c 1140
e5908723
MS
1141 if (!new_height_ok (tui_win_list[CMD_WIN], new_height)
1142 || tui_adjust_win_heights (tui_win_list[CMD_WIN],
1143 new_height) == TUI_FAILURE)
8a3fe4f8 1144 warning (_("Invalid window height specified.\n%s"),
c906108c
SS
1145 XDBWIN_HEIGHT_USAGE);
1146 }
1147 else
8a3fe4f8 1148 warning (_("Invalid window height specified.\n%s"),
c906108c
SS
1149 XDBWIN_HEIGHT_USAGE);
1150 }
1151 else
8a3fe4f8 1152 warning (_("Invalid window height specified.\n%s"), XDBWIN_HEIGHT_USAGE);
6ba8e26f 1153}
c906108c 1154
6ba8e26f 1155/* Set the height of the specified window, with va_list. */
c906108c 1156static void
6ba8e26f 1157tui_xdb_set_win_height_command (char *arg, int from_tty)
c906108c 1158{
6ba8e26f 1159 tui_xdb_set_win_height (arg, from_tty);
e8b915dc 1160}
c906108c
SS
1161
1162
6ba8e26f 1163/* Function to adjust all window heights around the primary. */
22940a24 1164static enum tui_status
08ef48c5
MS
1165tui_adjust_win_heights (struct tui_win_info *primary_win_info,
1166 int new_height)
c906108c 1167{
22940a24 1168 enum tui_status status = TUI_FAILURE;
c906108c 1169
6ba8e26f 1170 if (new_height_ok (primary_win_info, new_height))
c906108c
SS
1171 {
1172 status = TUI_SUCCESS;
6ba8e26f 1173 if (new_height != primary_win_info->generic.height)
c906108c 1174 {
bc712bbf 1175 int diff;
5b6fe301
MS
1176 struct tui_win_info *win_info;
1177 struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
6ba8e26f 1178 enum tui_layout_type cur_layout = tui_current_layout ();
c906108c 1179
6ba8e26f 1180 diff = (new_height - primary_win_info->generic.height) * (-1);
e5908723
MS
1181 if (cur_layout == SRC_COMMAND
1182 || cur_layout == DISASSEM_COMMAND)
c906108c 1183 {
5b6fe301 1184 struct tui_win_info *src_win_info;
c906108c 1185
6ba8e26f
AC
1186 make_invisible_and_set_new_height (primary_win_info, new_height);
1187 if (primary_win_info->generic.type == CMD_WIN)
c906108c 1188 {
96c1eda2 1189 win_info = (tui_source_windows ())->list[0];
6ba8e26f 1190 src_win_info = win_info;
c906108c
SS
1191 }
1192 else
1193 {
6d012f14 1194 win_info = tui_win_list[CMD_WIN];
6ba8e26f 1195 src_win_info = primary_win_info;
c906108c 1196 }
6ba8e26f 1197 make_invisible_and_set_new_height (win_info,
6d012f14
AC
1198 win_info->generic.height + diff);
1199 TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1;
6ba8e26f
AC
1200 make_visible_with_new_height (win_info);
1201 make_visible_with_new_height (primary_win_info);
1202 if (src_win_info->generic.content_size <= 0)
1203 tui_erase_source_content (src_win_info, EMPTY_SOURCE_PROMPT);
c906108c
SS
1204 }
1205 else
1206 {
6ba8e26f
AC
1207 struct tui_win_info *first_win;
1208 struct tui_win_info *second_win;
c906108c 1209
6ba8e26f 1210 if (cur_layout == SRC_DISASSEM_COMMAND)
c906108c 1211 {
6ba8e26f
AC
1212 first_win = TUI_SRC_WIN;
1213 second_win = TUI_DISASM_WIN;
c906108c
SS
1214 }
1215 else
1216 {
6ba8e26f 1217 first_win = TUI_DATA_WIN;
96c1eda2 1218 second_win = (tui_source_windows ())->list[0];
c906108c 1219 }
6ba8e26f 1220 if (primary_win_info == TUI_CMD_WIN)
ef5eab5a
MS
1221 { /* Split the change in height accross the 1st & 2nd
1222 windows, adjusting them as well. */
1223 /* Subtract the locator. */
1224 int first_split_diff = diff / 2;
6ba8e26f 1225 int second_split_diff = first_split_diff;
c906108c
SS
1226
1227 if (diff % 2)
1228 {
6ba8e26f
AC
1229 if (first_win->generic.height >
1230 second_win->generic.height)
c906108c 1231 if (diff < 0)
6ba8e26f 1232 first_split_diff--;
c906108c 1233 else
6ba8e26f 1234 first_split_diff++;
c906108c
SS
1235 else
1236 {
1237 if (diff < 0)
6ba8e26f 1238 second_split_diff--;
c906108c 1239 else
6ba8e26f 1240 second_split_diff++;
c906108c
SS
1241 }
1242 }
1cc6d956
MS
1243 /* Make sure that the minimum hieghts are
1244 honored. */
6ba8e26f 1245 while ((first_win->generic.height + first_split_diff) < 3)
c906108c 1246 {
6ba8e26f
AC
1247 first_split_diff++;
1248 second_split_diff--;
c906108c 1249 }
6ba8e26f 1250 while ((second_win->generic.height + second_split_diff) < 3)
c906108c 1251 {
6ba8e26f
AC
1252 second_split_diff++;
1253 first_split_diff--;
c906108c 1254 }
6ba8e26f
AC
1255 make_invisible_and_set_new_height (
1256 first_win,
1257 first_win->generic.height + first_split_diff);
1258 second_win->generic.origin.y = first_win->generic.height - 1;
9a2b4c1b
MS
1259 make_invisible_and_set_new_height (second_win,
1260 second_win->generic.height
1261 + second_split_diff);
6d012f14 1262 TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1;
6ba8e26f 1263 make_invisible_and_set_new_height (TUI_CMD_WIN, new_height);
c906108c
SS
1264 }
1265 else
1266 {
6d012f14 1267 if ((TUI_CMD_WIN->generic.height + diff) < 1)
ef5eab5a
MS
1268 { /* If there is no way to increase the command
1269 window take real estate from the 1st or 2nd
1270 window. */
6d012f14 1271 if ((TUI_CMD_WIN->generic.height + diff) < 1)
c906108c
SS
1272 {
1273 int i;
1c5313c5 1274
6d012f14 1275 for (i = TUI_CMD_WIN->generic.height + diff;
c906108c 1276 (i < 1); i++)
6ba8e26f
AC
1277 if (primary_win_info == first_win)
1278 second_win->generic.height--;
c906108c 1279 else
6ba8e26f 1280 first_win->generic.height--;
c906108c
SS
1281 }
1282 }
6ba8e26f
AC
1283 if (primary_win_info == first_win)
1284 make_invisible_and_set_new_height (first_win, new_height);
c906108c 1285 else
6ba8e26f
AC
1286 make_invisible_and_set_new_height (
1287 first_win,
1288 first_win->generic.height);
1289 second_win->generic.origin.y = first_win->generic.height - 1;
1290 if (primary_win_info == second_win)
1291 make_invisible_and_set_new_height (second_win, new_height);
c906108c 1292 else
6ba8e26f
AC
1293 make_invisible_and_set_new_height (
1294 second_win, second_win->generic.height);
6d012f14
AC
1295 TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1;
1296 if ((TUI_CMD_WIN->generic.height + diff) < 1)
6ba8e26f 1297 make_invisible_and_set_new_height (TUI_CMD_WIN, 1);
c906108c 1298 else
9a2b4c1b
MS
1299 make_invisible_and_set_new_height (TUI_CMD_WIN,
1300 TUI_CMD_WIN->generic.height + diff);
c906108c 1301 }
6ba8e26f
AC
1302 make_visible_with_new_height (TUI_CMD_WIN);
1303 make_visible_with_new_height (second_win);
1304 make_visible_with_new_height (first_win);
1305 if (first_win->generic.content_size <= 0)
1306 tui_erase_source_content (first_win, EMPTY_SOURCE_PROMPT);
1307 if (second_win->generic.content_size <= 0)
1308 tui_erase_source_content (second_win, EMPTY_SOURCE_PROMPT);
c906108c
SS
1309 }
1310 }
1311 }
1312
1313 return status;
6ba8e26f 1314}
c906108c
SS
1315
1316
6ba8e26f 1317/* Function make the target window (and auxillary windows associated
1cc6d956
MS
1318 with the targer) invisible, and set the new height and
1319 location. */
c906108c 1320static void
08ef48c5
MS
1321make_invisible_and_set_new_height (struct tui_win_info *win_info,
1322 int height)
c906108c
SS
1323{
1324 int i;
5b6fe301 1325 struct tui_gen_win_info *gen_win_info;
c906108c 1326
6d012f14
AC
1327 tui_make_invisible (&win_info->generic);
1328 win_info->generic.height = height;
c906108c 1329 if (height > 1)
6d012f14 1330 win_info->generic.viewport_height = height - 1;
c906108c 1331 else
6d012f14
AC
1332 win_info->generic.viewport_height = height;
1333 if (win_info != TUI_CMD_WIN)
1334 win_info->generic.viewport_height--;
c906108c 1335
1cc6d956 1336 /* Now deal with the auxillary windows associated with win_info. */
6d012f14 1337 switch (win_info->generic.type)
c906108c
SS
1338 {
1339 case SRC_WIN:
1340 case DISASSEM_WIN:
6ba8e26f
AC
1341 gen_win_info = win_info->detail.source_info.execution_info;
1342 tui_make_invisible (gen_win_info);
1343 gen_win_info->height = height;
1344 gen_win_info->origin.y = win_info->generic.origin.y;
c906108c 1345 if (height > 1)
6ba8e26f 1346 gen_win_info->viewport_height = height - 1;
c906108c 1347 else
6ba8e26f 1348 gen_win_info->viewport_height = height;
6d012f14 1349 if (win_info != TUI_CMD_WIN)
6ba8e26f 1350 gen_win_info->viewport_height--;
c906108c 1351
6d012f14 1352 if (tui_win_has_locator (win_info))
c906108c 1353 {
6ba8e26f
AC
1354 gen_win_info = tui_locator_win_info_ptr ();
1355 tui_make_invisible (gen_win_info);
1356 gen_win_info->origin.y = win_info->generic.origin.y + height;
c906108c
SS
1357 }
1358 break;
1359 case DATA_WIN:
1cc6d956 1360 /* Delete all data item windows. */
6d012f14 1361 for (i = 0; i < win_info->generic.content_size; i++)
c906108c 1362 {
9a2b4c1b
MS
1363 gen_win_info = (struct tui_gen_win_info *)
1364 &((struct tui_win_element *)
1365 win_info->generic.content[i])->which_element.data_window;
6ba8e26f
AC
1366 tui_delete_win (gen_win_info->handle);
1367 gen_win_info->handle = (WINDOW *) NULL;
c906108c
SS
1368 }
1369 break;
1370 default:
1371 break;
1372 }
bc712bbf 1373}
c906108c
SS
1374
1375
6ba8e26f
AC
1376/* Function to make the windows with new heights visible. This means
1377 re-creating the windows' content since the window had to be
1378 destroyed to be made invisible. */
c906108c 1379static void
5b6fe301 1380make_visible_with_new_height (struct tui_win_info *win_info)
c906108c 1381{
c906108c
SS
1382 struct symtab *s;
1383
6d012f14
AC
1384 tui_make_visible (&win_info->generic);
1385 tui_check_and_display_highlight_if_needed (win_info);
1386 switch (win_info->generic.type)
c906108c
SS
1387 {
1388 case SRC_WIN:
1389 case DISASSEM_WIN:
6d012f14
AC
1390 tui_free_win_content (win_info->detail.source_info.execution_info);
1391 tui_make_visible (win_info->detail.source_info.execution_info);
1392 if (win_info->generic.content != NULL)
c906108c 1393 {
13274fc3 1394 struct gdbarch *gdbarch = win_info->detail.source_info.gdbarch;
362c05fe 1395 struct tui_line_or_address line_or_addr;
52575520
EZ
1396 struct symtab_and_line cursal
1397 = get_current_source_symtab_and_line ();
c906108c 1398
362c05fe 1399 line_or_addr = win_info->detail.source_info.start_line_or_addr;
6d012f14 1400 tui_free_win_content (&win_info->generic);
13274fc3
UW
1401 tui_update_source_window (win_info, gdbarch,
1402 cursal.symtab, line_or_addr, TRUE);
c906108c 1403 }
206415a3 1404 else if (deprecated_safe_get_selected_frame () != NULL)
c906108c 1405 {
362c05fe 1406 struct tui_line_or_address line;
9a2b4c1b
MS
1407 struct symtab_and_line cursal
1408 = get_current_source_symtab_and_line ();
206415a3 1409 struct frame_info *frame = deprecated_safe_get_selected_frame ();
13274fc3 1410 struct gdbarch *gdbarch = get_frame_arch (frame);
52575520 1411
34248c3a 1412 s = find_pc_line_symtab (get_frame_pc (frame));
6d012f14 1413 if (win_info->generic.type == SRC_WIN)
362c05fe
AS
1414 {
1415 line.loa = LOA_LINE;
1416 line.u.line_no = cursal.line;
1417 }
c906108c 1418 else
84b1e7c7 1419 {
362c05fe
AS
1420 line.loa = LOA_ADDRESS;
1421 find_line_pc (s, cursal.line, &line.u.addr);
84b1e7c7 1422 }
13274fc3 1423 tui_update_source_window (win_info, gdbarch, s, line, TRUE);
c906108c 1424 }
6d012f14 1425 if (tui_win_has_locator (win_info))
c906108c 1426 {
dd1abb8c 1427 tui_make_visible (tui_locator_win_info_ptr ());
47d3492a 1428 tui_show_locator_content ();
c906108c
SS
1429 }
1430 break;
1431 case DATA_WIN:
edae1ccf 1432 tui_display_all_data ();
c906108c
SS
1433 break;
1434 case CMD_WIN:
6d012f14
AC
1435 win_info->detail.command_info.cur_line = 0;
1436 win_info->detail.command_info.curch = 0;
110ed339 1437#ifdef HAVE_WRESIZE
d27b3be4
PA
1438 wresize (TUI_CMD_WIN->generic.handle,
1439 TUI_CMD_WIN->generic.height,
1440 TUI_CMD_WIN->generic.width);
110ed339 1441#endif
d27b3be4
PA
1442 mvwin (TUI_CMD_WIN->generic.handle,
1443 TUI_CMD_WIN->generic.origin.y,
1444 TUI_CMD_WIN->generic.origin.x);
6d012f14
AC
1445 wmove (win_info->generic.handle,
1446 win_info->detail.command_info.cur_line,
1447 win_info->detail.command_info.curch);
c906108c
SS
1448 break;
1449 default:
1450 break;
1451 }
6ba8e26f 1452}
c906108c
SS
1453
1454
1455static int
08ef48c5
MS
1456new_height_ok (struct tui_win_info *primary_win_info,
1457 int new_height)
c906108c 1458{
6ba8e26f 1459 int ok = (new_height < tui_term_height ());
c906108c
SS
1460
1461 if (ok)
1462 {
bc712bbf 1463 int diff;
6d012f14 1464 enum tui_layout_type cur_layout = tui_current_layout ();
c906108c 1465
6ba8e26f 1466 diff = (new_height - primary_win_info->generic.height) * (-1);
6d012f14 1467 if (cur_layout == SRC_COMMAND || cur_layout == DISASSEM_COMMAND)
c906108c 1468 {
e5908723
MS
1469 ok = ((primary_win_info->generic.type == CMD_WIN
1470 && new_height <= (tui_term_height () - 4)
1471 && new_height >= MIN_CMD_WIN_HEIGHT)
1472 || (primary_win_info->generic.type != CMD_WIN
1473 && new_height <= (tui_term_height () - 2)
1474 && new_height >= MIN_WIN_HEIGHT));
c906108c 1475 if (ok)
1cc6d956 1476 { /* Check the total height. */
5b6fe301 1477 struct tui_win_info *win_info;
c906108c 1478
6ba8e26f 1479 if (primary_win_info == TUI_CMD_WIN)
96c1eda2 1480 win_info = (tui_source_windows ())->list[0];
c906108c 1481 else
6d012f14 1482 win_info = TUI_CMD_WIN;
6ba8e26f 1483 ok = ((new_height +
6d012f14 1484 (win_info->generic.height + diff)) <= tui_term_height ());
c906108c
SS
1485 }
1486 }
1487 else
1488 {
6ba8e26f
AC
1489 int cur_total_height, total_height, min_height = 0;
1490 struct tui_win_info *first_win;
1491 struct tui_win_info *second_win;
c906108c 1492
6d012f14 1493 if (cur_layout == SRC_DISASSEM_COMMAND)
c906108c 1494 {
6ba8e26f
AC
1495 first_win = TUI_SRC_WIN;
1496 second_win = TUI_DISASM_WIN;
c906108c
SS
1497 }
1498 else
1499 {
6ba8e26f 1500 first_win = TUI_DATA_WIN;
96c1eda2 1501 second_win = (tui_source_windows ())->list[0];
c906108c 1502 }
ef5eab5a
MS
1503 /* We could simply add all the heights to obtain the same
1504 result but below is more explicit since we subtract 1 for
1505 the line that the first and second windows share, and add
1506 one for the locator. */
6ba8e26f
AC
1507 total_height = cur_total_height =
1508 (first_win->generic.height + second_win->generic.height - 1)
1cc6d956 1509 + TUI_CMD_WIN->generic.height + 1; /* Locator. */
6ba8e26f 1510 if (primary_win_info == TUI_CMD_WIN)
c906108c 1511 {
1cc6d956 1512 /* Locator included since first & second win share a line. */
6ba8e26f
AC
1513 ok = ((first_win->generic.height +
1514 second_win->generic.height + diff) >=
e5908723
MS
1515 (MIN_WIN_HEIGHT * 2)
1516 && new_height >= MIN_CMD_WIN_HEIGHT);
c906108c
SS
1517 if (ok)
1518 {
e5908723
MS
1519 total_height = new_height +
1520 (first_win->generic.height +
1521 second_win->generic.height + diff);
6ba8e26f 1522 min_height = MIN_CMD_WIN_HEIGHT;
c906108c
SS
1523 }
1524 }
1525 else
1526 {
6ba8e26f 1527 min_height = MIN_WIN_HEIGHT;
ef5eab5a
MS
1528
1529 /* First see if we can increase/decrease the command
1530 window. And make sure that the command window is at
1531 least 1 line. */
6d012f14 1532 ok = ((TUI_CMD_WIN->generic.height + diff) > 0);
c906108c 1533 if (!ok)
ef5eab5a
MS
1534 { /* Looks like we have to increase/decrease one of
1535 the other windows. */
6ba8e26f
AC
1536 if (primary_win_info == first_win)
1537 ok = (second_win->generic.height + diff) >= min_height;
c906108c 1538 else
6ba8e26f 1539 ok = (first_win->generic.height + diff) >= min_height;
c906108c
SS
1540 }
1541 if (ok)
1542 {
6ba8e26f
AC
1543 if (primary_win_info == first_win)
1544 total_height = new_height +
1545 second_win->generic.height +
6d012f14 1546 TUI_CMD_WIN->generic.height + diff;
c906108c 1547 else
6ba8e26f
AC
1548 total_height = new_height +
1549 first_win->generic.height +
6d012f14 1550 TUI_CMD_WIN->generic.height + diff;
c906108c
SS
1551 }
1552 }
ef5eab5a
MS
1553 /* Now make sure that the proposed total height doesn't
1554 exceed the old total height. */
c906108c 1555 if (ok)
e5908723
MS
1556 ok = (new_height >= min_height
1557 && total_height <= cur_total_height);
c906108c
SS
1558 }
1559 }
1560
1561 return ok;
6ba8e26f 1562}
c906108c
SS
1563
1564
c906108c 1565static void
08ef48c5
MS
1566parse_scrolling_args (char *arg,
1567 struct tui_win_info **win_to_scroll,
6ba8e26f 1568 int *num_to_scroll)
c906108c 1569{
6ba8e26f
AC
1570 if (num_to_scroll)
1571 *num_to_scroll = 0;
1572 *win_to_scroll = tui_win_with_focus ();
c906108c 1573
ef5eab5a
MS
1574 /* First set up the default window to scroll, in case there is no
1575 window name arg. */
c906108c
SS
1576 if (arg != (char *) NULL)
1577 {
6ba8e26f 1578 char *buf, *buf_ptr;
c906108c 1579
1cc6d956 1580 /* Process the number of lines to scroll. */
6ba8e26f
AC
1581 buf = buf_ptr = xstrdup (arg);
1582 if (isdigit (*buf_ptr))
c906108c 1583 {
6ba8e26f 1584 char *num_str;
c906108c 1585
6ba8e26f
AC
1586 num_str = buf_ptr;
1587 buf_ptr = strchr (buf_ptr, ' ');
1588 if (buf_ptr != (char *) NULL)
c906108c 1589 {
6ba8e26f
AC
1590 *buf_ptr = (char) 0;
1591 if (num_to_scroll)
1592 *num_to_scroll = atoi (num_str);
1593 buf_ptr++;
c906108c 1594 }
6ba8e26f
AC
1595 else if (num_to_scroll)
1596 *num_to_scroll = atoi (num_str);
c906108c
SS
1597 }
1598
1cc6d956 1599 /* Process the window name if one is specified. */
6ba8e26f 1600 if (buf_ptr != (char *) NULL)
c906108c
SS
1601 {
1602 char *wname;
1603 int i;
1604
6ba8e26f
AC
1605 if (*buf_ptr == ' ')
1606 while (*(++buf_ptr) == ' ')
c906108c
SS
1607 ;
1608
6ba8e26f 1609 if (*buf_ptr != (char) 0)
c709a7c2
TT
1610 {
1611 wname = buf_ptr;
1612
1613 /* Validate the window name. */
1614 for (i = 0; i < strlen (wname); i++)
1615 wname[i] = toupper (wname[i]);
1616 }
a4b99e53
SC
1617 else
1618 wname = "?";
1619
6ba8e26f 1620 *win_to_scroll = tui_partial_win_by_name (wname);
c906108c 1621
e5908723
MS
1622 if (*win_to_scroll == (struct tui_win_info *) NULL
1623 || !(*win_to_scroll)->generic.is_visible)
ec502284 1624 error (_("Invalid window specified. \n\
8a3fe4f8 1625The window name specified must be valid and visible.\n"));
6ba8e26f 1626 else if (*win_to_scroll == TUI_CMD_WIN)
96c1eda2 1627 *win_to_scroll = (tui_source_windows ())->list[0];
c906108c 1628 }
22940a24 1629 xfree (buf);
c906108c 1630 }
6ba8e26f 1631}