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