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