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