Remove tui_gen_win_info::viewport_height
[deliverable/binutils-gdb.git] / gdb / tui / tui-layout.c
1 /* TUI layout window management.
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 #include "defs.h"
23 #include "arch-utils.h"
24 #include "command.h"
25 #include "symtab.h"
26 #include "frame.h"
27 #include "source.h"
28 #include <ctype.h>
29
30 #include "tui/tui.h"
31 #include "tui/tui-command.h"
32 #include "tui/tui-data.h"
33 #include "tui/tui-wingeneral.h"
34 #include "tui/tui-stack.h"
35 #include "tui/tui-regs.h"
36 #include "tui/tui-win.h"
37 #include "tui/tui-winsource.h"
38 #include "tui/tui-disasm.h"
39 #include "tui/tui-layout.h"
40 #include "tui/tui-source.h"
41 #include "gdb_curses.h"
42
43 static void show_layout (enum tui_layout_type);
44 static enum tui_layout_type next_layout (void);
45 static enum tui_layout_type prev_layout (void);
46 static void tui_layout_command (const char *, int);
47 static void extract_display_start_addr (struct gdbarch **, CORE_ADDR *);
48
49
50 /* The pre-defined layouts. */
51 static tui_layout_split *standard_layouts[UNDEFINED_LAYOUT];
52
53 /* The layout that is currently applied. */
54 static std::unique_ptr<tui_layout_base> applied_layout;
55
56 static enum tui_layout_type current_layout = UNDEFINED_LAYOUT;
57
58 /* Accessor for the current layout. */
59 enum tui_layout_type
60 tui_current_layout (void)
61 {
62 return current_layout;
63 }
64
65 /* See tui-layout.h. */
66
67 void
68 tui_apply_current_layout ()
69 {
70 applied_layout->apply (0, 0, tui_term_width (), tui_term_height ());
71 }
72
73 /* See tui-layout. */
74
75 void
76 tui_adjust_window_height (struct tui_win_info *win, int new_height)
77 {
78 applied_layout->adjust_size (win->name (), new_height);
79 }
80
81 /* Show the screen layout defined. */
82 static void
83 show_layout (enum tui_layout_type layout)
84 {
85 enum tui_layout_type cur_layout = tui_current_layout ();
86
87 if (layout != cur_layout)
88 {
89 tui_make_all_invisible ();
90 applied_layout = standard_layouts[layout]->clone ();
91 tui_apply_current_layout ();
92 current_layout = layout;
93 tui_delete_invisible_windows ();
94 }
95 }
96
97
98 /* Function to set the layout to SRC_COMMAND, DISASSEM_COMMAND,
99 SRC_DISASSEM_COMMAND, SRC_DATA_COMMAND, or DISASSEM_DATA_COMMAND. */
100 void
101 tui_set_layout (enum tui_layout_type layout_type)
102 {
103 gdb_assert (layout_type != UNDEFINED_LAYOUT);
104
105 enum tui_layout_type cur_layout = tui_current_layout ();
106 struct gdbarch *gdbarch;
107 CORE_ADDR addr;
108 struct tui_win_info *win_with_focus = tui_win_with_focus ();
109
110 extract_display_start_addr (&gdbarch, &addr);
111
112 enum tui_layout_type new_layout = layout_type;
113
114 if (new_layout != cur_layout)
115 {
116 show_layout (new_layout);
117
118 /* Now determine where focus should be. */
119 if (win_with_focus != TUI_CMD_WIN)
120 {
121 switch (new_layout)
122 {
123 case SRC_COMMAND:
124 tui_set_win_focus_to (TUI_SRC_WIN);
125 break;
126 case DISASSEM_COMMAND:
127 /* The previous layout was not showing code.
128 This can happen if there is no source
129 available:
130
131 1. if the source file is in another dir OR
132 2. if target was compiled without -g
133 We still want to show the assembly though! */
134
135 tui_get_begin_asm_address (&gdbarch, &addr);
136 tui_set_win_focus_to (TUI_DISASM_WIN);
137 break;
138 case SRC_DISASSEM_COMMAND:
139 /* The previous layout was not showing code.
140 This can happen if there is no source
141 available:
142
143 1. if the source file is in another dir OR
144 2. if target was compiled without -g
145 We still want to show the assembly though! */
146
147 tui_get_begin_asm_address (&gdbarch, &addr);
148 if (win_with_focus == TUI_SRC_WIN)
149 tui_set_win_focus_to (TUI_SRC_WIN);
150 else
151 tui_set_win_focus_to (TUI_DISASM_WIN);
152 break;
153 case SRC_DATA_COMMAND:
154 if (win_with_focus != TUI_DATA_WIN)
155 tui_set_win_focus_to (TUI_SRC_WIN);
156 else
157 tui_set_win_focus_to (TUI_DATA_WIN);
158 break;
159 case DISASSEM_DATA_COMMAND:
160 /* The previous layout was not showing code.
161 This can happen if there is no source
162 available:
163
164 1. if the source file is in another dir OR
165 2. if target was compiled without -g
166 We still want to show the assembly though! */
167
168 tui_get_begin_asm_address (&gdbarch, &addr);
169 if (win_with_focus != TUI_DATA_WIN)
170 tui_set_win_focus_to (TUI_DISASM_WIN);
171 else
172 tui_set_win_focus_to (TUI_DATA_WIN);
173 break;
174 default:
175 break;
176 }
177 }
178 /*
179 * Now update the window content.
180 */
181 tui_update_source_windows_with_addr (gdbarch, addr);
182 if (new_layout == SRC_DATA_COMMAND
183 || new_layout == DISASSEM_DATA_COMMAND)
184 TUI_DATA_WIN->show_registers (TUI_DATA_WIN->get_current_group ());
185 }
186 }
187
188 /* Add the specified window to the layout in a logical way. This
189 means setting up the most logical layout given the window to be
190 added. */
191 void
192 tui_add_win_to_layout (enum tui_win_type type)
193 {
194 enum tui_layout_type cur_layout = tui_current_layout ();
195
196 switch (type)
197 {
198 case SRC_WIN:
199 if (cur_layout != SRC_COMMAND
200 && cur_layout != SRC_DISASSEM_COMMAND
201 && cur_layout != SRC_DATA_COMMAND)
202 {
203 if (cur_layout == DISASSEM_DATA_COMMAND)
204 show_layout (SRC_DATA_COMMAND);
205 else
206 show_layout (SRC_COMMAND);
207 }
208 break;
209 case DISASSEM_WIN:
210 if (cur_layout != DISASSEM_COMMAND
211 && cur_layout != SRC_DISASSEM_COMMAND
212 && cur_layout != DISASSEM_DATA_COMMAND)
213 {
214 if (cur_layout == SRC_DATA_COMMAND)
215 show_layout (DISASSEM_DATA_COMMAND);
216 else
217 show_layout (DISASSEM_COMMAND);
218 }
219 break;
220 case DATA_WIN:
221 if (cur_layout != SRC_DATA_COMMAND
222 && cur_layout != DISASSEM_DATA_COMMAND)
223 {
224 if (cur_layout == DISASSEM_COMMAND)
225 show_layout (DISASSEM_DATA_COMMAND);
226 else
227 show_layout (SRC_DATA_COMMAND);
228 }
229 break;
230 default:
231 break;
232 }
233 }
234
235 /* Complete possible layout names. TEXT is the complete text entered so
236 far, WORD is the word currently being completed. */
237
238 static void
239 layout_completer (struct cmd_list_element *ignore,
240 completion_tracker &tracker,
241 const char *text, const char *word)
242 {
243 static const char *layout_names [] =
244 { "src", "asm", "split", "regs", "next", "prev", NULL };
245
246 complete_on_enum (tracker, layout_names, text, word);
247 }
248
249 /* Function to set the layout to SRC, ASM, SPLIT, NEXT, PREV, DATA, or
250 REGS. */
251 static void
252 tui_layout_command (const char *layout_name, int from_tty)
253 {
254 enum tui_layout_type new_layout = UNDEFINED_LAYOUT;
255 enum tui_layout_type cur_layout = tui_current_layout ();
256
257 if (layout_name == NULL || *layout_name == '\0')
258 error (_("Usage: layout prev | next | LAYOUT-NAME"));
259
260 /* First check for ambiguous input. */
261 if (strcmp (layout_name, "s") == 0)
262 error (_("Ambiguous command input."));
263
264 if (subset_compare (layout_name, "src"))
265 new_layout = SRC_COMMAND;
266 else if (subset_compare (layout_name, "asm"))
267 new_layout = DISASSEM_COMMAND;
268 else if (subset_compare (layout_name, "split"))
269 new_layout = SRC_DISASSEM_COMMAND;
270 else if (subset_compare (layout_name, "regs"))
271 {
272 if (cur_layout == SRC_COMMAND
273 || cur_layout == SRC_DATA_COMMAND)
274 new_layout = SRC_DATA_COMMAND;
275 else
276 new_layout = DISASSEM_DATA_COMMAND;
277 }
278 else if (subset_compare (layout_name, "next"))
279 new_layout = next_layout ();
280 else if (subset_compare (layout_name, "prev"))
281 new_layout = prev_layout ();
282 else
283 error (_("Unrecognized layout: %s"), layout_name);
284
285 /* Make sure the curses mode is enabled. */
286 tui_enable ();
287 tui_set_layout (new_layout);
288 }
289
290
291 static void
292 extract_display_start_addr (struct gdbarch **gdbarch_p, CORE_ADDR *addr_p)
293 {
294 enum tui_layout_type cur_layout = tui_current_layout ();
295 struct gdbarch *gdbarch = get_current_arch ();
296 CORE_ADDR addr;
297 CORE_ADDR pc;
298 struct symtab_and_line cursal = get_current_source_symtab_and_line ();
299
300 switch (cur_layout)
301 {
302 case SRC_COMMAND:
303 case SRC_DATA_COMMAND:
304 gdbarch = TUI_SRC_WIN->gdbarch;
305 find_line_pc (cursal.symtab,
306 TUI_SRC_WIN->start_line_or_addr.u.line_no,
307 &pc);
308 addr = pc;
309 break;
310 case DISASSEM_COMMAND:
311 case SRC_DISASSEM_COMMAND:
312 case DISASSEM_DATA_COMMAND:
313 gdbarch = TUI_DISASM_WIN->gdbarch;
314 addr = TUI_DISASM_WIN->start_line_or_addr.u.addr;
315 break;
316 default:
317 addr = 0;
318 break;
319 }
320
321 *gdbarch_p = gdbarch;
322 *addr_p = addr;
323 }
324
325
326 /* Answer the previous layout to cycle to. */
327 static enum tui_layout_type
328 next_layout (void)
329 {
330 int new_layout;
331
332 new_layout = tui_current_layout ();
333 if (new_layout == UNDEFINED_LAYOUT)
334 new_layout = SRC_COMMAND;
335 else
336 {
337 new_layout++;
338 if (new_layout == UNDEFINED_LAYOUT)
339 new_layout = SRC_COMMAND;
340 }
341
342 return (enum tui_layout_type) new_layout;
343 }
344
345
346 /* Answer the next layout to cycle to. */
347 static enum tui_layout_type
348 prev_layout (void)
349 {
350 int new_layout;
351
352 new_layout = tui_current_layout ();
353 if (new_layout == SRC_COMMAND)
354 new_layout = DISASSEM_DATA_COMMAND;
355 else
356 {
357 new_layout--;
358 if (new_layout == UNDEFINED_LAYOUT)
359 new_layout = DISASSEM_DATA_COMMAND;
360 }
361
362 return (enum tui_layout_type) new_layout;
363 }
364
365 void
366 tui_gen_win_info::resize (int height_, int width_,
367 int origin_x_, int origin_y_)
368 {
369 if (width == width_ && height == height_
370 && x == origin_x_ && y == origin_y_
371 && handle != nullptr)
372 return;
373
374 width = width_;
375 height = height_;
376 x = origin_x_;
377 y = origin_y_;
378
379 if (handle != nullptr)
380 {
381 #ifdef HAVE_WRESIZE
382 wresize (handle.get (), height, width);
383 mvwin (handle.get (), y, x);
384 wmove (handle.get (), 0, 0);
385 #else
386 handle.reset (nullptr);
387 #endif
388 }
389
390 if (handle == nullptr)
391 make_window ();
392
393 rerender ();
394 }
395
396 \f
397
398 /* Helper function that returns a TUI window, given its name. */
399
400 static tui_gen_win_info *
401 tui_get_window_by_name (const std::string &name)
402 {
403 if (name == "src")
404 {
405 if (tui_win_list[SRC_WIN] == nullptr)
406 tui_win_list[SRC_WIN] = new tui_source_window ();
407 return tui_win_list[SRC_WIN];
408 }
409 else if (name == "cmd")
410 {
411 if (tui_win_list[CMD_WIN] == nullptr)
412 tui_win_list[CMD_WIN] = new tui_cmd_window ();
413 return tui_win_list[CMD_WIN];
414 }
415 else if (name == "regs")
416 {
417 if (tui_win_list[DATA_WIN] == nullptr)
418 tui_win_list[DATA_WIN] = new tui_data_window ();
419 return tui_win_list[DATA_WIN];
420 }
421 else if (name == "asm")
422 {
423 if (tui_win_list[DISASSEM_WIN] == nullptr)
424 tui_win_list[DISASSEM_WIN] = new tui_disasm_window ();
425 return tui_win_list[DISASSEM_WIN];
426 }
427 else
428 {
429 gdb_assert (name == "locator");
430 return tui_locator_win_info_ptr ();
431 }
432 }
433
434 /* See tui-layout.h. */
435
436 std::unique_ptr<tui_layout_base>
437 tui_layout_window::clone () const
438 {
439 tui_layout_window *result = new tui_layout_window (m_contents.c_str ());
440 return std::unique_ptr<tui_layout_base> (result);
441 }
442
443 /* See tui-layout.h. */
444
445 void
446 tui_layout_window::apply (int x_, int y_, int width_, int height_)
447 {
448 x = x_;
449 y = y_;
450 width = width_;
451 height = height_;
452 gdb_assert (m_window != nullptr);
453 m_window->resize (height, width, x, y);
454 }
455
456 /* See tui-layout.h. */
457
458 void
459 tui_layout_window::get_sizes (int *min_height, int *max_height)
460 {
461 if (m_window == nullptr)
462 m_window = tui_get_window_by_name (m_contents);
463 *min_height = m_window->min_height ();
464 *max_height = m_window->max_height ();
465 }
466
467 /* See tui-layout.h. */
468
469 bool
470 tui_layout_window::top_boxed_p () const
471 {
472 gdb_assert (m_window != nullptr);
473 return m_window->can_box ();
474 }
475
476 /* See tui-layout.h. */
477
478 bool
479 tui_layout_window::bottom_boxed_p () const
480 {
481 gdb_assert (m_window != nullptr);
482 return m_window->can_box ();
483 }
484
485 /* See tui-layout.h. */
486
487 tui_layout_split *
488 tui_layout_split::add_split (int weight)
489 {
490 tui_layout_split *result = new tui_layout_split ();
491 split s = {weight, std::unique_ptr<tui_layout_base> (result)};
492 m_splits.push_back (std::move (s));
493 return result;
494 }
495
496 /* See tui-layout.h. */
497
498 void
499 tui_layout_split::add_window (const char *name, int weight)
500 {
501 tui_layout_window *result = new tui_layout_window (name);
502 split s = {weight, std::unique_ptr<tui_layout_base> (result)};
503 m_splits.push_back (std::move (s));
504 }
505
506 /* See tui-layout.h. */
507
508 std::unique_ptr<tui_layout_base>
509 tui_layout_split::clone () const
510 {
511 tui_layout_split *result = new tui_layout_split ();
512 for (const split &item : m_splits)
513 {
514 std::unique_ptr<tui_layout_base> next = item.layout->clone ();
515 split s = {item.weight, std::move (next)};
516 result->m_splits.push_back (std::move (s));
517 }
518 return std::unique_ptr<tui_layout_base> (result);
519 }
520
521 /* See tui-layout.h. */
522
523 void
524 tui_layout_split::get_sizes (int *min_height, int *max_height)
525 {
526 *min_height = 0;
527 *max_height = 0;
528 for (const split &item : m_splits)
529 {
530 int new_min, new_max;
531 item.layout->get_sizes (&new_min, &new_max);
532 *min_height += new_min;
533 *max_height += new_max;
534 }
535 }
536
537 /* See tui-layout.h. */
538
539 bool
540 tui_layout_split::top_boxed_p () const
541 {
542 if (m_splits.empty ())
543 return false;
544 return m_splits[0].layout->top_boxed_p ();
545 }
546
547 /* See tui-layout.h. */
548
549 bool
550 tui_layout_split::bottom_boxed_p () const
551 {
552 if (m_splits.empty ())
553 return false;
554 return m_splits.back ().layout->top_boxed_p ();
555 }
556
557 /* See tui-layout.h. */
558
559 void
560 tui_layout_split::set_weights_from_heights ()
561 {
562 for (int i = 0; i < m_splits.size (); ++i)
563 m_splits[i].weight = m_splits[i].layout->height;
564 }
565
566 /* See tui-layout.h. */
567
568 bool
569 tui_layout_split::adjust_size (const char *name, int new_height)
570 {
571 /* Look through the children. If one is a layout holding the named
572 window, we're done; or if one actually is the named window,
573 update it. */
574 int found_index = -1;
575 for (int i = 0; i < m_splits.size (); ++i)
576 {
577 if (m_splits[i].layout->adjust_size (name, new_height))
578 return true;
579 const char *win_name = m_splits[i].layout->get_name ();
580 if (win_name != nullptr && strcmp (name, win_name) == 0)
581 {
582 found_index = i;
583 break;
584 }
585 }
586
587 if (found_index == -1)
588 return false;
589 if (m_splits[found_index].layout->height == new_height)
590 return true;
591
592 set_weights_from_heights ();
593 int delta = m_splits[found_index].weight - new_height;
594 m_splits[found_index].weight = new_height;
595
596 /* Distribute the "delta" over the next window; but if the next
597 window cannot hold it all, keep going until we either find a
598 window that does, or until we loop all the way around. */
599 for (int i = 0; delta != 0 && i < m_splits.size () - 1; ++i)
600 {
601 int index = (found_index + 1 + i) % m_splits.size ();
602
603 int new_min, new_max;
604 m_splits[index].layout->get_sizes (&new_min, &new_max);
605
606 if (delta < 0)
607 {
608 /* The primary window grew, so we are trying to shrink other
609 windows. */
610 int available = m_splits[index].weight - new_min;
611 int shrink_by = std::min (available, -delta);
612 m_splits[index].weight -= shrink_by;
613 delta += shrink_by;
614 }
615 else
616 {
617 /* The primary window shrank, so we are trying to grow other
618 windows. */
619 int available = new_max - m_splits[index].weight;
620 int grow_by = std::min (available, delta);
621 m_splits[index].weight += grow_by;
622 delta -= grow_by;
623 }
624 }
625
626 if (delta != 0)
627 {
628 warning (_("Invalid window height specified"));
629 /* Effectively undo any modifications made here. */
630 set_weights_from_heights ();
631 }
632 else
633 {
634 /* Simply re-apply the updated layout. */
635 apply (x, y, width, height);
636 }
637
638 return true;
639 }
640
641 /* See tui-layout.h. */
642
643 void
644 tui_layout_split::apply (int x_, int y_, int width_, int height_)
645 {
646 x = x_;
647 y = y_;
648 width = width_;
649 height = height_;
650
651 struct height_info
652 {
653 int height;
654 int min_height;
655 int max_height;
656 /* True if this window will share a box border with the previous
657 window in the list. */
658 bool share_box;
659 };
660
661 std::vector<height_info> info (m_splits.size ());
662
663 /* Step 1: Find the min and max height of each sub-layout.
664 Fixed-sized layouts are given their desired height, and then the
665 remaining space is distributed among the remaining windows
666 according to the weights given. */
667 int available_height = height;
668 int last_index = -1;
669 int total_weight = 0;
670 for (int i = 0; i < m_splits.size (); ++i)
671 {
672 bool cmd_win_already_exists = TUI_CMD_WIN != nullptr;
673
674 /* Always call get_sizes, to ensure that the window is
675 instantiated. This is a bit gross but less gross than adding
676 special cases for this in other places. */
677 m_splits[i].layout->get_sizes (&info[i].min_height, &info[i].max_height);
678
679 if (!m_applied
680 && cmd_win_already_exists
681 && m_splits[i].layout->get_name () != nullptr
682 && strcmp (m_splits[i].layout->get_name (), "cmd") == 0)
683 {
684 /* If this layout has never been applied, then it means the
685 user just changed the layout. In this situation, it's
686 desirable to keep the size of the command window the
687 same. Setting the min and max heights this way ensures
688 that the resizing step, below, does the right thing with
689 this window. */
690 info[i].min_height = TUI_CMD_WIN->height;
691 info[i].max_height = TUI_CMD_WIN->height;
692 }
693
694 if (info[i].min_height == info[i].max_height)
695 available_height -= info[i].min_height;
696 else
697 {
698 last_index = i;
699 total_weight += m_splits[i].weight;
700 }
701
702 /* Two adjacent boxed windows will share a border, making a bit
703 more height available. */
704 if (i > 0
705 && m_splits[i - 1].layout->bottom_boxed_p ()
706 && m_splits[i].layout->top_boxed_p ())
707 info[i].share_box = true;
708 }
709
710 /* Step 2: Compute the height of each sub-layout. Fixed-sized items
711 are given their fixed size, while others are resized according to
712 their weight. */
713 int used_height = 0;
714 for (int i = 0; i < m_splits.size (); ++i)
715 {
716 /* Compute the height and clamp to the allowable range. */
717 info[i].height = available_height * m_splits[i].weight / total_weight;
718 if (info[i].height > info[i].max_height)
719 info[i].height = info[i].max_height;
720 if (info[i].height < info[i].min_height)
721 info[i].height = info[i].min_height;
722 /* If there is any leftover height, just redistribute it to the
723 last resizeable window, by dropping it from the allocated
724 height. We could try to be fancier here perhaps, by
725 redistributing this height among all windows, not just the
726 last window. */
727 if (info[i].min_height != info[i].max_height)
728 {
729 used_height += info[i].height;
730 if (info[i].share_box)
731 --used_height;
732 }
733 }
734
735 /* Allocate any leftover height. */
736 if (available_height >= used_height && last_index != -1)
737 info[last_index].height += available_height - used_height;
738
739 /* Step 3: Resize. */
740 int height_accum = 0;
741 for (int i = 0; i < m_splits.size (); ++i)
742 {
743 /* If we fall off the bottom, just make allocations overlap.
744 GIGO. */
745 if (height_accum + info[i].height > height)
746 height_accum = height - info[i].height;
747 else if (info[i].share_box)
748 --height_accum;
749 m_splits[i].layout->apply (x, y + height_accum, width, info[i].height);
750 height_accum += info[i].height;
751 }
752
753 m_applied = true;
754 }
755
756 static void
757 initialize_layouts ()
758 {
759 standard_layouts[SRC_COMMAND] = new tui_layout_split ();
760 standard_layouts[SRC_COMMAND]->add_window ("src", 2);
761 standard_layouts[SRC_COMMAND]->add_window ("locator", 0);
762 standard_layouts[SRC_COMMAND]->add_window ("cmd", 1);
763
764 standard_layouts[DISASSEM_COMMAND] = new tui_layout_split ();
765 standard_layouts[DISASSEM_COMMAND]->add_window ("asm", 2);
766 standard_layouts[DISASSEM_COMMAND]->add_window ("locator", 0);
767 standard_layouts[DISASSEM_COMMAND]->add_window ("cmd", 1);
768
769 standard_layouts[SRC_DATA_COMMAND] = new tui_layout_split ();
770 standard_layouts[SRC_DATA_COMMAND]->add_window ("regs", 1);
771 standard_layouts[SRC_DATA_COMMAND]->add_window ("src", 1);
772 standard_layouts[SRC_DATA_COMMAND]->add_window ("locator", 0);
773 standard_layouts[SRC_DATA_COMMAND]->add_window ("cmd", 1);
774
775 standard_layouts[DISASSEM_DATA_COMMAND] = new tui_layout_split ();
776 standard_layouts[DISASSEM_DATA_COMMAND]->add_window ("regs", 1);
777 standard_layouts[DISASSEM_DATA_COMMAND]->add_window ("asm", 1);
778 standard_layouts[DISASSEM_DATA_COMMAND]->add_window ("locator", 0);
779 standard_layouts[DISASSEM_DATA_COMMAND]->add_window ("cmd", 1);
780
781 standard_layouts[SRC_DISASSEM_COMMAND] = new tui_layout_split ();
782 standard_layouts[SRC_DISASSEM_COMMAND]->add_window ("src", 1);
783 standard_layouts[SRC_DISASSEM_COMMAND]->add_window ("asm", 1);
784 standard_layouts[SRC_DISASSEM_COMMAND]->add_window ("locator", 0);
785 standard_layouts[SRC_DISASSEM_COMMAND]->add_window ("cmd", 1);
786 }
787
788 \f
789
790 /* Function to initialize gdb commands, for tui window layout
791 manipulation. */
792
793 void
794 _initialize_tui_layout (void)
795 {
796 struct cmd_list_element *cmd;
797
798 cmd = add_com ("layout", class_tui, tui_layout_command, _("\
799 Change the layout of windows.\n\
800 Usage: layout prev | next | LAYOUT-NAME\n\
801 Layout names are:\n\
802 src : Displays source and command windows.\n\
803 asm : Displays disassembly and command windows.\n\
804 split : Displays source, disassembly and command windows.\n\
805 regs : Displays register window. If existing layout\n\
806 is source/command or assembly/command, the \n\
807 register window is displayed. If the\n\
808 source/assembly/command (split) is displayed, \n\
809 the register window is displayed with \n\
810 the window that has current logical focus."));
811 set_cmd_completer (cmd, layout_completer);
812
813 initialize_layouts ();
814 }
This page took 0.068365 seconds and 4 git commands to generate.