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