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