Simplify TUI C-x 2 binding
[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 /* See tui-layout.h. */
282
283 void
284 tui_next_layout ()
285 {
286 tui_layout_command ("next", 0);
287 }
288
289 static void
290 extract_display_start_addr (struct gdbarch **gdbarch_p, CORE_ADDR *addr_p)
291 {
292 enum tui_layout_type cur_layout = tui_current_layout ();
293 struct gdbarch *gdbarch = get_current_arch ();
294 CORE_ADDR addr;
295 CORE_ADDR pc;
296 struct symtab_and_line cursal = get_current_source_symtab_and_line ();
297
298 switch (cur_layout)
299 {
300 case SRC_COMMAND:
301 case SRC_DATA_COMMAND:
302 gdbarch = TUI_SRC_WIN->gdbarch;
303 find_line_pc (cursal.symtab,
304 TUI_SRC_WIN->start_line_or_addr.u.line_no,
305 &pc);
306 addr = pc;
307 break;
308 case DISASSEM_COMMAND:
309 case SRC_DISASSEM_COMMAND:
310 case DISASSEM_DATA_COMMAND:
311 gdbarch = TUI_DISASM_WIN->gdbarch;
312 addr = TUI_DISASM_WIN->start_line_or_addr.u.addr;
313 break;
314 default:
315 addr = 0;
316 break;
317 }
318
319 *gdbarch_p = gdbarch;
320 *addr_p = addr;
321 }
322
323
324 /* Answer the previous layout to cycle to. */
325 static enum tui_layout_type
326 next_layout (void)
327 {
328 int new_layout;
329
330 new_layout = tui_current_layout ();
331 if (new_layout == UNDEFINED_LAYOUT)
332 new_layout = SRC_COMMAND;
333 else
334 {
335 new_layout++;
336 if (new_layout == UNDEFINED_LAYOUT)
337 new_layout = SRC_COMMAND;
338 }
339
340 return (enum tui_layout_type) new_layout;
341 }
342
343
344 /* Answer the next layout to cycle to. */
345 static enum tui_layout_type
346 prev_layout (void)
347 {
348 int new_layout;
349
350 new_layout = tui_current_layout ();
351 if (new_layout == SRC_COMMAND)
352 new_layout = DISASSEM_DATA_COMMAND;
353 else
354 {
355 new_layout--;
356 if (new_layout == UNDEFINED_LAYOUT)
357 new_layout = DISASSEM_DATA_COMMAND;
358 }
359
360 return (enum tui_layout_type) new_layout;
361 }
362
363 void
364 tui_gen_win_info::resize (int height_, int width_,
365 int origin_x_, int origin_y_)
366 {
367 if (width == width_ && height == height_
368 && x == origin_x_ && y == origin_y_
369 && handle != nullptr)
370 return;
371
372 width = width_;
373 height = height_;
374 x = origin_x_;
375 y = origin_y_;
376
377 if (handle != nullptr)
378 {
379 #ifdef HAVE_WRESIZE
380 wresize (handle.get (), height, width);
381 mvwin (handle.get (), y, x);
382 wmove (handle.get (), 0, 0);
383 #else
384 handle.reset (nullptr);
385 #endif
386 }
387
388 if (handle == nullptr)
389 make_window ();
390
391 rerender ();
392 }
393
394 \f
395
396 /* Helper function that returns a TUI window, given its name. */
397
398 static tui_gen_win_info *
399 tui_get_window_by_name (const std::string &name)
400 {
401 if (name == "src")
402 {
403 if (tui_win_list[SRC_WIN] == nullptr)
404 tui_win_list[SRC_WIN] = new tui_source_window ();
405 return tui_win_list[SRC_WIN];
406 }
407 else if (name == "cmd")
408 {
409 if (tui_win_list[CMD_WIN] == nullptr)
410 tui_win_list[CMD_WIN] = new tui_cmd_window ();
411 return tui_win_list[CMD_WIN];
412 }
413 else if (name == "regs")
414 {
415 if (tui_win_list[DATA_WIN] == nullptr)
416 tui_win_list[DATA_WIN] = new tui_data_window ();
417 return tui_win_list[DATA_WIN];
418 }
419 else if (name == "asm")
420 {
421 if (tui_win_list[DISASSEM_WIN] == nullptr)
422 tui_win_list[DISASSEM_WIN] = new tui_disasm_window ();
423 return tui_win_list[DISASSEM_WIN];
424 }
425 else
426 {
427 gdb_assert (name == "locator");
428 return tui_locator_win_info_ptr ();
429 }
430 }
431
432 /* See tui-layout.h. */
433
434 std::unique_ptr<tui_layout_base>
435 tui_layout_window::clone () const
436 {
437 tui_layout_window *result = new tui_layout_window (m_contents.c_str ());
438 return std::unique_ptr<tui_layout_base> (result);
439 }
440
441 /* See tui-layout.h. */
442
443 void
444 tui_layout_window::apply (int x_, int y_, int width_, int height_)
445 {
446 x = x_;
447 y = y_;
448 width = width_;
449 height = height_;
450 gdb_assert (m_window != nullptr);
451 m_window->resize (height, width, x, y);
452 }
453
454 /* See tui-layout.h. */
455
456 void
457 tui_layout_window::get_sizes (int *min_height, int *max_height)
458 {
459 if (m_window == nullptr)
460 m_window = tui_get_window_by_name (m_contents);
461 *min_height = m_window->min_height ();
462 *max_height = m_window->max_height ();
463 }
464
465 /* See tui-layout.h. */
466
467 bool
468 tui_layout_window::top_boxed_p () const
469 {
470 gdb_assert (m_window != nullptr);
471 return m_window->can_box ();
472 }
473
474 /* See tui-layout.h. */
475
476 bool
477 tui_layout_window::bottom_boxed_p () const
478 {
479 gdb_assert (m_window != nullptr);
480 return m_window->can_box ();
481 }
482
483 /* See tui-layout.h. */
484
485 tui_layout_split *
486 tui_layout_split::add_split (int weight)
487 {
488 tui_layout_split *result = new tui_layout_split ();
489 split s = {weight, std::unique_ptr<tui_layout_base> (result)};
490 m_splits.push_back (std::move (s));
491 return result;
492 }
493
494 /* See tui-layout.h. */
495
496 void
497 tui_layout_split::add_window (const char *name, int weight)
498 {
499 tui_layout_window *result = new tui_layout_window (name);
500 split s = {weight, std::unique_ptr<tui_layout_base> (result)};
501 m_splits.push_back (std::move (s));
502 }
503
504 /* See tui-layout.h. */
505
506 std::unique_ptr<tui_layout_base>
507 tui_layout_split::clone () const
508 {
509 tui_layout_split *result = new tui_layout_split ();
510 for (const split &item : m_splits)
511 {
512 std::unique_ptr<tui_layout_base> next = item.layout->clone ();
513 split s = {item.weight, std::move (next)};
514 result->m_splits.push_back (std::move (s));
515 }
516 return std::unique_ptr<tui_layout_base> (result);
517 }
518
519 /* See tui-layout.h. */
520
521 void
522 tui_layout_split::get_sizes (int *min_height, int *max_height)
523 {
524 *min_height = 0;
525 *max_height = 0;
526 for (const split &item : m_splits)
527 {
528 int new_min, new_max;
529 item.layout->get_sizes (&new_min, &new_max);
530 *min_height += new_min;
531 *max_height += new_max;
532 }
533 }
534
535 /* See tui-layout.h. */
536
537 bool
538 tui_layout_split::top_boxed_p () const
539 {
540 if (m_splits.empty ())
541 return false;
542 return m_splits[0].layout->top_boxed_p ();
543 }
544
545 /* See tui-layout.h. */
546
547 bool
548 tui_layout_split::bottom_boxed_p () const
549 {
550 if (m_splits.empty ())
551 return false;
552 return m_splits.back ().layout->top_boxed_p ();
553 }
554
555 /* See tui-layout.h. */
556
557 void
558 tui_layout_split::set_weights_from_heights ()
559 {
560 for (int i = 0; i < m_splits.size (); ++i)
561 m_splits[i].weight = m_splits[i].layout->height;
562 }
563
564 /* See tui-layout.h. */
565
566 bool
567 tui_layout_split::adjust_size (const char *name, int new_height)
568 {
569 /* Look through the children. If one is a layout holding the named
570 window, we're done; or if one actually is the named window,
571 update it. */
572 int found_index = -1;
573 for (int i = 0; i < m_splits.size (); ++i)
574 {
575 if (m_splits[i].layout->adjust_size (name, new_height))
576 return true;
577 const char *win_name = m_splits[i].layout->get_name ();
578 if (win_name != nullptr && strcmp (name, win_name) == 0)
579 {
580 found_index = i;
581 break;
582 }
583 }
584
585 if (found_index == -1)
586 return false;
587 if (m_splits[found_index].layout->height == new_height)
588 return true;
589
590 set_weights_from_heights ();
591 int delta = m_splits[found_index].weight - new_height;
592 m_splits[found_index].weight = new_height;
593
594 /* Distribute the "delta" over the next window; but if the next
595 window cannot hold it all, keep going until we either find a
596 window that does, or until we loop all the way around. */
597 for (int i = 0; delta != 0 && i < m_splits.size () - 1; ++i)
598 {
599 int index = (found_index + 1 + i) % m_splits.size ();
600
601 int new_min, new_max;
602 m_splits[index].layout->get_sizes (&new_min, &new_max);
603
604 if (delta < 0)
605 {
606 /* The primary window grew, so we are trying to shrink other
607 windows. */
608 int available = m_splits[index].weight - new_min;
609 int shrink_by = std::min (available, -delta);
610 m_splits[index].weight -= shrink_by;
611 delta += shrink_by;
612 }
613 else
614 {
615 /* The primary window shrank, so we are trying to grow other
616 windows. */
617 int available = new_max - m_splits[index].weight;
618 int grow_by = std::min (available, delta);
619 m_splits[index].weight += grow_by;
620 delta -= grow_by;
621 }
622 }
623
624 if (delta != 0)
625 {
626 warning (_("Invalid window height specified"));
627 /* Effectively undo any modifications made here. */
628 set_weights_from_heights ();
629 }
630 else
631 {
632 /* Simply re-apply the updated layout. */
633 apply (x, y, width, height);
634 }
635
636 return true;
637 }
638
639 /* See tui-layout.h. */
640
641 void
642 tui_layout_split::apply (int x_, int y_, int width_, int height_)
643 {
644 x = x_;
645 y = y_;
646 width = width_;
647 height = height_;
648
649 struct height_info
650 {
651 int height;
652 int min_height;
653 int max_height;
654 /* True if this window will share a box border with the previous
655 window in the list. */
656 bool share_box;
657 };
658
659 std::vector<height_info> info (m_splits.size ());
660
661 /* Step 1: Find the min and max height of each sub-layout.
662 Fixed-sized layouts are given their desired height, and then the
663 remaining space is distributed among the remaining windows
664 according to the weights given. */
665 int available_height = height;
666 int last_index = -1;
667 int total_weight = 0;
668 for (int i = 0; i < m_splits.size (); ++i)
669 {
670 bool cmd_win_already_exists = TUI_CMD_WIN != nullptr;
671
672 /* Always call get_sizes, to ensure that the window is
673 instantiated. This is a bit gross but less gross than adding
674 special cases for this in other places. */
675 m_splits[i].layout->get_sizes (&info[i].min_height, &info[i].max_height);
676
677 if (!m_applied
678 && cmd_win_already_exists
679 && m_splits[i].layout->get_name () != nullptr
680 && strcmp (m_splits[i].layout->get_name (), "cmd") == 0)
681 {
682 /* If this layout has never been applied, then it means the
683 user just changed the layout. In this situation, it's
684 desirable to keep the size of the command window the
685 same. Setting the min and max heights this way ensures
686 that the resizing step, below, does the right thing with
687 this window. */
688 info[i].min_height = TUI_CMD_WIN->height;
689 info[i].max_height = TUI_CMD_WIN->height;
690 }
691
692 if (info[i].min_height == info[i].max_height)
693 available_height -= info[i].min_height;
694 else
695 {
696 last_index = i;
697 total_weight += m_splits[i].weight;
698 }
699
700 /* Two adjacent boxed windows will share a border, making a bit
701 more height available. */
702 if (i > 0
703 && m_splits[i - 1].layout->bottom_boxed_p ()
704 && m_splits[i].layout->top_boxed_p ())
705 info[i].share_box = true;
706 }
707
708 /* Step 2: Compute the height of each sub-layout. Fixed-sized items
709 are given their fixed size, while others are resized according to
710 their weight. */
711 int used_height = 0;
712 for (int i = 0; i < m_splits.size (); ++i)
713 {
714 /* Compute the height and clamp to the allowable range. */
715 info[i].height = available_height * m_splits[i].weight / total_weight;
716 if (info[i].height > info[i].max_height)
717 info[i].height = info[i].max_height;
718 if (info[i].height < info[i].min_height)
719 info[i].height = info[i].min_height;
720 /* If there is any leftover height, just redistribute it to the
721 last resizeable window, by dropping it from the allocated
722 height. We could try to be fancier here perhaps, by
723 redistributing this height among all windows, not just the
724 last window. */
725 if (info[i].min_height != info[i].max_height)
726 {
727 used_height += info[i].height;
728 if (info[i].share_box)
729 --used_height;
730 }
731 }
732
733 /* Allocate any leftover height. */
734 if (available_height >= used_height && last_index != -1)
735 info[last_index].height += available_height - used_height;
736
737 /* Step 3: Resize. */
738 int height_accum = 0;
739 for (int i = 0; i < m_splits.size (); ++i)
740 {
741 /* If we fall off the bottom, just make allocations overlap.
742 GIGO. */
743 if (height_accum + info[i].height > height)
744 height_accum = height - info[i].height;
745 else if (info[i].share_box)
746 --height_accum;
747 m_splits[i].layout->apply (x, y + height_accum, width, info[i].height);
748 height_accum += info[i].height;
749 }
750
751 m_applied = true;
752 }
753
754 static void
755 initialize_layouts ()
756 {
757 standard_layouts[SRC_COMMAND] = new tui_layout_split ();
758 standard_layouts[SRC_COMMAND]->add_window ("src", 2);
759 standard_layouts[SRC_COMMAND]->add_window ("locator", 0);
760 standard_layouts[SRC_COMMAND]->add_window ("cmd", 1);
761
762 standard_layouts[DISASSEM_COMMAND] = new tui_layout_split ();
763 standard_layouts[DISASSEM_COMMAND]->add_window ("asm", 2);
764 standard_layouts[DISASSEM_COMMAND]->add_window ("locator", 0);
765 standard_layouts[DISASSEM_COMMAND]->add_window ("cmd", 1);
766
767 standard_layouts[SRC_DATA_COMMAND] = new tui_layout_split ();
768 standard_layouts[SRC_DATA_COMMAND]->add_window ("regs", 1);
769 standard_layouts[SRC_DATA_COMMAND]->add_window ("src", 1);
770 standard_layouts[SRC_DATA_COMMAND]->add_window ("locator", 0);
771 standard_layouts[SRC_DATA_COMMAND]->add_window ("cmd", 1);
772
773 standard_layouts[DISASSEM_DATA_COMMAND] = new tui_layout_split ();
774 standard_layouts[DISASSEM_DATA_COMMAND]->add_window ("regs", 1);
775 standard_layouts[DISASSEM_DATA_COMMAND]->add_window ("asm", 1);
776 standard_layouts[DISASSEM_DATA_COMMAND]->add_window ("locator", 0);
777 standard_layouts[DISASSEM_DATA_COMMAND]->add_window ("cmd", 1);
778
779 standard_layouts[SRC_DISASSEM_COMMAND] = new tui_layout_split ();
780 standard_layouts[SRC_DISASSEM_COMMAND]->add_window ("src", 1);
781 standard_layouts[SRC_DISASSEM_COMMAND]->add_window ("asm", 1);
782 standard_layouts[SRC_DISASSEM_COMMAND]->add_window ("locator", 0);
783 standard_layouts[SRC_DISASSEM_COMMAND]->add_window ("cmd", 1);
784 }
785
786 \f
787
788 /* Function to initialize gdb commands, for tui window layout
789 manipulation. */
790
791 void _initialize_tui_layout ();
792 void
793 _initialize_tui_layout ()
794 {
795 struct cmd_list_element *cmd;
796
797 cmd = add_com ("layout", class_tui, tui_layout_command, _("\
798 Change the layout of windows.\n\
799 Usage: layout prev | next | LAYOUT-NAME\n\
800 Layout names are:\n\
801 src : Displays source and command windows.\n\
802 asm : Displays disassembly and command windows.\n\
803 split : Displays source, disassembly and command windows.\n\
804 regs : Displays register window. If existing layout\n\
805 is source/command or assembly/command, the \n\
806 register window is displayed. If the\n\
807 source/assembly/command (split) is displayed, \n\
808 the register window is displayed with \n\
809 the window that has current logical focus."));
810 set_cmd_completer (cmd, layout_completer);
811
812 initialize_layouts ();
813 }
This page took 0.046915 seconds and 5 git commands to generate.