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