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