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