GDB (API)
|
00001 /* TUI window generic functions. 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 /* This module contains procedures for handling tui window functions 00023 like resize, scrolling, scrolling, changing focus, etc. 00024 00025 Author: Susan B. Macchia */ 00026 00027 #include "defs.h" 00028 #include "command.h" 00029 #include "symtab.h" 00030 #include "breakpoint.h" 00031 #include "frame.h" 00032 #include "cli/cli-cmds.h" 00033 #include "top.h" 00034 #include "source.h" 00035 00036 #include "tui/tui.h" 00037 #include "tui/tui-data.h" 00038 #include "tui/tui-wingeneral.h" 00039 #include "tui/tui-stack.h" 00040 #include "tui/tui-regs.h" 00041 #include "tui/tui-disasm.h" 00042 #include "tui/tui-source.h" 00043 #include "tui/tui-winsource.h" 00044 #include "tui/tui-windata.h" 00045 #include "tui/tui-win.h" 00046 00047 #include "gdb_curses.h" 00048 00049 #include "gdb_string.h" 00050 #include <ctype.h> 00051 #include "readline/readline.h" 00052 00053 #include <signal.h> 00054 00055 /******************************* 00056 ** Static Local Decls 00057 ********************************/ 00058 static void make_visible_with_new_height (struct tui_win_info *); 00059 static void make_invisible_and_set_new_height (struct tui_win_info *, 00060 int); 00061 static enum tui_status tui_adjust_win_heights (struct tui_win_info *, 00062 int); 00063 static int new_height_ok (struct tui_win_info *, int); 00064 static void tui_set_tab_width_command (char *, int); 00065 static void tui_refresh_all_command (char *, int); 00066 static void tui_set_win_height_command (char *, int); 00067 static void tui_xdb_set_win_height_command (char *, int); 00068 static void tui_all_windows_info (char *, int); 00069 static void tui_set_focus_command (char *, int); 00070 static void tui_scroll_forward_command (char *, int); 00071 static void tui_scroll_backward_command (char *, int); 00072 static void tui_scroll_left_command (char *, int); 00073 static void tui_scroll_right_command (char *, int); 00074 static void parse_scrolling_args (char *, 00075 struct tui_win_info **, 00076 int *); 00077 00078 00079 /*************************************** 00080 ** DEFINITIONS 00081 ***************************************/ 00082 #define WIN_HEIGHT_USAGE "Usage: winheight <win_name> [+ | -] <#lines>\n" 00083 #define XDBWIN_HEIGHT_USAGE "Usage: w <#lines>\n" 00084 #define FOCUS_USAGE "Usage: focus {<win> | next | prev}\n" 00085 00086 /*************************************** 00087 ** PUBLIC FUNCTIONS 00088 ***************************************/ 00089 00090 #ifndef ACS_LRCORNER 00091 # define ACS_LRCORNER '+' 00092 #endif 00093 #ifndef ACS_LLCORNER 00094 # define ACS_LLCORNER '+' 00095 #endif 00096 #ifndef ACS_ULCORNER 00097 # define ACS_ULCORNER '+' 00098 #endif 00099 #ifndef ACS_URCORNER 00100 # define ACS_URCORNER '+' 00101 #endif 00102 #ifndef ACS_HLINE 00103 # define ACS_HLINE '-' 00104 #endif 00105 #ifndef ACS_VLINE 00106 # define ACS_VLINE '|' 00107 #endif 00108 00109 /* Possible values for tui-border-kind variable. */ 00110 static const char *const tui_border_kind_enums[] = { 00111 "space", 00112 "ascii", 00113 "acs", 00114 NULL 00115 }; 00116 00117 /* Possible values for tui-border-mode and tui-active-border-mode. */ 00118 static const char *const tui_border_mode_enums[] = { 00119 "normal", 00120 "standout", 00121 "reverse", 00122 "half", 00123 "half-standout", 00124 "bold", 00125 "bold-standout", 00126 NULL 00127 }; 00128 00129 struct tui_translate 00130 { 00131 const char *name; 00132 int value; 00133 }; 00134 00135 /* Translation table for border-mode variables. 00136 The list of values must be terminated by a NULL. 00137 After the NULL value, an entry defines the default. */ 00138 struct tui_translate tui_border_mode_translate[] = { 00139 { "normal", A_NORMAL }, 00140 { "standout", A_STANDOUT }, 00141 { "reverse", A_REVERSE }, 00142 { "half", A_DIM }, 00143 { "half-standout", A_DIM | A_STANDOUT }, 00144 { "bold", A_BOLD }, 00145 { "bold-standout", A_BOLD | A_STANDOUT }, 00146 { 0, 0 }, 00147 { "normal", A_NORMAL } 00148 }; 00149 00150 /* Translation tables for border-kind, one for each border 00151 character (see wborder, border curses operations). 00152 -1 is used to indicate the ACS because ACS characters 00153 are determined at run time by curses (depends on terminal). */ 00154 struct tui_translate tui_border_kind_translate_vline[] = { 00155 { "space", ' ' }, 00156 { "ascii", '|' }, 00157 { "acs", -1 }, 00158 { 0, 0 }, 00159 { "ascii", '|' } 00160 }; 00161 00162 struct tui_translate tui_border_kind_translate_hline[] = { 00163 { "space", ' ' }, 00164 { "ascii", '-' }, 00165 { "acs", -1 }, 00166 { 0, 0 }, 00167 { "ascii", '-' } 00168 }; 00169 00170 struct tui_translate tui_border_kind_translate_ulcorner[] = { 00171 { "space", ' ' }, 00172 { "ascii", '+' }, 00173 { "acs", -1 }, 00174 { 0, 0 }, 00175 { "ascii", '+' } 00176 }; 00177 00178 struct tui_translate tui_border_kind_translate_urcorner[] = { 00179 { "space", ' ' }, 00180 { "ascii", '+' }, 00181 { "acs", -1 }, 00182 { 0, 0 }, 00183 { "ascii", '+' } 00184 }; 00185 00186 struct tui_translate tui_border_kind_translate_llcorner[] = { 00187 { "space", ' ' }, 00188 { "ascii", '+' }, 00189 { "acs", -1 }, 00190 { 0, 0 }, 00191 { "ascii", '+' } 00192 }; 00193 00194 struct tui_translate tui_border_kind_translate_lrcorner[] = { 00195 { "space", ' ' }, 00196 { "ascii", '+' }, 00197 { "acs", -1 }, 00198 { 0, 0 }, 00199 { "ascii", '+' } 00200 }; 00201 00202 00203 /* Tui configuration variables controlled with set/show command. */ 00204 const char *tui_active_border_mode = "bold-standout"; 00205 static void 00206 show_tui_active_border_mode (struct ui_file *file, 00207 int from_tty, 00208 struct cmd_list_element *c, 00209 const char *value) 00210 { 00211 fprintf_filtered (file, _("\ 00212 The attribute mode to use for the active TUI window border is \"%s\".\n"), 00213 value); 00214 } 00215 00216 const char *tui_border_mode = "normal"; 00217 static void 00218 show_tui_border_mode (struct ui_file *file, 00219 int from_tty, 00220 struct cmd_list_element *c, 00221 const char *value) 00222 { 00223 fprintf_filtered (file, _("\ 00224 The attribute mode to use for the TUI window borders is \"%s\".\n"), 00225 value); 00226 } 00227 00228 const char *tui_border_kind = "acs"; 00229 static void 00230 show_tui_border_kind (struct ui_file *file, 00231 int from_tty, 00232 struct cmd_list_element *c, 00233 const char *value) 00234 { 00235 fprintf_filtered (file, _("The kind of border for TUI windows is \"%s\".\n"), 00236 value); 00237 } 00238 00239 00240 /* Tui internal configuration variables. These variables are updated 00241 by tui_update_variables to reflect the tui configuration 00242 variables. */ 00243 chtype tui_border_vline; 00244 chtype tui_border_hline; 00245 chtype tui_border_ulcorner; 00246 chtype tui_border_urcorner; 00247 chtype tui_border_llcorner; 00248 chtype tui_border_lrcorner; 00249 00250 int tui_border_attrs; 00251 int tui_active_border_attrs; 00252 00253 /* Identify the item in the translation table. 00254 When the item is not recognized, use the default entry. */ 00255 static struct tui_translate * 00256 translate (const char *name, struct tui_translate *table) 00257 { 00258 while (table->name) 00259 { 00260 if (name && strcmp (table->name, name) == 0) 00261 return table; 00262 table++; 00263 } 00264 00265 /* Not found, return default entry. */ 00266 table++; 00267 return table; 00268 } 00269 00270 /* Update the tui internal configuration according to gdb settings. 00271 Returns 1 if the configuration has changed and the screen should 00272 be redrawn. */ 00273 int 00274 tui_update_variables (void) 00275 { 00276 int need_redraw = 0; 00277 struct tui_translate *entry; 00278 00279 entry = translate (tui_border_mode, tui_border_mode_translate); 00280 if (tui_border_attrs != entry->value) 00281 { 00282 tui_border_attrs = entry->value; 00283 need_redraw = 1; 00284 } 00285 entry = translate (tui_active_border_mode, tui_border_mode_translate); 00286 if (tui_active_border_attrs != entry->value) 00287 { 00288 tui_active_border_attrs = entry->value; 00289 need_redraw = 1; 00290 } 00291 00292 /* If one corner changes, all characters are changed. 00293 Only check the first one. The ACS characters are determined at 00294 run time by curses terminal management. */ 00295 entry = translate (tui_border_kind, tui_border_kind_translate_lrcorner); 00296 if (tui_border_lrcorner != (chtype) entry->value) 00297 { 00298 tui_border_lrcorner = (entry->value < 0) ? ACS_LRCORNER : entry->value; 00299 need_redraw = 1; 00300 } 00301 entry = translate (tui_border_kind, tui_border_kind_translate_llcorner); 00302 tui_border_llcorner = (entry->value < 0) ? ACS_LLCORNER : entry->value; 00303 00304 entry = translate (tui_border_kind, tui_border_kind_translate_ulcorner); 00305 tui_border_ulcorner = (entry->value < 0) ? ACS_ULCORNER : entry->value; 00306 00307 entry = translate (tui_border_kind, tui_border_kind_translate_urcorner); 00308 tui_border_urcorner = (entry->value < 0) ? ACS_URCORNER : entry->value; 00309 00310 entry = translate (tui_border_kind, tui_border_kind_translate_hline); 00311 tui_border_hline = (entry->value < 0) ? ACS_HLINE : entry->value; 00312 00313 entry = translate (tui_border_kind, tui_border_kind_translate_vline); 00314 tui_border_vline = (entry->value < 0) ? ACS_VLINE : entry->value; 00315 00316 return need_redraw; 00317 } 00318 00319 static void 00320 set_tui_cmd (char *args, int from_tty) 00321 { 00322 } 00323 00324 static void 00325 show_tui_cmd (char *args, int from_tty) 00326 { 00327 } 00328 00329 static struct cmd_list_element *tuilist; 00330 00331 static void 00332 tui_command (char *args, int from_tty) 00333 { 00334 printf_unfiltered (_("\"tui\" must be followed by the name of a " 00335 "tui command.\n")); 00336 help_list (tuilist, "tui ", -1, gdb_stdout); 00337 } 00338 00339 struct cmd_list_element ** 00340 tui_get_cmd_list (void) 00341 { 00342 if (tuilist == 0) 00343 add_prefix_cmd ("tui", class_tui, tui_command, 00344 _("Text User Interface commands."), 00345 &tuilist, "tui ", 0, &cmdlist); 00346 return &tuilist; 00347 } 00348 00349 /* Function to initialize gdb commands, for tui window 00350 manipulation. */ 00351 00352 /* Provide a prototype to silence -Wmissing-prototypes. */ 00353 extern initialize_file_ftype _initialize_tui_win; 00354 00355 void 00356 _initialize_tui_win (void) 00357 { 00358 static struct cmd_list_element *tui_setlist; 00359 static struct cmd_list_element *tui_showlist; 00360 00361 /* Define the classes of commands. 00362 They will appear in the help list in the reverse of this order. */ 00363 add_prefix_cmd ("tui", class_tui, set_tui_cmd, 00364 _("TUI configuration variables"), 00365 &tui_setlist, "set tui ", 00366 0 /* allow-unknown */, &setlist); 00367 add_prefix_cmd ("tui", class_tui, show_tui_cmd, 00368 _("TUI configuration variables"), 00369 &tui_showlist, "show tui ", 00370 0 /* allow-unknown */, &showlist); 00371 00372 add_com ("refresh", class_tui, tui_refresh_all_command, 00373 _("Refresh the terminal display.\n")); 00374 if (xdb_commands) 00375 add_com_alias ("U", "refresh", class_tui, 0); 00376 add_com ("tabset", class_tui, tui_set_tab_width_command, _("\ 00377 Set the width (in characters) of tab stops.\n\ 00378 Usage: tabset <n>\n")); 00379 add_com ("winheight", class_tui, tui_set_win_height_command, _("\ 00380 Set the height of a specified window.\n\ 00381 Usage: winheight <win_name> [+ | -] <#lines>\n\ 00382 Window names are:\n\ 00383 src : the source window\n\ 00384 cmd : the command window\n\ 00385 asm : the disassembly window\n\ 00386 regs : the register display\n")); 00387 add_com_alias ("wh", "winheight", class_tui, 0); 00388 add_info ("win", tui_all_windows_info, 00389 _("List of all displayed windows.\n")); 00390 add_com ("focus", class_tui, tui_set_focus_command, _("\ 00391 Set focus to named window or next/prev window.\n\ 00392 Usage: focus {<win> | next | prev}\n\ 00393 Valid Window names are:\n\ 00394 src : the source window\n\ 00395 asm : the disassembly window\n\ 00396 regs : the register display\n\ 00397 cmd : the command window\n")); 00398 add_com_alias ("fs", "focus", class_tui, 0); 00399 add_com ("+", class_tui, tui_scroll_forward_command, _("\ 00400 Scroll window forward.\n\ 00401 Usage: + [win] [n]\n")); 00402 add_com ("-", class_tui, tui_scroll_backward_command, _("\ 00403 Scroll window backward.\n\ 00404 Usage: - [win] [n]\n")); 00405 add_com ("<", class_tui, tui_scroll_left_command, _("\ 00406 Scroll window forward.\n\ 00407 Usage: < [win] [n]\n")); 00408 add_com (">", class_tui, tui_scroll_right_command, _("\ 00409 Scroll window backward.\n\ 00410 Usage: > [win] [n]\n")); 00411 if (xdb_commands) 00412 add_com ("w", class_xdb, tui_xdb_set_win_height_command, _("\ 00413 XDB compatibility command for setting the height of a command window.\n\ 00414 Usage: w <#lines>\n")); 00415 00416 /* Define the tui control variables. */ 00417 add_setshow_enum_cmd ("border-kind", no_class, tui_border_kind_enums, 00418 &tui_border_kind, _("\ 00419 Set the kind of border for TUI windows."), _("\ 00420 Show the kind of border for TUI windows."), _("\ 00421 This variable controls the border of TUI windows:\n\ 00422 space use a white space\n\ 00423 ascii use ascii characters + - | for the border\n\ 00424 acs use the Alternate Character Set"), 00425 NULL, 00426 show_tui_border_kind, 00427 &tui_setlist, &tui_showlist); 00428 00429 add_setshow_enum_cmd ("border-mode", no_class, tui_border_mode_enums, 00430 &tui_border_mode, _("\ 00431 Set the attribute mode to use for the TUI window borders."), _("\ 00432 Show the attribute mode to use for the TUI window borders."), _("\ 00433 This variable controls the attributes to use for the window borders:\n\ 00434 normal normal display\n\ 00435 standout use highlight mode of terminal\n\ 00436 reverse use reverse video mode\n\ 00437 half use half bright\n\ 00438 half-standout use half bright and standout mode\n\ 00439 bold use extra bright or bold\n\ 00440 bold-standout use extra bright or bold with standout mode"), 00441 NULL, 00442 show_tui_border_mode, 00443 &tui_setlist, &tui_showlist); 00444 00445 add_setshow_enum_cmd ("active-border-mode", no_class, tui_border_mode_enums, 00446 &tui_active_border_mode, _("\ 00447 Set the attribute mode to use for the active TUI window border."), _("\ 00448 Show the attribute mode to use for the active TUI window border."), _("\ 00449 This variable controls the attributes to use for the active window border:\n\ 00450 normal normal display\n\ 00451 standout use highlight mode of terminal\n\ 00452 reverse use reverse video mode\n\ 00453 half use half bright\n\ 00454 half-standout use half bright and standout mode\n\ 00455 bold use extra bright or bold\n\ 00456 bold-standout use extra bright or bold with standout mode"), 00457 NULL, 00458 show_tui_active_border_mode, 00459 &tui_setlist, &tui_showlist); 00460 } 00461 00462 /* Update gdb's knowledge of the terminal size. */ 00463 void 00464 tui_update_gdb_sizes (void) 00465 { 00466 char cmd[50]; 00467 00468 /* Set to TUI command window dimension or use readline values. */ 00469 xsnprintf (cmd, sizeof (cmd), "set width %d", 00470 tui_active ? TUI_CMD_WIN->generic.width : tui_term_width()); 00471 execute_command (cmd, 0); 00472 xsnprintf (cmd, sizeof (cmd), "set height %d", 00473 tui_active ? TUI_CMD_WIN->generic.height : tui_term_height()); 00474 execute_command (cmd, 0); 00475 } 00476 00477 00478 /* Set the logical focus to win_info. */ 00479 void 00480 tui_set_win_focus_to (struct tui_win_info *win_info) 00481 { 00482 if (win_info != NULL) 00483 { 00484 struct tui_win_info *win_with_focus = tui_win_with_focus (); 00485 00486 if (win_with_focus != NULL 00487 && win_with_focus->generic.type != CMD_WIN) 00488 tui_unhighlight_win (win_with_focus); 00489 tui_set_win_with_focus (win_info); 00490 if (win_info->generic.type != CMD_WIN) 00491 tui_highlight_win (win_info); 00492 } 00493 } 00494 00495 00496 void 00497 tui_scroll_forward (struct tui_win_info *win_to_scroll, 00498 int num_to_scroll) 00499 { 00500 if (win_to_scroll != TUI_CMD_WIN) 00501 { 00502 int _num_to_scroll = num_to_scroll; 00503 00504 if (num_to_scroll == 0) 00505 _num_to_scroll = win_to_scroll->generic.height - 3; 00506 00507 /* If we are scrolling the source or disassembly window, do a 00508 "psuedo" scroll since not all of the source is in memory, 00509 only what is in the viewport. If win_to_scroll is the 00510 command window do nothing since the term should handle 00511 it. */ 00512 if (win_to_scroll == TUI_SRC_WIN) 00513 tui_vertical_source_scroll (FORWARD_SCROLL, _num_to_scroll); 00514 else if (win_to_scroll == TUI_DISASM_WIN) 00515 tui_vertical_disassem_scroll (FORWARD_SCROLL, _num_to_scroll); 00516 else if (win_to_scroll == TUI_DATA_WIN) 00517 tui_vertical_data_scroll (FORWARD_SCROLL, _num_to_scroll); 00518 } 00519 } 00520 00521 void 00522 tui_scroll_backward (struct tui_win_info *win_to_scroll, 00523 int num_to_scroll) 00524 { 00525 if (win_to_scroll != TUI_CMD_WIN) 00526 { 00527 int _num_to_scroll = num_to_scroll; 00528 00529 if (num_to_scroll == 0) 00530 _num_to_scroll = win_to_scroll->generic.height - 3; 00531 00532 /* If we are scrolling the source or disassembly window, do a 00533 "psuedo" scroll since not all of the source is in memory, 00534 only what is in the viewport. If win_to_scroll is the 00535 command window do nothing since the term should handle 00536 it. */ 00537 if (win_to_scroll == TUI_SRC_WIN) 00538 tui_vertical_source_scroll (BACKWARD_SCROLL, _num_to_scroll); 00539 else if (win_to_scroll == TUI_DISASM_WIN) 00540 tui_vertical_disassem_scroll (BACKWARD_SCROLL, _num_to_scroll); 00541 else if (win_to_scroll == TUI_DATA_WIN) 00542 tui_vertical_data_scroll (BACKWARD_SCROLL, _num_to_scroll); 00543 } 00544 } 00545 00546 00547 void 00548 tui_scroll_left (struct tui_win_info *win_to_scroll, 00549 int num_to_scroll) 00550 { 00551 if (win_to_scroll != TUI_CMD_WIN) 00552 { 00553 int _num_to_scroll = num_to_scroll; 00554 00555 if (_num_to_scroll == 0) 00556 _num_to_scroll = 1; 00557 00558 /* If we are scrolling the source or disassembly window, do a 00559 "psuedo" scroll since not all of the source is in memory, 00560 only what is in the viewport. If win_to_scroll is the command 00561 window do nothing since the term should handle it. */ 00562 if (win_to_scroll == TUI_SRC_WIN 00563 || win_to_scroll == TUI_DISASM_WIN) 00564 tui_horizontal_source_scroll (win_to_scroll, LEFT_SCROLL, 00565 _num_to_scroll); 00566 } 00567 } 00568 00569 00570 void 00571 tui_scroll_right (struct tui_win_info *win_to_scroll, 00572 int num_to_scroll) 00573 { 00574 if (win_to_scroll != TUI_CMD_WIN) 00575 { 00576 int _num_to_scroll = num_to_scroll; 00577 00578 if (_num_to_scroll == 0) 00579 _num_to_scroll = 1; 00580 00581 /* If we are scrolling the source or disassembly window, do a 00582 "psuedo" scroll since not all of the source is in memory, 00583 only what is in the viewport. If win_to_scroll is the command 00584 window do nothing since the term should handle it. */ 00585 if (win_to_scroll == TUI_SRC_WIN 00586 || win_to_scroll == TUI_DISASM_WIN) 00587 tui_horizontal_source_scroll (win_to_scroll, RIGHT_SCROLL, 00588 _num_to_scroll); 00589 } 00590 } 00591 00592 00593 /* Scroll a window. Arguments are passed through a va_list. */ 00594 void 00595 tui_scroll (enum tui_scroll_direction direction, 00596 struct tui_win_info *win_to_scroll, 00597 int num_to_scroll) 00598 { 00599 switch (direction) 00600 { 00601 case FORWARD_SCROLL: 00602 tui_scroll_forward (win_to_scroll, num_to_scroll); 00603 break; 00604 case BACKWARD_SCROLL: 00605 tui_scroll_backward (win_to_scroll, num_to_scroll); 00606 break; 00607 case LEFT_SCROLL: 00608 tui_scroll_left (win_to_scroll, num_to_scroll); 00609 break; 00610 case RIGHT_SCROLL: 00611 tui_scroll_right (win_to_scroll, num_to_scroll); 00612 break; 00613 default: 00614 break; 00615 } 00616 } 00617 00618 00619 void 00620 tui_refresh_all_win (void) 00621 { 00622 enum tui_win_type type; 00623 00624 clearok (curscr, TRUE); 00625 tui_refresh_all (tui_win_list); 00626 for (type = SRC_WIN; type < MAX_MAJOR_WINDOWS; type++) 00627 { 00628 if (tui_win_list[type] 00629 && tui_win_list[type]->generic.is_visible) 00630 { 00631 switch (type) 00632 { 00633 case SRC_WIN: 00634 case DISASSEM_WIN: 00635 tui_show_source_content (tui_win_list[type]); 00636 tui_check_and_display_highlight_if_needed (tui_win_list[type]); 00637 tui_erase_exec_info_content (tui_win_list[type]); 00638 tui_update_exec_info (tui_win_list[type]); 00639 break; 00640 case DATA_WIN: 00641 tui_refresh_data_win (); 00642 break; 00643 default: 00644 break; 00645 } 00646 } 00647 } 00648 tui_show_locator_content (); 00649 } 00650 00651 00652 /* Resize all the windows based on the terminal size. This function 00653 gets called from within the readline sinwinch handler. */ 00654 void 00655 tui_resize_all (void) 00656 { 00657 int height_diff, width_diff; 00658 int screenheight, screenwidth; 00659 00660 rl_get_screen_size (&screenheight, &screenwidth); 00661 width_diff = screenwidth - tui_term_width (); 00662 height_diff = screenheight - tui_term_height (); 00663 if (height_diff || width_diff) 00664 { 00665 enum tui_layout_type cur_layout = tui_current_layout (); 00666 struct tui_win_info *win_with_focus = tui_win_with_focus (); 00667 struct tui_win_info *first_win; 00668 struct tui_win_info *second_win; 00669 struct tui_gen_win_info *locator = tui_locator_win_info_ptr (); 00670 enum tui_win_type win_type; 00671 int new_height, split_diff, cmd_split_diff, num_wins_displayed = 2; 00672 00673 #ifdef HAVE_RESIZE_TERM 00674 resize_term (screenheight, screenwidth); 00675 #endif 00676 /* Turn keypad off while we resize. */ 00677 if (win_with_focus != TUI_CMD_WIN) 00678 keypad (TUI_CMD_WIN->generic.handle, FALSE); 00679 tui_update_gdb_sizes (); 00680 tui_set_term_height_to (screenheight); 00681 tui_set_term_width_to (screenwidth); 00682 if (cur_layout == SRC_DISASSEM_COMMAND 00683 || cur_layout == SRC_DATA_COMMAND 00684 || cur_layout == DISASSEM_DATA_COMMAND) 00685 num_wins_displayed++; 00686 split_diff = height_diff / num_wins_displayed; 00687 cmd_split_diff = split_diff; 00688 if (height_diff % num_wins_displayed) 00689 { 00690 if (height_diff < 0) 00691 cmd_split_diff--; 00692 else 00693 cmd_split_diff++; 00694 } 00695 /* Now adjust each window. */ 00696 /* erase + clearok are used instead of a straightforward clear as 00697 AIX 5.3 does not define clear. */ 00698 erase (); 00699 clearok (curscr, TRUE); 00700 refresh (); 00701 switch (cur_layout) 00702 { 00703 case SRC_COMMAND: 00704 case DISASSEM_COMMAND: 00705 first_win = (struct tui_win_info *) (tui_source_windows ())->list[0]; 00706 first_win->generic.width += width_diff; 00707 locator->width += width_diff; 00708 /* Check for invalid heights. */ 00709 if (height_diff == 0) 00710 new_height = first_win->generic.height; 00711 else if ((first_win->generic.height + split_diff) >= 00712 (screenheight - MIN_CMD_WIN_HEIGHT - 1)) 00713 new_height = screenheight - MIN_CMD_WIN_HEIGHT - 1; 00714 else if ((first_win->generic.height + split_diff) <= 0) 00715 new_height = MIN_WIN_HEIGHT; 00716 else 00717 new_height = first_win->generic.height + split_diff; 00718 00719 locator->origin.y = new_height + 1; 00720 make_invisible_and_set_new_height (first_win, new_height); 00721 TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1; 00722 TUI_CMD_WIN->generic.width += width_diff; 00723 new_height = screenheight - TUI_CMD_WIN->generic.origin.y; 00724 make_invisible_and_set_new_height (TUI_CMD_WIN, new_height); 00725 make_visible_with_new_height (first_win); 00726 make_visible_with_new_height (TUI_CMD_WIN); 00727 if (first_win->generic.content_size <= 0) 00728 tui_erase_source_content (first_win, EMPTY_SOURCE_PROMPT); 00729 break; 00730 default: 00731 if (cur_layout == SRC_DISASSEM_COMMAND) 00732 { 00733 first_win = TUI_SRC_WIN; 00734 first_win->generic.width += width_diff; 00735 second_win = TUI_DISASM_WIN; 00736 second_win->generic.width += width_diff; 00737 } 00738 else 00739 { 00740 first_win = TUI_DATA_WIN; 00741 first_win->generic.width += width_diff; 00742 second_win = (struct tui_win_info *) 00743 (tui_source_windows ())->list[0]; 00744 second_win->generic.width += width_diff; 00745 } 00746 /* Change the first window's height/width. */ 00747 /* Check for invalid heights. */ 00748 if (height_diff == 0) 00749 new_height = first_win->generic.height; 00750 else if ((first_win->generic.height + 00751 second_win->generic.height + (split_diff * 2)) >= 00752 (screenheight - MIN_CMD_WIN_HEIGHT - 1)) 00753 new_height = (screenheight - MIN_CMD_WIN_HEIGHT - 1) / 2; 00754 else if ((first_win->generic.height + split_diff) <= 0) 00755 new_height = MIN_WIN_HEIGHT; 00756 else 00757 new_height = first_win->generic.height + split_diff; 00758 make_invisible_and_set_new_height (first_win, new_height); 00759 00760 locator->width += width_diff; 00761 00762 /* Change the second window's height/width. */ 00763 /* Check for invalid heights. */ 00764 if (height_diff == 0) 00765 new_height = second_win->generic.height; 00766 else if ((first_win->generic.height + 00767 second_win->generic.height + (split_diff * 2)) >= 00768 (screenheight - MIN_CMD_WIN_HEIGHT - 1)) 00769 { 00770 new_height = screenheight - MIN_CMD_WIN_HEIGHT - 1; 00771 if (new_height % 2) 00772 new_height = (new_height / 2) + 1; 00773 else 00774 new_height /= 2; 00775 } 00776 else if ((second_win->generic.height + split_diff) <= 0) 00777 new_height = MIN_WIN_HEIGHT; 00778 else 00779 new_height = second_win->generic.height + split_diff; 00780 second_win->generic.origin.y = first_win->generic.height - 1; 00781 make_invisible_and_set_new_height (second_win, new_height); 00782 00783 /* Change the command window's height/width. */ 00784 TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1; 00785 make_invisible_and_set_new_height (TUI_CMD_WIN, 00786 TUI_CMD_WIN->generic.height 00787 + cmd_split_diff); 00788 make_visible_with_new_height (first_win); 00789 make_visible_with_new_height (second_win); 00790 make_visible_with_new_height (TUI_CMD_WIN); 00791 if (first_win->generic.content_size <= 0) 00792 tui_erase_source_content (first_win, EMPTY_SOURCE_PROMPT); 00793 if (second_win->generic.content_size <= 0) 00794 tui_erase_source_content (second_win, EMPTY_SOURCE_PROMPT); 00795 break; 00796 } 00797 /* Now remove all invisible windows, and their content so that 00798 they get created again when called for with the new size. */ 00799 for (win_type = SRC_WIN; (win_type < MAX_MAJOR_WINDOWS); win_type++) 00800 { 00801 if (win_type != CMD_WIN 00802 && (tui_win_list[win_type] != NULL) 00803 && !tui_win_list[win_type]->generic.is_visible) 00804 { 00805 tui_free_window (tui_win_list[win_type]); 00806 tui_win_list[win_type] = (struct tui_win_info *) NULL; 00807 } 00808 } 00809 /* Turn keypad back on, unless focus is in the command 00810 window. */ 00811 if (win_with_focus != TUI_CMD_WIN) 00812 keypad (TUI_CMD_WIN->generic.handle, TRUE); 00813 } 00814 } 00815 00816 #ifdef SIGWINCH 00817 /* SIGWINCH signal handler for the tui. This signal handler is always 00818 called, even when the readline package clears signals because it is 00819 set as the old_sigwinch() (TUI only). */ 00820 static void 00821 tui_sigwinch_handler (int signal) 00822 { 00823 /* Say that a resize was done so that the readline can do it later 00824 when appropriate. */ 00825 tui_set_win_resized_to (TRUE); 00826 } 00827 #endif 00828 00829 /* Initializes SIGWINCH signal handler for the tui. */ 00830 void 00831 tui_initialize_win (void) 00832 { 00833 #ifdef SIGWINCH 00834 #ifdef HAVE_SIGACTION 00835 struct sigaction old_winch; 00836 00837 memset (&old_winch, 0, sizeof (old_winch)); 00838 old_winch.sa_handler = &tui_sigwinch_handler; 00839 sigaction (SIGWINCH, &old_winch, NULL); 00840 #else 00841 signal (SIGWINCH, &tui_sigwinch_handler); 00842 #endif 00843 #endif 00844 } 00845 00846 00847 /************************* 00848 ** STATIC LOCAL FUNCTIONS 00849 **************************/ 00850 00851 00852 static void 00853 tui_scroll_forward_command (char *arg, int from_tty) 00854 { 00855 int num_to_scroll = 1; 00856 struct tui_win_info *win_to_scroll; 00857 00858 /* Make sure the curses mode is enabled. */ 00859 tui_enable (); 00860 if (arg == (char *) NULL) 00861 parse_scrolling_args (arg, &win_to_scroll, (int *) NULL); 00862 else 00863 parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll); 00864 tui_scroll (FORWARD_SCROLL, win_to_scroll, num_to_scroll); 00865 } 00866 00867 00868 static void 00869 tui_scroll_backward_command (char *arg, int from_tty) 00870 { 00871 int num_to_scroll = 1; 00872 struct tui_win_info *win_to_scroll; 00873 00874 /* Make sure the curses mode is enabled. */ 00875 tui_enable (); 00876 if (arg == (char *) NULL) 00877 parse_scrolling_args (arg, &win_to_scroll, (int *) NULL); 00878 else 00879 parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll); 00880 tui_scroll (BACKWARD_SCROLL, win_to_scroll, num_to_scroll); 00881 } 00882 00883 00884 static void 00885 tui_scroll_left_command (char *arg, int from_tty) 00886 { 00887 int num_to_scroll; 00888 struct tui_win_info *win_to_scroll; 00889 00890 /* Make sure the curses mode is enabled. */ 00891 tui_enable (); 00892 parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll); 00893 tui_scroll (LEFT_SCROLL, win_to_scroll, num_to_scroll); 00894 } 00895 00896 00897 static void 00898 tui_scroll_right_command (char *arg, int from_tty) 00899 { 00900 int num_to_scroll; 00901 struct tui_win_info *win_to_scroll; 00902 00903 /* Make sure the curses mode is enabled. */ 00904 tui_enable (); 00905 parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll); 00906 tui_scroll (RIGHT_SCROLL, win_to_scroll, num_to_scroll); 00907 } 00908 00909 00910 /* Set focus to the window named by 'arg'. */ 00911 static void 00912 tui_set_focus (char *arg, int from_tty) 00913 { 00914 if (arg != (char *) NULL) 00915 { 00916 char *buf_ptr = (char *) xstrdup (arg); 00917 int i; 00918 struct tui_win_info *win_info = (struct tui_win_info *) NULL; 00919 00920 for (i = 0; (i < strlen (buf_ptr)); i++) 00921 buf_ptr[i] = toupper (arg[i]); 00922 00923 if (subset_compare (buf_ptr, "NEXT")) 00924 win_info = tui_next_win (tui_win_with_focus ()); 00925 else if (subset_compare (buf_ptr, "PREV")) 00926 win_info = tui_prev_win (tui_win_with_focus ()); 00927 else 00928 win_info = tui_partial_win_by_name (buf_ptr); 00929 00930 if (win_info == (struct tui_win_info *) NULL 00931 || !win_info->generic.is_visible) 00932 warning (_("Invalid window specified. \n\ 00933 The window name specified must be valid and visible.\n")); 00934 else 00935 { 00936 tui_set_win_focus_to (win_info); 00937 keypad (TUI_CMD_WIN->generic.handle, (win_info != TUI_CMD_WIN)); 00938 } 00939 00940 if (TUI_DATA_WIN && TUI_DATA_WIN->generic.is_visible) 00941 tui_refresh_data_win (); 00942 xfree (buf_ptr); 00943 printf_filtered (_("Focus set to %s window.\n"), 00944 tui_win_name ((struct tui_gen_win_info *) 00945 tui_win_with_focus ())); 00946 } 00947 else 00948 warning (_("Incorrect Number of Arguments.\n%s"), FOCUS_USAGE); 00949 } 00950 00951 static void 00952 tui_set_focus_command (char *arg, int from_tty) 00953 { 00954 /* Make sure the curses mode is enabled. */ 00955 tui_enable (); 00956 tui_set_focus (arg, from_tty); 00957 } 00958 00959 00960 static void 00961 tui_all_windows_info (char *arg, int from_tty) 00962 { 00963 enum tui_win_type type; 00964 struct tui_win_info *win_with_focus = tui_win_with_focus (); 00965 00966 for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++) 00967 if (tui_win_list[type] 00968 && tui_win_list[type]->generic.is_visible) 00969 { 00970 if (win_with_focus == tui_win_list[type]) 00971 printf_filtered (" %s\t(%d lines) <has focus>\n", 00972 tui_win_name (&tui_win_list[type]->generic), 00973 tui_win_list[type]->generic.height); 00974 else 00975 printf_filtered (" %s\t(%d lines)\n", 00976 tui_win_name (&tui_win_list[type]->generic), 00977 tui_win_list[type]->generic.height); 00978 } 00979 } 00980 00981 00982 static void 00983 tui_refresh_all_command (char *arg, int from_tty) 00984 { 00985 /* Make sure the curses mode is enabled. */ 00986 tui_enable (); 00987 00988 tui_refresh_all_win (); 00989 } 00990 00991 00992 /* Set the height of the specified window. */ 00993 static void 00994 tui_set_tab_width_command (char *arg, int from_tty) 00995 { 00996 /* Make sure the curses mode is enabled. */ 00997 tui_enable (); 00998 if (arg != (char *) NULL) 00999 { 01000 int ts; 01001 01002 ts = atoi (arg); 01003 if (ts > 0) 01004 tui_set_default_tab_len (ts); 01005 else 01006 warning (_("Tab widths greater than 0 must be specified.")); 01007 } 01008 } 01009 01010 01011 /* Set the height of the specified window. */ 01012 static void 01013 tui_set_win_height (char *arg, int from_tty) 01014 { 01015 /* Make sure the curses mode is enabled. */ 01016 tui_enable (); 01017 if (arg != (char *) NULL) 01018 { 01019 char *buf = xstrdup (arg); 01020 char *buf_ptr = buf; 01021 char *wname = (char *) NULL; 01022 int new_height, i; 01023 struct tui_win_info *win_info; 01024 01025 wname = buf_ptr; 01026 buf_ptr = strchr (buf_ptr, ' '); 01027 if (buf_ptr != (char *) NULL) 01028 { 01029 *buf_ptr = (char) 0; 01030 01031 /* Validate the window name. */ 01032 for (i = 0; i < strlen (wname); i++) 01033 wname[i] = toupper (wname[i]); 01034 win_info = tui_partial_win_by_name (wname); 01035 01036 if (win_info == (struct tui_win_info *) NULL 01037 || !win_info->generic.is_visible) 01038 warning (_("Invalid window specified. \n\ 01039 The window name specified must be valid and visible.\n")); 01040 else 01041 { 01042 /* Process the size. */ 01043 while (*(++buf_ptr) == ' ') 01044 ; 01045 01046 if (*buf_ptr != (char) 0) 01047 { 01048 int negate = FALSE; 01049 int fixed_size = TRUE; 01050 int input_no;; 01051 01052 if (*buf_ptr == '+' || *buf_ptr == '-') 01053 { 01054 if (*buf_ptr == '-') 01055 negate = TRUE; 01056 fixed_size = FALSE; 01057 buf_ptr++; 01058 } 01059 input_no = atoi (buf_ptr); 01060 if (input_no > 0) 01061 { 01062 if (negate) 01063 input_no *= (-1); 01064 if (fixed_size) 01065 new_height = input_no; 01066 else 01067 new_height = win_info->generic.height + input_no; 01068 01069 /* Now change the window's height, and adjust 01070 all other windows around it. */ 01071 if (tui_adjust_win_heights (win_info, 01072 new_height) == TUI_FAILURE) 01073 warning (_("Invalid window height specified.\n%s"), 01074 WIN_HEIGHT_USAGE); 01075 else 01076 tui_update_gdb_sizes (); 01077 } 01078 else 01079 warning (_("Invalid window height specified.\n%s"), 01080 WIN_HEIGHT_USAGE); 01081 } 01082 } 01083 } 01084 else 01085 printf_filtered (WIN_HEIGHT_USAGE); 01086 01087 if (buf != (char *) NULL) 01088 xfree (buf); 01089 } 01090 else 01091 printf_filtered (WIN_HEIGHT_USAGE); 01092 } 01093 01094 /* Set the height of the specified window, with va_list. */ 01095 static void 01096 tui_set_win_height_command (char *arg, int from_tty) 01097 { 01098 /* Make sure the curses mode is enabled. */ 01099 tui_enable (); 01100 tui_set_win_height (arg, from_tty); 01101 } 01102 01103 01104 /* XDB Compatibility command for setting the window height. This will 01105 increase or decrease the command window by the specified 01106 amount. */ 01107 static void 01108 tui_xdb_set_win_height (char *arg, int from_tty) 01109 { 01110 /* Make sure the curses mode is enabled. */ 01111 tui_enable (); 01112 if (arg != (char *) NULL) 01113 { 01114 int input_no = atoi (arg); 01115 01116 if (input_no > 0) 01117 { /* Add 1 for the locator. */ 01118 int new_height = tui_term_height () - (input_no + 1); 01119 01120 if (!new_height_ok (tui_win_list[CMD_WIN], new_height) 01121 || tui_adjust_win_heights (tui_win_list[CMD_WIN], 01122 new_height) == TUI_FAILURE) 01123 warning (_("Invalid window height specified.\n%s"), 01124 XDBWIN_HEIGHT_USAGE); 01125 } 01126 else 01127 warning (_("Invalid window height specified.\n%s"), 01128 XDBWIN_HEIGHT_USAGE); 01129 } 01130 else 01131 warning (_("Invalid window height specified.\n%s"), XDBWIN_HEIGHT_USAGE); 01132 } 01133 01134 /* Set the height of the specified window, with va_list. */ 01135 static void 01136 tui_xdb_set_win_height_command (char *arg, int from_tty) 01137 { 01138 tui_xdb_set_win_height (arg, from_tty); 01139 } 01140 01141 01142 /* Function to adjust all window heights around the primary. */ 01143 static enum tui_status 01144 tui_adjust_win_heights (struct tui_win_info *primary_win_info, 01145 int new_height) 01146 { 01147 enum tui_status status = TUI_FAILURE; 01148 01149 if (new_height_ok (primary_win_info, new_height)) 01150 { 01151 status = TUI_SUCCESS; 01152 if (new_height != primary_win_info->generic.height) 01153 { 01154 int diff; 01155 struct tui_win_info *win_info; 01156 struct tui_gen_win_info *locator = tui_locator_win_info_ptr (); 01157 enum tui_layout_type cur_layout = tui_current_layout (); 01158 01159 diff = (new_height - primary_win_info->generic.height) * (-1); 01160 if (cur_layout == SRC_COMMAND 01161 || cur_layout == DISASSEM_COMMAND) 01162 { 01163 struct tui_win_info *src_win_info; 01164 01165 make_invisible_and_set_new_height (primary_win_info, new_height); 01166 if (primary_win_info->generic.type == CMD_WIN) 01167 { 01168 win_info = (tui_source_windows ())->list[0]; 01169 src_win_info = win_info; 01170 } 01171 else 01172 { 01173 win_info = tui_win_list[CMD_WIN]; 01174 src_win_info = primary_win_info; 01175 } 01176 make_invisible_and_set_new_height (win_info, 01177 win_info->generic.height + diff); 01178 TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1; 01179 make_visible_with_new_height (win_info); 01180 make_visible_with_new_height (primary_win_info); 01181 if (src_win_info->generic.content_size <= 0) 01182 tui_erase_source_content (src_win_info, EMPTY_SOURCE_PROMPT); 01183 } 01184 else 01185 { 01186 struct tui_win_info *first_win; 01187 struct tui_win_info *second_win; 01188 01189 if (cur_layout == SRC_DISASSEM_COMMAND) 01190 { 01191 first_win = TUI_SRC_WIN; 01192 second_win = TUI_DISASM_WIN; 01193 } 01194 else 01195 { 01196 first_win = TUI_DATA_WIN; 01197 second_win = (tui_source_windows ())->list[0]; 01198 } 01199 if (primary_win_info == TUI_CMD_WIN) 01200 { /* Split the change in height accross the 1st & 2nd 01201 windows, adjusting them as well. */ 01202 /* Subtract the locator. */ 01203 int first_split_diff = diff / 2; 01204 int second_split_diff = first_split_diff; 01205 01206 if (diff % 2) 01207 { 01208 if (first_win->generic.height > 01209 second_win->generic.height) 01210 if (diff < 0) 01211 first_split_diff--; 01212 else 01213 first_split_diff++; 01214 else 01215 { 01216 if (diff < 0) 01217 second_split_diff--; 01218 else 01219 second_split_diff++; 01220 } 01221 } 01222 /* Make sure that the minimum hieghts are 01223 honored. */ 01224 while ((first_win->generic.height + first_split_diff) < 3) 01225 { 01226 first_split_diff++; 01227 second_split_diff--; 01228 } 01229 while ((second_win->generic.height + second_split_diff) < 3) 01230 { 01231 second_split_diff++; 01232 first_split_diff--; 01233 } 01234 make_invisible_and_set_new_height ( 01235 first_win, 01236 first_win->generic.height + first_split_diff); 01237 second_win->generic.origin.y = first_win->generic.height - 1; 01238 make_invisible_and_set_new_height (second_win, 01239 second_win->generic.height 01240 + second_split_diff); 01241 TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1; 01242 make_invisible_and_set_new_height (TUI_CMD_WIN, new_height); 01243 } 01244 else 01245 { 01246 if ((TUI_CMD_WIN->generic.height + diff) < 1) 01247 { /* If there is no way to increase the command 01248 window take real estate from the 1st or 2nd 01249 window. */ 01250 if ((TUI_CMD_WIN->generic.height + diff) < 1) 01251 { 01252 int i; 01253 01254 for (i = TUI_CMD_WIN->generic.height + diff; 01255 (i < 1); i++) 01256 if (primary_win_info == first_win) 01257 second_win->generic.height--; 01258 else 01259 first_win->generic.height--; 01260 } 01261 } 01262 if (primary_win_info == first_win) 01263 make_invisible_and_set_new_height (first_win, new_height); 01264 else 01265 make_invisible_and_set_new_height ( 01266 first_win, 01267 first_win->generic.height); 01268 second_win->generic.origin.y = first_win->generic.height - 1; 01269 if (primary_win_info == second_win) 01270 make_invisible_and_set_new_height (second_win, new_height); 01271 else 01272 make_invisible_and_set_new_height ( 01273 second_win, second_win->generic.height); 01274 TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1; 01275 if ((TUI_CMD_WIN->generic.height + diff) < 1) 01276 make_invisible_and_set_new_height (TUI_CMD_WIN, 1); 01277 else 01278 make_invisible_and_set_new_height (TUI_CMD_WIN, 01279 TUI_CMD_WIN->generic.height + diff); 01280 } 01281 make_visible_with_new_height (TUI_CMD_WIN); 01282 make_visible_with_new_height (second_win); 01283 make_visible_with_new_height (first_win); 01284 if (first_win->generic.content_size <= 0) 01285 tui_erase_source_content (first_win, EMPTY_SOURCE_PROMPT); 01286 if (second_win->generic.content_size <= 0) 01287 tui_erase_source_content (second_win, EMPTY_SOURCE_PROMPT); 01288 } 01289 } 01290 } 01291 01292 return status; 01293 } 01294 01295 01296 /* Function make the target window (and auxillary windows associated 01297 with the targer) invisible, and set the new height and 01298 location. */ 01299 static void 01300 make_invisible_and_set_new_height (struct tui_win_info *win_info, 01301 int height) 01302 { 01303 int i; 01304 struct tui_gen_win_info *gen_win_info; 01305 01306 tui_make_invisible (&win_info->generic); 01307 win_info->generic.height = height; 01308 if (height > 1) 01309 win_info->generic.viewport_height = height - 1; 01310 else 01311 win_info->generic.viewport_height = height; 01312 if (win_info != TUI_CMD_WIN) 01313 win_info->generic.viewport_height--; 01314 01315 /* Now deal with the auxillary windows associated with win_info. */ 01316 switch (win_info->generic.type) 01317 { 01318 case SRC_WIN: 01319 case DISASSEM_WIN: 01320 gen_win_info = win_info->detail.source_info.execution_info; 01321 tui_make_invisible (gen_win_info); 01322 gen_win_info->height = height; 01323 gen_win_info->origin.y = win_info->generic.origin.y; 01324 if (height > 1) 01325 gen_win_info->viewport_height = height - 1; 01326 else 01327 gen_win_info->viewport_height = height; 01328 if (win_info != TUI_CMD_WIN) 01329 gen_win_info->viewport_height--; 01330 01331 if (tui_win_has_locator (win_info)) 01332 { 01333 gen_win_info = tui_locator_win_info_ptr (); 01334 tui_make_invisible (gen_win_info); 01335 gen_win_info->origin.y = win_info->generic.origin.y + height; 01336 } 01337 break; 01338 case DATA_WIN: 01339 /* Delete all data item windows. */ 01340 for (i = 0; i < win_info->generic.content_size; i++) 01341 { 01342 gen_win_info = (struct tui_gen_win_info *) 01343 &((struct tui_win_element *) 01344 win_info->generic.content[i])->which_element.data_window; 01345 tui_delete_win (gen_win_info->handle); 01346 gen_win_info->handle = (WINDOW *) NULL; 01347 } 01348 break; 01349 default: 01350 break; 01351 } 01352 } 01353 01354 01355 /* Function to make the windows with new heights visible. This means 01356 re-creating the windows' content since the window had to be 01357 destroyed to be made invisible. */ 01358 static void 01359 make_visible_with_new_height (struct tui_win_info *win_info) 01360 { 01361 struct symtab *s; 01362 01363 tui_make_visible (&win_info->generic); 01364 tui_check_and_display_highlight_if_needed (win_info); 01365 switch (win_info->generic.type) 01366 { 01367 case SRC_WIN: 01368 case DISASSEM_WIN: 01369 tui_free_win_content (win_info->detail.source_info.execution_info); 01370 tui_make_visible (win_info->detail.source_info.execution_info); 01371 if (win_info->generic.content != NULL) 01372 { 01373 struct gdbarch *gdbarch = win_info->detail.source_info.gdbarch; 01374 struct tui_line_or_address line_or_addr; 01375 struct symtab_and_line cursal 01376 = get_current_source_symtab_and_line (); 01377 01378 line_or_addr = win_info->detail.source_info.start_line_or_addr; 01379 tui_free_win_content (&win_info->generic); 01380 tui_update_source_window (win_info, gdbarch, 01381 cursal.symtab, line_or_addr, TRUE); 01382 } 01383 else if (deprecated_safe_get_selected_frame () != NULL) 01384 { 01385 struct tui_line_or_address line; 01386 struct symtab_and_line cursal 01387 = get_current_source_symtab_and_line (); 01388 struct frame_info *frame = deprecated_safe_get_selected_frame (); 01389 struct gdbarch *gdbarch = get_frame_arch (frame); 01390 01391 s = find_pc_symtab (get_frame_pc (frame)); 01392 if (win_info->generic.type == SRC_WIN) 01393 { 01394 line.loa = LOA_LINE; 01395 line.u.line_no = cursal.line; 01396 } 01397 else 01398 { 01399 line.loa = LOA_ADDRESS; 01400 find_line_pc (s, cursal.line, &line.u.addr); 01401 } 01402 tui_update_source_window (win_info, gdbarch, s, line, TRUE); 01403 } 01404 if (tui_win_has_locator (win_info)) 01405 { 01406 tui_make_visible (tui_locator_win_info_ptr ()); 01407 tui_show_locator_content (); 01408 } 01409 break; 01410 case DATA_WIN: 01411 tui_display_all_data (); 01412 break; 01413 case CMD_WIN: 01414 win_info->detail.command_info.cur_line = 0; 01415 win_info->detail.command_info.curch = 0; 01416 #ifdef HAVE_WRESIZE 01417 wresize (TUI_CMD_WIN->generic.handle, 01418 TUI_CMD_WIN->generic.height, 01419 TUI_CMD_WIN->generic.width); 01420 #endif 01421 mvwin (TUI_CMD_WIN->generic.handle, 01422 TUI_CMD_WIN->generic.origin.y, 01423 TUI_CMD_WIN->generic.origin.x); 01424 wmove (win_info->generic.handle, 01425 win_info->detail.command_info.cur_line, 01426 win_info->detail.command_info.curch); 01427 break; 01428 default: 01429 break; 01430 } 01431 } 01432 01433 01434 static int 01435 new_height_ok (struct tui_win_info *primary_win_info, 01436 int new_height) 01437 { 01438 int ok = (new_height < tui_term_height ()); 01439 01440 if (ok) 01441 { 01442 int diff; 01443 enum tui_layout_type cur_layout = tui_current_layout (); 01444 01445 diff = (new_height - primary_win_info->generic.height) * (-1); 01446 if (cur_layout == SRC_COMMAND || cur_layout == DISASSEM_COMMAND) 01447 { 01448 ok = ((primary_win_info->generic.type == CMD_WIN 01449 && new_height <= (tui_term_height () - 4) 01450 && new_height >= MIN_CMD_WIN_HEIGHT) 01451 || (primary_win_info->generic.type != CMD_WIN 01452 && new_height <= (tui_term_height () - 2) 01453 && new_height >= MIN_WIN_HEIGHT)); 01454 if (ok) 01455 { /* Check the total height. */ 01456 struct tui_win_info *win_info; 01457 01458 if (primary_win_info == TUI_CMD_WIN) 01459 win_info = (tui_source_windows ())->list[0]; 01460 else 01461 win_info = TUI_CMD_WIN; 01462 ok = ((new_height + 01463 (win_info->generic.height + diff)) <= tui_term_height ()); 01464 } 01465 } 01466 else 01467 { 01468 int cur_total_height, total_height, min_height = 0; 01469 struct tui_win_info *first_win; 01470 struct tui_win_info *second_win; 01471 01472 if (cur_layout == SRC_DISASSEM_COMMAND) 01473 { 01474 first_win = TUI_SRC_WIN; 01475 second_win = TUI_DISASM_WIN; 01476 } 01477 else 01478 { 01479 first_win = TUI_DATA_WIN; 01480 second_win = (tui_source_windows ())->list[0]; 01481 } 01482 /* We could simply add all the heights to obtain the same 01483 result but below is more explicit since we subtract 1 for 01484 the line that the first and second windows share, and add 01485 one for the locator. */ 01486 total_height = cur_total_height = 01487 (first_win->generic.height + second_win->generic.height - 1) 01488 + TUI_CMD_WIN->generic.height + 1; /* Locator. */ 01489 if (primary_win_info == TUI_CMD_WIN) 01490 { 01491 /* Locator included since first & second win share a line. */ 01492 ok = ((first_win->generic.height + 01493 second_win->generic.height + diff) >= 01494 (MIN_WIN_HEIGHT * 2) 01495 && new_height >= MIN_CMD_WIN_HEIGHT); 01496 if (ok) 01497 { 01498 total_height = new_height + 01499 (first_win->generic.height + 01500 second_win->generic.height + diff); 01501 min_height = MIN_CMD_WIN_HEIGHT; 01502 } 01503 } 01504 else 01505 { 01506 min_height = MIN_WIN_HEIGHT; 01507 01508 /* First see if we can increase/decrease the command 01509 window. And make sure that the command window is at 01510 least 1 line. */ 01511 ok = ((TUI_CMD_WIN->generic.height + diff) > 0); 01512 if (!ok) 01513 { /* Looks like we have to increase/decrease one of 01514 the other windows. */ 01515 if (primary_win_info == first_win) 01516 ok = (second_win->generic.height + diff) >= min_height; 01517 else 01518 ok = (first_win->generic.height + diff) >= min_height; 01519 } 01520 if (ok) 01521 { 01522 if (primary_win_info == first_win) 01523 total_height = new_height + 01524 second_win->generic.height + 01525 TUI_CMD_WIN->generic.height + diff; 01526 else 01527 total_height = new_height + 01528 first_win->generic.height + 01529 TUI_CMD_WIN->generic.height + diff; 01530 } 01531 } 01532 /* Now make sure that the proposed total height doesn't 01533 exceed the old total height. */ 01534 if (ok) 01535 ok = (new_height >= min_height 01536 && total_height <= cur_total_height); 01537 } 01538 } 01539 01540 return ok; 01541 } 01542 01543 01544 static void 01545 parse_scrolling_args (char *arg, 01546 struct tui_win_info **win_to_scroll, 01547 int *num_to_scroll) 01548 { 01549 if (num_to_scroll) 01550 *num_to_scroll = 0; 01551 *win_to_scroll = tui_win_with_focus (); 01552 01553 /* First set up the default window to scroll, in case there is no 01554 window name arg. */ 01555 if (arg != (char *) NULL) 01556 { 01557 char *buf, *buf_ptr; 01558 01559 /* Process the number of lines to scroll. */ 01560 buf = buf_ptr = xstrdup (arg); 01561 if (isdigit (*buf_ptr)) 01562 { 01563 char *num_str; 01564 01565 num_str = buf_ptr; 01566 buf_ptr = strchr (buf_ptr, ' '); 01567 if (buf_ptr != (char *) NULL) 01568 { 01569 *buf_ptr = (char) 0; 01570 if (num_to_scroll) 01571 *num_to_scroll = atoi (num_str); 01572 buf_ptr++; 01573 } 01574 else if (num_to_scroll) 01575 *num_to_scroll = atoi (num_str); 01576 } 01577 01578 /* Process the window name if one is specified. */ 01579 if (buf_ptr != (char *) NULL) 01580 { 01581 char *wname; 01582 int i; 01583 01584 if (*buf_ptr == ' ') 01585 while (*(++buf_ptr) == ' ') 01586 ; 01587 01588 if (*buf_ptr != (char) 0) 01589 { 01590 wname = buf_ptr; 01591 01592 /* Validate the window name. */ 01593 for (i = 0; i < strlen (wname); i++) 01594 wname[i] = toupper (wname[i]); 01595 } 01596 else 01597 wname = "?"; 01598 01599 *win_to_scroll = tui_partial_win_by_name (wname); 01600 01601 if (*win_to_scroll == (struct tui_win_info *) NULL 01602 || !(*win_to_scroll)->generic.is_visible) 01603 error (_("Invalid window specified. \n\ 01604 The window name specified must be valid and visible.\n")); 01605 else if (*win_to_scroll == TUI_CMD_WIN) 01606 *win_to_scroll = (tui_source_windows ())->list[0]; 01607 } 01608 xfree (buf); 01609 } 01610 }