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