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