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