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