GDB (API)
|
00001 /* TUI layout window management. 00002 00003 Copyright (C) 1998-2013 Free Software Foundation, Inc. 00004 00005 Contributed by Hewlett-Packard Company. 00006 00007 This file is part of GDB. 00008 00009 This program is free software; you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation; either version 3 of the License, or 00012 (at your option) any later version. 00013 00014 This program is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00021 00022 #include "defs.h" 00023 #include "arch-utils.h" 00024 #include "command.h" 00025 #include "symtab.h" 00026 #include "frame.h" 00027 #include "source.h" 00028 #include <ctype.h> 00029 00030 #include "tui/tui.h" 00031 #include "tui/tui-data.h" 00032 #include "tui/tui-windata.h" 00033 #include "tui/tui-wingeneral.h" 00034 #include "tui/tui-stack.h" 00035 #include "tui/tui-regs.h" 00036 #include "tui/tui-win.h" 00037 #include "tui/tui-winsource.h" 00038 #include "tui/tui-disasm.h" 00039 #include "tui/tui-layout.h" 00040 00041 #include "gdb_string.h" 00042 #include "gdb_curses.h" 00043 00044 /******************************* 00045 ** Static Local Decls 00046 ********************************/ 00047 static void show_layout (enum tui_layout_type); 00048 static void init_gen_win_info (struct tui_gen_win_info *, 00049 enum tui_win_type, 00050 int, int, int, int); 00051 static void *init_and_make_win (void *, enum tui_win_type, 00052 int, int, int, int, int); 00053 static void show_source_or_disasm_and_command (enum tui_layout_type); 00054 static void make_source_or_disasm_window (struct tui_win_info **, 00055 enum tui_win_type, 00056 int, int); 00057 static void make_command_window (struct tui_win_info **, int, int); 00058 static void make_source_window (struct tui_win_info **, int, int); 00059 static void make_disasm_window (struct tui_win_info **, int, int); 00060 static void make_data_window (struct tui_win_info **, int, int); 00061 static void show_source_command (void); 00062 static void show_disasm_command (void); 00063 static void show_source_disasm_command (void); 00064 static void show_data (enum tui_layout_type); 00065 static enum tui_layout_type next_layout (void); 00066 static enum tui_layout_type prev_layout (void); 00067 static void tui_layout_command (char *, int); 00068 static void tui_toggle_layout_command (char *, int); 00069 static void tui_toggle_split_layout_command (char *, int); 00070 static void extract_display_start_addr (struct gdbarch **, CORE_ADDR *); 00071 static void tui_handle_xdb_layout (struct tui_layout_def *); 00072 00073 00074 /*************************************** 00075 ** DEFINITIONS 00076 ***************************************/ 00077 00078 #define LAYOUT_USAGE "Usage: layout prev | next | <layout_name> \n" 00079 00080 /* Show the screen layout defined. */ 00081 static void 00082 show_layout (enum tui_layout_type layout) 00083 { 00084 enum tui_layout_type cur_layout = tui_current_layout (); 00085 00086 if (layout != cur_layout) 00087 { 00088 /* Since the new layout may cause changes in window size, we 00089 should free the content and reallocate on next display of 00090 source/asm. */ 00091 tui_free_all_source_wins_content (); 00092 tui_clear_source_windows (); 00093 if (layout == SRC_DATA_COMMAND 00094 || layout == DISASSEM_DATA_COMMAND) 00095 { 00096 show_data (layout); 00097 tui_refresh_all (tui_win_list); 00098 } 00099 else 00100 { 00101 /* First make the current layout be invisible. */ 00102 tui_make_all_invisible (); 00103 tui_make_invisible (tui_locator_win_info_ptr ()); 00104 00105 switch (layout) 00106 { 00107 /* Now show the new layout. */ 00108 case SRC_COMMAND: 00109 show_source_command (); 00110 tui_add_to_source_windows (TUI_SRC_WIN); 00111 break; 00112 case DISASSEM_COMMAND: 00113 show_disasm_command (); 00114 tui_add_to_source_windows (TUI_DISASM_WIN); 00115 break; 00116 case SRC_DISASSEM_COMMAND: 00117 show_source_disasm_command (); 00118 tui_add_to_source_windows (TUI_SRC_WIN); 00119 tui_add_to_source_windows (TUI_DISASM_WIN); 00120 break; 00121 default: 00122 break; 00123 } 00124 } 00125 } 00126 } 00127 00128 00129 /* Function to set the layout to SRC_COMMAND, DISASSEM_COMMAND, 00130 SRC_DISASSEM_COMMAND, SRC_DATA_COMMAND, or DISASSEM_DATA_COMMAND. 00131 If the layout is SRC_DATA_COMMAND, DISASSEM_DATA_COMMAND, or 00132 UNDEFINED_LAYOUT, then the data window is populated according to 00133 regs_display_type. */ 00134 enum tui_status 00135 tui_set_layout (enum tui_layout_type layout_type, 00136 enum tui_register_display_type regs_display_type) 00137 { 00138 enum tui_status status = TUI_SUCCESS; 00139 00140 if (layout_type != UNDEFINED_LAYOUT 00141 || regs_display_type != TUI_UNDEFINED_REGS) 00142 { 00143 enum tui_layout_type cur_layout = tui_current_layout (), 00144 new_layout = UNDEFINED_LAYOUT; 00145 int regs_populate = FALSE; 00146 struct gdbarch *gdbarch; 00147 CORE_ADDR addr; 00148 struct tui_win_info *win_with_focus = tui_win_with_focus (); 00149 struct tui_layout_def *layout_def = tui_layout_def (); 00150 00151 extract_display_start_addr (&gdbarch, &addr); 00152 00153 if (layout_type == UNDEFINED_LAYOUT 00154 && regs_display_type != TUI_UNDEFINED_REGS) 00155 { 00156 if (cur_layout == SRC_DISASSEM_COMMAND) 00157 new_layout = DISASSEM_DATA_COMMAND; 00158 else if (cur_layout == SRC_COMMAND 00159 || cur_layout == SRC_DATA_COMMAND) 00160 new_layout = SRC_DATA_COMMAND; 00161 else if (cur_layout == DISASSEM_COMMAND 00162 || cur_layout == DISASSEM_DATA_COMMAND) 00163 new_layout = DISASSEM_DATA_COMMAND; 00164 } 00165 else 00166 new_layout = layout_type; 00167 00168 regs_populate = (new_layout == SRC_DATA_COMMAND 00169 || new_layout == DISASSEM_DATA_COMMAND 00170 || regs_display_type != TUI_UNDEFINED_REGS); 00171 if (new_layout != cur_layout 00172 || regs_display_type != TUI_UNDEFINED_REGS) 00173 { 00174 if (new_layout != cur_layout) 00175 { 00176 show_layout (new_layout); 00177 00178 /* Now determine where focus should be. */ 00179 if (win_with_focus != TUI_CMD_WIN) 00180 { 00181 switch (new_layout) 00182 { 00183 case SRC_COMMAND: 00184 tui_set_win_focus_to (TUI_SRC_WIN); 00185 layout_def->display_mode = SRC_WIN; 00186 layout_def->split = FALSE; 00187 break; 00188 case DISASSEM_COMMAND: 00189 /* The previous layout was not showing code. 00190 This can happen if there is no source 00191 available: 00192 00193 1. if the source file is in another dir OR 00194 2. if target was compiled without -g 00195 We still want to show the assembly though! */ 00196 00197 tui_get_begin_asm_address (&gdbarch, &addr); 00198 tui_set_win_focus_to (TUI_DISASM_WIN); 00199 layout_def->display_mode = DISASSEM_WIN; 00200 layout_def->split = FALSE; 00201 break; 00202 case SRC_DISASSEM_COMMAND: 00203 /* The previous layout was not showing code. 00204 This can happen if there is no source 00205 available: 00206 00207 1. if the source file is in another dir OR 00208 2. if target was compiled without -g 00209 We still want to show the assembly though! */ 00210 00211 tui_get_begin_asm_address (&gdbarch, &addr); 00212 if (win_with_focus == TUI_SRC_WIN) 00213 tui_set_win_focus_to (TUI_SRC_WIN); 00214 else 00215 tui_set_win_focus_to (TUI_DISASM_WIN); 00216 layout_def->split = TRUE; 00217 break; 00218 case SRC_DATA_COMMAND: 00219 if (win_with_focus != TUI_DATA_WIN) 00220 tui_set_win_focus_to (TUI_SRC_WIN); 00221 else 00222 tui_set_win_focus_to (TUI_DATA_WIN); 00223 layout_def->display_mode = SRC_WIN; 00224 layout_def->split = FALSE; 00225 break; 00226 case DISASSEM_DATA_COMMAND: 00227 /* The previous layout was not showing code. 00228 This can happen if there is no source 00229 available: 00230 00231 1. if the source file is in another dir OR 00232 2. if target was compiled without -g 00233 We still want to show the assembly though! */ 00234 00235 tui_get_begin_asm_address (&gdbarch, &addr); 00236 if (win_with_focus != TUI_DATA_WIN) 00237 tui_set_win_focus_to (TUI_DISASM_WIN); 00238 else 00239 tui_set_win_focus_to (TUI_DATA_WIN); 00240 layout_def->display_mode = DISASSEM_WIN; 00241 layout_def->split = FALSE; 00242 break; 00243 default: 00244 break; 00245 } 00246 } 00247 /* 00248 * Now update the window content. 00249 */ 00250 if (!regs_populate 00251 && (new_layout == SRC_DATA_COMMAND 00252 || new_layout == DISASSEM_DATA_COMMAND)) 00253 tui_display_all_data (); 00254 00255 tui_update_source_windows_with_addr (gdbarch, addr); 00256 } 00257 if (regs_populate) 00258 { 00259 tui_show_registers (TUI_DATA_WIN->detail.data_display_info.current_group); 00260 } 00261 } 00262 } 00263 else 00264 status = TUI_FAILURE; 00265 00266 return status; 00267 } 00268 00269 /* Add the specified window to the layout in a logical way. This 00270 means setting up the most logical layout given the window to be 00271 added. */ 00272 void 00273 tui_add_win_to_layout (enum tui_win_type type) 00274 { 00275 enum tui_layout_type cur_layout = tui_current_layout (); 00276 00277 switch (type) 00278 { 00279 case SRC_WIN: 00280 if (cur_layout != SRC_COMMAND 00281 && cur_layout != SRC_DISASSEM_COMMAND 00282 && cur_layout != SRC_DATA_COMMAND) 00283 { 00284 tui_clear_source_windows_detail (); 00285 if (cur_layout == DISASSEM_DATA_COMMAND) 00286 show_layout (SRC_DATA_COMMAND); 00287 else 00288 show_layout (SRC_COMMAND); 00289 } 00290 break; 00291 case DISASSEM_WIN: 00292 if (cur_layout != DISASSEM_COMMAND 00293 && cur_layout != SRC_DISASSEM_COMMAND 00294 && cur_layout != DISASSEM_DATA_COMMAND) 00295 { 00296 tui_clear_source_windows_detail (); 00297 if (cur_layout == SRC_DATA_COMMAND) 00298 show_layout (DISASSEM_DATA_COMMAND); 00299 else 00300 show_layout (DISASSEM_COMMAND); 00301 } 00302 break; 00303 case DATA_WIN: 00304 if (cur_layout != SRC_DATA_COMMAND 00305 && cur_layout != DISASSEM_DATA_COMMAND) 00306 { 00307 if (cur_layout == DISASSEM_COMMAND) 00308 show_layout (DISASSEM_DATA_COMMAND); 00309 else 00310 show_layout (SRC_DATA_COMMAND); 00311 } 00312 break; 00313 default: 00314 break; 00315 } 00316 } 00317 00318 00319 /* Answer the height of a window. If it hasn't been created yet, 00320 answer what the height of a window would be based upon its type and 00321 the layout. */ 00322 int 00323 tui_default_win_height (enum tui_win_type type, 00324 enum tui_layout_type layout) 00325 { 00326 int h; 00327 00328 if (tui_win_list[type] != (struct tui_win_info *) NULL) 00329 h = tui_win_list[type]->generic.height; 00330 else 00331 { 00332 switch (layout) 00333 { 00334 case SRC_COMMAND: 00335 case DISASSEM_COMMAND: 00336 if (TUI_CMD_WIN == NULL) 00337 h = tui_term_height () / 2; 00338 else 00339 h = tui_term_height () - TUI_CMD_WIN->generic.height; 00340 break; 00341 case SRC_DISASSEM_COMMAND: 00342 case SRC_DATA_COMMAND: 00343 case DISASSEM_DATA_COMMAND: 00344 if (TUI_CMD_WIN == NULL) 00345 h = tui_term_height () / 3; 00346 else 00347 h = (tui_term_height () - TUI_CMD_WIN->generic.height) / 2; 00348 break; 00349 default: 00350 h = 0; 00351 break; 00352 } 00353 } 00354 00355 return h; 00356 } 00357 00358 00359 /* Answer the height of a window. If it hasn't been created yet, 00360 answer what the height of a window would be based upon its type and 00361 the layout. */ 00362 int 00363 tui_default_win_viewport_height (enum tui_win_type type, 00364 enum tui_layout_type layout) 00365 { 00366 int h; 00367 00368 h = tui_default_win_height (type, layout); 00369 00370 if (tui_win_list[type] == TUI_CMD_WIN) 00371 h -= 1; 00372 else 00373 h -= 2; 00374 00375 return h; 00376 } 00377 00378 00379 /* Function to initialize gdb commands, for tui window layout 00380 manipulation. */ 00381 00382 /* Provide a prototype to silence -Wmissing-prototypes. */ 00383 extern initialize_file_ftype _initialize_tui_layout; 00384 00385 void 00386 _initialize_tui_layout (void) 00387 { 00388 add_com ("layout", class_tui, tui_layout_command, _("\ 00389 Change the layout of windows.\n\ 00390 Usage: layout prev | next | <layout_name> \n\ 00391 Layout names are:\n\ 00392 src : Displays source and command windows.\n\ 00393 asm : Displays disassembly and command windows.\n\ 00394 split : Displays source, disassembly and command windows.\n\ 00395 regs : Displays register window. If existing layout\n\ 00396 is source/command or assembly/command, the \n\ 00397 register window is displayed. If the\n\ 00398 source/assembly/command (split) is displayed, \n\ 00399 the register window is displayed with \n\ 00400 the window that has current logical focus.\n")); 00401 if (xdb_commands) 00402 { 00403 add_com ("td", class_tui, tui_toggle_layout_command, _("\ 00404 Toggle between Source/Command and Disassembly/Command layouts.\n")); 00405 add_com ("ts", class_tui, tui_toggle_split_layout_command, _("\ 00406 Toggle between Source/Command or Disassembly/Command and \n\ 00407 Source/Disassembly/Command layouts.\n")); 00408 } 00409 } 00410 00411 00412 /************************* 00413 ** STATIC LOCAL FUNCTIONS 00414 **************************/ 00415 00416 00417 /* Function to set the layout to SRC, ASM, SPLIT, NEXT, PREV, DATA, 00418 REGS, $REGS, $GREGS, $FREGS, $SREGS. */ 00419 enum tui_status 00420 tui_set_layout_for_display_command (const char *layout_name) 00421 { 00422 enum tui_status status = TUI_SUCCESS; 00423 00424 if (layout_name != (char *) NULL) 00425 { 00426 int i; 00427 char *buf_ptr; 00428 enum tui_layout_type new_layout = UNDEFINED_LAYOUT; 00429 enum tui_register_display_type dpy_type = TUI_UNDEFINED_REGS; 00430 enum tui_layout_type cur_layout = tui_current_layout (); 00431 00432 buf_ptr = (char *) xstrdup (layout_name); 00433 for (i = 0; (i < strlen (layout_name)); i++) 00434 buf_ptr[i] = toupper (buf_ptr[i]); 00435 00436 /* First check for ambiguous input. */ 00437 if (strlen (buf_ptr) <= 1 00438 && (*buf_ptr == 'S' || *buf_ptr == '$')) 00439 { 00440 warning (_("Ambiguous command input.")); 00441 status = TUI_FAILURE; 00442 } 00443 else 00444 { 00445 if (subset_compare (buf_ptr, "SRC")) 00446 new_layout = SRC_COMMAND; 00447 else if (subset_compare (buf_ptr, "ASM")) 00448 new_layout = DISASSEM_COMMAND; 00449 else if (subset_compare (buf_ptr, "SPLIT")) 00450 new_layout = SRC_DISASSEM_COMMAND; 00451 else if (subset_compare (buf_ptr, "REGS") 00452 || subset_compare (buf_ptr, TUI_GENERAL_SPECIAL_REGS_NAME) 00453 || subset_compare (buf_ptr, TUI_GENERAL_REGS_NAME) 00454 || subset_compare (buf_ptr, TUI_FLOAT_REGS_NAME) 00455 || subset_compare (buf_ptr, TUI_SPECIAL_REGS_NAME)) 00456 { 00457 if (cur_layout == SRC_COMMAND 00458 || cur_layout == SRC_DATA_COMMAND) 00459 new_layout = SRC_DATA_COMMAND; 00460 else 00461 new_layout = DISASSEM_DATA_COMMAND; 00462 00463 /* Could ifdef out the following code. when compile with 00464 -z, there are null pointer references that cause a 00465 core dump if 'layout regs' is the first layout 00466 command issued by the user. HP has asked us to hook 00467 up this code. - edie epstein */ 00468 if (subset_compare (buf_ptr, TUI_FLOAT_REGS_NAME)) 00469 { 00470 if (TUI_DATA_WIN->detail.data_display_info.regs_display_type 00471 != TUI_SFLOAT_REGS 00472 && TUI_DATA_WIN->detail.data_display_info.regs_display_type 00473 != TUI_DFLOAT_REGS) 00474 dpy_type = TUI_SFLOAT_REGS; 00475 else 00476 dpy_type = 00477 TUI_DATA_WIN->detail.data_display_info.regs_display_type; 00478 } 00479 else if (subset_compare (buf_ptr, 00480 TUI_GENERAL_SPECIAL_REGS_NAME)) 00481 dpy_type = TUI_GENERAL_AND_SPECIAL_REGS; 00482 else if (subset_compare (buf_ptr, TUI_GENERAL_REGS_NAME)) 00483 dpy_type = TUI_GENERAL_REGS; 00484 else if (subset_compare (buf_ptr, TUI_SPECIAL_REGS_NAME)) 00485 dpy_type = TUI_SPECIAL_REGS; 00486 else if (TUI_DATA_WIN) 00487 { 00488 if (TUI_DATA_WIN->detail.data_display_info.regs_display_type 00489 != TUI_UNDEFINED_REGS) 00490 dpy_type 00491 = TUI_DATA_WIN->detail.data_display_info.regs_display_type; 00492 else 00493 dpy_type = TUI_GENERAL_REGS; 00494 } 00495 00496 /* End of potential ifdef. 00497 */ 00498 00499 /* If ifdefed out code above, then assume that the user 00500 wishes to display the general purpose registers . 00501 */ 00502 00503 /* dpy_type = TUI_GENERAL_REGS; */ 00504 } 00505 else if (subset_compare (buf_ptr, "NEXT")) 00506 new_layout = next_layout (); 00507 else if (subset_compare (buf_ptr, "PREV")) 00508 new_layout = prev_layout (); 00509 else 00510 status = TUI_FAILURE; 00511 00512 tui_set_layout (new_layout, dpy_type); 00513 } 00514 xfree (buf_ptr); 00515 } 00516 else 00517 status = TUI_FAILURE; 00518 00519 return status; 00520 } 00521 00522 00523 static void 00524 extract_display_start_addr (struct gdbarch **gdbarch_p, CORE_ADDR *addr_p) 00525 { 00526 enum tui_layout_type cur_layout = tui_current_layout (); 00527 struct gdbarch *gdbarch = get_current_arch (); 00528 CORE_ADDR addr; 00529 CORE_ADDR pc; 00530 struct symtab_and_line cursal = get_current_source_symtab_and_line (); 00531 00532 switch (cur_layout) 00533 { 00534 case SRC_COMMAND: 00535 case SRC_DATA_COMMAND: 00536 gdbarch = TUI_SRC_WIN->detail.source_info.gdbarch; 00537 find_line_pc (cursal.symtab, 00538 TUI_SRC_WIN->detail.source_info.start_line_or_addr.u.line_no, 00539 &pc); 00540 addr = pc; 00541 break; 00542 case DISASSEM_COMMAND: 00543 case SRC_DISASSEM_COMMAND: 00544 case DISASSEM_DATA_COMMAND: 00545 gdbarch = TUI_DISASM_WIN->detail.source_info.gdbarch; 00546 addr = TUI_DISASM_WIN->detail.source_info.start_line_or_addr.u.addr; 00547 break; 00548 default: 00549 addr = 0; 00550 break; 00551 } 00552 00553 *gdbarch_p = gdbarch; 00554 *addr_p = addr; 00555 } 00556 00557 00558 static void 00559 tui_handle_xdb_layout (struct tui_layout_def *layout_def) 00560 { 00561 if (layout_def->split) 00562 { 00563 tui_set_layout (SRC_DISASSEM_COMMAND, TUI_UNDEFINED_REGS); 00564 tui_set_win_focus_to (tui_win_list[layout_def->display_mode]); 00565 } 00566 else 00567 { 00568 if (layout_def->display_mode == SRC_WIN) 00569 tui_set_layout (SRC_COMMAND, TUI_UNDEFINED_REGS); 00570 else 00571 tui_set_layout (DISASSEM_DATA_COMMAND, layout_def->regs_display_type); 00572 } 00573 } 00574 00575 00576 static void 00577 tui_toggle_layout_command (char *arg, int from_tty) 00578 { 00579 struct tui_layout_def *layout_def = tui_layout_def (); 00580 00581 /* Make sure the curses mode is enabled. */ 00582 tui_enable (); 00583 if (layout_def->display_mode == SRC_WIN) 00584 layout_def->display_mode = DISASSEM_WIN; 00585 else 00586 layout_def->display_mode = SRC_WIN; 00587 00588 if (!layout_def->split) 00589 tui_handle_xdb_layout (layout_def); 00590 } 00591 00592 00593 static void 00594 tui_toggle_split_layout_command (char *arg, int from_tty) 00595 { 00596 struct tui_layout_def *layout_def = tui_layout_def (); 00597 00598 /* Make sure the curses mode is enabled. */ 00599 tui_enable (); 00600 layout_def->split = (!layout_def->split); 00601 tui_handle_xdb_layout (layout_def); 00602 } 00603 00604 00605 static void 00606 tui_layout_command (char *arg, int from_tty) 00607 { 00608 /* Make sure the curses mode is enabled. */ 00609 tui_enable (); 00610 00611 /* Switch to the selected layout. */ 00612 if (tui_set_layout_for_display_command (arg) != TUI_SUCCESS) 00613 warning (_("Invalid layout specified.\n%s"), LAYOUT_USAGE); 00614 00615 } 00616 00617 /* Answer the previous layout to cycle to. */ 00618 static enum tui_layout_type 00619 next_layout (void) 00620 { 00621 enum tui_layout_type new_layout; 00622 00623 new_layout = tui_current_layout (); 00624 if (new_layout == UNDEFINED_LAYOUT) 00625 new_layout = SRC_COMMAND; 00626 else 00627 { 00628 new_layout++; 00629 if (new_layout == UNDEFINED_LAYOUT) 00630 new_layout = SRC_COMMAND; 00631 } 00632 00633 return new_layout; 00634 } 00635 00636 00637 /* Answer the next layout to cycle to. */ 00638 static enum tui_layout_type 00639 prev_layout (void) 00640 { 00641 enum tui_layout_type new_layout; 00642 00643 new_layout = tui_current_layout (); 00644 if (new_layout == SRC_COMMAND) 00645 new_layout = DISASSEM_DATA_COMMAND; 00646 else 00647 { 00648 new_layout--; 00649 if (new_layout == UNDEFINED_LAYOUT) 00650 new_layout = DISASSEM_DATA_COMMAND; 00651 } 00652 00653 return new_layout; 00654 } 00655 00656 00657 00658 static void 00659 make_command_window (struct tui_win_info **win_info_ptr, 00660 int height, int origin_y) 00661 { 00662 *win_info_ptr = init_and_make_win (*win_info_ptr, 00663 CMD_WIN, 00664 height, 00665 tui_term_width (), 00666 0, 00667 origin_y, 00668 DONT_BOX_WINDOW); 00669 00670 (*win_info_ptr)->can_highlight = FALSE; 00671 } 00672 00673 00674 /* make_source_window(). 00675 */ 00676 static void 00677 make_source_window (struct tui_win_info **win_info_ptr, 00678 int height, int origin_y) 00679 { 00680 make_source_or_disasm_window (win_info_ptr, SRC_WIN, height, origin_y); 00681 00682 return; 00683 } /* make_source_window */ 00684 00685 00686 /* make_disasm_window(). 00687 */ 00688 static void 00689 make_disasm_window (struct tui_win_info **win_info_ptr, 00690 int height, int origin_y) 00691 { 00692 make_source_or_disasm_window (win_info_ptr, DISASSEM_WIN, height, origin_y); 00693 00694 return; 00695 } /* make_disasm_window */ 00696 00697 00698 static void 00699 make_data_window (struct tui_win_info **win_info_ptr, 00700 int height, int origin_y) 00701 { 00702 *win_info_ptr = init_and_make_win (*win_info_ptr, 00703 DATA_WIN, 00704 height, 00705 tui_term_width (), 00706 0, 00707 origin_y, 00708 BOX_WINDOW); 00709 } 00710 00711 00712 00713 /* Show the Source/Command layout. */ 00714 static void 00715 show_source_command (void) 00716 { 00717 show_source_or_disasm_and_command (SRC_COMMAND); 00718 } 00719 00720 00721 /* Show the Dissassem/Command layout. */ 00722 static void 00723 show_disasm_command (void) 00724 { 00725 show_source_or_disasm_and_command (DISASSEM_COMMAND); 00726 } 00727 00728 00729 /* Show the Source/Disassem/Command layout. */ 00730 static void 00731 show_source_disasm_command (void) 00732 { 00733 if (tui_current_layout () != SRC_DISASSEM_COMMAND) 00734 { 00735 int cmd_height, src_height, asm_height; 00736 00737 if (TUI_CMD_WIN != NULL) 00738 cmd_height = TUI_CMD_WIN->generic.height; 00739 else 00740 cmd_height = tui_term_height () / 3; 00741 00742 src_height = (tui_term_height () - cmd_height) / 2; 00743 asm_height = tui_term_height () - (src_height + cmd_height); 00744 00745 if (TUI_SRC_WIN == NULL) 00746 make_source_window (&TUI_SRC_WIN, src_height, 0); 00747 else 00748 { 00749 init_gen_win_info (&TUI_SRC_WIN->generic, 00750 TUI_SRC_WIN->generic.type, 00751 src_height, 00752 TUI_SRC_WIN->generic.width, 00753 TUI_SRC_WIN->detail.source_info.execution_info->width, 00754 0); 00755 TUI_SRC_WIN->can_highlight = TRUE; 00756 init_gen_win_info (TUI_SRC_WIN->detail.source_info.execution_info, 00757 EXEC_INFO_WIN, 00758 src_height, 00759 3, 00760 0, 00761 0); 00762 tui_make_visible (&TUI_SRC_WIN->generic); 00763 tui_make_visible (TUI_SRC_WIN->detail.source_info.execution_info); 00764 TUI_SRC_WIN->detail.source_info.has_locator = FALSE;; 00765 } 00766 if (TUI_SRC_WIN != NULL) 00767 { 00768 struct tui_gen_win_info *locator = tui_locator_win_info_ptr (); 00769 00770 tui_show_source_content (TUI_SRC_WIN); 00771 if (TUI_DISASM_WIN == NULL) 00772 { 00773 make_disasm_window (&TUI_DISASM_WIN, asm_height, src_height - 1); 00774 locator = init_and_make_win (locator, 00775 LOCATOR_WIN, 00776 2 /* 1 */ , 00777 tui_term_width (), 00778 0, 00779 (src_height + asm_height) - 1, 00780 DONT_BOX_WINDOW); 00781 } 00782 else 00783 { 00784 init_gen_win_info (locator, 00785 LOCATOR_WIN, 00786 2 /* 1 */ , 00787 tui_term_width (), 00788 0, 00789 (src_height + asm_height) - 1); 00790 TUI_DISASM_WIN->detail.source_info.has_locator = TRUE; 00791 init_gen_win_info (&TUI_DISASM_WIN->generic, 00792 TUI_DISASM_WIN->generic.type, 00793 asm_height, 00794 TUI_DISASM_WIN->generic.width, 00795 TUI_DISASM_WIN->detail.source_info.execution_info->width, 00796 src_height - 1); 00797 init_gen_win_info (TUI_DISASM_WIN->detail.source_info.execution_info, 00798 EXEC_INFO_WIN, 00799 asm_height, 00800 3, 00801 0, 00802 src_height - 1); 00803 TUI_DISASM_WIN->can_highlight = TRUE; 00804 tui_make_visible (&TUI_DISASM_WIN->generic); 00805 tui_make_visible (TUI_DISASM_WIN->detail.source_info.execution_info); 00806 } 00807 if (TUI_DISASM_WIN != NULL) 00808 { 00809 TUI_SRC_WIN->detail.source_info.has_locator = FALSE; 00810 TUI_DISASM_WIN->detail.source_info.has_locator = TRUE; 00811 tui_make_visible (locator); 00812 tui_show_locator_content (); 00813 tui_show_source_content (TUI_DISASM_WIN); 00814 00815 if (TUI_CMD_WIN == NULL) 00816 make_command_window (&TUI_CMD_WIN, 00817 cmd_height, 00818 tui_term_height () - cmd_height); 00819 else 00820 { 00821 init_gen_win_info (&TUI_CMD_WIN->generic, 00822 TUI_CMD_WIN->generic.type, 00823 TUI_CMD_WIN->generic.height, 00824 TUI_CMD_WIN->generic.width, 00825 0, 00826 TUI_CMD_WIN->generic.origin.y); 00827 TUI_CMD_WIN->can_highlight = FALSE; 00828 tui_make_visible (&TUI_CMD_WIN->generic); 00829 } 00830 if (TUI_CMD_WIN != NULL) 00831 tui_refresh_win (&TUI_CMD_WIN->generic); 00832 } 00833 } 00834 tui_set_current_layout_to (SRC_DISASSEM_COMMAND); 00835 } 00836 } 00837 00838 00839 /* Show the Source/Data/Command or the Dissassembly/Data/Command 00840 layout. */ 00841 static void 00842 show_data (enum tui_layout_type new_layout) 00843 { 00844 int total_height = (tui_term_height () - TUI_CMD_WIN->generic.height); 00845 int src_height, data_height; 00846 enum tui_win_type win_type; 00847 struct tui_gen_win_info *locator = tui_locator_win_info_ptr (); 00848 00849 00850 data_height = total_height / 2; 00851 src_height = total_height - data_height; 00852 tui_make_all_invisible (); 00853 tui_make_invisible (locator); 00854 make_data_window (&TUI_DATA_WIN, data_height, 0); 00855 TUI_DATA_WIN->can_highlight = TRUE; 00856 if (new_layout == SRC_DATA_COMMAND) 00857 win_type = SRC_WIN; 00858 else 00859 win_type = DISASSEM_WIN; 00860 if (tui_win_list[win_type] == NULL) 00861 { 00862 if (win_type == SRC_WIN) 00863 make_source_window (&tui_win_list[win_type], src_height, data_height - 1); 00864 else 00865 make_disasm_window (&tui_win_list[win_type], src_height, data_height - 1); 00866 locator = init_and_make_win (locator, 00867 LOCATOR_WIN, 00868 2 /* 1 */ , 00869 tui_term_width (), 00870 0, 00871 total_height - 1, 00872 DONT_BOX_WINDOW); 00873 } 00874 else 00875 { 00876 init_gen_win_info (&tui_win_list[win_type]->generic, 00877 tui_win_list[win_type]->generic.type, 00878 src_height, 00879 tui_win_list[win_type]->generic.width, 00880 tui_win_list[win_type]->detail.source_info.execution_info->width, 00881 data_height - 1); 00882 init_gen_win_info (tui_win_list[win_type]->detail.source_info.execution_info, 00883 EXEC_INFO_WIN, 00884 src_height, 00885 3, 00886 0, 00887 data_height - 1); 00888 tui_make_visible (&tui_win_list[win_type]->generic); 00889 tui_make_visible (tui_win_list[win_type]->detail.source_info.execution_info); 00890 init_gen_win_info (locator, 00891 LOCATOR_WIN, 00892 2 /* 1 */ , 00893 tui_term_width (), 00894 0, 00895 total_height - 1); 00896 } 00897 tui_win_list[win_type]->detail.source_info.has_locator = TRUE; 00898 tui_make_visible (locator); 00899 tui_show_locator_content (); 00900 tui_add_to_source_windows (tui_win_list[win_type]); 00901 tui_set_current_layout_to (new_layout); 00902 } 00903 00904 /* init_gen_win_info(). 00905 */ 00906 static void 00907 init_gen_win_info (struct tui_gen_win_info *win_info, 00908 enum tui_win_type type, 00909 int height, int width, 00910 int origin_x, int origin_y) 00911 { 00912 int h = height; 00913 00914 win_info->type = type; 00915 win_info->width = width; 00916 win_info->height = h; 00917 if (h > 1) 00918 { 00919 win_info->viewport_height = h - 1; 00920 if (win_info->type != CMD_WIN) 00921 win_info->viewport_height--; 00922 } 00923 else 00924 win_info->viewport_height = 1; 00925 win_info->origin.x = origin_x; 00926 win_info->origin.y = origin_y; 00927 00928 return; 00929 } /* init_gen_win_info */ 00930 00931 /* init_and_make_win(). 00932 */ 00933 static void * 00934 init_and_make_win (void *opaque_win_info, 00935 enum tui_win_type win_type, 00936 int height, int width, 00937 int origin_x, int origin_y, 00938 int box_it) 00939 { 00940 struct tui_gen_win_info *generic; 00941 00942 if (opaque_win_info == NULL) 00943 { 00944 if (tui_win_is_auxillary (win_type)) 00945 opaque_win_info = (void *) tui_alloc_generic_win_info (); 00946 else 00947 opaque_win_info = (void *) tui_alloc_win_info (win_type); 00948 } 00949 if (tui_win_is_auxillary (win_type)) 00950 generic = (struct tui_gen_win_info *) opaque_win_info; 00951 else 00952 generic = &((struct tui_win_info *) opaque_win_info)->generic; 00953 00954 if (opaque_win_info != NULL) 00955 { 00956 init_gen_win_info (generic, win_type, height, width, origin_x, origin_y); 00957 if (!tui_win_is_auxillary (win_type)) 00958 { 00959 if (generic->type == CMD_WIN) 00960 ((struct tui_win_info *) opaque_win_info)->can_highlight = FALSE; 00961 else 00962 ((struct tui_win_info *) opaque_win_info)->can_highlight = TRUE; 00963 } 00964 tui_make_window (generic, box_it); 00965 } 00966 return opaque_win_info; 00967 } 00968 00969 00970 static void 00971 make_source_or_disasm_window (struct tui_win_info **win_info_ptr, 00972 enum tui_win_type type, 00973 int height, int origin_y) 00974 { 00975 struct tui_gen_win_info *execution_info = (struct tui_gen_win_info *) NULL; 00976 00977 /* Create the exeuction info window. */ 00978 if (type == SRC_WIN) 00979 execution_info = tui_source_exec_info_win_ptr (); 00980 else 00981 execution_info = tui_disassem_exec_info_win_ptr (); 00982 execution_info = init_and_make_win (execution_info, 00983 EXEC_INFO_WIN, 00984 height, 00985 3, 00986 0, 00987 origin_y, 00988 DONT_BOX_WINDOW); 00989 00990 /* Now create the source window. */ 00991 *win_info_ptr = init_and_make_win (*win_info_ptr, 00992 type, 00993 height, 00994 tui_term_width () - execution_info->width, 00995 execution_info->width, 00996 origin_y, 00997 BOX_WINDOW); 00998 00999 (*win_info_ptr)->detail.source_info.execution_info = execution_info; 01000 } 01001 01002 01003 /* Show the Source/Command or the Disassem layout. */ 01004 static void 01005 show_source_or_disasm_and_command (enum tui_layout_type layout_type) 01006 { 01007 if (tui_current_layout () != layout_type) 01008 { 01009 struct tui_win_info **win_info_ptr; 01010 int src_height, cmd_height; 01011 struct tui_gen_win_info *locator = tui_locator_win_info_ptr (); 01012 01013 if (TUI_CMD_WIN != NULL) 01014 cmd_height = TUI_CMD_WIN->generic.height; 01015 else 01016 cmd_height = tui_term_height () / 3; 01017 src_height = tui_term_height () - cmd_height; 01018 01019 if (layout_type == SRC_COMMAND) 01020 win_info_ptr = &TUI_SRC_WIN; 01021 else 01022 win_info_ptr = &TUI_DISASM_WIN; 01023 01024 if ((*win_info_ptr) == NULL) 01025 { 01026 if (layout_type == SRC_COMMAND) 01027 make_source_window (win_info_ptr, src_height - 1, 0); 01028 else 01029 make_disasm_window (win_info_ptr, src_height - 1, 0); 01030 locator = init_and_make_win (locator, 01031 LOCATOR_WIN, 01032 2 /* 1 */ , 01033 tui_term_width (), 01034 0, 01035 src_height - 1, 01036 DONT_BOX_WINDOW); 01037 } 01038 else 01039 { 01040 init_gen_win_info (locator, 01041 LOCATOR_WIN, 01042 2 /* 1 */ , 01043 tui_term_width (), 01044 0, 01045 src_height - 1); 01046 (*win_info_ptr)->detail.source_info.has_locator = TRUE; 01047 init_gen_win_info (&(*win_info_ptr)->generic, 01048 (*win_info_ptr)->generic.type, 01049 src_height - 1, 01050 (*win_info_ptr)->generic.width, 01051 (*win_info_ptr)->detail.source_info.execution_info->width, 01052 0); 01053 init_gen_win_info ((*win_info_ptr)->detail.source_info.execution_info, 01054 EXEC_INFO_WIN, 01055 src_height - 1, 01056 3, 01057 0, 01058 0); 01059 (*win_info_ptr)->can_highlight = TRUE; 01060 tui_make_visible (&(*win_info_ptr)->generic); 01061 tui_make_visible ((*win_info_ptr)->detail.source_info.execution_info); 01062 } 01063 if ((*win_info_ptr) != NULL) 01064 { 01065 (*win_info_ptr)->detail.source_info.has_locator = TRUE; 01066 tui_make_visible (locator); 01067 tui_show_locator_content (); 01068 tui_show_source_content (*win_info_ptr); 01069 01070 if (TUI_CMD_WIN == NULL) 01071 { 01072 make_command_window (&TUI_CMD_WIN, cmd_height, src_height); 01073 tui_refresh_win (&TUI_CMD_WIN->generic); 01074 } 01075 else 01076 { 01077 init_gen_win_info (&TUI_CMD_WIN->generic, 01078 TUI_CMD_WIN->generic.type, 01079 TUI_CMD_WIN->generic.height, 01080 TUI_CMD_WIN->generic.width, 01081 TUI_CMD_WIN->generic.origin.x, 01082 TUI_CMD_WIN->generic.origin.y); 01083 TUI_CMD_WIN->can_highlight = FALSE; 01084 tui_make_visible (&TUI_CMD_WIN->generic); 01085 } 01086 } 01087 tui_set_current_layout_to (layout_type); 01088 } 01089 }