]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/tui/tui-layout.c
92984b11a5f1f4dce7b5845bca1baca35f21ea20
[thirdparty/binutils-gdb.git] / gdb / tui / tui-layout.c
1 /* TUI layout window management.
2
3 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007
4 Free Software Foundation, Inc.
5
6 Contributed by Hewlett-Packard Company.
7
8 This file is part of GDB.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
22
23 #include "defs.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-data.h"
32 #include "tui/tui-windata.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
40 #include "gdb_string.h"
41 #include "gdb_curses.h"
42
43 /*******************************
44 ** Static Local Decls
45 ********************************/
46 static void show_layout (enum tui_layout_type);
47 static void init_gen_win_info (struct tui_gen_win_info *,
48 enum tui_win_type,
49 int, int, int, int);
50 static void *init_and_make_win (void *, enum tui_win_type,
51 int, int, int, int, int);
52 static void show_source_or_disasm_and_command (enum tui_layout_type);
53 static void make_source_or_disasm_window (struct tui_win_info **,
54 enum tui_win_type,
55 int, int);
56 static void make_command_window (struct tui_win_info **, int, int);
57 static void make_source_window (struct tui_win_info **, int, int);
58 static void make_disasm_window (struct tui_win_info **, int, int);
59 static void make_data_window (struct tui_win_info **, int, int);
60 static void show_source_command (void);
61 static void show_disasm_command (void);
62 static void show_source_disasm_command (void);
63 static void show_data (enum tui_layout_type);
64 static enum tui_layout_type next_layout (void);
65 static enum tui_layout_type prev_layout (void);
66 static void tui_layout_command (char *, int);
67 static void tui_toggle_layout_command (char *, int);
68 static void tui_toggle_split_layout_command (char *, int);
69 static CORE_ADDR extract_display_start_addr (void);
70 static void tui_handle_xdb_layout (struct tui_layout_def *);
71
72
73 /***************************************
74 ** DEFINITIONS
75 ***************************************/
76
77 #define LAYOUT_USAGE "Usage: layout prev | next | <layout_name> \n"
78
79 /* Show the screen layout defined. */
80 static void
81 show_layout (enum tui_layout_type layout)
82 {
83 enum tui_layout_type cur_layout = tui_current_layout ();
84
85 if (layout != cur_layout)
86 {
87 /* Since the new layout may cause changes in window size, we
88 should free the content and reallocate on next display of
89 source/asm. */
90 tui_free_all_source_wins_content ();
91 tui_clear_source_windows ();
92 if (layout == SRC_DATA_COMMAND
93 || layout == DISASSEM_DATA_COMMAND)
94 {
95 show_data (layout);
96 tui_refresh_all (tui_win_list);
97 }
98 else
99 {
100 /* First make the current layout be invisible. */
101 tui_make_all_invisible ();
102 tui_make_invisible (tui_locator_win_info_ptr ());
103
104 switch (layout)
105 {
106 /* Now show the new layout. */
107 case SRC_COMMAND:
108 show_source_command ();
109 tui_add_to_source_windows (TUI_SRC_WIN);
110 break;
111 case DISASSEM_COMMAND:
112 show_disasm_command ();
113 tui_add_to_source_windows (TUI_DISASM_WIN);
114 break;
115 case SRC_DISASSEM_COMMAND:
116 show_source_disasm_command ();
117 tui_add_to_source_windows (TUI_SRC_WIN);
118 tui_add_to_source_windows (TUI_DISASM_WIN);
119 break;
120 default:
121 break;
122 }
123 }
124 }
125 }
126
127
128 /* Function to set the layout to SRC_COMMAND, DISASSEM_COMMAND,
129 SRC_DISASSEM_COMMAND, SRC_DATA_COMMAND, or DISASSEM_DATA_COMMAND.
130 If the layout is SRC_DATA_COMMAND, DISASSEM_DATA_COMMAND, or
131 UNDEFINED_LAYOUT, then the data window is populated according to
132 regs_display_type. */
133 enum tui_status
134 tui_set_layout (enum tui_layout_type layout_type,
135 enum tui_register_display_type regs_display_type)
136 {
137 enum tui_status status = TUI_SUCCESS;
138
139 if (layout_type != UNDEFINED_LAYOUT
140 || regs_display_type != TUI_UNDEFINED_REGS)
141 {
142 enum tui_layout_type cur_layout = tui_current_layout (),
143 new_layout = UNDEFINED_LAYOUT;
144 int regs_populate = FALSE;
145 CORE_ADDR addr = extract_display_start_addr ();
146 struct tui_win_info *win_with_focus = tui_win_with_focus ();
147 struct tui_layout_def *layout_def = tui_layout_def ();
148
149
150 if (layout_type == UNDEFINED_LAYOUT
151 && regs_display_type != TUI_UNDEFINED_REGS)
152 {
153 if (cur_layout == SRC_DISASSEM_COMMAND)
154 new_layout = DISASSEM_DATA_COMMAND;
155 else if (cur_layout == SRC_COMMAND
156 || cur_layout == SRC_DATA_COMMAND)
157 new_layout = SRC_DATA_COMMAND;
158 else if (cur_layout == DISASSEM_COMMAND
159 || cur_layout == DISASSEM_DATA_COMMAND)
160 new_layout = DISASSEM_DATA_COMMAND;
161 }
162 else
163 new_layout = layout_type;
164
165 regs_populate = (new_layout == SRC_DATA_COMMAND
166 || new_layout == DISASSEM_DATA_COMMAND
167 || regs_display_type != TUI_UNDEFINED_REGS);
168 if (new_layout != cur_layout
169 || regs_display_type != TUI_UNDEFINED_REGS)
170 {
171 if (new_layout != cur_layout)
172 {
173 show_layout (new_layout);
174
175 /* Now determine where focus should be. */
176 if (win_with_focus != TUI_CMD_WIN)
177 {
178 switch (new_layout)
179 {
180 case SRC_COMMAND:
181 tui_set_win_focus_to (TUI_SRC_WIN);
182 layout_def->display_mode = SRC_WIN;
183 layout_def->split = FALSE;
184 break;
185 case DISASSEM_COMMAND:
186 /* The previous layout was not showing code.
187 This can happen if there is no source
188 available:
189
190 1. if the source file is in another dir OR
191 2. if target was compiled without -g
192 We still want to show the assembly though! */
193
194 addr = tui_get_begin_asm_address ();
195 tui_set_win_focus_to (TUI_DISASM_WIN);
196 layout_def->display_mode = DISASSEM_WIN;
197 layout_def->split = FALSE;
198 break;
199 case SRC_DISASSEM_COMMAND:
200 /* The previous layout was not showing code.
201 This can happen if there is no source
202 available:
203
204 1. if the source file is in another dir OR
205 2. if target was compiled without -g
206 We still want to show the assembly though! */
207
208 addr = tui_get_begin_asm_address ();
209 if (win_with_focus == TUI_SRC_WIN)
210 tui_set_win_focus_to (TUI_SRC_WIN);
211 else
212 tui_set_win_focus_to (TUI_DISASM_WIN);
213 layout_def->split = TRUE;
214 break;
215 case SRC_DATA_COMMAND:
216 if (win_with_focus != TUI_DATA_WIN)
217 tui_set_win_focus_to (TUI_SRC_WIN);
218 else
219 tui_set_win_focus_to (TUI_DATA_WIN);
220 layout_def->display_mode = SRC_WIN;
221 layout_def->split = FALSE;
222 break;
223 case DISASSEM_DATA_COMMAND:
224 /* The previous layout was not showing code.
225 This can happen if there is no source
226 available:
227
228 1. if the source file is in another dir OR
229 2. if target was compiled without -g
230 We still want to show the assembly though! */
231
232 addr = tui_get_begin_asm_address ();
233 if (win_with_focus != TUI_DATA_WIN)
234 tui_set_win_focus_to (TUI_DISASM_WIN);
235 else
236 tui_set_win_focus_to (TUI_DATA_WIN);
237 layout_def->display_mode = DISASSEM_WIN;
238 layout_def->split = FALSE;
239 break;
240 default:
241 break;
242 }
243 }
244 /*
245 * Now update the window content.
246 */
247 if (!regs_populate
248 && (new_layout == SRC_DATA_COMMAND
249 || new_layout == DISASSEM_DATA_COMMAND))
250 tui_display_all_data ();
251
252 tui_update_source_windows_with_addr (addr);
253 }
254 if (regs_populate)
255 {
256 tui_show_registers (TUI_DATA_WIN->detail.data_display_info.current_group);
257 }
258 }
259 }
260 else
261 status = TUI_FAILURE;
262
263 return status;
264 }
265
266 /* Add the specified window to the layout in a logical way. This
267 means setting up the most logical layout given the window to be
268 added. */
269 void
270 tui_add_win_to_layout (enum tui_win_type type)
271 {
272 enum tui_layout_type cur_layout = tui_current_layout ();
273
274 switch (type)
275 {
276 case SRC_WIN:
277 if (cur_layout != SRC_COMMAND
278 && cur_layout != SRC_DISASSEM_COMMAND
279 && cur_layout != SRC_DATA_COMMAND)
280 {
281 tui_clear_source_windows_detail ();
282 if (cur_layout == DISASSEM_DATA_COMMAND)
283 show_layout (SRC_DATA_COMMAND);
284 else
285 show_layout (SRC_COMMAND);
286 }
287 break;
288 case DISASSEM_WIN:
289 if (cur_layout != DISASSEM_COMMAND
290 && cur_layout != SRC_DISASSEM_COMMAND
291 && cur_layout != DISASSEM_DATA_COMMAND)
292 {
293 tui_clear_source_windows_detail ();
294 if (cur_layout == SRC_DATA_COMMAND)
295 show_layout (DISASSEM_DATA_COMMAND);
296 else
297 show_layout (DISASSEM_COMMAND);
298 }
299 break;
300 case DATA_WIN:
301 if (cur_layout != SRC_DATA_COMMAND
302 && cur_layout != DISASSEM_DATA_COMMAND)
303 {
304 if (cur_layout == DISASSEM_COMMAND)
305 show_layout (DISASSEM_DATA_COMMAND);
306 else
307 show_layout (SRC_DATA_COMMAND);
308 }
309 break;
310 default:
311 break;
312 }
313 }
314
315
316 /* Answer the height of a window. If it hasn't been created yet,
317 answer what the height of a window would be based upon its type and
318 the layout. */
319 int
320 tui_default_win_height (enum tui_win_type type,
321 enum tui_layout_type layout)
322 {
323 int h;
324
325 if (tui_win_list[type] != (struct tui_win_info *) NULL)
326 h = tui_win_list[type]->generic.height;
327 else
328 {
329 switch (layout)
330 {
331 case SRC_COMMAND:
332 case DISASSEM_COMMAND:
333 if (TUI_CMD_WIN == NULL)
334 h = tui_term_height () / 2;
335 else
336 h = tui_term_height () - TUI_CMD_WIN->generic.height;
337 break;
338 case SRC_DISASSEM_COMMAND:
339 case SRC_DATA_COMMAND:
340 case DISASSEM_DATA_COMMAND:
341 if (TUI_CMD_WIN == NULL)
342 h = tui_term_height () / 3;
343 else
344 h = (tui_term_height () - TUI_CMD_WIN->generic.height) / 2;
345 break;
346 default:
347 h = 0;
348 break;
349 }
350 }
351
352 return h;
353 }
354
355
356 /* Answer the height of a window. If it hasn't been created yet,
357 answer what the height of a window would be based upon its type and
358 the layout. */
359 int
360 tui_default_win_viewport_height (enum tui_win_type type,
361 enum tui_layout_type layout)
362 {
363 int h;
364
365 h = tui_default_win_height (type, layout);
366
367 if (tui_win_list[type] == TUI_CMD_WIN)
368 h -= 1;
369 else
370 h -= 2;
371
372 return h;
373 }
374
375
376 /* Function to initialize gdb commands, for tui window layout
377 manipulation. */
378 void
379 _initialize_tui_layout (void)
380 {
381 add_com ("layout", class_tui, tui_layout_command, _("\
382 Change the layout of windows.\n\
383 Usage: layout prev | next | <layout_name> \n\
384 Layout names are:\n\
385 src : Displays source and command windows.\n\
386 asm : Displays disassembly and command windows.\n\
387 split : Displays source, disassembly and command windows.\n\
388 regs : Displays register window. If existing layout\n\
389 is source/command or assembly/command, the \n\
390 register window is displayed. If the\n\
391 source/assembly/command (split) is displayed, \n\
392 the register window is displayed with \n\
393 the window that has current logical focus.\n"));
394 if (xdb_commands)
395 {
396 add_com ("td", class_tui, tui_toggle_layout_command, _("\
397 Toggle between Source/Command and Disassembly/Command layouts.\n"));
398 add_com ("ts", class_tui, tui_toggle_split_layout_command, _("\
399 Toggle between Source/Command or Disassembly/Command and \n\
400 Source/Disassembly/Command layouts.\n"));
401 }
402 }
403
404
405 /*************************
406 ** STATIC LOCAL FUNCTIONS
407 **************************/
408
409
410 /* Function to set the layout to SRC, ASM, SPLIT, NEXT, PREV, DATA,
411 REGS, $REGS, $GREGS, $FREGS, $SREGS. */
412 enum tui_status
413 tui_set_layout_for_display_command (const char *layout_name)
414 {
415 enum tui_status status = TUI_SUCCESS;
416
417 if (layout_name != (char *) NULL)
418 {
419 int i;
420 char *buf_ptr;
421 enum tui_layout_type new_layout = UNDEFINED_LAYOUT;
422 enum tui_register_display_type dpy_type = TUI_UNDEFINED_REGS;
423 enum tui_layout_type cur_layout = tui_current_layout ();
424
425 buf_ptr = (char *) xstrdup (layout_name);
426 for (i = 0; (i < strlen (layout_name)); i++)
427 buf_ptr[i] = toupper (buf_ptr[i]);
428
429 /* First check for ambiguous input. */
430 if (strlen (buf_ptr) <= 1
431 && (*buf_ptr == 'S' || *buf_ptr == '$'))
432 {
433 warning (_("Ambiguous command input."));
434 status = TUI_FAILURE;
435 }
436 else
437 {
438 if (subset_compare (buf_ptr, "SRC"))
439 new_layout = SRC_COMMAND;
440 else if (subset_compare (buf_ptr, "ASM"))
441 new_layout = DISASSEM_COMMAND;
442 else if (subset_compare (buf_ptr, "SPLIT"))
443 new_layout = SRC_DISASSEM_COMMAND;
444 else if (subset_compare (buf_ptr, "REGS")
445 || subset_compare (buf_ptr, TUI_GENERAL_SPECIAL_REGS_NAME)
446 || subset_compare (buf_ptr, TUI_GENERAL_REGS_NAME)
447 || subset_compare (buf_ptr, TUI_FLOAT_REGS_NAME)
448 || subset_compare (buf_ptr, TUI_SPECIAL_REGS_NAME))
449 {
450 if (cur_layout == SRC_COMMAND
451 || cur_layout == SRC_DATA_COMMAND)
452 new_layout = SRC_DATA_COMMAND;
453 else
454 new_layout = DISASSEM_DATA_COMMAND;
455
456 /* Could ifdef out the following code. when compile with
457 -z, there are null pointer references that cause a
458 core dump if 'layout regs' is the first layout
459 command issued by the user. HP has asked us to hook
460 up this code. - edie epstein */
461 if (subset_compare (buf_ptr, TUI_FLOAT_REGS_NAME))
462 {
463 if (TUI_DATA_WIN->detail.data_display_info.regs_display_type != TUI_SFLOAT_REGS
464 && TUI_DATA_WIN->detail.data_display_info.regs_display_type != TUI_DFLOAT_REGS)
465 dpy_type = TUI_SFLOAT_REGS;
466 else
467 dpy_type =
468 TUI_DATA_WIN->detail.data_display_info.regs_display_type;
469 }
470 else if (subset_compare (buf_ptr,
471 TUI_GENERAL_SPECIAL_REGS_NAME))
472 dpy_type = TUI_GENERAL_AND_SPECIAL_REGS;
473 else if (subset_compare (buf_ptr, TUI_GENERAL_REGS_NAME))
474 dpy_type = TUI_GENERAL_REGS;
475 else if (subset_compare (buf_ptr, TUI_SPECIAL_REGS_NAME))
476 dpy_type = TUI_SPECIAL_REGS;
477 else if (TUI_DATA_WIN)
478 {
479 if (TUI_DATA_WIN->detail.data_display_info.regs_display_type !=
480 TUI_UNDEFINED_REGS)
481 dpy_type =
482 TUI_DATA_WIN->detail.data_display_info.regs_display_type;
483 else
484 dpy_type = TUI_GENERAL_REGS;
485 }
486
487 /* End of potential ifdef.
488 */
489
490 /* If ifdefed out code above, then assume that the user
491 wishes to display the general purpose registers .
492 */
493
494 /* dpy_type = TUI_GENERAL_REGS; */
495 }
496 else if (subset_compare (buf_ptr, "NEXT"))
497 new_layout = next_layout ();
498 else if (subset_compare (buf_ptr, "PREV"))
499 new_layout = prev_layout ();
500 else
501 status = TUI_FAILURE;
502
503 tui_set_layout (new_layout, dpy_type);
504 }
505 xfree (buf_ptr);
506 }
507 else
508 status = TUI_FAILURE;
509
510 return status;
511 }
512
513
514 static CORE_ADDR
515 extract_display_start_addr (void)
516 {
517 enum tui_layout_type cur_layout = tui_current_layout ();
518 CORE_ADDR addr;
519 CORE_ADDR pc;
520 struct symtab_and_line cursal = get_current_source_symtab_and_line ();
521
522 switch (cur_layout)
523 {
524 case SRC_COMMAND:
525 case SRC_DATA_COMMAND:
526 find_line_pc (cursal.symtab,
527 TUI_SRC_WIN->detail.source_info.start_line_or_addr.u.line_no,
528 &pc);
529 addr = pc;
530 break;
531 case DISASSEM_COMMAND:
532 case SRC_DISASSEM_COMMAND:
533 case DISASSEM_DATA_COMMAND:
534 addr = TUI_DISASM_WIN->detail.source_info.start_line_or_addr.u.addr;
535 break;
536 default:
537 addr = 0;
538 break;
539 }
540
541 return addr;
542 }
543
544
545 static void
546 tui_handle_xdb_layout (struct tui_layout_def *layout_def)
547 {
548 if (layout_def->split)
549 {
550 tui_set_layout (SRC_DISASSEM_COMMAND, TUI_UNDEFINED_REGS);
551 tui_set_win_focus_to (tui_win_list[layout_def->display_mode]);
552 }
553 else
554 {
555 if (layout_def->display_mode == SRC_WIN)
556 tui_set_layout (SRC_COMMAND, TUI_UNDEFINED_REGS);
557 else
558 tui_set_layout (DISASSEM_DATA_COMMAND, layout_def->regs_display_type);
559 }
560 }
561
562
563 static void
564 tui_toggle_layout_command (char *arg, int from_tty)
565 {
566 struct tui_layout_def *layout_def = tui_layout_def ();
567
568 /* Make sure the curses mode is enabled. */
569 tui_enable ();
570 if (layout_def->display_mode == SRC_WIN)
571 layout_def->display_mode = DISASSEM_WIN;
572 else
573 layout_def->display_mode = SRC_WIN;
574
575 if (!layout_def->split)
576 tui_handle_xdb_layout (layout_def);
577 }
578
579
580 static void
581 tui_toggle_split_layout_command (char *arg, int from_tty)
582 {
583 struct tui_layout_def *layout_def = tui_layout_def ();
584
585 /* Make sure the curses mode is enabled. */
586 tui_enable ();
587 layout_def->split = (!layout_def->split);
588 tui_handle_xdb_layout (layout_def);
589 }
590
591
592 static void
593 tui_layout_command (char *arg, int from_tty)
594 {
595 /* Make sure the curses mode is enabled. */
596 tui_enable ();
597
598 /* Switch to the selected layout. */
599 if (tui_set_layout_for_display_command (arg) != TUI_SUCCESS)
600 warning (_("Invalid layout specified.\n%s"), LAYOUT_USAGE);
601
602 }
603
604 /* Answer the previous layout to cycle to. */
605 static enum tui_layout_type
606 next_layout (void)
607 {
608 enum tui_layout_type new_layout;
609
610 new_layout = tui_current_layout ();
611 if (new_layout == UNDEFINED_LAYOUT)
612 new_layout = SRC_COMMAND;
613 else
614 {
615 new_layout++;
616 if (new_layout == UNDEFINED_LAYOUT)
617 new_layout = SRC_COMMAND;
618 }
619
620 return new_layout;
621 }
622
623
624 /* Answer the next layout to cycle to. */
625 static enum tui_layout_type
626 prev_layout (void)
627 {
628 enum tui_layout_type new_layout;
629
630 new_layout = tui_current_layout ();
631 if (new_layout == SRC_COMMAND)
632 new_layout = DISASSEM_DATA_COMMAND;
633 else
634 {
635 new_layout--;
636 if (new_layout == UNDEFINED_LAYOUT)
637 new_layout = DISASSEM_DATA_COMMAND;
638 }
639
640 return new_layout;
641 }
642
643
644
645 static void
646 make_command_window (struct tui_win_info **win_info_ptr,
647 int height, int origin_y)
648 {
649 *win_info_ptr = init_and_make_win (*win_info_ptr,
650 CMD_WIN,
651 height,
652 tui_term_width (),
653 0,
654 origin_y,
655 DONT_BOX_WINDOW);
656
657 (*win_info_ptr)->can_highlight = FALSE;
658 }
659
660
661 /* make_source_window().
662 */
663 static void
664 make_source_window (struct tui_win_info **win_info_ptr,
665 int height, int origin_y)
666 {
667 make_source_or_disasm_window (win_info_ptr, SRC_WIN, height, origin_y);
668
669 return;
670 } /* make_source_window */
671
672
673 /* make_disasm_window().
674 */
675 static void
676 make_disasm_window (struct tui_win_info **win_info_ptr,
677 int height, int origin_y)
678 {
679 make_source_or_disasm_window (win_info_ptr, DISASSEM_WIN, height, origin_y);
680
681 return;
682 } /* make_disasm_window */
683
684
685 static void
686 make_data_window (struct tui_win_info **win_info_ptr,
687 int height, int origin_y)
688 {
689 *win_info_ptr = init_and_make_win (*win_info_ptr,
690 DATA_WIN,
691 height,
692 tui_term_width (),
693 0,
694 origin_y,
695 BOX_WINDOW);
696 }
697
698
699
700 /* Show the Source/Command layout. */
701 static void
702 show_source_command (void)
703 {
704 show_source_or_disasm_and_command (SRC_COMMAND);
705 }
706
707
708 /* Show the Dissassem/Command layout. */
709 static void
710 show_disasm_command (void)
711 {
712 show_source_or_disasm_and_command (DISASSEM_COMMAND);
713 }
714
715
716 /* Show the Source/Disassem/Command layout. */
717 static void
718 show_source_disasm_command (void)
719 {
720 if (tui_current_layout () != SRC_DISASSEM_COMMAND)
721 {
722 int cmd_height, src_height, asm_height;
723
724 if (TUI_CMD_WIN != NULL)
725 cmd_height = TUI_CMD_WIN->generic.height;
726 else
727 cmd_height = tui_term_height () / 3;
728
729 src_height = (tui_term_height () - cmd_height) / 2;
730 asm_height = tui_term_height () - (src_height + cmd_height);
731
732 if (TUI_SRC_WIN == NULL)
733 make_source_window (&TUI_SRC_WIN, src_height, 0);
734 else
735 {
736 init_gen_win_info (&TUI_SRC_WIN->generic,
737 TUI_SRC_WIN->generic.type,
738 src_height,
739 TUI_SRC_WIN->generic.width,
740 TUI_SRC_WIN->detail.source_info.execution_info->width,
741 0);
742 TUI_SRC_WIN->can_highlight = TRUE;
743 init_gen_win_info (TUI_SRC_WIN->detail.source_info.execution_info,
744 EXEC_INFO_WIN,
745 src_height,
746 3,
747 0,
748 0);
749 tui_make_visible (&TUI_SRC_WIN->generic);
750 tui_make_visible (TUI_SRC_WIN->detail.source_info.execution_info);
751 TUI_SRC_WIN->detail.source_info.has_locator = FALSE;;
752 }
753 if (TUI_SRC_WIN != NULL)
754 {
755 struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
756
757 tui_show_source_content (TUI_SRC_WIN);
758 if (TUI_DISASM_WIN == NULL)
759 {
760 make_disasm_window (&TUI_DISASM_WIN, asm_height, src_height - 1);
761 locator = init_and_make_win (locator,
762 LOCATOR_WIN,
763 2 /* 1 */ ,
764 tui_term_width (),
765 0,
766 (src_height + asm_height) - 1,
767 DONT_BOX_WINDOW);
768 }
769 else
770 {
771 init_gen_win_info (locator,
772 LOCATOR_WIN,
773 2 /* 1 */ ,
774 tui_term_width (),
775 0,
776 (src_height + asm_height) - 1);
777 TUI_DISASM_WIN->detail.source_info.has_locator = TRUE;
778 init_gen_win_info (&TUI_DISASM_WIN->generic,
779 TUI_DISASM_WIN->generic.type,
780 asm_height,
781 TUI_DISASM_WIN->generic.width,
782 TUI_DISASM_WIN->detail.source_info.execution_info->width,
783 src_height - 1);
784 init_gen_win_info (TUI_DISASM_WIN->detail.source_info.execution_info,
785 EXEC_INFO_WIN,
786 asm_height,
787 3,
788 0,
789 src_height - 1);
790 TUI_DISASM_WIN->can_highlight = TRUE;
791 tui_make_visible (&TUI_DISASM_WIN->generic);
792 tui_make_visible (TUI_DISASM_WIN->detail.source_info.execution_info);
793 }
794 if (TUI_DISASM_WIN != NULL)
795 {
796 TUI_SRC_WIN->detail.source_info.has_locator = FALSE;
797 TUI_DISASM_WIN->detail.source_info.has_locator = TRUE;
798 tui_make_visible (locator);
799 tui_show_locator_content ();
800 tui_show_source_content (TUI_DISASM_WIN);
801
802 if (TUI_CMD_WIN == NULL)
803 make_command_window (&TUI_CMD_WIN,
804 cmd_height,
805 tui_term_height () - cmd_height);
806 else
807 {
808 init_gen_win_info (&TUI_CMD_WIN->generic,
809 TUI_CMD_WIN->generic.type,
810 TUI_CMD_WIN->generic.height,
811 TUI_CMD_WIN->generic.width,
812 0,
813 TUI_CMD_WIN->generic.origin.y);
814 TUI_CMD_WIN->can_highlight = FALSE;
815 tui_make_visible (&TUI_CMD_WIN->generic);
816 }
817 if (TUI_CMD_WIN != NULL)
818 tui_refresh_win (&TUI_CMD_WIN->generic);
819 }
820 }
821 tui_set_current_layout_to (SRC_DISASSEM_COMMAND);
822 }
823 }
824
825
826 /* Show the Source/Data/Command or the Dissassembly/Data/Command
827 layout. */
828 static void
829 show_data (enum tui_layout_type new_layout)
830 {
831 int total_height = (tui_term_height () - TUI_CMD_WIN->generic.height);
832 int src_height, data_height;
833 enum tui_win_type win_type;
834 struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
835
836
837 data_height = total_height / 2;
838 src_height = total_height - data_height;
839 tui_make_all_invisible ();
840 tui_make_invisible (locator);
841 make_data_window (&TUI_DATA_WIN, data_height, 0);
842 TUI_DATA_WIN->can_highlight = TRUE;
843 if (new_layout == SRC_DATA_COMMAND)
844 win_type = SRC_WIN;
845 else
846 win_type = DISASSEM_WIN;
847 if (tui_win_list[win_type] == NULL)
848 {
849 if (win_type == SRC_WIN)
850 make_source_window (&tui_win_list[win_type], src_height, data_height - 1);
851 else
852 make_disasm_window (&tui_win_list[win_type], src_height, data_height - 1);
853 locator = init_and_make_win (locator,
854 LOCATOR_WIN,
855 2 /* 1 */ ,
856 tui_term_width (),
857 0,
858 total_height - 1,
859 DONT_BOX_WINDOW);
860 }
861 else
862 {
863 init_gen_win_info (&tui_win_list[win_type]->generic,
864 tui_win_list[win_type]->generic.type,
865 src_height,
866 tui_win_list[win_type]->generic.width,
867 tui_win_list[win_type]->detail.source_info.execution_info->width,
868 data_height - 1);
869 init_gen_win_info (tui_win_list[win_type]->detail.source_info.execution_info,
870 EXEC_INFO_WIN,
871 src_height,
872 3,
873 0,
874 data_height - 1);
875 tui_make_visible (&tui_win_list[win_type]->generic);
876 tui_make_visible (tui_win_list[win_type]->detail.source_info.execution_info);
877 init_gen_win_info (locator,
878 LOCATOR_WIN,
879 2 /* 1 */ ,
880 tui_term_width (),
881 0,
882 total_height - 1);
883 }
884 tui_win_list[win_type]->detail.source_info.has_locator = TRUE;
885 tui_make_visible (locator);
886 tui_show_locator_content ();
887 tui_add_to_source_windows (tui_win_list[win_type]);
888 tui_set_current_layout_to (new_layout);
889 }
890
891 /* init_gen_win_info().
892 */
893 static void
894 init_gen_win_info (struct tui_gen_win_info *win_info,
895 enum tui_win_type type,
896 int height, int width,
897 int origin_x, int origin_y)
898 {
899 int h = height;
900
901 win_info->type = type;
902 win_info->width = width;
903 win_info->height = h;
904 if (h > 1)
905 {
906 win_info->viewport_height = h - 1;
907 if (win_info->type != CMD_WIN)
908 win_info->viewport_height--;
909 }
910 else
911 win_info->viewport_height = 1;
912 win_info->origin.x = origin_x;
913 win_info->origin.y = origin_y;
914
915 return;
916 } /* init_gen_win_info */
917
918 /* init_and_make_win().
919 */
920 static void *
921 init_and_make_win (void *opaque_win_info,
922 enum tui_win_type win_type,
923 int height, int width,
924 int origin_x, int origin_y,
925 int box_it)
926 {
927 struct tui_gen_win_info *generic;
928
929 if (opaque_win_info == NULL)
930 {
931 if (tui_win_is_auxillary (win_type))
932 opaque_win_info = (void *) tui_alloc_generic_win_info ();
933 else
934 opaque_win_info = (void *) tui_alloc_win_info (win_type);
935 }
936 if (tui_win_is_auxillary (win_type))
937 generic = (struct tui_gen_win_info *) opaque_win_info;
938 else
939 generic = &((struct tui_win_info *) opaque_win_info)->generic;
940
941 if (opaque_win_info != NULL)
942 {
943 init_gen_win_info (generic, win_type, height, width, origin_x, origin_y);
944 if (!tui_win_is_auxillary (win_type))
945 {
946 if (generic->type == CMD_WIN)
947 ((struct tui_win_info *) opaque_win_info)->can_highlight = FALSE;
948 else
949 ((struct tui_win_info *) opaque_win_info)->can_highlight = TRUE;
950 }
951 tui_make_window (generic, box_it);
952 }
953 return opaque_win_info;
954 }
955
956
957 static void
958 make_source_or_disasm_window (struct tui_win_info **win_info_ptr,
959 enum tui_win_type type,
960 int height, int origin_y)
961 {
962 struct tui_gen_win_info *execution_info = (struct tui_gen_win_info *) NULL;
963
964 /* Create the exeuction info window. */
965 if (type == SRC_WIN)
966 execution_info = tui_source_exec_info_win_ptr ();
967 else
968 execution_info = tui_disassem_exec_info_win_ptr ();
969 execution_info = init_and_make_win (execution_info,
970 EXEC_INFO_WIN,
971 height,
972 3,
973 0,
974 origin_y,
975 DONT_BOX_WINDOW);
976
977 /* Now create the source window. */
978 *win_info_ptr = init_and_make_win (*win_info_ptr,
979 type,
980 height,
981 tui_term_width () - execution_info->width,
982 execution_info->width,
983 origin_y,
984 BOX_WINDOW);
985
986 (*win_info_ptr)->detail.source_info.execution_info = execution_info;
987 }
988
989
990 /* Show the Source/Command or the Disassem layout. */
991 static void
992 show_source_or_disasm_and_command (enum tui_layout_type layout_type)
993 {
994 if (tui_current_layout () != layout_type)
995 {
996 struct tui_win_info **win_info_ptr;
997 int src_height, cmd_height;
998 struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
999
1000 if (TUI_CMD_WIN != NULL)
1001 cmd_height = TUI_CMD_WIN->generic.height;
1002 else
1003 cmd_height = tui_term_height () / 3;
1004 src_height = tui_term_height () - cmd_height;
1005
1006 if (layout_type == SRC_COMMAND)
1007 win_info_ptr = &TUI_SRC_WIN;
1008 else
1009 win_info_ptr = &TUI_DISASM_WIN;
1010
1011 if ((*win_info_ptr) == NULL)
1012 {
1013 if (layout_type == SRC_COMMAND)
1014 make_source_window (win_info_ptr, src_height - 1, 0);
1015 else
1016 make_disasm_window (win_info_ptr, src_height - 1, 0);
1017 locator = init_and_make_win (locator,
1018 LOCATOR_WIN,
1019 2 /* 1 */ ,
1020 tui_term_width (),
1021 0,
1022 src_height - 1,
1023 DONT_BOX_WINDOW);
1024 }
1025 else
1026 {
1027 init_gen_win_info (locator,
1028 LOCATOR_WIN,
1029 2 /* 1 */ ,
1030 tui_term_width (),
1031 0,
1032 src_height - 1);
1033 (*win_info_ptr)->detail.source_info.has_locator = TRUE;
1034 init_gen_win_info (&(*win_info_ptr)->generic,
1035 (*win_info_ptr)->generic.type,
1036 src_height - 1,
1037 (*win_info_ptr)->generic.width,
1038 (*win_info_ptr)->detail.source_info.execution_info->width,
1039 0);
1040 init_gen_win_info ((*win_info_ptr)->detail.source_info.execution_info,
1041 EXEC_INFO_WIN,
1042 src_height - 1,
1043 3,
1044 0,
1045 0);
1046 (*win_info_ptr)->can_highlight = TRUE;
1047 tui_make_visible (&(*win_info_ptr)->generic);
1048 tui_make_visible ((*win_info_ptr)->detail.source_info.execution_info);
1049 }
1050 if ((*win_info_ptr) != NULL)
1051 {
1052 (*win_info_ptr)->detail.source_info.has_locator = TRUE;
1053 tui_make_visible (locator);
1054 tui_show_locator_content ();
1055 tui_show_source_content (*win_info_ptr);
1056
1057 if (TUI_CMD_WIN == NULL)
1058 {
1059 make_command_window (&TUI_CMD_WIN, cmd_height, src_height);
1060 tui_refresh_win (&TUI_CMD_WIN->generic);
1061 }
1062 else
1063 {
1064 init_gen_win_info (&TUI_CMD_WIN->generic,
1065 TUI_CMD_WIN->generic.type,
1066 TUI_CMD_WIN->generic.height,
1067 TUI_CMD_WIN->generic.width,
1068 TUI_CMD_WIN->generic.origin.x,
1069 TUI_CMD_WIN->generic.origin.y);
1070 TUI_CMD_WIN->can_highlight = FALSE;
1071 tui_make_visible (&TUI_CMD_WIN->generic);
1072 }
1073 }
1074 tui_set_current_layout_to (layout_type);
1075 }
1076 }