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