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