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