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