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