1 /* TUI layout window management. 2 3 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009 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 #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 != TUI_SFLOAT_REGS 471 && TUI_DATA_WIN->detail.data_display_info.regs_display_type != TUI_DFLOAT_REGS) 472 dpy_type = TUI_SFLOAT_REGS; 473 else 474 dpy_type = 475 TUI_DATA_WIN->detail.data_display_info.regs_display_type; 476 } 477 else if (subset_compare (buf_ptr, 478 TUI_GENERAL_SPECIAL_REGS_NAME)) 479 dpy_type = TUI_GENERAL_AND_SPECIAL_REGS; 480 else if (subset_compare (buf_ptr, TUI_GENERAL_REGS_NAME)) 481 dpy_type = TUI_GENERAL_REGS; 482 else if (subset_compare (buf_ptr, TUI_SPECIAL_REGS_NAME)) 483 dpy_type = TUI_SPECIAL_REGS; 484 else if (TUI_DATA_WIN) 485 { 486 if (TUI_DATA_WIN->detail.data_display_info.regs_display_type != 487 TUI_UNDEFINED_REGS) 488 dpy_type = 489 TUI_DATA_WIN->detail.data_display_info.regs_display_type; 490 else 491 dpy_type = TUI_GENERAL_REGS; 492 } 493 494 /* End of potential ifdef. 495 */ 496 497 /* If ifdefed out code above, then assume that the user 498 wishes to display the general purpose registers . 499 */ 500 501 /* dpy_type = TUI_GENERAL_REGS; */ 502 } 503 else if (subset_compare (buf_ptr, "NEXT")) 504 new_layout = next_layout (); 505 else if (subset_compare (buf_ptr, "PREV")) 506 new_layout = prev_layout (); 507 else 508 status = TUI_FAILURE; 509 510 tui_set_layout (new_layout, dpy_type); 511 } 512 xfree (buf_ptr); 513 } 514 else 515 status = TUI_FAILURE; 516 517 return status; 518 } 519 520 521 static void 522 extract_display_start_addr (struct gdbarch **gdbarch_p, CORE_ADDR *addr_p) 523 { 524 enum tui_layout_type cur_layout = tui_current_layout (); 525 struct gdbarch *gdbarch = NULL; 526 CORE_ADDR addr; 527 CORE_ADDR pc; 528 struct symtab_and_line cursal = get_current_source_symtab_and_line (); 529 530 switch (cur_layout) 531 { 532 case SRC_COMMAND: 533 case SRC_DATA_COMMAND: 534 gdbarch = TUI_SRC_WIN->detail.source_info.gdbarch; 535 find_line_pc (cursal.symtab, 536 TUI_SRC_WIN->detail.source_info.start_line_or_addr.u.line_no, 537 &pc); 538 addr = pc; 539 break; 540 case DISASSEM_COMMAND: 541 case SRC_DISASSEM_COMMAND: 542 case DISASSEM_DATA_COMMAND: 543 gdbarch = TUI_DISASM_WIN->detail.source_info.gdbarch; 544 addr = TUI_DISASM_WIN->detail.source_info.start_line_or_addr.u.addr; 545 break; 546 default: 547 addr = 0; 548 break; 549 } 550 551 *gdbarch_p = gdbarch; 552 *addr_p = addr; 553 } 554 555 556 static void 557 tui_handle_xdb_layout (struct tui_layout_def *layout_def) 558 { 559 if (layout_def->split) 560 { 561 tui_set_layout (SRC_DISASSEM_COMMAND, TUI_UNDEFINED_REGS); 562 tui_set_win_focus_to (tui_win_list[layout_def->display_mode]); 563 } 564 else 565 { 566 if (layout_def->display_mode == SRC_WIN) 567 tui_set_layout (SRC_COMMAND, TUI_UNDEFINED_REGS); 568 else 569 tui_set_layout (DISASSEM_DATA_COMMAND, layout_def->regs_display_type); 570 } 571 } 572 573 574 static void 575 tui_toggle_layout_command (char *arg, int from_tty) 576 { 577 struct tui_layout_def *layout_def = tui_layout_def (); 578 579 /* Make sure the curses mode is enabled. */ 580 tui_enable (); 581 if (layout_def->display_mode == SRC_WIN) 582 layout_def->display_mode = DISASSEM_WIN; 583 else 584 layout_def->display_mode = SRC_WIN; 585 586 if (!layout_def->split) 587 tui_handle_xdb_layout (layout_def); 588 } 589 590 591 static void 592 tui_toggle_split_layout_command (char *arg, int from_tty) 593 { 594 struct tui_layout_def *layout_def = tui_layout_def (); 595 596 /* Make sure the curses mode is enabled. */ 597 tui_enable (); 598 layout_def->split = (!layout_def->split); 599 tui_handle_xdb_layout (layout_def); 600 } 601 602 603 static void 604 tui_layout_command (char *arg, int from_tty) 605 { 606 /* Make sure the curses mode is enabled. */ 607 tui_enable (); 608 609 /* Switch to the selected layout. */ 610 if (tui_set_layout_for_display_command (arg) != TUI_SUCCESS) 611 warning (_("Invalid layout specified.\n%s"), LAYOUT_USAGE); 612 613 } 614 615 /* Answer the previous layout to cycle to. */ 616 static enum tui_layout_type 617 next_layout (void) 618 { 619 enum tui_layout_type new_layout; 620 621 new_layout = tui_current_layout (); 622 if (new_layout == UNDEFINED_LAYOUT) 623 new_layout = SRC_COMMAND; 624 else 625 { 626 new_layout++; 627 if (new_layout == UNDEFINED_LAYOUT) 628 new_layout = SRC_COMMAND; 629 } 630 631 return new_layout; 632 } 633 634 635 /* Answer the next layout to cycle to. */ 636 static enum tui_layout_type 637 prev_layout (void) 638 { 639 enum tui_layout_type new_layout; 640 641 new_layout = tui_current_layout (); 642 if (new_layout == SRC_COMMAND) 643 new_layout = DISASSEM_DATA_COMMAND; 644 else 645 { 646 new_layout--; 647 if (new_layout == UNDEFINED_LAYOUT) 648 new_layout = DISASSEM_DATA_COMMAND; 649 } 650 651 return new_layout; 652 } 653 654 655 656 static void 657 make_command_window (struct tui_win_info **win_info_ptr, 658 int height, int origin_y) 659 { 660 *win_info_ptr = init_and_make_win (*win_info_ptr, 661 CMD_WIN, 662 height, 663 tui_term_width (), 664 0, 665 origin_y, 666 DONT_BOX_WINDOW); 667 668 (*win_info_ptr)->can_highlight = FALSE; 669 } 670 671 672 /* make_source_window(). 673 */ 674 static void 675 make_source_window (struct tui_win_info **win_info_ptr, 676 int height, int origin_y) 677 { 678 make_source_or_disasm_window (win_info_ptr, SRC_WIN, height, origin_y); 679 680 return; 681 } /* make_source_window */ 682 683 684 /* make_disasm_window(). 685 */ 686 static void 687 make_disasm_window (struct tui_win_info **win_info_ptr, 688 int height, int origin_y) 689 { 690 make_source_or_disasm_window (win_info_ptr, DISASSEM_WIN, height, origin_y); 691 692 return; 693 } /* make_disasm_window */ 694 695 696 static void 697 make_data_window (struct tui_win_info **win_info_ptr, 698 int height, int origin_y) 699 { 700 *win_info_ptr = init_and_make_win (*win_info_ptr, 701 DATA_WIN, 702 height, 703 tui_term_width (), 704 0, 705 origin_y, 706 BOX_WINDOW); 707 } 708 709 710 711 /* Show the Source/Command layout. */ 712 static void 713 show_source_command (void) 714 { 715 show_source_or_disasm_and_command (SRC_COMMAND); 716 } 717 718 719 /* Show the Dissassem/Command layout. */ 720 static void 721 show_disasm_command (void) 722 { 723 show_source_or_disasm_and_command (DISASSEM_COMMAND); 724 } 725 726 727 /* Show the Source/Disassem/Command layout. */ 728 static void 729 show_source_disasm_command (void) 730 { 731 if (tui_current_layout () != SRC_DISASSEM_COMMAND) 732 { 733 int cmd_height, src_height, asm_height; 734 735 if (TUI_CMD_WIN != NULL) 736 cmd_height = TUI_CMD_WIN->generic.height; 737 else 738 cmd_height = tui_term_height () / 3; 739 740 src_height = (tui_term_height () - cmd_height) / 2; 741 asm_height = tui_term_height () - (src_height + cmd_height); 742 743 if (TUI_SRC_WIN == NULL) 744 make_source_window (&TUI_SRC_WIN, src_height, 0); 745 else 746 { 747 init_gen_win_info (&TUI_SRC_WIN->generic, 748 TUI_SRC_WIN->generic.type, 749 src_height, 750 TUI_SRC_WIN->generic.width, 751 TUI_SRC_WIN->detail.source_info.execution_info->width, 752 0); 753 TUI_SRC_WIN->can_highlight = TRUE; 754 init_gen_win_info (TUI_SRC_WIN->detail.source_info.execution_info, 755 EXEC_INFO_WIN, 756 src_height, 757 3, 758 0, 759 0); 760 tui_make_visible (&TUI_SRC_WIN->generic); 761 tui_make_visible (TUI_SRC_WIN->detail.source_info.execution_info); 762 TUI_SRC_WIN->detail.source_info.has_locator = FALSE;; 763 } 764 if (TUI_SRC_WIN != NULL) 765 { 766 struct tui_gen_win_info *locator = tui_locator_win_info_ptr (); 767 768 tui_show_source_content (TUI_SRC_WIN); 769 if (TUI_DISASM_WIN == NULL) 770 { 771 make_disasm_window (&TUI_DISASM_WIN, asm_height, src_height - 1); 772 locator = init_and_make_win (locator, 773 LOCATOR_WIN, 774 2 /* 1 */ , 775 tui_term_width (), 776 0, 777 (src_height + asm_height) - 1, 778 DONT_BOX_WINDOW); 779 } 780 else 781 { 782 init_gen_win_info (locator, 783 LOCATOR_WIN, 784 2 /* 1 */ , 785 tui_term_width (), 786 0, 787 (src_height + asm_height) - 1); 788 TUI_DISASM_WIN->detail.source_info.has_locator = TRUE; 789 init_gen_win_info (&TUI_DISASM_WIN->generic, 790 TUI_DISASM_WIN->generic.type, 791 asm_height, 792 TUI_DISASM_WIN->generic.width, 793 TUI_DISASM_WIN->detail.source_info.execution_info->width, 794 src_height - 1); 795 init_gen_win_info (TUI_DISASM_WIN->detail.source_info.execution_info, 796 EXEC_INFO_WIN, 797 asm_height, 798 3, 799 0, 800 src_height - 1); 801 TUI_DISASM_WIN->can_highlight = TRUE; 802 tui_make_visible (&TUI_DISASM_WIN->generic); 803 tui_make_visible (TUI_DISASM_WIN->detail.source_info.execution_info); 804 } 805 if (TUI_DISASM_WIN != NULL) 806 { 807 TUI_SRC_WIN->detail.source_info.has_locator = FALSE; 808 TUI_DISASM_WIN->detail.source_info.has_locator = TRUE; 809 tui_make_visible (locator); 810 tui_show_locator_content (); 811 tui_show_source_content (TUI_DISASM_WIN); 812 813 if (TUI_CMD_WIN == NULL) 814 make_command_window (&TUI_CMD_WIN, 815 cmd_height, 816 tui_term_height () - cmd_height); 817 else 818 { 819 init_gen_win_info (&TUI_CMD_WIN->generic, 820 TUI_CMD_WIN->generic.type, 821 TUI_CMD_WIN->generic.height, 822 TUI_CMD_WIN->generic.width, 823 0, 824 TUI_CMD_WIN->generic.origin.y); 825 TUI_CMD_WIN->can_highlight = FALSE; 826 tui_make_visible (&TUI_CMD_WIN->generic); 827 } 828 if (TUI_CMD_WIN != NULL) 829 tui_refresh_win (&TUI_CMD_WIN->generic); 830 } 831 } 832 tui_set_current_layout_to (SRC_DISASSEM_COMMAND); 833 } 834 } 835 836 837 /* Show the Source/Data/Command or the Dissassembly/Data/Command 838 layout. */ 839 static void 840 show_data (enum tui_layout_type new_layout) 841 { 842 int total_height = (tui_term_height () - TUI_CMD_WIN->generic.height); 843 int src_height, data_height; 844 enum tui_win_type win_type; 845 struct tui_gen_win_info *locator = tui_locator_win_info_ptr (); 846 847 848 data_height = total_height / 2; 849 src_height = total_height - data_height; 850 tui_make_all_invisible (); 851 tui_make_invisible (locator); 852 make_data_window (&TUI_DATA_WIN, data_height, 0); 853 TUI_DATA_WIN->can_highlight = TRUE; 854 if (new_layout == SRC_DATA_COMMAND) 855 win_type = SRC_WIN; 856 else 857 win_type = DISASSEM_WIN; 858 if (tui_win_list[win_type] == NULL) 859 { 860 if (win_type == SRC_WIN) 861 make_source_window (&tui_win_list[win_type], src_height, data_height - 1); 862 else 863 make_disasm_window (&tui_win_list[win_type], src_height, data_height - 1); 864 locator = init_and_make_win (locator, 865 LOCATOR_WIN, 866 2 /* 1 */ , 867 tui_term_width (), 868 0, 869 total_height - 1, 870 DONT_BOX_WINDOW); 871 } 872 else 873 { 874 init_gen_win_info (&tui_win_list[win_type]->generic, 875 tui_win_list[win_type]->generic.type, 876 src_height, 877 tui_win_list[win_type]->generic.width, 878 tui_win_list[win_type]->detail.source_info.execution_info->width, 879 data_height - 1); 880 init_gen_win_info (tui_win_list[win_type]->detail.source_info.execution_info, 881 EXEC_INFO_WIN, 882 src_height, 883 3, 884 0, 885 data_height - 1); 886 tui_make_visible (&tui_win_list[win_type]->generic); 887 tui_make_visible (tui_win_list[win_type]->detail.source_info.execution_info); 888 init_gen_win_info (locator, 889 LOCATOR_WIN, 890 2 /* 1 */ , 891 tui_term_width (), 892 0, 893 total_height - 1); 894 } 895 tui_win_list[win_type]->detail.source_info.has_locator = TRUE; 896 tui_make_visible (locator); 897 tui_show_locator_content (); 898 tui_add_to_source_windows (tui_win_list[win_type]); 899 tui_set_current_layout_to (new_layout); 900 } 901 902 /* init_gen_win_info(). 903 */ 904 static void 905 init_gen_win_info (struct tui_gen_win_info *win_info, 906 enum tui_win_type type, 907 int height, int width, 908 int origin_x, int origin_y) 909 { 910 int h = height; 911 912 win_info->type = type; 913 win_info->width = width; 914 win_info->height = h; 915 if (h > 1) 916 { 917 win_info->viewport_height = h - 1; 918 if (win_info->type != CMD_WIN) 919 win_info->viewport_height--; 920 } 921 else 922 win_info->viewport_height = 1; 923 win_info->origin.x = origin_x; 924 win_info->origin.y = origin_y; 925 926 return; 927 } /* init_gen_win_info */ 928 929 /* init_and_make_win(). 930 */ 931 static void * 932 init_and_make_win (void *opaque_win_info, 933 enum tui_win_type win_type, 934 int height, int width, 935 int origin_x, int origin_y, 936 int box_it) 937 { 938 struct tui_gen_win_info *generic; 939 940 if (opaque_win_info == NULL) 941 { 942 if (tui_win_is_auxillary (win_type)) 943 opaque_win_info = (void *) tui_alloc_generic_win_info (); 944 else 945 opaque_win_info = (void *) tui_alloc_win_info (win_type); 946 } 947 if (tui_win_is_auxillary (win_type)) 948 generic = (struct tui_gen_win_info *) opaque_win_info; 949 else 950 generic = &((struct tui_win_info *) opaque_win_info)->generic; 951 952 if (opaque_win_info != NULL) 953 { 954 init_gen_win_info (generic, win_type, height, width, origin_x, origin_y); 955 if (!tui_win_is_auxillary (win_type)) 956 { 957 if (generic->type == CMD_WIN) 958 ((struct tui_win_info *) opaque_win_info)->can_highlight = FALSE; 959 else 960 ((struct tui_win_info *) opaque_win_info)->can_highlight = TRUE; 961 } 962 tui_make_window (generic, box_it); 963 } 964 return opaque_win_info; 965 } 966 967 968 static void 969 make_source_or_disasm_window (struct tui_win_info **win_info_ptr, 970 enum tui_win_type type, 971 int height, int origin_y) 972 { 973 struct tui_gen_win_info *execution_info = (struct tui_gen_win_info *) NULL; 974 975 /* Create the exeuction info window. */ 976 if (type == SRC_WIN) 977 execution_info = tui_source_exec_info_win_ptr (); 978 else 979 execution_info = tui_disassem_exec_info_win_ptr (); 980 execution_info = init_and_make_win (execution_info, 981 EXEC_INFO_WIN, 982 height, 983 3, 984 0, 985 origin_y, 986 DONT_BOX_WINDOW); 987 988 /* Now create the source window. */ 989 *win_info_ptr = init_and_make_win (*win_info_ptr, 990 type, 991 height, 992 tui_term_width () - execution_info->width, 993 execution_info->width, 994 origin_y, 995 BOX_WINDOW); 996 997 (*win_info_ptr)->detail.source_info.execution_info = execution_info; 998 } 999 1000 1001 /* Show the Source/Command or the Disassem layout. */ 1002 static void 1003 show_source_or_disasm_and_command (enum tui_layout_type layout_type) 1004 { 1005 if (tui_current_layout () != layout_type) 1006 { 1007 struct tui_win_info **win_info_ptr; 1008 int src_height, cmd_height; 1009 struct tui_gen_win_info *locator = tui_locator_win_info_ptr (); 1010 1011 if (TUI_CMD_WIN != NULL) 1012 cmd_height = TUI_CMD_WIN->generic.height; 1013 else 1014 cmd_height = tui_term_height () / 3; 1015 src_height = tui_term_height () - cmd_height; 1016 1017 if (layout_type == SRC_COMMAND) 1018 win_info_ptr = &TUI_SRC_WIN; 1019 else 1020 win_info_ptr = &TUI_DISASM_WIN; 1021 1022 if ((*win_info_ptr) == NULL) 1023 { 1024 if (layout_type == SRC_COMMAND) 1025 make_source_window (win_info_ptr, src_height - 1, 0); 1026 else 1027 make_disasm_window (win_info_ptr, src_height - 1, 0); 1028 locator = init_and_make_win (locator, 1029 LOCATOR_WIN, 1030 2 /* 1 */ , 1031 tui_term_width (), 1032 0, 1033 src_height - 1, 1034 DONT_BOX_WINDOW); 1035 } 1036 else 1037 { 1038 init_gen_win_info (locator, 1039 LOCATOR_WIN, 1040 2 /* 1 */ , 1041 tui_term_width (), 1042 0, 1043 src_height - 1); 1044 (*win_info_ptr)->detail.source_info.has_locator = TRUE; 1045 init_gen_win_info (&(*win_info_ptr)->generic, 1046 (*win_info_ptr)->generic.type, 1047 src_height - 1, 1048 (*win_info_ptr)->generic.width, 1049 (*win_info_ptr)->detail.source_info.execution_info->width, 1050 0); 1051 init_gen_win_info ((*win_info_ptr)->detail.source_info.execution_info, 1052 EXEC_INFO_WIN, 1053 src_height - 1, 1054 3, 1055 0, 1056 0); 1057 (*win_info_ptr)->can_highlight = TRUE; 1058 tui_make_visible (&(*win_info_ptr)->generic); 1059 tui_make_visible ((*win_info_ptr)->detail.source_info.execution_info); 1060 } 1061 if ((*win_info_ptr) != NULL) 1062 { 1063 (*win_info_ptr)->detail.source_info.has_locator = TRUE; 1064 tui_make_visible (locator); 1065 tui_show_locator_content (); 1066 tui_show_source_content (*win_info_ptr); 1067 1068 if (TUI_CMD_WIN == NULL) 1069 { 1070 make_command_window (&TUI_CMD_WIN, cmd_height, src_height); 1071 tui_refresh_win (&TUI_CMD_WIN->generic); 1072 } 1073 else 1074 { 1075 init_gen_win_info (&TUI_CMD_WIN->generic, 1076 TUI_CMD_WIN->generic.type, 1077 TUI_CMD_WIN->generic.height, 1078 TUI_CMD_WIN->generic.width, 1079 TUI_CMD_WIN->generic.origin.x, 1080 TUI_CMD_WIN->generic.origin.y); 1081 TUI_CMD_WIN->can_highlight = FALSE; 1082 tui_make_visible (&TUI_CMD_WIN->generic); 1083 } 1084 } 1085 tui_set_current_layout_to (layout_type); 1086 } 1087 } 1088