diff options
Diffstat (limited to 'gdb/tui')
-rw-r--r-- | gdb/tui/ChangeLog-1998-2003 | 1217 | ||||
-rw-r--r-- | gdb/tui/tui-command.c | 135 | ||||
-rw-r--r-- | gdb/tui/tui-command.h | 30 | ||||
-rw-r--r-- | gdb/tui/tui-data.c | 1055 | ||||
-rw-r--r-- | gdb/tui/tui-data.h | 386 | ||||
-rw-r--r-- | gdb/tui/tui-disasm.c | 403 | ||||
-rw-r--r-- | gdb/tui/tui-disasm.h | 37 | ||||
-rw-r--r-- | gdb/tui/tui-io.c | 722 | ||||
-rw-r--r-- | gdb/tui/tui-io.h | 55 | ||||
-rw-r--r-- | gdb/tui/tui-layout.c | 1140 | ||||
-rw-r--r-- | gdb/tui/tui-layout.h | 38 | ||||
-rw-r--r-- | gdb/tui/tui-regs.c | 1023 | ||||
-rw-r--r-- | gdb/tui/tui-regs.h | 41 | ||||
-rw-r--r-- | gdb/tui/tui-source.c | 356 | ||||
-rw-r--r-- | gdb/tui/tui-source.h | 33 | ||||
-rw-r--r-- | gdb/tui/tui-stack.c | 435 | ||||
-rw-r--r-- | gdb/tui/tui-stack.h | 33 | ||||
-rw-r--r-- | gdb/tui/tui-win.c | 1615 | ||||
-rw-r--r-- | gdb/tui/tui-win.h | 59 | ||||
-rw-r--r-- | gdb/tui/tui-windata.c | 349 | ||||
-rw-r--r-- | gdb/tui/tui-windata.h | 47 | ||||
-rw-r--r-- | gdb/tui/tui-wingeneral.c | 285 | ||||
-rw-r--r-- | gdb/tui/tui-wingeneral.h | 49 | ||||
-rw-r--r-- | gdb/tui/tui-winsource.c | 715 | ||||
-rw-r--r-- | gdb/tui/tui-winsource.h | 68 |
25 files changed, 10326 insertions, 0 deletions
diff --git a/gdb/tui/ChangeLog-1998-2003 b/gdb/tui/ChangeLog-1998-2003 new file mode 100644 index 00000000000..fc5886c1ae1 --- /dev/null +++ b/gdb/tui/ChangeLog-1998-2003 @@ -0,0 +1,1217 @@ +2003-09-27 Andrew Cagney <cagney@redhat.com> + + * tuiRegs.c: Rename REGISTER_RAW_SIZE to + DEPRECATED_REGISTER_RAW_SIZE. + +2003-09-13 Andrew Cagney <cagney@redhat.com> + + * tui.h (struct ui_file): Add opaque declaration. + +2003-08-04 Daniel Jacobowitz <drow@mvista.com> + + * tui-interp.c: Include "cli-out.h". + (tui_resume): Update tui_old_uiout's stream to gdb_stdout. + +2003-07-24 Stephane Carrez <stcarrez@nerim.fr> + + * tui.c (tui_rl_other_window): New function to switch the TUI active + window and give focus to a next window. + (tui_initialize_readline): Bind it to c-x o. + (tui_rl_next_keymap): Activate TUI mode when entering SingleKey mode. + +2003-07-23 Stephane Carrez <stcarrez@nerim.fr> + + * tui.c (tui_enable): Call tuiRefreshAll to make sure the window + is accurate. + +2003-07-23 Stephane Carrez <stcarrez@nerim.fr> + + * tui-interp.c (tui_resume): Enable tui when we expected it. + (tui_suspend): Remember in which TUI mode we are. + (_initialize_tui_interp): Use the tui interpreter even when no + other interpreter was set and define in which TUI mode to start. + +2003-06-28 Daniel Jacobowitz <drow@mvista.com> + + * tui-out.c (tui_ui_out_impl): Add NULL for redirect member. + +2003-06-22 Daniel Jacobowitz <drow@mvista.com> + + * tui-hooks.c: Update include order. + * tui.c: Likewise. + * tuiCommand.c: Likewise. + * tuiData.c: Likewise. + * tuiDataWin.c: Likewise. + * tuiDisassem.c: Likewise. + * tuiGeneralWin.c: Likewise. + * tuiIO.c: Likewise. + * tuiLayout.c: Likewise. + * tuiRegs.c: Likewise. + * tuiSource.c: Likewise. + * tuiSourceWin.c: Likewise. + * tuiStack.c: Likewise. + * tuiWin.c: Likewise. + +2003-06-12 Andreas Schwab <schwab@suse.de> + + * tuiSource.c (tuiVerticalSourceScroll): Use get_frame_pc. + * tuiSourceWin.c (tuiHorizontalSourceScroll): Likewise. + * tuiStack.c (tui_get_function_from_frame): Likewise. + (tuiShowFrameInfo): Likewise. + * tuiWin.c (_makeVisibleWithNewHeight): Likewise. + * tui-hooks.c (tui_selected_frame_level_changed_hook): Likewise. + * tuiDisassem.c (tuiVerticalDisassemScroll): Likewise. + Include "disasm.h". + +2003-05-08 Andrew Cagney <cagney@redhat.com> + + * tuiRegs.c: Use MAX_REGISTER_SIZE instead of + MAX_REGISTER_RAW_SIZE. + +2003-05-03 Andrew Cagney <cagney@redhat.com> + + * tuiDisassem.c (tui_disassemble): Call gdb_print_insn, instead of + TARGET_PRINT_INSN. Do not initialize a disassemble_info object. + +2003-04-30 Andrew Cagney <cagney@redhat.com> + + * tuiDisassem.c (tui_disassemble): Use + "deprecated_tm_print_insn_info" instead of TARGET_PRINT_INSN_INFO, + add comment. + +2003-03-14 Andrew Cagney <cagney@redhat.com> + + * tuiRegs.c (_tuiGetRegisterRawValue): Use frame_read_register, + instead of get_saved_register. + +2003-03-13 Stephane Carrez <stcarrez@nerim.fr> + + * tui-out.c (tui_out_data): Fix typedef. + +2003-03-08 Andrew Cagney <cagney@redhat.com> + + * tui-out.c: Update copyright. + (tui_out_data): Define typedef. Use instead of ui_out_data. + +2003-02-14 Andrew Cagney <ac131313@redhat.com> + + * tui.c (tui_enable, tui_disable): Don't modify tui_version. + (tui_is_window_visible, tui_get_command_dimension): Test + tui_active instead of tui_version. + * tuiData.h (tui_version): Delete declaration. + * tui-hooks.c (tui_init_hook, tui_event_loop): Delete function, + moved to "tui-interp.c". + (tui_exit, tui_command_loop): Ditto. + (_initialize_tui): Don't initialize init_ui_hook. Initialize + target_new_objfile_hook. + * tui-interp.c: New file. + +2003-02-12 Andrew Cagney <ac131313@redhat.com> + + * tuiIO.c (tui_prep_terminal): Add one notused parameter. + * tui.c (tui_rl_switch_mode): Add two notused parameters. + (tui_rl_change_windows, tui_rl_next_keymap): Ditto. + (tui_rl_delete_other_windows): Ditto. + (tui_rl_change_windows, tui_rl_delete_other_windows): Update + calls. + +2002-12-08 Elena Zannoni <ezannoni@redhat.com> + + Import of readline 4.3. + Fix PR gdb/675 + * tuiWin.c: Include readline/readline.h. + (tui_update_gdb_sizes): Use accessor function rl_get_screen_size. + (tuiResizeAll): Ditto. + +2002-12-06 Elena Zannoni <ezannoni@redhat.com> + + * tuiStack.c (tuiShowFrameInfo): Fix typo. + +2002-11-29 Andrew Cagney <ac131313@redhat.com> + + * tui/tui-hooks.c: Update to use deprecated_selected_frame. + * tui/tui.c, tui/tuiDisassem.c, tui/tuiRegs.c: Ditto. + * tui/tuiSource.c, tui/tuiSourceWin.c, tui/tuiWin.c: Ditto. + +2002-11-28 Andrew Cagney <ac131313@redhat.com> + + * tuiStack.c (tuiShowFrameInfo): Use find_frame_sal instead of + find_pc_line. + +2002-11-23 Andrew Cagney <ac131313@redhat.com> + + * tuiStack.c (tuiShowFrameInfo): Use get_frame_type instead of + deprecated_frame_in_dummy. Fix coding style. + +2002-11-21 Stephane Carrez <stcarrez@nerim.fr> + + * tui-hooks.c (tui_init_hook): Don't enable the TUI if a specific + interpreter is installed. + +2002-11-18 Andrew Cagney <ac131313@redhat.com> + + * tuiStack.c (tuiShowFrameInfo): Use get_frame_type instead of + signal_handler_caller. + +2002-11-10 Andrew Cagney <ac131313@redhat.com> + + * tuiStack.c (tuiShowFrameInfo): Replace frame_in_dummy with + deprecated_frame_in_dummy. + +2002-10-26 Stephane Carrez <stcarrez@nerim.fr> + + * tuiIO.c (tui_prep_terminal): Save the prompt registered in readline. + (tui_redisplay_readline): Use the last saved prompt. + (tui_rl_saved_prompt): New. + +2002-10-25 Stephane Carrez <stcarrez@nerim.fr> + + Fix PR gdb/787 + * tuiWin.c (ACS_LRCORNER, ACS_LLCORNER, ACS_ULCORNER, ACS_URCORNER, + ACS_HLINE, ACS_VLINE): Define if they don't exist. + +2002-10-25 Stephane Carrez <stcarrez@nerim.fr> + + Fix PR gdb/478 + * tuiIO.c (tui_initialize_io): Use setvbuf since this is portable. + +2002-10-02 Elena Zannoni <ezannoni@redhat.com> + + * tui-hooks.c (selected_frame_level_changed_hook): Use the one + exported from frame.h. + +2002-09-29 Elena Zannoni <ezannoni@redhat.com> + + * tui.c (tui_show_source): Don't access current_source_symtab, use + accessor function instead. Include source.h and symtab.h + * tuiDisassem.c (tuiShowDisassemAndUpdateSource, + tuiVerticalDisassemScroll): Use accessor functions for current + source line and symtab. Include source.h. + * tuiLayout.c (_extractDisplayStartAddr): Use accessor functions + for current source line and symtab. Include source.h. + * tuiWin.c (_makeVisibleWithNewHeight): Ditto. + * tuiSourceWin.c (tuiUpdateSourceWindowAsIs, + tuiHorizontalSourceScroll): Ditto. + * tuiSource.c (tuiVerticalSourceScroll): Ditto. + +2002-09-13 Stephane Carrez <stcarrez@nerim.fr> + + * tui.c (tui_rl_switch_mode): Remove unecessary TUI switch printfs. + (tui_initialize_readline): Allow to use space to leave SingleKey + to enter one gdb command. + (tui_enable): Restore the TUI keymap when we are back to TUI. + (tui_disable): Restore normal keymap when leaving TUI. + * tuiIO.c (tui_redisplay_readline): Restore the SingleKey mode + when the buffer becomes empty and we are in tui_one_command_mode. + +2002-09-13 Stephane Carrez <stcarrez@nerim.fr> + + * tuiIO.c (tui_setup_io): rl_already_prompted must be cleared + when leaving TUI mode so that gdb prompt is displayed. + +2002-09-13 Stephane Carrez <stcarrez@nerim.fr> + + * tuiStack.c (tui_make_status_line): Make sure the local buffer + is large enough to hold the complete line. + +2002-09-10 Stephane Carrez <stcarrez@nerim.fr> + + * tui-hooks.c (tui_event_loop): New function. + (tui_command_loop): New function to override gdb loop and make sure + uiout is set according to TUI mode. + (tui_command_loop): Install the specific TUI command hook. + * tuiIO.c (tui_initialize_io): Initialize tui_old_uiout. + (tui_uiout, tui_old_uiout): Make public. + * tuiIO.h (tui_uiout, tui_old_uiout): Declare. + +2002-09-04 Stephane Carrez <stcarrez@nerim.fr> + + * tuiIO.c (tui_putc): New function to print one character. + (printable_part): New function from readline/complete.c. + (PUTX): New macro, likewise. + (print_filename): New function, likewise. + (get_y_or_n): New function, likewise and adapted for TUI. + (tui_rl_display_match_list): New function from readline/complete.c + and writes on TUI command window. + (tui_setup_io): Install or remove the readline hook + rl_completion_display_matches_hook so that completion is written + directly in TUI command window instead of in the TUI pipe. + (tui_initialize_io): Use #ifdef TUI_USE_PIPE_FOR_READLINE for the + TUI redirection pipe. + (tui_getc): Likewise for call to tui_readline_output. + (tui_readline_output): Likewise for function. + * tui.c (tui_rl_startup_hook): Always take care of gdb prompt. + +2002-09-02 Stephane Carrez <stcarrez@nerim.fr> + + * tuiWin.c (_newHeightOk): Fix compilation warnings. + +2002-09-01 Stephane Carrez <stcarrez@nerim.fr> + + * tuiWin.c (_tuiAllWindowsInfo): Don't crash if the window + is not displayed. + +2002-09-01 Stephane Carrez <stcarrez@nerim.fr> + + * tui-out.c (tui_out_new): Clear start_of_line. + * tuiSource.c (tuiVerticalSourceScroll): Use print_source_lines + to update the current source line. + +2002-09-01 Stephane Carrez <stcarrez@nerim.fr> + + * tui-hooks.c (tui_detach_hook): New hook to know when a process dies. + (tui_install_hooks): Install it. + (tui_remove_hooks): Remove it. + +2002-09-01 Stephane Carrez <stcarrez@nerim.fr> + + * tuiData.h (FILE_PREFIX): Don't define. + (blankStr, locationStr, breakStr): Don't declare. + (breakLocationStr, nullStr, historyLimit, setHistoryLimitTo): Likewise. + (displayableWinContentOf, displayableWinContentAt): Likewise. + (winElementHeight, winByName, freeAllWindows): Likewise. + + * tuiData.c (blankStr, locationStr, breakStr): Remove. + (breakLocationStr, nullStr, historyLimit, setHistoryLimitTo): Remove. + (displayableWinContentOf, displayableWinContentAt): Remove. + (winElementHeight, winByName, freeAllWindows): Remove. + +2002-09-01 Stephane Carrez <stcarrez@nerim.fr> + + * tuiStack.c (tui_make_status_line): New function to create the + status line. + (tuiShowLocatorContent): Use it instead of displayableWinContentAt. + * tuiData.h (PROC_PREFIX): Use "In:" to reduce length of prefix. + (PC_PREFIX): Use upper case. + (SINGLE_KEY, MIN_LINE_WIDTH, MIN_PROC_WIDTH): Define. + (MAX_TARGET_WIDTH, MAX_PID_WIDTH): Define. + +2002-08-31 Stephane Carrez <stcarrez@nerim.fr> + + * tuiSourceWin.h (tuiUpdateAllExecInfos): Don't declare. + (tuiClearAllExecInfosContent): Likewise. + (tuiEraseAllExecInfosContent): Ditto. + (tuiUpdateSourceWindowsFromLocator): Ditto. + * tuiSourceWin.c (tuiUpdateAllExecInfos): Remove. + * tui.h (tui_vCheckDataValues): Don't declare. + (tui_vStartNewLines, tui_vAllSetHasBreakAt): Likewise. + (tui_vUpdateLocatorFilename, tui_vUpdateSourceWindowsWithAddr): Ditto. + (tui_vShowFrameInfo): Ditto. + +2002-08-31 Stephane Carrez <stcarrez@nerim.fr> + + * tui.c (tui_commands): Table of single key commands. + (tui_rl_command_key): New function to execute gdb command. + (tui_rl_command_mode): New function to temporarily leave SingleKey. + (tui_rl_next_keymap): New function to enter/leave the SingleKey mode. + (tui_rl_startup_hook): New function to avoid prompt display by + readline functions. + (tui_set_key_mode): New function to set the key mode and install + the readline keymap. + (tui_initialize_readline): Create TUI SingleKey readline map. + (tui_enable): Install rl_startup_hook. + (tui_disable): Remove it. + * tui.h (enum tui_key_mode): Declare. + (tui_set_key_mode, tui_current_key_mode): Declare. + * tuiIO.c (tui_redisplay_readline): Don't display the prompt in + SingleKey mode. + * tuiIO.h (tui_redisplay_readline): Declare. + +2002-08-31 Stephane Carrez <stcarrez@nerim.fr> + + * tuiSourceWin.c (tuiSetIsExecPointAt): Redraw the previous and + current line. + +2002-08-31 Stephane Carrez <stcarrez@nerim.fr> + + * tuiSource.c (tuiSetSourceContent): Remove old breakpoint code. + (_hasBreak): Remove. + (tuiShowSource): Fix comment indentation. + (tuiSourceIsDisplayed): Likewise. + (tuiVerticalSourceScroll): Likewise. + +2002-08-30 Stephane Carrez <stcarrez@nerim.fr> + + * tuiSourceWin.h (tui_update_all_breakpoint_info): Declare. + (tui_update_breakpoint_info): Declare. + (tuiSetHasBreakAt, tuiAllSetHasBreakAt): Remove. + + * tuiSourceWin.c (tuiUpdateSourceWindowAsIs): Update breakpoint + information using tui_update_breakpoint_info. + (tui_update_all_breakpoint_info): New function to refresh all + execution windows. + (tui_update_breakpoint_info): New function to recompute the status + of exec info window from breakpoints. + (tuiSetHasBreakAt, tuiAllSetHasBreakAt): Remove. + (tuiSetExecInfoContent): Use the exec info flags computed by + tui_update_breakpoint_info to display a short status about breakpoints. + + * tuiData.h (TuiExecInfoContent): New for exec info string. + (TuiWhichElement): Use it. + (TUI_BP_ENABLED, TUI_BP_DISABLED, TUI_BP_HIT): New defines. + (TUI_BP_CONDITIONAL, TUI_BP_HARDWARE): New defines. + (TUI_BP_HIT_POS, TUI_BP_BREAK_POS, TUI_EXEC_POS): Likewise. + (TUI_EXECINFO_SIZE): Likewise. + * tuiData.c (initContentElement): Clear exec info string. + + * tui-hooks.c (get_breakpoint): Remove. + (tui_event_create_breakpoint): Call tui_update_all_breakpoint_info. + (tui_event_delete_breakpoint): Likewise. + (tui_event_modify_breakpoint): Likewise. + +2002-08-29 Stephane Carrez <stcarrez@nerim.fr> + + * tui.c (tuiGetLowDisassemblyAddress): Moved from here. + * tuiDisassem.c (tuiGetLowDisassemblyAddress): To here, and use + tui_find_disassembly_address to find the starting address of + disassemble window. + +2002-08-28 Stephane Carrez <stcarrez@nerim.fr> + + * tuiDisassem.c (tui_disassemble): New function to disassemble + several lines in a buffer. + (tui_find_disassembly_address): New function to search backward + or forward a disassembly line. + (tuiSetDisassemContent): Use tui_disassemble to obtain the real + content and format it in the window. + (tuiShowDisassemAndUpdateSource): Remove unused locals. + (tuiVerticalDisassemScroll): Use tui_find_disassembly_address to + obtain the address to disassemble for the scrolling. + * tuiDisassem.h (tuiGetBeginAsmAddress): Update. + * tuiSourceWin.c (tuiUpdateSourceWindowAsIs): Don't pass symtab. + +2002-08-28 Stephane Carrez <stcarrez@nerim.fr> + + * tuiIO.c (CTRL_CHAR): Redefine and use readline 4.3 definition. + +2002-08-26 Stephane Carrez <stcarrez@nerim.fr> + + Fix PR gdb/393: + * tui.c (tui_disable): Update gdb's knowledge of its terminal + using target_terminal_save_ours. + (tui_enable): Likewise. + +2002-08-25 Stephane Carrez <stcarrez@nerim.fr> + + * tui.c (tui_rl_switch_mode): Renames tui_switch_mode. + (tui_rl_change_windows): Renames tui_change_windows. + (tui_rl_delete_other_windows): Renames tui_delete_other_windows. + (tui_initialize_readline): Update. + +2002-08-25 Stephane Carrez <stcarrez@nerim.fr> + + * tuiDisassem.c (tuiSetDisassemContent): Use breakpoint_here_p. + (_hasBreak): Remove. + +2002-08-25 Stephane Carrez <stcarrez@nerim.fr> + + * tuiDisassem.c (tuiGetBeginAsmAddress): Use lookup_minimal_symbol + to find symbol address. + +2002-08-25 Stephane Carrez <stcarrez@nerim.fr> + + * tuiSourceWin.c (tui_display_main): Rename from tuiDisplayMainFunction + and use tuiGetBeginAsmAddress. + * tuiSourceWin.h (tui_display_main): Declare. + * tui.h (tuiDisplayMainFunction): Remove. + * tui-hooks.c (tui_new_objfile_hook): Update. + +2002-08-25 Stephane Carrez <stcarrez@nerim.fr> + + * tuiSource.h (m_tuiShowSourceAsIs): Remove macro. + (tuiShowSourceAsIs): Don't declare. + +2002-08-25 Stephane Carrez <stcarrez@nerim.fr> + + * tui-hooks.c (tui_selected_frame_level_changed_hook): Always update + the frame position. + +2002-08-25 Stephane Carrez <stcarrez@nerim.fr> + + * tuiStack.c (tuiSetLocatorContent): Remove. + (tuiUpdateLocatorInfoFromFrame): Remove. + (tui_set_locator_info): Allocate the content buffer if necessary. + (tui_set_locator_filename): Call tui_set_locator_info directly. + (tuiShowFrameInfo): Likewise and use find_pc_line instead of + find_pc_symtab. + +2002-08-25 Stephane Carrez <stcarrez@nerim.fr> + + * tuiSourceWin.c (tuiDisplayMainFunction): Update to use + tuiUpdateLocatorFilename. + * tuiStack.c (tuiSetLocatorInfo): Make it static. + (tuiSetLocatorContent): Likewise. + (tuiUpdateLocatorInfoFromFrame): Likewise. + (tuiSwitchFilename): Remove. + (tui_set_locator_filename): New function + (tui_set_locator_info): Rename from tuiSetLocatorInfo to GNU-ify; + use tui_set_locator_filename to record the filename. + (tuiUpdateLocatorFilename): Likewise. + (tuiUpdateLocatorInfoFromFrame): Update. + (tuiSetLocatorContent): Likewise. + * tuiStack.h (tuiClearLocatorContent): Don't declare. + (tuiSetLocatorInfo, tuiSetLocatorContent): Likewise. + (tuiUpdateLocatorInfoFromFrame, tuiSwitchFilename): Likewise. + +2002-08-25 Stephane Carrez <stcarrez@nerim.fr> + + * tuiSourceWin.c (tuiSetHasBreakAt): Use filename for breakpoint + comparison; cleanup. + * tuiSource.c (tuiSetSourceContent): Set window title and filename. + * tuiGeneralWin.c (boxWin): Print optional title on top of window. + * tuiData.h (TuiSourceInfo): Add filename member. + (TuiGenWinInfo): Add title member. + * tuiData.c (initGenericPart): Clear title. + (freeWindow): Free title and filename; remove unused locals. + (initWinInfo): Clear filename. + (tuiDelWindow): Free it; remove unused locals. + +2002-08-25 Stephane Carrez <stcarrez@nerim.fr> + + * tuiStack.h (tuiGetLocatorFilename): Don't declare. + (tuiUpdateLocatorDisplay): Likewise. + * tuiStack.c (tuiGetLocatorFilename): Remove. + (tuiShowFrameInfo): Use tuiSetLocatorContent and tuiShowLocatorContent + instead of tuiUpdateLocatorDisplay. + (tuiUpdateLocatorDisplay): Remove. + +2002-08-25 Stephane Carrez <stcarrez@nerim.fr> + + * tuiStack.h (tuiClearLocatorDisplay): Don't declare. + * tuiStack.c (tuiClearLocatorDisplay): Remove. + (tuiShowLocatorContent): Use wclrtoeol to clear end of status line. + (tuiUpdateLocatorDisplay): Don't call tuiClearLocatorDisplay. + +2002-08-25 Stephane Carrez <stcarrez@nerim.fr> + + * tuiStack.c (tui_get_function_from_frame): Rename from + _getFuncNameFromFrame; use print_address_symbolic to get symbolic + name of address. + (tuiUpdateLocatorInfoFromFrame): Update. + +2002-08-25 Stephane Carrez <stcarrez@nerim.fr> + + * tuiRegs.c (tuiDisplayRegistersFrom): Remove unused locals. + (_tuiRegisterFormat, _tuiSetSpecialRegsContent): Likewise. + (_tuiSetGeneralAndSpecialRegsContent): Likewise. + (_tuiSetFloatRegsContent): Likewise. + (_tuiRegisterName): Return a const char*. + * tuiData.h (_TuiDataElement): Use const char* for name. + +2002-08-25 Stephane Carrez <stcarrez@nerim.fr> + + * tuiSourceWin.h (tuiEraseAllSourceContent): Don't declare. + (tuiShowAllExecInfosContent): Likewise. + * tuiSourceWin.c (tuiEraseAllSourceContent): Remove. + (tuiShowAllExecInfosContent): Remove. + (tuiAllocSourceBuffer): Remove unused locals. + +2002-08-25 Stephane Carrez <stcarrez@nerim.fr> + + * tuiStack.c (tui_update_command): Rename _tuiUpdateLocation_command + to follow other gdb's command names; use execute_command; cleanup. + (_initialize_tuiStack): Update. + +2002-08-25 Stephane Carrez <stcarrez@nerim.fr> + + * tuiWin.h (tui_update_gdb_sizes): Declare. + +2002-08-24 Stephane Carrez <stcarrez@nerim.fr> + + * tui.c (strcat_to_buf): Use const char* for source item. + (tui_enable): Update the windows if there is a selected frame. + * tui.h (strcat_to_buf): Update prototype. + (strcat_to_buf_with_fmt): Remove. + +2002-08-24 Stephane Carrez <stcarrez@nerim.fr> + + * tuiWin.c (tui_update_gdb_sizes): New function to tell gdb what + is the size of command window. + (tuiResizeAll): Call it instead of init_page_info. + * tui.c (tui_enable): Call it to resize to TUI command window. + (tui_disable): Likewise for plain screen. + +2002-08-24 Stephane Carrez <stcarrez@nerim.fr> + + * tui.c (tui_enable): Use tuiSetLayout instead of showLayout and + use tuiShowFrameInfo instead of tuiSetLocatorContent. + * tuiLayout.h (showLayout): Remove. + * tuiLayout.c (_showSourceOrDisassemAndCommand): Remove unused locals. + (_showSourceDisassemCommand): Likewise. + (showLayout): Make it static. + (lastLayout): Remove. + +2002-08-24 Stephane Carrez <stcarrez@nerim.fr> + + * tuiSourceWin.c (tui_show_source_line): New function. + (tuiShowSourceContent): Call it and avoid clearing the window before + redrawing it. + (tuiClearAllSourceWinsContent): Remove. + * tuiSourceWin.h (tuiClearAllSourceWinsContent): Don't declare. + * tuiWin.h (tuiClearWinFocus, tuiClearWinFocusFrom): Don't declare. + * tuiWin.c (tuiClearWinFocus, tuiClearWinFocusFrom): Remove. + (tuiRefreshAll): Don't clear the window. + (_makeVisibleWithNewHeight): Don't clear locator line. + (tuiResizeAll): Remove unused locals. + (_tuiAdjustWinHeights): Likewise. + (_makeInvisibleAndSetNewHeight): Likewise. + (_newHeightOk): Likewise. + * tuiLayout.c (showLayout): Don't clear source windows. + (tuiSetLayout): Don't clear the window. + (_initAndMakeWin): Likewise for status line. + * tuiGeneralWin.c (makeVisible): Don't clear or refresh the window. + (makeWindow): Likewise. + (tuiClearWin): Remove. + * tuiGeneralWin.h (tuiClearWin): Don't declare. + +2002-08-24 Stephane Carrez <stcarrez@nerim.fr> + + * tuiSourceWin.c (tuiSrcWinIsDisplayed): Remove. + (tuiAsmWinIsDisplayed): Remove. + (tuiShowAllSourceWinsContent): Remove. + (tuiUpdateOnEnd): Remove. + * tuiGeneralWin.c (scrollWinForward): Remove. + (scrollWinBackward): Remove. + (_winResize): Don't declare. + * tui.h (tuiUpdateOnEnd): Don't declare. + (vcatch_errors, va_catch_errors): Likewise. + * tuiSourceWin.h (tuiUpdateOnEnd): Likewise. + (tuiShowAllSourceWinsContent): Likewise. + * tuiGeneralWin.h (scrollWinForward): Likewise. + (scrollWinBackward): Likewise. + +2002-08-24 Stephane Carrez <stcarrez@nerim.fr> + + * tuiRegs.c (_tuiRegisterFormat): Use gdbarch_print_registers_info. + +2002-08-18 Daniel Jacobowitz <drow@mvista.com> + + Fix PR gdb/655 + * tui.c: Disable <termio.h> include. + +2002-03-15 Andrew Cagney <ac131313@redhat.com> + + * tui-out.c (XMALLOC): Delete macro. Update copyright. + +2002-03-01 Andrew Cagney <ac131313@redhat.com> + + * tui-hooks.c: Add FIXME to explain true/false problem. Update + copyright. + * tui.c, tuiCommand.c, tuiData.c, tuiDataWin.c: Ditto. + * tuiDisassem.c, tuiGeneralWin.c, tuiIO.c, tuiLayout.c: Ditto. + * tuiRegs.c, tuiSource.c, tuiSourceWin.c, tuiStack.c: Ditto. + * tuiWin.c: Ditto. + + 2002-02-08 Daniel Jacobowitz <drow@mvista.com> + * tui-hooks.c: Include <curses.h> before "bfd.h". + * tui.c: Likewise. + * tuiCommand.c: Likewise. + * tuiData.c: Likewise. + * tuiDataWin.c: Likewise. + * tuiDisassem.c: Likewise. + * tuiGeneralWin.c: Likewise. + * tuiIO.c: Likewise. + * tuiLayout.c: Likewise. + * tuiRegs.c: Likewise. + * tuiSource.c: Likewise. + * tuiSourceWin.c: Likewise. + * tuiStack.c: Likewise. + * tuiWin.c: Likewise. + +2002-02-01 Andrew Cagney <ac131313@redhat.com> + + * tuiWin.c (_initialize_tuiWin): Replace NO_FUNCTION with NULL. + +2001-10-20 Andrew Cagney <ac131313@redhat.com> + + * tuiDisassem.c: Include "value.h". + * tuiSourceWin.c: Ditto. + +2001-09-28 Tom Tromey <tromey@redhat.com> + + * tuiLayout.h (tui_set_layout): Don't declare. + * tui.h (tui_vAddWinToLayout): Don't declare. + (tui_vSetLayoutTo): Likewise. + (tui_set_layout): Declare. + +2001-08-02 Eli Zaretskii <eliz@is.elta.co.il> + + * tuiSourceWin.c: Use disp_del instead of del. + + * tuiSource.c: Use disp_del instead of del. + + * tuiDisassem.c: Use disp_del instead of del. + +2001-07-31 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tui.c (tui_enable): Remove call to terminal_save_ours(). + (tui_disable): Likewise. + +2001-07-28 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiWin.c (_initialize_tuiWin): Use specific tui prefix for + set/show configuration variables. + (show_tui_cmd): New function. + (set_tui_cmd): New function. + +2001-07-24 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tui-hooks.c: New file, gdb hooks for tui. + * tui-out.c: New file, image copied from cli-out.c. + (tui_field_int): Identify "line" fields and keep track of them. + (tui_field_string): Likewise for "file". + (tui_out_new): Use flags = 0 to avoid printing the sources. + +2001-07-23 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiIO.c (tui_cont_sig): Update cursor position on the screen to + leave it in the command window. + (tui_redisplay_readline): Save cursor position to restore the + cursor after we go back from background. + * tuiData.h (TuiCommandInfo): Add start_line member. + +2001-07-23 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiStack.c (tuiUpdateLocatorFilename): Use const char*. + * tuiStack.h (tuiUpdateLocatorFilename): Update prototype. + * tuiWin.c (_initialize_tuiWin): Don't cast table of enum in calls + to add_set_enum_cmd. + * tui.c (tui_show_source): New function. + (tuiGetLowDisassemblyAddress): Use CORE_ADDR for newLow. + (tui_switch_mode): Prep or deprep readline terminal; + make sure the \n we return does not redo the last command. + * tui.h (tui_show_source): Declare. + (tui_out_new, tui_install_hooks, tui_remove_hooks): Likewise. + (tui_active, tui_initialize_io, tui_initialize_readline): Likewise. + +2001-07-22 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiIO.c (tui_initialize_io): Install tui_cont_sig signal handler + if SIGCONT is defined. + (tui_cont_sig): New function when SIGCONT is defined. + (tui_setup_io): Save tty setting to restore by SIGCONT. + +2001-07-22 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tui.h (tui_show_assembly): Declare. + (tui_is_window_visible): Declare. + * tui.c (tui_show_assembly): New function. + (tui_is_window_visible): New function. + (tui_get_command_dimension): New function. + +2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiWin.c (tuiRefreshAll): Use clearok to force a refresh. + +2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tui-file.c (tui_file_fputs): Use tui_puts. + +2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiStack.c (tuiSetLocatorInfo): Cleanup. + * tuiStack.h (tuiGetLocatorFilename): Declare. + * tuiRegs.h (tuiFirstRegElementNoInLine): Declare. + * tuiData.h (addToSourceWindows): Declare. + +2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tui.c (tui_change_windows): New function. + (tui_delete_other_windows): New function. + (tui_initialize_readline): Bind them to C-X 1 and C-X 2. + (tui_enable): Enable the keypad; call tui_update_variables. + (strcat_to_buf_with_fmt): Remove. + +2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tui.h: Remove old declarations, add the new ones. + * tui.c (tui_switch_mode): New function. + (tui_initialize_readline): New function. + (tui_enable): New function. + (tui_disable): New function. + (tuiGetLowDisassemblyAddress): Use CORE_ADDR, cleanup. + (tui_vSelectSourceSymtab): Remove. + (tuiInitWindows): Remove. + (_initialize_tui): Remove. + (_tuiReset): Keep but put arround #if 0. + +2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiIO.h: Remove old declarations and add the new ones. + * tuiIO.c: New management for curses and gdb terminal interactions. + (tui_tputs): Remove. + (tuiTermSetup, tuiTermUnsetup): Remove, must use normal curses ops. + (tuiBufferGetc, tui_vStartNewLines, _updateCommandInfo): Remove. + (tui_owns_terminal): Remove. + (tui_redisplay_readline): New function. + (tui_puts): New function. + (tui_prep_terminal): New function. + (tui_deprep_terminal): New function. + (tui_getc): Rename of tuiGetc, simplify and fix. + (tui_setup_io): New function. + (tui_initialize_io): New function. + +2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiRegs.c (tuiDisplayRegistersFrom): Call touchwin. + (_tuiRegisterFormat): Reduce size of format result. + +2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiGeneralWin.c (boxWin): Use the tui configuration variables. + * tuiWin.h: Declare the new variables. + * tuiWin.c (_initialize_tuiWin): Create TUI configuration variables. + (tui_update_variables): New function. + (translate): New function. + (tui_border_kind_enums, tui_border_mode_enums): New tables. + (tui_border_mode_translate): New table. + (tui_border_kind_translate_*): New tables. + (tui_active_border_mode): New variables. + (tui_border_*): New variables. + +2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiWin.c (_parseScrollingArgs): Fix uninitialized variable. + (_makeVisibleWithNewHeight): Use TuiLineOrAddress type. + + * tuiStack.c (tuiShowFrameInfo): Use TuiLineOrAddress type. + (tui_vUpdateLocatorFilename): Remove. + * tuiStack.h: Update prototypes. + + * tuiSourceWin.c (tuiAddrIsDisplayed): New function. + (tuiLineIsDisplayed): Split for address and line. + (tuiUpdateSourceWindow): Use TuiLineOrAddress type. + (tuiUpdateSourceWindowAsIs): Likewise. + (tuiUpdateSourceWindowsWithAddr): Likewise. + (tuiUpdateSourceWindowsWithLine): Likewise. + (tuiHorizontalSourceScroll): Likewise. + (tuiSetIsExecPointAt): Likewise. + (tuiUpdateOnEnd): Likewise. + * tuiSourceWin.h: Update prototypes. + + * tuiSource.c (tuiVerticalSourceScroll): Use TuiLineOrAddress type. + (tuiShowSource): Likewise. + (tuiVerticalSourceScroll): Likewise. + * tuiSource.h (tuiShowSource): Update prototype. + + * tuiDisassem.c (tuiSetDisassemContent): Use CORE_ADDR for address. + (tuiShowDisassem): Use TuiLineOrAddress type. + (tuiShowDisassemAndUpdateSource): Likewise. + (tuiVerticalDisassemScroll): Likewise. + (tuiShowDisassemAsIs): Remove. + * tuiDisassem.h (tuiSetDisassemContent): Update prototype. + + * tuiData.c (initWinInfo): Use CORE_ADDR for address. + (clearWinDetail): Likewise. + (displayableWinContentOf): Fix address conversion. + (tuiNextWin): Fix crash when the window is not yet created. + (partialWinByName): Likewise. + +2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiSourceWin.h: Remove unused declarations. + * tuiSourceWin.c (tui_vUpdateSourceWindowsWithAddr): Remove. + (tui_vUpdateSourceWindowsWithLine): Remove. + (tui_vAllSetHasBreakAt): Remove. + + * tuiLayout.h (tui_set_layout): Declare. + (tui_vSetLayoutTo): Remove. + (tui_vAddWinToLayout): Remove. + * tuiLayout.c (_tuiLayout_command): Call tui_enable() to force TUI. + (_tuiToggleLayout_command): Remove. + (_tuiToggleSplitLayout_command): Remove. + (_tuiLayout_command): Remove. + (tui_vSetLayoutTo): Remove. + (tui_vAddWinToLayout): Remove. + + * tuiDataWin.h (tui_vCheckDataValues): Remove. + * tuiDataWin.c (tui_vCheckDataValues): Remove. + +2001-07-20 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiWin.c (tuiStrDup): Remove, replaced by xstrdup. + (_parseScrollingArgs): Use xstrdup. + (_tuiScrollForward_command): Call tui_enable() to force TUI mode. + (_tuiScrollBackward_command): Likewise. + (_tuiScrollLeft_command): Likewise. + (_tuiScrollRight_command): Likewise. + (_tuiSetFocus): Likewise. + (_tuiSetFocus_command): Likewise. + (_tuiRefreshAll_command): Likewise. + (_tuiSetTabWidth_command): Likewise. + (_tuiSetWinHeight): Likewise. + (_tuiSetWinHeight_command): Likewise. + (_tuiXDBsetWinHeight): Likewise. + (_tui_vSetFocus): Remove. + (_tui_vSetWinHeight): Remove. + (_tui_vXDBsetWinHeight): Remove. + +2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiCommand.h: Remove unused declarations. + * tuiCommand.c (tuiDispatchCtrlChar): Fix escape sequences. + (tuiIncrCommandCharCountBy): Remove. + (tuiDecrCommandCharCountBy): Remove. + (tuiSetCommandCharCountTo): Remove. + (tuiClearCommandCharCount): Remove. + +2001-07-20 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiWin.c (_initialize_tuiWin): Always define the tui commands; + create the tui class help. + * tuiLayout.c (_initialize_tuiLayout): Always define the tui commands. + * tuiRegs.c (_initialize_tuiRegs): Likewise. + * tuiStack.c (_initialize_tuiStack): Likewise. + +2001-07-19 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiDisassem.c (tuiVerticalDisassemScroll): Use CORE_ADDR. + (tuiVerticalDisassemScroll): Likewise. + (tuiShowDisassemAndUpdateSource): Check for null symtab to + prevent a crash. + +2001-07-18 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiIO.c (_tuiHandleResizeDuringIO): Call tuiRefreshAll. + (tuiRead, tui_vread): Remove. + + * tui.c (va_catch_errors, tuiDo, tuiDoAndReturnToTop): Remove. + (vcatch_errors, _tui_vDo): Remove. + * tui.h (tuiDo, tuiDoAndReturnToTop): Remove. + + * tuiLayout.c (tuiSetLayout): Remove vcatch_errors. + (tui_set_layout): Rename of _tuiSetLayoutTo, public. + (_tuiToggleLayout_command): Merge with _tui_vToggleLayout_command. + (_tuiToggleSplitLayout_command): Merge with _tui_vToggleSplitLayout_command. + (_tuiLayout_command): Call tui_set_layout. + + * tuiRegs.c (_tuiScrollRegsBackward_command): Call tui_scroll. + (_tuiScrollRegsForward_command): Likewise. + (_tuiShowFloat_command): Call _tui_vShowRegisters_commandSupport. + (_tuiShowGeneral_command): Likewise. + (_tuiShowSpecial_command): Likewise. + (_tuiToggleFloatRegs_command): Call tuiToggleFloatRegs. + * tuiWin.c (tui_scroll): Rename of tui_vScroll, update parameters. + (_tuiScrollForward_command): Call tui_scroll. + (_tuiScrollBackward_command): Likewise. + (_tuiScrollLeft_command): Likewise. + (_tuiScrollRight_command): Likewise. + (_tuiSetFocus_command): Call _tuiSetFocus. + (_tuiRefreshAll_command): Call tuiRefreshAll. + (_tuiSetWinHeight_command): Call _tuiSetWinHeight. + (_tuiXDBsetWinHeight_command): Call _tuiXDBsetWinHeight. + * tuiWin.h (tui_scroll): Rename of tui_vScroll, update parameters. + +2001-07-18 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiData.h (TuiLocatorElement): Use CORE_ADDR for address member. + (TuiLineOrAddress): Likewise. + * tuiDisassem.c (tuiGetBeginAsmAddress): Use CORE_ADDR to specify + an address. + (tuiSetDisassemContent): Likewise. + (tuiShowDisassem, tuiShowDisassemAndUpdateSource): Likewise. + * tuiLayout.c (_extractDisplayStartAddr): Likewise. + (tuiSetLayout): Likewise. + * tuiSourceWin.c (tuiDisplayMainFunction): Likewise. + (tuiUpdateSourceWindowsWithAddr): Likewise. + (tuiUpdateSourceWindowsWithLine): Likewise. + (tuiSetHasBreakAt): Likewise. + * tuiStack.c (tuiSetLocatorInfo): Likewise. + (tuiSwitchFilename): Likewise. + (tuiUpdateLocatorInfoFromFrame): Likewise. + (tuiSetLocatorContent): Likewise. + (tuiShowFrameInfo): Likewise. + * tuiDisassem.h: Update prototypes to use CORE_ADDR. + * tuiSourceWin.h: Likewise. + * tuiStack.h: Likewise. + +2001-07-17 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiWin.c: Add missing includes. + (_makeVisibleWithNewHeight): Fix call to find_line_pc. + * tuiLayout.c: Add missing includes. + (_initAndMakeWin): Don't put curses in echo mode. + (_extractDisplayStartAddr): Fix calls to find_line_pc. + (_tuiLayout_command): Missing ',' in warning call. + * tuiSourceWin.c (tuiUpdateSourceWindowsWithLine): Fix calls to + find_line_pc. + (tuiSetHasBreakAt): Check for null source file. + +2001-07-17 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiWin.c (_tuiSetFocus): Replace subsetCompare with subset_compare. + * tuiLayout.c (_tuiSetLayoutTo): Likewise. + * tui.c (_tui_vToggle_command): Likewise. + +2001-07-17 Elena Zannoni <ezannoni@redhat.com> + + * tui-file.c: Add include of tuiIO.h, for tuiPuts_unfiltered. + +2001-07-16 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiRegs.c (tuiDisplayRegistersFrom): Set scrollok to FALSE in + each register window. + (tuiCheckRegisterValues): Use REGISTER_RAW_SIZE to obtain the size + of the register to check. + (_tuiRegValueHasChanged): Likewise. + (_tuiRegisterName): Use REGISTER_NAME. + (tui_restore_gdbout): New function. + (_tuiRegisterFormat): Use do_registers_info with gdb_stdout redirected + to a string. + (START_SPECIAL_REGS): Define. + (_tuiGetRegisterRawValue): Use get_saved_register. + (_tuiDisplayRegister): Fix clearing of register window. + +2001-07-17 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tui-file.h (fputs_unfiltered_hook): Remove. + * tui-file.c (tui_file_flush): Remove fputs_unfiltered_hook. + (tui_file_fputs): Likewise; simplify + +2001-07-16 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiStack.c: Add missing includes. + (tuiShowFrameInfo): Don't crash when there is no symbol table + associated with the pc. + * tuiSource.c (_hasBreak): Check for null source file. + * tuiWin.c (tuiRefreshAll): Check for null winList[type]. + (_tuiSetFocus): Check for null dataWin. + * tuiGeneralWin.c (refreshAll): Check for null list[type]. + +2001-07-16 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiDisassem.c (tuiSetDisassemContent): Use tm_print_insn_info + to disassemble in the curses window. + +2001-07-16 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tui.h: Cleanup to avoid inclusion of curses includes. + (TuiGenWinInfo, TuiGenWinInfoPtr): Move from here. + * tuiData.h: To here; include curses includes here. + (setTermHeightTo): Rename of setTermHeight to follow reality. + (setTermWidthTo): Likewise with setTermWidth. + +2001-07-14 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiWin.c, tui.c, tuiCommand.c: Use ansi prototype. + tuiIO.c, tuiData.c: Likewise. + tuiDataWin.c, tuiDisassem.c: Likewise. + tuiGeneralWin.c, tuiLayout.c: Likewise. + tuiRegs.c, tuiSource.c: Likewise. + tuiSouceWin.c, tuiStack.c: Likewise. + +2001-07-14 Stephane Carrez <Stephane.Carrez@worldnet.fr> + + * tuiWin.c, tuiWin.h, tui.c, tui.h, tuiCommand.c: Add FSF copyright. + tuiCommand.h, tuiIO.c, tuiIO.h, tuiData.h, tuiData.c: Likewise. + tuiDataWin.c, tuiDataWin.h, tuiDisassem.c, tuiDisassem.h: Likewise. + tuiGeneralWin.c, tuiGeneralWin.h, tuiLayout.c, tuiLayout.h: Likewise. + tuiRegs.c, tuiRegs.h, tuiSource.c, tuiSource.h: Likewise. + tuiSouceWin.c, tuiSourceWin.h, tuiStack.c, tuiStack.h: Likewise. + +2001-03-08 Andrew Cagney <ac131313@redhat.com> + + * tuiRegs.c: Use NUM_REGS, not ARCH_NUM_REGS. + +2001-03-06 Kevin Buettner <kevinb@redhat.com> + + * tui-file.h: Update/correct copyright notice. + +Wed Feb 7 19:54:27 2001 Andrew Cagney <cagney@redhat.com> + + * tui-file.c: Add __FILE__ and __LINE__ parameter to calls to + internal_error. + +2000-12-14 Kevin Buettner <kevinb@redhat.com> + + * tui-file.c, tui.c, tuiData.c, tuiLayout.c: Replace occurrences + of free() with xfree(). + +2000-06-22 Kevin Buettner <kevinb@redhat.com> + + * tuiSourceWin.h: Eliminate use of PARAMS from this file. + +2000-06-20 Kevin Buettner <kevinb@redhat.com> + + * tuiLayout.c: Eliminate use of PARAMS from this file. + +2000-06-17 Kevin Buettner <kevinb@redhat.com> + + * tuiIO.c: Eliminate use of PARAMS from this file. + +Thu May 25 14:46:20 2000 Andrew Cagney <cagney@b1.cygnus.com> + + * tui-file.c: Include "tui.h", "tuiData.h", "tuiIO.h" and + "tuiCommand.h". + (tui_file_fputs): Pass ``file'' and not ``stream'' to + tui_file_adjust_strbuf. + +Thu May 25 16:58:01 2000 Andrew Cagney <cagney@b1.cygnus.com> + + * tui.h: Include <ncurses.h> when available. + * tui.c, tuiGeneralWin.c: Do not include <curses.h>. + +Mon May 15 17:16:10 2000 Andrew Cagney <cagney@b1.cygnus.com> + + * Makefile.in: Delete. + +Tue Apr 18 15:32:15 2000 Andrew Cagney <cagney@b1.cygnus.com> + + * Makefile.in (distclean, maintainer-clean, realclean, + mostlyclean): New targets. + +Tue Feb 1 00:17:12 2000 Andrew Cagney <cagney@b1.cygnus.com> + + * tui-file.c, tui-file.h, tuiDisassem.c, tuiIO.c, tuiIO.h, + tuiRegs.c: Update to reflect rename of gdb-file / GDB_FILE to + ui-file / ``struct ui_file''. + +Mon Jan 31 18:12:43 2000 Andrew Cagney <cagney@b1.cygnus.com> + + * tui-file.c (enum streamtype, struct tui_stream, tui_file_new, + tui_file_delete, tui_fileopen, tui_sfileopen, tui_file_isatty, + tui_file_rewind, tui_file_put, tui_file_fputs, + tui_file_get_strbuf, tui_file_adjust_strbuf, tui_file_flush, + fputs_unfiltered_hook): Move to here from ../utils.c + + * tui-file.h, tui-file.c: New files. + +Mon Nov 8 17:47:37 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * tuiRegs.c (_tuiRegisterFormat), tuiDisassem.c + (tuiSetDisassemContent): Replace gdb_file_init_astring with + tui_sfileopen. Replace gdb_file_get_strbuf with + tui_file_get_strbuf. + +Mon Nov 8 16:54:51 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * tuiRegs.c (_tuiRegisterFormat), tuiDisassem.c + (tuiSetDisassemContent): Repace gdb_file_deallocate with + gdb_file_delete. Replace gdb_file_init_astring with tui_sfileopen. + +Fri Sep 17 19:34:38 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * tuiSource.c: Include "source.h". + (open_source_file, find_source_lines): Delete declarations. + +1999-01-26 Jason Molenda (jsm@bugshack.cygnus.com) + + * tui.h: Include stdarg.h instead of varargs.h if we're on an ISO Cish + system. + +Thu Dec 31 12:08:32 1998 David Taylor <taylor@texas.cygnus.com> + + The following changes were made by Jim Blandy <jimb@cygnus.com>, + Edith Epstein <eepstein@cygnus.com>, Elena Zannoni + <ezannoni@cygnus.com> Stan Shebs <shebs@cygnus.com>, and David + Taylor <taylor@cygnus.com>, as part of the project to merge in + changes originally made by HP; HP did not create ChangeLog + entries. + + * Makefile.in: New file; we're merging HP's changes into GDB, and + we've moved the TUI files into a subdirectory, so we need a new + Makefile. + + * tui.c: + #include <term.h>, if we have it, to get declarations for + the termcap functions on Solaris. + (tgoto): Add external K&R declaration for this; Solaris doesn't + bother to actually declare it in their header files. + (_tuiReset): Ignore the #definition of TIOCGETC if USG is defined; + we'd rather use the USG mechanisms than the Berkeley mechanisms + (TIOCGETC is one of the Berkeley terminal control ioctls). + Apologies if this causes trouble later; this should all be handled + by autoconf... + (strcat_to_buf, strcat_to_buf_with_fmt): New functions, moved here + from ../utils.h. + (tuiFree): replace safe_free with free. + (strcat_to_buf): new function, copied from utils.c. + (tuiInit): Add ignored `argv0' argument, to match the type that + init_ui_hook expects; updated declaration. Call the + initialize_tui_files function constructed above. Initialize + flush_hook to NULL. + (tuiInitWindows): Call tuiSetLocatorContent, to get the first + element of the locator window's content allocated. This seems + wrong, because it must have been initialized somehow in HP's + sources, and we should do it the same way now. But we do get + further before it segfaults. [Postscript: HP didn't bother to + initialize it; they compile + (va_catch_errors, vcatch_errors): Functions moved here from + ../utils.c in HP's sources. They're not used anywhere else. + (xdb_style): Delete this variable, and remove all references to + it. It's always true. + (tuiInit, _tui_vDo): References removed. + + * tui.h: Add prototypes. + Don't #include "gendefs.h"; it's only used in the TUI. + Integrate its contents into this file: + #include <ansidecl.h> here. + (Opaque, OpaqueFuncPtr): Typedefs moved to here. + + * tuiCommand.c: #include "defs.h", so we get the appropriate + definition of GDB_FILE. + + * tuiData.c + (freeWindow): replace safe_free with free. + (tui_version): don't define it here; it's defined in main.c now. + + * tuiDisassem.c + (tuiSetDisassemContent): Call strcat_address_numeric instead of + strcat_address. Simplify the control structure. Use predefined + GDB function to print asm inst address. Use GDB_FILE to collect + output into buffers. + + * tuiIO.c + (tgoto): Add external K&R declaration for this here too. + (tuiGetc, tuiTermSetup, tuiTermUnsetup): Same. + (tuiPuts_unfiltered): change FILE to GDB_FILE. + (tui_tputs): fix prototype for 3rd argument. + + * tuiIO.h (tuiPuts_unfiltered): change declaration. + + * tuiLayout.c + (_tuiSetLayoutTo): for displaying registers, hook up the HP code + that decides which registers to display (i.e. single precision + float, double precision float, general, special). Previously, + only handled TUI_GENERAL_REGS. Now that the code is hooked up, + compiling with -z poses a problem. When the first layout command + is 'layout regs', dataWin->detail is a NULL pointer, and gdb + core dumps. + + * tuiLayout.c (_tuiSetLayoutTo): replace safe_free with free. + + * tuiRegs.c #include "defs.h" earlier, to avoid problems in + <stdarg.h>. No idea exactly what's conflicting with what, but the + errors went away... + (_tuiRegisterFormat): Change so that function creates a GDB_FILE + object, calls pa_do_strcat_registers_info, copies the register + info into a buffer, and deallocates the GDB_FILE object. Remove + some code that is not executed. Also, call to + pa_do_strcat_registers_info has an additional parameter, + precision. This code requires some new per-target functions that + we don't want to merge. Dyke it out, with #ifdef + TUI_EXTENDED_FORMATTERS. + (_tuiSetSpecialRegsContent): this function was ifdefed out. + Hooked this up. + (_tuiSetGeneralAndSpecialRegsContent): this function was ifdefed + out. Hooked it up. + (IS_64BIT): Just define this to be zero; we're not merging in the + 64-bit support. + (tuiShowRegisters): Comment out all references to the "special" + regs; we don't have a distinction between the "special" and + "non-special" regs in most of our machine descriptions. This code + is PA-specific in other ways as well, and needs to be redesigned + to be portable to other processors. + + * tuiWin.c: #include <string.h>, to get a declaration for + strchr. + + * tui.c, tuiCommand.c, tuiData.c, tuiDataWin.c, tuiDisassem.c, + tuiGeneralWin.c, tuiIO.c, tuiLayout.c, tuiRegs.c, tuiSource.c, + tuiSourceWin.c, tuiStack.c, tuiWin.c: New files (from HP). Changed + bool to int throughout. Re-indented, GNU style. + + * tui.h, tuiCommand.h, tuiData.h, tuiDataWin.h, tuiDisassem.h, + tuiGeneralWin.h, tuiIO.h, tuiLayout.h, tuiRegs.h, tuiSource.h, + tuiSourceWin.h, tuiStack.h, tuiWin.h: new files (from HP). + Changed bool to int throughout. diff --git a/gdb/tui/tui-command.c b/gdb/tui/tui-command.c new file mode 100644 index 00000000000..4b1c0fd8e0d --- /dev/null +++ b/gdb/tui/tui-command.c @@ -0,0 +1,135 @@ +/* Specific command window processing. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include <ctype.h> +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-win.h" +#include "tui/tui-io.h" + +#ifdef HAVE_NCURSES_H +#include <ncurses.h> +#else +#ifdef HAVE_CURSES_H +#include <curses.h> +#endif +#endif + + +/***************************************** +** STATIC LOCAL FUNCTIONS FORWARD DECLS ** +******************************************/ + + + +/***************************************** +** PUBLIC FUNCTIONS ** +******************************************/ + +/* Dispatch the correct tui function based upon the control character. */ +unsigned int +tui_dispatch_ctrl_char (unsigned int ch) +{ + TuiWinInfoPtr winInfo = tuiWinWithFocus (); + WINDOW *w = cmdWin->generic.handle; + + /* + ** If the command window has the logical focus, or no-one does + ** assume it is the command window; in this case, pass the + ** character on through and do nothing here. + */ + if (winInfo == (TuiWinInfoPtr) NULL || winInfo == cmdWin) + return ch; + else + { + unsigned int c = 0, chCopy = ch; + register int i; + char *term; + + /* If this is an xterm, page next/prev keys aren't returned + ** by keypad as a single char, so we must handle them here. + ** Seems like a bug in the curses library? + */ + term = (char *) getenv ("TERM"); + for (i = 0; (term && term[i]); i++) + term[i] = toupper (term[i]); + if ((strcmp (term, "XTERM") == 0) && key_is_start_sequence (ch)) + { + unsigned int pageCh = 0, tmpChar; + + tmpChar = 0; + while (!key_is_end_sequence (tmpChar)) + { + tmpChar = (int) wgetch (w); + if (tmpChar == ERR) + { + return ch; + } + if (!tmpChar) + break; + if (tmpChar == 53) + pageCh = KEY_PPAGE; + else if (tmpChar == 54) + pageCh = KEY_NPAGE; + else + { + return 0; + } + } + chCopy = pageCh; + } + + switch (chCopy) + { + case KEY_NPAGE: + tuiScrollForward (winInfo, 0); + break; + case KEY_PPAGE: + tuiScrollBackward (winInfo, 0); + break; + case KEY_DOWN: + case KEY_SF: + tuiScrollForward (winInfo, 1); + break; + case KEY_UP: + case KEY_SR: + tuiScrollBackward (winInfo, 1); + break; + case KEY_RIGHT: + tuiScrollLeft (winInfo, 1); + break; + case KEY_LEFT: + tuiScrollRight (winInfo, 1); + break; + case '\f': + tuiRefreshAll (); + break; + default: + c = chCopy; + break; + } + return c; + } +} diff --git a/gdb/tui/tui-command.h b/gdb/tui/tui-command.h new file mode 100644 index 00000000000..9653bf07ee5 --- /dev/null +++ b/gdb/tui/tui-command.h @@ -0,0 +1,30 @@ +/* Specific command window processing. + + Copyright 1998, 1999, 2000, 2001, 2004 Free Software Foundation, + Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_COMMAND_H +#define TUI_COMMAND_H + +extern unsigned int tui_dispatch_ctrl_char (unsigned int); + +#endif diff --git a/gdb/tui/tui-data.c b/gdb/tui/tui-data.c new file mode 100644 index 00000000000..c6f4fb5dafc --- /dev/null +++ b/gdb/tui/tui-data.c @@ -0,0 +1,1055 @@ +/* TUI data manipulation routines. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, + Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "symtab.h" +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-wingeneral.h" + +#ifdef HAVE_NCURSES_H +#include <ncurses.h> +#else +#ifdef HAVE_CURSES_H +#include <curses.h> +#endif +#endif + +/**************************** +** GLOBAL DECLARATIONS +****************************/ +TuiWinInfoPtr winList[MAX_MAJOR_WINDOWS]; + +/*************************** +** Private data +****************************/ +static TuiLayoutType _currentLayout = UNDEFINED_LAYOUT; +static int _termHeight, _termWidth; +static TuiGenWinInfo _locator; +static TuiGenWinInfo _execInfo[2]; +static TuiWinInfoPtr _srcWinList[2]; +static TuiList _sourceWindows = +{(OpaqueList) _srcWinList, 0}; +static int _defaultTabLen = DEFAULT_TAB_LEN; +static TuiWinInfoPtr _winWithFocus = (TuiWinInfoPtr) NULL; +static TuiLayoutDef _layoutDef = +{SRC_WIN, /* displayMode */ + FALSE, /* split */ + TUI_UNDEFINED_REGS, /* regsDisplayType */ + TUI_SFLOAT_REGS}; /* floatRegsDisplayType */ +static int _winResized = FALSE; + + +/********************************* +** Static function forward decls +**********************************/ +static void freeContent (TuiWinContent, int, TuiWinType); +static void freeContentElements (TuiWinContent, int, TuiWinType); + + + +/********************************* +** PUBLIC FUNCTIONS +**********************************/ + +/****************************************** +** ACCESSORS & MUTATORS FOR PRIVATE DATA +******************************************/ + +/* + ** tuiWinResized(). + ** Answer a whether the terminal window has been resized or not + */ +int +tuiWinResized (void) +{ + return _winResized; +} /* tuiWinResized */ + + +/* + ** tuiSetWinResized(). + ** Set a whether the terminal window has been resized or not + */ +void +tuiSetWinResizedTo (int resized) +{ + _winResized = resized; + + return; +} /* tuiSetWinResizedTo */ + + +/* + ** tuiLayoutDef(). + ** Answer a pointer to the current layout definition + */ +TuiLayoutDefPtr +tuiLayoutDef (void) +{ + return &_layoutDef; +} /* tuiLayoutDef */ + + +/* + ** tuiWinWithFocus(). + ** Answer the window with the logical focus + */ +TuiWinInfoPtr +tuiWinWithFocus (void) +{ + return _winWithFocus; +} /* tuiWinWithFocus */ + + +/* + ** tuiSetWinWithFocus(). + ** Set the window that has the logical focus + */ +void +tuiSetWinWithFocus (TuiWinInfoPtr winInfo) +{ + _winWithFocus = winInfo; + + return; +} /* tuiSetWinWithFocus */ + + +/* + ** tuiDefaultTabLen(). + ** Answer the length in chars, of tabs + */ +int +tuiDefaultTabLen (void) +{ + return _defaultTabLen; +} /* tuiDefaultTabLen */ + + +/* + ** tuiSetDefaultTabLen(). + ** Set the length in chars, of tabs + */ +void +tuiSetDefaultTabLen (int len) +{ + _defaultTabLen = len; + + return; +} /* tuiSetDefaultTabLen */ + + +/* + ** currentSourceWin() + ** Accessor for the current source window. Usually there is only + ** one source window (either source or disassembly), but both can + ** be displayed at the same time. + */ +TuiListPtr +sourceWindows (void) +{ + return &_sourceWindows; +} /* currentSourceWindows */ + + +/* + ** clearSourceWindows() + ** Clear the list of source windows. Usually there is only one + ** source window (either source or disassembly), but both can be + ** displayed at the same time. + */ +void +clearSourceWindows (void) +{ + _sourceWindows.list[0] = (Opaque) NULL; + _sourceWindows.list[1] = (Opaque) NULL; + _sourceWindows.count = 0; + + return; +} /* currentSourceWindows */ + + +/* + ** clearSourceWindowsDetail() + ** Clear the pertinant detail in the source windows. + */ +void +clearSourceWindowsDetail (void) +{ + int i; + + for (i = 0; i < (sourceWindows ())->count; i++) + clearWinDetail ((TuiWinInfoPtr) (sourceWindows ())->list[i]); + + return; +} /* currentSourceWindows */ + + +/* + ** addSourceWindowToList(). + ** Add a window to the list of source windows. Usually there is + ** only one source window (either source or disassembly), but + ** both can be displayed at the same time. + */ +void +addToSourceWindows (TuiWinInfoPtr winInfo) +{ + if (_sourceWindows.count < 2) + _sourceWindows.list[_sourceWindows.count++] = (Opaque) winInfo; + + return; +} /* addToSourceWindows */ + + +/* + ** clearWinDetail() + ** Clear the pertinant detail in the windows. + */ +void +clearWinDetail (TuiWinInfoPtr winInfo) +{ + if (m_winPtrNotNull (winInfo)) + { + switch (winInfo->generic.type) + { + case SRC_WIN: + case DISASSEM_WIN: + winInfo->detail.sourceInfo.startLineOrAddr.addr = 0; + winInfo->detail.sourceInfo.horizontalOffset = 0; + break; + case CMD_WIN: + winInfo->detail.commandInfo.curLine = + winInfo->detail.commandInfo.curch = 0; + break; + case DATA_WIN: + winInfo->detail.dataDisplayInfo.dataContent = + (TuiWinContent) NULL; + winInfo->detail.dataDisplayInfo.dataContentCount = 0; + winInfo->detail.dataDisplayInfo.regsContent = + (TuiWinContent) NULL; + winInfo->detail.dataDisplayInfo.regsContentCount = 0; + winInfo->detail.dataDisplayInfo.regsDisplayType = + TUI_UNDEFINED_REGS; + winInfo->detail.dataDisplayInfo.regsColumnCount = 1; + winInfo->detail.dataDisplayInfo.displayRegs = FALSE; + break; + default: + break; + } + } + + return; +} /* clearWinDetail */ + + +/* + ** sourceExecInfoPtr(). + ** Accessor for the source execution info ptr. + */ +TuiGenWinInfoPtr +sourceExecInfoWinPtr (void) +{ + return &_execInfo[0]; +} /* sourceExecInfoWinPtr */ + + +/* + ** disassemExecInfoPtr(). + ** Accessor for the disassem execution info ptr. + */ +TuiGenWinInfoPtr +disassemExecInfoWinPtr (void) +{ + return &_execInfo[1]; +} /* disassemExecInfoWinPtr */ + + +/* + ** locatorWinInfoPtr(). + ** Accessor for the locator win info. Answers a pointer to the + ** static locator win info struct. + */ +TuiGenWinInfoPtr +locatorWinInfoPtr (void) +{ + return &_locator; +} /* locatorWinInfoPtr */ + + +/* + ** termHeight(). + ** Accessor for the termHeight + */ +int +termHeight (void) +{ + return _termHeight; +} /* termHeight */ + + +/* + ** setTermHeightTo(). + ** Mutator for the term height + */ +void +setTermHeightTo (int h) +{ + _termHeight = h; + + return; +} /* setTermHeightTo */ + + +/* + ** termWidth(). + ** Accessor for the termWidth + */ +int +termWidth (void) +{ + return _termWidth; +} /* termWidth */ + + +/* + ** setTermWidth(). + ** Mutator for the termWidth + */ +void +setTermWidthTo (int w) +{ + _termWidth = w; + + return; +} /* setTermWidthTo */ + + +/* + ** currentLayout(). + ** Accessor for the current layout + */ +TuiLayoutType +currentLayout (void) +{ + return _currentLayout; +} /* currentLayout */ + + +/* + ** setCurrentLayoutTo(). + ** Mutator for the current layout + */ +void +setCurrentLayoutTo (TuiLayoutType newLayout) +{ + _currentLayout = newLayout; + + return; +} /* setCurrentLayoutTo */ + + +/* + ** setGenWinOrigin(). + ** Set the origin of the window + */ +void +setGenWinOrigin (TuiGenWinInfoPtr winInfo, int x, int y) +{ + winInfo->origin.x = x; + winInfo->origin.y = y; + + return; +} /* setGenWinOrigin */ + + +/***************************** +** OTHER PUBLIC FUNCTIONS +*****************************/ + + +/* + ** tuiNextWin(). + ** Answer the next window in the list, cycling back to the top + ** if necessary + */ +TuiWinInfoPtr +tuiNextWin (TuiWinInfoPtr curWin) +{ + TuiWinType type = curWin->generic.type; + TuiWinInfoPtr nextWin = (TuiWinInfoPtr) NULL; + + if (curWin->generic.type == CMD_WIN) + type = SRC_WIN; + else + type = curWin->generic.type + 1; + while (type != curWin->generic.type && m_winPtrIsNull (nextWin)) + { + if (winList[type] && winList[type]->generic.isVisible) + nextWin = winList[type]; + else + { + if (type == CMD_WIN) + type = SRC_WIN; + else + type++; + } + } + + return nextWin; +} /* tuiNextWin */ + + +/* + ** tuiPrevWin(). + ** Answer the prev window in the list, cycling back to the bottom + ** if necessary + */ +TuiWinInfoPtr +tuiPrevWin (TuiWinInfoPtr curWin) +{ + TuiWinType type = curWin->generic.type; + TuiWinInfoPtr prev = (TuiWinInfoPtr) NULL; + + if (curWin->generic.type == SRC_WIN) + type = CMD_WIN; + else + type = curWin->generic.type - 1; + while (type != curWin->generic.type && m_winPtrIsNull (prev)) + { + if (winList[type]->generic.isVisible) + prev = winList[type]; + else + { + if (type == SRC_WIN) + type = CMD_WIN; + else + type--; + } + } + + return prev; +} + + +/* + ** partialWinByName(). + ** Answer the window represented by name + */ +TuiWinInfoPtr +partialWinByName (char *name) +{ + TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL; + + if (name != (char *) NULL) + { + int i = 0; + + while (i < MAX_MAJOR_WINDOWS && m_winPtrIsNull (winInfo)) + { + if (winList[i] != 0) + { + char *curName = winName (&winList[i]->generic); + if (strlen (name) <= strlen (curName) && + strncmp (name, curName, strlen (name)) == 0) + winInfo = winList[i]; + } + i++; + } + } + + return winInfo; +} /* partialWinByName */ + + +/* + ** winName(). + ** Answer the name of the window + */ +char * +winName (TuiGenWinInfoPtr winInfo) +{ + char *name = (char *) NULL; + + switch (winInfo->type) + { + case SRC_WIN: + name = SRC_NAME; + break; + case CMD_WIN: + name = CMD_NAME; + break; + case DISASSEM_WIN: + name = DISASSEM_NAME; + break; + case DATA_WIN: + name = DATA_NAME; + break; + default: + name = ""; + break; + } + + return name; +} /* winName */ + + +/* + ** initializeStaticData + */ +void +initializeStaticData (void) +{ + initGenericPart (sourceExecInfoWinPtr ()); + initGenericPart (disassemExecInfoWinPtr ()); + initGenericPart (locatorWinInfoPtr ()); + + return; +} /* initializeStaticData */ + + +/* + ** allocGenericWinInfo(). + */ +TuiGenWinInfoPtr +allocGenericWinInfo (void) +{ + TuiGenWinInfoPtr win; + + if ((win = (TuiGenWinInfoPtr) xmalloc ( + sizeof (TuiGenWinInfoPtr))) != (TuiGenWinInfoPtr) NULL) + initGenericPart (win); + + return win; +} /* allocGenericWinInfo */ + + +/* + ** initGenericPart(). + */ +void +initGenericPart (TuiGenWinInfoPtr win) +{ + win->width = + win->height = + win->origin.x = + win->origin.y = + win->viewportHeight = + win->contentSize = + win->lastVisibleLine = 0; + win->handle = (WINDOW *) NULL; + win->content = (OpaquePtr) NULL; + win->contentInUse = + win->isVisible = FALSE; + win->title = 0; +} + + +/* + ** initContentElement(). + */ +void +initContentElement (TuiWinElementPtr element, TuiWinType type) +{ + element->highlight = FALSE; + switch (type) + { + case SRC_WIN: + case DISASSEM_WIN: + element->whichElement.source.line = (char *) NULL; + element->whichElement.source.lineOrAddr.lineNo = 0; + element->whichElement.source.isExecPoint = FALSE; + element->whichElement.source.hasBreak = FALSE; + break; + case DATA_WIN: + initGenericPart (&element->whichElement.dataWindow); + element->whichElement.dataWindow.type = DATA_ITEM_WIN; + ((TuiGenWinInfoPtr) & element->whichElement.dataWindow)->content = + (OpaquePtr) allocContent (1, DATA_ITEM_WIN); + ((TuiGenWinInfoPtr) + & element->whichElement.dataWindow)->contentSize = 1; + break; + case CMD_WIN: + element->whichElement.command.line = (char *) NULL; + break; + case DATA_ITEM_WIN: + element->whichElement.data.name = (char *) NULL; + element->whichElement.data.type = TUI_REGISTER; + element->whichElement.data.itemNo = UNDEFINED_ITEM; + element->whichElement.data.value = (Opaque) NULL; + element->whichElement.data.highlight = FALSE; + break; + case LOCATOR_WIN: + element->whichElement.locator.fileName[0] = + element->whichElement.locator.procName[0] = (char) 0; + element->whichElement.locator.lineNo = 0; + element->whichElement.locator.addr = 0; + break; + case EXEC_INFO_WIN: + memset(element->whichElement.simpleString, ' ', + sizeof(element->whichElement.simpleString)); + break; + default: + break; + } + return; +} /* initContentElement */ + +/* + ** initWinInfo(). + */ +void +initWinInfo (TuiWinInfoPtr winInfo) +{ + initGenericPart (&winInfo->generic); + winInfo->canHighlight = + winInfo->isHighlighted = FALSE; + switch (winInfo->generic.type) + { + case SRC_WIN: + case DISASSEM_WIN: + winInfo->detail.sourceInfo.executionInfo = (TuiGenWinInfoPtr) NULL; + winInfo->detail.sourceInfo.hasLocator = FALSE; + winInfo->detail.sourceInfo.horizontalOffset = 0; + winInfo->detail.sourceInfo.startLineOrAddr.addr = 0; + winInfo->detail.sourceInfo.filename = 0; + break; + case DATA_WIN: + winInfo->detail.dataDisplayInfo.dataContent = (TuiWinContent) NULL; + winInfo->detail.dataDisplayInfo.dataContentCount = 0; + winInfo->detail.dataDisplayInfo.regsContent = (TuiWinContent) NULL; + winInfo->detail.dataDisplayInfo.regsContentCount = 0; + winInfo->detail.dataDisplayInfo.regsDisplayType = + TUI_UNDEFINED_REGS; + winInfo->detail.dataDisplayInfo.regsColumnCount = 1; + winInfo->detail.dataDisplayInfo.displayRegs = FALSE; + break; + case CMD_WIN: + winInfo->detail.commandInfo.curLine = 0; + winInfo->detail.commandInfo.curch = 0; + break; + default: + winInfo->detail.opaque = (Opaque) NULL; + break; + } + + return; +} /* initWinInfo */ + + +/* + ** allocWinInfo(). + */ +TuiWinInfoPtr +allocWinInfo (TuiWinType type) +{ + TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL; + + winInfo = (TuiWinInfoPtr) xmalloc (sizeof (TuiWinInfo)); + if (m_winPtrNotNull (winInfo)) + { + winInfo->generic.type = type; + initWinInfo (winInfo); + } + + return winInfo; +} /* allocWinInfo */ + + +/* + ** allocContent(). + ** Allocates the content and elements in a block. + */ +TuiWinContent +allocContent (int numElements, TuiWinType type) +{ + TuiWinContent content = (TuiWinContent) NULL; + char *elementBlockPtr = (char *) NULL; + int i; + + if ((content = (TuiWinContent) + xmalloc (sizeof (TuiWinElementPtr) * numElements)) != (TuiWinContent) NULL) + { /* + ** All windows, except the data window, can allocate the elements + ** in a chunk. The data window cannot because items can be + ** added/removed from the data display by the user at any time. + */ + if (type != DATA_WIN) + { + if ((elementBlockPtr = (char *) + xmalloc (sizeof (TuiWinElement) * numElements)) != (char *) NULL) + { + for (i = 0; i < numElements; i++) + { + content[i] = (TuiWinElementPtr) elementBlockPtr; + initContentElement (content[i], type); + elementBlockPtr += sizeof (TuiWinElement); + } + } + else + { + tuiFree ((char *) content); + content = (TuiWinContent) NULL; + } + } + } + + return content; +} /* allocContent */ + + +/* + ** addContentElements(). + ** Adds the input number of elements to the windows's content. If + ** no content has been allocated yet, allocContent() is called to + ** do this. The index of the first element added is returned, + ** unless there is a memory allocation error, in which case, (-1) + ** is returned. + */ +int +addContentElements (TuiGenWinInfoPtr winInfo, int numElements) +{ + TuiWinElementPtr elementPtr; + int i, indexStart; + + if (winInfo->content == (OpaquePtr) NULL) + { + winInfo->content = (OpaquePtr) allocContent (numElements, winInfo->type); + indexStart = 0; + } + else + indexStart = winInfo->contentSize; + if (winInfo->content != (OpaquePtr) NULL) + { + for (i = indexStart; (i < numElements + indexStart); i++) + { + if ((elementPtr = (TuiWinElementPtr) + xmalloc (sizeof (TuiWinElement))) != (TuiWinElementPtr) NULL) + { + winInfo->content[i] = (Opaque) elementPtr; + initContentElement (elementPtr, winInfo->type); + winInfo->contentSize++; + } + else /* things must be really hosed now! We ran out of memory!? */ + return (-1); + } + } + + return indexStart; +} /* addContentElements */ + + +/* Delete all curses windows associated with winInfo, leaving everything + else intact. */ +void +tuiDelWindow (TuiWinInfoPtr winInfo) +{ + TuiGenWinInfoPtr genericWin; + + switch (winInfo->generic.type) + { + case SRC_WIN: + case DISASSEM_WIN: + genericWin = locatorWinInfoPtr (); + if (genericWin != (TuiGenWinInfoPtr) NULL) + { + tuiDelwin (genericWin->handle); + genericWin->handle = (WINDOW *) NULL; + genericWin->isVisible = FALSE; + } + if (winInfo->detail.sourceInfo.filename) + { + xfree (winInfo->detail.sourceInfo.filename); + winInfo->detail.sourceInfo.filename = 0; + } + genericWin = winInfo->detail.sourceInfo.executionInfo; + if (genericWin != (TuiGenWinInfoPtr) NULL) + { + tuiDelwin (genericWin->handle); + genericWin->handle = (WINDOW *) NULL; + genericWin->isVisible = FALSE; + } + break; + case DATA_WIN: + if (winInfo->generic.content != (OpaquePtr) NULL) + { + tuiDelDataWindows (winInfo->detail.dataDisplayInfo.regsContent, + winInfo->detail.dataDisplayInfo.regsContentCount); + tuiDelDataWindows (winInfo->detail.dataDisplayInfo.dataContent, + winInfo->detail.dataDisplayInfo.dataContentCount); + } + break; + default: + break; + } + if (winInfo->generic.handle != (WINDOW *) NULL) + { + tuiDelwin (winInfo->generic.handle); + winInfo->generic.handle = (WINDOW *) NULL; + winInfo->generic.isVisible = FALSE; + } +} + + +/* + ** freeWindow(). + */ +void +freeWindow (TuiWinInfoPtr winInfo) +{ + TuiGenWinInfoPtr genericWin; + + switch (winInfo->generic.type) + { + case SRC_WIN: + case DISASSEM_WIN: + genericWin = locatorWinInfoPtr (); + if (genericWin != (TuiGenWinInfoPtr) NULL) + { + tuiDelwin (genericWin->handle); + genericWin->handle = (WINDOW *) NULL; + } + freeWinContent (genericWin); + if (winInfo->detail.sourceInfo.filename) + { + xfree (winInfo->detail.sourceInfo.filename); + winInfo->detail.sourceInfo.filename = 0; + } + genericWin = winInfo->detail.sourceInfo.executionInfo; + if (genericWin != (TuiGenWinInfoPtr) NULL) + { + tuiDelwin (genericWin->handle); + genericWin->handle = (WINDOW *) NULL; + freeWinContent (genericWin); + } + break; + case DATA_WIN: + if (winInfo->generic.content != (OpaquePtr) NULL) + { + freeDataContent ( + winInfo->detail.dataDisplayInfo.regsContent, + winInfo->detail.dataDisplayInfo.regsContentCount); + winInfo->detail.dataDisplayInfo.regsContent = + (TuiWinContent) NULL; + winInfo->detail.dataDisplayInfo.regsContentCount = 0; + freeDataContent ( + winInfo->detail.dataDisplayInfo.dataContent, + winInfo->detail.dataDisplayInfo.dataContentCount); + winInfo->detail.dataDisplayInfo.dataContent = + (TuiWinContent) NULL; + winInfo->detail.dataDisplayInfo.dataContentCount = 0; + winInfo->detail.dataDisplayInfo.regsDisplayType = + TUI_UNDEFINED_REGS; + winInfo->detail.dataDisplayInfo.regsColumnCount = 1; + winInfo->detail.dataDisplayInfo.displayRegs = FALSE; + winInfo->generic.content = (OpaquePtr) NULL; + winInfo->generic.contentSize = 0; + } + break; + default: + break; + } + if (winInfo->generic.handle != (WINDOW *) NULL) + { + tuiDelwin (winInfo->generic.handle); + winInfo->generic.handle = (WINDOW *) NULL; + freeWinContent (&winInfo->generic); + } + if (winInfo->generic.title) + xfree (winInfo->generic.title); + xfree (winInfo); +} + + +/* + ** freeAllSourceWinsContent(). + */ +void +freeAllSourceWinsContent (void) +{ + int i; + + for (i = 0; i < (sourceWindows ())->count; i++) + { + TuiWinInfoPtr winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i]; + + if (m_winPtrNotNull (winInfo)) + { + freeWinContent (&(winInfo->generic)); + freeWinContent (winInfo->detail.sourceInfo.executionInfo); + } + } + + return; +} /* freeAllSourceWinsContent */ + + +/* + ** freeWinContent(). + */ +void +freeWinContent (TuiGenWinInfoPtr winInfo) +{ + if (winInfo->content != (OpaquePtr) NULL) + { + freeContent ((TuiWinContent) winInfo->content, + winInfo->contentSize, + winInfo->type); + winInfo->content = (OpaquePtr) NULL; + } + winInfo->contentSize = 0; + + return; +} /* freeWinContent */ + + +void +tuiDelDataWindows (TuiWinContent content, int contentSize) +{ + int i; + + /* + ** Remember that data window content elements are of type TuiGenWinInfoPtr, + ** each of which whose single element is a data element. + */ + for (i = 0; i < contentSize; i++) + { + TuiGenWinInfoPtr genericWin = &content[i]->whichElement.dataWindow; + + if (genericWin != (TuiGenWinInfoPtr) NULL) + { + tuiDelwin (genericWin->handle); + genericWin->handle = (WINDOW *) NULL; + genericWin->isVisible = FALSE; + } + } + + return; +} /* tuiDelDataWindows */ + + +void +freeDataContent (TuiWinContent content, int contentSize) +{ + int i; + + /* + ** Remember that data window content elements are of type TuiGenWinInfoPtr, + ** each of which whose single element is a data element. + */ + for (i = 0; i < contentSize; i++) + { + TuiGenWinInfoPtr genericWin = &content[i]->whichElement.dataWindow; + + if (genericWin != (TuiGenWinInfoPtr) NULL) + { + tuiDelwin (genericWin->handle); + genericWin->handle = (WINDOW *) NULL; + freeWinContent (genericWin); + } + } + freeContent (content, + contentSize, + DATA_WIN); + + return; +} /* freeDataContent */ + + +/********************************** +** LOCAL STATIC FUNCTIONS ** +**********************************/ + + +/* + ** freeContent(). + */ +static void +freeContent (TuiWinContent content, int contentSize, TuiWinType winType) +{ + if (content != (TuiWinContent) NULL) + { + freeContentElements (content, contentSize, winType); + tuiFree ((char *) content); + } + + return; +} /* freeContent */ + + +/* + ** freeContentElements(). + */ +static void +freeContentElements (TuiWinContent content, int contentSize, TuiWinType type) +{ + if (content != (TuiWinContent) NULL) + { + int i; + + if (type == SRC_WIN || type == DISASSEM_WIN) + { + /* free whole source block */ + if (content[0]->whichElement.source.line != (char *) NULL) + tuiFree (content[0]->whichElement.source.line); + } + else + { + for (i = 0; i < contentSize; i++) + { + TuiWinElementPtr element; + + element = content[i]; + if (element != (TuiWinElementPtr) NULL) + { + switch (type) + { + case DATA_WIN: + tuiFree ((char *) element); + break; + case DATA_ITEM_WIN: + /* + ** Note that data elements are not allocated + ** in a single block, but individually, as needed. + */ + if (element->whichElement.data.type != TUI_REGISTER) + tuiFree ((char *) + element->whichElement.data.name); + tuiFree ((char *) element->whichElement.data.value); + tuiFree ((char *) element); + break; + case CMD_WIN: + tuiFree ((char *) element->whichElement.command.line); + break; + default: + break; + } + } + } + } + if (type != DATA_WIN && type != DATA_ITEM_WIN) + tuiFree ((char *) content[0]); /* free the element block */ + } + + return; +} /* freeContentElements */ diff --git a/gdb/tui/tui-data.h b/gdb/tui/tui-data.h new file mode 100644 index 00000000000..6657fcdbda1 --- /dev/null +++ b/gdb/tui/tui-data.h @@ -0,0 +1,386 @@ +/* TUI data manipulation routines. + + Copyright 1998, 1999, 2000, 2001, 2002, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_DATA_H +#define TUI_DATA_H + +#if defined (HAVE_NCURSES_H) +#include <ncurses.h> +#elif defined (HAVE_CURSES_H) +#include <curses.h> +#endif + +/* Generic window information */ + typedef struct _TuiGenWinInfo + { + WINDOW *handle; /* window handle */ + TuiWinType type; /* type of window */ + int width; /* window width */ + int height; /* window height */ + TuiPoint origin; /* origin of window */ + OpaquePtr content; /* content of window */ + int contentSize; /* Size of content (# of elements) */ + int contentInUse; /* Can it be used, or is it already used? */ + int viewportHeight; /* viewport height */ + int lastVisibleLine; /* index of last visible line */ + int isVisible; /* whether the window is visible or not */ + char* title; /* Window title to display. */ + } +TuiGenWinInfo, *TuiGenWinInfoPtr; + +/* Constant definitions */ +#define DEFAULT_TAB_LEN 8 +#define NO_SRC_STRING "[ No Source Available ]" +#define NO_DISASSEM_STRING "[ No Assembly Available ]" +#define NO_REGS_STRING "[ Register Values Unavailable ]" +#define NO_DATA_STRING "[ No Data Values Displayed ]" +#define MAX_CONTENT_COUNT 100 +#define SRC_NAME "SRC" +#define CMD_NAME "CMD" +#define DATA_NAME "REGS" +#define DISASSEM_NAME "ASM" +#define TUI_NULL_STR "" +#define DEFAULT_HISTORY_COUNT 25 +#define BOX_WINDOW TRUE +#define DONT_BOX_WINDOW FALSE +#define HILITE TRUE +#define NO_HILITE FALSE +#define WITH_LOCATOR TRUE +#define NO_LOCATOR FALSE +#define EMPTY_SOURCE_PROMPT TRUE +#define NO_EMPTY_SOURCE_PROMPT FALSE +#define UNDEFINED_ITEM -1 +#define MIN_WIN_HEIGHT 3 +#define MIN_CMD_WIN_HEIGHT 3 + +/* Strings to display in the TUI status line. */ +#define PROC_PREFIX "In: " +#define LINE_PREFIX "Line: " +#define PC_PREFIX "PC: " +#define SINGLE_KEY "(SingleKey)" + +/* Minimum/Maximum length of some fields displayed in the TUI status line. */ +#define MIN_LINE_WIDTH 4 /* Use at least 4 digits for line numbers. */ +#define MIN_PROC_WIDTH 12 +#define MAX_TARGET_WIDTH 10 +#define MAX_PID_WIDTH 14 + +#define TUI_FLOAT_REGS_NAME "$FREGS" +#define TUI_FLOAT_REGS_NAME_LOWER "$fregs" +#define TUI_GENERAL_REGS_NAME "$GREGS" +#define TUI_GENERAL_REGS_NAME_LOWER "$gregs" +#define TUI_SPECIAL_REGS_NAME "$SREGS" +#define TUI_SPECIAL_REGS_NAME_LOWER "$sregs" +#define TUI_GENERAL_SPECIAL_REGS_NAME "$REGS" +#define TUI_GENERAL_SPECIAL_REGS_NAME_LOWER "$regs" + +/* Scroll direction enum */ +typedef enum tui_scroll_direction + { + FORWARD_SCROLL, + BACKWARD_SCROLL, + LEFT_SCROLL, + RIGHT_SCROLL + } +TuiScrollDirection, *TuiScrollDirectionPtr; + + +/* General list struct */ +typedef struct _TuiList + { + OpaqueList list; + int count; + } +TuiList, *TuiListPtr; + + +/* The kinds of layouts available */ +typedef enum tui_layout_type + { + SRC_COMMAND, + DISASSEM_COMMAND, + SRC_DISASSEM_COMMAND, + SRC_DATA_COMMAND, + DISASSEM_DATA_COMMAND, + UNDEFINED_LAYOUT + } +TuiLayoutType, *TuiLayoutTypePtr; + +/* Basic data types that can be displayed in the data window. */ +typedef enum _TuiDataType + { + TUI_REGISTER, + TUI_SCALAR, + TUI_COMPLEX, + TUI_STRUCT + } +TuiDataType, TuiDataTypePtr; + +/* Types of register displays */ +typedef enum tui_register_display_type + { + TUI_UNDEFINED_REGS, + TUI_GENERAL_REGS, + TUI_SFLOAT_REGS, + TUI_DFLOAT_REGS, + TUI_SPECIAL_REGS, + TUI_GENERAL_AND_SPECIAL_REGS + } +TuiRegisterDisplayType, *TuiRegisterDisplayTypePtr; + +/* Structure describing source line or line address */ +typedef union _TuiLineOrAddress + { + int lineNo; + CORE_ADDR addr; + } +TuiLineOrAddress, *TuiLineOrAddressPtr; + +/* Current Layout definition */ +typedef struct _TuiLayoutDef + { + TuiWinType displayMode; + int split; + TuiRegisterDisplayType regsDisplayType; + TuiRegisterDisplayType floatRegsDisplayType; + } +TuiLayoutDef, *TuiLayoutDefPtr; + +/* Elements in the Source/Disassembly Window */ +typedef struct _TuiSourceElement + { + char *line; + TuiLineOrAddress lineOrAddr; + int isExecPoint; + int hasBreak; + } +TuiSourceElement, *TuiSourceElementPtr; + + +/* Elements in the data display window content */ +typedef struct _TuiDataElement + { + const char *name; + int itemNo; /* the register number, or data display number */ + TuiDataType type; + Opaque value; + int highlight; + } +TuiDataElement, *TuiDataElementPtr; + + +/* Elements in the command window content */ +typedef struct _TuiCommandElement + { + char *line; + } +TuiCommandElement, *TuiCommandElementPtr; + + +#define MAX_LOCATOR_ELEMENT_LEN 100 + +/* Elements in the locator window content */ +typedef struct _TuiLocatorElement + { + char fileName[MAX_LOCATOR_ELEMENT_LEN]; + char procName[MAX_LOCATOR_ELEMENT_LEN]; + int lineNo; + CORE_ADDR addr; + } +TuiLocatorElement, *TuiLocatorElementPtr; + +/* Flags to tell what kind of breakpoint is at current line. */ +#define TUI_BP_ENABLED 0x01 +#define TUI_BP_DISABLED 0x02 +#define TUI_BP_HIT 0x04 +#define TUI_BP_CONDITIONAL 0x08 +#define TUI_BP_HARDWARE 0x10 + +/* Position of breakpoint markers in the exec info string. */ +#define TUI_BP_HIT_POS 0 +#define TUI_BP_BREAK_POS 1 +#define TUI_EXEC_POS 2 +#define TUI_EXECINFO_SIZE 4 + +typedef char TuiExecInfoContent[TUI_EXECINFO_SIZE]; + +/* An content element in a window */ +typedef union + { + TuiSourceElement source; /* the source elements */ + TuiGenWinInfo dataWindow; /* data display elements */ + TuiDataElement data; /* elements of dataWindow */ + TuiCommandElement command; /* command elements */ + TuiLocatorElement locator; /* locator elements */ + TuiExecInfoContent simpleString; /* simple char based elements */ + } +TuiWhichElement, *TuiWhichElementPtr; + +typedef struct _TuiWinElement + { + int highlight; + TuiWhichElement whichElement; + } +TuiWinElement, *TuiWinElementPtr; + + +/* This describes the content of the window. */ +typedef TuiWinElementPtr *TuiWinContent; + + +/* This struct defines the specific information about a data display window */ +typedef struct _TuiDataInfo + { + TuiWinContent dataContent; /* start of data display content */ + int dataContentCount; + TuiWinContent regsContent; /* start of regs display content */ + int regsContentCount; + TuiRegisterDisplayType regsDisplayType; + int regsColumnCount; + int displayRegs; /* Should regs be displayed at all? */ + } +TuiDataInfo, *TuiDataInfoPtr; + + +typedef struct _TuiSourceInfo + { + int hasLocator; /* Does locator belongs to this window? */ + TuiGenWinInfoPtr executionInfo; /* execution information window */ + int horizontalOffset; /* used for horizontal scroll */ + TuiLineOrAddress startLineOrAddr; + char* filename; + } +TuiSourceInfo, *TuiSourceInfoPtr; + + +typedef struct _TuiCommandInfo + { + int curLine; /* The current line position */ + int curch; /* The current cursor position */ + int start_line; + } +TuiCommandInfo, *TuiCommandInfoPtr; + + +/* This defines information about each logical window */ +typedef struct _TuiWinInfo + { + TuiGenWinInfo generic; /* general window information */ + union + { + TuiSourceInfo sourceInfo; + TuiDataInfo dataDisplayInfo; + TuiCommandInfo commandInfo; + Opaque opaque; + } + detail; + int canHighlight; /* Can this window ever be highlighted? */ + int isHighlighted; /* Is this window highlighted? */ + } +TuiWinInfo, *TuiWinInfoPtr; + +/* MACROS (prefixed with m_) */ + +/* Testing macros */ +#define m_genWinPtrIsNull(winInfo) \ + ((winInfo) == (TuiGenWinInfoPtr)NULL) +#define m_genWinPtrNotNull(winInfo) \ + ((winInfo) != (TuiGenWinInfoPtr)NULL) +#define m_winPtrIsNull(winInfo) \ + ((winInfo) == (TuiWinInfoPtr)NULL) +#define m_winPtrNotNull(winInfo) \ + ((winInfo) != (TuiWinInfoPtr)NULL) + +#define m_winIsSourceType(type) \ + (type == SRC_WIN || type == DISASSEM_WIN) +#define m_winIsAuxillary(winType) \ + (winType > MAX_MAJOR_WINDOWS) +#define m_hasLocator(winInfo) \ + ( ((winInfo) != (TuiWinInfoPtr)NULL) ? \ + (winInfo->detail.sourceInfo.hasLocator) : \ + FALSE ) + +#define m_setWinHighlightOn(winInfo) \ + if ((winInfo) != (TuiWinInfoPtr)NULL) \ + (winInfo)->isHighlighted = TRUE +#define m_setWinHighlightOff(winInfo) \ + if ((winInfo) != (TuiWinInfoPtr)NULL) \ + (winInfo)->isHighlighted = FALSE + + +/* Global Data */ +extern TuiWinInfoPtr winList[MAX_MAJOR_WINDOWS]; + +/* Macros */ +#define srcWin winList[SRC_WIN] +#define disassemWin winList[DISASSEM_WIN] +#define dataWin winList[DATA_WIN] +#define cmdWin winList[CMD_WIN] + +/* Data Manipulation Functions */ +extern void initializeStaticData (void); +extern TuiGenWinInfoPtr allocGenericWinInfo (void); +extern TuiWinInfoPtr allocWinInfo (TuiWinType); +extern void initGenericPart (TuiGenWinInfoPtr); +extern void initWinInfo (TuiWinInfoPtr); +extern TuiWinContent allocContent (int, TuiWinType); +extern int addContentElements (TuiGenWinInfoPtr, int); +extern void initContentElement (TuiWinElementPtr, TuiWinType); +extern void freeWindow (TuiWinInfoPtr); +extern void freeWinContent (TuiGenWinInfoPtr); +extern void freeDataContent (TuiWinContent, int); +extern void freeAllSourceWinsContent (void); +extern void tuiDelWindow (TuiWinInfoPtr); +extern void tuiDelDataWindows (TuiWinContent, int); +extern TuiWinInfoPtr partialWinByName (char *); +extern char *winName (TuiGenWinInfoPtr); +extern TuiLayoutType currentLayout (void); +extern void setCurrentLayoutTo (TuiLayoutType); +extern int termHeight (void); +extern void setTermHeightTo (int); +extern int termWidth (void); +extern void setTermWidthTo (int); +extern void setGenWinOrigin (TuiGenWinInfoPtr, int, int); +extern TuiGenWinInfoPtr locatorWinInfoPtr (void); +extern TuiGenWinInfoPtr sourceExecInfoWinPtr (void); +extern TuiGenWinInfoPtr disassemExecInfoWinPtr (void); +extern TuiListPtr sourceWindows (void); +extern void clearSourceWindows (void); +extern void clearSourceWindowsDetail (void); +extern void clearWinDetail (TuiWinInfoPtr winInfo); +extern void tuiAddToSourceWindows (TuiWinInfoPtr); +extern int tuiDefaultTabLen (void); +extern void tuiSetDefaultTabLen (int); +extern TuiWinInfoPtr tuiWinWithFocus (void); +extern void tuiSetWinWithFocus (TuiWinInfoPtr); +extern TuiLayoutDefPtr tuiLayoutDef (void); +extern int tuiWinResized (void); +extern void tuiSetWinResizedTo (int); + +extern TuiWinInfoPtr tuiNextWin (TuiWinInfoPtr); +extern TuiWinInfoPtr tuiPrevWin (TuiWinInfoPtr); + +extern void addToSourceWindows (TuiWinInfoPtr winInfo); + +#endif /* TUI_DATA_H */ diff --git a/gdb/tui/tui-disasm.c b/gdb/tui/tui-disasm.c new file mode 100644 index 00000000000..493c00ded68 --- /dev/null +++ b/gdb/tui/tui-disasm.c @@ -0,0 +1,403 @@ +/* Disassembly display. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "symtab.h" +#include "breakpoint.h" +#include "frame.h" +#include "value.h" +#include "source.h" +#include "disasm.h" + +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-win.h" +#include "tui/tui-layout.h" +#include "tui/tui-winsource.h" +#include "tui/tui-stack.h" +#include "tui/tui-file.h" + +#ifdef HAVE_NCURSES_H +#include <ncurses.h> +#else +#ifdef HAVE_CURSES_H +#include <curses.h> +#endif +#endif + +struct tui_asm_line +{ + CORE_ADDR addr; + char* addr_string; + char* insn; +}; + +/* Function to set the disassembly window's content. + Disassemble count lines starting at pc. + Return address of the count'th instruction after pc. */ +static CORE_ADDR +tui_disassemble (struct tui_asm_line* lines, CORE_ADDR pc, int count) +{ + struct ui_file *gdb_dis_out; + + /* now init the ui_file structure */ + gdb_dis_out = tui_sfileopen (256); + + /* Now construct each line */ + for (; count > 0; count--, lines++) + { + if (lines->addr_string) + xfree (lines->addr_string); + if (lines->insn) + xfree (lines->insn); + + print_address (pc, gdb_dis_out); + lines->addr = pc; + lines->addr_string = xstrdup (tui_file_get_strbuf (gdb_dis_out)); + + ui_file_rewind (gdb_dis_out); + + pc = pc + gdb_print_insn (pc, gdb_dis_out); + + lines->insn = xstrdup (tui_file_get_strbuf (gdb_dis_out)); + + /* reset the buffer to empty */ + ui_file_rewind (gdb_dis_out); + } + ui_file_delete (gdb_dis_out); + return pc; +} + +/* Find the disassembly address that corresponds to FROM lines + above or below the PC. Variable sized instructions are taken + into account by the algorithm. */ +static CORE_ADDR +tui_find_disassembly_address (CORE_ADDR pc, int from) +{ + register CORE_ADDR newLow; + int maxLines; + int i; + struct tui_asm_line* lines; + + maxLines = (from > 0) ? from : - from; + if (maxLines <= 1) + return pc; + + lines = (struct tui_asm_line*) alloca (sizeof (struct tui_asm_line) + * maxLines); + memset (lines, 0, sizeof (struct tui_asm_line) * maxLines); + + newLow = pc; + if (from > 0) + { + tui_disassemble (lines, pc, maxLines); + newLow = lines[maxLines - 1].addr; + } + else + { + CORE_ADDR last_addr; + int pos; + struct minimal_symbol* msymbol; + + /* Find backward an address which is a symbol + and for which disassembling from that address will fill + completely the window. */ + pos = maxLines - 1; + do { + newLow -= 1 * maxLines; + msymbol = lookup_minimal_symbol_by_pc_section (newLow, 0); + + if (msymbol) + newLow = SYMBOL_VALUE_ADDRESS (msymbol); + else + newLow += 1 * maxLines; + + tui_disassemble (lines, newLow, maxLines); + last_addr = lines[pos].addr; + } while (last_addr > pc && msymbol); + + /* Scan forward disassembling one instruction at a time + until the last visible instruction of the window + matches the pc. We keep the disassembled instructions + in the 'lines' window and shift it downward (increasing + its addresses). */ + if (last_addr < pc) + do + { + CORE_ADDR next_addr; + + pos++; + if (pos >= maxLines) + pos = 0; + + next_addr = tui_disassemble (&lines[pos], last_addr, 1); + + /* If there are some problems while disassembling exit. */ + if (next_addr <= last_addr) + break; + last_addr = next_addr; + } while (last_addr <= pc); + pos++; + if (pos >= maxLines) + pos = 0; + newLow = lines[pos].addr; + } + for (i = 0; i < maxLines; i++) + { + xfree (lines[i].addr_string); + xfree (lines[i].insn); + } + return newLow; +} + +/* Function to set the disassembly window's content. */ +enum tui_status +tui_set_disassem_content (CORE_ADDR pc) +{ + TuiStatus ret = TUI_FAILURE; + register int i; + register int offset = disassemWin->detail.sourceInfo.horizontalOffset; + register int lineWidth, maxLines; + CORE_ADDR cur_pc; + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + int tab_len = tuiDefaultTabLen (); + struct tui_asm_line* lines; + int insn_pos; + int addr_size, max_size; + char* line; + + if (pc == 0) + return TUI_FAILURE; + + ret = tuiAllocSourceBuffer (disassemWin); + if (ret != TUI_SUCCESS) + return ret; + + disassemWin->detail.sourceInfo.startLineOrAddr.addr = pc; + cur_pc = (CORE_ADDR) + (((TuiWinElementPtr) locator->content[0])->whichElement.locator.addr); + + maxLines = disassemWin->generic.height - 2; /* account for hilite */ + + /* Get temporary table that will hold all strings (addr & insn). */ + lines = (struct tui_asm_line*) alloca (sizeof (struct tui_asm_line) + * maxLines); + memset (lines, 0, sizeof (struct tui_asm_line) * maxLines); + + lineWidth = disassemWin->generic.width - 1; + + tui_disassemble (lines, pc, maxLines); + + /* See what is the maximum length of an address and of a line. */ + addr_size = 0; + max_size = 0; + for (i = 0; i < maxLines; i++) + { + size_t len = strlen (lines[i].addr_string); + if (len > addr_size) + addr_size = len; + + len = strlen (lines[i].insn) + tab_len; + if (len > max_size) + max_size = len; + } + max_size += addr_size + tab_len; + + /* Allocate memory to create each line. */ + line = (char*) alloca (max_size); + insn_pos = (1 + (addr_size / tab_len)) * tab_len; + + /* Now construct each line */ + for (i = 0; i < maxLines; i++) + { + TuiWinElementPtr element; + TuiSourceElement* src; + int curLen; + + element = (TuiWinElementPtr) disassemWin->generic.content[i]; + src = &element->whichElement.source; + strcpy (line, lines[i].addr_string); + curLen = strlen (line); + + /* Add spaces to make the instructions start on the same column */ + while (curLen < insn_pos) + { + strcat (line, " "); + curLen++; + } + + strcat (line, lines[i].insn); + + /* Now copy the line taking the offset into account */ + if (strlen (line) > offset) + strcpy (src->line, &line[offset]); + else + src->line[0] = '\0'; + + src->lineOrAddr.addr = lines[i].addr; + src->isExecPoint = lines[i].addr == cur_pc; + + /* See whether there is a breakpoint installed. */ + src->hasBreak = (!src->isExecPoint + && breakpoint_here_p (pc) != no_breakpoint_here); + + xfree (lines[i].addr_string); + xfree (lines[i].insn); + } + disassemWin->generic.contentSize = i; + return TUI_SUCCESS; +} + + +/* Function to display the disassembly window with disassembled code. */ +void +tui_show_disassem (CORE_ADDR startAddr) +{ + struct symtab *s = find_pc_symtab (startAddr); + TuiWinInfoPtr winWithFocus = tuiWinWithFocus (); + TuiLineOrAddress val; + + val.addr = startAddr; + tui_add_win_to_layout (DISASSEM_WIN); + tuiUpdateSourceWindow (disassemWin, s, val, FALSE); + /* + ** if the focus was in the src win, put it in the asm win, if the + ** source view isn't split + */ + if (currentLayout () != SRC_DISASSEM_COMMAND && winWithFocus == srcWin) + tuiSetWinFocusTo (disassemWin); + + return; +} + + +/* Function to display the disassembly window. */ +void +tui_show_disassem_and_update_source (CORE_ADDR startAddr) +{ + struct symtab_and_line sal; + + tui_show_disassem (startAddr); + if (currentLayout () == SRC_DISASSEM_COMMAND) + { + TuiLineOrAddress val; + + /* + ** Update what is in the source window if it is displayed too, + ** note that it follows what is in the disassembly window and visa-versa + */ + sal = find_pc_line (startAddr, 0); + val.lineNo = sal.line; + tuiUpdateSourceWindow (srcWin, sal.symtab, val, TRUE); + if (sal.symtab) + { + set_current_source_symtab_and_line (&sal); + tuiUpdateLocatorFilename (sal.symtab->filename); + } + else + tuiUpdateLocatorFilename ("?"); + } + + return; +} + +CORE_ADDR +tui_get_begin_asm_address (void) +{ + TuiGenWinInfoPtr locator; + TuiLocatorElementPtr element; + CORE_ADDR addr; + + locator = locatorWinInfoPtr (); + element = &((TuiWinElementPtr) locator->content[0])->whichElement.locator; + + if (element->addr == 0) + { + struct minimal_symbol *main_symbol; + + /* Find address of the start of program. + Note: this should be language specific. */ + main_symbol = lookup_minimal_symbol ("main", NULL, NULL); + if (main_symbol == 0) + main_symbol = lookup_minimal_symbol ("MAIN", NULL, NULL); + if (main_symbol == 0) + main_symbol = lookup_minimal_symbol ("_start", NULL, NULL); + if (main_symbol) + addr = SYMBOL_VALUE_ADDRESS (main_symbol); + else + addr = 0; + } + else /* the target is executing */ + addr = element->addr; + + return addr; +} + +/* Determine what the low address will be to display in the TUI's + disassembly window. This may or may not be the same as the + low address input. */ +CORE_ADDR +tuiGetLowDisassemblyAddress (CORE_ADDR low, CORE_ADDR pc) +{ + int pos; + + /* Determine where to start the disassembly so that the pc is about in the + middle of the viewport. */ + pos = tui_default_win_viewport_height (DISASSEM_WIN, DISASSEM_COMMAND) / 2; + pc = tui_find_disassembly_address (pc, -pos); + + if (pc < low) + pc = low; + return pc; +} + +/* Scroll the disassembly forward or backward vertically. */ +void +tui_vertical_disassem_scroll (enum tui_scroll_direction scrollDirection, + int numToScroll) +{ + if (disassemWin->generic.content != (OpaquePtr) NULL) + { + CORE_ADDR pc; + TuiWinContent content; + struct symtab *s; + TuiLineOrAddress val; + int maxLines, dir; + struct symtab_and_line cursal = get_current_source_symtab_and_line (); + + content = (TuiWinContent) disassemWin->generic.content; + if (cursal.symtab == (struct symtab *) NULL) + s = find_pc_symtab (get_frame_pc (deprecated_selected_frame)); + else + s = cursal.symtab; + + /* account for hilite */ + maxLines = disassemWin->generic.height - 2; + pc = content[0]->whichElement.source.lineOrAddr.addr; + dir = (scrollDirection == FORWARD_SCROLL) ? maxLines : - maxLines; + + val.addr = tui_find_disassembly_address (pc, dir); + tuiUpdateSourceWindowAsIs (disassemWin, s, val, FALSE); + } +} diff --git a/gdb/tui/tui-disasm.h b/gdb/tui/tui-disasm.h new file mode 100644 index 00000000000..e72aba1f3f1 --- /dev/null +++ b/gdb/tui/tui-disasm.h @@ -0,0 +1,37 @@ +/* Disassembly display. + + Copyright 1998, 1999, 2000, 2001, 2004 Free Software Foundation, + Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_DISASM_H +#define TUI_DISASM_H + +#include "tui/tui.h" /* For enum tui_status. */ +#include "tui/tui-data.h" /* For enum tui_scroll_direction. */ + +extern enum tui_status tui_set_disassem_content (CORE_ADDR); +extern void tui_show_disassem (CORE_ADDR); +extern void tui_show_disassem_and_update_source (CORE_ADDR); +extern void tui_vertical_disassem_scroll (enum tui_scroll_direction, int); +extern CORE_ADDR tui_get_begin_asm_address (void); + +#endif diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c new file mode 100644 index 00000000000..61b1f93dcbd --- /dev/null +++ b/gdb/tui/tui-io.c @@ -0,0 +1,722 @@ +/* TUI support I/O functions. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "terminal.h" +#include "target.h" +#include "event-loop.h" +#include "event-top.h" +#include "command.h" +#include "top.h" +#include "readline/readline.h" +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-io.h" +#include "tui/tui-command.h" +#include "tui/tui-win.h" +#include "tui/tui-wingeneral.h" +#include "tui/tui-file.h" +#include "ui-out.h" +#include "cli-out.h" +#include <fcntl.h> +#include <signal.h> +#include <stdio.h> + +#ifdef HAVE_NCURSES_H +#include <ncurses.h> +#else +#ifdef HAVE_CURSES_H +#include <curses.h> +#endif +#endif + +int +key_is_start_sequence (int ch) +{ + return (ch == 27); +} + +int +key_is_end_sequence (int ch) +{ + return (ch == 126); +} + +int +key_is_backspace (int ch) +{ + return (ch == 8); +} + +int +key_is_command_char (int ch) +{ + return ((ch == KEY_NPAGE) || (ch == KEY_PPAGE) + || (ch == KEY_LEFT) || (ch == KEY_RIGHT) + || (ch == KEY_UP) || (ch == KEY_DOWN) + || (ch == KEY_SF) || (ch == KEY_SR) + || (ch == (int)'\f') || key_is_start_sequence (ch)); +} + +/* Use definition from readline 4.3. */ +#undef CTRL_CHAR +#define CTRL_CHAR(c) ((c) < control_character_threshold && (((c) & 0x80) == 0)) + +/* This file controls the IO interactions between gdb and curses. + When the TUI is enabled, gdb has two modes a curses and a standard + mode. + + In curses mode, the gdb outputs are made in a curses command window. + For this, the gdb_stdout and gdb_stderr are redirected to the specific + ui_file implemented by TUI. The output is handled by tui_puts(). + The input is also controlled by curses with tui_getc(). The readline + library uses this function to get its input. Several readline hooks + are installed to redirect readline output to the TUI (see also the + note below). + + In normal mode, the gdb outputs are restored to their origin, that + is as if TUI is not used. Readline also uses its original getc() + function with stdin. + + Note SCz/2001-07-21: the current readline is not clean in its management of + the output. Even if we install a redisplay handler, it sometimes writes on + a stdout file. It is important to redirect every output produced by + readline, otherwise the curses window will be garbled. This is implemented + with a pipe that TUI reads and readline writes to. A gdb input handler + is created so that reading the pipe is handled automatically. + This will probably not work on non-Unix platforms. The best fix is + to make readline clean enougth so that is never write on stdout. + + Note SCz/2002-09-01: we now use more readline hooks and it seems that + with them we don't need the pipe anymore (verified by creating the pipe + and closing its end so that write causes a SIGPIPE). The old pipe code + is still there and can be conditionally removed by + #undef TUI_USE_PIPE_FOR_READLINE. */ + +/* For gdb 5.3, prefer to continue the pipe hack as a backup wheel. */ +#define TUI_USE_PIPE_FOR_READLINE +/*#undef TUI_USE_PIPE_FOR_READLINE*/ + +/* TUI output files. */ +static struct ui_file *tui_stdout; +static struct ui_file *tui_stderr; +struct ui_out *tui_out; + +/* GDB output files in non-curses mode. */ +static struct ui_file *tui_old_stdout; +static struct ui_file *tui_old_stderr; +struct ui_out *tui_old_uiout; + +/* Readline previous hooks. */ +static Function *tui_old_rl_getc_function; +static VFunction *tui_old_rl_redisplay_function; +static VFunction *tui_old_rl_prep_terminal; +static VFunction *tui_old_rl_deprep_terminal; +static int tui_old_readline_echoing_p; + +/* Readline output stream. + Should be removed when readline is clean. */ +static FILE *tui_rl_outstream; +static FILE *tui_old_rl_outstream; +#ifdef TUI_USE_PIPE_FOR_READLINE +static int tui_readline_pipe[2]; +#endif + +/* The last gdb prompt that was registered in readline. + This may be the main gdb prompt or a secondary prompt. */ +static char *tui_rl_saved_prompt; + +static unsigned int _tuiHandleResizeDuringIO (unsigned int); + +static void +tui_putc (char c) +{ + char buf[2]; + + buf[0] = c; + buf[1] = 0; + tui_puts (buf); +} + +/* Print the string in the curses command window. */ +void +tui_puts (const char *string) +{ + static int tui_skip_line = -1; + char c; + WINDOW *w; + + w = cmdWin->generic.handle; + while ((c = *string++) != 0) + { + /* Catch annotation and discard them. We need two \032 and + discard until a \n is seen. */ + if (c == '\032') + { + tui_skip_line++; + } + else if (tui_skip_line != 1) + { + tui_skip_line = -1; + waddch (w, c); + } + else if (c == '\n') + tui_skip_line = -1; + } + getyx (w, cmdWin->detail.commandInfo.curLine, + cmdWin->detail.commandInfo.curch); + cmdWin->detail.commandInfo.start_line = cmdWin->detail.commandInfo.curLine; + + /* We could defer the following. */ + wrefresh (w); + fflush (stdout); +} + +/* Readline callback. + Redisplay the command line with its prompt after readline has + changed the edited text. */ +void +tui_redisplay_readline (void) +{ + int prev_col; + int height; + int col, line; + int c_pos; + int c_line; + int in; + WINDOW *w; + char *prompt; + int start_line; + + /* Detect when we temporarily left SingleKey and now the readline + edit buffer is empty, automatically restore the SingleKey mode. */ + if (tui_current_key_mode == tui_one_command_mode && rl_end == 0) + tui_set_key_mode (tui_single_key_mode); + + if (tui_current_key_mode == tui_single_key_mode) + prompt = ""; + else + prompt = tui_rl_saved_prompt; + + c_pos = -1; + c_line = -1; + w = cmdWin->generic.handle; + start_line = cmdWin->detail.commandInfo.start_line; + wmove (w, start_line, 0); + prev_col = 0; + height = 1; + for (in = 0; prompt && prompt[in]; in++) + { + waddch (w, prompt[in]); + getyx (w, line, col); + if (col < prev_col) + height++; + prev_col = col; + } + for (in = 0; in < rl_end; in++) + { + unsigned char c; + + c = (unsigned char) rl_line_buffer[in]; + if (in == rl_point) + { + getyx (w, c_line, c_pos); + } + + if (CTRL_CHAR (c) || c == RUBOUT) + { + waddch (w, '^'); + waddch (w, CTRL_CHAR (c) ? UNCTRL (c) : '?'); + } + else + { + waddch (w, c); + } + if (c == '\n') + { + getyx (w, cmdWin->detail.commandInfo.start_line, + cmdWin->detail.commandInfo.curch); + } + getyx (w, line, col); + if (col < prev_col) + height++; + prev_col = col; + } + wclrtobot (w); + getyx (w, cmdWin->detail.commandInfo.start_line, + cmdWin->detail.commandInfo.curch); + if (c_line >= 0) + { + wmove (w, c_line, c_pos); + cmdWin->detail.commandInfo.curLine = c_line; + cmdWin->detail.commandInfo.curch = c_pos; + } + cmdWin->detail.commandInfo.start_line -= height - 1; + + wrefresh (w); + fflush(stdout); +} + +/* Readline callback to prepare the terminal. It is called once + each time we enter readline. Terminal is already setup in curses mode. */ +static void +tui_prep_terminal (int notused1) +{ + /* Save the prompt registered in readline to correctly display it. + (we can't use gdb_prompt() due to secondary prompts and can't use + rl_prompt because it points to an alloca buffer). */ + xfree (tui_rl_saved_prompt); + tui_rl_saved_prompt = xstrdup (rl_prompt); +} + +/* Readline callback to restore the terminal. It is called once + each time we leave readline. There is nothing to do in curses mode. */ +static void +tui_deprep_terminal (void) +{ +} + +#ifdef TUI_USE_PIPE_FOR_READLINE +/* Read readline output pipe and feed the command window with it. + Should be removed when readline is clean. */ +static void +tui_readline_output (int code, gdb_client_data data) +{ + int size; + char buf[256]; + + size = read (tui_readline_pipe[0], buf, sizeof (buf) - 1); + if (size > 0 && tui_active) + { + buf[size] = 0; + tui_puts (buf); + } +} +#endif + +/* Return the portion of PATHNAME that should be output when listing + possible completions. If we are hacking filename completion, we + are only interested in the basename, the portion following the + final slash. Otherwise, we return what we were passed. + + Comes from readline/complete.c */ +static char * +printable_part (pathname) + char *pathname; +{ + char *temp; + + temp = rl_filename_completion_desired ? strrchr (pathname, '/') : (char *)NULL; +#if defined (__MSDOS__) + if (rl_filename_completion_desired && temp == 0 && isalpha (pathname[0]) && pathname[1] == ':') + temp = pathname + 1; +#endif + return (temp ? ++temp : pathname); +} + +/* Output TO_PRINT to rl_outstream. If VISIBLE_STATS is defined and we + are using it, check for and output a single character for `special' + filenames. Return the number of characters we output. */ + +#define PUTX(c) \ + do { \ + if (CTRL_CHAR (c)) \ + { \ + tui_puts ("^"); \ + tui_putc (UNCTRL (c)); \ + printed_len += 2; \ + } \ + else if (c == RUBOUT) \ + { \ + tui_puts ("^?"); \ + printed_len += 2; \ + } \ + else \ + { \ + tui_putc (c); \ + printed_len++; \ + } \ + } while (0) + +static int +print_filename (to_print, full_pathname) + char *to_print, *full_pathname; +{ + int printed_len = 0; + char *s; + + for (s = to_print; *s; s++) + { + PUTX (*s); + } + return printed_len; +} + +/* The user must press "y" or "n". Non-zero return means "y" pressed. + Comes from readline/complete.c */ +static int +get_y_or_n () +{ + extern int _rl_abort_internal (); + int c; + + for (;;) + { + c = rl_read_key (); + if (c == 'y' || c == 'Y' || c == ' ') + return (1); + if (c == 'n' || c == 'N' || c == RUBOUT) + return (0); + if (c == ABORT_CHAR) + _rl_abort_internal (); + beep (); + } +} + +/* A convenience function for displaying a list of strings in + columnar format on readline's output stream. MATCHES is the list + of strings, in argv format, LEN is the number of strings in MATCHES, + and MAX is the length of the longest string in MATCHES. + + Comes from readline/complete.c and modified to write in + the TUI command window using tui_putc/tui_puts. */ +static void +tui_rl_display_match_list (matches, len, max) + char **matches; + int len, max; +{ + typedef int QSFUNC (const void *, const void *); + extern int _rl_qsort_string_compare (const void*, const void*); + extern int _rl_print_completions_horizontally; + + int count, limit, printed_len; + int i, j, k, l; + char *temp; + + /* Screen dimension correspond to the TUI command window. */ + int screenwidth = cmdWin->generic.width; + + /* If there are many items, then ask the user if she really wants to + see them all. */ + if (len >= rl_completion_query_items) + { + char msg[256]; + + sprintf (msg, "\nDisplay all %d possibilities? (y or n)", len); + tui_puts (msg); + if (get_y_or_n () == 0) + { + tui_puts ("\n"); + return; + } + } + + /* How many items of MAX length can we fit in the screen window? */ + max += 2; + limit = screenwidth / max; + if (limit != 1 && (limit * max == screenwidth)) + limit--; + + /* Avoid a possible floating exception. If max > screenwidth, + limit will be 0 and a divide-by-zero fault will result. */ + if (limit == 0) + limit = 1; + + /* How many iterations of the printing loop? */ + count = (len + (limit - 1)) / limit; + + /* Watch out for special case. If LEN is less than LIMIT, then + just do the inner printing loop. + 0 < len <= limit implies count = 1. */ + + /* Sort the items if they are not already sorted. */ + if (rl_ignore_completion_duplicates == 0) + qsort (matches + 1, len, sizeof (char *), + (QSFUNC *)_rl_qsort_string_compare); + + tui_putc ('\n'); + + if (_rl_print_completions_horizontally == 0) + { + /* Print the sorted items, up-and-down alphabetically, like ls. */ + for (i = 1; i <= count; i++) + { + for (j = 0, l = i; j < limit; j++) + { + if (l > len || matches[l] == 0) + break; + else + { + temp = printable_part (matches[l]); + printed_len = print_filename (temp, matches[l]); + + if (j + 1 < limit) + for (k = 0; k < max - printed_len; k++) + tui_putc (' '); + } + l += count; + } + tui_putc ('\n'); + } + } + else + { + /* Print the sorted items, across alphabetically, like ls -x. */ + for (i = 1; matches[i]; i++) + { + temp = printable_part (matches[i]); + printed_len = print_filename (temp, matches[i]); + /* Have we reached the end of this line? */ + if (matches[i+1]) + { + if (i && (limit > 1) && (i % limit) == 0) + tui_putc ('\n'); + else + for (k = 0; k < max - printed_len; k++) + tui_putc (' '); + } + } + tui_putc ('\n'); + } +} + +/* Setup the IO for curses or non-curses mode. + - In non-curses mode, readline and gdb use the standard input and + standard output/error directly. + - In curses mode, the standard output/error is controlled by TUI + with the tui_stdout and tui_stderr. The output is redirected in + the curses command window. Several readline callbacks are installed + so that readline asks for its input to the curses command window + with wgetch(). */ +void +tui_setup_io (int mode) +{ + extern int readline_echoing_p; + + if (mode) + { + /* Redirect readline to TUI. */ + tui_old_rl_redisplay_function = rl_redisplay_function; + tui_old_rl_deprep_terminal = rl_deprep_term_function; + tui_old_rl_prep_terminal = rl_prep_term_function; + tui_old_rl_getc_function = rl_getc_function; + tui_old_rl_outstream = rl_outstream; + tui_old_readline_echoing_p = readline_echoing_p; + rl_redisplay_function = tui_redisplay_readline; + rl_deprep_term_function = tui_deprep_terminal; + rl_prep_term_function = tui_prep_terminal; + rl_getc_function = tui_getc; + readline_echoing_p = 0; + rl_outstream = tui_rl_outstream; + rl_prompt = 0; + rl_completion_display_matches_hook = tui_rl_display_match_list; + rl_already_prompted = 0; + + /* Keep track of previous gdb output. */ + tui_old_stdout = gdb_stdout; + tui_old_stderr = gdb_stderr; + tui_old_uiout = uiout; + + /* Reconfigure gdb output. */ + gdb_stdout = tui_stdout; + gdb_stderr = tui_stderr; + gdb_stdlog = gdb_stdout; /* for moment */ + gdb_stdtarg = gdb_stderr; /* for moment */ + uiout = tui_out; + + /* Save tty for SIGCONT. */ + savetty (); + } + else + { + /* Restore gdb output. */ + gdb_stdout = tui_old_stdout; + gdb_stderr = tui_old_stderr; + gdb_stdlog = gdb_stdout; /* for moment */ + gdb_stdtarg = gdb_stderr; /* for moment */ + uiout = tui_old_uiout; + + /* Restore readline. */ + rl_redisplay_function = tui_old_rl_redisplay_function; + rl_deprep_term_function = tui_old_rl_deprep_terminal; + rl_prep_term_function = tui_old_rl_prep_terminal; + rl_getc_function = tui_old_rl_getc_function; + rl_outstream = tui_old_rl_outstream; + rl_completion_display_matches_hook = 0; + readline_echoing_p = tui_old_readline_echoing_p; + rl_already_prompted = 0; + + /* Save tty for SIGCONT. */ + savetty (); + } +} + +#ifdef SIGCONT +/* Catch SIGCONT to restore the terminal and refresh the screen. */ +static void +tui_cont_sig (int sig) +{ + if (tui_active) + { + /* Restore the terminal setting because another process (shell) + might have changed it. */ + resetty (); + + /* Force a refresh of the screen. */ + tuiRefreshAll (); + + /* Update cursor position on the screen. */ + wmove (cmdWin->generic.handle, + cmdWin->detail.commandInfo.start_line, + cmdWin->detail.commandInfo.curch); + wrefresh (cmdWin->generic.handle); + } + signal (sig, tui_cont_sig); +} +#endif + +/* Initialize the IO for gdb in curses mode. */ +void +tui_initialize_io () +{ +#ifdef SIGCONT + signal (SIGCONT, tui_cont_sig); +#endif + + /* Create tui output streams. */ + tui_stdout = tui_fileopen (stdout); + tui_stderr = tui_fileopen (stderr); + tui_out = tui_out_new (tui_stdout); + + /* Create the default UI. It is not created because we installed + a init_ui_hook. */ + tui_old_uiout = uiout = cli_out_new (gdb_stdout); + +#ifdef TUI_USE_PIPE_FOR_READLINE + /* Temporary solution for readline writing to stdout: + redirect readline output in a pipe, read that pipe and + output the content in the curses command window. */ + if (pipe (tui_readline_pipe) != 0) + { + fprintf_unfiltered (gdb_stderr, "Cannot create pipe for readline"); + exit (1); + } + tui_rl_outstream = fdopen (tui_readline_pipe[1], "w"); + if (tui_rl_outstream == 0) + { + fprintf_unfiltered (gdb_stderr, "Cannot redirect readline output"); + exit (1); + } + setvbuf (tui_rl_outstream, (char*) NULL, _IOLBF, 0); + +#ifdef O_NONBLOCK + (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NONBLOCK); +#else +#ifdef O_NDELAY + (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NDELAY); +#endif +#endif + add_file_handler (tui_readline_pipe[0], tui_readline_output, 0); +#else + tui_rl_outstream = stdout; +#endif +} + +/* Get a character from the command window. This is called from the readline + package. */ +int +tui_getc (FILE *fp) +{ + int ch; + WINDOW *w; + + w = cmdWin->generic.handle; + +#ifdef TUI_USE_PIPE_FOR_READLINE + /* Flush readline output. */ + tui_readline_output (GDB_READABLE, 0); +#endif + + ch = wgetch (w); + ch = _tuiHandleResizeDuringIO (ch); + + /* The \n must be echoed because it will not be printed by readline. */ + if (ch == '\n') + { + /* When hitting return with an empty input, gdb executes the last + command. If we emit a newline, this fills up the command window + with empty lines with gdb prompt at beginning. Instead of that, + stay on the same line but provide a visual effect to show the + user we recognized the command. */ + if (rl_end == 0) + { + wmove (w, cmdWin->detail.commandInfo.curLine, 0); + + /* Clear the line. This will blink the gdb prompt since + it will be redrawn at the same line. */ + wclrtoeol (w); + wrefresh (w); + napms (20); + } + else + { + wmove (w, cmdWin->detail.commandInfo.curLine, + cmdWin->detail.commandInfo.curch); + waddch (w, ch); + } + } + + if (key_is_command_char (ch)) + { /* Handle prev/next/up/down here */ + ch = tui_dispatch_ctrl_char (ch); + } + + if (ch == '\n' || ch == '\r' || ch == '\f') + cmdWin->detail.commandInfo.curch = 0; +#if 0 + else + tuiIncrCommandCharCountBy (1); +#endif + if (ch == KEY_BACKSPACE) + return '\b'; + + return ch; +} + + +/* Cleanup when a resize has occured. + Returns the character that must be processed. */ +static unsigned int +_tuiHandleResizeDuringIO (unsigned int originalCh) +{ + if (tuiWinResized ()) + { + tuiRefreshAll (); + dont_repeat (); + tuiSetWinResizedTo (FALSE); + return '\n'; + } + else + return originalCh; +} diff --git a/gdb/tui/tui-io.h b/gdb/tui/tui-io.h new file mode 100644 index 00000000000..06d085de93f --- /dev/null +++ b/gdb/tui/tui-io.h @@ -0,0 +1,55 @@ +/* TUI support I/O functions. + + Copyright 1998, 1999, 2000, 2001, 2002, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_IO_H +#define TUI_IO_H + +struct ui_out; + +/* Print the string in the curses command window. */ +extern void tui_puts (const char *); + +/* Setup the IO for curses or non-curses mode. */ +extern void tui_setup_io (int mode); + +/* Initialize the IO for gdb in curses mode. */ +extern void tui_initialize_io (void); + +/* Get a character from the command window. */ +extern int tui_getc (FILE *); + +/* Readline callback. + Redisplay the command line with its prompt after readline has + changed the edited text. */ +extern void tui_redisplay_readline (void); + +extern struct ui_out *tui_out; +extern struct ui_out *tui_old_uiout; + +extern int key_is_start_sequence (int ch); +extern int key_is_end_sequence (int ch); +extern int key_is_backspace (int ch); +extern int key_is_command_char (int ch); + +#endif diff --git a/gdb/tui/tui-layout.c b/gdb/tui/tui-layout.c new file mode 100644 index 00000000000..38d8de57a00 --- /dev/null +++ b/gdb/tui/tui-layout.c @@ -0,0 +1,1140 @@ +/* TUI layout window management. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "command.h" +#include "symtab.h" +#include "frame.h" +#include "source.h" +#include <ctype.h> + +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-windata.h" +#include "tui/tui-wingeneral.h" +#include "tui/tui-stack.h" +#include "tui/tui-regs.h" +#include "tui/tui-win.h" +#include "tui/tui-winsource.h" +#include "tui/tui-disasm.h" + +#ifdef HAVE_NCURSES_H +#include <ncurses.h> +#else +#ifdef HAVE_CURSES_H +#include <curses.h> +#endif +#endif + +/******************************* +** Static Local Decls +********************************/ +static void showLayout (TuiLayoutType); +static void _initGenWinInfo (TuiGenWinInfoPtr, TuiWinType, int, int, int, int); +static void _initAndMakeWin (Opaque *, TuiWinType, int, int, int, int, int); +static void _showSourceOrDisassemAndCommand (TuiLayoutType); +static void _makeSourceOrDisassemWindow (TuiWinInfoPtr *, TuiWinType, int, int); +static void _makeCommandWindow (TuiWinInfoPtr *, int, int); +static void _makeSourceWindow (TuiWinInfoPtr *, int, int); +static void _makeDisassemWindow (TuiWinInfoPtr *, int, int); +static void _makeDataWindow (TuiWinInfoPtr *, int, int); +static void _showSourceCommand (void); +static void _showDisassemCommand (void); +static void _showSourceDisassemCommand (void); +static void _showData (TuiLayoutType); +static TuiLayoutType _nextLayout (void); +static TuiLayoutType _prevLayout (void); +static void _tuiLayout_command (char *, int); +static void _tuiToggleLayout_command (char *, int); +static void _tuiToggleSplitLayout_command (char *, int); +static CORE_ADDR _extractDisplayStartAddr (void); +static void _tuiHandleXDBLayout (TuiLayoutDefPtr); + + +/*************************************** +** DEFINITIONS +***************************************/ + +#define LAYOUT_USAGE "Usage: layout prev | next | <layout_name> \n" + +/* Show the screen layout defined. */ +static void +showLayout (TuiLayoutType layout) +{ + TuiLayoutType curLayout = currentLayout (); + + if (layout != curLayout) + { + /* + ** Since the new layout may cause changes in window size, we + ** should free the content and reallocate on next display of + ** source/asm + */ + freeAllSourceWinsContent (); + clearSourceWindows (); + if (layout == SRC_DATA_COMMAND || layout == DISASSEM_DATA_COMMAND) + { + _showData (layout); + refreshAll (winList); + } + else + { + /* First make the current layout be invisible */ + m_allBeInvisible (); + m_beInvisible (locatorWinInfoPtr ()); + + switch (layout) + { + /* Now show the new layout */ + case SRC_COMMAND: + _showSourceCommand (); + addToSourceWindows (srcWin); + break; + case DISASSEM_COMMAND: + _showDisassemCommand (); + addToSourceWindows (disassemWin); + break; + case SRC_DISASSEM_COMMAND: + _showSourceDisassemCommand (); + addToSourceWindows (srcWin); + addToSourceWindows (disassemWin); + break; + default: + break; + } + } + } +} + + +/* Function to set the layout to SRC_COMMAND, DISASSEM_COMMAND, + SRC_DISASSEM_COMMAND, SRC_DATA_COMMAND, or DISASSEM_DATA_COMMAND. + If the layout is SRC_DATA_COMMAND, DISASSEM_DATA_COMMAND, or + UNDEFINED_LAYOUT, then the data window is populated according to + regsDisplayType. */ +enum tui_status +tui_set_layout (enum tui_layout_type layoutType, + enum tui_register_display_type regsDisplayType) +{ + TuiStatus status = TUI_SUCCESS; + + if (layoutType != UNDEFINED_LAYOUT || regsDisplayType != TUI_UNDEFINED_REGS) + { + TuiLayoutType curLayout = currentLayout (), newLayout = UNDEFINED_LAYOUT; + int regsPopulate = FALSE; + CORE_ADDR addr = _extractDisplayStartAddr (); + TuiWinInfoPtr newWinWithFocus = (TuiWinInfoPtr) NULL, winWithFocus = tuiWinWithFocus (); + TuiLayoutDefPtr layoutDef = tuiLayoutDef (); + + + if (layoutType == UNDEFINED_LAYOUT && + regsDisplayType != TUI_UNDEFINED_REGS) + { + if (curLayout == SRC_DISASSEM_COMMAND) + newLayout = DISASSEM_DATA_COMMAND; + else if (curLayout == SRC_COMMAND || curLayout == SRC_DATA_COMMAND) + newLayout = SRC_DATA_COMMAND; + else if (curLayout == DISASSEM_COMMAND || + curLayout == DISASSEM_DATA_COMMAND) + newLayout = DISASSEM_DATA_COMMAND; + } + else + newLayout = layoutType; + + regsPopulate = (newLayout == SRC_DATA_COMMAND || + newLayout == DISASSEM_DATA_COMMAND || + regsDisplayType != TUI_UNDEFINED_REGS); + if (newLayout != curLayout || regsDisplayType != TUI_UNDEFINED_REGS) + { + if (newLayout != curLayout) + { + showLayout (newLayout); + /* + ** Now determine where focus should be + */ + if (winWithFocus != cmdWin) + { + switch (newLayout) + { + case SRC_COMMAND: + tuiSetWinFocusTo (srcWin); + layoutDef->displayMode = SRC_WIN; + layoutDef->split = FALSE; + break; + case DISASSEM_COMMAND: + /* the previous layout was not showing + ** code. this can happen if there is no + ** source available: + ** 1. if the source file is in another dir OR + ** 2. if target was compiled without -g + ** We still want to show the assembly though! + */ + addr = tui_get_begin_asm_address (); + tuiSetWinFocusTo (disassemWin); + layoutDef->displayMode = DISASSEM_WIN; + layoutDef->split = FALSE; + break; + case SRC_DISASSEM_COMMAND: + /* the previous layout was not showing + ** code. this can happen if there is no + ** source available: + ** 1. if the source file is in another dir OR + ** 2. if target was compiled without -g + ** We still want to show the assembly though! + */ + addr = tui_get_begin_asm_address (); + if (winWithFocus == srcWin) + tuiSetWinFocusTo (srcWin); + else + tuiSetWinFocusTo (disassemWin); + layoutDef->split = TRUE; + break; + case SRC_DATA_COMMAND: + if (winWithFocus != dataWin) + tuiSetWinFocusTo (srcWin); + else + tuiSetWinFocusTo (dataWin); + layoutDef->displayMode = SRC_WIN; + layoutDef->split = FALSE; + break; + case DISASSEM_DATA_COMMAND: + /* the previous layout was not showing + ** code. this can happen if there is no + ** source available: + ** 1. if the source file is in another dir OR + ** 2. if target was compiled without -g + ** We still want to show the assembly though! + */ + addr = tui_get_begin_asm_address (); + if (winWithFocus != dataWin) + tuiSetWinFocusTo (disassemWin); + else + tuiSetWinFocusTo (dataWin); + layoutDef->displayMode = DISASSEM_WIN; + layoutDef->split = FALSE; + break; + default: + break; + } + } + if (newWinWithFocus != (TuiWinInfoPtr) NULL) + tuiSetWinFocusTo (newWinWithFocus); + /* + ** Now update the window content + */ + if (!regsPopulate && + (newLayout == SRC_DATA_COMMAND || + newLayout == DISASSEM_DATA_COMMAND)) + tuiDisplayAllData (); + + tuiUpdateSourceWindowsWithAddr (addr); + } + if (regsPopulate) + { + layoutDef->regsDisplayType = + (regsDisplayType == TUI_UNDEFINED_REGS ? + TUI_GENERAL_REGS : regsDisplayType); + tui_show_registers (layoutDef->regsDisplayType); + } + } + } + else + status = TUI_FAILURE; + + return status; +} + +/* Add the specified window to the layout in a logical way. This + means setting up the most logical layout given the window to be + added. */ +void +tui_add_win_to_layout (enum tui_win_type type) +{ + TuiLayoutType curLayout = currentLayout (); + + switch (type) + { + case SRC_WIN: + if (curLayout != SRC_COMMAND && + curLayout != SRC_DISASSEM_COMMAND && + curLayout != SRC_DATA_COMMAND) + { + clearSourceWindowsDetail (); + if (curLayout == DISASSEM_DATA_COMMAND) + showLayout (SRC_DATA_COMMAND); + else + showLayout (SRC_COMMAND); + } + break; + case DISASSEM_WIN: + if (curLayout != DISASSEM_COMMAND && + curLayout != SRC_DISASSEM_COMMAND && + curLayout != DISASSEM_DATA_COMMAND) + { + clearSourceWindowsDetail (); + if (curLayout == SRC_DATA_COMMAND) + showLayout (DISASSEM_DATA_COMMAND); + else + showLayout (DISASSEM_COMMAND); + } + break; + case DATA_WIN: + if (curLayout != SRC_DATA_COMMAND && + curLayout != DISASSEM_DATA_COMMAND) + { + if (curLayout == DISASSEM_COMMAND) + showLayout (DISASSEM_DATA_COMMAND); + else + showLayout (SRC_DATA_COMMAND); + } + break; + default: + break; + } + + return; +} /* tuiAddWinToLayout */ + + +/* + ** tuiDefaultWinHeight(). + ** Answer the height of a window. If it hasn't been created yet, + ** answer what the height of a window would be based upon its + ** type and the layout. + */ +int +tuiDefaultWinHeight (TuiWinType type, TuiLayoutType layout) +{ + int h; + + if (winList[type] != (TuiWinInfoPtr) NULL) + h = winList[type]->generic.height; + else + { + switch (layout) + { + case SRC_COMMAND: + case DISASSEM_COMMAND: + if (m_winPtrIsNull (cmdWin)) + h = termHeight () / 2; + else + h = termHeight () - cmdWin->generic.height; + break; + case SRC_DISASSEM_COMMAND: + case SRC_DATA_COMMAND: + case DISASSEM_DATA_COMMAND: + if (m_winPtrIsNull (cmdWin)) + h = termHeight () / 3; + else + h = (termHeight () - cmdWin->generic.height) / 2; + break; + default: + h = 0; + break; + } + } + + return h; +} /* tuiDefaultWinHeight */ + + +/* Answer the height of a window. If it hasn't been created yet, + answer what the height of a window would be based upon its type and + the layout. */ +int +tui_default_win_viewport_height (enum tui_win_type type, + enum tui_layout_type layout) +{ + int h; + + h = tuiDefaultWinHeight (type, layout); + + if (winList[type] == cmdWin) + h -= 1; + else + h -= 2; + + return h; +} /* tuiDefaultWinViewportHeight */ + + +/* + ** _initialize_tuiLayout(). + ** Function to initialize gdb commands, for tui window layout + ** manipulation. + */ +void +_initialize_tuiLayout (void) +{ + add_com ("layout", class_tui, _tuiLayout_command, + "Change the layout of windows.\n\ +Usage: layout prev | next | <layout_name> \n\ +Layout names are:\n\ + src : Displays source and command windows.\n\ + asm : Displays disassembly and command windows.\n\ + split : Displays source, disassembly and command windows.\n\ + regs : Displays register window. If existing layout\n\ + is source/command or assembly/command, the \n\ + register window is displayed. If the\n\ + source/assembly/command (split) is displayed, \n\ + the register window is displayed with \n\ + the window that has current logical focus.\n"); + if (xdb_commands) + { + add_com ("td", class_tui, _tuiToggleLayout_command, + "Toggle between Source/Command and Disassembly/Command layouts.\n"); + add_com ("ts", class_tui, _tuiToggleSplitLayout_command, + "Toggle between Source/Command or Disassembly/Command and \n\ +Source/Disassembly/Command layouts.\n"); + } +} + + +/************************* +** STATIC LOCAL FUNCTIONS +**************************/ + + +/* + ** _tuiSetLayoutTo() + ** Function to set the layout to SRC, ASM, SPLIT, NEXT, PREV, DATA, REGS, + ** $REGS, $GREGS, $FREGS, $SREGS. + */ +TuiStatus +tui_set_layout_for_display_command (const char *layoutName) +{ + TuiStatus status = TUI_SUCCESS; + + if (layoutName != (char *) NULL) + { + register int i; + register char *bufPtr; + TuiLayoutType newLayout = UNDEFINED_LAYOUT; + TuiRegisterDisplayType dpyType = TUI_UNDEFINED_REGS; + TuiLayoutType curLayout = currentLayout (); + + bufPtr = (char *) xstrdup (layoutName); + for (i = 0; (i < strlen (layoutName)); i++) + bufPtr[i] = toupper (bufPtr[i]); + + /* First check for ambiguous input */ + if (strlen (bufPtr) <= 1 && (*bufPtr == 'S' || *bufPtr == '$')) + { + warning ("Ambiguous command input.\n"); + status = TUI_FAILURE; + } + else + { + if (subset_compare (bufPtr, "SRC")) + newLayout = SRC_COMMAND; + else if (subset_compare (bufPtr, "ASM")) + newLayout = DISASSEM_COMMAND; + else if (subset_compare (bufPtr, "SPLIT")) + newLayout = SRC_DISASSEM_COMMAND; + else if (subset_compare (bufPtr, "REGS") || + subset_compare (bufPtr, TUI_GENERAL_SPECIAL_REGS_NAME) || + subset_compare (bufPtr, TUI_GENERAL_REGS_NAME) || + subset_compare (bufPtr, TUI_FLOAT_REGS_NAME) || + subset_compare (bufPtr, TUI_SPECIAL_REGS_NAME)) + { + if (curLayout == SRC_COMMAND || curLayout == SRC_DATA_COMMAND) + newLayout = SRC_DATA_COMMAND; + else + newLayout = DISASSEM_DATA_COMMAND; + +/* could ifdef out the following code. when compile with -z, there are null + pointer references that cause a core dump if 'layout regs' is the first + layout command issued by the user. HP has asked us to hook up this code + - edie epstein + */ + if (subset_compare (bufPtr, TUI_FLOAT_REGS_NAME)) + { + if (dataWin->detail.dataDisplayInfo.regsDisplayType != + TUI_SFLOAT_REGS && + dataWin->detail.dataDisplayInfo.regsDisplayType != + TUI_DFLOAT_REGS) + dpyType = TUI_SFLOAT_REGS; + else + dpyType = + dataWin->detail.dataDisplayInfo.regsDisplayType; + } + else if (subset_compare (bufPtr, + TUI_GENERAL_SPECIAL_REGS_NAME)) + dpyType = TUI_GENERAL_AND_SPECIAL_REGS; + else if (subset_compare (bufPtr, TUI_GENERAL_REGS_NAME)) + dpyType = TUI_GENERAL_REGS; + else if (subset_compare (bufPtr, TUI_SPECIAL_REGS_NAME)) + dpyType = TUI_SPECIAL_REGS; + else if (dataWin) + { + if (dataWin->detail.dataDisplayInfo.regsDisplayType != + TUI_UNDEFINED_REGS) + dpyType = + dataWin->detail.dataDisplayInfo.regsDisplayType; + else + dpyType = TUI_GENERAL_REGS; + } + +/* end of potential ifdef + */ + +/* if ifdefed out code above, then assume that the user wishes to display the + general purpose registers + */ + +/* dpyType = TUI_GENERAL_REGS; + */ + } + else if (subset_compare (bufPtr, "NEXT")) + newLayout = _nextLayout (); + else if (subset_compare (bufPtr, "PREV")) + newLayout = _prevLayout (); + else + status = TUI_FAILURE; + xfree (bufPtr); + + tui_set_layout (newLayout, dpyType); + } + } + else + status = TUI_FAILURE; + + return status; +} + + +static CORE_ADDR +_extractDisplayStartAddr (void) +{ + TuiLayoutType curLayout = currentLayout (); + CORE_ADDR addr; + CORE_ADDR pc; + struct symtab_and_line cursal = get_current_source_symtab_and_line (); + + switch (curLayout) + { + case SRC_COMMAND: + case SRC_DATA_COMMAND: + find_line_pc (cursal.symtab, + srcWin->detail.sourceInfo.startLineOrAddr.lineNo, + &pc); + addr = pc; + break; + case DISASSEM_COMMAND: + case SRC_DISASSEM_COMMAND: + case DISASSEM_DATA_COMMAND: + addr = disassemWin->detail.sourceInfo.startLineOrAddr.addr; + break; + default: + addr = 0; + break; + } + + return addr; +} /* _extractDisplayStartAddr */ + + +static void +_tuiHandleXDBLayout (TuiLayoutDefPtr layoutDef) +{ + if (layoutDef->split) + { + tui_set_layout (SRC_DISASSEM_COMMAND, TUI_UNDEFINED_REGS); + tuiSetWinFocusTo (winList[layoutDef->displayMode]); + } + else + { + if (layoutDef->displayMode == SRC_WIN) + tui_set_layout (SRC_COMMAND, TUI_UNDEFINED_REGS); + else + tui_set_layout (DISASSEM_DATA_COMMAND, layoutDef->regsDisplayType); + } + + + return; +} /* _tuiHandleXDBLayout */ + + +static void +_tuiToggleLayout_command (char *arg, int fromTTY) +{ + TuiLayoutDefPtr layoutDef = tuiLayoutDef (); + + /* Make sure the curses mode is enabled. */ + tui_enable (); + if (layoutDef->displayMode == SRC_WIN) + layoutDef->displayMode = DISASSEM_WIN; + else + layoutDef->displayMode = SRC_WIN; + + if (!layoutDef->split) + _tuiHandleXDBLayout (layoutDef); + +} + + +static void +_tuiToggleSplitLayout_command (char *arg, int fromTTY) +{ + TuiLayoutDefPtr layoutDef = tuiLayoutDef (); + + /* Make sure the curses mode is enabled. */ + tui_enable (); + layoutDef->split = (!layoutDef->split); + _tuiHandleXDBLayout (layoutDef); + +} + + +static void +_tuiLayout_command (char *arg, int fromTTY) +{ + /* Make sure the curses mode is enabled. */ + tui_enable (); + + /* Switch to the selected layout. */ + if (tui_set_layout_for_display_command (arg) != TUI_SUCCESS) + warning ("Invalid layout specified.\n%s", LAYOUT_USAGE); + +} + +/* + ** _nextLayout(). + ** Answer the previous layout to cycle to. + */ +static TuiLayoutType +_nextLayout (void) +{ + TuiLayoutType newLayout; + + newLayout = currentLayout (); + if (newLayout == UNDEFINED_LAYOUT) + newLayout = SRC_COMMAND; + else + { + newLayout++; + if (newLayout == UNDEFINED_LAYOUT) + newLayout = SRC_COMMAND; + } + + return newLayout; +} /* _nextLayout */ + + +/* + ** _prevLayout(). + ** Answer the next layout to cycle to. + */ +static TuiLayoutType +_prevLayout (void) +{ + TuiLayoutType newLayout; + + newLayout = currentLayout (); + if (newLayout == SRC_COMMAND) + newLayout = DISASSEM_DATA_COMMAND; + else + { + newLayout--; + if (newLayout == UNDEFINED_LAYOUT) + newLayout = DISASSEM_DATA_COMMAND; + } + + return newLayout; +} /* _prevLayout */ + + + +/* + ** _makeCommandWindow(). + */ +static void +_makeCommandWindow (TuiWinInfoPtr * winInfoPtr, int height, int originY) +{ + _initAndMakeWin ((Opaque *) winInfoPtr, + CMD_WIN, + height, + termWidth (), + 0, + originY, + DONT_BOX_WINDOW); + + (*winInfoPtr)->canHighlight = FALSE; + + return; +} /* _makeCommandWindow */ + + +/* + ** _makeSourceWindow(). + */ +static void +_makeSourceWindow (TuiWinInfoPtr * winInfoPtr, int height, int originY) +{ + _makeSourceOrDisassemWindow (winInfoPtr, SRC_WIN, height, originY); + + return; +} /* _makeSourceWindow */ + + +/* + ** _makeDisassemWindow(). + */ +static void +_makeDisassemWindow (TuiWinInfoPtr * winInfoPtr, int height, int originY) +{ + _makeSourceOrDisassemWindow (winInfoPtr, DISASSEM_WIN, height, originY); + + return; +} /* _makeDisassemWindow */ + + +/* + ** _makeDataWindow(). + */ +static void +_makeDataWindow (TuiWinInfoPtr * winInfoPtr, int height, int originY) +{ + _initAndMakeWin ((Opaque *) winInfoPtr, + DATA_WIN, + height, + termWidth (), + 0, + originY, + BOX_WINDOW); + + return; +} /* _makeDataWindow */ + + + +/* + ** _showSourceCommand(). + ** Show the Source/Command layout + */ +static void +_showSourceCommand (void) +{ + _showSourceOrDisassemAndCommand (SRC_COMMAND); + + return; +} /* _showSourceCommand */ + + +/* + ** _showDisassemCommand(). + ** Show the Dissassem/Command layout + */ +static void +_showDisassemCommand (void) +{ + _showSourceOrDisassemAndCommand (DISASSEM_COMMAND); + + return; +} /* _showDisassemCommand */ + + +/* + ** _showSourceDisassemCommand(). + ** Show the Source/Disassem/Command layout + */ +static void +_showSourceDisassemCommand (void) +{ + if (currentLayout () != SRC_DISASSEM_COMMAND) + { + int cmdHeight, srcHeight, asmHeight; + + if (m_winPtrNotNull (cmdWin)) + cmdHeight = cmdWin->generic.height; + else + cmdHeight = termHeight () / 3; + + srcHeight = (termHeight () - cmdHeight) / 2; + asmHeight = termHeight () - (srcHeight + cmdHeight); + + if (m_winPtrIsNull (srcWin)) + _makeSourceWindow (&srcWin, srcHeight, 0); + else + { + _initGenWinInfo (&srcWin->generic, + srcWin->generic.type, + srcHeight, + srcWin->generic.width, + srcWin->detail.sourceInfo.executionInfo->width, + 0); + srcWin->canHighlight = TRUE; + _initGenWinInfo (srcWin->detail.sourceInfo.executionInfo, + EXEC_INFO_WIN, + srcHeight, + 3, + 0, + 0); + m_beVisible (srcWin); + m_beVisible (srcWin->detail.sourceInfo.executionInfo); + srcWin->detail.sourceInfo.hasLocator = FALSE;; + } + if (m_winPtrNotNull (srcWin)) + { + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + + tuiShowSourceContent (srcWin); + if (m_winPtrIsNull (disassemWin)) + { + _makeDisassemWindow (&disassemWin, asmHeight, srcHeight - 1); + _initAndMakeWin ((Opaque *) & locator, + LOCATOR_WIN, + 2 /* 1 */ , + termWidth (), + 0, + (srcHeight + asmHeight) - 1, + DONT_BOX_WINDOW); + } + else + { + _initGenWinInfo (locator, + LOCATOR_WIN, + 2 /* 1 */ , + termWidth (), + 0, + (srcHeight + asmHeight) - 1); + disassemWin->detail.sourceInfo.hasLocator = TRUE; + _initGenWinInfo ( + &disassemWin->generic, + disassemWin->generic.type, + asmHeight, + disassemWin->generic.width, + disassemWin->detail.sourceInfo.executionInfo->width, + srcHeight - 1); + _initGenWinInfo (disassemWin->detail.sourceInfo.executionInfo, + EXEC_INFO_WIN, + asmHeight, + 3, + 0, + srcHeight - 1); + disassemWin->canHighlight = TRUE; + m_beVisible (disassemWin); + m_beVisible (disassemWin->detail.sourceInfo.executionInfo); + } + if (m_winPtrNotNull (disassemWin)) + { + srcWin->detail.sourceInfo.hasLocator = FALSE; + disassemWin->detail.sourceInfo.hasLocator = TRUE; + m_beVisible (locator); + tuiShowLocatorContent (); + tuiShowSourceContent (disassemWin); + + if (m_winPtrIsNull (cmdWin)) + _makeCommandWindow (&cmdWin, + cmdHeight, + termHeight () - cmdHeight); + else + { + _initGenWinInfo (&cmdWin->generic, + cmdWin->generic.type, + cmdWin->generic.height, + cmdWin->generic.width, + 0, + cmdWin->generic.origin.y); + cmdWin->canHighlight = FALSE; + m_beVisible (cmdWin); + } + if (m_winPtrNotNull (cmdWin)) + tuiRefreshWin (&cmdWin->generic); + } + } + setCurrentLayoutTo (SRC_DISASSEM_COMMAND); + } + + return; +} /* _showSourceDisassemCommand */ + + +/* + ** _showData(). + ** Show the Source/Data/Command or the Dissassembly/Data/Command layout + */ +static void +_showData (TuiLayoutType newLayout) +{ + int totalHeight = (termHeight () - cmdWin->generic.height); + int srcHeight, dataHeight; + TuiWinType winType; + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + + + dataHeight = totalHeight / 2; + srcHeight = totalHeight - dataHeight; + m_allBeInvisible (); + m_beInvisible (locator); + _makeDataWindow (&dataWin, dataHeight, 0); + dataWin->canHighlight = TRUE; + if (newLayout == SRC_DATA_COMMAND) + winType = SRC_WIN; + else + winType = DISASSEM_WIN; + if (m_winPtrIsNull (winList[winType])) + { + if (winType == SRC_WIN) + _makeSourceWindow (&winList[winType], srcHeight, dataHeight - 1); + else + _makeDisassemWindow (&winList[winType], srcHeight, dataHeight - 1); + _initAndMakeWin ((Opaque *) & locator, + LOCATOR_WIN, + 2 /* 1 */ , + termWidth (), + 0, + totalHeight - 1, + DONT_BOX_WINDOW); + } + else + { + _initGenWinInfo (&winList[winType]->generic, + winList[winType]->generic.type, + srcHeight, + winList[winType]->generic.width, + winList[winType]->detail.sourceInfo.executionInfo->width, + dataHeight - 1); + _initGenWinInfo (winList[winType]->detail.sourceInfo.executionInfo, + EXEC_INFO_WIN, + srcHeight, + 3, + 0, + dataHeight - 1); + m_beVisible (winList[winType]); + m_beVisible (winList[winType]->detail.sourceInfo.executionInfo); + _initGenWinInfo (locator, + LOCATOR_WIN, + 2 /* 1 */ , + termWidth (), + 0, + totalHeight - 1); + } + winList[winType]->detail.sourceInfo.hasLocator = TRUE; + m_beVisible (locator); + tuiShowLocatorContent (); + addToSourceWindows (winList[winType]); + setCurrentLayoutTo (newLayout); + + return; +} /* _showData */ + +/* + ** _initGenWinInfo(). + */ +static void +_initGenWinInfo (TuiGenWinInfoPtr winInfo, TuiWinType type, + int height, int width, int originX, int originY) +{ + int h = height; + + winInfo->type = type; + winInfo->width = width; + winInfo->height = h; + if (h > 1) + { + winInfo->viewportHeight = h - 1; + if (winInfo->type != CMD_WIN) + winInfo->viewportHeight--; + } + else + winInfo->viewportHeight = 1; + winInfo->origin.x = originX; + winInfo->origin.y = originY; + + return; +} /* _initGenWinInfo */ + +/* + ** _initAndMakeWin(). + */ +static void +_initAndMakeWin (Opaque * winInfoPtr, TuiWinType winType, + int height, int width, int originX, int originY, int boxIt) +{ + Opaque opaqueWinInfo = *winInfoPtr; + TuiGenWinInfoPtr generic; + + if (opaqueWinInfo == (Opaque) NULL) + { + if (m_winIsAuxillary (winType)) + opaqueWinInfo = (Opaque) allocGenericWinInfo (); + else + opaqueWinInfo = (Opaque) allocWinInfo (winType); + } + if (m_winIsAuxillary (winType)) + generic = (TuiGenWinInfoPtr) opaqueWinInfo; + else + generic = &((TuiWinInfoPtr) opaqueWinInfo)->generic; + + if (opaqueWinInfo != (Opaque) NULL) + { + _initGenWinInfo (generic, winType, height, width, originX, originY); + if (!m_winIsAuxillary (winType)) + { + if (generic->type == CMD_WIN) + ((TuiWinInfoPtr) opaqueWinInfo)->canHighlight = FALSE; + else + ((TuiWinInfoPtr) opaqueWinInfo)->canHighlight = TRUE; + } + makeWindow (generic, boxIt); + } + *winInfoPtr = opaqueWinInfo; +} + + +/* + ** _makeSourceOrDisassemWindow(). + */ +static void +_makeSourceOrDisassemWindow (TuiWinInfoPtr * winInfoPtr, TuiWinType type, + int height, int originY) +{ + TuiGenWinInfoPtr executionInfo = (TuiGenWinInfoPtr) NULL; + + /* + ** Create the exeuction info window. + */ + if (type == SRC_WIN) + executionInfo = sourceExecInfoWinPtr (); + else + executionInfo = disassemExecInfoWinPtr (); + _initAndMakeWin ((Opaque *) & executionInfo, + EXEC_INFO_WIN, + height, + 3, + 0, + originY, + DONT_BOX_WINDOW); + /* + ** Now create the source window. + */ + _initAndMakeWin ((Opaque *) winInfoPtr, + type, + height, + termWidth () - executionInfo->width, + executionInfo->width, + originY, + BOX_WINDOW); + + (*winInfoPtr)->detail.sourceInfo.executionInfo = executionInfo; + + return; +} /* _makeSourceOrDisassemWindow */ + + +/* + ** _showSourceOrDisassemAndCommand(). + ** Show the Source/Command or the Disassem layout + */ +static void +_showSourceOrDisassemAndCommand (TuiLayoutType layoutType) +{ + if (currentLayout () != layoutType) + { + TuiWinInfoPtr *winInfoPtr; + int srcHeight, cmdHeight; + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + + if (m_winPtrNotNull (cmdWin)) + cmdHeight = cmdWin->generic.height; + else + cmdHeight = termHeight () / 3; + srcHeight = termHeight () - cmdHeight; + + + if (layoutType == SRC_COMMAND) + winInfoPtr = &srcWin; + else + winInfoPtr = &disassemWin; + + if (m_winPtrIsNull (*winInfoPtr)) + { + if (layoutType == SRC_COMMAND) + _makeSourceWindow (winInfoPtr, srcHeight - 1, 0); + else + _makeDisassemWindow (winInfoPtr, srcHeight - 1, 0); + _initAndMakeWin ((Opaque *) & locator, + LOCATOR_WIN, + 2 /* 1 */ , + termWidth (), + 0, + srcHeight - 1, + DONT_BOX_WINDOW); + } + else + { + _initGenWinInfo (locator, + LOCATOR_WIN, + 2 /* 1 */ , + termWidth (), + 0, + srcHeight - 1); + (*winInfoPtr)->detail.sourceInfo.hasLocator = TRUE; + _initGenWinInfo ( + &(*winInfoPtr)->generic, + (*winInfoPtr)->generic.type, + srcHeight - 1, + (*winInfoPtr)->generic.width, + (*winInfoPtr)->detail.sourceInfo.executionInfo->width, + 0); + _initGenWinInfo ((*winInfoPtr)->detail.sourceInfo.executionInfo, + EXEC_INFO_WIN, + srcHeight - 1, + 3, + 0, + 0); + (*winInfoPtr)->canHighlight = TRUE; + m_beVisible (*winInfoPtr); + m_beVisible ((*winInfoPtr)->detail.sourceInfo.executionInfo); + } + if (m_winPtrNotNull (*winInfoPtr)) + { + (*winInfoPtr)->detail.sourceInfo.hasLocator = TRUE; + m_beVisible (locator); + tuiShowLocatorContent (); + tuiShowSourceContent (*winInfoPtr); + + if (m_winPtrIsNull (cmdWin)) + { + _makeCommandWindow (&cmdWin, cmdHeight, srcHeight); + tuiRefreshWin (&cmdWin->generic); + } + else + { + _initGenWinInfo (&cmdWin->generic, + cmdWin->generic.type, + cmdWin->generic.height, + cmdWin->generic.width, + cmdWin->generic.origin.x, + cmdWin->generic.origin.y); + cmdWin->canHighlight = FALSE; + m_beVisible (cmdWin); + } + } + setCurrentLayoutTo (layoutType); + } + + return; +} /* _showSourceOrDisassemAndCommand */ diff --git a/gdb/tui/tui-layout.h b/gdb/tui/tui-layout.h new file mode 100644 index 00000000000..5df1f0be9f1 --- /dev/null +++ b/gdb/tui/tui-layout.h @@ -0,0 +1,38 @@ +/* TUI layout window management. + + Copyright 1998, 1999, 2000, 2001, 2002, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_LAYOUT_H +#define TUI_LAYOUT_H + +#include "tui/tui.h" +#include "tui/tui-data.h" + +extern void tui_add_win_to_layout (enum tui_win_type); +extern int tui_default_win_height (enum tui_win_type, enum tui_layout_type); +extern int tui_default_win_viewport_height (enum tui_win_type, + enum tui_layout_type); +extern enum tui_status tui_set_layout (enum tui_layout_type, + enum tui_register_display_type); + +#endif /*TUI_LAYOUT_H */ diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c new file mode 100644 index 00000000000..68520b9f6eb --- /dev/null +++ b/gdb/tui/tui-regs.c @@ -0,0 +1,1023 @@ +/* TUI display registers in window. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "symtab.h" +#include "gdbtypes.h" +#include "gdbcmd.h" +#include "frame.h" +#include "regcache.h" +#include "inferior.h" +#include "target.h" +#include "tui/tui-layout.h" +#include "tui/tui-win.h" +#include "tui/tui-windata.h" +#include "tui/tui-wingeneral.h" +#include "tui/tui-file.h" + +#ifdef HAVE_NCURSES_H +#include <ncurses.h> +#else +#ifdef HAVE_CURSES_H +#include <curses.h> +#endif +#endif + +/***************************************** +** LOCAL DEFINITIONS ** +******************************************/ +#define DOUBLE_FLOAT_LABEL_WIDTH 6 +#define DOUBLE_FLOAT_LABEL_FMT "%6.6s: " +#define DOUBLE_FLOAT_VALUE_WIDTH 30 /*min of 16 but may be in sci notation */ + +#define SINGLE_FLOAT_LABEL_WIDTH 6 +#define SINGLE_FLOAT_LABEL_FMT "%6.6s: " +#define SINGLE_FLOAT_VALUE_WIDTH 25 /* min of 8 but may be in sci notation */ + +#define SINGLE_LABEL_WIDTH 16 +#define SINGLE_LABEL_FMT "%10.10s: " +#define SINGLE_VALUE_WIDTH 20 /* minimum of 8 but may be in sci notation */ + +/* In the code HP gave Cygnus, this was actually a function call to a + PA-specific function, which was supposed to determine whether the + target was a 64-bit or 32-bit processor. However, the 64-bit + support wasn't complete, so we didn't merge that in, so we leave + this here as a stub. */ +#define IS_64BIT 0 + +/***************************************** +** STATIC DATA ** +******************************************/ + + +/***************************************** +** STATIC LOCAL FUNCTIONS FORWARD DECLS ** +******************************************/ +static TuiStatus _tuiSetRegsContent + (int, int, struct frame_info *, TuiRegisterDisplayType, int); +static const char *_tuiRegisterName (int); +static TuiStatus _tuiGetRegisterRawValue (int, char *, struct frame_info *); +static void _tuiSetRegisterElement + (int, struct frame_info *, TuiDataElementPtr, int); +static void _tuiDisplayRegister (int, TuiGenWinInfoPtr, enum precision_type); +static void _tuiRegisterFormat + (char *, int, int, TuiDataElementPtr, enum precision_type); +static TuiStatus _tuiSetGeneralRegsContent (int); +static TuiStatus _tuiSetSpecialRegsContent (int); +static TuiStatus _tuiSetGeneralAndSpecialRegsContent (int); +static TuiStatus _tuiSetFloatRegsContent (TuiRegisterDisplayType, int); +static int _tuiRegValueHasChanged + (TuiDataElementPtr, struct frame_info *, char *); +static void _tuiShowFloat_command (char *, int); +static void _tuiShowGeneral_command (char *, int); +static void _tuiShowSpecial_command (char *, int); +static void _tui_vShowRegisters_commandSupport (TuiRegisterDisplayType); +static void _tuiToggleFloatRegs_command (char *, int); +static void _tuiScrollRegsForward_command (char *, int); +static void _tuiScrollRegsBackward_command (char *, int); + + + +/***************************************** +** PUBLIC FUNCTIONS ** +******************************************/ + +/* Answer the number of the last line in the regs display. If there + are no registers (-1) is returned. */ +int +tui_last_regs_line_no (void) +{ + register int numLines = (-1); + + if (dataWin->detail.dataDisplayInfo.regsContentCount > 0) + { + numLines = (dataWin->detail.dataDisplayInfo.regsContentCount / + dataWin->detail.dataDisplayInfo.regsColumnCount); + if (dataWin->detail.dataDisplayInfo.regsContentCount % + dataWin->detail.dataDisplayInfo.regsColumnCount) + numLines++; + } + return numLines; +} + + +/* Answer the line number that the register element at elementNo is + on. If elementNo is greater than the number of register elements + there are, -1 is returned. */ +int +tui_line_from_reg_element_no (int elementNo) +{ + if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount) + { + int i, line = (-1); + + i = 1; + while (line == (-1)) + { + if (elementNo < + (dataWin->detail.dataDisplayInfo.regsColumnCount * i)) + line = i - 1; + else + i++; + } + + return line; + } + else + return (-1); +} + + +/* Answer the index of the first element in lineNo. If lineNo is past + the register area (-1) is returned. */ +int +tui_first_reg_element_no_inline (int lineNo) +{ + if ((lineNo * dataWin->detail.dataDisplayInfo.regsColumnCount) + <= dataWin->detail.dataDisplayInfo.regsContentCount) + return ((lineNo + 1) * + dataWin->detail.dataDisplayInfo.regsColumnCount) - + dataWin->detail.dataDisplayInfo.regsColumnCount; + else + return (-1); +} + + +/* + ** tuiLastRegElementNoInLine() + ** Answer the index of the last element in lineNo. If lineNo is past + ** the register area (-1) is returned. + */ +int +tuiLastRegElementNoInLine (int lineNo) +{ + if ((lineNo * dataWin->detail.dataDisplayInfo.regsColumnCount) <= + dataWin->detail.dataDisplayInfo.regsContentCount) + return ((lineNo + 1) * + dataWin->detail.dataDisplayInfo.regsColumnCount) - 1; + else + return (-1); +} /* tuiLastRegElementNoInLine */ + + +/* Calculate the number of columns that should be used to display the + registers. */ +int +tui_calculate_regs_column_count (TuiRegisterDisplayType dpyType) +{ + int colCount, colWidth; + + if (IS_64BIT || dpyType == TUI_DFLOAT_REGS) + colWidth = DOUBLE_FLOAT_VALUE_WIDTH + DOUBLE_FLOAT_LABEL_WIDTH; + else + { + if (dpyType == TUI_SFLOAT_REGS) + colWidth = SINGLE_FLOAT_VALUE_WIDTH + SINGLE_FLOAT_LABEL_WIDTH; + else + colWidth = SINGLE_VALUE_WIDTH + SINGLE_LABEL_WIDTH; + } + colCount = (dataWin->generic.width - 2) / colWidth; + + return colCount; +} /* tuiCalulateRegsColumnCount */ + + +/* Show the registers int the data window as indicated by dpyType. If + there is any other registers being displayed, then they are + cleared. What registers are displayed is dependent upon dpyType. */ +void +tui_show_registers (TuiRegisterDisplayType dpyType) +{ + TuiStatus ret = TUI_FAILURE; + int refreshValuesOnly = FALSE; + + /* Say that registers should be displayed, even if there is a problem */ + dataWin->detail.dataDisplayInfo.displayRegs = TRUE; + + if (target_has_registers) + { + refreshValuesOnly = + (dpyType == dataWin->detail.dataDisplayInfo.regsDisplayType); + switch (dpyType) + { + case TUI_GENERAL_REGS: + ret = _tuiSetGeneralRegsContent (refreshValuesOnly); + break; + case TUI_SFLOAT_REGS: + case TUI_DFLOAT_REGS: + ret = _tuiSetFloatRegsContent (dpyType, refreshValuesOnly); + break; + +/* could ifdef out */ + + case TUI_SPECIAL_REGS: + ret = _tuiSetSpecialRegsContent (refreshValuesOnly); + break; + case TUI_GENERAL_AND_SPECIAL_REGS: + ret = _tuiSetGeneralAndSpecialRegsContent (refreshValuesOnly); + break; + +/* end of potential if def */ + + default: + break; + } + } + if (ret == TUI_FAILURE) + { + dataWin->detail.dataDisplayInfo.regsDisplayType = TUI_UNDEFINED_REGS; + tuiEraseDataContent (NO_REGS_STRING); + } + else + { + int i; + + /* Clear all notation of changed values */ + for (i = 0; (i < dataWin->detail.dataDisplayInfo.regsContentCount); i++) + { + TuiGenWinInfoPtr dataItemWin; + + dataItemWin = &dataWin->detail.dataDisplayInfo. + regsContent[i]->whichElement.dataWindow; + (&((TuiWinElementPtr) + dataItemWin->content[0])->whichElement.data)->highlight = FALSE; + } + dataWin->detail.dataDisplayInfo.regsDisplayType = dpyType; + tuiDisplayAllData (); + } + (tuiLayoutDef ())->regsDisplayType = dpyType; + + return; +} + + +/* Function to display the registers in the content from + 'startElementNo' until the end of the register content or the end + of the display height. No checking for displaying past the end of + the registers is done here. */ +void +tui_display_registers_from (int startElementNo) +{ + if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL && + dataWin->detail.dataDisplayInfo.regsContentCount > 0) + { + register int i = startElementNo; + int j, valueCharsWide, itemWinWidth, curY, labelWidth; + enum precision_type precision; + + precision = (dataWin->detail.dataDisplayInfo.regsDisplayType + == TUI_DFLOAT_REGS) ? + double_precision : unspecified_precision; + if (IS_64BIT || + dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS) + { + valueCharsWide = DOUBLE_FLOAT_VALUE_WIDTH; + labelWidth = DOUBLE_FLOAT_LABEL_WIDTH; + } + else + { + if (dataWin->detail.dataDisplayInfo.regsDisplayType == + TUI_SFLOAT_REGS) + { + valueCharsWide = SINGLE_FLOAT_VALUE_WIDTH; + labelWidth = SINGLE_FLOAT_LABEL_WIDTH; + } + else + { + valueCharsWide = SINGLE_VALUE_WIDTH; + labelWidth = SINGLE_LABEL_WIDTH; + } + } + itemWinWidth = valueCharsWide + labelWidth; + /* + ** Now create each data "sub" window, and write the display into it. + */ + curY = 1; + while (i < dataWin->detail.dataDisplayInfo.regsContentCount && + curY <= dataWin->generic.viewportHeight) + { + for (j = 0; + (j < dataWin->detail.dataDisplayInfo.regsColumnCount && + i < dataWin->detail.dataDisplayInfo.regsContentCount); j++) + { + TuiGenWinInfoPtr dataItemWin; + TuiDataElementPtr dataElementPtr; + + /* create the window if necessary */ + dataItemWin = &dataWin->detail.dataDisplayInfo. + regsContent[i]->whichElement.dataWindow; + dataElementPtr = &((TuiWinElementPtr) + dataItemWin->content[0])->whichElement.data; + if (dataItemWin->handle == (WINDOW *) NULL) + { + dataItemWin->height = 1; + dataItemWin->width = (precision == double_precision) ? + itemWinWidth + 2 : itemWinWidth + 1; + dataItemWin->origin.x = (itemWinWidth * j) + 1; + dataItemWin->origin.y = curY; + makeWindow (dataItemWin, DONT_BOX_WINDOW); + scrollok (dataItemWin->handle, FALSE); + } + touchwin (dataItemWin->handle); + + /* + ** Get the printable representation of the register + ** and display it + */ + _tuiDisplayRegister ( + dataElementPtr->itemNo, dataItemWin, precision); + i++; /* next register */ + } + curY++; /* next row; */ + } + } + + return; +} + + +/* + ** tuiDisplayRegElementAtLine(). + ** Function to display the registers in the content from + ** 'startElementNo' on 'startLineNo' until the end of the + ** register content or the end of the display height. + ** This function checks that we won't display off the end + ** of the register display. + */ +void +tuiDisplayRegElementAtLine (int startElementNo, int startLineNo) +{ + if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL && + dataWin->detail.dataDisplayInfo.regsContentCount > 0) + { + register int elementNo = startElementNo; + + if (startElementNo != 0 && startLineNo != 0) + { + register int lastLineNo, firstLineOnLastPage; + + lastLineNo = tui_last_regs_line_no (); + firstLineOnLastPage = lastLineNo - (dataWin->generic.height - 2); + if (firstLineOnLastPage < 0) + firstLineOnLastPage = 0; + /* + ** If there is no other data displayed except registers, + ** and the elementNo causes us to scroll past the end of the + ** registers, adjust what element to really start the display at. + */ + if (dataWin->detail.dataDisplayInfo.dataContentCount <= 0 && + startLineNo > firstLineOnLastPage) + elementNo = tui_first_reg_element_no_inline (firstLineOnLastPage); + } + tui_display_registers_from (elementNo); + } + + return; +} /* tuiDisplayRegElementAtLine */ + + + +/* Function to display the registers starting at line lineNo in the + data window. Answers the line number that the display actually + started from. If nothing is displayed (-1) is returned. */ +int +tui_display_registers_from_line (int lineNo, int forceDisplay) +{ + if (dataWin->detail.dataDisplayInfo.regsContentCount > 0) + { + int line, elementNo; + + if (lineNo < 0) + line = 0; + else if (forceDisplay) + { /* + ** If we must display regs (forceDisplay is true), then make + ** sure that we don't display off the end of the registers. + */ + if (lineNo >= tui_last_regs_line_no ()) + { + if ((line = tui_line_from_reg_element_no ( + dataWin->detail.dataDisplayInfo.regsContentCount - 1)) < 0) + line = 0; + } + else + line = lineNo; + } + else + line = lineNo; + + elementNo = tui_first_reg_element_no_inline (line); + if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount) + tuiDisplayRegElementAtLine (elementNo, line); + else + line = (-1); + + return line; + } + + return (-1); /* nothing was displayed */ +} + + +/* This function check all displayed registers for changes in values, + given a particular frame. If the values have changed, they are + updated with the new value and highlighted. */ +void +tui_check_register_values (struct frame_info *frame) +{ + if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible) + { + if (dataWin->detail.dataDisplayInfo.regsContentCount <= 0 && + dataWin->detail.dataDisplayInfo.displayRegs) + tui_show_registers ((tuiLayoutDef ())->regsDisplayType); + else + { + int i, j; + char rawBuf[MAX_REGISTER_SIZE]; + + for (i = 0; + (i < dataWin->detail.dataDisplayInfo.regsContentCount); i++) + { + TuiDataElementPtr dataElementPtr; + TuiGenWinInfoPtr dataItemWinPtr; + int wasHilighted; + + dataItemWinPtr = &dataWin->detail.dataDisplayInfo. + regsContent[i]->whichElement.dataWindow; + dataElementPtr = &((TuiWinElementPtr) + dataItemWinPtr->content[0])->whichElement.data; + wasHilighted = dataElementPtr->highlight; + dataElementPtr->highlight = + _tuiRegValueHasChanged (dataElementPtr, frame, &rawBuf[0]); + if (dataElementPtr->highlight) + { + int size; + + size = DEPRECATED_REGISTER_RAW_SIZE (dataElementPtr->itemNo); + for (j = 0; j < size; j++) + ((char *) dataElementPtr->value)[j] = rawBuf[j]; + _tuiDisplayRegister ( + dataElementPtr->itemNo, + dataItemWinPtr, + ((dataWin->detail.dataDisplayInfo.regsDisplayType == + TUI_DFLOAT_REGS) ? + double_precision : unspecified_precision)); + } + else if (wasHilighted) + { + dataElementPtr->highlight = FALSE; + _tuiDisplayRegister ( + dataElementPtr->itemNo, + dataItemWinPtr, + ((dataWin->detail.dataDisplayInfo.regsDisplayType == + TUI_DFLOAT_REGS) ? + double_precision : unspecified_precision)); + } + } + } + } + return; +} + + +/* + ** tuiToggleFloatRegs(). + */ +void +tuiToggleFloatRegs (void) +{ + TuiLayoutDefPtr layoutDef = tuiLayoutDef (); + + if (layoutDef->floatRegsDisplayType == TUI_SFLOAT_REGS) + layoutDef->floatRegsDisplayType = TUI_DFLOAT_REGS; + else + layoutDef->floatRegsDisplayType = TUI_SFLOAT_REGS; + + if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible && + (dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_SFLOAT_REGS || + dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS)) + tui_show_registers (layoutDef->floatRegsDisplayType); + + return; +} /* tuiToggleFloatRegs */ + + +void +_initialize_tuiRegs (void) +{ + if (xdb_commands) + { + add_com ("fr", class_tui, _tuiShowFloat_command, + "Display only floating point registers\n"); + add_com ("gr", class_tui, _tuiShowGeneral_command, + "Display only general registers\n"); + add_com ("sr", class_tui, _tuiShowSpecial_command, + "Display only special registers\n"); + add_com ("+r", class_tui, _tuiScrollRegsForward_command, + "Scroll the registers window forward\n"); + add_com ("-r", class_tui, _tuiScrollRegsBackward_command, + "Scroll the register window backward\n"); + add_com ("tf", class_tui, _tuiToggleFloatRegs_command, + "Toggle between single and double precision floating point registers.\n"); + add_cmd (TUI_FLOAT_REGS_NAME_LOWER, + class_tui, + _tuiToggleFloatRegs_command, + "Toggle between single and double precision floating point \ +registers.\n", + &togglelist); + } +} + + +/***************************************** +** STATIC LOCAL FUNCTIONS ** +******************************************/ + + +/* + ** _tuiRegisterName(). + ** Return the register name. + */ +static const char * +_tuiRegisterName (int regNum) +{ + return REGISTER_NAME (regNum); +} +extern int pagination_enabled; + +static void +tui_restore_gdbout (void *ui) +{ + ui_file_delete (gdb_stdout); + gdb_stdout = (struct ui_file*) ui; + pagination_enabled = 1; +} + +/* + ** _tuiRegisterFormat + ** Function to format the register name and value into a buffer, + ** suitable for printing or display + */ +static void +_tuiRegisterFormat (char *buf, int bufLen, int regNum, + TuiDataElementPtr dataElement, + enum precision_type precision) +{ + struct ui_file *stream; + struct ui_file *old_stdout; + const char *name; + struct cleanup *cleanups; + char *p; + int pos; + + name = REGISTER_NAME (regNum); + if (name == 0) + { + strcpy (buf, ""); + return; + } + + pagination_enabled = 0; + old_stdout = gdb_stdout; + stream = tui_sfileopen (bufLen); + gdb_stdout = stream; + cleanups = make_cleanup (tui_restore_gdbout, (void*) old_stdout); + gdbarch_print_registers_info (current_gdbarch, stream, deprecated_selected_frame, + regNum, 1); + + /* Save formatted output in the buffer. */ + p = tui_file_get_strbuf (stream); + pos = 0; + while (*p && *p == *name++ && bufLen) + { + *buf++ = *p++; + bufLen--; + pos++; + } + while (*p == ' ') + p++; + while (pos < 8 && bufLen) + { + *buf++ = ' '; + bufLen--; + pos++; + } + strncpy (buf, p, bufLen); + + /* Remove the possible \n. */ + p = strchr (buf, '\n'); + if (p) + *p = 0; + + do_cleanups (cleanups); +} + + +#define NUM_GENERAL_REGS 32 +/* + ** _tuiSetGeneralRegsContent(). + ** Set the content of the data window to consist of the general registers. + */ +static TuiStatus +_tuiSetGeneralRegsContent (int refreshValuesOnly) +{ + return (_tuiSetRegsContent (0, + NUM_GENERAL_REGS - 1, + deprecated_selected_frame, + TUI_GENERAL_REGS, + refreshValuesOnly)); + +} /* _tuiSetGeneralRegsContent */ + + +#ifndef PCOQ_HEAD_REGNUM +#define START_SPECIAL_REGS 0 +#else +#define START_SPECIAL_REGS PCOQ_HEAD_REGNUM +#endif + +/* + ** _tuiSetSpecialRegsContent(). + ** Set the content of the data window to consist of the special registers. + */ +static TuiStatus +_tuiSetSpecialRegsContent (int refreshValuesOnly) +{ + TuiStatus ret = TUI_FAILURE; + int endRegNum; + + endRegNum = FP0_REGNUM - 1; + ret = _tuiSetRegsContent (START_SPECIAL_REGS, + endRegNum, + deprecated_selected_frame, + TUI_SPECIAL_REGS, + refreshValuesOnly); + + return ret; +} /* _tuiSetSpecialRegsContent */ + + +/* + ** _tuiSetGeneralAndSpecialRegsContent(). + ** Set the content of the data window to consist of the special registers. + */ +static TuiStatus +_tuiSetGeneralAndSpecialRegsContent (int refreshValuesOnly) +{ + TuiStatus ret = TUI_FAILURE; + int endRegNum = (-1); + + endRegNum = FP0_REGNUM - 1; + ret = _tuiSetRegsContent ( + 0, endRegNum, deprecated_selected_frame, TUI_SPECIAL_REGS, refreshValuesOnly); + + return ret; +} /* _tuiSetGeneralAndSpecialRegsContent */ + +/* + ** _tuiSetFloatRegsContent(). + ** Set the content of the data window to consist of the float registers. + */ +static TuiStatus +_tuiSetFloatRegsContent (TuiRegisterDisplayType dpyType, int refreshValuesOnly) +{ + TuiStatus ret = TUI_FAILURE; + int startRegNum; + + startRegNum = FP0_REGNUM; + ret = _tuiSetRegsContent (startRegNum, + NUM_REGS - 1, + deprecated_selected_frame, + dpyType, + refreshValuesOnly); + + return ret; +} /* _tuiSetFloatRegsContent */ + + +/* + ** _tuiRegValueHasChanged(). + ** Answer TRUE if the register's value has changed, FALSE otherwise. + ** If TRUE, newValue is filled in with the new value. + */ +static int +_tuiRegValueHasChanged (TuiDataElementPtr dataElement, + struct frame_info *frame, + char *newValue) +{ + int hasChanged = FALSE; + + if (dataElement->itemNo != UNDEFINED_ITEM && + _tuiRegisterName (dataElement->itemNo) != (char *) NULL) + { + char rawBuf[MAX_REGISTER_SIZE]; + int i; + + if (_tuiGetRegisterRawValue ( + dataElement->itemNo, rawBuf, frame) == TUI_SUCCESS) + { + int size = DEPRECATED_REGISTER_RAW_SIZE (dataElement->itemNo); + + for (i = 0; (i < size && !hasChanged); i++) + hasChanged = (((char *) dataElement->value)[i] != rawBuf[i]); + if (hasChanged && newValue != (char *) NULL) + { + for (i = 0; i < size; i++) + newValue[i] = rawBuf[i]; + } + } + } + return hasChanged; +} /* _tuiRegValueHasChanged */ + + + +/* + ** _tuiGetRegisterRawValue(). + ** Get the register raw value. The raw value is returned in regValue. + */ +static TuiStatus +_tuiGetRegisterRawValue (int regNum, char *regValue, struct frame_info *frame) +{ + TuiStatus ret = TUI_FAILURE; + + if (target_has_registers) + { + get_frame_register (frame, regNum, regValue); + /* NOTE: cagney/2003-03-13: This is bogus. It is refering to + the register cache and not the frame which could have pulled + the register value off the stack. */ + if (register_cached (regNum) >= 0) + ret = TUI_SUCCESS; + } + return ret; +} /* _tuiGetRegisterRawValue */ + + + +/* + ** _tuiSetRegisterElement(). + ** Function to initialize a data element with the input and + ** the register value. + */ +static void +_tuiSetRegisterElement (int regNum, struct frame_info *frame, + TuiDataElementPtr dataElement, + int refreshValueOnly) +{ + if (dataElement != (TuiDataElementPtr) NULL) + { + if (!refreshValueOnly) + { + dataElement->itemNo = regNum; + dataElement->name = _tuiRegisterName (regNum); + dataElement->highlight = FALSE; + } + if (dataElement->value == (Opaque) NULL) + dataElement->value = (Opaque) xmalloc (MAX_REGISTER_SIZE); + if (dataElement->value != (Opaque) NULL) + _tuiGetRegisterRawValue (regNum, dataElement->value, frame); + } + + return; +} /* _tuiSetRegisterElement */ + + +/* + ** _tuiSetRegsContent(). + ** Set the content of the data window to consist of the registers + ** numbered from startRegNum to endRegNum. Note that if + ** refreshValuesOnly is TRUE, startRegNum and endRegNum are ignored. + */ +static TuiStatus +_tuiSetRegsContent (int startRegNum, int endRegNum, + struct frame_info *frame, + TuiRegisterDisplayType dpyType, + int refreshValuesOnly) +{ + TuiStatus ret = TUI_FAILURE; + int numRegs = endRegNum - startRegNum + 1; + int allocatedHere = FALSE; + + if (dataWin->detail.dataDisplayInfo.regsContentCount > 0 && + !refreshValuesOnly) + { + freeDataContent (dataWin->detail.dataDisplayInfo.regsContent, + dataWin->detail.dataDisplayInfo.regsContentCount); + dataWin->detail.dataDisplayInfo.regsContentCount = 0; + } + if (dataWin->detail.dataDisplayInfo.regsContentCount <= 0) + { + dataWin->detail.dataDisplayInfo.regsContent = + allocContent (numRegs, DATA_WIN); + allocatedHere = TRUE; + } + + if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL) + { + int i; + + if (!refreshValuesOnly || allocatedHere) + { + dataWin->generic.content = (OpaquePtr) NULL; + dataWin->generic.contentSize = 0; + addContentElements (&dataWin->generic, numRegs); + dataWin->detail.dataDisplayInfo.regsContent = + (TuiWinContent) dataWin->generic.content; + dataWin->detail.dataDisplayInfo.regsContentCount = numRegs; + } + /* + ** Now set the register names and values + */ + for (i = startRegNum; (i <= endRegNum); i++) + { + TuiGenWinInfoPtr dataItemWin; + + dataItemWin = &dataWin->detail.dataDisplayInfo. + regsContent[i - startRegNum]->whichElement.dataWindow; + _tuiSetRegisterElement ( + i, + frame, + &((TuiWinElementPtr) dataItemWin->content[0])->whichElement.data, + !allocatedHere && refreshValuesOnly); + } + dataWin->detail.dataDisplayInfo.regsColumnCount = + tui_calculate_regs_column_count (dpyType); +#ifdef LATER + if (dataWin->detail.dataDisplayInfo.dataContentCount > 0) + { + /* delete all the windows? */ + /* realloc content equal to dataContentCount + regsContentCount */ + /* append dataWin->detail.dataDisplayInfo.dataContent to content */ + } +#endif + dataWin->generic.contentSize = + dataWin->detail.dataDisplayInfo.regsContentCount + + dataWin->detail.dataDisplayInfo.dataContentCount; + ret = TUI_SUCCESS; + } + + return ret; +} /* _tuiSetRegsContent */ + + +/* + ** _tuiDisplayRegister(). + ** Function to display a register in a window. If hilite is TRUE, + ** than the value will be displayed in reverse video + */ +static void +_tuiDisplayRegister (int regNum, + TuiGenWinInfoPtr winInfo, /* the data item window */ + enum precision_type precision) +{ + if (winInfo->handle != (WINDOW *) NULL) + { + int i; + char buf[40]; + int valueCharsWide, labelWidth; + TuiDataElementPtr dataElementPtr = &((TuiWinContent) + winInfo->content)[0]->whichElement.data; + + if (IS_64BIT || + dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS) + { + valueCharsWide = DOUBLE_FLOAT_VALUE_WIDTH; + labelWidth = DOUBLE_FLOAT_LABEL_WIDTH; + } + else + { + if (dataWin->detail.dataDisplayInfo.regsDisplayType == + TUI_SFLOAT_REGS) + { + valueCharsWide = SINGLE_FLOAT_VALUE_WIDTH; + labelWidth = SINGLE_FLOAT_LABEL_WIDTH; + } + else + { + valueCharsWide = SINGLE_VALUE_WIDTH; + labelWidth = SINGLE_LABEL_WIDTH; + } + } + + buf[0] = (char) 0; + _tuiRegisterFormat (buf, + valueCharsWide + labelWidth, + regNum, + dataElementPtr, + precision); + + if (dataElementPtr->highlight) + wstandout (winInfo->handle); + + wmove (winInfo->handle, 0, 0); + for (i = 1; i < winInfo->width; i++) + waddch (winInfo->handle, ' '); + wmove (winInfo->handle, 0, 0); + waddstr (winInfo->handle, buf); + + if (dataElementPtr->highlight) + wstandend (winInfo->handle); + tuiRefreshWin (winInfo); + } + return; +} /* _tuiDisplayRegister */ + + +static void +_tui_vShowRegisters_commandSupport (TuiRegisterDisplayType dpyType) +{ + + if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible) + { /* Data window already displayed, show the registers */ + if (dataWin->detail.dataDisplayInfo.regsDisplayType != dpyType) + tui_show_registers (dpyType); + } + else + (tuiLayoutDef ())->regsDisplayType = dpyType; + + return; +} /* _tui_vShowRegisters_commandSupport */ + + +static void +_tuiShowFloat_command (char *arg, int fromTTY) +{ + if (m_winPtrIsNull (dataWin) || !dataWin->generic.isVisible || + (dataWin->detail.dataDisplayInfo.regsDisplayType != TUI_SFLOAT_REGS && + dataWin->detail.dataDisplayInfo.regsDisplayType != TUI_DFLOAT_REGS)) + _tui_vShowRegisters_commandSupport ((tuiLayoutDef ())->floatRegsDisplayType); + + return; +} /* _tuiShowFloat_command */ + + +static void +_tuiShowGeneral_command (char *arg, int fromTTY) +{ + _tui_vShowRegisters_commandSupport (TUI_GENERAL_REGS); +} + + +static void +_tuiShowSpecial_command (char *arg, int fromTTY) +{ + _tui_vShowRegisters_commandSupport (TUI_SPECIAL_REGS); +} + + +static void +_tuiToggleFloatRegs_command (char *arg, int fromTTY) +{ + if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible) + tuiToggleFloatRegs (); + else + { + TuiLayoutDefPtr layoutDef = tuiLayoutDef (); + + if (layoutDef->floatRegsDisplayType == TUI_SFLOAT_REGS) + layoutDef->floatRegsDisplayType = TUI_DFLOAT_REGS; + else + layoutDef->floatRegsDisplayType = TUI_SFLOAT_REGS; + } + + + return; +} /* _tuiToggleFloatRegs_command */ + + +static void +_tuiScrollRegsForward_command (char *arg, int fromTTY) +{ + tui_scroll (FORWARD_SCROLL, dataWin, 1); +} + + +static void +_tuiScrollRegsBackward_command (char *arg, int fromTTY) +{ + tui_scroll (BACKWARD_SCROLL, dataWin, 1); +} diff --git a/gdb/tui/tui-regs.h b/gdb/tui/tui-regs.h new file mode 100644 index 00000000000..19703a2ccbc --- /dev/null +++ b/gdb/tui/tui-regs.h @@ -0,0 +1,41 @@ +/* TUI display registers in window. + + Copyright 1998, 1999, 2000, 2001, 2004 Free Software Foundation, + Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_REGS_H +#define TUI_REGS_H + +#include "tui/tui-data.h" /* For TuiRegisterDisplayType. */ + +extern void tui_check_register_values (struct frame_info *); +extern void tui_show_registers (enum tui_register_display_type); +extern void tui_display_registers_from (int); +extern int tui_display_registers_from_line (int, int); +extern int tui_last_regs_line_no (void); +extern int tui_first_reg_element_inline (int); +extern int tui_line_from_reg_element_no (int); +extern void tui_toggle_float_regs (void); +extern int tui_calculate_regs_column_count (enum tui_register_display_type); +extern int tui_first_reg_element_no_inline (int lineno); + +#endif diff --git a/gdb/tui/tui-source.c b/gdb/tui/tui-source.c new file mode 100644 index 00000000000..f2d3762f8cd --- /dev/null +++ b/gdb/tui/tui-source.c @@ -0,0 +1,356 @@ +/* TUI display source window. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, + Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include <ctype.h> +#include "symtab.h" +#include "frame.h" +#include "breakpoint.h" +#include "source.h" +#include "symtab.h" + +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-stack.h" +#include "tui/tui-winsource.h" +#include "tui/tui-source.h" + +#ifdef HAVE_NCURSES_H +#include <ncurses.h> +#else +#ifdef HAVE_CURSES_H +#include <curses.h> +#endif +#endif + +/* Function to display source in the source window. */ +TuiStatus +tuiSetSourceContent (struct symtab *s, int lineNo, int noerror) +{ + TuiStatus ret = TUI_FAILURE; + + if (s != (struct symtab *) NULL && s->filename != (char *) NULL) + { + register FILE *stream; + register int i, desc, c, lineWidth, nlines; + register char *srcLine = 0; + + if ((ret = tuiAllocSourceBuffer (srcWin)) == TUI_SUCCESS) + { + lineWidth = srcWin->generic.width - 1; + /* Take hilite (window border) into account, when calculating + the number of lines */ + nlines = (lineNo + (srcWin->generic.height - 2)) - lineNo; + desc = open_source_file (s); + if (desc < 0) + { + if (!noerror) + { + char *name = alloca (strlen (s->filename) + 100); + sprintf (name, "%s:%d", s->filename, lineNo); + print_sys_errmsg (name, errno); + } + ret = TUI_FAILURE; + } + else + { + if (s->line_charpos == 0) + find_source_lines (s, desc); + + if (lineNo < 1 || lineNo > s->nlines) + { + close (desc); + printf_unfiltered ( + "Line number %d out of range; %s has %d lines.\n", + lineNo, s->filename, s->nlines); + } + else if (lseek (desc, s->line_charpos[lineNo - 1], 0) < 0) + { + close (desc); + perror_with_name (s->filename); + } + else + { + register int offset, curLineNo, curLine, curLen, threshold; + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + TuiSourceInfoPtr src = &srcWin->detail.sourceInfo; + + if (srcWin->generic.title) + xfree (srcWin->generic.title); + srcWin->generic.title = xstrdup (s->filename); + + if (src->filename) + xfree (src->filename); + src->filename = xstrdup (s->filename); + + /* Determine the threshold for the length of the line + and the offset to start the display. */ + offset = src->horizontalOffset; + threshold = (lineWidth - 1) + offset; + stream = fdopen (desc, FOPEN_RT); + clearerr (stream); + curLine = 0; + curLineNo = src->startLineOrAddr.lineNo = lineNo; + if (offset > 0) + srcLine = (char *) xmalloc ( + (threshold + 1) * sizeof (char)); + while (curLine < nlines) + { + TuiWinElementPtr element = (TuiWinElementPtr) + srcWin->generic.content[curLine]; + + /* get the first character in the line */ + c = fgetc (stream); + + if (offset == 0) + srcLine = ((TuiWinElementPtr) + srcWin->generic.content[ + curLine])->whichElement.source.line; + /* Init the line with the line number */ + sprintf (srcLine, "%-6d", curLineNo); + curLen = strlen (srcLine); + i = curLen - + ((curLen / tuiDefaultTabLen ()) * tuiDefaultTabLen ()); + while (i < tuiDefaultTabLen ()) + { + srcLine[curLen] = ' '; + i++; + curLen++; + } + srcLine[curLen] = (char) 0; + + /* Set whether element is the execution point and + whether there is a break point on it. */ + element->whichElement.source.lineOrAddr.lineNo = + curLineNo; + element->whichElement.source.isExecPoint = + (strcmp (((TuiWinElementPtr) + locator->content[0])->whichElement.locator.fileName, + s->filename) == 0 + && curLineNo == ((TuiWinElementPtr) + locator->content[0])->whichElement.locator.lineNo); + if (c != EOF) + { + i = strlen (srcLine) - 1; + do + { + if ((c != '\n') && + (c != '\r') && (++i < threshold)) + { + if (c < 040 && c != '\t') + { + srcLine[i++] = '^'; + srcLine[i] = c + 0100; + } + else if (c == 0177) + { + srcLine[i++] = '^'; + srcLine[i] = '?'; + } + else + { /* Store the charcter in the line + buffer. If it is a tab, then + translate to the correct number of + chars so we don't overwrite our + buffer. */ + if (c == '\t') + { + int j, maxTabLen = tuiDefaultTabLen (); + + for (j = i - ( + (i / maxTabLen) * maxTabLen); + ((j < maxTabLen) && + i < threshold); + i++, j++) + srcLine[i] = ' '; + i--; + } + else + srcLine[i] = c; + } + srcLine[i + 1] = 0; + } + else + { /* If we have not reached EOL, then eat + chars until we do */ + while (c != EOF && c != '\n' && c != '\r') + c = fgetc (stream); + } + } + while (c != EOF && c != '\n' && c != '\r' && + i < threshold && (c = fgetc (stream))); + } + /* Now copy the line taking the offset into account */ + if (strlen (srcLine) > offset) + strcpy (((TuiWinElementPtr) srcWin->generic.content[ + curLine])->whichElement.source.line, + &srcLine[offset]); + else + ((TuiWinElementPtr) + srcWin->generic.content[ + curLine])->whichElement.source.line[0] = (char) 0; + curLine++; + curLineNo++; + } + if (offset > 0) + tuiFree (srcLine); + fclose (stream); + srcWin->generic.contentSize = nlines; + ret = TUI_SUCCESS; + } + } + } + } + return ret; +} + + +/* elz: this function sets the contents of the source window to empty + except for a line in the middle with a warning message about the + source not being available. This function is called by + tuiEraseSourceContents, which in turn is invoked when the source files + cannot be accessed */ + +void +tuiSetSourceContentNil (TuiWinInfoPtr winInfo, char *warning_string) +{ + int lineWidth; + int nLines; + int curr_line = 0; + + lineWidth = winInfo->generic.width - 1; + nLines = winInfo->generic.height - 2; + + /* set to empty each line in the window, except for the one + which contains the message */ + while (curr_line < winInfo->generic.contentSize) + { + /* set the information related to each displayed line + to null: i.e. the line number is 0, there is no bp, + it is not where the program is stopped */ + + TuiWinElementPtr element = + (TuiWinElementPtr) winInfo->generic.content[curr_line]; + element->whichElement.source.lineOrAddr.lineNo = 0; + element->whichElement.source.isExecPoint = FALSE; + element->whichElement.source.hasBreak = FALSE; + + /* set the contents of the line to blank */ + element->whichElement.source.line[0] = (char) 0; + + /* if the current line is in the middle of the screen, then we want to + display the 'no source available' message in it. + Note: the 'weird' arithmetic with the line width and height comes from + the function tuiEraseSourceContent. We need to keep the screen and the + window's actual contents in synch */ + + if (curr_line == (nLines / 2 + 1)) + { + int i; + int xpos; + int warning_length = strlen (warning_string); + char *srcLine; + + srcLine = element->whichElement.source.line; + + if (warning_length >= ((lineWidth - 1) / 2)) + xpos = 1; + else + xpos = (lineWidth - 1) / 2 - warning_length; + + for (i = 0; i < xpos; i++) + srcLine[i] = ' '; + + sprintf (srcLine + i, "%s", warning_string); + + for (i = xpos + warning_length; i < lineWidth; i++) + srcLine[i] = ' '; + + srcLine[i] = '\n'; + + } /* end if */ + + curr_line++; + + } /* end while */ +} + + +/* Function to display source in the source window. This function + initializes the horizontal scroll to 0. */ +void +tuiShowSource (struct symtab *s, TuiLineOrAddress line, int noerror) +{ + srcWin->detail.sourceInfo.horizontalOffset = 0; + tuiUpdateSourceWindowAsIs(srcWin, s, line, noerror); +} + + +/* Answer whether the source is currently displayed in the source window. */ +int +tuiSourceIsDisplayed (char *fname) +{ + return (srcWin->generic.contentInUse && + (strcmp (((TuiWinElementPtr) (locatorWinInfoPtr ())-> + content[0])->whichElement.locator.fileName, fname) == 0)); +} + + +/* Scroll the source forward or backward vertically. */ +void +tuiVerticalSourceScroll (TuiScrollDirection scrollDirection, + int numToScroll) +{ + if (srcWin->generic.content != (OpaquePtr) NULL) + { + TuiLineOrAddress l; + struct symtab *s; + TuiWinContent content = (TuiWinContent) srcWin->generic.content; + struct symtab_and_line cursal = get_current_source_symtab_and_line (); + + if (cursal.symtab == (struct symtab *) NULL) + s = find_pc_symtab (get_frame_pc (deprecated_selected_frame)); + else + s = cursal.symtab; + + if (scrollDirection == FORWARD_SCROLL) + { + l.lineNo = content[0]->whichElement.source.lineOrAddr.lineNo + + numToScroll; + if (l.lineNo > s->nlines) + /*line = s->nlines - winInfo->generic.contentSize + 1; */ + /*elz: fix for dts 23398 */ + l.lineNo = content[0]->whichElement.source.lineOrAddr.lineNo; + } + else + { + l.lineNo = content[0]->whichElement.source.lineOrAddr.lineNo - + numToScroll; + if (l.lineNo <= 0) + l.lineNo = 1; + } + + print_source_lines (s, l.lineNo, l.lineNo + 1, 0); + } +} diff --git a/gdb/tui/tui-source.h b/gdb/tui/tui-source.h new file mode 100644 index 00000000000..96cf8652aca --- /dev/null +++ b/gdb/tui/tui-source.h @@ -0,0 +1,33 @@ +/* TUI display source window. + Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _TUI_SOURCE_H +#define _TUI_SOURCE_H + +#include "defs.h" + +extern TuiStatus tuiSetSourceContent (struct symtab *, int, int); +extern void tuiShowSource (struct symtab *, TuiLineOrAddress, int); +extern int tuiSourceIsDisplayed (char *); +extern void tuiVerticalSourceScroll (TuiScrollDirection, int); + +#endif +/*_TUI_SOURCE_H*/ diff --git a/gdb/tui/tui-stack.c b/gdb/tui/tui-stack.c new file mode 100644 index 00000000000..6bf64bb4b19 --- /dev/null +++ b/gdb/tui/tui-stack.c @@ -0,0 +1,435 @@ +/* TUI display locator. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, + Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "symtab.h" +#include "breakpoint.h" +#include "frame.h" +#include "command.h" +#include "inferior.h" +#include "target.h" +#include "top.h" + +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-stack.h" +#include "tui/tui-wingeneral.h" +#include "tui/tui-source.h" +#include "tui/tui-winsource.h" +#include "tui/tui-file.h" + +#ifdef HAVE_NCURSES_H +#include <ncurses.h> +#else +#ifdef HAVE_CURSES_H +#include <curses.h> +#endif +#endif + +/* Get a printable name for the function at the address. + The symbol name is demangled if demangling is turned on. + Returns a pointer to a static area holding the result. */ +static char* tui_get_function_from_frame (struct frame_info *fi); + +/* Set the filename portion of the locator. */ +static void tui_set_locator_filename (const char *filename); + +/* Update the locator, with the provided arguments. */ +static void tui_set_locator_info (const char *filename, const char *procname, + int lineno, CORE_ADDR addr); + +static void tui_update_command (char *, int); + + +/* Create the status line to display as much information as we + can on this single line: target name, process number, current + function, current line, current PC, SingleKey mode. */ +static char* +tui_make_status_line (TuiLocatorElement* loc) +{ + char* string; + char line_buf[50], *pname; + char* buf; + int status_size; + int i, proc_width; + const char* pid_name; + const char* pc_buf; + int target_width; + int pid_width; + int line_width; + int pc_width; + struct ui_file *pc_out; + + if (ptid_equal (inferior_ptid, null_ptid)) + pid_name = "No process"; + else + pid_name = target_pid_to_str (inferior_ptid); + + target_width = strlen (target_shortname); + if (target_width > MAX_TARGET_WIDTH) + target_width = MAX_TARGET_WIDTH; + + pid_width = strlen (pid_name); + if (pid_width > MAX_PID_WIDTH) + pid_width = MAX_PID_WIDTH; + + status_size = termWidth (); + string = (char *) xmalloc (status_size + 1); + buf = (char*) alloca (status_size + 1); + + /* Translate line number and obtain its size. */ + if (loc->lineNo > 0) + sprintf (line_buf, "%d", loc->lineNo); + else + strcpy (line_buf, "??"); + line_width = strlen (line_buf); + if (line_width < MIN_LINE_WIDTH) + line_width = MIN_LINE_WIDTH; + + /* Translate PC address. */ + pc_out = tui_sfileopen (128); + print_address_numeric (loc->addr, 1, pc_out); + pc_buf = tui_file_get_strbuf (pc_out); + pc_width = strlen (pc_buf); + + /* First determine the amount of proc name width we have available. + The +1 are for a space separator between fields. + The -1 are to take into account the \0 counted by sizeof. */ + proc_width = (status_size + - (target_width + 1) + - (pid_width + 1) + - (sizeof (PROC_PREFIX) - 1 + 1) + - (sizeof (LINE_PREFIX) - 1 + line_width + 1) + - (sizeof (PC_PREFIX) - 1 + pc_width + 1) + - (tui_current_key_mode == tui_single_key_mode + ? (sizeof (SINGLE_KEY) - 1 + 1) + : 0)); + + /* If there is no room to print the function name, try by removing + some fields. */ + if (proc_width < MIN_PROC_WIDTH) + { + proc_width += target_width + 1; + target_width = 0; + if (proc_width < MIN_PROC_WIDTH) + { + proc_width += pid_width + 1; + pid_width = 0; + if (proc_width <= MIN_PROC_WIDTH) + { + proc_width += pc_width + sizeof (PC_PREFIX) - 1 + 1; + pc_width = 0; + if (proc_width < 0) + { + proc_width += line_width + sizeof (LINE_PREFIX) - 1 + 1; + line_width = 0; + if (proc_width < 0) + proc_width = 0; + } + } + } + } + + /* Now convert elements to string form */ + pname = loc->procName; + + /* Now create the locator line from the string version + of the elements. We could use sprintf() here but + that wouldn't ensure that we don't overrun the size + of the allocated buffer. strcat_to_buf() will. */ + *string = (char) 0; + + if (target_width > 0) + { + sprintf (buf, "%*.*s ", + -target_width, target_width, target_shortname); + strcat_to_buf (string, status_size, buf); + } + if (pid_width > 0) + { + sprintf (buf, "%*.*s ", + -pid_width, pid_width, pid_name); + strcat_to_buf (string, status_size, buf); + } + + /* Show whether we are in SingleKey mode. */ + if (tui_current_key_mode == tui_single_key_mode) + { + strcat_to_buf (string, status_size, SINGLE_KEY); + strcat_to_buf (string, status_size, " "); + } + + /* procedure/class name */ + if (proc_width > 0) + { + if (strlen (pname) > proc_width) + sprintf (buf, "%s%*.*s* ", PROC_PREFIX, + 1 - proc_width, proc_width - 1, pname); + else + sprintf (buf, "%s%*.*s ", PROC_PREFIX, + -proc_width, proc_width, pname); + strcat_to_buf (string, status_size, buf); + } + + if (line_width > 0) + { + sprintf (buf, "%s%*.*s ", LINE_PREFIX, + -line_width, line_width, line_buf); + strcat_to_buf (string, status_size, buf); + } + if (pc_width > 0) + { + strcat_to_buf (string, status_size, PC_PREFIX); + strcat_to_buf (string, status_size, pc_buf); + } + + + for (i = strlen (string); i < status_size; i++) + string[i] = ' '; + string[status_size] = (char) 0; + + ui_file_delete (pc_out); + return string; +} + +/* Get a printable name for the function at the address. + The symbol name is demangled if demangling is turned on. + Returns a pointer to a static area holding the result. */ +static char* +tui_get_function_from_frame (struct frame_info *fi) +{ + static char name[256]; + struct ui_file *stream = tui_sfileopen (256); + char *p; + + print_address_symbolic (get_frame_pc (fi), stream, demangle, ""); + p = tui_file_get_strbuf (stream); + + /* Use simple heuristics to isolate the function name. The symbol can + be demangled and we can have function parameters. Remove them because + the status line is too short to display them. */ + if (*p == '<') + p++; + strncpy (name, p, sizeof (name)); + p = strchr (name, '('); + if (!p) + p = strchr (name, '>'); + if (p) + *p = 0; + p = strchr (name, '+'); + if (p) + *p = 0; + ui_file_delete (stream); + return name; +} + +/* + ** tuiShowLocatorContent() + */ +void +tuiShowLocatorContent (void) +{ + char *string; + TuiGenWinInfoPtr locator; + + locator = locatorWinInfoPtr (); + + if (m_genWinPtrNotNull (locator) && locator->handle != (WINDOW *) NULL) + { + TuiWinElementPtr element; + + element = (TuiWinElementPtr) locator->content[0]; + + string = tui_make_status_line (&element->whichElement.locator); + wmove (locator->handle, 0, 0); + wstandout (locator->handle); + waddstr (locator->handle, string); + wclrtoeol (locator->handle); + wstandend (locator->handle); + tuiRefreshWin (locator); + wmove (locator->handle, 0, 0); + xfree (string); + locator->contentInUse = TRUE; + } +} + + +/* Set the filename portion of the locator. */ +static void +tui_set_locator_filename (const char *filename) +{ + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + TuiLocatorElementPtr element; + + if (locator->content[0] == (Opaque) NULL) + { + tui_set_locator_info (filename, NULL, 0, 0); + return; + } + + element = &((TuiWinElementPtr) locator->content[0])->whichElement.locator; + element->fileName[0] = 0; + strcat_to_buf (element->fileName, MAX_LOCATOR_ELEMENT_LEN, filename); +} + +/* Update the locator, with the provided arguments. */ +static void +tui_set_locator_info (const char *filename, const char *procname, int lineno, + CORE_ADDR addr) +{ + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + TuiLocatorElementPtr element; + + /* Allocate the locator content if necessary. */ + if (locator->contentSize <= 0) + { + locator->content = (OpaquePtr) allocContent (1, locator->type); + locator->contentSize = 1; + } + + element = &((TuiWinElementPtr) locator->content[0])->whichElement.locator; + element->procName[0] = (char) 0; + strcat_to_buf (element->procName, MAX_LOCATOR_ELEMENT_LEN, procname); + element->lineNo = lineno; + element->addr = addr; + tui_set_locator_filename (filename); +} + +/* Update only the filename portion of the locator. */ +void +tuiUpdateLocatorFilename (const char *filename) +{ + tui_set_locator_filename (filename); + tuiShowLocatorContent (); +} + +/* Function to print the frame information for the TUI. */ +void +tuiShowFrameInfo (struct frame_info *fi) +{ + TuiWinInfoPtr winInfo; + register int i; + + if (fi) + { + register int startLine, i; + CORE_ADDR low; + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + int sourceAlreadyDisplayed; + struct symtab_and_line sal; + + find_frame_sal (fi, &sal); + + sourceAlreadyDisplayed = sal.symtab != 0 + && tuiSourceIsDisplayed (sal.symtab->filename); + tui_set_locator_info (sal.symtab == 0 ? "??" : sal.symtab->filename, + tui_get_function_from_frame (fi), + sal.line, + get_frame_pc (fi)); + tuiShowLocatorContent (); + startLine = 0; + for (i = 0; i < (sourceWindows ())->count; i++) + { + TuiWhichElement *item; + winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i]; + + item = &((TuiWinElementPtr) locator->content[0])->whichElement; + if (winInfo == srcWin) + { + startLine = (item->locator.lineNo - + (winInfo->generic.viewportHeight / 2)) + 1; + if (startLine <= 0) + startLine = 1; + } + else + { + if (find_pc_partial_function (get_frame_pc (fi), (char **) NULL, + &low, (CORE_ADDR) NULL) == 0) + error ("No function contains program counter for selected frame.\n"); + else + low = tuiGetLowDisassemblyAddress (low, get_frame_pc (fi)); + } + + if (winInfo == srcWin) + { + TuiLineOrAddress l; + l.lineNo = startLine; + if (!(sourceAlreadyDisplayed + && tuiLineIsDisplayed (item->locator.lineNo, winInfo, TRUE))) + tuiUpdateSourceWindow (winInfo, sal.symtab, l, TRUE); + else + { + l.lineNo = item->locator.lineNo; + tuiSetIsExecPointAt (l, winInfo); + } + } + else + { + if (winInfo == disassemWin) + { + TuiLineOrAddress a; + a.addr = low; + if (!tuiAddrIsDisplayed (item->locator.addr, winInfo, TRUE)) + tuiUpdateSourceWindow (winInfo, sal.symtab, a, TRUE); + else + { + a.addr = item->locator.addr; + tuiSetIsExecPointAt (a, winInfo); + } + } + } + tuiUpdateExecInfo (winInfo); + } + } + else + { + tui_set_locator_info (NULL, NULL, 0, (CORE_ADDR) 0); + tuiShowLocatorContent (); + for (i = 0; i < (sourceWindows ())->count; i++) + { + winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i]; + tuiClearSourceContent (winInfo, EMPTY_SOURCE_PROMPT); + tuiUpdateExecInfo (winInfo); + } + } +} + +/* Function to initialize gdb commands, for tui window stack manipulation. */ +void +_initialize_tuiStack (void) +{ + add_com ("update", class_tui, tui_update_command, + "Update the source window and locator to display the current " + "execution point.\n"); +} + +/* Command to update the display with the current execution point. */ +static void +tui_update_command (char *arg, int from_tty) +{ + char cmd[sizeof("frame 0")]; + + strcpy (cmd, "frame 0"); + execute_command (cmd, from_tty); +} diff --git a/gdb/tui/tui-stack.h b/gdb/tui/tui-stack.h new file mode 100644 index 00000000000..14be4974bed --- /dev/null +++ b/gdb/tui/tui-stack.h @@ -0,0 +1,33 @@ +/* TUI display locator. + Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _TUI_STACK_H +#define _TUI_STACK_H +/* + ** This header file supports + */ + +extern void tuiUpdateLocatorFilename (const char *); +extern void tuiShowLocatorContent (void); +extern void tuiShowFrameInfo (struct frame_info *); + +#endif +/*_TUI_STACK_H*/ diff --git a/gdb/tui/tui-win.c b/gdb/tui/tui-win.c new file mode 100644 index 00000000000..a7d35ce93f4 --- /dev/null +++ b/gdb/tui/tui-win.c @@ -0,0 +1,1615 @@ +/* TUI window generic functions. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This module contains procedures for handling tui window functions + like resize, scrolling, scrolling, changing focus, etc. + + Author: Susan B. Macchia */ + +#include "defs.h" +#include "command.h" +#include "symtab.h" +#include "breakpoint.h" +#include "frame.h" +#include "cli/cli-cmds.h" +#include "top.h" +#include "source.h" + +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-wingeneral.h" +#include "tui/tui-stack.h" +#include "tui/tui-regs.h" +#include "tui/tui-disasm.h" +#include "tui/tui-source.h" +#include "tui/tui-winsource.h" +#include "tui/tui-windata.h" + +#ifdef HAVE_NCURSES_H +#include <ncurses.h> +#else +#ifdef HAVE_CURSES_H +#include <curses.h> +#endif +#endif + +#include <string.h> +#include <ctype.h> +#include <readline/readline.h> + +/******************************* +** Static Local Decls +********************************/ +static void _makeVisibleWithNewHeight (TuiWinInfoPtr); +static void _makeInvisibleAndSetNewHeight (TuiWinInfoPtr, int); +static TuiStatus _tuiAdjustWinHeights (TuiWinInfoPtr, int); +static int _newHeightOk (TuiWinInfoPtr, int); +static void _tuiSetTabWidth_command (char *, int); +static void _tuiRefreshAll_command (char *, int); +static void _tuiSetWinHeight_command (char *, int); +static void _tuiXDBsetWinHeight_command (char *, int); +static void _tuiAllWindowsInfo (char *, int); +static void _tuiSetFocus_command (char *, int); +static void _tuiScrollForward_command (char *, int); +static void _tuiScrollBackward_command (char *, int); +static void _tuiScrollLeft_command (char *, int); +static void _tuiScrollRight_command (char *, int); +static void _parseScrollingArgs (char *, TuiWinInfoPtr *, int *); + + +/*************************************** +** DEFINITIONS +***************************************/ +#define WIN_HEIGHT_USAGE "Usage: winheight <win_name> [+ | -] <#lines>\n" +#define XDBWIN_HEIGHT_USAGE "Usage: w <#lines>\n" +#define FOCUS_USAGE "Usage: focus {<win> | next | prev}\n" + +/*************************************** +** PUBLIC FUNCTIONS +***************************************/ + +#ifndef ACS_LRCORNER +# define ACS_LRCORNER '+' +#endif +#ifndef ACS_LLCORNER +# define ACS_LLCORNER '+' +#endif +#ifndef ACS_ULCORNER +# define ACS_ULCORNER '+' +#endif +#ifndef ACS_URCORNER +# define ACS_URCORNER '+' +#endif +#ifndef ACS_HLINE +# define ACS_HLINE '-' +#endif +#ifndef ACS_VLINE +# define ACS_VLINE '|' +#endif + +/* Possible values for tui-border-kind variable. */ +static const char *tui_border_kind_enums[] = { + "space", + "ascii", + "acs", + NULL +}; + +/* Possible values for tui-border-mode and tui-active-border-mode. */ +static const char *tui_border_mode_enums[] = { + "normal", + "standout", + "reverse", + "half", + "half-standout", + "bold", + "bold-standout", + NULL +}; + +struct tui_translate +{ + const char *name; + int value; +}; + +/* Translation table for border-mode variables. + The list of values must be terminated by a NULL. + After the NULL value, an entry defines the default. */ +struct tui_translate tui_border_mode_translate[] = { + { "normal", A_NORMAL }, + { "standout", A_STANDOUT }, + { "reverse", A_REVERSE }, + { "half", A_DIM }, + { "half-standout", A_DIM | A_STANDOUT }, + { "bold", A_BOLD }, + { "bold-standout", A_BOLD | A_STANDOUT }, + { 0, 0 }, + { "normal", A_NORMAL } +}; + +/* Translation tables for border-kind, one for each border + character (see wborder, border curses operations). + -1 is used to indicate the ACS because ACS characters + are determined at run time by curses (depends on terminal). */ +struct tui_translate tui_border_kind_translate_vline[] = { + { "space", ' ' }, + { "ascii", '|' }, + { "acs", -1 }, + { 0, 0 }, + { "ascii", '|' } +}; + +struct tui_translate tui_border_kind_translate_hline[] = { + { "space", ' ' }, + { "ascii", '-' }, + { "acs", -1 }, + { 0, 0 }, + { "ascii", '-' } +}; + +struct tui_translate tui_border_kind_translate_ulcorner[] = { + { "space", ' ' }, + { "ascii", '+' }, + { "acs", -1 }, + { 0, 0 }, + { "ascii", '+' } +}; + +struct tui_translate tui_border_kind_translate_urcorner[] = { + { "space", ' ' }, + { "ascii", '+' }, + { "acs", -1 }, + { 0, 0 }, + { "ascii", '+' } +}; + +struct tui_translate tui_border_kind_translate_llcorner[] = { + { "space", ' ' }, + { "ascii", '+' }, + { "acs", -1 }, + { 0, 0 }, + { "ascii", '+' } +}; + +struct tui_translate tui_border_kind_translate_lrcorner[] = { + { "space", ' ' }, + { "ascii", '+' }, + { "acs", -1 }, + { 0, 0 }, + { "ascii", '+' } +}; + + +/* Tui configuration variables controlled with set/show command. */ +const char *tui_active_border_mode = "bold-standout"; +const char *tui_border_mode = "normal"; +const char *tui_border_kind = "acs"; + +/* Tui internal configuration variables. These variables are + updated by tui_update_variables to reflect the tui configuration + variables. */ +chtype tui_border_vline; +chtype tui_border_hline; +chtype tui_border_ulcorner; +chtype tui_border_urcorner; +chtype tui_border_llcorner; +chtype tui_border_lrcorner; + +int tui_border_attrs; +int tui_active_border_attrs; + +/* Identify the item in the translation table. + When the item is not recognized, use the default entry. */ +static struct tui_translate * +translate (const char *name, struct tui_translate *table) +{ + while (table->name) + { + if (name && strcmp (table->name, name) == 0) + return table; + table++; + } + + /* Not found, return default entry. */ + table++; + return table; +} + +/* Update the tui internal configuration according to gdb settings. + Returns 1 if the configuration has changed and the screen should + be redrawn. */ +int +tui_update_variables () +{ + int need_redraw = 0; + struct tui_translate *entry; + + entry = translate (tui_border_mode, tui_border_mode_translate); + if (tui_border_attrs != entry->value) + { + tui_border_attrs = entry->value; + need_redraw = 1; + } + entry = translate (tui_active_border_mode, tui_border_mode_translate); + if (tui_active_border_attrs != entry->value) + { + tui_active_border_attrs = entry->value; + need_redraw = 1; + } + + /* If one corner changes, all characters are changed. + Only check the first one. The ACS characters are determined at + run time by curses terminal management. */ + entry = translate (tui_border_kind, tui_border_kind_translate_lrcorner); + if (tui_border_lrcorner != (chtype) entry->value) + { + tui_border_lrcorner = (entry->value < 0) ? ACS_LRCORNER : entry->value; + need_redraw = 1; + } + entry = translate (tui_border_kind, tui_border_kind_translate_llcorner); + tui_border_llcorner = (entry->value < 0) ? ACS_LLCORNER : entry->value; + + entry = translate (tui_border_kind, tui_border_kind_translate_ulcorner); + tui_border_ulcorner = (entry->value < 0) ? ACS_ULCORNER : entry->value; + + entry = translate (tui_border_kind, tui_border_kind_translate_urcorner); + tui_border_urcorner = (entry->value < 0) ? ACS_URCORNER : entry->value; + + entry = translate (tui_border_kind, tui_border_kind_translate_hline); + tui_border_hline = (entry->value < 0) ? ACS_HLINE : entry->value; + + entry = translate (tui_border_kind, tui_border_kind_translate_vline); + tui_border_vline = (entry->value < 0) ? ACS_VLINE : entry->value; + + return need_redraw; +} + +static void +set_tui_cmd (char *args, int from_tty) +{ +} + +static void +show_tui_cmd (char *args, int from_tty) +{ +} + +/* + ** _initialize_tuiWin(). + ** Function to initialize gdb commands, for tui window manipulation. + */ +void +_initialize_tuiWin (void) +{ + struct cmd_list_element *c; + static struct cmd_list_element *tui_setlist; + static struct cmd_list_element *tui_showlist; + + /* Define the classes of commands. + They will appear in the help list in the reverse of this order. */ + add_cmd ("tui", class_tui, NULL, + "Text User Interface commands.", + &cmdlist); + + add_prefix_cmd ("tui", class_tui, set_tui_cmd, + "TUI configuration variables", + &tui_setlist, "set tui ", + 0/*allow-unknown*/, &setlist); + add_prefix_cmd ("tui", class_tui, show_tui_cmd, + "TUI configuration variables", + &tui_showlist, "show tui ", + 0/*allow-unknown*/, &showlist); + + add_com ("refresh", class_tui, _tuiRefreshAll_command, + "Refresh the terminal display.\n"); + if (xdb_commands) + add_com_alias ("U", "refresh", class_tui, 0); + add_com ("tabset", class_tui, _tuiSetTabWidth_command, + "Set the width (in characters) of tab stops.\n\ +Usage: tabset <n>\n"); + add_com ("winheight", class_tui, _tuiSetWinHeight_command, + "Set the height of a specified window.\n\ +Usage: winheight <win_name> [+ | -] <#lines>\n\ +Window names are:\n\ +src : the source window\n\ +cmd : the command window\n\ +asm : the disassembly window\n\ +regs : the register display\n"); + add_com_alias ("wh", "winheight", class_tui, 0); + add_info ("win", _tuiAllWindowsInfo, + "List of all displayed windows.\n"); + add_com ("focus", class_tui, _tuiSetFocus_command, + "Set focus to named window or next/prev window.\n\ +Usage: focus {<win> | next | prev}\n\ +Valid Window names are:\n\ +src : the source window\n\ +asm : the disassembly window\n\ +regs : the register display\n\ +cmd : the command window\n"); + add_com_alias ("fs", "focus", class_tui, 0); + add_com ("+", class_tui, _tuiScrollForward_command, + "Scroll window forward.\nUsage: + [win] [n]\n"); + add_com ("-", class_tui, _tuiScrollBackward_command, + "Scroll window backward.\nUsage: - [win] [n]\n"); + add_com ("<", class_tui, _tuiScrollLeft_command, + "Scroll window forward.\nUsage: < [win] [n]\n"); + add_com (">", class_tui, _tuiScrollRight_command, + "Scroll window backward.\nUsage: > [win] [n]\n"); + if (xdb_commands) + add_com ("w", class_xdb, _tuiXDBsetWinHeight_command, + "XDB compatibility command for setting the height of a command window.\n\ +Usage: w <#lines>\n"); + + /* Define the tui control variables. */ + c = add_set_enum_cmd + ("border-kind", no_class, + tui_border_kind_enums, &tui_border_kind, + "Set the kind of border for TUI windows.\n" + "This variable controls the border of TUI windows:\n" + "space use a white space\n" + "ascii use ascii characters + - | for the border\n" + "acs use the Alternate Character Set\n", + &tui_setlist); + add_show_from_set (c, &tui_showlist); + + c = add_set_enum_cmd + ("border-mode", no_class, + tui_border_mode_enums, &tui_border_mode, + "Set the attribute mode to use for the TUI window borders.\n" + "This variable controls the attributes to use for the window borders:\n" + "normal normal display\n" + "standout use highlight mode of terminal\n" + "reverse use reverse video mode\n" + "half use half bright\n" + "half-standout use half bright and standout mode\n" + "bold use extra bright or bold\n" + "bold-standout use extra bright or bold with standout mode\n", + &tui_setlist); + add_show_from_set (c, &tui_showlist); + + c = add_set_enum_cmd + ("active-border-mode", no_class, + tui_border_mode_enums, &tui_active_border_mode, + "Set the attribute mode to use for the active TUI window border.\n" + "This variable controls the attributes to use for the active window border:\n" + "normal normal display\n" + "standout use highlight mode of terminal\n" + "reverse use reverse video mode\n" + "half use half bright\n" + "half-standout use half bright and standout mode\n" + "bold use extra bright or bold\n" + "bold-standout use extra bright or bold with standout mode\n", + &tui_setlist); + add_show_from_set (c, &tui_showlist); +} + +/* Update gdb's knowledge of the terminal size. */ +void +tui_update_gdb_sizes () +{ + char cmd[50]; + int screenheight, screenwidth; + + rl_get_screen_size (&screenheight, &screenwidth); + /* Set to TUI command window dimension or use readline values. */ + sprintf (cmd, "set width %d", + tui_active ? cmdWin->generic.width : screenwidth); + execute_command (cmd, 0); + sprintf (cmd, "set height %d", + tui_active ? cmdWin->generic.height : screenheight); + execute_command (cmd, 0); +} + + +/* + ** tuiSetWinFocusTo + ** Set the logical focus to winInfo + */ +void +tuiSetWinFocusTo (TuiWinInfoPtr winInfo) +{ + if (m_winPtrNotNull (winInfo)) + { + TuiWinInfoPtr winWithFocus = tuiWinWithFocus (); + + if (m_winPtrNotNull (winWithFocus) && + winWithFocus->generic.type != CMD_WIN) + unhighlightWin (winWithFocus); + tuiSetWinWithFocus (winInfo); + if (winInfo->generic.type != CMD_WIN) + highlightWin (winInfo); + } + + return; +} /* tuiSetWinFocusTo */ + + +/* + ** tuiScrollForward(). + */ +void +tuiScrollForward (TuiWinInfoPtr winToScroll, int numToScroll) +{ + if (winToScroll != cmdWin) + { + int _numToScroll = numToScroll; + + if (numToScroll == 0) + _numToScroll = winToScroll->generic.height - 3; + /* + ** If we are scrolling the source or disassembly window, do a + ** "psuedo" scroll since not all of the source is in memory, + ** only what is in the viewport. If winToScroll is the + ** command window do nothing since the term should handle it. + */ + if (winToScroll == srcWin) + tuiVerticalSourceScroll (FORWARD_SCROLL, _numToScroll); + else if (winToScroll == disassemWin) + tui_vertical_disassem_scroll (FORWARD_SCROLL, _numToScroll); + else if (winToScroll == dataWin) + tuiVerticalDataScroll (FORWARD_SCROLL, _numToScroll); + } + + return; +} /* tuiScrollForward */ + + +/* + ** tuiScrollBackward(). + */ +void +tuiScrollBackward (TuiWinInfoPtr winToScroll, int numToScroll) +{ + if (winToScroll != cmdWin) + { + int _numToScroll = numToScroll; + + if (numToScroll == 0) + _numToScroll = winToScroll->generic.height - 3; + /* + ** If we are scrolling the source or disassembly window, do a + ** "psuedo" scroll since not all of the source is in memory, + ** only what is in the viewport. If winToScroll is the + ** command window do nothing since the term should handle it. + */ + if (winToScroll == srcWin) + tuiVerticalSourceScroll (BACKWARD_SCROLL, _numToScroll); + else if (winToScroll == disassemWin) + tui_vertical_disassem_scroll (BACKWARD_SCROLL, _numToScroll); + else if (winToScroll == dataWin) + tuiVerticalDataScroll (BACKWARD_SCROLL, _numToScroll); + } + return; +} /* tuiScrollBackward */ + + +/* + ** tuiScrollLeft(). + */ +void +tuiScrollLeft (TuiWinInfoPtr winToScroll, int numToScroll) +{ + if (winToScroll != cmdWin) + { + int _numToScroll = numToScroll; + + if (_numToScroll == 0) + _numToScroll = 1; + /* + ** If we are scrolling the source or disassembly window, do a + ** "psuedo" scroll since not all of the source is in memory, + ** only what is in the viewport. If winToScroll is the + ** command window do nothing since the term should handle it. + */ + if (winToScroll == srcWin || winToScroll == disassemWin) + tuiHorizontalSourceScroll (winToScroll, LEFT_SCROLL, _numToScroll); + } + return; +} /* tuiScrollLeft */ + + +/* + ** tuiScrollRight(). + */ +void +tuiScrollRight (TuiWinInfoPtr winToScroll, int numToScroll) +{ + if (winToScroll != cmdWin) + { + int _numToScroll = numToScroll; + + if (_numToScroll == 0) + _numToScroll = 1; + /* + ** If we are scrolling the source or disassembly window, do a + ** "psuedo" scroll since not all of the source is in memory, + ** only what is in the viewport. If winToScroll is the + ** command window do nothing since the term should handle it. + */ + if (winToScroll == srcWin || winToScroll == disassemWin) + tuiHorizontalSourceScroll (winToScroll, RIGHT_SCROLL, _numToScroll); + } + return; +} /* tuiScrollRight */ + + +/* + ** tui_scroll(). + ** Scroll a window. Arguments are passed through a va_list. + */ +void +tui_scroll (TuiScrollDirection direction, + TuiWinInfoPtr winToScroll, + int numToScroll) +{ + switch (direction) + { + case FORWARD_SCROLL: + tuiScrollForward (winToScroll, numToScroll); + break; + case BACKWARD_SCROLL: + tuiScrollBackward (winToScroll, numToScroll); + break; + case LEFT_SCROLL: + tuiScrollLeft (winToScroll, numToScroll); + break; + case RIGHT_SCROLL: + tuiScrollRight (winToScroll, numToScroll); + break; + default: + break; + } +} + + +/* + ** tuiRefreshAll(). + */ +void +tuiRefreshAll (void) +{ + TuiWinType type; + + clearok (curscr, TRUE); + refreshAll (winList); + for (type = SRC_WIN; type < MAX_MAJOR_WINDOWS; type++) + { + if (winList[type] && winList[type]->generic.isVisible) + { + switch (type) + { + case SRC_WIN: + case DISASSEM_WIN: + tuiShowSourceContent (winList[type]); + checkAndDisplayHighlightIfNeeded (winList[type]); + tuiEraseExecInfoContent (winList[type]); + tuiUpdateExecInfo (winList[type]); + break; + case DATA_WIN: + tuiRefreshDataWin (); + break; + default: + break; + } + } + } + tuiShowLocatorContent (); +} + + +/* + ** tuiResizeAll(). + ** Resize all the windows based on the the terminal size. This + ** function gets called from within the readline sinwinch handler. + */ +void +tuiResizeAll (void) +{ + int heightDiff, widthDiff; + int screenheight, screenwidth; + + rl_get_screen_size (&screenheight, &screenwidth); + widthDiff = screenwidth - termWidth (); + heightDiff = screenheight - termHeight (); + if (heightDiff || widthDiff) + { + TuiLayoutType curLayout = currentLayout (); + TuiWinInfoPtr winWithFocus = tuiWinWithFocus (); + TuiWinInfoPtr firstWin, secondWin; + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + TuiWinType winType; + int newHeight, splitDiff, cmdSplitDiff, numWinsDisplayed = 2; + + /* turn keypad off while we resize */ + if (winWithFocus != cmdWin) + keypad (cmdWin->generic.handle, FALSE); + tui_update_gdb_sizes (); + setTermHeightTo (screenheight); + setTermWidthTo (screenwidth); + if (curLayout == SRC_DISASSEM_COMMAND || + curLayout == SRC_DATA_COMMAND || curLayout == DISASSEM_DATA_COMMAND) + numWinsDisplayed++; + splitDiff = heightDiff / numWinsDisplayed; + cmdSplitDiff = splitDiff; + if (heightDiff % numWinsDisplayed) + { + if (heightDiff < 0) + cmdSplitDiff--; + else + cmdSplitDiff++; + } + /* now adjust each window */ + clear (); + refresh (); + switch (curLayout) + { + case SRC_COMMAND: + case DISASSEM_COMMAND: + firstWin = (TuiWinInfoPtr) (sourceWindows ())->list[0]; + firstWin->generic.width += widthDiff; + locator->width += widthDiff; + /* check for invalid heights */ + if (heightDiff == 0) + newHeight = firstWin->generic.height; + else if ((firstWin->generic.height + splitDiff) >= + (screenheight - MIN_CMD_WIN_HEIGHT - 1)) + newHeight = screenheight - MIN_CMD_WIN_HEIGHT - 1; + else if ((firstWin->generic.height + splitDiff) <= 0) + newHeight = MIN_WIN_HEIGHT; + else + newHeight = firstWin->generic.height + splitDiff; + + _makeInvisibleAndSetNewHeight (firstWin, newHeight); + cmdWin->generic.origin.y = locator->origin.y + 1; + cmdWin->generic.width += widthDiff; + newHeight = screenheight - cmdWin->generic.origin.y; + _makeInvisibleAndSetNewHeight (cmdWin, newHeight); + _makeVisibleWithNewHeight (firstWin); + _makeVisibleWithNewHeight (cmdWin); + if (firstWin->generic.contentSize <= 0) + tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT); + break; + default: + if (curLayout == SRC_DISASSEM_COMMAND) + { + firstWin = srcWin; + firstWin->generic.width += widthDiff; + secondWin = disassemWin; + secondWin->generic.width += widthDiff; + } + else + { + firstWin = dataWin; + firstWin->generic.width += widthDiff; + secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0]; + secondWin->generic.width += widthDiff; + } + /* Change the first window's height/width */ + /* check for invalid heights */ + if (heightDiff == 0) + newHeight = firstWin->generic.height; + else if ((firstWin->generic.height + + secondWin->generic.height + (splitDiff * 2)) >= + (screenheight - MIN_CMD_WIN_HEIGHT - 1)) + newHeight = (screenheight - MIN_CMD_WIN_HEIGHT - 1) / 2; + else if ((firstWin->generic.height + splitDiff) <= 0) + newHeight = MIN_WIN_HEIGHT; + else + newHeight = firstWin->generic.height + splitDiff; + _makeInvisibleAndSetNewHeight (firstWin, newHeight); + + if (firstWin == dataWin && widthDiff != 0) + firstWin->detail.dataDisplayInfo.regsColumnCount = + tui_calculate_regs_column_count ( + firstWin->detail.dataDisplayInfo.regsDisplayType); + locator->width += widthDiff; + + /* Change the second window's height/width */ + /* check for invalid heights */ + if (heightDiff == 0) + newHeight = secondWin->generic.height; + else if ((firstWin->generic.height + + secondWin->generic.height + (splitDiff * 2)) >= + (screenheight - MIN_CMD_WIN_HEIGHT - 1)) + { + newHeight = screenheight - MIN_CMD_WIN_HEIGHT - 1; + if (newHeight % 2) + newHeight = (newHeight / 2) + 1; + else + newHeight /= 2; + } + else if ((secondWin->generic.height + splitDiff) <= 0) + newHeight = MIN_WIN_HEIGHT; + else + newHeight = secondWin->generic.height + splitDiff; + secondWin->generic.origin.y = firstWin->generic.height - 1; + _makeInvisibleAndSetNewHeight (secondWin, newHeight); + + /* Change the command window's height/width */ + cmdWin->generic.origin.y = locator->origin.y + 1; + _makeInvisibleAndSetNewHeight ( + cmdWin, cmdWin->generic.height + cmdSplitDiff); + _makeVisibleWithNewHeight (firstWin); + _makeVisibleWithNewHeight (secondWin); + _makeVisibleWithNewHeight (cmdWin); + if (firstWin->generic.contentSize <= 0) + tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT); + if (secondWin->generic.contentSize <= 0) + tuiEraseSourceContent (secondWin, EMPTY_SOURCE_PROMPT); + break; + } + /* + ** Now remove all invisible windows, and their content so that they get + ** created again when called for with the new size + */ + for (winType = SRC_WIN; (winType < MAX_MAJOR_WINDOWS); winType++) + { + if (winType != CMD_WIN && m_winPtrNotNull (winList[winType]) && + !winList[winType]->generic.isVisible) + { + freeWindow (winList[winType]); + winList[winType] = (TuiWinInfoPtr) NULL; + } + } + tuiSetWinResizedTo (TRUE); + /* turn keypad back on, unless focus is in the command window */ + if (winWithFocus != cmdWin) + keypad (cmdWin->generic.handle, TRUE); + } + return; +} /* tuiResizeAll */ + + +/* + ** tuiSigwinchHandler() + ** SIGWINCH signal handler for the tui. This signal handler is + ** always called, even when the readline package clears signals + ** because it is set as the old_sigwinch() (TUI only) + */ +void +tuiSigwinchHandler (int signal) +{ + /* + ** Say that a resize was done so that the readline can do it + ** later when appropriate. + */ + tuiSetWinResizedTo (TRUE); + + return; +} /* tuiSigwinchHandler */ + + + +/************************* +** STATIC LOCAL FUNCTIONS +**************************/ + + +/* + ** _tuiScrollForward_command(). + */ +static void +_tuiScrollForward_command (char *arg, int fromTTY) +{ + int numToScroll = 1; + TuiWinInfoPtr winToScroll; + + /* Make sure the curses mode is enabled. */ + tui_enable (); + if (arg == (char *) NULL) + _parseScrollingArgs (arg, &winToScroll, (int *) NULL); + else + _parseScrollingArgs (arg, &winToScroll, &numToScroll); + tui_scroll (FORWARD_SCROLL, winToScroll, numToScroll); +} + + +/* + ** _tuiScrollBackward_command(). + */ +static void +_tuiScrollBackward_command (char *arg, int fromTTY) +{ + int numToScroll = 1; + TuiWinInfoPtr winToScroll; + + /* Make sure the curses mode is enabled. */ + tui_enable (); + if (arg == (char *) NULL) + _parseScrollingArgs (arg, &winToScroll, (int *) NULL); + else + _parseScrollingArgs (arg, &winToScroll, &numToScroll); + tui_scroll (BACKWARD_SCROLL, winToScroll, numToScroll); +} + + +/* + ** _tuiScrollLeft_command(). + */ +static void +_tuiScrollLeft_command (char *arg, int fromTTY) +{ + int numToScroll; + TuiWinInfoPtr winToScroll; + + /* Make sure the curses mode is enabled. */ + tui_enable (); + _parseScrollingArgs (arg, &winToScroll, &numToScroll); + tui_scroll (LEFT_SCROLL, winToScroll, numToScroll); +} + + +/* + ** _tuiScrollRight_command(). + */ +static void +_tuiScrollRight_command (char *arg, int fromTTY) +{ + int numToScroll; + TuiWinInfoPtr winToScroll; + + /* Make sure the curses mode is enabled. */ + tui_enable (); + _parseScrollingArgs (arg, &winToScroll, &numToScroll); + tui_scroll (RIGHT_SCROLL, winToScroll, numToScroll); +} + + +/* + ** _tuiSetFocus(). + ** Set focus to the window named by 'arg' + */ +static void +_tuiSetFocus (char *arg, int fromTTY) +{ + if (arg != (char *) NULL) + { + char *bufPtr = (char *) xstrdup (arg); + int i; + TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL; + + for (i = 0; (i < strlen (bufPtr)); i++) + bufPtr[i] = toupper (arg[i]); + + if (subset_compare (bufPtr, "NEXT")) + winInfo = tuiNextWin (tuiWinWithFocus ()); + else if (subset_compare (bufPtr, "PREV")) + winInfo = tuiPrevWin (tuiWinWithFocus ()); + else + winInfo = partialWinByName (bufPtr); + + if (winInfo == (TuiWinInfoPtr) NULL || !winInfo->generic.isVisible) + warning ("Invalid window specified. \n\ +The window name specified must be valid and visible.\n"); + else + { + tuiSetWinFocusTo (winInfo); + keypad (cmdWin->generic.handle, (winInfo != cmdWin)); + } + + if (dataWin && dataWin->generic.isVisible) + tuiRefreshDataWin (); + tuiFree (bufPtr); + printf_filtered ("Focus set to %s window.\n", + winName ((TuiGenWinInfoPtr) tuiWinWithFocus ())); + } + else + warning ("Incorrect Number of Arguments.\n%s", FOCUS_USAGE); + + return; +} /* _tuiSetFocus */ + +/* + ** _tuiSetFocus_command() + */ +static void +_tuiSetFocus_command (char *arg, int fromTTY) +{ + /* Make sure the curses mode is enabled. */ + tui_enable (); + _tuiSetFocus (arg, fromTTY); +} + + +/* + ** _tuiAllWindowsInfo(). + */ +static void +_tuiAllWindowsInfo (char *arg, int fromTTY) +{ + TuiWinType type; + TuiWinInfoPtr winWithFocus = tuiWinWithFocus (); + + for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++) + if (winList[type] && winList[type]->generic.isVisible) + { + if (winWithFocus == winList[type]) + printf_filtered (" %s\t(%d lines) <has focus>\n", + winName (&winList[type]->generic), + winList[type]->generic.height); + else + printf_filtered (" %s\t(%d lines)\n", + winName (&winList[type]->generic), + winList[type]->generic.height); + } + + return; +} /* _tuiAllWindowsInfo */ + + +/* + ** _tuiRefreshAll_command(). + */ +static void +_tuiRefreshAll_command (char *arg, int fromTTY) +{ + /* Make sure the curses mode is enabled. */ + tui_enable (); + + tuiRefreshAll (); +} + + +/* + ** _tuiSetWinTabWidth_command(). + ** Set the height of the specified window. + */ +static void +_tuiSetTabWidth_command (char *arg, int fromTTY) +{ + /* Make sure the curses mode is enabled. */ + tui_enable (); + if (arg != (char *) NULL) + { + int ts; + + ts = atoi (arg); + if (ts > 0) + tuiSetDefaultTabLen (ts); + else + warning ("Tab widths greater than 0 must be specified.\n"); + } + + return; +} /* _tuiSetTabWidth_command */ + + +/* + ** _tuiSetWinHeight(). + ** Set the height of the specified window. + */ +static void +_tuiSetWinHeight (char *arg, int fromTTY) +{ + /* Make sure the curses mode is enabled. */ + tui_enable (); + if (arg != (char *) NULL) + { + char *buf = xstrdup (arg); + char *bufPtr = buf; + char *wname = (char *) NULL; + int newHeight, i; + TuiWinInfoPtr winInfo; + + wname = bufPtr; + bufPtr = strchr (bufPtr, ' '); + if (bufPtr != (char *) NULL) + { + *bufPtr = (char) 0; + + /* + ** Validate the window name + */ + for (i = 0; i < strlen (wname); i++) + wname[i] = toupper (wname[i]); + winInfo = partialWinByName (wname); + + if (winInfo == (TuiWinInfoPtr) NULL || !winInfo->generic.isVisible) + warning ("Invalid window specified. \n\ +The window name specified must be valid and visible.\n"); + else + { + /* Process the size */ + while (*(++bufPtr) == ' ') + ; + + if (*bufPtr != (char) 0) + { + int negate = FALSE; + int fixedSize = TRUE; + int inputNo;; + + if (*bufPtr == '+' || *bufPtr == '-') + { + if (*bufPtr == '-') + negate = TRUE; + fixedSize = FALSE; + bufPtr++; + } + inputNo = atoi (bufPtr); + if (inputNo > 0) + { + if (negate) + inputNo *= (-1); + if (fixedSize) + newHeight = inputNo; + else + newHeight = winInfo->generic.height + inputNo; + /* + ** Now change the window's height, and adjust all + ** other windows around it + */ + if (_tuiAdjustWinHeights (winInfo, + newHeight) == TUI_FAILURE) + warning ("Invalid window height specified.\n%s", + WIN_HEIGHT_USAGE); + else + tui_update_gdb_sizes (); + } + else + warning ("Invalid window height specified.\n%s", + WIN_HEIGHT_USAGE); + } + } + } + else + printf_filtered (WIN_HEIGHT_USAGE); + + if (buf != (char *) NULL) + tuiFree (buf); + } + else + printf_filtered (WIN_HEIGHT_USAGE); + + return; +} /* _tuiSetWinHeight */ + +/* + ** _tuiSetWinHeight_command(). + ** Set the height of the specified window, with va_list. + */ +static void +_tuiSetWinHeight_command (char *arg, int fromTTY) +{ + /* Make sure the curses mode is enabled. */ + tui_enable (); + _tuiSetWinHeight (arg, fromTTY); +} + + +/* + ** _tuiXDBsetWinHeight(). + ** XDB Compatibility command for setting the window height. This will + ** increase or decrease the command window by the specified amount. + */ +static void +_tuiXDBsetWinHeight (char *arg, int fromTTY) +{ + /* Make sure the curses mode is enabled. */ + tui_enable (); + if (arg != (char *) NULL) + { + int inputNo = atoi (arg); + + if (inputNo > 0) + { /* Add 1 for the locator */ + int newHeight = termHeight () - (inputNo + 1); + + if (!_newHeightOk (winList[CMD_WIN], newHeight) || + _tuiAdjustWinHeights (winList[CMD_WIN], + newHeight) == TUI_FAILURE) + warning ("Invalid window height specified.\n%s", + XDBWIN_HEIGHT_USAGE); + } + else + warning ("Invalid window height specified.\n%s", + XDBWIN_HEIGHT_USAGE); + } + else + warning ("Invalid window height specified.\n%s", XDBWIN_HEIGHT_USAGE); + + return; +} /* _tuiXDBsetWinHeight */ + +/* + ** _tuiSetWinHeight_command(). + ** Set the height of the specified window, with va_list. + */ +static void +_tuiXDBsetWinHeight_command (char *arg, int fromTTY) +{ + _tuiXDBsetWinHeight (arg, fromTTY); +} + + +/* + ** _tuiAdjustWinHeights(). + ** Function to adjust all window heights around the primary + */ +static TuiStatus +_tuiAdjustWinHeights (TuiWinInfoPtr primaryWinInfo, int newHeight) +{ + TuiStatus status = TUI_FAILURE; + + if (_newHeightOk (primaryWinInfo, newHeight)) + { + status = TUI_SUCCESS; + if (newHeight != primaryWinInfo->generic.height) + { + int diff; + TuiWinInfoPtr winInfo; + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + TuiLayoutType curLayout = currentLayout (); + + diff = (newHeight - primaryWinInfo->generic.height) * (-1); + if (curLayout == SRC_COMMAND || curLayout == DISASSEM_COMMAND) + { + TuiWinInfoPtr srcWinInfo; + + _makeInvisibleAndSetNewHeight (primaryWinInfo, newHeight); + if (primaryWinInfo->generic.type == CMD_WIN) + { + winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[0]; + srcWinInfo = winInfo; + } + else + { + winInfo = winList[CMD_WIN]; + srcWinInfo = primaryWinInfo; + } + _makeInvisibleAndSetNewHeight (winInfo, + winInfo->generic.height + diff); + cmdWin->generic.origin.y = locator->origin.y + 1; + _makeVisibleWithNewHeight (winInfo); + _makeVisibleWithNewHeight (primaryWinInfo); + if (srcWinInfo->generic.contentSize <= 0) + tuiEraseSourceContent (srcWinInfo, EMPTY_SOURCE_PROMPT); + } + else + { + TuiWinInfoPtr firstWin, secondWin; + + if (curLayout == SRC_DISASSEM_COMMAND) + { + firstWin = srcWin; + secondWin = disassemWin; + } + else + { + firstWin = dataWin; + secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0]; + } + if (primaryWinInfo == cmdWin) + { /* + ** Split the change in height accross the 1st & 2nd windows + ** adjusting them as well. + */ + int firstSplitDiff = diff / 2; /* subtract the locator */ + int secondSplitDiff = firstSplitDiff; + + if (diff % 2) + { + if (firstWin->generic.height > + secondWin->generic.height) + if (diff < 0) + firstSplitDiff--; + else + firstSplitDiff++; + else + { + if (diff < 0) + secondSplitDiff--; + else + secondSplitDiff++; + } + } + /* make sure that the minimum hieghts are honored */ + while ((firstWin->generic.height + firstSplitDiff) < 3) + { + firstSplitDiff++; + secondSplitDiff--; + } + while ((secondWin->generic.height + secondSplitDiff) < 3) + { + secondSplitDiff++; + firstSplitDiff--; + } + _makeInvisibleAndSetNewHeight ( + firstWin, + firstWin->generic.height + firstSplitDiff); + secondWin->generic.origin.y = firstWin->generic.height - 1; + _makeInvisibleAndSetNewHeight ( + secondWin, secondWin->generic.height + secondSplitDiff); + cmdWin->generic.origin.y = locator->origin.y + 1; + _makeInvisibleAndSetNewHeight (cmdWin, newHeight); + } + else + { + if ((cmdWin->generic.height + diff) < 1) + { /* + ** If there is no way to increase the command window + ** take real estate from the 1st or 2nd window. + */ + if ((cmdWin->generic.height + diff) < 1) + { + int i; + for (i = cmdWin->generic.height + diff; + (i < 1); i++) + if (primaryWinInfo == firstWin) + secondWin->generic.height--; + else + firstWin->generic.height--; + } + } + if (primaryWinInfo == firstWin) + _makeInvisibleAndSetNewHeight (firstWin, newHeight); + else + _makeInvisibleAndSetNewHeight ( + firstWin, + firstWin->generic.height); + secondWin->generic.origin.y = firstWin->generic.height - 1; + if (primaryWinInfo == secondWin) + _makeInvisibleAndSetNewHeight (secondWin, newHeight); + else + _makeInvisibleAndSetNewHeight ( + secondWin, secondWin->generic.height); + cmdWin->generic.origin.y = locator->origin.y + 1; + if ((cmdWin->generic.height + diff) < 1) + _makeInvisibleAndSetNewHeight (cmdWin, 1); + else + _makeInvisibleAndSetNewHeight ( + cmdWin, cmdWin->generic.height + diff); + } + _makeVisibleWithNewHeight (cmdWin); + _makeVisibleWithNewHeight (secondWin); + _makeVisibleWithNewHeight (firstWin); + if (firstWin->generic.contentSize <= 0) + tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT); + if (secondWin->generic.contentSize <= 0) + tuiEraseSourceContent (secondWin, EMPTY_SOURCE_PROMPT); + } + } + } + + return status; +} /* _tuiAdjustWinHeights */ + + +/* + ** _makeInvisibleAndSetNewHeight(). + ** Function make the target window (and auxillary windows associated + ** with the targer) invisible, and set the new height and location. + */ +static void +_makeInvisibleAndSetNewHeight (TuiWinInfoPtr winInfo, int height) +{ + int i; + TuiGenWinInfoPtr genWinInfo; + + + m_beInvisible (&winInfo->generic); + winInfo->generic.height = height; + if (height > 1) + winInfo->generic.viewportHeight = height - 1; + else + winInfo->generic.viewportHeight = height; + if (winInfo != cmdWin) + winInfo->generic.viewportHeight--; + + /* Now deal with the auxillary windows associated with winInfo */ + switch (winInfo->generic.type) + { + case SRC_WIN: + case DISASSEM_WIN: + genWinInfo = winInfo->detail.sourceInfo.executionInfo; + m_beInvisible (genWinInfo); + genWinInfo->height = height; + genWinInfo->origin.y = winInfo->generic.origin.y; + if (height > 1) + genWinInfo->viewportHeight = height - 1; + else + genWinInfo->viewportHeight = height; + if (winInfo != cmdWin) + genWinInfo->viewportHeight--; + + if (m_hasLocator (winInfo)) + { + genWinInfo = locatorWinInfoPtr (); + m_beInvisible (genWinInfo); + genWinInfo->origin.y = winInfo->generic.origin.y + height; + } + break; + case DATA_WIN: + /* delete all data item windows */ + for (i = 0; i < winInfo->generic.contentSize; i++) + { + genWinInfo = (TuiGenWinInfoPtr) & ((TuiWinElementPtr) + winInfo->generic.content[i])->whichElement.dataWindow; + tuiDelwin (genWinInfo->handle); + genWinInfo->handle = (WINDOW *) NULL; + } + break; + default: + break; + } +} + + +/* + ** _makeVisibleWithNewHeight(). + ** Function to make the windows with new heights visible. + ** This means re-creating the windows' content since the window + ** had to be destroyed to be made invisible. + */ +static void +_makeVisibleWithNewHeight (TuiWinInfoPtr winInfo) +{ + struct symtab *s; + + m_beVisible (&winInfo->generic); + checkAndDisplayHighlightIfNeeded (winInfo); + switch (winInfo->generic.type) + { + case SRC_WIN: + case DISASSEM_WIN: + freeWinContent (winInfo->detail.sourceInfo.executionInfo); + m_beVisible (winInfo->detail.sourceInfo.executionInfo); + if (winInfo->generic.content != (OpaquePtr) NULL) + { + TuiLineOrAddress lineOrAddr; + struct symtab_and_line cursal + = get_current_source_symtab_and_line (); + + if (winInfo->generic.type == SRC_WIN) + lineOrAddr.lineNo = + winInfo->detail.sourceInfo.startLineOrAddr.lineNo; + else + lineOrAddr.addr = + winInfo->detail.sourceInfo.startLineOrAddr.addr; + freeWinContent (&winInfo->generic); + tuiUpdateSourceWindow (winInfo, + cursal.symtab, lineOrAddr, TRUE); + } + else if (deprecated_selected_frame != (struct frame_info *) NULL) + { + TuiLineOrAddress line; + struct symtab_and_line cursal = get_current_source_symtab_and_line (); + + + s = find_pc_symtab (get_frame_pc (deprecated_selected_frame)); + if (winInfo->generic.type == SRC_WIN) + line.lineNo = cursal.line; + else + { + find_line_pc (s, cursal.line, &line.addr); + } + tuiUpdateSourceWindow (winInfo, s, line, TRUE); + } + if (m_hasLocator (winInfo)) + { + m_beVisible (locatorWinInfoPtr ()); + tuiShowLocatorContent (); + } + break; + case DATA_WIN: + tuiDisplayAllData (); + break; + case CMD_WIN: + winInfo->detail.commandInfo.curLine = 0; + winInfo->detail.commandInfo.curch = 0; + wmove (winInfo->generic.handle, + winInfo->detail.commandInfo.curLine, + winInfo->detail.commandInfo.curch); + break; + default: + break; + } + + return; +} /* _makeVisibleWithNewHeight */ + + +static int +_newHeightOk (TuiWinInfoPtr primaryWinInfo, int newHeight) +{ + int ok = (newHeight < termHeight ()); + + if (ok) + { + int diff; + TuiLayoutType curLayout = currentLayout (); + + diff = (newHeight - primaryWinInfo->generic.height) * (-1); + if (curLayout == SRC_COMMAND || curLayout == DISASSEM_COMMAND) + { + ok = ((primaryWinInfo->generic.type == CMD_WIN && + newHeight <= (termHeight () - 4) && + newHeight >= MIN_CMD_WIN_HEIGHT) || + (primaryWinInfo->generic.type != CMD_WIN && + newHeight <= (termHeight () - 2) && + newHeight >= MIN_WIN_HEIGHT)); + if (ok) + { /* check the total height */ + TuiWinInfoPtr winInfo; + + if (primaryWinInfo == cmdWin) + winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[0]; + else + winInfo = cmdWin; + ok = ((newHeight + + (winInfo->generic.height + diff)) <= termHeight ()); + } + } + else + { + int curTotalHeight, totalHeight, minHeight = 0; + TuiWinInfoPtr firstWin, secondWin; + + if (curLayout == SRC_DISASSEM_COMMAND) + { + firstWin = srcWin; + secondWin = disassemWin; + } + else + { + firstWin = dataWin; + secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0]; + } + /* + ** We could simply add all the heights to obtain the same result + ** but below is more explicit since we subtract 1 for the + ** line that the first and second windows share, and add one + ** for the locator. + */ + totalHeight = curTotalHeight = + (firstWin->generic.height + secondWin->generic.height - 1) + + cmdWin->generic.height + 1 /*locator */ ; + if (primaryWinInfo == cmdWin) + { + /* locator included since first & second win share a line */ + ok = ((firstWin->generic.height + + secondWin->generic.height + diff) >= + (MIN_WIN_HEIGHT * 2) && + newHeight >= MIN_CMD_WIN_HEIGHT); + if (ok) + { + totalHeight = newHeight + (firstWin->generic.height + + secondWin->generic.height + diff); + minHeight = MIN_CMD_WIN_HEIGHT; + } + } + else + { + minHeight = MIN_WIN_HEIGHT; + /* + ** First see if we can increase/decrease the command + ** window. And make sure that the command window is + ** at least 1 line + */ + ok = ((cmdWin->generic.height + diff) > 0); + if (!ok) + { /* + ** Looks like we have to increase/decrease one of + ** the other windows + */ + if (primaryWinInfo == firstWin) + ok = (secondWin->generic.height + diff) >= minHeight; + else + ok = (firstWin->generic.height + diff) >= minHeight; + } + if (ok) + { + if (primaryWinInfo == firstWin) + totalHeight = newHeight + + secondWin->generic.height + + cmdWin->generic.height + diff; + else + totalHeight = newHeight + + firstWin->generic.height + + cmdWin->generic.height + diff; + } + } + /* + ** Now make sure that the proposed total height doesn't exceed + ** the old total height. + */ + if (ok) + ok = (newHeight >= minHeight && totalHeight <= curTotalHeight); + } + } + + return ok; +} /* _newHeightOk */ + + +/* + ** _parseScrollingArgs(). + */ +static void +_parseScrollingArgs (char *arg, TuiWinInfoPtr * winToScroll, int *numToScroll) +{ + if (numToScroll) + *numToScroll = 0; + *winToScroll = tuiWinWithFocus (); + + /* + ** First set up the default window to scroll, in case there is no + ** window name arg + */ + if (arg != (char *) NULL) + { + char *buf, *bufPtr; + + /* process the number of lines to scroll */ + buf = bufPtr = xstrdup (arg); + if (isdigit (*bufPtr)) + { + char *numStr; + + numStr = bufPtr; + bufPtr = strchr (bufPtr, ' '); + if (bufPtr != (char *) NULL) + { + *bufPtr = (char) 0; + if (numToScroll) + *numToScroll = atoi (numStr); + bufPtr++; + } + else if (numToScroll) + *numToScroll = atoi (numStr); + } + + /* process the window name if one is specified */ + if (bufPtr != (char *) NULL) + { + char *wname; + int i; + + if (*bufPtr == ' ') + while (*(++bufPtr) == ' ') + ; + + if (*bufPtr != (char) 0) + wname = bufPtr; + else + wname = "?"; + + /* Validate the window name */ + for (i = 0; i < strlen (wname); i++) + wname[i] = toupper (wname[i]); + *winToScroll = partialWinByName (wname); + + if (*winToScroll == (TuiWinInfoPtr) NULL || + !(*winToScroll)->generic.isVisible) + warning ("Invalid window specified. \n\ +The window name specified must be valid and visible.\n"); + else if (*winToScroll == cmdWin) + *winToScroll = (TuiWinInfoPtr) (sourceWindows ())->list[0]; + } + tuiFree (buf); + } + + return; +} /* _parseScrollingArgs */ diff --git a/gdb/tui/tui-win.h b/gdb/tui/tui-win.h new file mode 100644 index 00000000000..bc260804888 --- /dev/null +++ b/gdb/tui/tui-win.h @@ -0,0 +1,59 @@ +/* TUI window generic functions. + Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _TUI_WIN_H +#define _TUI_WIN_H + +/***************************************** +** TYPE DEFINITIONS ** +******************************************/ + + + +/***************************************** +** PUBLIC FUNCTION EXTERNAL DECLS ** +******************************************/ +extern void tuiScrollForward (TuiWinInfoPtr, int); +extern void tuiScrollBackward (TuiWinInfoPtr, int); +extern void tuiScrollLeft (TuiWinInfoPtr, int); +extern void tuiScrollRight (TuiWinInfoPtr, int); +extern void tui_scroll (TuiScrollDirection, TuiWinInfoPtr, int); +extern void tuiSetWinFocusTo (TuiWinInfoPtr); +extern void tuiResizeAll (void); +extern void tuiRefreshAll (void); +extern void tuiSigwinchHandler (int); + +extern chtype tui_border_ulcorner; +extern chtype tui_border_urcorner; +extern chtype tui_border_lrcorner; +extern chtype tui_border_llcorner; +extern chtype tui_border_vline; +extern chtype tui_border_hline; +extern int tui_border_attrs; +extern int tui_active_border_attrs; + +extern int tui_update_variables (); + +/* Update gdb's knowledge of the terminal size. */ +extern void tui_update_gdb_sizes (void); + +#endif +/*_TUI_WIN_H*/ diff --git a/gdb/tui/tui-windata.c b/gdb/tui/tui-windata.c new file mode 100644 index 00000000000..f504f7fc6c7 --- /dev/null +++ b/gdb/tui/tui-windata.c @@ -0,0 +1,349 @@ +/* Data/register window display. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-wingeneral.h" +#include "tui/tui-regs.h" + +#ifdef HAVE_NCURSES_H +#include <ncurses.h> +#else +#ifdef HAVE_CURSES_H +#include <curses.h> +#endif +#endif + + +/***************************************** +** STATIC LOCAL FUNCTIONS FORWARD DECLS ** +******************************************/ + + + +/***************************************** +** PUBLIC FUNCTIONS ** +******************************************/ + + +/* + ** tuiFirstDataItemDisplayed() + ** Answer the index first element displayed. + ** If none are displayed, then return (-1). + */ +int +tuiFirstDataItemDisplayed (void) +{ + int elementNo = (-1); + int i; + + for (i = 0; (i < dataWin->generic.contentSize && elementNo < 0); i++) + { + TuiGenWinInfoPtr dataItemWin; + + dataItemWin = &((TuiWinContent) + dataWin->generic.content)[i]->whichElement.dataWindow; + if (dataItemWin->handle != (WINDOW *) NULL && dataItemWin->isVisible) + elementNo = i; + } + + return elementNo; +} /* tuiFirstDataItemDisplayed */ + + +/* + ** tuiFirstDataElementNoInLine() + ** Answer the index of the first element in lineNo. If lineNo is + ** past the data area (-1) is returned. + */ +int +tuiFirstDataElementNoInLine (int lineNo) +{ + int firstElementNo = (-1); + + /* + ** First see if there is a register on lineNo, and if so, set the + ** first element number + */ + if ((firstElementNo = tui_first_reg_element_no_inline (lineNo)) == -1) + { /* + ** Looking at the general data, the 1st element on lineNo + */ + } + + return firstElementNo; +} /* tuiFirstDataElementNoInLine */ + + +/* + ** tuiDeleteDataContentWindows() + ** Function to delete all the item windows in the data window. + ** This is usually done when the data window is scrolled. + */ +void +tuiDeleteDataContentWindows (void) +{ + int i; + TuiGenWinInfoPtr dataItemWinPtr; + + for (i = 0; (i < dataWin->generic.contentSize); i++) + { + dataItemWinPtr = &((TuiWinContent) + dataWin->generic.content)[i]->whichElement.dataWindow; + tuiDelwin (dataItemWinPtr->handle); + dataItemWinPtr->handle = (WINDOW *) NULL; + dataItemWinPtr->isVisible = FALSE; + } + + return; +} /* tuiDeleteDataContentWindows */ + + +void +tuiEraseDataContent (char *prompt) +{ + werase (dataWin->generic.handle); + checkAndDisplayHighlightIfNeeded (dataWin); + if (prompt != (char *) NULL) + { + int halfWidth = (dataWin->generic.width - 2) / 2; + int xPos; + + if (strlen (prompt) >= halfWidth) + xPos = 1; + else + xPos = halfWidth - strlen (prompt); + mvwaddstr (dataWin->generic.handle, + (dataWin->generic.height / 2), + xPos, + prompt); + } + wrefresh (dataWin->generic.handle); + + return; +} /* tuiEraseDataContent */ + + +/* + ** tuiDisplayAllData(). + ** This function displays the data that is in the data window's + ** content. It does not set the content. + */ +void +tuiDisplayAllData (void) +{ + if (dataWin->generic.contentSize <= 0) + tuiEraseDataContent (NO_DATA_STRING); + else + { + tuiEraseDataContent ((char *) NULL); + tuiDeleteDataContentWindows (); + checkAndDisplayHighlightIfNeeded (dataWin); + tui_display_registers_from (0); + /* + ** Then display the other data + */ + if (dataWin->detail.dataDisplayInfo.dataContent != + (TuiWinContent) NULL && + dataWin->detail.dataDisplayInfo.dataContentCount > 0) + { + } + } + return; +} /* tuiDisplayAllData */ + + +/* + ** tuiDisplayDataFromLine() + ** Function to display the data starting at line, lineNo, in the + ** data window. + */ +void +tuiDisplayDataFromLine (int lineNo) +{ + int _lineNo = lineNo; + + if (lineNo < 0) + _lineNo = 0; + + checkAndDisplayHighlightIfNeeded (dataWin); + + /* there is no general data, force regs to display (if there are any) */ + if (dataWin->detail.dataDisplayInfo.dataContentCount <= 0) + tui_display_registers_from_line (_lineNo, TRUE); + else + { + int elementNo, startLineNo; + int regsLastLine = tui_last_regs_line_no (); + + + /* display regs if we can */ + if (tui_display_registers_from_line (_lineNo, FALSE) < 0) + { /* + ** _lineNo is past the regs display, so calc where the + ** start data element is + */ + if (regsLastLine < _lineNo) + { /* figure out how many lines each element is to obtain + the start elementNo */ + } + } + else + { /* + ** calculate the starting element of the data display, given + ** regsLastLine and how many lines each element is, up to + ** _lineNo + */ + } + /* Now display the data , starting at elementNo */ + } + + return; +} /* tuiDisplayDataFromLine */ + + +/* + ** tuiDisplayDataFrom() + ** Display data starting at element elementNo + */ +void +tuiDisplayDataFrom (int elementNo, int reuseWindows) +{ + int firstLine = (-1); + + if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount) + firstLine = tui_line_from_reg_element_no (elementNo); + else + { /* calculate the firstLine from the element number */ + } + + if (firstLine >= 0) + { + tuiEraseDataContent ((char *) NULL); + if (!reuseWindows) + tuiDeleteDataContentWindows (); + tuiDisplayDataFromLine (firstLine); + } + + return; +} /* tuiDisplayDataFrom */ + + +/* + ** tuiRefreshDataWin() + ** Function to redisplay the contents of the data window. + */ +void +tuiRefreshDataWin (void) +{ + tuiEraseDataContent ((char *) NULL); + if (dataWin->generic.contentSize > 0) + { + int firstElement = tuiFirstDataItemDisplayed (); + + if (firstElement >= 0) /* re-use existing windows */ + tuiDisplayDataFrom (firstElement, TRUE); + } + + return; +} /* tuiRefreshDataWin */ + + +/* + ** tuiCheckDataValues(). + ** Function to check the data values and hilite any that have changed + */ +void +tuiCheckDataValues (struct frame_info *frame) +{ + tui_check_register_values (frame); + + /* Now check any other data values that there are */ + if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible) + { + int i; + + for (i = 0; dataWin->detail.dataDisplayInfo.dataContentCount; i++) + { +#ifdef LATER + TuiDataElementPtr dataElementPtr; + TuiGenWinInfoPtr dataItemWinPtr; + Opaque newValue; + + dataItemPtr = &dataWin->detail.dataDisplayInfo. + dataContent[i]->whichElement.dataWindow; + dataElementPtr = &((TuiWinContent) + dataItemWinPtr->content)[0]->whichElement.data; + if value + has changed (dataElementPtr, frame, &newValue) + { + dataElementPtr->value = newValue; + update the display with the new value, hiliting it. + } +#endif + } + } +} /* tuiCheckDataValues */ + + +/* + ** tuiVerticalDataScroll() + ** Scroll the data window vertically forward or backward. + */ +void +tuiVerticalDataScroll (TuiScrollDirection scrollDirection, int numToScroll) +{ + int firstElementNo; + int firstLine = (-1); + + firstElementNo = tuiFirstDataItemDisplayed (); + if (firstElementNo < dataWin->detail.dataDisplayInfo.regsContentCount) + firstLine = tui_line_from_reg_element_no (firstElementNo); + else + { /* calculate the first line from the element number which is in + ** the general data content + */ + } + + if (firstLine >= 0) + { + int lastElementNo, lastLine; + + if (scrollDirection == FORWARD_SCROLL) + firstLine += numToScroll; + else + firstLine -= numToScroll; + tuiEraseDataContent ((char *) NULL); + tuiDeleteDataContentWindows (); + tuiDisplayDataFromLine (firstLine); + } + + return; +} /* tuiVerticalDataScroll */ + + +/***************************************** +** STATIC LOCAL FUNCTIONS ** +******************************************/ diff --git a/gdb/tui/tui-windata.h b/gdb/tui/tui-windata.h new file mode 100644 index 00000000000..0b1e700f1bb --- /dev/null +++ b/gdb/tui/tui-windata.h @@ -0,0 +1,47 @@ +/* Data/register window display. + Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _TUI_DATAWIN_H +#define _TUI_DATAWIN_H + + +/***************************************** +** TYPE DEFINITIONS ** +******************************************/ + + + +/***************************************** +** PUBLIC FUNCTION EXTERNAL DECLS ** +******************************************/ +extern void tuiEraseDataContent (char *); +extern void tuiDisplayAllData (void); +extern void tuiCheckDataValues (struct frame_info *); +extern void tuiDisplayDataFromLine (int); +extern int tuiFirstDataItemDisplayed (void); +extern int tuiFirstDataElementNoInLine (int); +extern void tuiDeleteDataContentWindows (void); +extern void tuiRefreshDataWin (void); +extern void tuiDisplayDataFrom (int, int); +extern void tuiVerticalDataScroll (TuiScrollDirection, int); + +#endif +/*_TUI_DATAWIN_H*/ diff --git a/gdb/tui/tui-wingeneral.c b/gdb/tui/tui-wingeneral.c new file mode 100644 index 00000000000..2f32f646c74 --- /dev/null +++ b/gdb/tui/tui-wingeneral.c @@ -0,0 +1,285 @@ +/* General window behavior. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, + Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-wingeneral.h" +#include "tui/tui-win.h" + +#ifdef HAVE_NCURSES_H +#include <ncurses.h> +#else +#ifdef HAVE_CURSES_H +#include <curses.h> +#endif +#endif + +/*********************** +** PUBLIC FUNCTIONS +***********************/ +/* + ** tuiRefreshWin() + ** Refresh the window + */ +void +tuiRefreshWin (TuiGenWinInfoPtr winInfo) +{ + if (winInfo->type == DATA_WIN && winInfo->contentSize > 0) + { + int i; + + for (i = 0; (i < winInfo->contentSize); i++) + { + TuiGenWinInfoPtr dataItemWinPtr; + + dataItemWinPtr = &((TuiWinContent) + winInfo->content)[i]->whichElement.dataWindow; + if (m_genWinPtrNotNull (dataItemWinPtr) && + dataItemWinPtr->handle != (WINDOW *) NULL) + wrefresh (dataItemWinPtr->handle); + } + } + else if (winInfo->type == CMD_WIN) + { + /* Do nothing */ + } + else + { + if (winInfo->handle != (WINDOW *) NULL) + wrefresh (winInfo->handle); + } + + return; +} /* tuiRefreshWin */ + + +/* + ** tuiDelwin() + ** Function to delete the curses window, checking for null + */ +void +tuiDelwin (WINDOW * window) +{ + if (window != (WINDOW *) NULL) + delwin (window); + + return; +} /* tuiDelwin */ + + +/* Draw a border arround the window. */ +void +boxWin (TuiGenWinInfoPtr winInfo, int highlightFlag) +{ + if (winInfo && winInfo->handle) + { + WINDOW *win; + int attrs; + + win = winInfo->handle; + if (highlightFlag == HILITE) + attrs = tui_active_border_attrs; + else + attrs = tui_border_attrs; + + wattron (win, attrs); + wborder (win, tui_border_vline, tui_border_vline, + tui_border_hline, tui_border_hline, + tui_border_ulcorner, tui_border_urcorner, + tui_border_llcorner, tui_border_lrcorner); + if (winInfo->title) + mvwaddstr (win, 0, 3, winInfo->title); + wattroff (win, attrs); + } +} + + +/* + ** unhighlightWin(). + */ +void +unhighlightWin (TuiWinInfoPtr winInfo) +{ + if (m_winPtrNotNull (winInfo) && winInfo->generic.handle != (WINDOW *) NULL) + { + boxWin ((TuiGenWinInfoPtr) winInfo, NO_HILITE); + wrefresh (winInfo->generic.handle); + m_setWinHighlightOff (winInfo); + } +} /* unhighlightWin */ + + +/* + ** highlightWin(). + */ +void +highlightWin (TuiWinInfoPtr winInfo) +{ + if (m_winPtrNotNull (winInfo) && + winInfo->canHighlight && winInfo->generic.handle != (WINDOW *) NULL) + { + boxWin ((TuiGenWinInfoPtr) winInfo, HILITE); + wrefresh (winInfo->generic.handle); + m_setWinHighlightOn (winInfo); + } +} /* highlightWin */ + + +/* + ** checkAndDisplayHighlightIfNecessay + */ +void +checkAndDisplayHighlightIfNeeded (TuiWinInfoPtr winInfo) +{ + if (m_winPtrNotNull (winInfo) && winInfo->generic.type != CMD_WIN) + { + if (winInfo->isHighlighted) + highlightWin (winInfo); + else + unhighlightWin (winInfo); + + } + return; +} /* checkAndDisplayHighlightIfNeeded */ + + +/* + ** makeWindow(). + */ +void +makeWindow (TuiGenWinInfoPtr winInfo, int boxIt) +{ + WINDOW *handle; + + handle = newwin (winInfo->height, + winInfo->width, + winInfo->origin.y, + winInfo->origin.x); + winInfo->handle = handle; + if (handle != (WINDOW *) NULL) + { + if (boxIt == BOX_WINDOW) + boxWin (winInfo, NO_HILITE); + winInfo->isVisible = TRUE; + scrollok (handle, TRUE); + } +} + + +/* + ** makeVisible(). + ** We can't really make windows visible, or invisible. So we + ** have to delete the entire window when making it visible, + ** and create it again when making it visible. + */ +void +makeVisible (TuiGenWinInfoPtr winInfo, int visible) +{ + /* Don't tear down/recreate command window */ + if (winInfo->type == CMD_WIN) + return; + + if (visible) + { + if (!winInfo->isVisible) + { + makeWindow ( + winInfo, + (winInfo->type != CMD_WIN && !m_winIsAuxillary (winInfo->type))); + winInfo->isVisible = TRUE; + } + } + else if (!visible && + winInfo->isVisible && winInfo->handle != (WINDOW *) NULL) + { + winInfo->isVisible = FALSE; + tuiDelwin (winInfo->handle); + winInfo->handle = (WINDOW *) NULL; + } + + return; +} /* makeVisible */ + + +/* + ** makeAllVisible(). + ** Makes all windows invisible (except the command and locator windows) + */ +void +makeAllVisible (int visible) +{ + int i; + + for (i = 0; i < MAX_MAJOR_WINDOWS; i++) + { + if (m_winPtrNotNull (winList[i]) && + ((winList[i])->generic.type) != CMD_WIN) + { + if (m_winIsSourceType ((winList[i])->generic.type)) + makeVisible ((winList[i])->detail.sourceInfo.executionInfo, + visible); + makeVisible ((TuiGenWinInfoPtr) winList[i], visible); + } + } + + return; +} /* makeAllVisible */ + +/* + ** refreshAll(). + ** Function to refresh all the windows currently displayed + */ +void +refreshAll (TuiWinInfoPtr * list) +{ + TuiWinType type; + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + + for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++) + { + if (list[type] && list[type]->generic.isVisible) + { + if (type == SRC_WIN || type == DISASSEM_WIN) + { + touchwin (list[type]->detail.sourceInfo.executionInfo->handle); + tuiRefreshWin (list[type]->detail.sourceInfo.executionInfo); + } + touchwin (list[type]->generic.handle); + tuiRefreshWin (&list[type]->generic); + } + } + if (locator->isVisible) + { + touchwin (locator->handle); + tuiRefreshWin (locator); + } + + return; +} /* refreshAll */ + + +/********************************* +** Local Static Functions +*********************************/ diff --git a/gdb/tui/tui-wingeneral.h b/gdb/tui/tui-wingeneral.h new file mode 100644 index 00000000000..42d1ce46add --- /dev/null +++ b/gdb/tui/tui-wingeneral.h @@ -0,0 +1,49 @@ +/* General window behavior. + Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_GENERAL_WIN_H +#define TUI_GENERAL_WIN_H + +/* + ** Functions + */ +extern void unhighlightWin (TuiWinInfoPtr); +extern void makeVisible (TuiGenWinInfoPtr, int); +extern void makeAllVisible (int); +extern void makeWindow (TuiGenWinInfoPtr, int); +extern TuiWinInfoPtr copyWin (TuiWinInfoPtr); +extern void boxWin (TuiGenWinInfoPtr, int); +extern void highlightWin (TuiWinInfoPtr); +extern void checkAndDisplayHighlightIfNeeded (TuiWinInfoPtr); +extern void refreshAll (TuiWinInfoPtr *); +extern void tuiDelwin (WINDOW * window); +extern void tuiRefreshWin (TuiGenWinInfoPtr); + +/* + ** Macros + */ +#define m_beVisible(winInfo) makeVisible((TuiGenWinInfoPtr)(winInfo), TRUE) +#define m_beInvisible(winInfo) \ + makeVisible((TuiGenWinInfoPtr)(winInfo), FALSE) +#define m_allBeVisible() makeAllVisible(TRUE) +#define m_allBeInvisible() makeAllVisible(FALSE) + +#endif /*TUI_GENERAL_WIN_H */ diff --git a/gdb/tui/tui-winsource.c b/gdb/tui/tui-winsource.c new file mode 100644 index 00000000000..87609b4cde8 --- /dev/null +++ b/gdb/tui/tui-winsource.c @@ -0,0 +1,715 @@ +/* TUI display source/assembly window. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include <ctype.h> +#include "symtab.h" +#include "frame.h" +#include "breakpoint.h" +#include "value.h" +#include "source.h" + +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-stack.h" +#include "tui/tui-win.h" +#include "tui/tui-wingeneral.h" +#include "tui/tui-winsource.h" +#include "tui/tui-source.h" +#include "tui/tui-disasm.h" + +#ifdef HAVE_NCURSES_H +#include <ncurses.h> +#else +#ifdef HAVE_CURSES_H +#include <curses.h> +#endif +#endif + +/* Function to display the "main" routine. */ +void +tui_display_main (void) +{ + if ((sourceWindows ())->count > 0) + { + CORE_ADDR addr; + + addr = tui_get_begin_asm_address (); + if (addr != (CORE_ADDR) 0) + { + struct symtab_and_line sal; + + tuiUpdateSourceWindowsWithAddr (addr); + sal = find_pc_line (addr, 0); + if (sal.symtab) + tuiUpdateLocatorFilename (sal.symtab->filename); + else + tuiUpdateLocatorFilename ("??"); + } + } +} + + + +/* + ** tuiUpdateSourceWindow(). + ** Function to display source in the source window. This function + ** initializes the horizontal scroll to 0. + */ +void +tuiUpdateSourceWindow (TuiWinInfoPtr winInfo, struct symtab *s, + TuiLineOrAddress lineOrAddr, int noerror) +{ + winInfo->detail.sourceInfo.horizontalOffset = 0; + tuiUpdateSourceWindowAsIs (winInfo, s, lineOrAddr, noerror); + + return; +} /* tuiUpdateSourceWindow */ + + +/* + ** tuiUpdateSourceWindowAsIs(). + ** Function to display source in the source/asm window. This + ** function shows the source as specified by the horizontal offset. + */ +void +tuiUpdateSourceWindowAsIs (TuiWinInfoPtr winInfo, struct symtab *s, + TuiLineOrAddress lineOrAddr, int noerror) +{ + TuiStatus ret; + + if (winInfo->generic.type == SRC_WIN) + ret = tuiSetSourceContent (s, lineOrAddr.lineNo, noerror); + else + ret = tui_set_disassem_content (lineOrAddr.addr); + + if (ret == TUI_FAILURE) + { + tuiClearSourceContent (winInfo, EMPTY_SOURCE_PROMPT); + tuiClearExecInfoContent (winInfo); + } + else + { + tui_update_breakpoint_info (winInfo, 0); + tuiShowSourceContent (winInfo); + tuiUpdateExecInfo (winInfo); + if (winInfo->generic.type == SRC_WIN) + { + struct symtab_and_line sal; + + sal.line = lineOrAddr.lineNo + + (winInfo->generic.contentSize - 2); + sal.symtab = s; + set_current_source_symtab_and_line (&sal); + /* + ** If the focus was in the asm win, put it in the src + ** win if we don't have a split layout + */ + if (tuiWinWithFocus () == disassemWin && + currentLayout () != SRC_DISASSEM_COMMAND) + tuiSetWinFocusTo (srcWin); + } + } + + + return; +} /* tuiUpdateSourceWindowAsIs */ + + +/* + ** tuiUpdateSourceWindowsWithAddr(). + ** Function to ensure that the source and/or disassemly windows + ** reflect the input address. + */ +void +tuiUpdateSourceWindowsWithAddr (CORE_ADDR addr) +{ + if (addr != 0) + { + struct symtab_and_line sal; + TuiLineOrAddress l; + + switch (currentLayout ()) + { + case DISASSEM_COMMAND: + case DISASSEM_DATA_COMMAND: + tui_show_disassem (addr); + break; + case SRC_DISASSEM_COMMAND: + tui_show_disassem_and_update_source (addr); + break; + default: + sal = find_pc_line (addr, 0); + l.lineNo = sal.line; + tuiShowSource (sal.symtab, l, FALSE); + break; + } + } + else + { + int i; + + for (i = 0; i < (sourceWindows ())->count; i++) + { + TuiWinInfoPtr winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i]; + + tuiClearSourceContent (winInfo, EMPTY_SOURCE_PROMPT); + tuiClearExecInfoContent (winInfo); + } + } + + return; +} /* tuiUpdateSourceWindowsWithAddr */ + +/* + ** tuiUpdateSourceWindowsWithLine(). + ** Function to ensure that the source and/or disassemly windows + ** reflect the input address. + */ +void +tuiUpdateSourceWindowsWithLine (struct symtab *s, int line) +{ + CORE_ADDR pc; + TuiLineOrAddress l; + + switch (currentLayout ()) + { + case DISASSEM_COMMAND: + case DISASSEM_DATA_COMMAND: + find_line_pc (s, line, &pc); + tuiUpdateSourceWindowsWithAddr (pc); + break; + default: + l.lineNo = line; + tuiShowSource (s, l, FALSE); + if (currentLayout () == SRC_DISASSEM_COMMAND) + { + find_line_pc (s, line, &pc); + tui_show_disassem (pc); + } + break; + } + + return; +} /* tuiUpdateSourceWindowsWithLine */ + +/* + ** tuiClearSourceContent(). + */ +void +tuiClearSourceContent (TuiWinInfoPtr winInfo, int displayPrompt) +{ + if (m_winPtrNotNull (winInfo)) + { + register int i; + + winInfo->generic.contentInUse = FALSE; + tuiEraseSourceContent (winInfo, displayPrompt); + for (i = 0; i < winInfo->generic.contentSize; i++) + { + TuiWinElementPtr element = + (TuiWinElementPtr) winInfo->generic.content[i]; + element->whichElement.source.hasBreak = FALSE; + element->whichElement.source.isExecPoint = FALSE; + } + } + + return; +} /* tuiClearSourceContent */ + + +/* + ** tuiEraseSourceContent(). + */ +void +tuiEraseSourceContent (TuiWinInfoPtr winInfo, int displayPrompt) +{ + int xPos; + int halfWidth = (winInfo->generic.width - 2) / 2; + + if (winInfo->generic.handle != (WINDOW *) NULL) + { + werase (winInfo->generic.handle); + checkAndDisplayHighlightIfNeeded (winInfo); + if (displayPrompt == EMPTY_SOURCE_PROMPT) + { + char *noSrcStr; + + if (winInfo->generic.type == SRC_WIN) + noSrcStr = NO_SRC_STRING; + else + noSrcStr = NO_DISASSEM_STRING; + if (strlen (noSrcStr) >= halfWidth) + xPos = 1; + else + xPos = halfWidth - strlen (noSrcStr); + mvwaddstr (winInfo->generic.handle, + (winInfo->generic.height / 2), + xPos, + noSrcStr); + + /* elz: added this function call to set the real contents of + the window to what is on the screen, so that later calls + to refresh, do display + the correct stuff, and not the old image */ + + tuiSetSourceContentNil (winInfo, noSrcStr); + } + tuiRefreshWin (&winInfo->generic); + } + return; +} /* tuiEraseSourceContent */ + + +/* Redraw the complete line of a source or disassembly window. */ +static void +tui_show_source_line (TuiWinInfoPtr winInfo, int lineno) +{ + TuiWinElementPtr line; + int x, y; + + line = (TuiWinElementPtr) winInfo->generic.content[lineno - 1]; + if (line->whichElement.source.isExecPoint) + wattron (winInfo->generic.handle, A_STANDOUT); + + mvwaddstr (winInfo->generic.handle, lineno, 1, + line->whichElement.source.line); + if (line->whichElement.source.isExecPoint) + wattroff (winInfo->generic.handle, A_STANDOUT); + + /* Clear to end of line but stop before the border. */ + getyx (winInfo->generic.handle, y, x); + while (x + 1 < winInfo->generic.width) + { + waddch (winInfo->generic.handle, ' '); + getyx (winInfo->generic.handle, y, x); + } +} + +/* + ** tuiShowSourceContent(). + */ +void +tuiShowSourceContent (TuiWinInfoPtr winInfo) +{ + if (winInfo->generic.contentSize > 0) + { + int lineno; + + for (lineno = 1; lineno <= winInfo->generic.contentSize; lineno++) + tui_show_source_line (winInfo, lineno); + } + else + tuiEraseSourceContent (winInfo, TRUE); + + checkAndDisplayHighlightIfNeeded (winInfo); + tuiRefreshWin (&winInfo->generic); + winInfo->generic.contentInUse = TRUE; +} + + +/* + ** tuiHorizontalSourceScroll(). + ** Scroll the source forward or backward horizontally + */ +void +tuiHorizontalSourceScroll (TuiWinInfoPtr winInfo, + TuiScrollDirection direction, + int numToScroll) +{ + if (winInfo->generic.content != (OpaquePtr) NULL) + { + int offset; + struct symtab *s; + struct symtab_and_line cursal = get_current_source_symtab_and_line (); + + if (cursal.symtab == (struct symtab *) NULL) + s = find_pc_symtab (get_frame_pc (deprecated_selected_frame)); + else + s = cursal.symtab; + + if (direction == LEFT_SCROLL) + offset = winInfo->detail.sourceInfo.horizontalOffset + numToScroll; + else + { + if ((offset = + winInfo->detail.sourceInfo.horizontalOffset - numToScroll) < 0) + offset = 0; + } + winInfo->detail.sourceInfo.horizontalOffset = offset; + tuiUpdateSourceWindowAsIs ( + winInfo, + s, + ((TuiWinElementPtr) + winInfo->generic.content[0])->whichElement.source.lineOrAddr, + FALSE); + } + + return; +} /* tuiHorizontalSourceScroll */ + + +/* Set or clear the hasBreak flag in the line whose line is lineNo. */ +void +tuiSetIsExecPointAt (TuiLineOrAddress l, TuiWinInfoPtr winInfo) +{ + int changed = 0; + int i; + TuiWinContent content = (TuiWinContent) winInfo->generic.content; + + i = 0; + while (i < winInfo->generic.contentSize) + { + int newState; + + if (content[i]->whichElement.source.lineOrAddr.addr == l.addr) + newState = TRUE; + else + newState = FALSE; + if (newState != content[i]->whichElement.source.isExecPoint) + { + changed++; + content[i]->whichElement.source.isExecPoint = newState; + tui_show_source_line (winInfo, i + 1); + } + i++; + } + if (changed) + tuiRefreshWin (&winInfo->generic); +} + +/* Update the execution windows to show the active breakpoints. + This is called whenever a breakpoint is inserted, removed or + has its state changed. */ +void +tui_update_all_breakpoint_info () +{ + TuiList* list = sourceWindows (); + int i; + + for (i = 0; i < list->count; i++) + { + TuiWinInfoPtr win = (TuiWinInfoPtr) list->list[i]; + + if (tui_update_breakpoint_info (win, FALSE)) + { + tuiUpdateExecInfo (win); + } + } +} + + +/* Scan the source window and the breakpoints to update the + hasBreak information for each line. + Returns 1 if something changed and the execution window + must be refreshed. */ +int +tui_update_breakpoint_info (TuiWinInfoPtr win, int current_only) +{ + int i; + int need_refresh = 0; + TuiSourceInfoPtr src = &win->detail.sourceInfo; + + for (i = 0; i < win->generic.contentSize; i++) + { + struct breakpoint *bp; + extern struct breakpoint *breakpoint_chain; + int mode; + TuiSourceElement* line; + + line = &((TuiWinElementPtr) win->generic.content[i])->whichElement.source; + if (current_only && !line->isExecPoint) + continue; + + /* Scan each breakpoint to see if the current line has something to + do with it. Identify enable/disabled breakpoints as well as + those that we already hit. */ + mode = 0; + for (bp = breakpoint_chain; + bp != (struct breakpoint *) NULL; + bp = bp->next) + { + if ((win == srcWin + && bp->source_file + && (strcmp (src->filename, bp->source_file) == 0) + && bp->line_number == line->lineOrAddr.lineNo) + || (win == disassemWin + && bp->loc->address == line->lineOrAddr.addr)) + { + if (bp->enable_state == bp_disabled) + mode |= TUI_BP_DISABLED; + else + mode |= TUI_BP_ENABLED; + if (bp->hit_count) + mode |= TUI_BP_HIT; + if (bp->cond) + mode |= TUI_BP_CONDITIONAL; + if (bp->type == bp_hardware_breakpoint) + mode |= TUI_BP_HARDWARE; + } + } + if (line->hasBreak != mode) + { + line->hasBreak = mode; + need_refresh = 1; + } + } + return need_refresh; +} + + +/* + ** tuiSetExecInfoContent(). + ** Function to initialize the content of the execution info window, + ** based upon the input window which is either the source or + ** disassembly window. + */ +TuiStatus +tuiSetExecInfoContent (TuiWinInfoPtr winInfo) +{ + TuiStatus ret = TUI_SUCCESS; + + if (winInfo->detail.sourceInfo.executionInfo != (TuiGenWinInfoPtr) NULL) + { + TuiGenWinInfoPtr execInfoPtr = winInfo->detail.sourceInfo.executionInfo; + + if (execInfoPtr->content == (OpaquePtr) NULL) + execInfoPtr->content = + (OpaquePtr) allocContent (winInfo->generic.height, + execInfoPtr->type); + if (execInfoPtr->content != (OpaquePtr) NULL) + { + int i; + + tui_update_breakpoint_info (winInfo, 1); + for (i = 0; i < winInfo->generic.contentSize; i++) + { + TuiWinElementPtr element; + TuiWinElementPtr srcElement; + int mode; + + element = (TuiWinElementPtr) execInfoPtr->content[i]; + srcElement = (TuiWinElementPtr) winInfo->generic.content[i]; + + memset(element->whichElement.simpleString, ' ', + sizeof(element->whichElement.simpleString)); + element->whichElement.simpleString[TUI_EXECINFO_SIZE - 1] = 0; + + /* Now update the exec info content based upon the state + of each line as indicated by the source content. */ + mode = srcElement->whichElement.source.hasBreak; + if (mode & TUI_BP_HIT) + element->whichElement.simpleString[TUI_BP_HIT_POS] = + (mode & TUI_BP_HARDWARE) ? 'H' : 'B'; + else if (mode & (TUI_BP_ENABLED | TUI_BP_DISABLED)) + element->whichElement.simpleString[TUI_BP_HIT_POS] = + (mode & TUI_BP_HARDWARE) ? 'h' : 'b'; + + if (mode & TUI_BP_ENABLED) + element->whichElement.simpleString[TUI_BP_BREAK_POS] = '+'; + else if (mode & TUI_BP_DISABLED) + element->whichElement.simpleString[TUI_BP_BREAK_POS] = '-'; + + if (srcElement->whichElement.source.isExecPoint) + element->whichElement.simpleString[TUI_EXEC_POS] = '>'; + } + execInfoPtr->contentSize = winInfo->generic.contentSize; + } + else + ret = TUI_FAILURE; + } + + return ret; +} + + +/* + ** tuiShowExecInfoContent(). + */ +void +tuiShowExecInfoContent (TuiWinInfoPtr winInfo) +{ + TuiGenWinInfoPtr execInfo = winInfo->detail.sourceInfo.executionInfo; + int curLine; + + werase (execInfo->handle); + tuiRefreshWin (execInfo); + for (curLine = 1; (curLine <= execInfo->contentSize); curLine++) + mvwaddstr (execInfo->handle, + curLine, + 0, + ((TuiWinElementPtr) + execInfo->content[curLine - 1])->whichElement.simpleString); + tuiRefreshWin (execInfo); + execInfo->contentInUse = TRUE; + + return; +} /* tuiShowExecInfoContent */ + + +/* + ** tuiEraseExecInfoContent(). + */ +void +tuiEraseExecInfoContent (TuiWinInfoPtr winInfo) +{ + TuiGenWinInfoPtr execInfo = winInfo->detail.sourceInfo.executionInfo; + + werase (execInfo->handle); + tuiRefreshWin (execInfo); + + return; +} /* tuiEraseExecInfoContent */ + +/* + ** tuiClearExecInfoContent(). + */ +void +tuiClearExecInfoContent (TuiWinInfoPtr winInfo) +{ + winInfo->detail.sourceInfo.executionInfo->contentInUse = FALSE; + tuiEraseExecInfoContent (winInfo); + + return; +} /* tuiClearExecInfoContent */ + +/* + ** tuiUpdateExecInfo(). + ** Function to update the execution info window + */ +void +tuiUpdateExecInfo (TuiWinInfoPtr winInfo) +{ + tuiSetExecInfoContent (winInfo); + tuiShowExecInfoContent (winInfo); +} /* tuiUpdateExecInfo */ + +TuiStatus +tuiAllocSourceBuffer (TuiWinInfoPtr winInfo) +{ + register char *srcLineBuf; + register int i, lineWidth, maxLines; + TuiStatus ret = TUI_FAILURE; + + maxLines = winInfo->generic.height; /* less the highlight box */ + lineWidth = winInfo->generic.width - 1; + /* + ** Allocate the buffer for the source lines. Do this only once since they + ** will be re-used for all source displays. The only other time this will + ** be done is when a window's size changes. + */ + if (winInfo->generic.content == (OpaquePtr) NULL) + { + srcLineBuf = (char *) xmalloc ((maxLines * lineWidth) * sizeof (char)); + if (srcLineBuf == (char *) NULL) + fputs_unfiltered ( + "Unable to Allocate Memory for Source or Disassembly Display.\n", + gdb_stderr); + else + { + /* allocate the content list */ + if ((winInfo->generic.content = + (OpaquePtr) allocContent (maxLines, SRC_WIN)) == (OpaquePtr) NULL) + { + tuiFree (srcLineBuf); + srcLineBuf = (char *) NULL; + fputs_unfiltered ( + "Unable to Allocate Memory for Source or Disassembly Display.\n", + gdb_stderr); + } + } + for (i = 0; i < maxLines; i++) + ((TuiWinElementPtr) + winInfo->generic.content[i])->whichElement.source.line = + srcLineBuf + (lineWidth * i); + ret = TUI_SUCCESS; + } + else + ret = TUI_SUCCESS; + + return ret; +} /* tuiAllocSourceBuffer */ + + +/* + ** tuiLineIsDisplayed(). + ** Answer whether the a particular line number or address is displayed + ** in the current source window. + */ +int +tuiLineIsDisplayed (int line, TuiWinInfoPtr winInfo, + int checkThreshold) +{ + int isDisplayed = FALSE; + int i, threshold; + + if (checkThreshold) + threshold = SCROLL_THRESHOLD; + else + threshold = 0; + i = 0; + while (i < winInfo->generic.contentSize - threshold && !isDisplayed) + { + isDisplayed = (((TuiWinElementPtr) + winInfo->generic.content[i])->whichElement.source.lineOrAddr.lineNo + == (int) line); + i++; + } + + return isDisplayed; +} /* tuiLineIsDisplayed */ + + +/* + ** tuiLineIsDisplayed(). + ** Answer whether the a particular line number or address is displayed + ** in the current source window. + */ +int +tuiAddrIsDisplayed (CORE_ADDR addr, TuiWinInfoPtr winInfo, + int checkThreshold) +{ + int isDisplayed = FALSE; + int i, threshold; + + if (checkThreshold) + threshold = SCROLL_THRESHOLD; + else + threshold = 0; + i = 0; + while (i < winInfo->generic.contentSize - threshold && !isDisplayed) + { + isDisplayed = (((TuiWinElementPtr) + winInfo->generic.content[i])->whichElement.source.lineOrAddr.addr + == addr); + i++; + } + + return isDisplayed; +} + + +/***************************************** +** STATIC LOCAL FUNCTIONS ** +******************************************/ diff --git a/gdb/tui/tui-winsource.h b/gdb/tui/tui-winsource.h new file mode 100644 index 00000000000..cb00449ed2d --- /dev/null +++ b/gdb/tui/tui-winsource.h @@ -0,0 +1,68 @@ +/* TUI display source/assembly window. + Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _TUI_SOURCEWIN_H +#define _TUI_SOURCEWIN_H + +/* Update the execution windows to show the active breakpoints. + This is called whenever a breakpoint is inserted, removed or + has its state changed. */ +extern void tui_update_all_breakpoint_info (void); + +/* Scan the source window and the breakpoints to update the + hasBreak information for each line. + Returns 1 if something changed and the execution window + must be refreshed. */ +extern int tui_update_breakpoint_info (TuiWinInfoPtr win, int current_only); + +/* Function to display the "main" routine. */ +extern void tui_display_main (void); +extern void tuiUpdateSourceWindow (TuiWinInfoPtr, struct symtab *, TuiLineOrAddress, + int); +extern void tuiUpdateSourceWindowAsIs (TuiWinInfoPtr, struct symtab *, TuiLineOrAddress, + int); +extern void tuiUpdateSourceWindowsWithAddr (CORE_ADDR); +extern void tuiUpdateSourceWindowsWithLine (struct symtab *, int); +extern void tuiClearSourceContent (TuiWinInfoPtr, int); +extern void tuiEraseSourceContent (TuiWinInfoPtr, int); +extern void tuiSetSourceContentNil (TuiWinInfoPtr, char *); +extern void tuiShowSourceContent (TuiWinInfoPtr); +extern void tuiHorizontalSourceScroll (TuiWinInfoPtr, TuiScrollDirection, + int); +extern TuiStatus tuiSetExecInfoContent (TuiWinInfoPtr); +extern void tuiShowExecInfoContent (TuiWinInfoPtr); +extern void tuiEraseExecInfoContent (TuiWinInfoPtr); +extern void tuiClearExecInfoContent (TuiWinInfoPtr); +extern void tuiUpdateExecInfo (TuiWinInfoPtr); + +extern void tuiSetIsExecPointAt (TuiLineOrAddress, TuiWinInfoPtr); +extern TuiStatus tuiAllocSourceBuffer (TuiWinInfoPtr); +extern int tuiLineIsDisplayed (int, TuiWinInfoPtr, int); +extern int tuiAddrIsDisplayed (CORE_ADDR, TuiWinInfoPtr, int); + + +/* + ** Constant definitions + */ +#define SCROLL_THRESHOLD 2 /* threshold for lazy scroll */ + +#endif +/*_TUI_SOURCEWIN_H */ |