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