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