From: David Taylor Date: Thu, 31 Dec 1998 17:46:28 +0000 (+0000) Subject: HP tui support files for gdb. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=03b93bdc8296691bf77eaeed5a2f459c1e8eb61d;p=binutils-gdb.git HP tui support files for gdb. --- diff --git a/gdb/tui/.Sanitize b/gdb/tui/.Sanitize new file mode 100644 index 00000000000..16d5f59f8d4 --- /dev/null +++ b/gdb/tui/.Sanitize @@ -0,0 +1,64 @@ +# .Sanitize for devo/gdb/tui. + +# Each directory to survive its way into a release will need a file +# like this one called "./.Sanitize". All keyword lines must exist, +# and must exist in the order specified by this file. Each directory +# in the tree will be processed, top down, in the following order. + +# Hash started lines like this one are comments and will be deleted +# before anything else is done. Blank lines will also be squashed +# out. + +# The lines between the "Do-first:" line and the "Things-to-keep:" +# line are executed as a /bin/sh shell script before anything else is +# done in this directory. + +Do-first: + +# All files listed between the "Things-to-keep:" line and the +# "Files-to-sed:" line will be kept. All other files will be removed. +# Directories listed in this section will have their own Sanitize +# called. Directories not listed will be removed in their entirety +# with rm -rf. + +Things-to-keep: + +Makefile.in +tui.c +tui.h +tuiCommand.c +tuiCommand.h +tuiData.c +tuiData.h +tuiDataWin.c +tuiDataWin.h +tuiDisassem.c +tuiDisassem.h +tuiGeneralWin.c +tuiGeneralWin.h +tuiIO.c +tuiIO.h +tuiLayout.c +tuiLayout.h +tuiRegs.c +tuiRegs.h +tuiSource.c +tuiSource.h +tuiSourceWin.c +tuiSourceWin.h +tuiStack.c +tuiStack.h +tuiWin.c +tuiWin.h + +# Things which are explicitly *not* kept, for now. + +Things-to-lose: + +Do-last: + +# Don't try to clean directories here, as the 'mv' command will fail. +# Also, grep fails on NFS mounted directories. + +# +# End of file. diff --git a/gdb/tui/ChangeLog b/gdb/tui/ChangeLog new file mode 100644 index 00000000000..8e8b92d3355 --- /dev/null +++ b/gdb/tui/ChangeLog @@ -0,0 +1,116 @@ +Thu Dec 31 12:08:32 1998 David Taylor + + The following changes were made by Jim Blandy , + Edith Epstein , Elena Zannoni + Stan Shebs , and David + Taylor , 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 , 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 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 + . 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 , 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/Makefile.in b/gdb/tui/Makefile.in new file mode 100644 index 00000000000..256464b5bc5 --- /dev/null +++ b/gdb/tui/Makefile.in @@ -0,0 +1,168 @@ +# Copyright 1998 Free Software Foundation, Inc. + +# 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. + +all: libtui.a + +srcdir=@srcdir@ +VPATH = @srcdir@ + +SHELL = @SHELL@ + +CC=@CC@ +CFLAGS=@CFLAGS@ +AR=@AR@ +RANLIB=@RANLIB@ + +# Host and target-dependent makefile fragments come in here. +@host_makefile_frag@ +@target_makefile_frag@ +# End of host and target-dependent makefile fragments + +# Where is our "include" directory? Typically $(srcdir)/../include. +# This is essentially the header file directory for the library +# routines in libiberty. +INCLUDE_DIR = $(srcdir)/../../include +INCLUDE_CFLAGS = -I$(INCLUDE_DIR) + +# Configured by the --with-mmalloc option to configure. +MMALLOC = @MMALLOC@ +MMALLOC_CFLAGS = @MMALLOC_CFLAGS@ + +# Where is the BFD library? Typically in ../bfd. +BFD_DIR = ../../bfd +BFD_SRC = $(srcdir)/$(BFD_DIR) +BFD_CFLAGS = -I$(BFD_DIR) -I$(BFD_SRC) + +# Where is the READLINE library? Typically in ../readline. +READLINE_DIR = ../../readline +READLINE_SRC = $(srcdir)/$(READLINE_DIR) +READLINE_CFLAGS = -I$(READLINE_SRC) + +# Where is the INTL library? Typically in ../intl. +INTL_DIR = ../../intl +INTL_SRC = $(srcdir)/$(INTL_DIR) +INTL_CFLAGS = -I$(INTL_DIR) -I$(INTL_SRC) + +# Where is the TCL library? Typically in ../tcl. +TCL_CFLAGS = @TCLHDIR@ + +# Where is the TK library? Typically in ../tk. +TK_CFLAGS = @TKHDIR@ @TK_BUILD_INCLUDES@ + +# Where is Itcl? Typically in ../itcl. +ITCL_CFLAGS = @ITCLHDIR@ + +# Where is Tix? Typically in ../tix. +TIX_CFLAGS = @TIXHDIR@ + +X11_CFLAGS = @TK_XINCLUDES@ + +ENABLE_IDE= @ENABLE_IDE@ + +GUI_CFLAGS_X = -I$(srcdir)/../../libgui/src + +IDE_CFLAGS_X = -I$(srcdir)/../../libidetcl/src -I$(srcdir)/../../libide/src \ + `if [ x"$(ENABLE_IDE)" != x ] ; then \ + echo -DIDE -I$(srcdir)/../../ilu/runtime/mainloop;\ + fi` + +IDE_CFLAGS=$(GUI_CFLAGS_X) $(IDE_CFLAGS_X) + +ENABLE_CFLAGS= @ENABLE_CFLAGS@ + +# -I. for config files. +# -I$(srcdir) for gdb internal headers and possibly for gnu-regex.h also. +# -I$(srcdir)/config for more generic config files. + +# It is also possible that you will need to add -I/usr/include/sys if +# your system doesn't have fcntl.h in /usr/include (which is where it +# should be according to Posix). +DEFS = @DEFS@ +GDB_CFLAGS = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config $(DEFS) + +# M{H,T}_CFLAGS, if defined, have host- and target-dependent CFLAGS +# from the config directory. +GLOBAL_CFLAGS = $(MT_CFLAGS) $(MH_CFLAGS) +#PROFILE_CFLAGS = -pg + +# INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros. +INTERNAL_CFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) \ + $(GDB_CFLAGS) $(READLINE_CFLAGS) $(BFD_CFLAGS) \ + $(MMALLOC_CFLAGS) $(INCLUDE_CFLAGS) $(INTL_CFLAGS) \ + $(ENABLE_CFLAGS) + +HEADERS = tuiIO.h tuiData.h tuiGeneralWin.h tuiLayout.h tuiStack.h \ + tuiSource.h tuiCommand.h tuiWin.h tuiDisassem.h \ + tuiSourceWin.h tuiRegs.h tuiDataWin.h + +SOURCES = tui.c tuiData.c tuiSource.c tuiStack.c tuiIO.c \ + tuiGeneralWin.c tuiLayout.c tuiWin.c tuiCommand.c \ + tuiDisassem.c tuiSourceWin.c tuiRegs.c tuiDataWin.c + +OBJECTS = tui.o tuiData.o tuiSource.o tuiStack.o tuiIO.o \ + tuiGeneralWin.o tuiLayout.o tuiWin.o tuiCommand.o \ + tuiDisassem.o tuiSourceWin.o tuiRegs.o tuiDataWin.o \ + tuiInit.o + + +# Prevent Sun make from putting in the machine type. Setting +# TARGET_ARCH to nothing works for SunOS 3, 4.0, but not for 4.1. +.c.o: + $(CC) -c $(INTERNAL_CFLAGS) $< +.SUFFIXES: .cpp +.c.cpp: + $(CC) -E $(INTERNAL_CFLAGS) $< > $@ + +libtui.a: $(OBJECTS) + rm -f libtui.a + $(AR) rc libtui.a $(OBJECTS) + $(RANLIB) libtui.a + +tui.o: tui.c tui.h tuiData.h tuiLayout.h tuiIO.h tuiRegs.h tuiWin.h +tuiCommand.o: tui.h tuiData.h tuiWin.h tuiIO.h +tuiData.o: tui.h tuiData.h +tuiDataWin.o: tui.h tuiData.h tuiRegs.h +tuiDisassem.o: tui.h tuiData.h tuiLayout.h tuiSourceWin.h tuiStack.h +tuiGeneralWin.o: tui.h tuiData.h tuiGeneralWin.h +tuiIO.o: tui.h tuiData.h tuiIO.h tuiCommand.h tuiWin.h +tuiLayout.o: tui.h tuiData.h tuiGeneralWin.h tuiStack.h tuiRegs.h \ + tuiDisassem.h +tuiRegs.o: tui.h tuiData.h tuiLayout.h tuiWin.h +tuiSource.o: tui.h tuiData.h tuiStack.h tuiSourceWin.h tuiSource.h +tuiSourceWin.o: tui.h tuiData.h tuiStack.h tuiSourceWin.h tuiSource.h \ + tuiDisassem.h +tuiStack.o: tui.h tuiData.h tuiStack.h tuiSourceWin.h +tuiWin.o: tui.h tuiData.h tuiGeneralWin.h tuiStack.h tuiSourceWin.h \ + tuiDataWin.h + +tuiInit.o: tuiInit.c +tuiInit.c: $(SOURCES) + @echo Making tuiInit.c + @rm -f init.c-tmp + @echo '/* Do not modify this file. */' >init.c-tmp + @echo '/* It is created automatically by the Makefile. */'>>init.c-tmp + @echo '#include "ansidecl.h"' >>init.c-tmp + @echo 'extern void initialize_tui_files PARAMS ((void));' >>init.c-tmp + @echo 'void initialize_tui_files PARAMS ((void)) {' >>init.c-tmp + @-( cd $(srcdir) ; grep '^_initialize_[a-z_0-9A-Z]* *(' $(SOURCES) ) 2>/dev/null \ + | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 PARAMS ((void)); \1 ();}/' >>init.c-tmp + @echo '}' >>init.c-tmp + @mv init.c-tmp tuiInit.c + +clean: + rm -f *.o *.a diff --git a/gdb/tui/tuiCommand.c b/gdb/tui/tuiCommand.c new file mode 100644 index 00000000000..454dc62e857 --- /dev/null +++ b/gdb/tui/tuiCommand.c @@ -0,0 +1,215 @@ +/* +** tuiCommand.c +** This module contains functions specific to command window processing. +*/ + + +#include "defs.h" +#include "tui.h" +#include "tuiData.h" +#include "tuiWin.h" +#include "tuiIO.h" + + +/***************************************** +** STATIC LOCAL FUNCTIONS FORWARD DECLS ** +******************************************/ + + + +/***************************************** +** PUBLIC FUNCTIONS ** +******************************************/ + +/* +** tuiDispatchCtrlChar(). +** Dispatch the correct tui function based upon the control character. +*/ +unsigned int +#ifdef __STDC__ +tuiDispatchCtrlChar ( + unsigned int ch) +#else +tuiDispatchCtrlChar (ch) + unsigned int ch; +#endif +{ + TuiWinInfoPtr winInfo = tuiWinWithFocus (); + + /* + ** 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) && m_isStartSequence (ch)) + { + unsigned int pageCh = 0, tmpChar; + + tmpChar = 0; + while (!m_isEndSequence (tmpChar)) + { + tmpChar = (int) wgetch (cmdWin->generic.handle); + if (!tmpChar) + break; + if (tmpChar == 53) + pageCh = KEY_PPAGE; + else if (tmpChar == 54) + pageCh = KEY_NPAGE; + } + 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; + } +} /* tuiDispatchCtrlChar */ + + +/* +** tuiIncrCommandCharCountBy() +** Increment the current character count in the command window, +** checking for overflow. Returns the new value of the char count. +*/ +int +#ifdef __STDC__ +tuiIncrCommandCharCountBy ( + int count) +#else +tuiIncrCommandCharCountBy (count) + int count; +#endif +{ + if (tui_version) + { + if ((count + cmdWin->detail.commandInfo.curch) >= cmdWin->generic.width) + cmdWin->detail.commandInfo.curch = + (count + cmdWin->detail.commandInfo.curch) - cmdWin->generic.width; + else + cmdWin->detail.commandInfo.curch += count; + } + + return cmdWin->detail.commandInfo.curch; +} /* tuiIncrCommandCharCountBy */ + + +/* +** tuiDecrCommandCharCountBy() +** Decrement the current character count in the command window, +** checking for overflow. Returns the new value of the char count. +*/ +int +#ifdef __STDC__ +tuiDecrCommandCharCountBy ( + int count) +#else +tuiDecrCommandCharCountBy (count) + int count; +#endif +{ + if (tui_version) + { + if ((cmdWin->detail.commandInfo.curch - count) < 0) + cmdWin->detail.commandInfo.curch = + cmdWin->generic.width + (cmdWin->detail.commandInfo.curch - count); + else + cmdWin->detail.commandInfo.curch -= count; + } + + return cmdWin->detail.commandInfo.curch; +} /* tuiDecrCommandCharCountBy */ + + +/* +** tuiSetCommandCharCountTo() +** Set the character count to count. +*/ +int +#ifdef __STDC__ +tuiSetCommandCharCountTo ( + int count) +#else +tuiSetCommandCharCountTo (count) + int count; +#endif +{ + if (tui_version) + { + if (count > cmdWin->generic.width - 1) + { + cmdWin->detail.commandInfo.curch = 0; + tuiIncrCommandCharCountBy (count); + } + else + cmdWin->detail.commandInfo.curch -= count; + } + + return cmdWin->detail.commandInfo.curch; +} /* tuiSetCommandCharCountTo */ + + + +/* +** tuiClearCommandCharCount() +** Clear the character count to count. +*/ +int +#ifdef __STDC__ +tuiClearCommandCharCount (void) +#else +tuiClearCommandCharCount () +#endif +{ + if (tui_version) + cmdWin->detail.commandInfo.curch = 0; + + return cmdWin->detail.commandInfo.curch; +} /* tuiClearCommandCharCount */ + + + +/***************************************** +** STATIC LOCAL FUNCTIONS ** +******************************************/ diff --git a/gdb/tui/tuiCommand.h b/gdb/tui/tuiCommand.h new file mode 100644 index 00000000000..206d918dd56 --- /dev/null +++ b/gdb/tui/tuiCommand.h @@ -0,0 +1,24 @@ +#ifndef _TUI_COMMAND_H +#define _TUI_COMMAND_H +/* +** This header file supports +*/ + + +/***************************************** +** TYPE DEFINITIONS ** +******************************************/ + + + +/***************************************** +** PUBLIC FUNCTION EXTERNAL DECLS ** +******************************************/ + +extern unsigned int tuiDispatchCtrlChar PARAMS ((unsigned int)); +extern int tuiIncrCommandCharCountBy PARAMS ((int)); +extern int tuiDecrCommandCharCountBy PARAMS ((int)); +extern int tuiSetCommandCharCountTo PARAMS ((int)); +extern int tuiClearCommandCharCount PARAMS ((void)); + +#endif /*_TUI_COMMAND_H*/ diff --git a/gdb/tui/tuiData.c b/gdb/tui/tuiData.c new file mode 100644 index 00000000000..758a6cde492 --- /dev/null +++ b/gdb/tui/tuiData.c @@ -0,0 +1,1624 @@ +/* +** tuiData.c +** This module contains functions for manipulating the data +** structures used by the TUI +*/ + +#include "defs.h" +#include "tui.h" +#include "tuiData.h" + +/**************************** +** GLOBAL DECLARATIONS +****************************/ +TuiWinInfoPtr winList[MAX_MAJOR_WINDOWS]; + +/*************************** +** Private Definitions +****************************/ +#define FILE_WIDTH 30 +#define PROC_WIDTH 40 +#define LINE_WIDTH 4 +#define PC_WIDTH 8 + +/*************************** +** Private data +****************************/ +static char *_tuiNullStr = TUI_NULL_STR; +static char *_tuiBlankStr = " "; +static char *_tuiLocationStr = " >"; +static char *_tuiBreakStr = " * "; +static char *_tuiBreakLocationStr = " *>"; +static TuiLayoutType _currentLayout = UNDEFINED_LAYOUT; +static int _termHeight, _termWidth; +static int _historyLimit = DEFAULT_HISTORY_COUNT; +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 PARAMS ((TuiWinContent, int, TuiWinType)); +static void freeContentElements PARAMS ((TuiWinContent, int, TuiWinType)); + + + +/********************************* +** PUBLIC FUNCTIONS +**********************************/ + +/****************************************** +** ACCESSORS & MUTATORS FOR PRIVATE DATA +******************************************/ + +/* +** tuiWinResized(). +** Answer a whether the terminal window has been resized or not +*/ +int +#ifdef __STDC__ +tuiWinResized (void) +#else +tuiWinResized () +#endif +{ + return _winResized; +} /* tuiWinResized */ + + +/* +** tuiSetWinResized(). +** Set a whether the terminal window has been resized or not +*/ +void +#ifdef __STDC__ +tuiSetWinResizedTo ( + int resized) +#else +tuiSetWinResizedTo (resized) + int resized; +#endif +{ + _winResized = resized; + + return; +} /* tuiSetWinResizedTo */ + + +/* +** tuiLayoutDef(). +** Answer a pointer to the current layout definition +*/ +TuiLayoutDefPtr +#ifdef __STDC__ +tuiLayoutDef (void) +#else +tuiLayoutDef () +#endif +{ + return &_layoutDef; +} /* tuiLayoutDef */ + + +/* +** tuiWinWithFocus(). +** Answer the window with the logical focus +*/ +TuiWinInfoPtr +#ifdef __STDC__ +tuiWinWithFocus (void) +#else +tuiWinWithFocus () +#endif +{ + return _winWithFocus; +} /* tuiWinWithFocus */ + + +/* +** tuiSetWinWithFocus(). +** Set the window that has the logical focus +*/ +void +#ifdef __STDC__ +tuiSetWinWithFocus ( + TuiWinInfoPtr winInfo) +#else +tuiSetWinWithFocus (winInfo) + TuiWinInfoPtr winInfo; +#endif +{ + _winWithFocus = winInfo; + + return; +} /* tuiSetWinWithFocus */ + + +/* +** tuiDefaultTabLen(). +** Answer the length in chars, of tabs +*/ +int +#ifdef __STDC__ +tuiDefaultTabLen (void) +#else +tuiDefaultTabLen () +#endif +{ + return _defaultTabLen; +} /* tuiDefaultTabLen */ + + +/* +** tuiSetDefaultTabLen(). +** Set the length in chars, of tabs +*/ +void +#ifdef __STDC__ +tuiSetDefaultTabLen ( + int len) +#else +tuiSetDefaultTabLen (len) + int len; +#endif +{ + _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 +#ifdef __STDC__ +sourceWindows (void) +#else +sourceWindows () +#endif +{ + 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 +#ifdef __STDC__ +clearSourceWindows (void) +#else +clearSourceWindows () +#endif +{ + _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 +#ifdef __STDC__ +clearSourceWindowsDetail (void) +#else +clearSourceWindowsDetail () +#endif +{ + 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 +#ifdef __STDC__ +addToSourceWindows ( + TuiWinInfoPtr winInfo) +#else +addToSourceWindows (winInfo) + TuiWinInfoPtr winInfo; +#endif +{ + if (_sourceWindows.count < 2) + _sourceWindows.list[_sourceWindows.count++] = (Opaque) winInfo; + + return; +} /* addToSourceWindows */ + + +/* +** clearWinDetail() +** Clear the pertinant detail in the windows. +*/ +void +#ifdef __STDC__ +clearWinDetail ( + TuiWinInfoPtr winInfo) +#else +clearWinDetail (winInfo) + TuiWinInfoPtr winInfo; +#endif +{ + if (m_winPtrNotNull (winInfo)) + { + switch (winInfo->generic.type) + { + case SRC_WIN: + case DISASSEM_WIN: + winInfo->detail.sourceInfo.startLineOrAddr.addr = (Opaque) NULL; + 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 */ + + +/* +** blankStr() +** Accessor for the blank string. +*/ +char * +#ifdef __STDC__ +blankStr (void) +#else +blankStr () +#endif +{ + return _tuiBlankStr; +} /* blankStr */ + + +/* +** locationStr() +** Accessor for the location string. +*/ +char * +#ifdef __STDC__ +locationStr (void) +#else +locationStr () +#endif +{ + return _tuiLocationStr; +} /* locationStr */ + + +/* +** breakStr() +** Accessor for the break string. +*/ +char * +#ifdef __STDC__ +breakStr (void) +#else +breakStr () +#endif +{ + return _tuiBreakStr; +} /* breakStr */ + + +/* +** breakLocationStr() +** Accessor for the breakLocation string. +*/ +char * +#ifdef __STDC__ +breakLocationStr (void) +#else +breakLocationStr () +#endif +{ + return _tuiBreakLocationStr; +} /* breakLocationStr */ + + +/* +** nullStr() +** Accessor for the null string. +*/ +char * +#ifdef __STDC__ +nullStr (void) +#else +nullStr () +#endif +{ + return _tuiNullStr; +} /* nullStr */ + + +/* +** sourceExecInfoPtr(). +** Accessor for the source execution info ptr. +*/ +TuiGenWinInfoPtr +#ifdef __STDC__ +sourceExecInfoWinPtr (void) +#else +sourceExecInfoWinPtr () +#endif +{ + return &_execInfo[0]; +} /* sourceExecInfoWinPtr */ + + +/* +** disassemExecInfoPtr(). +** Accessor for the disassem execution info ptr. +*/ +TuiGenWinInfoPtr +#ifdef __STDC__ +disassemExecInfoWinPtr (void) +#else +disassemExecInfoWinPtr () +#endif +{ + return &_execInfo[1]; +} /* disassemExecInfoWinPtr */ + + +/* +** locatorWinInfoPtr(). +** Accessor for the locator win info. Answers a pointer to the +** static locator win info struct. +*/ +TuiGenWinInfoPtr +#ifdef __STDC__ +locatorWinInfoPtr (void) +#else +locatorWinInfoPtr () +#endif +{ + return &_locator; +} /* locatorWinInfoPtr */ + + +/* +** historyLimit(). +** Accessor for the history limit +*/ +int +#ifdef __STDC__ +historyLimit (void) +#else +historyLimit () +#endif +{ + return _historyLimit; +} /* historyLimit */ + + +/* +** setHistoryLimitTo(). +** Mutator for the history limit +*/ +void +#ifdef __STDC__ +setHistoryLimitTo ( + int h) +#else +setHistoryLimitTo (h) + int h; +#endif +{ + _historyLimit = h; + + return; +} /* setHistoryLimitTo */ + +/* +** termHeight(). +** Accessor for the termHeight +*/ +int +#ifdef __STDC__ +termHeight (void) +#else +termHeight () +#endif +{ + return _termHeight; +} /* termHeight */ + + +/* +** setTermHeightTo(). +** Mutator for the term height +*/ +void +#ifdef __STDC__ +setTermHeightTo ( + int h) +#else +setTermHeightTo (h) + int h; +#endif +{ + _termHeight = h; + + return; +} /* setTermHeightTo */ + + +/* +** termWidth(). +** Accessor for the termWidth +*/ +int +#ifdef __STDC__ +termWidth (void) +#else +termWidth () +#endif +{ + return _termWidth; +} /* termWidth */ + + +/* +** setTermWidth(). +** Mutator for the termWidth +*/ +void +#ifdef __STDC__ +setTermWidthTo ( + int w) +#else +setTermWidthTo (w) + int w; +#endif +{ + _termWidth = w; + + return; +} /* setTermWidthTo */ + + +/* +** currentLayout(). +** Accessor for the current layout +*/ +TuiLayoutType +#ifdef __STDC__ +currentLayout (void) +#else +currentLayout () +#endif +{ + return _currentLayout; +} /* currentLayout */ + + +/* +** setCurrentLayoutTo(). +** Mutator for the current layout +*/ +void +#ifdef __STDC__ +setCurrentLayoutTo ( + TuiLayoutType newLayout) +#else +setCurrentLayoutTo (newLayout) + TuiLayoutType newLayout; +#endif +{ + _currentLayout = newLayout; + + return; +} /* setCurrentLayoutTo */ + + +/* +** setGenWinOrigin(). +** Set the origin of the window +*/ +void +#ifdef __STDC__ +setGenWinOrigin ( + TuiGenWinInfoPtr winInfo, + int x, + int y) +#else +setGenWinOrigin (winInfo, x, y) + TuiGenWinInfoPtr winInfo; + int x; + int y; +#endif +{ + 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 +#ifdef __STDC__ +tuiNextWin ( + TuiWinInfoPtr curWin) +#else +tuiNextWin (curWin) + TuiWinInfoPtr curWin; +#endif +{ + 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]->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 +#ifdef __STDC__ +tuiPrevWin ( + TuiWinInfoPtr curWin) +#else +tuiPrevWin (curWin) + TuiWinInfoPtr curWin; +#endif +{ + 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; +} /* tuiPrevWin */ + + +/* +** displayableWinContentOf(). +** Answer a the content at the location indicated by index. Note +** that if this is a locator window, the string returned should be +** freed after use. +*/ +char * +#ifdef __STDC__ +displayableWinContentOf ( + TuiGenWinInfoPtr winInfo, + TuiWinElementPtr elementPtr) +#else +displayableWinContentOf (winInfo, elementPtr) + TuiGenWinInfoPtr winInfo; + TuiWinElementPtr elementPtr; +#endif +{ + + char *string = nullStr (); + + if (elementPtr != (TuiWinElementPtr) NULL || winInfo->type == LOCATOR_WIN) + { + /* + ** Now convert the line to a displayable string + */ + switch (winInfo->type) + { + case SRC_WIN: + case DISASSEM_WIN: + string = elementPtr->whichElement.source.line; + break; + case CMD_WIN: + string = elementPtr->whichElement.command.line; + break; + case LOCATOR_WIN: + if ((string = (char *) xmalloc ( + (termWidth () + 1) * sizeof (char))) == (char *) NULL) + string = nullStr (); + else + { + char lineNo[50], pc[50], buf[50], *fname, *pname; + register int strSize = termWidth (), i, procWidth, fileWidth; + + /* + ** First determine the amount of file/proc name width + ** we have available + */ + i = strSize - (PC_WIDTH + LINE_WIDTH + + 25 /* pc and line labels */ + + strlen (FILE_PREFIX) + 1 /* file label */ + + 15 /* procedure label */ ); + if (i >= FILE_WIDTH + PROC_WIDTH) + { + fileWidth = FILE_WIDTH; + procWidth = PROC_WIDTH; + } + else + { + fileWidth = i / 2; + procWidth = i - fileWidth; + } + + /* Now convert elements to string form */ + if (elementPtr != (TuiWinElementPtr) NULL && + *elementPtr->whichElement.locator.fileName != (char) 0 && + srcWin->generic.isVisible) + fname = elementPtr->whichElement.locator.fileName; + else + fname = "??"; + if (elementPtr != (TuiWinElementPtr) NULL && + *elementPtr->whichElement.locator.procName != (char) 0) + pname = elementPtr->whichElement.locator.procName; + else + pname = "??"; + if (elementPtr != (TuiWinElementPtr) NULL && + elementPtr->whichElement.locator.lineNo > 0) + sprintf (lineNo, "%d", + elementPtr->whichElement.locator.lineNo); + else + strcpy (lineNo, "??"); + if (elementPtr != (TuiWinElementPtr) NULL && + elementPtr->whichElement.locator.addr > (Opaque) 0) + sprintf (pc, "0x%x", + elementPtr->whichElement.locator.addr); + else + strcpy (pc, "??"); + /* + ** 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; + /* Filename */ + strcat_to_buf (string, strSize, " "); + strcat_to_buf (string, strSize, FILE_PREFIX); + if (strlen (fname) > fileWidth) + { + strncpy (buf, fname, fileWidth - 1); + buf[fileWidth - 1] = '*'; + buf[fileWidth] = (char) 0; + } + else + strcpy (buf, fname); + strcat_to_buf (string, strSize, buf); + /* procedure/class name */ + sprintf (buf, "%15s", PROC_PREFIX); + strcat_to_buf (string, strSize, buf); + if (strlen (pname) > procWidth) + { + strncpy (buf, pname, procWidth - 1); + buf[procWidth - 1] = '*'; + buf[procWidth] = (char) 0; + } + else + strcpy (buf, pname); + strcat_to_buf (string, strSize, buf); + sprintf (buf, "%10s", LINE_PREFIX); + strcat_to_buf (string, strSize, buf); + strcat_to_buf (string, strSize, lineNo); + sprintf (buf, "%10s", PC_PREFIX); + strcat_to_buf (string, strSize, buf); + strcat_to_buf (string, strSize, pc); + for (i = strlen (string); i < strSize; i++) + string[i] = ' '; + string[strSize] = (char) 0; + } + break; + case EXEC_INFO_WIN: + string = elementPtr->whichElement.simpleString; + break; + default: + break; + } + } + return string; +} /* displayableWinContentOf */ + + +/* +** winContentAt(). +** Answer a the content at the location indicated by index +*/ +char * +#ifdef __STDC__ +displayableWinContentAt ( + TuiGenWinInfoPtr winInfo, + int index) +#else +displayableWinContentAt (winInfo, index) + TuiGenWinInfoPtr winInfo; + int index; +#endif +{ + return (displayableWinContentOf (winInfo, (TuiWinElementPtr) winInfo->content[index])); +} /* winContentAt */ + + +/* +** winElementHeight(). +** Answer the height of the element in lines +*/ +int +#ifdef __STDC__ +winElementHeight ( + TuiGenWinInfoPtr winInfo, + TuiWinElementPtr element) +#else +winElementHeight (winInfo, element) + TuiGenWinInfoPtr winInfo; + TuiWinElementPtr element; +#endif +{ + int h; + + if (winInfo->type == DATA_WIN) +/* FOR NOW SAY IT IS ONLY ONE LINE HIGH */ + h = 1; + else + h = 1; + + return h; +} /* winElementHeight */ + + +/* +** winByName(). +** Answer the window represented by name +*/ +TuiWinInfoPtr +#ifdef __STDC__ +winByName ( + char *name) +#else +winByName (name) + char *name; +#endif +{ + TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL; + int i = 0; + + while (i < MAX_MAJOR_WINDOWS && m_winPtrIsNull (winInfo)) + { + if (strcmp (name, winName (&(winList[i]->generic))) == 0) + winInfo = winList[i]; + i++; + } + + return winInfo; +} /* winByName */ + + +/* +** partialWinByName(). +** Answer the window represented by name +*/ +TuiWinInfoPtr +#ifdef __STDC__ +partialWinByName ( + char *name) +#else +partialWinByName (name) + char *name; +#endif +{ + TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL; + + if (name != (char *) NULL) + { + int i = 0; + + while (i < MAX_MAJOR_WINDOWS && m_winPtrIsNull (winInfo)) + { + 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 * +#ifdef __STDC__ +winName ( + TuiGenWinInfoPtr winInfo) +#else +winName (winInfo) + TuiGenWinInfoPtr winInfo; +#endif +{ + 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 +#ifdef __STDC__ +initializeStaticData (void) +#else +initializeStaticData () +#endif +{ + initGenericPart (sourceExecInfoWinPtr ()); + initGenericPart (disassemExecInfoWinPtr ()); + initGenericPart (locatorWinInfoPtr ()); + + return; +} /* initializeStaticData */ + + +/* +** allocGenericWinInfo(). +*/ +TuiGenWinInfoPtr +#ifdef __STDC__ +allocGenericWinInfo (void) +#else +allocGenericWinInfo () +#endif +{ + TuiGenWinInfoPtr win; + + if ((win = (TuiGenWinInfoPtr) xmalloc ( + sizeof (TuiGenWinInfoPtr))) != (TuiGenWinInfoPtr) NULL) + initGenericPart (win); + + return win; +} /* allocGenericWinInfo */ + + +/* +** initGenericPart(). +*/ +void +#ifdef __STDC__ +initGenericPart ( + TuiGenWinInfoPtr win) +#else +initGenericPart (win) + TuiGenWinInfoPtr win; +#endif +{ + 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; + + return; +} /* initGenericPart */ + + +/* +** initContentElement(). +*/ +void +#ifdef __STDC__ +initContentElement ( + TuiWinElementPtr element, + TuiWinType type) +#else +initContentElement (element, type) + TuiWinElementPtr element; + TuiWinType type; +#endif +{ + 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: + element->whichElement.simpleString = blankStr (); + break; + default: + break; + } + return; +} /* initContentElement */ + +/* +** initWinInfo(). +*/ +void +#ifdef __STDC__ +initWinInfo ( + TuiWinInfoPtr winInfo) +#else +initWinInfo (winInfo) + TuiWinInfoPtr winInfo; +#endif +{ + 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 = (Opaque) NULL; + 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 +#ifdef __STDC__ +allocWinInfo ( + TuiWinType type) +#else +allocWinInfo (type) + TuiWinType type; +#endif +{ + 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 +#ifdef __STDC__ +allocContent ( + int numElements, + TuiWinType type) +#else +allocContent (numElements, type) + int numElements; + TuiWinType type; +#endif +{ + 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 +#ifdef __STDC__ +addContentElements ( + TuiGenWinInfoPtr winInfo, + int numElements) +#else +addContentElements (winInfo, numElements) + TuiGenWinInfoPtr winInfo; + int numElements; +#endif +{ + 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 */ + + +/* +** tuiDelWindow(). +** Delete all curses windows associated with winInfo, leaving everything +** else in tact. +*/ +void +#ifdef __STDC__ +tuiDelWindow ( + TuiWinInfoPtr winInfo) +#else +tuiDelWindow (winInfo) + TuiWinInfoPtr winInfo; +#endif +{ + Opaque detail; + int i; + 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; + } + 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) + { + int i; + + 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; + } + + return; +} /* tuiDelWindow */ + + +/* +** freeWindow(). +*/ +void +#ifdef __STDC__ +freeWindow ( + TuiWinInfoPtr winInfo) +#else +freeWindow (winInfo) + TuiWinInfoPtr winInfo; +#endif +{ + Opaque detail; + int i; + 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); + 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); + } + free (winInfo); + + return; +} /* freeWindow */ + + +/* +** freeAllSourceWinsContent(). +*/ +void +#ifdef __STDC__ +freeAllSourceWinsContent (void) +#else +freeAllSourceWinsContent () +#endif +{ + 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 +#ifdef __STDC__ +freeWinContent ( + TuiGenWinInfoPtr winInfo) +#else +freeWinContent (winInfo) + TuiGenWinInfoPtr winInfo; +#endif +{ + if (winInfo->content != (OpaquePtr) NULL) + { + freeContent ((TuiWinContent) winInfo->content, + winInfo->contentSize, + winInfo->type); + winInfo->content = (OpaquePtr) NULL; + } + winInfo->contentSize = 0; + + return; +} /* freeWinContent */ + + +/* +** freeAllWindows(). +*/ +void +#ifdef __STDC__ +freeAllWindows (void) +#else +freeAllWindows () +#endif +{ + TuiWinType type = SRC_WIN; + + for (; type < MAX_MAJOR_WINDOWS; type++) + if (m_winPtrNotNull (winList[type]) && + winList[type]->generic.type != UNDEFINED_WIN) + freeWindow (winList[type]); + return; +} /* freeAllWindows */ + + +void +#ifdef __STDC__ +tuiDelDataWindows ( + TuiWinContent content, + int contentSize) +#else +tuiDelDataWindows (content, contentSize) + TuiWinContent content; + int contentSize; +#endif +{ + 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 +#ifdef __STDC__ +freeDataContent ( + TuiWinContent content, + int contentSize) +#else +freeDataContent (content, contentSize) + TuiWinContent content; + int contentSize; +#endif +{ + 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 +#ifdef __STDC__ +freeContent ( + TuiWinContent content, + int contentSize, + TuiWinType winType) +#else +freeContent (content, contentSize, winType) + TuiWinContent content; + int contentSize; + TuiWinType winType; +#endif +{ + if (content != (TuiWinContent) NULL) + { + freeContentElements (content, contentSize, winType); + tuiFree ((char *) content); + } + + return; +} /* freeContent */ + + +/* +** freeContentElements(). +*/ +static void +#ifdef __STDC__ +freeContentElements ( + TuiWinContent content, + int contentSize, + TuiWinType type) +#else +freeContentElements (content, contentSize, type) + TuiWinContent content; + int contentSize; + TuiWinType type; +#endif +{ + 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/tuiData.h b/gdb/tui/tuiData.h new file mode 100644 index 00000000000..bb4d19c90e2 --- /dev/null +++ b/gdb/tui/tuiData.h @@ -0,0 +1,302 @@ +#ifndef TUI_DATA_H +#define TUI_DATA_H + +/* 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 + +#define FILE_PREFIX "File: " +#define PROC_PREFIX "Procedure: " +#define LINE_PREFIX "Line: " +#define PC_PREFIX "pc: " + +#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 { + 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 { + 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 _TuiRegisterDisplayType { + 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; + Opaque 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 +{ + 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; + Opaque addr; +} TuiLocatorElement, *TuiLocatorElementPtr; + + +/* 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 */ + char *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; +} TuiSourceInfo, *TuiSourceInfoPtr; + + +typedef struct _TuiCommandInfo { + int curLine; /* The current line position */ + int curch; /* The current cursor position */ +} 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]; +extern int tui_version; + +/* 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 PARAMS ((void)); +extern TuiGenWinInfoPtr allocGenericWinInfo PARAMS ((void)); +extern TuiWinInfoPtr allocWinInfo PARAMS ((TuiWinType)); +extern void initGenericPart PARAMS ((TuiGenWinInfoPtr)); +extern void initWinInfo PARAMS ((TuiWinInfoPtr)); +extern TuiWinContent allocContent PARAMS ((int, TuiWinType)); +extern int addContentElements + PARAMS ((TuiGenWinInfoPtr, int)); +extern void initContentElement + PARAMS ((TuiWinElementPtr, TuiWinType)); +extern void freeWindow PARAMS ((TuiWinInfoPtr)); +extern void freeAllWindows PARAMS ((void)); +extern void freeWinContent PARAMS ((TuiGenWinInfoPtr)); +extern void freeDataContent PARAMS ((TuiWinContent, int)); +extern void freeAllSourceWinsContent PARAMS ((void)); +extern void tuiDelWindow PARAMS ((TuiWinInfoPtr)); +extern void tuiDelDataWindows PARAMS ((TuiWinContent, int)); +extern TuiWinInfoPtr winByName PARAMS ((char *)); +extern TuiWinInfoPtr partialWinByName PARAMS ((char *)); +extern char *winName PARAMS ((TuiGenWinInfoPtr)); +extern char *displayableWinContentOf + PARAMS ((TuiGenWinInfoPtr, TuiWinElementPtr)); +extern char *displayableWinContentAt + PARAMS ((TuiGenWinInfoPtr, int)); +extern int winElementHeight + PARAMS ((TuiGenWinInfoPtr, TuiWinElementPtr)); +extern TuiLayoutType currentLayout PARAMS ((void)); +extern void setCurrentLayoutTo PARAMS ((TuiLayoutType)); +extern int termHeight PARAMS ((void)); +extern void setTermHeight PARAMS ((int)); +extern int termWidth PARAMS ((void)); +extern void setTermWidth PARAMS ((int)); +extern int historyLimit PARAMS ((void)); +extern void setHistoryLimit PARAMS ((int)); +extern void setGenWinOrigin PARAMS ((TuiGenWinInfoPtr, int, int)); +extern TuiGenWinInfoPtr locatorWinInfoPtr PARAMS ((void)); +extern TuiGenWinInfoPtr sourceExecInfoWinPtr PARAMS ((void)); +extern TuiGenWinInfoPtr disassemExecInfoWinPtr PARAMS ((void)); +extern char *nullStr PARAMS ((void)); +extern char *blankStr PARAMS ((void)); +extern char *locationStr PARAMS ((void)); +extern char *breakStr PARAMS ((void)); +extern char *breakLocationStr PARAMS ((void)); +extern TuiListPtr sourceWindows PARAMS ((void)); +extern void clearSourceWindows PARAMS ((void)); +extern void clearSourceWindowsDetail PARAMS ((void)); +extern void clearWinDetail PARAMS ((TuiWinInfoPtr winInfo)); +extern void tuiAddToSourceWindows PARAMS ((TuiWinInfoPtr)); +extern int tuiDefaultTabLen PARAMS ((void)); +extern void tuiSetDefaultTabLen PARAMS ((int)); +extern TuiWinInfoPtr tuiWinWithFocus PARAMS ((void)); +extern void tuiSetWinWithFocus PARAMS ((TuiWinInfoPtr)); +extern TuiLayoutDefPtr tuiLayoutDef PARAMS ((void)); +extern int tuiWinResized PARAMS ((void)); +extern void tuiSetWinResizedTo PARAMS ((int)); + +extern TuiWinInfoPtr tuiNextWin PARAMS ((TuiWinInfoPtr)); +extern TuiWinInfoPtr tuiPrevWin PARAMS ((TuiWinInfoPtr)); + + +#endif /* TUI_DATA_H */ diff --git a/gdb/tui/tuiDataWin.c b/gdb/tui/tuiDataWin.c new file mode 100644 index 00000000000..522730ae2fd --- /dev/null +++ b/gdb/tui/tuiDataWin.c @@ -0,0 +1,400 @@ +/* +** tuiDataWin.c +** This module contains functions to support the data/register window display. +*/ + + +#include "defs.h" +#include "tui.h" +#include "tuiData.h" +#include "tuiRegs.h" + + +/***************************************** +** STATIC LOCAL FUNCTIONS FORWARD DECLS ** +******************************************/ + + + +/***************************************** +** PUBLIC FUNCTIONS ** +******************************************/ + + +/* +** tuiFirstDataItemDisplayed() +** Answer the index first element displayed. +** If none are displayed, then return (-1). +*/ +int +#ifdef __STDC__ +tuiFirstDataItemDisplayed (void) +#else +tuiFirstDataItemDisplayed () +#endif +{ + 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 +#ifdef __STDC__ +tuiFirstDataElementNoInLine ( + int lineNo) +#else +tuiFirstDataElementNoInLine (lineNo) + int lineNo; +#endif +{ + int firstElementNo = (-1); + + /* + ** First see if there is a register on lineNo, and if so, set the + ** first element number + */ + if ((firstElementNo = tuiFirstRegElementNoInLine (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 +#ifdef __STDC__ +tuiDeleteDataContentWindows (void) +#else +tuiDeleteDataContentWindows () +#endif +{ + 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 +#ifdef __STDC__ +tuiEraseDataContent ( + char *prompt) +#else +tuiEraseDataContent (prompt) + char *prompt; +#endif +{ + 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 +#ifdef __STDC__ +tuiDisplayAllData (void) +#else +tuiDisplayAllData () +#endif +{ + if (dataWin->generic.contentSize <= 0) + tuiEraseDataContent (NO_DATA_STRING); + else + { + tuiEraseDataContent ((char *) NULL); + tuiDeleteDataContentWindows (); + checkAndDisplayHighlightIfNeeded (dataWin); + tuiDisplayRegistersFrom (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 +#ifdef __STDC__ +tuiDisplayDataFromLine ( + int lineNo) +#else +tuiDisplayDataFromLine (lineNo) + int lineNo; +#endif +{ + 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) + tuiDisplayRegistersFromLine (_lineNo, TRUE); + else + { + int elementNo, startLineNo; + int regsLastLine = tuiLastRegsLineNo (); + + + /* display regs if we can */ + if (tuiDisplayRegistersFromLine (_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 +#ifdef __STDC__ +tuiDisplayDataFrom ( + int elementNo, + int reuseWindows) +#else +tuiDisplayDataFrom (elementNo, reuseWindows) + int elementNo; + int reuseWindows; +#endif +{ + int firstLine = (-1); + + if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount) + firstLine = tuiLineFromRegElementNo (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 +#ifdef __STDC__ +tuiRefreshDataWin (void) +#else +tuiRefreshDataWin () +#endif +{ + 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 +#ifdef __STDC__ +tuiCheckDataValues ( + struct frame_info *frame) +#else +tuiCheckDataValues (frame) + struct frame_info *frame; +#endif +{ + tuiCheckRegisterValues (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 */ + + +/* +** tui_vCheckDataValues(). +** Function to check the data values and hilite any that have +** changed with args in a va_list +*/ +void +#ifdef __STDC__ +tui_vCheckDataValues ( + va_list args) +#else +tui_vCheckDataValues (args) + va_list args; +#endif +{ + struct frame_info *frame = va_arg (args, struct frame_info *); + + tuiCheckDataValues (frame); + + return; +} /* tui_vCheckDataValues */ + + +/* +** tuiVerticalDataScroll() +** Scroll the data window vertically forward or backward. +*/ +void +#ifdef __STDC__ +tuiVerticalDataScroll ( + TuiScrollDirection scrollDirection, + int numToScroll) +#else +tuiVerticalDataScroll (scrollDirection, numToScroll) + TuiScrollDirection scrollDirection; + int numToScroll; +#endif +{ + int firstElementNo; + int firstLine = (-1); + + firstElementNo = tuiFirstDataItemDisplayed (); + if (firstElementNo < dataWin->detail.dataDisplayInfo.regsContentCount) + firstLine = tuiLineFromRegElementNo (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/tuiDataWin.h b/gdb/tui/tuiDataWin.h new file mode 100644 index 00000000000..8f9e46d80e7 --- /dev/null +++ b/gdb/tui/tuiDataWin.h @@ -0,0 +1,29 @@ +#ifndef _TUI_DATAWIN_H +#define _TUI_DATAWIN_H +/* +** This header file supports the display of registers/data in the data window. +*/ + + +/***************************************** +** TYPE DEFINITIONS ** +******************************************/ + + + +/***************************************** +** PUBLIC FUNCTION EXTERNAL DECLS ** +******************************************/ +extern void tuiEraseDataContent PARAMS ((char *)); +extern void tuiDisplayAllData PARAMS ((void)); +extern void tuiCheckDataValues PARAMS ((struct frame_info *)); +extern void tui_vCheckDataValues PARAMS ((va_list)); +extern void tuiDisplayDataFromLine PARAMS ((int)); +extern int tuiFirstDataItemDisplayed PARAMS ((void)); +extern int tuiFirstDataElementNoInLine PARAMS ((int)); +extern void tuiDeleteDataContentWindows PARAMS ((void)); +extern void tuiRefreshDataWin PARAMS ((void)); +extern void tuiDisplayDataFrom PARAMS ((int, int)); +extern void tuiVerticalDataScroll PARAMS ((TuiScrollDirection, int)); + +#endif /*_TUI_DATAWIN_H*/ diff --git a/gdb/tui/tuiDisassem.c b/gdb/tui/tuiDisassem.c new file mode 100644 index 00000000000..ad0b70f655d --- /dev/null +++ b/gdb/tui/tuiDisassem.c @@ -0,0 +1,343 @@ +/* +** tuiDisassem.c +** This module contains functions for handling disassembly display. +*/ + + +#include "defs.h" +#include "symtab.h" +#include "breakpoint.h" +#include "frame.h" + +#include "tui.h" +#include "tuiData.h" +#include "tuiLayout.h" +#include "tuiSourceWin.h" +#include "tuiStack.h" + + +/***************************************** +** STATIC LOCAL FUNCTIONS FORWARD DECLS ** +******************************************/ + +static struct breakpoint *_hasBreak PARAMS ((CORE_ADDR)); + + +/***************************************** +** PUBLIC FUNCTIONS ** +******************************************/ + +/* +** tuiSetDisassemContent(). +** Function to set the disassembly window's content. +*/ +TuiStatus +#ifdef __STDC__ +tuiSetDisassemContent ( + struct symtab *s, + Opaque startAddr) +#else + tuiSetDisassemContent (s, startAddr) + struct symtab *s; + Opaque startAddr; +#endif +{ + TuiStatus ret = TUI_FAILURE; + GDB_FILE *gdb_dis_out; + + if (startAddr != (Opaque) NULL) + { + register int i, desc; + + if ((ret = tuiAllocSourceBuffer (disassemWin)) == TUI_SUCCESS) + { + register int offset = disassemWin->detail.sourceInfo.horizontalOffset; + register int threshold, curLine = 0, lineWidth, maxLines; + CORE_ADDR newpc, pc; + disassemble_info asmInfo; + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + extern void strcat_address PARAMS ((CORE_ADDR, char *, int)); + extern void strcat_address_numeric PARAMS ((CORE_ADDR, int, char *, int)); + int curLen = 0; + int tab_len = tuiDefaultTabLen (); + + maxLines = disassemWin->generic.height - 2; /* account for hilite */ + lineWidth = disassemWin->generic.width - 1; + threshold = (lineWidth - 1) + offset; + + /* now init the gdb_file structure */ + gdb_dis_out = gdb_file_init_astring (threshold); + + INIT_DISASSEMBLE_INFO_NO_ARCH (asmInfo, gdb_dis_out, (fprintf_ftype) fprintf_filtered); + asmInfo.read_memory_func = dis_asm_read_memory; + asmInfo.memory_error_func = dis_asm_memory_error; + + disassemWin->detail.sourceInfo.startLineOrAddr.addr = startAddr; + + /* Now construct each line */ + for (curLine = 0, pc = (CORE_ADDR) startAddr; (curLine < maxLines);) + { + TuiWinElementPtr element = (TuiWinElementPtr)disassemWin->generic.content[curLine]; + struct breakpoint *bp; + + print_address (pc, gdb_dis_out); + + curLen = strlen (gdb_file_get_strbuf (gdb_dis_out)); + i = curLen - ((curLen / tab_len) * tab_len); + + /* adjust buffer length if necessary */ + gdb_file_adjust_strbuf ((tab_len - i > 0) ? (tab_len - i ) : 0, gdb_dis_out); + + /* Add spaces to make the instructions start onthe same column */ + while (i < tab_len) + { + gdb_file_get_strbuf (gdb_dis_out)[curLen] = ' '; + i++; + curLen++; + } + gdb_file_get_strbuf (gdb_dis_out)[curLen] = '\0'; + + newpc = pc + ((*tm_print_insn) (pc, &asmInfo)); + + /* Now copy the line taking the offset into account */ + if (strlen (gdb_file_get_strbuf (gdb_dis_out)) > offset) + strcpy (element->whichElement.source.line, + &(gdb_file_get_strbuf (gdb_dis_out)[offset])); + else + element->whichElement.source.line[0] = '\0'; + element->whichElement.source.lineOrAddr.addr = (Opaque) pc; + element->whichElement.source.isExecPoint = + (pc == (CORE_ADDR) ((TuiWinElementPtr)locator->content[0])->whichElement.locator.addr); + bp = _hasBreak (pc); + element->whichElement.source.hasBreak = + (bp != (struct breakpoint *) NULL && + (!element->whichElement.source.isExecPoint || + (bp->disposition != del || bp->hit_count <= 0))); + curLine++; + pc = newpc; + /* reset the buffer to empty */ + gdb_file_get_strbuf (gdb_dis_out)[0] = '\0'; + } + gdb_file_deallocate (&gdb_dis_out); + disassemWin->generic.contentSize = curLine; + ret = TUI_SUCCESS; + } + } + + return ret; +} /* tuiSetDisassemContent */ + + +/* +** tuiShowDisassem(). +** Function to display the disassembly window with disassembled code. +*/ +void +#ifdef __STDC__ +tuiShowDisassem ( + Opaque startAddr) +#else +tuiShowDisassem (startAddr) + Opaque startAddr; +#endif +{ + struct symtab *s = find_pc_symtab ((CORE_ADDR) startAddr); + TuiWinInfoPtr winWithFocus = tuiWinWithFocus (); + + tuiAddWinToLayout (DISASSEM_WIN); + tuiUpdateSourceWindow (disassemWin, s, startAddr, 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; +} /* tuiShowDisassem */ + + +/* +** tuiShowDisassemAndUpdateSource(). +** Function to display the disassembly window. +*/ +void +#ifdef __STDC__ +tuiShowDisassemAndUpdateSource ( + Opaque startAddr) +#else +tuiShowDisassemAndUpdateSource (startAddr) + Opaque startAddr; +#endif +{ + struct symtab_and_line sal; + + tuiShowDisassem (startAddr); + if (currentLayout () == SRC_DISASSEM_COMMAND) + { + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + /* + ** 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 ((CORE_ADDR) startAddr, 0); + current_source_symtab = sal.symtab; + tuiUpdateSourceWindow (srcWin, sal.symtab, (Opaque) sal.line, TRUE); + tuiUpdateLocatorFilename (sal.symtab->filename); + } + + return; +} /* tuiShowDisassemAndUpdateSource */ + + +/* +** tuiShowDisassemAsIs(). +** Function to display the disassembly window. This function shows +** the disassembly as specified by the horizontal offset. +*/ +void +#ifdef __STDC__ +tuiShowDisassemAsIs ( + Opaque addr) +#else +tuiShowDisassemAsIs (addr) + Opaque addr; +#endif +{ + tuiAddWinToLayout (DISASSEM_WIN); + tuiUpdateSourceWindowAsIs (disassemWin, (struct symtab *) NULL, addr, FALSE); + /* + ** Update what is in the source window if it is displayed too, not that it + ** follows what is in the disassembly window and visa-versa + */ + if (currentLayout () == SRC_DISASSEM_COMMAND) + tuiShowSourceContent (srcWin); /*???? Need to do more? */ + + return; +} /* tuiShowDisassem */ + + +/* +** tuiGetBeginAsmAddress(). +*/ +Opaque +#ifdef __STDC__ +tuiGetBeginAsmAddress (void) +#else +tuiGetBeginAsmAddress () +#endif +{ + TuiGenWinInfoPtr locator; + TuiLocatorElementPtr element; + Opaque addr; + + locator = locatorWinInfoPtr (); + element = &((TuiWinElementPtr) locator->content[0])->whichElement.locator; + + if (element->addr == (Opaque) 0) + { + /*the target is not executing, because the pc is 0*/ + + addr = (Opaque) parse_and_eval_address ("main"); + + if (addr == (Opaque) 0) + addr = (Opaque) parse_and_eval_address ("MAIN"); + + } + else /* the target is executing */ + addr = element->addr; + + return addr; +} /* tuiGetBeginAsmAddress */ + + +/* +** tuiVerticalDisassemScroll(). +** Scroll the disassembly forward or backward vertically +*/ +void +#ifdef __STDC__ +tuiVerticalDisassemScroll ( + TuiScrollDirection scrollDirection, + int numToScroll) +#else +tuiVerticalDisassemScroll (scrollDirection, numToScroll) + TuiScrollDirection scrollDirection; + int numToScroll; +#endif +{ + if (disassemWin->generic.content != (OpaquePtr) NULL) + { + Opaque pc, lowAddr; + TuiWinContent content; + struct symtab *s; + + content = (TuiWinContent) disassemWin->generic.content; + if (current_source_symtab == (struct symtab *) NULL) + s = find_pc_symtab (selected_frame->pc); + else + s = current_source_symtab; + + pc = content[0]->whichElement.source.lineOrAddr.addr; + if (find_pc_partial_function ((CORE_ADDR) pc, + (char **) NULL, + (CORE_ADDR *) & lowAddr, + (CORE_ADDR) NULL) == 0) + error ("No function contains prgram counter for selected frame.\n"); + else + { + register int line = 0; + register Opaque newLow; + bfd_byte buffer[4]; + + newLow = pc; + if (scrollDirection == FORWARD_SCROLL) + { + for (; line < numToScroll; line++) + newLow += sizeof (bfd_getb32 (buffer)); + } + else + { + for (; newLow >= (Opaque) 0 && line < numToScroll; line++) + newLow -= sizeof (bfd_getb32 (buffer)); + } + tuiUpdateSourceWindowAsIs (disassemWin, s, newLow, FALSE); + } + } + + return; +} /* tuiVerticalDisassemScroll */ + + + +/***************************************** +** STATIC LOCAL FUNCTIONS ** +******************************************/ +/* +** _hasBreak(). +** Answer whether there is a break point at the input line in the +** source file indicated +*/ +static struct breakpoint * +#ifdef __STDC__ +_hasBreak ( + CORE_ADDR addr) +#else +_hasBreak (addr) + CORE_ADDR addr; +#endif +{ + struct breakpoint *bpWithBreak = (struct breakpoint *) NULL; + struct breakpoint *bp; + extern struct breakpoint *breakpoint_chain; + + + for (bp = breakpoint_chain; + (bp != (struct breakpoint *) NULL && + bpWithBreak == (struct breakpoint *) NULL); + bp = bp->next) + if (addr == bp->address) + bpWithBreak = bp; + + return bpWithBreak; +} /* _hasBreak */ diff --git a/gdb/tui/tuiDisassem.h b/gdb/tui/tuiDisassem.h new file mode 100644 index 00000000000..711ac48587d --- /dev/null +++ b/gdb/tui/tuiDisassem.h @@ -0,0 +1,22 @@ +#ifndef _TUI_DISASSEM_H +#define _TUI_DISASSEM_H +/* +** This header file supports +*/ + +/***************************************** +** TYPE DEFINITIONS ** +******************************************/ + + + +/***************************************** +** PUBLIC FUNCTION EXTERNAL DECLS ** +******************************************/ +extern TuiStatus tuiSetDisassemContent PARAMS ((struct symtab *, Opaque)); +extern void tuiShowDisassem PARAMS ((Opaque)); +extern void tuiShowDisassemAndUpdateSource PARAMS ((Opaque)); +extern void tuiVerticalDisassemScroll PARAMS ((TuiScrollDirection, int)); +extern Opaque tuiGetBeginAsmAddress PARAMS ((void)); + +#endif /*_TUI_DISASSEM_H*/ diff --git a/gdb/tui/tuiGeneralWin.c b/gdb/tui/tuiGeneralWin.c new file mode 100644 index 00000000000..5af0cd7a92e --- /dev/null +++ b/gdb/tui/tuiGeneralWin.c @@ -0,0 +1,469 @@ +/* +** TuiGeneralWin.c +** This module supports general window behavior +*/ + +#include +#include "defs.h" +#include "tui.h" +#include "tuiData.h" +#include "tuiGeneralWin.h" + + +/* +** local support functions +*/ +static void _winResize PARAMS ((void)); + + +/*********************** +** PUBLIC FUNCTIONS +***********************/ +/* +** tuiRefreshWin() +** Refresh the window +*/ +void +#ifdef __STDC__ +tuiRefreshWin ( + TuiGenWinInfoPtr winInfo) +#else +tuiRefreshWin (winInfo) + TuiGenWinInfoPtr winInfo; +#endif +{ + 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 +#ifdef __STDC__ +tuiDelwin ( + WINDOW * window) +#else +tuiDelwin (window) + WINDOW *window; +#endif +{ + if (window != (WINDOW *) NULL) + delwin (window); + + return; +} /* tuiDelwin */ + + +/* +** boxWin(). +*/ +void +#ifdef __STDC__ +boxWin ( + TuiGenWinInfoPtr winInfo, + int highlightFlag) +#else +boxWin (winInfo, highlightFlag) + TuiGenWinInfoPtr winInfo; + int highlightFlag; +#endif +{ + if (m_genWinPtrNotNull (winInfo) && winInfo->handle != (WINDOW *) NULL) + { + if (highlightFlag == HILITE) + box (winInfo->handle, '|', '-'); + else + { +/* wattron(winInfo->handle, A_DIM);*/ + box (winInfo->handle, ':', '.'); +/* wattroff(winInfo->handle, A_DIM);*/ + } + } + + return; +} /* boxWin */ + + +/* +** unhighlightWin(). +*/ +void +#ifdef __STDC__ +unhighlightWin ( + TuiWinInfoPtr winInfo) +#else +unhighlightWin (winInfo) + TuiWinInfoPtr winInfo; +#endif +{ + if (m_winPtrNotNull (winInfo) && winInfo->generic.handle != (WINDOW *) NULL) + { + boxWin ((TuiGenWinInfoPtr) winInfo, NO_HILITE); + wrefresh (winInfo->generic.handle); + m_setWinHighlightOff (winInfo); + } +} /* unhighlightWin */ + + +/* +** highlightWin(). +*/ +void +#ifdef __STDC__ +highlightWin ( + TuiWinInfoPtr winInfo) +#else +highlightWin (winInfo) + TuiWinInfoPtr winInfo; +#endif +{ + 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 +#ifdef __STDC__ +checkAndDisplayHighlightIfNeeded ( + TuiWinInfoPtr winInfo) +#else +checkAndDisplayHighlightIfNeeded (winInfo) + TuiWinInfoPtr winInfo; +#endif +{ + if (m_winPtrNotNull (winInfo) && winInfo->generic.type != CMD_WIN) + { + if (winInfo->isHighlighted) + highlightWin (winInfo); + else + unhighlightWin (winInfo); + + } + return; +} /* checkAndDisplayHighlightIfNeeded */ + + +/* +** makeWindow(). +*/ +void +#ifdef __STDC__ +makeWindow ( + TuiGenWinInfoPtr winInfo, + int boxIt) +#else +makeWindow (winInfo, boxIt) + TuiGenWinInfoPtr winInfo; + int boxIt; +#endif +{ + 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); + tuiRefreshWin (winInfo); + +#ifndef FOR_TEST + if ( /*!m_WinIsAuxillary(winInfo->type) && */ + (winInfo->type != CMD_WIN) && + (winInfo->content == (OpaquePtr) NULL)) + { + mvwaddstr (handle, 1, 1, winName (winInfo)); + tuiRefreshWin (winInfo); + } +#endif /*FOR_TEST*/ + } + + return; +} /* makeWindow */ + + +/* +** tuiClearWin(). +** Clear the window of all contents without calling wclear. +*/ +void +#ifdef __STDC__ +tuiClearWin ( + TuiGenWinInfoPtr winInfo) +#else +tuiClearWin (winInfo) + TuiGenWinInfoPtr winInfo; +#endif +{ + if (m_genWinPtrNotNull (winInfo) && winInfo->handle != (WINDOW *) NULL) + { + int curRow, curCol; + + for (curRow = 0; (curRow < winInfo->height); curRow++) + for (curCol = 0; (curCol < winInfo->width); curCol++) + mvwaddch (winInfo->handle, curRow, curCol, ' '); + + tuiRefreshWin (winInfo); + } + + return; +} /* tuiClearWin */ + + +/* +** 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 +#ifdef __STDC__ +makeVisible ( + TuiGenWinInfoPtr winInfo, + int visible) +#else +makeVisible (winInfo, visible) + TuiGenWinInfoPtr winInfo; + int visible; +#endif +{ + /* 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; + } + tuiRefreshWin (winInfo); + } + else if (!visible && + winInfo->isVisible && winInfo->handle != (WINDOW *) NULL) + { + winInfo->isVisible = FALSE; + tuiClearWin (winInfo); + tuiDelwin (winInfo->handle); + winInfo->handle = (WINDOW *) NULL; + } + + return; +} /* makeVisible */ + + +/* +** makeAllVisible(). +** Makes all windows invisible (except the command and locator windows) +*/ +void +#ifdef __STDC__ +makeAllVisible ( + int visible) +#else +makeAllVisible (visible) + int visible; +#endif +{ + 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 */ + + +/* +** scrollWinForward +*/ +void +#ifdef __STDC__ +scrollWinForward ( + TuiGenWinInfoPtr winInfo, + int numLines) +#else +scrollWinForward (winInfo, numLines) + TuiGenWinInfoPtr winInfo; + int numLines; +#endif +{ + if (winInfo->content != (OpaquePtr) NULL && + winInfo->lastVisibleLine < winInfo->contentSize - 1) + { + int i, firstLine, newLastLine; + + firstLine = winInfo->lastVisibleLine - winInfo->viewportHeight + 1; + if (winInfo->lastVisibleLine + numLines > winInfo->contentSize) + newLastLine = winInfo->contentSize - 1; + else + newLastLine = winInfo->lastVisibleLine + numLines - 1; + + for (i = (newLastLine - winInfo->viewportHeight); + (i <= newLastLine); i++) + { + TuiWinElementPtr line; + int lineHeight; + + line = (TuiWinElementPtr) winInfo->content[i]; + if (line->highlight) + wstandout (winInfo->handle); + mvwaddstr (winInfo->handle, + i - (newLastLine - winInfo->viewportHeight), + 1, + displayableWinContentOf (winInfo, line)); + if (line->highlight) + wstandend (winInfo->handle); + lineHeight = winElementHeight (winInfo, line); + newLastLine += (lineHeight - 1); + } + winInfo->lastVisibleLine = newLastLine; + } + + return; +} /* scrollWinForward */ + + +/* +** scrollWinBackward +*/ +void +#ifdef __STDC__ +scrollWinBackward ( + TuiGenWinInfoPtr winInfo, + int numLines) +#else +scrollWinBackward (winInfo, numLines) + TuiGenWinInfoPtr winInfo; + int numLines; +#endif +{ + if (winInfo->content != (OpaquePtr) NULL && + (winInfo->lastVisibleLine - winInfo->viewportHeight) > 0) + { + int i, newLastLine, firstLine; + + firstLine = winInfo->lastVisibleLine - winInfo->viewportHeight + 1; + if ((firstLine - numLines) < 0) + newLastLine = winInfo->viewportHeight - 1; + else + newLastLine = winInfo->lastVisibleLine - numLines + 1; + + for (i = newLastLine - winInfo->viewportHeight; (i <= newLastLine); i++) + { + TuiWinElementPtr line; + int lineHeight; + + line = (TuiWinElementPtr) winInfo->content[i]; + if (line->highlight) + wstandout (winInfo->handle); + mvwaddstr (winInfo->handle, + i - (newLastLine - winInfo->viewportHeight), + 1, + displayableWinContentOf (winInfo, line)); + if (line->highlight) + wstandend (winInfo->handle); + lineHeight = winElementHeight (winInfo, line); + newLastLine += (lineHeight - 1); + } + winInfo->lastVisibleLine = newLastLine; + } + + return; +} /* scrollWinBackward */ + + +/* +** refreshAll(). +** Function to refresh all the windows currently displayed +*/ +void +#ifdef __STDC__ +refreshAll ( + TuiWinInfoPtr * list) +#else +refreshAll (list) + TuiWinInfoPtr *list; +#endif +{ + TuiWinType type; + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + + for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++) + { + if (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/tuiGeneralWin.h b/gdb/tui/tuiGeneralWin.h new file mode 100644 index 00000000000..559f8ab3339 --- /dev/null +++ b/gdb/tui/tuiGeneralWin.h @@ -0,0 +1,31 @@ +#ifndef TUI_GENERAL_WIN_H +#define TUI_GENERAL_WIN_H + +/* +** Functions +*/ +extern void tuiClearWin PARAMS ((TuiGenWinInfoPtr)); +extern void unhighlightWin PARAMS ((TuiWinInfoPtr)); +extern void makeVisible PARAMS ((TuiGenWinInfoPtr, int)); +extern void makeAllVisible PARAMS ((int)); +extern void scrollWinForward PARAMS ((TuiGenWinInfoPtr, int)); +extern void scrollWinBackward PARAMS ((TuiGenWinInfoPtr, int)); +extern void makeWindow PARAMS ((TuiGenWinInfoPtr, int)); +extern TuiWinInfoPtr copyWin PARAMS ((TuiWinInfoPtr)); +extern void boxWin PARAMS ((TuiGenWinInfoPtr, int)); +extern void highlightWin PARAMS ((TuiWinInfoPtr)); +extern void checkAndDisplayHighlightIfNeeded PARAMS ((TuiWinInfoPtr)); +extern void refreshAll PARAMS ((TuiWinInfoPtr *)); +extern void tuiDelwin PARAMS ((WINDOW *window)); +extern void tuiRefreshWin PARAMS ((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/tuiIO.c b/gdb/tui/tuiIO.c new file mode 100644 index 00000000000..29a3613f968 --- /dev/null +++ b/gdb/tui/tuiIO.c @@ -0,0 +1,734 @@ + +/* +** This module contains functions to support i/o in the TUI +*/ + + +#include +#include "defs.h" +#include "terminal.h" +#include "tui.h" +#include "tuiData.h" +#include "tuiIO.h" +#include "tuiCommand.h" +#include "tuiWin.h" + +#ifdef ANSI_PROTOTYPES +#include +#else +#include +#endif + +/* The Solaris header files seem to provide no declaration for this at + all when __STDC__ is defined. This shouldn't conflict with + anything. */ +extern char *tgoto (); + +int insert_mode = 0; + +/******************************************** +** LOCAL STATIC FORWARD DECLS ** +********************************************/ +static void _updateCommandInfo PARAMS ((int)); +static unsigned int _tuiHandleResizeDuringIO PARAMS ((unsigned int)); + + +/********************************************************************************* +** PUBLIC FUNCTIONS ** +*********************************************************************************/ + +/* +** tuiPuts_unfiltered(). +** Function to put a string to the command window +** When running in TUI mode, this is the "hook" +** for fputs_unfiltered(). That is, all debugger +** output eventually makes it's way to the bottom-level +** routine fputs_unfiltered (main.c), which (in TUI +** mode), calls tuiPuts_unfiltered(). +*/ +void +#ifdef __STDC__ +tuiPuts_unfiltered ( + const char *string, + GDB_FILE * stream) +#else +tuiPuts_unfiltered (string, stream) + char *string; + GDB_FILE *stream; +#endif +{ + int len = strlen (string); + int i, linech; + + for (i = 0; i < len; i++) + { + if (string[i] == '\n' || string[i] == '\r') + m_tuiStartNewLine; + else + { + if ((cmdWin->detail.commandInfo.curch + 1) > cmdWin->generic.width) + m_tuiStartNewLine; + + if (insert_mode) + { + mvwinsch (cmdWin->generic.handle, + cmdWin->detail.commandInfo.curLine, + cmdWin->detail.commandInfo.curch++, + string[i]); + wmove (cmdWin->generic.handle, + cmdWin->detail.commandInfo.curLine, + cmdWin->detail.commandInfo.curch); + } + else + mvwaddch (cmdWin->generic.handle, + cmdWin->detail.commandInfo.curLine, + cmdWin->detail.commandInfo.curch++, + string[i]); + } + } + tuiRefreshWin (&cmdWin->generic); + + return; +} /* tuiPuts_unfiltered */ + +/* A cover routine for tputs(). + * tputs() is called from the readline package to put + * out strings representing cursor positioning. + * In TUI mode (non-XDB-style), tui_tputs() is called instead. + * + * The reason we need to hook tputs() is: + * Since the output is going to curses and not to + * a raw terminal, we need to intercept these special + * sequences, and handle them them here. + * + * This function seems to be correctly handling all sequences + * aimed at hpterm's, but there is additional work to do + * for xterm's and dtterm's. I abandoned further work on this + * in favor of "XDB style". In "XDB style", the command region + * looks like terminal, not a curses window, and this routine + * is not called. - RT + */ +void +tui_tputs (str, affcnt, putfunc) + char *str; + int affcnt; + int (*putfunc) PARAMS ((int)); +{ + extern char *rl_prompt; /* the prompt string */ + + /* This set of globals are defined and initialized + * by the readline package. + * + * Note we're assuming tui_tputs() is being called + * by the readline package. That's because we're recognizing + * that a given string is being passed by + * matching the string address against readline's + * term_ global. To make this more general, + * we'd have to actually recognize the termcap sequence + * inside the string (more work than I want to do). - RT + * + * We don't see or need to handle every one of these here; + * this is just the full list defined in readline/readline.c + */ + extern char *term_backspace; + extern char *term_clreol; + extern char *term_clrpag; + extern char *term_cr; + extern char *term_dc; + extern char *term_ei; + extern char *term_goto; + extern char *term_ic; + extern char *term_im; + extern char *term_mm; + extern char *term_mo; + extern char *term_up; + extern char *term_scroll_region; + extern char *term_memory_lock; + extern char *term_memory_unlock; + extern char *term_cursor_move; + extern char *visible_bell; + + /* Sanity check - if not TUI, just call tputs() */ + if (!tui_version) + tputs (str, affcnt, putfunc); + + /* The strings we special-case are handled first */ + + if (str == term_backspace) + { + /* Backspace. */ + + /* We see this on an emacs control-B. + * I.e., it's like the left-arrow key (not like the backspace key). + * The effect that readline wants when it transmits this + * character to us is simply to back up one character + * (but not to write a space over the old character). + */ + + _updateCommandInfo (-1); + wmove (cmdWin->generic.handle, + cmdWin->detail.commandInfo.curLine, + cmdWin->detail.commandInfo.curch); + wrefresh (cmdWin->generic.handle); + + } + else if (str == term_clreol) + { + + /* Clear to end of line. */ + wclrtoeol (cmdWin->generic.handle); + wrefresh (cmdWin->generic.handle); + + } + else if (str == term_cr) + { + + /* Carriage return */ + _updateCommandInfo (-cmdWin->detail.commandInfo.curch); + wmove (cmdWin->generic.handle, + cmdWin->detail.commandInfo.curLine, + 0 /* readline will rewrite the prompt from 0 */ ); + wrefresh (cmdWin->generic.handle); + + } + else if (str == term_goto) + { + + /* This is actually a tgoto() specifying a character position, + * followed by either a term_IC/term_DC which [I think] means + * insert/delete one character at that position. + * There are complications with this one - need to either + * extract the position from the string, or have a backdoor + * means of communicating it from ../readline/display.c. + * So this one is not yet implemented. + * Not doing it seems to have no ill effects on command-line-editing + * that I've noticed so far. - RT + */ + + } + else if (str == term_dc) + { + + /* Delete character at current cursor position */ + wdelch (cmdWin->generic.handle); + wrefresh (cmdWin->generic.handle); + + } + else if (str == term_im) + { + + /* Turn on insert mode. */ + insert_mode = 1; + + } + else if (str == term_ei) + { + + /* Turn off insert mode. */ + insert_mode = 0; + + /* Strings we know about but don't handle + * specially here are just passed along to tputs(). + * + * These are not handled because (as far as I can tell) + * they are not actually emitted by the readline package + * in the course of doing command-line editing. Some of them + * theoretically could be used in the future, in which case we'd + * need to handle them. + */ + } + else if (str == term_ic || /* insert character */ + str == term_cursor_move || /* cursor move */ + str == term_clrpag ||/* clear page */ + str == term_mm || /* turn on meta key */ + str == term_mo || /* turn off meta key */ + str == term_up || /* up one line (not expected) */ + str == term_scroll_region || /* set scroll region */ + str == term_memory_lock || /* lock screen above cursor */ + str == term_memory_unlock || /* unlock screen above cursor */ + str == visible_bell) + { /* flash screen */ + tputs (str, affcnt, putfunc); + } + else + { /* something else */ + tputs (str, affcnt, putfunc); + } +} /* tui_tputs */ + + +/* +** tui_vwgetch() +** Wrapper around wgetch with the window in a va_list +*/ +unsigned int +#ifdef __STDC__ +tui_vwgetch (va_list args) +#else +tui_vwgetch (args) + va_list args; +#endif +{ + unsigned int ch; + WINDOW *window; + + window = va_arg (args, WINDOW *); + + return ((unsigned int) wgetch (window)); +} /* tui_vwgetch */ + + +/* +** tui_vread() +** Wrapper around read() with paramets in a va_list +*/ +unsigned int +#ifdef __STDC__ +tui_vread (va_list args) +#else +tui_vread (args) + va_list args; +#endif +{ + int result = 0; + int filedes = va_arg (args, int); + char *buf = va_arg (args, char *); + int nbytes = va_arg (args, int); + + result = read (filedes, buf, nbytes); + + return result; +} /* tui_vread() */ + +/* +** tuiRead() +** Function to perform a read() catching resize events +*/ +int +#ifdef __STDC__ +tuiRead ( + int filedes, + char *buf, + int nbytes) +#else +tuiRead (filedes, buf, nbytes) + int filedes; + char *buf; + int nbytes; +#endif +{ + int result = 0; + + result = (int) vcatch_errors ((OpaqueFuncPtr) tui_vread, filedes, buf, nbytes); + *buf = _tuiHandleResizeDuringIO (*buf); + + return result; +} /* tuiRead */ + + +/* +** tuiGetc(). +** Get a character from the command window. +** This is called from the readline package, +** that is, we have: +** tuiGetc() [here], called from +** readline code [in ../readline/], called from +** command_line_input() in top.c +*/ +unsigned int +#ifdef __STDC__ +tuiGetc (void) +#else +tuiGetc () +#endif +{ + unsigned int ch; + extern char *rl_prompt; + extern char *rl_line_buffer; + extern int rl_point; + + /* Call the curses routine that reads one character */ +#ifndef COMMENT + ch = (unsigned int) vcatch_errors ((OpaqueFuncPtr) tui_vwgetch, + cmdWin->generic.handle); +#else + ch = wgetch (cmdWin->generic.handle); +#endif + ch = _tuiHandleResizeDuringIO (ch); + + if (m_isCommandChar (ch)) + { /* Handle prev/next/up/down here */ + tuiTermSetup (0); + ch = tuiDispatchCtrlChar (ch); + cmdWin->detail.commandInfo.curch = strlen (rl_prompt) + rl_point; + tuiTermUnsetup (0, cmdWin->detail.commandInfo.curch); + } + if (ch == '\n' || ch == '\r' || ch == '\f') + cmdWin->detail.commandInfo.curch = 0; + else + tuiIncrCommandCharCountBy (1); + + return ch; +} /* tuiGetc */ + + +/* +** tuiBufferGetc(). +*/ +/*elz: this function reads a line of input from the user and +puts it in a static buffer. Subsequent calls to this same function +obtain one char at the time, providing the caller with a behavior +similar to fgetc. When the input is buffered, the backspaces have +the needed effect, i.e. ignore the last char active in the buffer*/ +/* so far this function is called only from the query function in +utils.c*/ + +unsigned int +#ifdef __STDC__ +tuiBufferGetc (void) +#else +tuiBufferGetc () +#endif +{ + unsigned int ch; + static unsigned char _ibuffer[512]; + static int index_read = -1; + static int length_of_answer = -1; + int pos = 0; + + if (length_of_answer == -1) + { + /* this is the first time through, need to read the answer*/ + do + { + /* Call the curses routine that reads one character */ + ch = (unsigned int) wgetch (cmdWin->generic.handle); + if (ch != '\b') + { + _ibuffer[pos] = ch; + pos++; + } + else + pos--; + } + while (ch != '\r' && ch != '\n'); + + length_of_answer = pos; + index_read = 0; + } + + ch = _ibuffer[index_read]; + index_read++; + + if (index_read == length_of_answer) + { + /*this is the last time through, reset for next query*/ + index_read = -1; + length_of_answer = -1; + } + + wrefresh (cmdWin->generic.handle); + + return (ch); +} /* tuiBufferGetc */ + + +/* +** tuiStartNewLines(). +*/ +void +#ifdef __STDC__ +tuiStartNewLines ( + int numLines) +#else +tuiStartNewLines (numLines) + int numLines; +#endif +{ + if (numLines > 0) + { + if (cmdWin->generic.viewportHeight > 1 && + cmdWin->detail.commandInfo.curLine < cmdWin->generic.viewportHeight) + cmdWin->detail.commandInfo.curLine += numLines; + else + scroll (cmdWin->generic.handle); + cmdWin->detail.commandInfo.curch = 0; + wmove (cmdWin->generic.handle, + cmdWin->detail.commandInfo.curLine, + cmdWin->detail.commandInfo.curch); + tuiRefreshWin (&cmdWin->generic); + } + + return; +} /* tuiStartNewLines */ + + +/* +** tui_vStartNewLines(). +** With numLines in a va_list +*/ +void +#ifdef __STDC__ +tui_vStartNewLines ( + va_list args) +#else +tui_vStartNewLines (args) + va_list args; +#endif +{ + int numLines = va_arg (args, int); + + tuiStartNewLines (numLines); + + return; +} /* tui_vStartNewLines */ + + +/**************************************************************************** +** LOCAL STATIC FUNCTIONS ** +*****************************************************************************/ + + +/* +** _tuiHandleResizeDuringIO +** This function manages the cleanup when a resize has occured +** From within a call to getch() or read. Returns the character +** to return from getc or read. +*/ +static unsigned int +#ifdef __STDC__ +_tuiHandleResizeDuringIO ( + unsigned int originalCh) /* the char just read */ +#else +_tuiHandleResizeDuringIO (originalCh) + unsigned int originalCh; +#endif +{ + if (tuiWinResized ()) + { + tuiDo ((TuiOpaqueFuncPtr) tuiRefreshAll); + dont_repeat (); + tuiSetWinResizedTo (FALSE); + rl_reset (); + return '\n'; + } + else + return originalCh; +} /* _tuiHandleResizeDuringIO */ + + +/* +** _updateCommandInfo(). +** Function to update the command window information. +*/ +static void +#ifdef __STDC__ +_updateCommandInfo ( + int sizeOfString) +#else +_updateCommandInfo (sizeOfString) + int sizeOfString; +#endif +{ + + if ((sizeOfString + + cmdWin->detail.commandInfo.curch) > cmdWin->generic.width) + { + int newCurch = sizeOfString + cmdWin->detail.commandInfo.curch; + + tuiStartNewLines (1); + cmdWin->detail.commandInfo.curch = newCurch - cmdWin->generic.width; + } + else + cmdWin->detail.commandInfo.curch += sizeOfString; + + return; +} /* _updateCommandInfo */ + + +/* Looked at in main.c, fputs_unfiltered(), to decide + * if it's safe to do standard output to the command window. + */ +int tui_owns_terminal = 0; + +/* Called to set up the terminal for TUI (curses) I/O. + * We do this either on our way "in" to GDB after target + * program execution, or else within tuiDo just before + * going off to TUI routines. + */ + +void +#ifdef __STDC__ +tuiTermSetup ( + int turn_off_echo) +#else +tuiTermSetup (turn_off_echo) + int turn_off_echo; +#endif +{ + char *buffer; + int start; + int end; + int endcol; + extern char *term_scroll_region; + extern char *term_cursor_move; + extern char *term_memory_lock; + extern char *term_memory_unlock; + + /* Turn off echoing, since the TUI does not + * expect echoing. Below I only put in the TERMIOS + * case, since that is what applies on HP-UX. turn_off_echo + * is 1 except for the case where we're being called + * on a "quit", in which case we want to leave echo on. + */ + if (turn_off_echo) + { +#ifdef HAVE_TERMIOS + struct termios tio; + tcgetattr (0, &tio); + tio.c_lflag &= ~(ECHO); + tcsetattr (0, TCSANOW, &tio); +#endif + } + + /* Compute the start and end lines of the command + * region. (Actually we only use end here) + */ + start = winList[CMD_WIN]->generic.origin.y; + end = start + winList[CMD_WIN]->generic.height - 1; + endcol = winList[CMD_WIN]->generic.width - 1; + + if (term_memory_unlock) + { + + /* Un-do the effect of the memory lock in terminal_inferior() */ + tputs (term_memory_unlock, 1, (int (*)PARAMS ((int))) putchar); + fflush (stdout); + + } + else if (term_scroll_region) + { + + /* Un-do the effect of setting scroll region in terminal_inferior() */ + /* I'm actually not sure how to do this (we don't know for + * sure what the scroll region was *before* we changed it), + * but I'll guess that setting it to the whole screen is + * the right thing. So, ... + */ + + /* Set scroll region to be 0..end */ + buffer = (char *) tgoto (term_scroll_region, end, 0); + tputs (buffer, 1, (int (*)PARAMS ((int))) putchar); + + } /* else we're out of luck */ + + /* This is an attempt to keep the logical & physical + * cursor in synch, going into curses. Without this, + * curses seems to be confused by the fact that + * GDB has physically moved the curser on it. One + * visible effect of removing this code is that the + * locator window fails to get updated and the line + * of text that *should* go into the locator window + * often goes to the wrong place. + */ + /* What's done here is to tell curses to write a ' ' + * at the bottom right corner of the screen. + * The idea is to wind up with the cursor in a known + * place. + * Note I'm relying on refresh() + * only writing what changed (the space), + * not the whole screen. + */ + standend (); + move (end, endcol - 1); + addch (' '); + refresh (); + + tui_owns_terminal = 1; +} /* tuiTermSetup */ + + +/* Called to set up the terminal for target program I/O, meaning I/O + * is confined to the command-window area. We also call this on our + * way out of tuiDo, thus setting up the terminal this way for + * debugger command I/O. */ +void +#ifdef __STDC__ +tuiTermUnsetup ( + int turn_on_echo, + int to_column) +#else +tuiTermUnsetup (turn_on_echo, to_column) + int turn_on_echo; + int to_column; +#endif +{ + int start; + int end; + int curline; + char *buffer; + /* The next bunch of things are from readline */ + extern char *term_scroll_region; + extern char *term_cursor_move; + extern char *term_memory_lock; + extern char *term_memory_unlock; + extern char *term_se; + + /* We need to turn on echoing, since the TUI turns it off */ + /* Below I only put in the TERMIOS case, since that + * is what applies on HP-UX. + */ + if (turn_on_echo) + { +#ifdef HAVE_TERMIOS + struct termios tio; + tcgetattr (0, &tio); + tio.c_lflag |= (ECHO); + tcsetattr (0, TCSANOW, &tio); +#endif + } + + /* Compute the start and end lines of the command + * region, as well as the last "real" line of + * the region (normally same as end, except when + * we're first populating the region) + */ + start = winList[CMD_WIN]->generic.origin.y; + end = start + winList[CMD_WIN]->generic.height - 1; + curline = start + winList[CMD_WIN]->detail.commandInfo.curLine; + + /* We want to confine target I/O to the command region. + * In order to do so, we must either have "memory lock" + * (hpterm's) or "scroll regions" (xterm's). + */ + if (term_cursor_move && term_memory_lock) + { + + /* Memory lock means lock region above cursor. + * So first position the cursor, then call memory lock. + */ + buffer = tgoto (term_cursor_move, 0, start); + tputs (buffer, 1, (int (*)PARAMS ((int))) putchar); + tputs (term_memory_lock, 1, (int (*)PARAMS ((int))) putchar); + + } + else if (term_scroll_region) + { + + /* Set the scroll region to the command window */ + buffer = tgoto (term_scroll_region, end, start); + tputs (buffer, 1, (int (*)PARAMS ((int))) putchar); + + } /* else we can't do anything about target I/O */ + + /* Also turn off standout mode, in case it is on */ + if (term_se != NULL) + tputs (term_se, 1, (int (*)PARAMS ((int))) putchar); + + /* Now go to the appropriate spot on the end line */ + buffer = tgoto (term_cursor_move, to_column, end); + tputs (buffer, 1, (int (*)PARAMS ((int))) putchar); + fflush (stdout); + + tui_owns_terminal = 0; +} /* tuiTermUnsetup */ diff --git a/gdb/tui/tuiIO.h b/gdb/tui/tuiIO.h new file mode 100644 index 00000000000..bcbeffe4edc --- /dev/null +++ b/gdb/tui/tuiIO.h @@ -0,0 +1,43 @@ +#ifndef _TUI_IO_H +#define _TUI_IO_H +/* +** This header contains defitions to support tuiIO.c +*/ + + +#include + +extern void tuiPuts_unfiltered PARAMS ((const char *, GDB_FILE *)); +extern unsigned int tuiGetc PARAMS ((void)); +extern unsigned int tuiBufferGetc PARAMS ((void)); +extern int tuiRead PARAMS ((int, char *, int)); +extern void tuiStartNewLines PARAMS ((int)); +extern void tui_vStartNewLines PARAMS ((va_list)); +extern unsigned int tui_vwgetch PARAMS ((va_list)); +extern void tuiTermSetup PARAMS ((int)); +extern void tuiTermUnsetup PARAMS ((int, int)); + + + +#define m_tuiStartNewLine tuiStartNewLines(1) +#define m_isStartSequence(ch) (ch == 27) +#define m_isEndSequence(ch) (ch == 126) +#define m_isBackspace(ch) (ch == 8) +#define m_isDeleteChar(ch) (ch == KEY_DC) +#define m_isDeleteLine(ch) (ch == KEY_DL) +#define m_isDeleteToEol(ch) (ch == KEY_EOL) +#define m_isNextPage(ch) (ch == KEY_NPAGE) +#define m_isPrevPage(ch) (ch == KEY_PPAGE) +#define m_isLeftArrow(ch) (ch == KEY_LEFT) +#define m_isRightArrow(ch) (ch == KEY_RIGHT) + +#define m_isCommandChar(ch) (m_isNextPage(ch) || m_isPrevPage(ch) || \ + m_isLeftArrow(ch) || m_isRightArrow(ch) || \ + (ch == KEY_UP) || (ch == KEY_DOWN) || \ + (ch == KEY_SF) || (ch == KEY_SR) || \ + (ch == (int)'\f') || m_isStartSequence(ch)) + +#define m_isXdbStyleCommandChar(ch) (m_isNextPage(ch) || m_isPrevPage(ch)) + + +#endif /*_TUI_IO_H*/ diff --git a/gdb/tui/tuiLayout.c b/gdb/tui/tuiLayout.c new file mode 100644 index 00000000000..6aa380cfe41 --- /dev/null +++ b/gdb/tui/tuiLayout.c @@ -0,0 +1,1410 @@ +/* +** tuiLayout.c +** This module contains procedures for handling the layout of the windows. +*/ + + +#include "defs.h" +#include "command.h" +#include "symtab.h" +#include "frame.h" + +#include "tui.h" +#include "tuiData.h" +#include "tuiGeneralWin.h" +#include "tuiStack.h" +#include "tuiRegs.h" +#include "tuiDisassem.h" + +/******************************* +** Static Local Decls +********************************/ + +static void _initGenWinInfo PARAMS + ((TuiGenWinInfoPtr, TuiWinType, int, int, int, int)); +static void _initAndMakeWin PARAMS + ((Opaque *, TuiWinType, int, int, int, int, int)); +static void _showSourceOrDisassemAndCommand PARAMS + ((TuiLayoutType)); +static void _makeSourceOrDisassemWindow PARAMS + ((TuiWinInfoPtr *, TuiWinType, int, int)); +static void _makeCommandWindow PARAMS ((TuiWinInfoPtr *, int, int)); +static void _makeSourceWindow PARAMS ((TuiWinInfoPtr *, int, int)); +static void _makeDisassemWindow PARAMS + ((TuiWinInfoPtr *, int, int)); +static void _makeDataWindow PARAMS ((TuiWinInfoPtr *, int, int)); +static void _showSourceCommand PARAMS ((void)); +static void _showDisassemCommand PARAMS ((void)); +static void _showSourceDisassemCommand PARAMS ((void)); +static void _showData PARAMS ((TuiLayoutType)); +static TuiLayoutType _nextLayout PARAMS ((void)); +static TuiLayoutType _prevLayout PARAMS ((void)); +static void _tuiLayout_command PARAMS ((char *, int)); +static void _tuiToggleLayout_command PARAMS ((char *, int)); +static void _tui_vToggleLayout_command PARAMS ((va_list)); +static void _tuiToggleSplitLayout_command PARAMS ((char *, int)); +static void _tui_vToggleSplitLayout_command PARAMS ((va_list)); +static Opaque _extractDisplayStartAddr PARAMS ((void)); +static void _tuiHandleXDBLayout PARAMS ((TuiLayoutDefPtr)); +static TuiStatus _tuiSetLayoutTo PARAMS ((char *)); + + +/*************************************** +** DEFINITIONS +***************************************/ + +#define LAYOUT_USAGE "Usage: layout prev | next | \n" + +/*************************************** +** Static Local Data +***************************************/ +static TuiLayoutType lastLayout = UNDEFINED_LAYOUT; + +/*************************************** +** PUBLIC FUNCTIONS +***************************************/ + +/* +** showLayout(). +** Show the screen layout defined +*/ +void +#ifdef __STDC__ +showLayout ( + TuiLayoutType layout) +#else +showLayout (layout) + TuiLayoutType layout; +#endif +{ + 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 + */ + tuiClearAllSourceWinsContent (NO_EMPTY_SOURCE_PROMPT); + 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; + } + } + } + + return; +} /* showLayout */ + + +/* +** tuiSetLayout() +** 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. +*/ +TuiStatus +#ifdef __STDC__ +tuiSetLayout ( + TuiLayoutType layoutType, + TuiRegisterDisplayType regsDisplayType) +#else +tuiSetLayout (layoutType, regsDisplayType) + TuiLayoutType layoutType; + TuiRegisterDisplayType regsDisplayType; +#endif +{ + TuiStatus status = TUI_SUCCESS; + + if (layoutType != UNDEFINED_LAYOUT || regsDisplayType != TUI_UNDEFINED_REGS) + { + TuiLayoutType curLayout = currentLayout (), newLayout = UNDEFINED_LAYOUT; + int regsPopulate = FALSE; + Opaque 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) + { + if (winWithFocus != cmdWin) + tuiClearWinFocus (); + 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 = vcatch_errors ((OpaqueFuncPtr) + tuiGetBeginAsmAddress); + 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 = vcatch_errors ((OpaqueFuncPtr) + tuiGetBeginAsmAddress); + 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 = vcatch_errors ((OpaqueFuncPtr) + tuiGetBeginAsmAddress); + 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); + tuiShowRegisters (layoutDef->regsDisplayType); + } + } + } + else + status = TUI_FAILURE; + + return status; +} /* tuiSetLayout */ + + +/* +** tui_vSetLayoutTo() +** Function to set the layout to SRC, ASM, SPLIT, NEXT, PREV, DATA, +** REGS, $REGS, $GREGS, $FREGS, $SREGS with arguments in a va_list +*/ +TuiStatus +#ifdef __STDC__ +tui_vSetLayoutTo ( + va_list args) +#else +tui_vSetLayoutTo (args) + va_list args; +#endif +{ + char *layoutName; + + layoutName = va_arg (args, char *); + + return (_tuiSetLayoutTo (layoutName)); +} /* tui_vSetLayoutTo */ + + +/* +** tuiAddWinToLayout(). +** 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 +#ifdef __STDC__ +tuiAddWinToLayout ( + TuiWinType type) +#else +tuiAddWinToLayout (type) + TuiWinType type; +#endif +{ + 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 */ + + +/* +** tui_vAddWinToLayout(). +** Add the specified window to the layout in a logical way, +** with arguments in a va_list. +*/ +void +#ifdef __STDC__ +tui_vAddWinToLayout ( + va_list args) +#else +tui_vAddWinToLayout (args) + va_list args; +#endif +{ + TuiWinType type = va_arg (args, TuiWinType); + + tuiAddWinToLayout (type); + + return; +} /* tui_vAddWinToLayout */ + + +/* +** 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 +#ifdef __STDC__ +tuiDefaultWinHeight ( + TuiWinType type, + TuiLayoutType layout) +#else +tuiDefaultWinHeight (type, layout) + TuiWinType type; + TuiLayoutType layout; +#endif +{ + 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 */ + + +/* +** tuiDefaultWinViewportHeight(). +** 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 +#ifdef __STDC__ +tuiDefaultWinViewportHeight ( + TuiWinType type, + TuiLayoutType layout) +#else +tuiDefaultWinViewportHeight (type, layout) + TuiWinType type; + TuiLayoutType layout; +#endif +{ + 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 () +{ + if (tui_version) + { + add_com ("layout", class_tui, _tuiLayout_command, + "Change the layout of windows.\n\ +Usage: layout prev | next | \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"); + } + } + + return; +} /* _intialize_tuiLayout */ + + +/************************* +** STATIC LOCAL FUNCTIONS +**************************/ + + +/* +** _tuiSetLayoutTo() +** Function to set the layout to SRC, ASM, SPLIT, NEXT, PREV, DATA, REGS, +** $REGS, $GREGS, $FREGS, $SREGS. +*/ +static TuiStatus +#ifdef __STDC__ +_tuiSetLayoutTo ( + char *layoutName) +#else +_tuiSetLayoutTo (layoutName) + char *layoutName; +#endif +{ + 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 *) tuiStrDup (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 (subsetCompare (bufPtr, "SRC")) + newLayout = SRC_COMMAND; + else if (subsetCompare (bufPtr, "ASM")) + newLayout = DISASSEM_COMMAND; + else if (subsetCompare (bufPtr, "SPLIT")) + newLayout = SRC_DISASSEM_COMMAND; + else if (subsetCompare (bufPtr, "REGS") || + subsetCompare (bufPtr, TUI_GENERAL_SPECIAL_REGS_NAME) || + subsetCompare (bufPtr, TUI_GENERAL_REGS_NAME) || + subsetCompare (bufPtr, TUI_FLOAT_REGS_NAME) || + subsetCompare (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 (subsetCompare (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 (subsetCompare (bufPtr, + TUI_GENERAL_SPECIAL_REGS_NAME)) + dpyType = TUI_GENERAL_AND_SPECIAL_REGS; + else if (subsetCompare (bufPtr, TUI_GENERAL_REGS_NAME)) + dpyType = TUI_GENERAL_REGS; + else if (subsetCompare (bufPtr, TUI_SPECIAL_REGS_NAME)) + dpyType = TUI_SPECIAL_REGS; + else + { + 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 (subsetCompare (bufPtr, "NEXT")) + newLayout = _nextLayout (); + else if (subsetCompare (bufPtr, "PREV")) + newLayout = _prevLayout (); + else + status = TUI_FAILURE; + free (bufPtr); + + tuiSetLayout (newLayout, dpyType); + } + } + else + status = TUI_FAILURE; + + return status; +} /* _tuiSetLayoutTo */ + + +static Opaque +#ifdef __STDC__ +_extractDisplayStartAddr (void) +#else +_extractDisplayStartAddr () +#endif +{ + TuiLayoutType curLayout = currentLayout (); + Opaque addr; + + switch (curLayout) + { + case SRC_COMMAND: + case SRC_DATA_COMMAND: + addr = (Opaque) find_line_pc ( + current_source_symtab, + srcWin->detail.sourceInfo.startLineOrAddr.lineNo); + break; + case DISASSEM_COMMAND: + case SRC_DISASSEM_COMMAND: + case DISASSEM_DATA_COMMAND: + addr = disassemWin->detail.sourceInfo.startLineOrAddr.addr; + break; + default: + addr = (Opaque) NULL; + break; + } + + return addr; +} /* _extractDisplayStartAddr */ + + +static void +#ifdef __STDC__ +_tuiHandleXDBLayout ( + TuiLayoutDefPtr layoutDef) +#else +_tuiHandleXDBLayout (layoutDef) + TuiLayoutDefPtr layoutDef; +#endif +{ + if (layoutDef->split) + { + tuiSetLayout (SRC_DISASSEM_COMMAND, TUI_UNDEFINED_REGS); + tuiSetWinFocusTo (winList[layoutDef->displayMode]); + } + else + { + if (layoutDef->displayMode == SRC_WIN) + tuiSetLayout (SRC_COMMAND, TUI_UNDEFINED_REGS); + else + tuiSetLayout (DISASSEM_DATA_COMMAND, layoutDef->regsDisplayType); + } + + + return; +} /* _tuiHandleXDBLayout */ + + +static void +#ifdef __STDC__ +_tuiToggleLayout_command ( + char *arg, + int fromTTY) +#else +_tuiToggleLayout_command (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + tuiDo ((TuiOpaqueFuncPtr) _tui_vToggleLayout_command, arg, fromTTY); +} + +static void +#ifdef __STDC__ +_tui_vToggleLayout_command ( + va_list args) +#else +_tui_vToggleLayout_command (args) + va_list args; +#endif +{ + TuiLayoutDefPtr layoutDef = tuiLayoutDef (); + + if (layoutDef->displayMode == SRC_WIN) + layoutDef->displayMode = DISASSEM_WIN; + else + layoutDef->displayMode = SRC_WIN; + + if (!layoutDef->split) + _tuiHandleXDBLayout (layoutDef); + + return; +} /* _tuiToggleLayout_command */ + + +static void +#ifdef __STDC__ +_tuiToggleSplitLayout_command ( + char *arg, + int fromTTY) +#else +_tuiToggleSplitLayout_command (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + tuiDo ((TuiOpaqueFuncPtr) _tui_vToggleSplitLayout_command, arg, fromTTY); +} + +static void +#ifdef __STDC__ +_tui_vToggleSplitLayout_command ( + va_list args) +#else +_tui_vToggleSplitLayout_command (args) + va_list args; +#endif +{ + TuiLayoutDefPtr layoutDef = tuiLayoutDef (); + + layoutDef->split = (!layoutDef->split); + _tuiHandleXDBLayout (layoutDef); + + return; +} /* _tui_vToggleSplitLayout_command */ + + +static void +#ifdef __STDC__ +_tuiLayout_command ( + char *arg, + int fromTTY) +#else +_tuiLayout_command (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + if ((TuiStatus) tuiDo ( + (TuiOpaqueFuncPtr) tui_vSetLayoutTo, arg) != TUI_SUCCESS) + warning ("Invalid layout specified.\n%s" LAYOUT_USAGE); + + return; +} /* _tuiLayout_command */ + +/* +** _nextLayout(). +** Answer the previous layout to cycle to. +*/ +static TuiLayoutType +#ifdef __STDC__ +_nextLayout (void) +#else +_nextLayout () +#endif +{ + 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 +#ifdef __STDC__ +_prevLayout (void) +#else +_prevLayout () +#endif +{ + 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 +#ifdef __STDC__ +_makeCommandWindow ( + TuiWinInfoPtr * winInfoPtr, + int height, + int originY) +#else +_makeCommandWindow (winInfoPtr, height, originY) + TuiWinInfoPtr *winInfoPtr; + int height; + int originY; +#endif +{ + _initAndMakeWin ((Opaque *) winInfoPtr, + CMD_WIN, + height, + termWidth (), + 0, + originY, + DONT_BOX_WINDOW); + + (*winInfoPtr)->canHighlight = FALSE; + + return; +} /* _makeCommandWindow */ + + +/* +** _makeSourceWindow(). +*/ +static void +#ifdef __STDC__ +_makeSourceWindow ( + TuiWinInfoPtr * winInfoPtr, + int height, + int originY) +#else +_makeSourceWindow (winInfoPtr, height, originY) + TuiWinInfoPtr *winInfoPtr; + int height; + int originY; +#endif +{ + _makeSourceOrDisassemWindow (winInfoPtr, SRC_WIN, height, originY); + + return; +} /* _makeSourceWindow */ + + +/* +** _makeDisassemWindow(). +*/ +static void +#ifdef __STDC__ +_makeDisassemWindow ( + TuiWinInfoPtr * winInfoPtr, + int height, + int originY) +#else +_makeDisassemWindow (winInfoPtr, height, originY) + TuiWinInfoPtr *winInfoPtr; + int height; + int originY; +#endif +{ + _makeSourceOrDisassemWindow (winInfoPtr, DISASSEM_WIN, height, originY); + + return; +} /* _makeDisassemWindow */ + + +/* +** _makeDataWindow(). +*/ +static void +#ifdef __STDC__ +_makeDataWindow ( + TuiWinInfoPtr * winInfoPtr, + int height, + int originY) +#else +_makeDataWindow (winInfoPtr, height, originY) + TuiWinInfoPtr *winInfoPtr; + int height; + int originY; +#endif +{ + _initAndMakeWin ((Opaque *) winInfoPtr, + DATA_WIN, + height, + termWidth (), + 0, + originY, + BOX_WINDOW); + + return; +} /* _makeDataWindow */ + + + +/* +** _showSourceCommand(). +** Show the Source/Command layout +*/ +static void +#ifdef __STDC__ +_showSourceCommand (void) +#else +_showSourceCommand () +#endif +{ + _showSourceOrDisassemAndCommand (SRC_COMMAND); + + return; +} /* _showSourceCommand */ + + +/* +** _showDisassemCommand(). +** Show the Dissassem/Command layout +*/ +static void +#ifdef __STDC__ +_showDisassemCommand (void) +#else +_showDisassemCommand () +#endif +{ + _showSourceOrDisassemAndCommand (DISASSEM_COMMAND); + + return; +} /* _showDisassemCommand */ + + +/* +** _showSourceDisassemCommand(). +** Show the Source/Disassem/Command layout +*/ +static void +#ifdef __STDC__ +_showSourceDisassemCommand (void) +#else +_showSourceDisassemCommand () +#endif +{ + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + + 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 +#ifdef __STDC__ +_showData ( + TuiLayoutType newLayout) +#else +_showData (newLayout) + TuiLayoutType newLayout; +#endif +{ + 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 +#ifdef __STDC__ +_initGenWinInfo ( + TuiGenWinInfoPtr winInfo, + TuiWinType type, + int height, + int width, + int originX, + int originY) +#else +_initGenWinInfo (winInfo, type, height, width, originX, originY) + TuiGenWinInfoPtr winInfo; + TuiWinType type; + int height; + int width; + int originX; + int originY; +#endif +{ + 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 +#ifdef __STDC__ +_initAndMakeWin ( + Opaque * winInfoPtr, + TuiWinType winType, + int height, + int width, + int originX, + int originY, + int boxIt) +#else +_initAndMakeWin (winInfoPtr, winType, height, width, originX, originY, boxIt) + Opaque *winInfoPtr; + TuiWinType winType; + int height; + int width; + int originX; + int originY; + int boxIt; +#endif +{ + 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); + if (winType == LOCATOR_WIN) + tuiClearLocatorDisplay (); + echo (); + } + *winInfoPtr = opaqueWinInfo; + + return; +} /* _initAndMakeWin */ + + +/* +** _makeSourceOrDisassemWindow(). +*/ +static void +#ifdef __STDC__ +_makeSourceOrDisassemWindow ( + TuiWinInfoPtr * winInfoPtr, + TuiWinType type, + int height, + int originY) +#else +_makeSourceOrDisassemWindow (winInfoPtr, type, height, originY) + TuiWinInfoPtr *winInfoPtr; + TuiWinType type; + int height; + int originY; +#endif +{ + 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 +#ifdef __STDC__ +_showSourceOrDisassemAndCommand ( + TuiLayoutType layoutType) +#else +_showSourceOrDisassemAndCommand (layoutType) + TuiLayoutType layoutType; +#endif +{ + if (currentLayout () != layoutType) + { + TuiWinInfoPtr *winInfoPtr; + int areaLeft; + 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/tuiLayout.h b/gdb/tui/tuiLayout.h new file mode 100644 index 00000000000..57d8bbc90b6 --- /dev/null +++ b/gdb/tui/tuiLayout.h @@ -0,0 +1,15 @@ +#ifndef TUI_LAYOUT_H +#define TUI_LAYOUT_H + +extern void showLayout PARAMS ((TuiLayoutType)); +extern void tuiAddWinToLayout PARAMS ((TuiWinType)); +extern void tui_vAddWinToLayout PARAMS ((va_list)); +extern int tuiDefaultWinHeight + PARAMS ((TuiWinType, TuiLayoutType)); +extern int tuiDefaultWinViewportHeight + PARAMS ((TuiWinType, TuiLayoutType)); +extern TuiStatus tuiSetLayout + PARAMS ((TuiLayoutType, TuiRegisterDisplayType)); +extern TuiStatus tui_vSetLayoutTo PARAMS ((va_list)); + +#endif /*TUI_LAYOUT_H*/ diff --git a/gdb/tui/tuiRegs.c b/gdb/tui/tuiRegs.c new file mode 100644 index 00000000000..b78b9bc873c --- /dev/null +++ b/gdb/tui/tuiRegs.c @@ -0,0 +1,1210 @@ + +/* +** tuiRegs.c +** This module contains functions to support display of registers +** in the data window. +*/ + + +#include "defs.h" +#include "tui.h" +#include "tuiData.h" +#include "symtab.h" +#include "gdbtypes.h" +#include "gdbcmd.h" +#include "frame.h" +#include "inferior.h" +#include "target.h" +#include "tuiLayout.h" +#include "tuiWin.h" + + +/***************************************** +** 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 10 +#define SINGLE_LABEL_FMT "%10.10s: " +#define SINGLE_VALUE_WIDTH 14/* 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 + PARAMS ((int, int, struct frame_info *, + TuiRegisterDisplayType, int)); +static char *_tuiRegisterName PARAMS ((int)); +static TuiStatus _tuiGetRegisterRawValue + PARAMS ((int, char *, struct frame_info *)); +static void _tuiSetRegisterElement + PARAMS ((int, struct frame_info *, + TuiDataElementPtr, int)); +static void _tuiDisplayRegister + PARAMS ((int, TuiGenWinInfoPtr, enum precision_type)); +static void _tuiRegisterFormat + PARAMS ((char *, int, int, TuiDataElementPtr, + enum precision_type)); +static TuiStatus _tuiSetGeneralRegsContent PARAMS ((int)); +static TuiStatus _tuiSetSpecialRegsContent PARAMS ((int)); +static TuiStatus _tuiSetGeneralAndSpecialRegsContent PARAMS ((int)); +static TuiStatus _tuiSetFloatRegsContent PARAMS ((TuiRegisterDisplayType, int)); +static int _tuiRegValueHasChanged + PARAMS ((TuiDataElementPtr, struct frame_info *, + char *)); +static void _tuiShowFloat_command PARAMS ((char *, int)); +static void _tuiShowGeneral_command PARAMS ((char *, int)); +static void _tuiShowSpecial_command PARAMS ((char *, int)); +static void _tui_vShowRegisters_commandSupport PARAMS ((va_list)); +static void _tuiToggleFloatRegs_command PARAMS ((char *, int)); +static void _tuiScrollRegsForward_command PARAMS ((char *, int)); +static void _tuiScrollRegsBackward_command PARAMS ((char *, int)); +static void _tui_vShowRegisters_commandSupport PARAMS ((va_list)); + + + +/***************************************** +** PUBLIC FUNCTIONS ** +******************************************/ + +/* +** tuiLastRegsLineNo() +** Answer the number of the last line in the regs display. +** If there are no registers (-1) is returned. +*/ +int +#ifdef __STDC__ +tuiLastRegsLineNo (void) +#else +tuiLastRegsLineNo () +#endif +{ + 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; +} /* tuiLastRegsLineNo */ + + +/* +** tuiLineFromRegElementNo() +** 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 +#ifdef __STDC__ +tuiLineFromRegElementNo ( + int elementNo) +#else +tuiLineFromRegElementNo (elementNo) + int elementNo; +#endif +{ + 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); +} /* tuiLineFromRegElementNo */ + + +/* +** tuiFirstRegElementNoInLine() +** Answer the index of the first element in lineNo. If lineNo is +** past the register area (-1) is returned. +*/ +int +#ifdef __STDC__ +tuiFirstRegElementNoInLine ( + int lineNo) +#else +tuiFirstRegElementNoInLine (lineNo) + int lineNo; +#endif +{ + if ((lineNo * dataWin->detail.dataDisplayInfo.regsColumnCount) + <= dataWin->detail.dataDisplayInfo.regsContentCount) + return ((lineNo + 1) * + dataWin->detail.dataDisplayInfo.regsColumnCount) - + dataWin->detail.dataDisplayInfo.regsColumnCount; + else + return (-1); +} /* tuiFirstRegElementNoInLine */ + + +/* +** tuiLastRegElementNoInLine() +** Answer the index of the last element in lineNo. If lineNo is past +** the register area (-1) is returned. +*/ +int +#ifdef __STDC__ +tuiLastRegElementNoInLine ( + int lineNo) +#else +tuiLastRegElementNoInLine (lineNo) + int lineNo; +#endif +{ + if ((lineNo * dataWin->detail.dataDisplayInfo.regsColumnCount) <= + dataWin->detail.dataDisplayInfo.regsContentCount) + return ((lineNo + 1) * + dataWin->detail.dataDisplayInfo.regsColumnCount) - 1; + else + return (-1); +} /* tuiLastRegElementNoInLine */ + + +/* +** tuiCalculateRegsColumnCount +** Calculate the number of columns that should be used to display +** the registers. +*/ +int +#ifdef __STDC__ +tuiCalculateRegsColumnCount ( + TuiRegisterDisplayType dpyType) +#else +tuiCalculateRegsColumnCount (dpyType) + TuiRegisterDisplayType dpyType; +#endif +{ + 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 */ + + +/* +** tuiShowRegisters(). +** 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 +#ifdef __STDC__ +tuiShowRegisters ( + TuiRegisterDisplayType dpyType) +#else +tuiShowRegisters (dpyType) + TuiRegisterDisplayType dpyType; +#endif +{ + 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; +} /* tuiShowRegisters */ + + +/* +** tuiDisplayRegistersFrom(). +** 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 +#ifdef __STDC__ +tuiDisplayRegistersFrom ( + int startElementNo) +#else +tuiDisplayRegistersFrom (startElementNo) + int startElementNo; +#endif +{ + if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL && + dataWin->detail.dataDisplayInfo.regsContentCount > 0) + { + register int i = startElementNo; + int j, valueCharsWide, charsWide, 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); + } + /* + ** Get the printable representation of the register + ** and display it + */ + _tuiDisplayRegister ( + dataElementPtr->itemNo, dataItemWin, precision); + i++; /* next register */ + } + curY++; /* next row; */ + } + } + + return; +} /* tuiDisplayRegistersFrom */ + + +/* +** 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 +#ifdef __STDC__ +tuiDisplayRegElementAtLine ( + int startElementNo, + int startLineNo) +#else +tuiDisplayRegElementAtLine (startElementNo, startLineNo) + int startElementNo; + int startLineNo; +#endif +{ + 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 = tuiLastRegsLineNo (); + 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 = tuiFirstRegElementNoInLine (firstLineOnLastPage); + } + tuiDisplayRegistersFrom (elementNo); + } + + return; +} /* tuiDisplayRegElementAtLine */ + + + +/* +** tuiDisplayRegistersFromLine(). +** 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 +#ifdef __STDC__ +tuiDisplayRegistersFromLine ( + int lineNo, + int forceDisplay) +#else +tuiDisplayRegistersFromLine (lineNo, forceDisplay) + int lineNo; + int forceDisplay; +#endif +{ + int elementNo; + + 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 >= tuiLastRegsLineNo ()) + { + if ((line = tuiLineFromRegElementNo ( + dataWin->detail.dataDisplayInfo.regsContentCount - 1)) < 0) + line = 0; + } + else + line = lineNo; + } + else + line = lineNo; + + elementNo = tuiFirstRegElementNoInLine (line); + if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount) + tuiDisplayRegElementAtLine (elementNo, line); + else + line = (-1); + + return line; + } + + return (-1); /* nothing was displayed */ +} /* tuiDisplayRegistersFromLine */ + + +/* +** tuiCheckRegisterValues() +** 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 +#ifdef __STDC__ +tuiCheckRegisterValues ( + struct frame_info *frame) +#else +tuiCheckRegisterValues (frame) + struct frame_info *frame; +#endif +{ + if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible) + { + if (dataWin->detail.dataDisplayInfo.regsContentCount <= 0 && + dataWin->detail.dataDisplayInfo.displayRegs) + tuiShowRegisters ((tuiLayoutDef ())->regsDisplayType); + else + { + int i, j; + char rawBuf[MAX_REGISTER_RAW_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) + { + for (j = 0; j < MAX_REGISTER_RAW_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; +} /* tuiCheckRegisterValues */ + + +/* +** tuiToggleFloatRegs(). +*/ +void +#ifdef __STDC__ +tuiToggleFloatRegs (void) +#else +tuiToggleFloatRegs () +#endif +{ + 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)) + tuiShowRegisters (layoutDef->floatRegsDisplayType); + + return; +} /* tuiToggleFloatRegs */ + + +void +_initialize_tuiRegs () +{ + if (tui_version && 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); + } + + return; +} /* _initialize_tuiRegs */ + + +/***************************************** +** STATIC LOCAL FUNCTIONS ** +******************************************/ + + +/* +** _tuiRegisterName(). +** Return the register name. +*/ +static char * +#ifdef __STDC__ +_tuiRegisterName ( + int regNum) +#else +_tuiRegisterName (regNum) + int regNum; +#endif +{ + if (reg_names[regNum] != (char *) NULL && *(reg_names[regNum]) != (char) 0) + return reg_names[regNum]; + else + return ((char *) NULL); +} /* tuiGetRegisterName */ + + +/* +** _tuiRegisterFormat +** Function to format the register name and value into a buffer, +** suitable for printing or display +*/ +static void +#ifdef __STDC__ +_tuiRegisterFormat ( + char *buf, + int bufLen, + int regNum, + TuiDataElementPtr dataElement, + enum precision_type precision) +#else +_tuiRegisterFormat (buf, bufLen, regNum, dataElement, precision) + char *buf; + int bufLen; + int regNum; + TuiDataElementPtr dataElement; + enum precision_type precision; +#endif +{ + char tmpBuf[15]; + char *fmt; + GDB_FILE *stream; + + stream = gdb_file_init_astring(bufLen); + pa_do_strcat_registers_info (regNum, 0, stream, precision); + strcpy (buf, gdb_file_get_strbuf(stream)); + gdb_file_deallocate(&stream); + + return; +} /* _tuiRegisterFormat */ + + +#define NUM_GENERAL_REGS 32 +/* +** _tuiSetGeneralRegsContent(). +** Set the content of the data window to consist of the general registers. +*/ +static TuiStatus +#ifdef __STDC__ +_tuiSetGeneralRegsContent ( + int refreshValuesOnly) +#else +_tuiSetGeneralRegsContent (refreshValuesOnly) + int refreshValuesOnly; +#endif +{ + return (_tuiSetRegsContent (0, + NUM_GENERAL_REGS - 1, + selected_frame, + TUI_GENERAL_REGS, + refreshValuesOnly)); + +} /* _tuiSetGeneralRegsContent */ + + +#define START_SPECIAL_REGS PCOQ_HEAD_REGNUM +/* +** _tuiSetSpecialRegsContent(). +** Set the content of the data window to consist of the special registers. +*/ +static TuiStatus +#ifdef __STDC__ +_tuiSetSpecialRegsContent ( + int refreshValuesOnly) +#else +_tuiSetSpecialRegsContent (refreshValuesOnly) + int refreshValuesOnly; +#endif +{ + TuiStatus ret = TUI_FAILURE; + int i, endRegNum; + + endRegNum = FP0_REGNUM - 1; +#if 0 + endRegNum = (-1); + for (i = START_SPECIAL_REGS; (i < ARCH_NUM_REGS && endRegNum < 0); i++) + if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT) + endRegNum = i - 1; +#endif + ret = _tuiSetRegsContent (START_SPECIAL_REGS, + endRegNum, + 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 +#ifdef __STDC__ +_tuiSetGeneralAndSpecialRegsContent ( + int refreshValuesOnly) +#else +_tuiSetGeneralAndSpecialRegsContent (refreshValuesOnly) + int refreshValuesOnly; +#endif +{ + TuiStatus ret = TUI_FAILURE; + int i, endRegNum = (-1); + + endRegNum = FP0_REGNUM - 1; +#if 0 + endRegNum = (-1); + for (i = 0; (i < ARCH_NUM_REGS && endRegNum < 0); i++) + if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT) + endRegNum = i - 1; +#endif + ret = _tuiSetRegsContent ( + 0, endRegNum, 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 +#ifdef __STDC__ +_tuiSetFloatRegsContent ( + TuiRegisterDisplayType dpyType, + int refreshValuesOnly) +#else +_tuiSetFloatRegsContent (dpyType, refreshValuesOnly) + TuiRegisterDisplayType dpyType; + int refreshValuesOnly; +#endif +{ + TuiStatus ret = TUI_FAILURE; + int i, startRegNum; + + startRegNum = FP0_REGNUM; +#if 0 + startRegNum = (-1); + for (i = ARCH_NUM_REGS - 1; (i >= 0 && startRegNum < 0); i--) + if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) != TYPE_CODE_FLT) + startRegNum = i + 1; +#endif + ret = _tuiSetRegsContent (startRegNum, + ARCH_NUM_REGS - 1, + 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 +#ifdef __STDC__ +_tuiRegValueHasChanged ( + TuiDataElementPtr dataElement, + struct frame_info *frame, + char *newValue) +#else +_tuiRegValueHasChanged (dataElement, frame, newValue) + TuiDataElementPtr dataElement; + struct frame_info *frame; + char *newValue; +#endif +{ + int hasChanged = FALSE; + + if (dataElement->itemNo != UNDEFINED_ITEM && + _tuiRegisterName (dataElement->itemNo) != (char *) NULL) + { + char rawBuf[MAX_REGISTER_RAW_SIZE]; + int i; + + if (_tuiGetRegisterRawValue ( + dataElement->itemNo, rawBuf, frame) == TUI_SUCCESS) + { + for (i = 0; (i < MAX_REGISTER_RAW_SIZE && !hasChanged); i++) + hasChanged = (((char *) dataElement->value)[i] != rawBuf[i]); + if (hasChanged && newValue != (char *) NULL) + { + for (i = 0; (i < MAX_REGISTER_RAW_SIZE); i++) + newValue[i] = rawBuf[i]; + } + } + } + return hasChanged; +} /* _tuiRegValueHasChanged */ + + + +/* +** _tuiGetRegisterRawValue(). +** Get the register raw value. The raw value is returned in regValue. +*/ +static TuiStatus +#ifdef __STDC__ +_tuiGetRegisterRawValue ( + int regNum, + char *regValue, + struct frame_info *frame) +#else +_tuiGetRegisterRawValue (regNum, regValue, frame) + int regNum; + char *regValue; + struct frame_info *frame; +#endif +{ + TuiStatus ret = TUI_FAILURE; + + if (target_has_registers) + { + read_relative_register_raw_bytes_for_frame (regNum, regValue, frame); + ret = TUI_SUCCESS; + } + + return ret; +} /* _tuiGetRegisterRawValue */ + + + +/* +** _tuiSetRegisterElement(). +** Function to initialize a data element with the input and +** the register value. +*/ +static void +#ifdef __STDC__ +_tuiSetRegisterElement ( + int regNum, + struct frame_info *frame, + TuiDataElementPtr dataElement, + int refreshValueOnly) +#else +_tuiSetRegisterElement (regNum, frame, dataElement, refreshValueOnly) + int regNum; + struct frame_info *frame; + TuiDataElementPtr dataElement; + int refreshValueOnly; +#endif +{ + 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_RAW_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 +#ifdef __STDC__ +_tuiSetRegsContent ( + int startRegNum, + int endRegNum, + struct frame_info *frame, + TuiRegisterDisplayType dpyType, + int refreshValuesOnly) +#else +_tuiSetRegsContent (startRegNum, endRegNum, frame, dpyType, refreshValuesOnly) + int startRegNum; + int endRegNum; + struct frame_info *frame; + TuiRegisterDisplayType dpyType; + int refreshValuesOnly; +#endif +{ + 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 = + tuiCalculateRegsColumnCount (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 +#ifdef __STDC__ +_tuiDisplayRegister ( + int regNum, + TuiGenWinInfoPtr winInfo, /* the data item window */ + enum precision_type precision) +#else +_tuiDisplayRegister (regNum, winInfo, precision) + int regNum; + TuiGenWinInfoPtr winInfo; /* the data item window */ + enum precision_type precision; +#endif +{ + if (winInfo->handle != (WINDOW *) NULL) + { + char buf[100]; + 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); + + werase (winInfo->handle); + wmove (winInfo->handle, 0, 0); + waddstr (winInfo->handle, buf); + + if (dataElementPtr->highlight) + wstandend (winInfo->handle); + tuiRefreshWin (winInfo); + } + return; +} /* _tuiDisplayRegister */ + + +static void +#ifdef __STDC__ +_tui_vShowRegisters_commandSupport ( + va_list args) +#else +_tui_vShowRegisters_commandSupport (args) + va_list args; +#endif +{ + TuiRegisterDisplayType dpyType = va_arg (args, TuiRegisterDisplayType); + + if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible) + { /* Data window already displayed, show the registers */ + if (dataWin->detail.dataDisplayInfo.regsDisplayType != dpyType) + tuiShowRegisters (dpyType); + } + else + (tuiLayoutDef ())->regsDisplayType = dpyType; + + return; +} /* _tui_vShowRegisters_commandSupport */ + + +static void +#ifdef __STDC__ +_tuiShowFloat_command ( + char *arg, + int fromTTY) +#else +_tuiShowFloat_command (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + if (m_winPtrIsNull (dataWin) || !dataWin->generic.isVisible || + (dataWin->detail.dataDisplayInfo.regsDisplayType != TUI_SFLOAT_REGS && + dataWin->detail.dataDisplayInfo.regsDisplayType != TUI_DFLOAT_REGS)) + tuiDo ((TuiOpaqueFuncPtr) _tui_vShowRegisters_commandSupport, + (tuiLayoutDef ())->floatRegsDisplayType); + + return; +} /* _tuiShowFloat_command */ + + +static void +#ifdef __STDC__ +_tuiShowGeneral_command ( + char *arg, + int fromTTY) +#else +_tuiShowGeneral_command (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + tuiDo ((TuiOpaqueFuncPtr) _tui_vShowRegisters_commandSupport, + TUI_GENERAL_REGS); + + return; +} /* _tuiShowGeneral_command */ + + +static void +#ifdef __STDC__ +_tuiShowSpecial_command ( + char *arg, + int fromTTY) +#else +_tuiShowSpecial_command (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + tuiDo ((TuiOpaqueFuncPtr) _tui_vShowRegisters_commandSupport, + TUI_SPECIAL_REGS); + + return; +} /* _tuiShowSpecial_command */ + + +static void +#ifdef __STDC__ +_tuiToggleFloatRegs_command ( + char *arg, + int fromTTY) +#else +_tuiToggleFloatRegs_command (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible) + tuiDo ((TuiOpaqueFuncPtr) 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 +#ifdef __STDC__ +_tuiScrollRegsForward_command ( + char *arg, + int fromTTY) +#else +_tuiScrollRegsForward_command (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + tuiDo ((TuiOpaqueFuncPtr) tui_vScroll, FORWARD_SCROLL, dataWin, 1); + + return; +} /* _tuiScrollRegsForward_command */ + + +static void +#ifdef __STDC__ +_tuiScrollRegsBackward_command ( + char *arg, + int fromTTY) +#else +_tuiScrollRegsBackward_command (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + tuiDo ((TuiOpaqueFuncPtr) tui_vScroll, BACKWARD_SCROLL, dataWin, 1); + + return; +} /* _tuiScrollRegsBackward_command */ diff --git a/gdb/tui/tuiRegs.h b/gdb/tui/tuiRegs.h new file mode 100644 index 00000000000..4a777ec9a9b --- /dev/null +++ b/gdb/tui/tuiRegs.h @@ -0,0 +1,28 @@ +#ifndef _TUI_REGS_H +#define _TUI_REGS_H +/* +** This header file supports the display of registers in the data window. +*/ + +/***************************************** +** TYPE DEFINITIONS ** +******************************************/ + + + +/***************************************** +** PUBLIC FUNCTION EXTERNAL DECLS ** +******************************************/ +extern void tuiCheckRegisterValues PARAMS ((struct frame_info *)); +extern void tuiShowRegisters PARAMS ((TuiRegisterDisplayType)); +extern void tuiDisplayRegistersFrom PARAMS ((int)); +extern int tuiDisplayRegistersFromLine PARAMS ((int, int)); +extern int tuiLastRegsLineNo PARAMS ((void)); +extern int tuiFirstRegElementInLine PARAMS ((int)); +extern int tuiLastRegElementInLine PARAMS ((int)); +extern int tuiLineFromRegElementNo PARAMS ((int)); +extern void tuiToggleFloatRegs PARAMS ((void)); +extern int tuiCalculateRegsColumnCount PARAMS ((TuiRegisterDisplayType)); + + +#endif /*_TUI_REGS_H*/ diff --git a/gdb/tui/tuiSource.c b/gdb/tui/tuiSource.c new file mode 100644 index 00000000000..e0259d014b4 --- /dev/null +++ b/gdb/tui/tuiSource.c @@ -0,0 +1,465 @@ +/* +** tuiSource.c +** This module contains functions for displaying source in the source window +*/ + +#include "defs.h" +#include +#include "symtab.h" +#include "frame.h" +#include "breakpoint.h" + +#include "tui.h" +#include "tuiData.h" +#include "tuiStack.h" +#include "tuiSourceWin.h" +#include "tuiSource.h" + + +/***************************************** +** EXTERNAL FUNCTION DECLS ** +******************************************/ + +extern int open_source_file PARAMS ((struct symtab *)); +extern void find_source_lines PARAMS ((struct symtab *, int)); + +/***************************************** +** EXTERNAL DATA DECLS ** +******************************************/ +extern int current_source_line; +extern struct symtab *current_source_symtab; + + +/***************************************** +** STATIC LOCAL FUNCTIONS FORWARD DECLS ** +******************************************/ + +static struct breakpoint *_hasBreak PARAMS ((char *, int)); + + +/***************************************** +** STATIC LOCAL DATA ** +******************************************/ + + +/***************************************** +** PUBLIC FUNCTIONS ** +******************************************/ + +/********************************* +** SOURCE/DISASSEM FUNCTIONS ** +*********************************/ + +/* +** tuiSetSourceContent(). +** Function to display source in the source window. +*/ +TuiStatus +#ifdef __STDC__ +tuiSetSourceContent ( + struct symtab *s, + int lineNo, + int noerror) +#else +tuiSetSourceContent (s, lineNo, noerror) + struct symtab *s; + int lineNo; + int noerror; +#endif +{ + 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; + + 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 (); + /* + ** Determine the threshold for the length of the line + ** and the offset to start the display + */ + offset = srcWin->detail.sourceInfo.horizontalOffset; + threshold = (lineWidth - 1) + offset; + stream = fdopen (desc, FOPEN_RT); + clearerr (stream); + curLine = 0; + curLineNo = + srcWin->detail.sourceInfo.startLineOrAddr.lineNo = lineNo; + if (offset > 0) + srcLine = (char *) xmalloc ( + (threshold + 1) * sizeof (char)); + while (curLine < nlines) + { + TuiWinElementPtr element = (TuiWinElementPtr) + srcWin->generic.content[curLine]; + struct breakpoint *bp; + + /* 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); + bp = _hasBreak (s->filename, curLineNo); + element->whichElement.source.hasBreak = + (bp != (struct breakpoint *) NULL && + (!element->whichElement.source.isExecPoint || + (bp->disposition != del || bp->hit_count <= 0))); + 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; +} /* tuiSetSourceContent */ + + +/* 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 +#ifdef __STDC__ +tuiSetSourceContentNil ( + TuiWinInfoPtr winInfo, + char *warning_string) +#else +tuiSetSourceContentNil (winInfo, warning_string) + TuiWinInfoPtr winInfo; + char *warning_string; +#endif +{ + 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*/ + +} /*tuiSetSourceContentNil*/ + + + + +/* +** tuiShowSource(). +** Function to display source in the source window. This function +** initializes the horizontal scroll to 0. +*/ +void +#ifdef __STDC__ +tuiShowSource ( + struct symtab *s, + Opaque line, + int noerror) +#else +tuiShowSource (s, line, noerror) + struct symtab *s; + Opaque line; + int noerror; +#endif +{ + srcWin->detail.sourceInfo.horizontalOffset = 0; + m_tuiShowSourceAsIs (s, line, noerror); + + return; +} /* tuiShowSource */ + + +/* +** tuiSourceIsDisplayed(). +** Answer whether the source is currently displayed in the source window. +*/ +int +#ifdef __STDC__ +tuiSourceIsDisplayed ( + char *fname) +#else +tuiSourceIsDisplayed (fname) + char *fname; +#endif +{ + return (srcWin->generic.contentInUse && + (strcmp (((TuiWinElementPtr) (locatorWinInfoPtr ())-> + content[0])->whichElement.locator.fileName, fname) == 0)); +} /* tuiSourceIsDisplayed */ + + +/* +** tuiVerticalSourceScroll(). +** Scroll the source forward or backward vertically +*/ +void +#ifdef __STDC__ +tuiVerticalSourceScroll ( + TuiScrollDirection scrollDirection, + int numToScroll) +#else +tuiVerticalSourceScroll (scrollDirection, numToScroll) + TuiScrollDirection scrollDirection; + int numToScroll; +#endif +{ + if (srcWin->generic.content != (OpaquePtr) NULL) + { + int line; + Opaque addr; + struct symtab *s; + TuiWinContent content = (TuiWinContent) srcWin->generic.content; + + if (current_source_symtab == (struct symtab *) NULL) + s = find_pc_symtab (selected_frame->pc); + else + s = current_source_symtab; + + if (scrollDirection == FORWARD_SCROLL) + { + line = content[0]->whichElement.source.lineOrAddr.lineNo + + numToScroll; + if (line > s->nlines) + /*line = s->nlines - winInfo->generic.contentSize + 1;*/ + /*elz: fix for dts 23398*/ + line = content[0]->whichElement.source.lineOrAddr.lineNo; + } + else + { + line = content[0]->whichElement.source.lineOrAddr.lineNo - + numToScroll; + if (line <= 0) + line = 1; + } + tuiUpdateSourceWindowAsIs (srcWin, s, (Opaque) line, FALSE); + } + + return; +} /* tuiVerticalSourceScroll */ + + +/***************************************** +** STATIC LOCAL FUNCTIONS ** +******************************************/ + +/* +** _hasBreak(). +** Answer whether there is a break point at the input line in +** the source file indicated +*/ +static struct breakpoint * +#ifdef __STDC__ +_hasBreak ( + char *sourceFileName, + int lineNo) +#else +_hasBreak (sourceFileName, lineNo) + char *sourceFileName; + int lineNo; +#endif +{ + struct breakpoint *bpWithBreak = (struct breakpoint *) NULL; + struct breakpoint *bp; + extern struct breakpoint *breakpoint_chain; + + + for (bp = breakpoint_chain; + (bp != (struct breakpoint *) NULL && + bpWithBreak == (struct breakpoint *) NULL); + bp = bp->next) + if ((strcmp (sourceFileName, bp->source_file) == 0) && + (lineNo == bp->line_number)) + bpWithBreak = bp; + + return bpWithBreak; +} /* _hasBreak */ diff --git a/gdb/tui/tuiSource.h b/gdb/tui/tuiSource.h new file mode 100644 index 00000000000..f898c611c71 --- /dev/null +++ b/gdb/tui/tuiSource.h @@ -0,0 +1,27 @@ +#ifndef _TUI_SOURCE_H +#define _TUI_SOURCE_H +/* +** This header file supports +*/ + + +#include "defs.h" +#if 0 +#include "symtab.h" +#include "breakpoint.h" +#endif + +extern TuiStatus tuiSetSourceContent PARAMS ((struct symtab *, int, int)); +extern void tuiShowSource PARAMS ((struct symtab *, Opaque, int)); +extern void tuiShowSourceAsIs PARAMS ((struct symtab *, Opaque, int)); +extern int tuiSourceIsDisplayed PARAMS ((char *)); +extern void tuiVerticalSourceScroll PARAMS ((TuiScrollDirection, int)); + + +/******************* +** MACROS ** +*******************/ +#define m_tuiShowSourceAsIs(s, line, noerror) tuiUpdateSourceWindowAsIs(srcWin, s, line, noerror) + + +#endif /*_TUI_SOURCE_H*/ diff --git a/gdb/tui/tuiSourceWin.c b/gdb/tui/tuiSourceWin.c new file mode 100644 index 00000000000..e20392598ad --- /dev/null +++ b/gdb/tui/tuiSourceWin.c @@ -0,0 +1,1098 @@ +/* +** tuiSourceWin.c +** This module contains functions for displaying source or assembly in the "source" window. +* The "source" window may be the assembly or the source windows. +*/ + +#include "defs.h" +#include +#include "symtab.h" +#include "frame.h" +#include "breakpoint.h" + +#include "tui.h" +#include "tuiData.h" +#include "tuiStack.h" +#include "tuiSourceWin.h" +#include "tuiSource.h" +#include "tuiDisassem.h" + + +/***************************************** +** EXTERNAL FUNCTION DECLS ** +******************************************/ + +/***************************************** +** EXTERNAL DATA DECLS ** +******************************************/ +extern int current_source_line; +extern struct symtab *current_source_symtab; + + +/***************************************** +** STATIC LOCAL FUNCTIONS FORWARD DECLS ** +******************************************/ + +/***************************************** +** STATIC LOCAL DATA ** +******************************************/ + + +/***************************************** +** PUBLIC FUNCTIONS ** +******************************************/ + +/********************************* +** SOURCE/DISASSEM FUNCTIONS ** +*********************************/ + +/* +** tuiSrcWinIsDisplayed(). +*/ +int +#ifdef __STDC__ +tuiSrcWinIsDisplayed (void) +#else +tuiSrcWinIsDisplayed () +#endif +{ + return (m_winPtrNotNull (srcWin) && srcWin->generic.isVisible); +} /* tuiSrcWinIsDisplayed */ + + +/* +** tuiAsmWinIsDisplayed(). +*/ +int +#ifdef __STDC__ +tuiAsmWinIsDisplayed (void) +#else +tuiAsmWinIsDisplayed () +#endif +{ + return (m_winPtrNotNull (disassemWin) && disassemWin->generic.isVisible); +} /* tuiAsmWinIsDisplayed */ + + +/* +** tuiDisplayMainFunction(). +** Function to display the "main" routine" +*/ +void +#ifdef __STDC__ +tuiDisplayMainFunction (void) +#else +tuiDisplayMainFunction () +#endif +{ + if ((sourceWindows ())->count > 0) + { + CORE_ADDR addr; + + addr = parse_and_eval_address ("main"); + if (addr <= (CORE_ADDR) 0) + addr = parse_and_eval_address ("MAIN"); + if (addr > (CORE_ADDR) 0) + { + struct symtab_and_line sal; + + tuiUpdateSourceWindowsWithAddr ((Opaque) addr); + sal = find_pc_line (addr, 0); + tuiSwitchFilename (sal.symtab->filename); + } + } + + return; +} /* tuiDisplayMainFunction */ + + + +/* +** tuiUpdateSourceWindow(). +** Function to display source in the source window. This function +** initializes the horizontal scroll to 0. +*/ +void +#ifdef __STDC__ +tuiUpdateSourceWindow ( + TuiWinInfoPtr winInfo, + struct symtab *s, + Opaque lineOrAddr, + int noerror) +#else +tuiUpdateSourceWindow (winInfo, s, lineOrAddr, noerror) + TuiWinInfoPtr winInfo; + struct symtab *s; + Opaque lineOrAddr; + int noerror; +#endif +{ + 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 +#ifdef __STDC__ +tuiUpdateSourceWindowAsIs ( + TuiWinInfoPtr winInfo, + struct symtab *s, + Opaque lineOrAddr, + int noerror) +#else +tuiUpdateSourceWindowAsIs (winInfo, s, lineOrAddr, noerror) + TuiWinInfoPtr winInfo; + struct symtab *s; + Opaque lineOrAddr; + int noerror; +#endif +{ + TuiStatus ret; + + if (winInfo->generic.type == SRC_WIN) + ret = tuiSetSourceContent (s, (int) lineOrAddr, noerror); + else + ret = tuiSetDisassemContent (s, (Opaque) lineOrAddr); + + if (ret == TUI_FAILURE) + { + tuiClearSourceContent (winInfo, EMPTY_SOURCE_PROMPT); + tuiClearExecInfoContent (winInfo); + } + else + { + tuiEraseSourceContent (winInfo, NO_EMPTY_SOURCE_PROMPT); + tuiShowSourceContent (winInfo); + tuiUpdateExecInfo (winInfo); + if (winInfo->generic.type == SRC_WIN) + { + current_source_line = (int) lineOrAddr + + (winInfo->generic.contentSize - 2); + current_source_symtab = s; + /* + ** 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 +#ifdef __STDC__ +tuiUpdateSourceWindowsWithAddr ( + Opaque addr) +#else +tuiUpdateSourceWindowsWithAddr (addr) + Opaque addr; +#endif +{ + if (addr > (Opaque) NULL) + { + struct symtab_and_line sal; + + switch (currentLayout ()) + { + case DISASSEM_COMMAND: + case DISASSEM_DATA_COMMAND: + tuiShowDisassem (addr); + break; + case SRC_DISASSEM_COMMAND: + tuiShowDisassemAndUpdateSource (addr); + break; + default: + sal = find_pc_line ((CORE_ADDR) addr, 0); + tuiShowSource (sal.symtab, + (Opaque) sal.line, + 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 */ + + +/* +** tui_vUpdateSourceWindowsWithAddr() +** Update the source window with the address in a va_list +*/ +void +#ifdef __STDC__ +tui_vUpdateSourceWindowsWithAddr ( + va_list args) +#else +tui_vUpdateSourceWindowsWithAddr (args) + va_list args; +#endif +{ + Opaque addr = va_arg (args, Opaque); + + tuiUpdateSourceWindowsWithAddr (addr); + + return; +} /* tui_vUpdateSourceWindowsWithAddr */ + + +/* +** tuiUpdateSourceWindowsWithLine(). +** Function to ensure that the source and/or disassemly windows +** reflect the input address. +*/ +void +#ifdef __STDC__ +tuiUpdateSourceWindowsWithLine ( + struct symtab *s, + int line) +#else +tuiUpdateSourceWindowsWithLine (s, line) + struct symtab *s; + int line; +#endif +{ + switch (currentLayout ()) + { + case DISASSEM_COMMAND: + case DISASSEM_DATA_COMMAND: + tuiUpdateSourceWindowsWithAddr ((Opaque) find_line_pc (s, line)); + break; + default: + tuiShowSource (s, (Opaque) line, FALSE); + if (currentLayout () == SRC_DISASSEM_COMMAND) + tuiShowDisassem ((Opaque) find_line_pc (s, line)); + break; + } + + return; +} /* tuiUpdateSourceWindowsWithLine */ + + +/* +** tui_vUpdateSourceWindowsWithLine() +** Update the source window with the line number in a va_list +*/ +void +#ifdef __STDC__ +tui_vUpdateSourceWindowsWithLine ( + va_list args) +#else +tui_vUpdateSourceWindowsWithLine (args) + va_list args; +#endif +{ + struct symtab *s = va_arg (args, struct symtab *); + int line = va_arg (args, int); + + tuiUpdateSourceWindowsWithLine (s, line); + + return; +} /* tui_vUpdateSourceWindowsWithLine */ + + +/* +** tuiClearSourceContent(). +*/ +void +#ifdef __STDC__ +tuiClearSourceContent ( + TuiWinInfoPtr winInfo, + int displayPrompt) +#else +tuiClearSourceContent (winInfo, displayPrompt) + TuiWinInfoPtr winInfo; + int displayPrompt; +#endif +{ + 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 */ + + +/* +** tuiClearAllSourceWinsContent(). +*/ +void +#ifdef __STDC__ +tuiClearAllSourceWinsContent ( + int displayPrompt) +#else +tuiClearAllSourceWinsContent (displayPrompt) + int displayPrompt; +#endif +{ + int i; + + for (i = 0; i < (sourceWindows ())->count; i++) + tuiClearSourceContent ((TuiWinInfoPtr) (sourceWindows ())->list[i], + displayPrompt); + + return; +} /* tuiClearAllSourceWinsContent */ + + +/* +** tuiEraseSourceContent(). +*/ +void +#ifdef __STDC__ +tuiEraseSourceContent ( + TuiWinInfoPtr winInfo, + int displayPrompt) +#else +tuiEraseSourceContent (winInfo, displayPrompt) + TuiWinInfoPtr winInfo; + int displayPrompt; +#endif +{ + 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 */ + + +/* +** tuiEraseAllSourceContent(). +*/ +void +#ifdef __STDC__ +tuiEraseAllSourceWinsContent ( + int displayPrompt) +#else +tuiEraseAllSourceWinsContent (displayPrompt) + int displayPrompt; +#endif +{ + int i; + + for (i = 0; i < (sourceWindows ())->count; i++) + tuiEraseSourceContent ((TuiWinInfoPtr) (sourceWindows ())->list[i], + displayPrompt); + + return; +} /* tuiEraseAllSourceWinsContent */ + + +/* +** tuiShowSourceContent(). +*/ +void +#ifdef __STDC__ +tuiShowSourceContent ( + TuiWinInfoPtr winInfo) +#else +tuiShowSourceContent (winInfo) + TuiWinInfoPtr winInfo; +#endif +{ + int curLine, i, curX; + + tuiEraseSourceContent (winInfo, (winInfo->generic.contentSize <= 0)); + if (winInfo->generic.contentSize > 0) + { + char *line; + + for (curLine = 1; (curLine <= winInfo->generic.contentSize); curLine++) + mvwaddstr ( + winInfo->generic.handle, + curLine, + 1, + ((TuiWinElementPtr) + winInfo->generic.content[curLine - 1])->whichElement.source.line); + } + checkAndDisplayHighlightIfNeeded (winInfo); + tuiRefreshWin (&winInfo->generic); + winInfo->generic.contentInUse = TRUE; + + return; +} /* tuiShowSourceContent */ + + +/* +** tuiShowAllSourceWinsContent() +*/ +void +#ifdef __STDC__ +tuiShowAllSourceWinsContent (void) +#else +tuiShowAllSourceWinsContent () +#endif +{ + int i; + + for (i = 0; i < (sourceWindows ())->count; i++) + tuiShowSourceContent ((TuiWinInfoPtr) (sourceWindows ())->list[i]); + + return; +} /* tuiShowAllSourceWinsContent */ + + +/* +** tuiHorizontalSourceScroll(). +** Scroll the source forward or backward horizontally +*/ +void +#ifdef __STDC__ +tuiHorizontalSourceScroll ( + TuiWinInfoPtr winInfo, + TuiScrollDirection direction, + int numToScroll) +#else +tuiHorizontalSourceScroll (winInfo, direction, numToScroll) + TuiWinInfoPtr winInfo; + TuiScrollDirection direction; + int numToScroll; +#endif +{ + if (winInfo->generic.content != (OpaquePtr) NULL) + { + int offset; + struct symtab *s; + + if (current_source_symtab == (struct symtab *) NULL) + s = find_pc_symtab (selected_frame->pc); + else + s = current_source_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, + ((winInfo == srcWin) ? + (Opaque) ((TuiWinElementPtr) + winInfo->generic.content[0])->whichElement.source.lineOrAddr.lineNo : + (Opaque) ((TuiWinElementPtr) + winInfo->generic.content[0])->whichElement.source.lineOrAddr.addr), + (int) FALSE); + } + + return; +} /* tuiHorizontalSourceScroll */ + + +/* +** tuiSetHasExecPointAt(). +** Set or clear the hasBreak flag in the line whose line is lineNo. +*/ +void +#ifdef __STDC__ +tuiSetIsExecPointAt ( + Opaque lineOrAddr, + TuiWinInfoPtr winInfo) +#else +tuiSetIsExecPointAt (lineOrAddr, winInfo) + Opaque lineOrAddr; + TuiWinInfoPtr winInfo; +#endif +{ + int i; + TuiWinContent content = (TuiWinContent) winInfo->generic.content; + + i = 0; + while (i < winInfo->generic.contentSize) + { + if (content[i]->whichElement.source.lineOrAddr.addr == lineOrAddr) + content[i]->whichElement.source.isExecPoint = TRUE; + else + content[i]->whichElement.source.isExecPoint = FALSE; + i++; + } + + return; +} /* tuiSetIsExecPointAt */ + + +/* +** tuiSetHasBreakAt(). +** Set or clear the hasBreak flag in the line whose line is lineNo. +*/ +void +#ifdef __STDC__ +tuiSetHasBreakAt ( + struct breakpoint *bp, + TuiWinInfoPtr winInfo, + int hasBreak) +#else +tuiSetHasBreakAt (bp, winInfo, hasBreak) + struct breakpoint *bp; + TuiWinInfoPtr winInfo; + int hasBreak; +#endif +{ + int i; + TuiWinContent content = (TuiWinContent) winInfo->generic.content; + + i = 0; + while (i < winInfo->generic.contentSize) + { + int gotIt; + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + + if (winInfo == srcWin) + { + char *fileNameDisplayed = (char *) NULL; + + if (((TuiWinElementPtr) + locator->content[0])->whichElement.locator.fileName != + (char *) NULL) + fileNameDisplayed = ((TuiWinElementPtr) + locator->content[0])->whichElement.locator.fileName; + else if (current_source_symtab != (struct symtab *) NULL) + fileNameDisplayed = current_source_symtab->filename; + + gotIt = (fileNameDisplayed != (char *) NULL && + (strcmp (bp->source_file, fileNameDisplayed) == 0) && + content[i]->whichElement.source.lineOrAddr.lineNo == + bp->line_number); + } + else + gotIt = (content[i]->whichElement.source.lineOrAddr.addr + == (Opaque) bp->address); + if (gotIt) + { + content[i]->whichElement.source.hasBreak = hasBreak; + break; + } + i++; + } + + return; +} /* tuiSetHasBreakAt */ + + +/* +** tuiAllSetHasBreakAt(). +** Set or clear the hasBreak flag in all displayed source windows. +*/ +void +#ifdef __STDC__ +tuiAllSetHasBreakAt ( + struct breakpoint *bp, + int hasBreak) +#else +tuiAllSetHasBreakAt (bp, hasBreak) + struct breakpoint *bp; + int hasBreak; +#endif +{ + int i; + + for (i = 0; i < (sourceWindows ())->count; i++) + tuiSetHasBreakAt (bp, + (TuiWinInfoPtr) (sourceWindows ())->list[i], hasBreak); + + return; +} /* tuiAllSetHasBreakAt */ + + +/* +** tui_vAllSetHasBreakAt() +** Set or clear the hasBreak flag in all displayed source windows, +** with params in a va_list +*/ +void +#ifdef __STDC__ +tui_vAllSetHasBreakAt ( + va_list args) +#else +tui_vAllSetHasBreakAt (args) + va_list args; +#endif +{ + struct breakpoint *bp = va_arg (args, struct breakpoint *); + int hasBreak = va_arg (args, int); + + tuiAllSetHasBreakAt (bp, hasBreak); + + return; +} /* tui_vAllSetHasBreakAt */ + + + +/********************************* +** EXECUTION INFO FUNCTIONS ** +*********************************/ + +/* +** 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 +#ifdef __STDC__ +tuiSetExecInfoContent ( + TuiWinInfoPtr winInfo) +#else +tuiSetExecInfoContent (winInfo) + TuiWinInfoPtr winInfo; +#endif +{ + 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; + + for (i = 0; i < winInfo->generic.contentSize; i++) + { + TuiWinElementPtr element; + TuiWinElementPtr srcElement; + + element = (TuiWinElementPtr) execInfoPtr->content[i]; + srcElement = (TuiWinElementPtr) winInfo->generic.content[i]; + /* + ** First check to see if we have a breakpoint that is + ** temporary. If so, and this is our current execution point, + ** then clear the break indicator. + */ + if (srcElement->whichElement.source.hasBreak && + srcElement->whichElement.source.isExecPoint) + { + struct breakpoint *bp; + int found = FALSE; + extern struct breakpoint *breakpoint_chain; + + for (bp = breakpoint_chain; + (bp != (struct breakpoint *) NULL && !found); + bp = bp->next) + { + found = + (winInfo == srcWin && + bp->line_number == + srcElement->whichElement.source.lineOrAddr.lineNo) || + (winInfo == disassemWin && + bp->address == (CORE_ADDR) + srcElement->whichElement.source.lineOrAddr.addr); + if (found) + srcElement->whichElement.source.hasBreak = + (bp->disposition != del || bp->hit_count <= 0); + } + if (!found) + srcElement->whichElement.source.hasBreak = FALSE; + } + /* + ** Now update the exec info content based upon the state + ** of each line as indicated by the source content. + */ + if (srcElement->whichElement.source.hasBreak && + srcElement->whichElement.source.isExecPoint) + element->whichElement.simpleString = breakLocationStr (); + else if (srcElement->whichElement.source.hasBreak) + element->whichElement.simpleString = breakStr (); + else if (srcElement->whichElement.source.isExecPoint) + element->whichElement.simpleString = locationStr (); + else + element->whichElement.simpleString = blankStr (); + } + execInfoPtr->contentSize = winInfo->generic.contentSize; + } + else + ret = TUI_FAILURE; + } + + return ret; +} /* tuiSetExecInfoContent */ + + +/* +** tuiShowExecInfoContent(). +*/ +void +#ifdef __STDC__ +tuiShowExecInfoContent ( + TuiWinInfoPtr winInfo) +#else +tuiShowExecInfoContent (winInfo) + TuiWinInfoPtr winInfo; +#endif +{ + 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 */ + + +/* +** tuiShowAllExecInfosContent() +*/ +void +#ifdef __STDC__ +tuiShowAllExecInfosContent (void) +#else +tuiShowAllExecInfosContent () +#endif +{ + int i; + + for (i = 0; i < (sourceWindows ())->count; i++) + tuiShowExecInfoContent ((TuiWinInfoPtr) (sourceWindows ())->list[i]); + + return; +} /* tuiShowAllExecInfosContent */ + + +/* +** tuiEraseExecInfoContent(). +*/ +void +#ifdef __STDC__ +tuiEraseExecInfoContent ( + TuiWinInfoPtr winInfo) +#else +tuiEraseExecInfoContent (winInfo) + TuiWinInfoPtr winInfo; +#endif +{ + TuiGenWinInfoPtr execInfo = winInfo->detail.sourceInfo.executionInfo; + + werase (execInfo->handle); + tuiRefreshWin (execInfo); + + return; +} /* tuiEraseExecInfoContent */ + + +/* +** tuiEraseAllExecInfosContent() +*/ +void +#ifdef __STDC__ +tuiEraseAllExecInfosContent (void) +#else +tuiEraseAllExecInfosContent () +#endif +{ + int i; + + for (i = 0; i < (sourceWindows ())->count; i++) + tuiEraseExecInfoContent ((TuiWinInfoPtr) (sourceWindows ())->list[i]); + + return; +} /* tuiEraseAllExecInfosContent */ + + +/* +** tuiClearExecInfoContent(). +*/ +void +#ifdef __STDC__ +tuiClearExecInfoContent ( + TuiWinInfoPtr winInfo) +#else +tuiClearExecInfoContent (winInfo) + TuiWinInfoPtr winInfo; +#endif +{ + winInfo->detail.sourceInfo.executionInfo->contentInUse = FALSE; + tuiEraseExecInfoContent (winInfo); + + return; +} /* tuiClearExecInfoContent */ + + +/* +** tuiClearAllExecInfosContent() +*/ +void +#ifdef __STDC__ +tuiClearAllExecInfosContent (void) +#else +tuiClearAllExecInfosContent () +#endif +{ + int i; + + for (i = 0; i < (sourceWindows ())->count; i++) + tuiClearExecInfoContent ((TuiWinInfoPtr) (sourceWindows ())->list[i]); + + return; +} /* tuiClearAllExecInfosContent */ + + +/* +** tuiUpdateExecInfo(). +** Function to update the execution info window +*/ +void +#ifdef __STDC__ +tuiUpdateExecInfo ( + TuiWinInfoPtr winInfo) +#else +tuiUpdateExecInfo (winInfo) + TuiWinInfoPtr winInfo; +#endif +{ + tuiSetExecInfoContent (winInfo); + tuiShowExecInfoContent (winInfo); +} /* tuiUpdateExecInfo + + +/* +** tuiUpdateAllExecInfos() +*/ +void +#ifdef __STDC__ +tuiUpdateAllExecInfos (void) +#else +tuiUpdateAllExecInfos () +#endif +{ + int i; + + for (i = 0; i < (sourceWindows ())->count; i++) + tuiUpdateExecInfo ((TuiWinInfoPtr) (sourceWindows ())->list[i]); + + return; +} /* tuiUpdateAllExecInfos*/ + + + +/* tuiUpdateOnEnd() +** elz: This function clears the execution info from the source windows +** and resets the locator to display no line info, procedure info, pc +** info. It is called by stack_publish_stopped_with_no_frame, which +** is called then the target terminates execution +*/ +void +#ifdef __STDC__ +tuiUpdateOnEnd (void) +#else +tuiUpdateOnEnd () +#endif +{ + int i; + TuiGenWinInfoPtr locator; + char *filename; + TuiWinInfoPtr winInfo; + + locator = locatorWinInfoPtr (); + + /* for all the windows (src, asm) */ + for (i = 0; i < (sourceWindows ())->count; i++) + { + winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i]; + + tuiSetIsExecPointAt ((Opaque) - 1, winInfo); /* the target is'n running */ + /* -1 should not match any line number or pc */ + tuiSetExecInfoContent (winInfo); /*set winInfo so that > is'n displayed*/ + tuiShowExecInfoContent (winInfo); /* display the new contents */ + } + + /*now update the locator*/ + tuiClearLocatorDisplay (); + tuiGetLocatorFilename (locator, &filename); + tuiSetLocatorInfo ( + filename, + (char *) NULL, + 0, + (Opaque) NULL, + &((TuiWinElementPtr) locator->content[0])->whichElement.locator); + tuiShowLocatorContent (); + + return; +} /* tuiUpdateOnEnd */ + + + +TuiStatus +#ifdef __STDC__ +tuiAllocSourceBuffer ( + TuiWinInfoPtr winInfo) +#else +tuiAllocSourceBuffer (winInfo) + TuiWinInfoPtr winInfo; +#endif +{ + register char *srcLine, *srcLineBuf; + register int i, lineWidth, c, 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 +#ifdef __STDC__ +tuiLineIsDisplayed ( + Opaque lineNoOrAddr, + TuiWinInfoPtr winInfo, + int checkThreshold) +#else +tuiLineIsDisplayed (lineNoOrAddr, winInfo, checkThreshold) + Opaque lineNoOrAddr; + TuiWinInfoPtr winInfo; + int checkThreshold; +#endif +{ + int isDisplayed = FALSE; + int i, threshold; + + if (checkThreshold) + threshold = SCROLL_THRESHOLD; + else + threshold = 0; + i = 0; + while (i < winInfo->generic.contentSize - threshold && !isDisplayed) + { + if (winInfo == srcWin) + isDisplayed = (((TuiWinElementPtr) + winInfo->generic.content[i])->whichElement.source.lineOrAddr.lineNo + == (int) lineNoOrAddr); + else + isDisplayed = (((TuiWinElementPtr) + winInfo->generic.content[i])->whichElement.source.lineOrAddr.addr + == lineNoOrAddr); + i++; + } + + return isDisplayed; +} /* tuiLineIsDisplayed */ + + +/***************************************** +** STATIC LOCAL FUNCTIONS ** +******************************************/ diff --git a/gdb/tui/tuiSourceWin.h b/gdb/tui/tuiSourceWin.h new file mode 100644 index 00000000000..13f3a78ab18 --- /dev/null +++ b/gdb/tui/tuiSourceWin.h @@ -0,0 +1,74 @@ +#ifndef _TUI_SOURCEWIN_H +#define _TUI_SOURCEWIN_H +/* +** This header file supports +*/ + + +extern void tuiDisplayMainFunction PARAMS ((void)); +extern void tuiUpdateSourceWindow PARAMS + ((TuiWinInfoPtr, struct symtab *, Opaque, int)); +extern void tuiUpdateSourceWindowAsIs PARAMS + ((TuiWinInfoPtr, struct symtab *, Opaque, int)); +extern void tuiUpdateSourceWindowsWithAddr PARAMS ((Opaque)); +extern void tui_vUpdateSourceWindowsWithAddr PARAMS ((va_list)); +extern void tuiUpdateSourceWindowsWithLine PARAMS ((struct symtab *, int)); +extern void tui_vUpdateSourceWindowsWithLine PARAMS ((va_list)); +extern void tuiUpdateSourceWindowsFromLocator PARAMS ((void)); +extern void tuiClearSourceContent PARAMS ((TuiWinInfoPtr, int)); +extern void tuiClearAllSourceWinsContent PARAMS ((int)); +extern void tuiEraseSourceContent PARAMS ((TuiWinInfoPtr, int)); +extern void tuiEraseAllSourceWinsContent PARAMS ((int)); +extern void tuiSetSourceContentNil PARAMS ((TuiWinInfoPtr, char *)); +extern void tuiShowSourceContent PARAMS ((TuiWinInfoPtr)); +extern void tuiShowAllSourceWinsContent PARAMS ((void)); +extern void tuiHorizontalSourceScroll PARAMS ((TuiWinInfoPtr, TuiScrollDirection, int)); +extern void tuiUpdateOnEnd PARAMS ((void)); + +extern TuiStatus tuiSetExecInfoContent PARAMS ((TuiWinInfoPtr)); +extern void tuiShowExecInfoContent PARAMS ((TuiWinInfoPtr)); +extern void tuiShowAllExecInfosContent PARAMS ((void)); +extern void tuiEraseExecInfoContent PARAMS ((TuiWinInfoPtr)); +extern void tuiEraseAllExecInfosContent PARAMS ((void)); +extern void tuiClearExecInfoContent PARAMS ((TuiWinInfoPtr)); +extern void tuiClearAllExecInfosContent PARAMS ((void)); +extern void tuiUpdateExecInfo PARAMS ((TuiWinInfoPtr)); +extern void tuiUpdateAllExecInfos PARAMS ((void)); + +extern void tuiSetIsExecPointAt PARAMS ((Opaque, TuiWinInfoPtr)); +extern void tuiSetHasBreakAt PARAMS ((struct breakpoint *, TuiWinInfoPtr, int)); +extern void tuiAllSetHasBreakAt PARAMS ((struct breakpoint *, int)); +extern void tui_vAllSetHasBreakAt PARAMS ((va_list)); +extern TuiStatus tuiAllocSourceBuffer PARAMS ((TuiWinInfoPtr)); +extern int tuiLineIsDisplayed PARAMS ((Opaque, TuiWinInfoPtr, int)); + + +/* +** Constant definitions +*/ +#define SCROLL_THRESHOLD 2 /* threshold for lazy scroll */ + + +/* +** Macros +*/ +#define m_tuiSetBreakAt(bp, winInfo) tuiSetHasBreakAt((bp, winInfo, TRUE) +#define m_tuiClearBreakAt(bp, winInfo) tuiSetHasBreakAt(bp, winInfo, FALSE) + +#define m_tuiAllSetBreakAt(bp) tuiAllSetHasBreakAt(bp, TRUE) +#define m_tuiAllClearBreakAt(bp) tuiAllSetHasBreakAt(bp, FALSE) + +#define m_tuiSrcLineDisplayed(lineNo) tuiLineIsDisplayed((Opaque)(lineNo), srcWin, FALSE) +#define m_tuiSrcAddrDisplayed(addr) tuiLineIsDisplayed((Opaque)(addr), disassemWin, FALSE) +#define m_tuiSrcLineDisplayedWithinThreshold(lineNo) \ + tuiLineIsDisplayed((Opaque)(lineNo), srcWin, TRUE) +#define m_tuiSrcAddrDisplayedWithinThreshold(addr) \ + tuiLineIsDisplayed((Opaque)(addr), disassemWin, TRUE) +#define m_tuiLineDisplayedWithinThreshold(winInfo, lineOrAddr) \ + ( (winInfo == srcWin) ? \ + m_tuiSrcLineDisplayedWithinThreshold(lineOrAddr) : \ + m_tuiSrcAddrDisplayedWithinThreshold(lineOrAddr) ) + + + +#endif /*_TUI_SOURCEWIN_H */ diff --git a/gdb/tui/tuiStack.c b/gdb/tui/tuiStack.c new file mode 100644 index 00000000000..401dfe23d82 --- /dev/null +++ b/gdb/tui/tuiStack.c @@ -0,0 +1,554 @@ +/* +** This module contains functions for displaying the locator information in the locator window. +*/ + +#include "defs.h" +#include "symtab.h" +#include "breakpoint.h" +#include "frame.h" + +#include "tui.h" +#include "tuiData.h" +#include "tuiStack.h" +#include "tuiSourceWin.h" + + +/***************************************** +** STATIC LOCAL FUNCTIONS FORWARD DECLS ** +******************************************/ + +static char *_getFuncNameFromFrame PARAMS ((struct frame_info *)); +static void _tuiUpdateLocation_command PARAMS ((char *, int)); + + + +/***************************************** +** PUBLIC FUNCTION ** +******************************************/ + +/* +** tuiClearLocatorDisplay() +*/ +void +#ifdef __STDC__ +tuiClearLocatorDisplay (void) +#else +tuiClearLocatorDisplay () +#endif +{ + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + int i; + + if (locator->handle != (WINDOW *) NULL) + { + /* No need to werase, since writing a line of + * blanks which we do below, is equivalent. + */ + /* werase(locator->handle); */ + wmove (locator->handle, 0, 0); + wstandout (locator->handle); + for (i = 0; i < locator->width; i++) + waddch (locator->handle, ' '); + wstandend (locator->handle); + tuiRefreshWin (locator); + wmove (locator->handle, 0, 0); + locator->contentInUse = FALSE; + } + + return; +} /* tuiClearLocatorDisplay */ + + +/* +** tuiShowLocatorContent() +*/ +void +#ifdef __STDC__ +tuiShowLocatorContent (void) +#else +tuiShowLocatorContent () +#endif +{ + char *string; + TuiGenWinInfoPtr locator; + + locator = locatorWinInfoPtr (); + + if (m_genWinPtrNotNull (locator) && locator->handle != (WINDOW *) NULL) + { + string = displayableWinContentAt (locator, 0); + if (string != (char *) NULL) + { + wmove (locator->handle, 0, 0); + wstandout (locator->handle); + waddstr (locator->handle, string); + wstandend (locator->handle); + tuiRefreshWin (locator); + wmove (locator->handle, 0, 0); + if (string != nullStr ()) + tuiFree (string); + locator->contentInUse = TRUE; + } + } + + return; +} /* tuiShowLocatorContent */ + + +/* +** tuiSetLocatorInfo(). +** Function to update the locator, with the provided arguments. +*/ +void +#ifdef __STDC__ +tuiSetLocatorInfo ( + char *fname, + char *procname, + int lineNo, + Opaque addr, + TuiLocatorElementPtr element) +#else +tuiSetLocatorInfo (fname, procname, lineNo, addr, element) + char *fname; + char *procname; + int lineNo; + Opaque addr; + TuiLocatorElementPtr element; +#endif +{ +#ifdef COMMENT + /* first free the old info */ + if (element->fileName) + tuiFree (element->fileName); + if (element->procName) + tuiFree (element->procName); + + if (fname == (char *) NULL) + element->fileName = fname; + else + element->fileName = tuiStrDup (fname); + if (procname == (char *) NULL) + element->procName = procname; + else + element->procName = tuiStrDup (procname); +#else + element->fileName[0] = (char) 0; + element->procName[0] = (char) 0; + strcat_to_buf (element->fileName, MAX_LOCATOR_ELEMENT_LEN, fname); + strcat_to_buf (element->procName, MAX_LOCATOR_ELEMENT_LEN, procname); +#endif + element->lineNo = lineNo; + element->addr = (Opaque) addr; + + return; +} /* tuiSetLocatorInfo */ + + +/* +** tuiUpdateLocatorFilename(). +** Update only the filename portion of the locator. +*/ +void +#ifdef __STDC__ +tuiUpdateLocatorFilename ( + char *fileName) +#else +tuiUpdateLocatorFilename (fileName) + char *fileName; +#endif +{ + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + + if (locator->content[0] == (Opaque) NULL) + tuiSetLocatorContent ((struct frame_info *) NULL); + ((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName[0] = (char) 0; + strcat_to_buf (((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName, + MAX_LOCATOR_ELEMENT_LEN, + fileName); + + tuiShowLocatorContent (); + + return; +} /* tuiUpdateLocatorFilename */ + + +/* +** tui_vUpdateLocatorFilename(). +** Update only the filename portion of the locator with args in a va_list. +*/ +void +#ifdef __STDC__ +tui_vUpdateLocatorFilename ( + va_list args) +#else +tui_vUpdateLocatorFilename (args) + va_list args; +#endif +{ + char *fileName; + + fileName = va_arg (args, char *); + tuiUpdateLocatorFilename (fileName); + + return; +} /* tui_vUpdateLocatorFilename */ + + +/* +** tuiSwitchFilename(). +** Update the filename portion of the locator. Clear the other info in locator. +** (elz) +*/ +void +#ifdef __STDC__ +tuiSwitchFilename ( + char *fileName) +#else +tuiSwitchFilename (fileName) + char *fileName; +#endif +{ + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + + if (locator->content[0] == (Opaque) NULL) + tuiSetLocatorContent ((struct frame_info *) NULL); + ((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName[0] = (char) 0; + + tuiSetLocatorInfo (fileName, + (char *) NULL, + 0, + (Opaque) NULL, + &((TuiWinElementPtr) locator->content[0])->whichElement.locator); + + tuiShowLocatorContent (); + + return; +} /* tuiSwitchFilename */ + + +/* +** tuiGetLocatorFilename(). +** Get the filename portion of the locator. +** (elz) +*/ +void +#ifdef __STDC__ +tuiGetLocatorFilename ( + TuiGenWinInfoPtr locator, + char **filename) +#else +tuiGetLocatorFilename (locator, filename) + TuiGenWinInfoPtr locator; + char **filename; +#endif +{ + + /* the current filename could be non known, in which case the xmalloc would + allocate no memory, because the length would be 0 */ + if (((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName) + { + int name_length = + strlen (((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName); + + (*filename) = (char *) xmalloc (name_length + 1); + strcpy ((*filename), + ((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName); + } + + return; +} /* tuiGetLocatorFilename */ + + +/* +** tuiUpdateLocatorInfoFromFrame(). +** Function to update the locator, with the information extracted from frameInfo +*/ +void +#ifdef __STDC__ +tuiUpdateLocatorInfoFromFrame ( + struct frame_info *frameInfo, + TuiLocatorElementPtr element) +#else +tuiUpdateLocatorInfoFromFrame (frameInfo, element) + struct frame_info *frameInfo; + TuiLocatorElementPtr element; +#endif +{ + struct symtab_and_line symtabAndLine; + + /* now get the new info */ + symtabAndLine = find_pc_line (frameInfo->pc, + (frameInfo->next != (struct frame_info *) NULL && + !frameInfo->next->signal_handler_caller && + !frame_in_dummy (frameInfo->next))); + if (symtabAndLine.symtab && symtabAndLine.symtab->filename) + tuiSetLocatorInfo (symtabAndLine.symtab->filename, + _getFuncNameFromFrame (frameInfo), + symtabAndLine.line, + (Opaque) frameInfo->pc, + element); + else + tuiSetLocatorInfo ((char *) NULL, + _getFuncNameFromFrame (frameInfo), + 0, + (Opaque) frameInfo->pc, + element); + + return; +} /* tuiUpdateLocatorInfoFromFrame */ + + +/* +** tuiSetLocatorContent(). +** Function to set the content of the locator +*/ +void +#ifdef __STDC__ +tuiSetLocatorContent ( + struct frame_info *frameInfo) +#else +tuiSetLocatorContent (frameInfo) + struct frame_info *frameInfo; +#endif +{ + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + TuiWinElementPtr element; + struct symtab_and_line symtabAndLine; + + /* Allocate the element if necessary */ + if (locator->contentSize <= 0) + { + TuiWinContent contentPtr; + + if ((locator->content = (OpaquePtr) allocContent (1, locator->type)) == (OpaquePtr) NULL) + error ("Unable to Allocate Memory to Display Location."); + locator->contentSize = 1; + } + + if (frameInfo != (struct frame_info *) NULL) + tuiUpdateLocatorInfoFromFrame (frameInfo, + &((TuiWinElementPtr) locator->content[0])->whichElement.locator); + else + tuiSetLocatorInfo ((char *) NULL, + (char *) NULL, + 0, + (Opaque) NULL, + &((TuiWinElementPtr) locator->content[0])->whichElement.locator); + return; +} /* tuiSetLocatorContent */ + + +/* +** tuiUpdateLocatorDisplay(). +** Function to update the locator display +*/ +void +#ifdef __STDC__ +tuiUpdateLocatorDisplay ( + struct frame_info *frameInfo) +#else +tuiUpdateLocatorDisplay (frameInfo) + struct frame_info *frameInfo; +#endif +{ + tuiClearLocatorDisplay (); + tuiSetLocatorContent (frameInfo); + tuiShowLocatorContent (); + + return; +} /* tuiUpdateLocatorDisplay */ + + +/* +** tuiShowFrameInfo(). +** Function to print the frame inforrmation for the TUI. +*/ +void +#ifdef __STDC__ +tuiShowFrameInfo ( + struct frame_info *fi) +#else +tuiShowFrameInfo (fi) + struct frame_info *fi; +#endif +{ + TuiWinInfoPtr winInfo; + register int i; + + if (fi) + { + register int startLine, i; + register struct symtab *s; + CORE_ADDR low; + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + int sourceAlreadyDisplayed; + + + s = find_pc_symtab (fi->pc); + sourceAlreadyDisplayed = tuiSourceIsDisplayed (s->filename); + tuiUpdateLocatorDisplay (fi); + for (i = 0; i < (sourceWindows ())->count; i++) + { + winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i]; + if (winInfo == srcWin) + { + startLine = + (((TuiWinElementPtr) locator->content[0])->whichElement.locator.lineNo - + (winInfo->generic.viewportHeight / 2)) + 1; + if (startLine <= 0) + startLine = 1; + } + else + { + if (find_pc_partial_function (fi->pc, (char **) NULL, &low, (CORE_ADDR) NULL) == 0) + error ("No function contains program counter for selected frame.\n"); + else + low = (CORE_ADDR) tuiGetLowDisassemblyAddress ((Opaque) low, (Opaque) fi->pc); + } + + if (winInfo == srcWin) + { + if (!(sourceAlreadyDisplayed && m_tuiLineDisplayedWithinThreshold ( + winInfo, + ((TuiWinElementPtr) locator->content[0])->whichElement.locator.lineNo))) + tuiUpdateSourceWindow (winInfo, s, (Opaque) startLine, TRUE); + else + tuiSetIsExecPointAt ((Opaque) + ((TuiWinElementPtr) locator->content[0])->whichElement.locator.lineNo, + winInfo); + } + else + { + if (winInfo == disassemWin) + { + if (!m_tuiLineDisplayedWithinThreshold (winInfo, + ((TuiWinElementPtr) locator->content[0])->whichElement.locator.addr)) + tuiUpdateSourceWindow (winInfo, s, (Opaque) low, TRUE); + else + tuiSetIsExecPointAt ((Opaque) + ((TuiWinElementPtr) locator->content[0])->whichElement.locator.addr, + winInfo); + } + } + tuiUpdateExecInfo (winInfo); + } + } + else + { + tuiUpdateLocatorDisplay (fi); + for (i = 0; i < (sourceWindows ())->count; i++) + { + winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i]; + tuiClearSourceContent (winInfo, EMPTY_SOURCE_PROMPT); + tuiUpdateExecInfo (winInfo); + } + } + + return; +} /* tuiShowFrameInfo */ + + +/* +** tui_vShowFrameInfo(). +** Function to print the frame inforrmation for the TUI with args in a va_list. +*/ +void +#ifdef __STDC__ +tui_vShowFrameInfo ( + va_list args) +#else +tui_vShowFrameInfo (args) + va_list args; +#endif +{ + struct frame_info *fi; + + fi = va_arg (args, struct frame_info *); + tuiShowFrameInfo (fi); + + return; +} /* tui_vShowFrameInfo */ + + +/* +** _initialize_tuiStack(). +** Function to initialize gdb commands, for tui window stack manipulation. +*/ +void +_initialize_tuiStack () +{ + if (tui_version) + { + add_com ("update", class_tui, _tuiUpdateLocation_command, + "Update the source window and locator to display the current execution point.\n"); + } + + return; +} /* _initialize_tuiStack */ + + +/***************************************** +** STATIC LOCAL FUNCTIONS ** +******************************************/ + +/* +** _getFuncNameFromFrame(). +*/ +static char * +#ifdef __STDC__ +_getFuncNameFromFrame ( + struct frame_info *frameInfo) +#else +_getFuncNameFromFrame (frameInfo) + struct frame_info *frameInfo; +#endif +{ + char *funcName = (char *) NULL; + + find_pc_partial_function (frameInfo->pc, + &funcName, + (CORE_ADDR *) NULL, + (CORE_ADDR *) NULL); + return funcName; +} /* _getFuncNameFromFrame */ + + +/* +** _tuiUpdateLocation_command(). +** Command to update the display with the current execution point +*/ +static void +#ifdef __STDC__ +_tuiUpdateLocation_command ( + char *arg, + int fromTTY) +#else +_tuiUpdateLocation_command (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ +#ifndef TRY + extern void frame_command PARAMS ((char *, int)); + frame_command ("0", FALSE); +#else + struct frame_info *curFrame; + + /* Obtain the current execution point */ + if ((curFrame = get_current_frame ()) != (struct frame_info *) NULL) + { + struct frame_info *frame; + int curLevel = 0; + + for (frame = get_prev_frame (curLevel); + (frame != (struct frame_info *) NULL && (frame != curFrame)); + frame = get_prev_frame (frame)) + curLevel++; + + if (curFrame != (struct frame_info *) NULL) + print_frame_info (frame, curLevel, 0, 1); + } +#endif + + return; +} /* _tuiUpdateLocation_command */ diff --git a/gdb/tui/tuiStack.h b/gdb/tui/tuiStack.h new file mode 100644 index 00000000000..20e9a92c61c --- /dev/null +++ b/gdb/tui/tuiStack.h @@ -0,0 +1,22 @@ +#ifndef _TUI_STACK_H +#define _TUI_STACK_H +/* +** This header file supports +*/ + +extern void tuiSetLocatorInfo PARAMS ((char *, char *, int, Opaque, TuiLocatorElementPtr)); +extern void tuiUpdateLocatorFilename PARAMS ((char *)); +extern void tui_vUpdateLocatorFilename PARAMS ((va_list)); +extern void tuiUpdateLocatorInfoFromFrame + PARAMS ((struct frame_info *, TuiLocatorElementPtr)); +extern void tuiUpdateLocatorDisplay PARAMS ((struct frame_info *)); +extern void tuiSetLocatorContent PARAMS ((struct frame_info *)); +extern void tuiShowLocatorContent PARAMS ((void)); +extern void tuiClearLocatorContent PARAMS ((void)); +extern void tuiSwitchFilename PARAMS ((char *)); +extern void tuiShowFrameInfo PARAMS ((struct frame_info *)); +extern void tui_vShowFrameInfo PARAMS ((va_list)); +extern void tuiGetLocatorFilename PARAMS ((TuiGenWinInfoPtr, char **)); + + +#endif /*_TUI_STACK_H*/ diff --git a/gdb/tui/tuiWin.c b/gdb/tui/tuiWin.c new file mode 100644 index 00000000000..45bb0f6a4e9 --- /dev/null +++ b/gdb/tui/tuiWin.c @@ -0,0 +1,1650 @@ +/* +** tuiWin.c +** This module contains procedures for handling tui window functions +** like resize, scrolling, scrolling, changing focus, etc. +** +** Author: Susan B. Macchia +*/ + + +#include +#include "defs.h" +#include "command.h" +#include "symtab.h" +#include "breakpoint.h" +#include "frame.h" + +#include "tui.h" +#include "tuiData.h" +#include "tuiGeneralWin.h" +#include "tuiStack.h" +#include "tuiSourceWin.h" +#include "tuiDataWin.h" + +/******************************* +** External Declarations +********************************/ +extern void init_page_info (); + +/******************************* +** Static Local Decls +********************************/ +static void _makeVisibleWithNewHeight PARAMS ((TuiWinInfoPtr)); +static void _makeInvisibleAndSetNewHeight PARAMS ((TuiWinInfoPtr, int)); +static TuiStatus _tuiAdjustWinHeights PARAMS ((TuiWinInfoPtr, int)); +static int _newHeightOk PARAMS ((TuiWinInfoPtr, int)); +static void _tuiSetTabWidth_command PARAMS ((char *, int)); +static void _tuiRefreshAll_command PARAMS ((char *, int)); +static void _tuiSetWinHeight_command PARAMS ((char *, int)); +static void _tuiXDBsetWinHeight_command PARAMS ((char *, int)); +static void _tuiAllWindowsInfo PARAMS ((char *, int)); +static void _tuiSetFocus_command PARAMS ((char *, int)); +static void _tuiScrollForward_command PARAMS ((char *, int)); +static void _tuiScrollBackward_command PARAMS ((char *, int)); +static void _tuiScrollLeft_command PARAMS ((char *, int)); +static void _tuiScrollRight_command PARAMS ((char *, int)); +static void _parseScrollingArgs PARAMS ((char *, TuiWinInfoPtr *, int *)); + + +/*************************************** +** DEFINITIONS +***************************************/ +#define WIN_HEIGHT_USAGE "Usage: winheight [+ | -] <#lines>\n" +#define XDBWIN_HEIGHT_USAGE "Usage: w <#lines>\n" +#define FOCUS_USAGE "Usage: focus { | next | prev}\n" + +/*************************************** +** PUBLIC FUNCTIONS +***************************************/ + +/* +** _initialize_tuiWin(). +** Function to initialize gdb commands, for tui window manipulation. +*/ +void +_initialize_tuiWin () +{ + if (tui_version) + { + 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"); + add_com ("winheight", class_tui, _tuiSetWinHeight_command, + "Set the height of a specified window.\n\ +Usage: winheight [+ | -] <#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 { | 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"); + } + + return; +} /* _intialize_tuiWin */ + + +/* +** tuiClearWinFocusFrom +** Clear the logical focus from winInfo +*/ +void +#ifdef __STDC__ +tuiClearWinFocusFrom ( + TuiWinInfoPtr winInfo) +#else +tuiClearWinFocusFrom (winInfo) + TuiWinInfoPtr winInfo; +#endif +{ + if (m_winPtrNotNull (winInfo)) + { + if (winInfo->generic.type != CMD_WIN) + unhighlightWin (winInfo); + tuiSetWinWithFocus ((TuiWinInfoPtr) NULL); + } + + return; +} /* tuiClearWinFocusFrom */ + + +/* +** tuiClearWinFocus(). +** Clear the window that has focus. +*/ +void +#ifdef __STDC__ +tuiClearWinFocus (void) +#else +tuiClearWinFocus () +#endif +{ + tuiClearWinFocusFrom (tuiWinWithFocus ()); + + return; +} /* tuiClearWinFocus */ + + +/* +** tuiSetWinFocusTo +** Set the logical focus to winInfo +*/ +void +#ifdef __STDC__ +tuiSetWinFocusTo ( + TuiWinInfoPtr winInfo) +#else +tuiSetWinFocusTo (winInfo) + TuiWinInfoPtr winInfo; +#endif +{ + 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 */ + + +char * +#ifdef __STDC__ +tuiStrDup ( + char *str) +#else +tuiStrDup (str) + char *str; +#endif +{ + char *newStr = (char *) NULL; + + if (str != (char *) NULL) + { + newStr = (char *) xmalloc (strlen (str) + 1); + strcpy (newStr, str); + } + + return newStr; +} /* tuiStrDup */ + + +/* +** tuiScrollForward(). +*/ +void +#ifdef __STDC__ +tuiScrollForward ( + TuiWinInfoPtr winToScroll, + int numToScroll) +#else +tuiScrollForward (winToScroll, numToScroll) + TuiWinInfoPtr winToScroll; + int numToScroll; +#endif +{ + 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) + tuiVerticalDisassemScroll (FORWARD_SCROLL, _numToScroll); + else if (winToScroll == dataWin) + tuiVerticalDataScroll (FORWARD_SCROLL, _numToScroll); + } + + return; +} /* tuiScrollForward */ + + +/* +** tuiScrollBackward(). +*/ +void +#ifdef __STDC__ +tuiScrollBackward ( + TuiWinInfoPtr winToScroll, + int numToScroll) +#else +tuiScrollBackward (winToScroll, numToScroll) + TuiWinInfoPtr winToScroll; + int numToScroll; +#endif +{ + 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) + tuiVerticalDisassemScroll (BACKWARD_SCROLL, _numToScroll); + else if (winToScroll == dataWin) + tuiVerticalDataScroll (BACKWARD_SCROLL, _numToScroll); + } + return; +} /* tuiScrollBackward */ + + +/* +** tuiScrollLeft(). +*/ +void +#ifdef __STDC__ +tuiScrollLeft ( + TuiWinInfoPtr winToScroll, + int numToScroll) +#else +tuiScrollLeft (winToScroll, numToScroll) + TuiWinInfoPtr winToScroll; + int numToScroll; +#endif +{ + 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 +#ifdef __STDC__ +tuiScrollRight ( + TuiWinInfoPtr winToScroll, + int numToScroll) +#else +tuiScrollRight (winToScroll, numToScroll) + TuiWinInfoPtr winToScroll; + int numToScroll; +#endif +{ + 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_vScroll(). +** Scroll a window. Arguments are passed through a va_list. +*/ +void +#ifdef __STDC__ +tui_vScroll ( + va_list args) +#else +tui_vScroll (args) + va_list args; +#endif +{ + TuiScrollDirection direction = va_arg (args, TuiScrollDirection); + TuiWinInfoPtr winToScroll = va_arg (args, TuiWinInfoPtr); + int numToScroll = va_arg (args, int); + + 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; + } + + return; +} /* tui_vScroll */ + + +/* +** tuiRefreshAll(). +*/ +void +#ifdef __STDC__ +tuiRefreshAll (void) +#else +tuiRefreshAll () +#endif +{ + TuiWinType type; + + refreshAll (winList); + for (type = SRC_WIN; type < MAX_MAJOR_WINDOWS; type++) + { + if (winList[type]->generic.isVisible) + { + switch (type) + { + case SRC_WIN: + case DISASSEM_WIN: + tuiClearWin (&winList[type]->generic); + if (winList[type]->detail.sourceInfo.hasLocator) + tuiClearLocatorDisplay (); + tuiShowSourceContent (winList[type]); + checkAndDisplayHighlightIfNeeded (winList[type]); + tuiEraseExecInfoContent (winList[type]); + tuiUpdateExecInfo (winList[type]); + break; + case DATA_WIN: + tuiRefreshDataWin (); + break; + default: + break; + } + } + } + tuiClearLocatorDisplay (); + tuiShowLocatorContent (); + + return; +} /* tuiRefreshAll */ + + +/* +** tuiResizeAll(). +** Resize all the windows based on the the terminal size. This +** function gets called from within the readline sinwinch handler. +*/ +void +#ifdef __STDC__ +tuiResizeAll (void) +#else +tuiResizeAll () +#endif +{ + int heightDiff, widthDiff; + extern int screenheight, screenwidth; /* in readline */ + + widthDiff = screenwidth - termWidth (); + heightDiff = screenheight - termHeight (); + if (heightDiff || widthDiff) + { + TuiLayoutType curLayout = currentLayout (); + TuiWinInfoPtr winWithFocus = tuiWinWithFocus (); + TuiWinInfoPtr firstWin, secondWin; + TuiGenWinInfoPtr locator = locatorWinInfoPtr (); + TuiWinType winType; + int i, newHeight, splitDiff, cmdSplitDiff, numWinsDisplayed = 2; + + /* turn keypad off while we resize */ + if (winWithFocus != cmdWin) + keypad (cmdWin->generic.handle, FALSE); + init_page_info (); + 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 = + tuiCalculateRegsColumnCount ( + 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 +#ifdef __STDC__ +tuiSigwinchHandler ( + int signal) +#else +tuiSigwinchHandler (signal) + int signal; +#endif +{ + /* + ** 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 +#ifdef __STDC__ +_tuiScrollForward_command ( + char *arg, + int fromTTY) +#else +_tuiScrollForward_command (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + int numToScroll = 1; + TuiWinInfoPtr winToScroll; + + if (arg == (char *) NULL) + _parseScrollingArgs (arg, &winToScroll, (int *) NULL); + else + _parseScrollingArgs (arg, &winToScroll, &numToScroll); + tuiDo ((TuiOpaqueFuncPtr) tui_vScroll, + FORWARD_SCROLL, + winToScroll, + numToScroll); + + return; +} /* _tuiScrollForward_command */ + + +/* +** _tuiScrollBackward_command(). +*/ +static void +#ifdef __STDC__ +_tuiScrollBackward_command ( + char *arg, + int fromTTY) +#else +_tuiScrollBackward_command (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + int numToScroll = 1; + TuiWinInfoPtr winToScroll; + + if (arg == (char *) NULL) + _parseScrollingArgs (arg, &winToScroll, (int *) NULL); + else + _parseScrollingArgs (arg, &winToScroll, &numToScroll); + tuiDo ((TuiOpaqueFuncPtr) tui_vScroll, + BACKWARD_SCROLL, + winToScroll, + numToScroll); + + return; +} /* _tuiScrollBackward_command */ + + +/* +** _tuiScrollLeft_command(). +*/ +static void +#ifdef __STDC__ +_tuiScrollLeft_command ( + char *arg, + int fromTTY) +#else +_tuiScrollLeft_command (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + int numToScroll; + TuiWinInfoPtr winToScroll; + + _parseScrollingArgs (arg, &winToScroll, &numToScroll); + tuiDo ((TuiOpaqueFuncPtr) tui_vScroll, + LEFT_SCROLL, + winToScroll, + numToScroll); + + return; +} /* _tuiScrollLeft_command */ + + +/* +** _tuiScrollRight_command(). +*/ +static void +#ifdef __STDC__ +_tuiScrollRight_command ( + char *arg, + int fromTTY) +#else +_tuiScrollRight_command (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + int numToScroll; + TuiWinInfoPtr winToScroll; + + _parseScrollingArgs (arg, &winToScroll, &numToScroll); + tuiDo ((TuiOpaqueFuncPtr) tui_vScroll, + RIGHT_SCROLL, + winToScroll, + numToScroll); + + return; +} /* _tuiScrollRight_command */ + + +/* +** _tuiSetFocus(). +** Set focus to the window named by 'arg' +*/ +static void +#ifdef __STDC__ +_tuiSetFocus ( + char *arg, + int fromTTY) +#else +_tuiSetFocus (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + if (arg != (char *) NULL) + { + char *bufPtr = (char *) tuiStrDup (arg); + int i; + TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL; + + for (i = 0; (i < strlen (bufPtr)); i++) + bufPtr[i] = toupper (arg[i]); + + if (subsetCompare (bufPtr, "NEXT")) + winInfo = tuiNextWin (tuiWinWithFocus ()); + else if (subsetCompare (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->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 */ + + +/* +** _tui_vSetFocus() +*/ +static void +#ifdef __STDC__ +_tui_vSetFocus ( + va_list args) +#else +_tui_vSetFocus (args) + va_list args; +#endif +{ + char *arg = va_arg (args, char *); + int fromTTY = va_arg (args, int); + + _tuiSetFocus (arg, fromTTY); + + return; +} /* tui_vSetFocus */ + + +/* +** _tuiSetFocus_command() +*/ +static void +#ifdef __STDC__ +_tuiSetFocus_command ( + char *arg, + int fromTTY) +#else +_tuiSetFocus_command (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + tuiDo ((TuiOpaqueFuncPtr) _tui_vSetFocus, arg, fromTTY); + + return; +} /* tui_SetFocus */ + + +/* +** _tuiAllWindowsInfo(). +*/ +static void +#ifdef __STDC__ +_tuiAllWindowsInfo ( + char *arg, + int fromTTY) +#else +_tuiAllWindowsInfo (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + TuiWinType type; + TuiWinInfoPtr winWithFocus = tuiWinWithFocus (); + + for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++) + if (winList[type]->generic.isVisible) + { + if (winWithFocus == winList[type]) + printf_filtered (" %s\t(%d lines) \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 +#ifdef __STDC__ +_tuiRefreshAll_command ( + char *arg, + int fromTTY) +#else +_tuiRefreshAll_command (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + tuiDo ((TuiOpaqueFuncPtr) tuiRefreshAll); +} + + +/* +** _tuiSetWinTabWidth_command(). +** Set the height of the specified window. +*/ +static void +#ifdef __STDC__ +_tuiSetTabWidth_command ( + char *arg, + int fromTTY) +#else +_tuiSetTabWidth_command (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + 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 +#ifdef __STDC__ +_tuiSetWinHeight ( + char *arg, + int fromTTY) +#else +_tuiSetWinHeight (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + if (arg != (char *) NULL) + { + char *buf = tuiStrDup (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 + init_page_info (); + } + 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 */ + + +/* +** _tui_vSetWinHeight(). +** Set the height of the specified window, with va_list. +*/ +static void +#ifdef __STDC__ +_tui_vSetWinHeight ( + va_list args) +#else +_tui_vSetWinHeight (args) + va_list args; +#endif +{ + char *arg = va_arg (args, char *); + int fromTTY = va_arg (args, int); + + _tuiSetWinHeight (arg, fromTTY); + + return; +} /* _tui_vSetWinHeight */ + + +/* +** _tuiSetWinHeight_command(). +** Set the height of the specified window, with va_list. +*/ +static void +#ifdef __STDC__ +_tuiSetWinHeight_command ( + char *arg, + int fromTTY) +#else +_tuiSetWinHeight_command (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + tuiDo ((TuiOpaqueFuncPtr) _tui_vSetWinHeight, arg, fromTTY); + + return; +} /* _tuiSetWinHeight_command */ + + +/* +** _tuiXDBsetWinHeight(). +** XDB Compatibility command for setting the window height. This will +** increase or decrease the command window by the specified amount. +*/ +static void +#ifdef __STDC__ +_tuiXDBsetWinHeight ( + char *arg, + int fromTTY) +#else +_tuiXDBsetWinHeight (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + 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 */ + + +/* +** _tui_vXDBsetWinHeight(). +** Set the height of the specified window, with va_list. +*/ +static void +#ifdef __STDC__ +_tui_vXDBsetWinHeight ( + va_list args) +#else +_tui_vXDBsetWinHeight (args) + va_list args; +#endif +{ + char *arg = va_arg (args, char *); + int fromTTY = va_arg (args, int); + + _tuiXDBsetWinHeight (arg, fromTTY); + + return; +} /* _tui_vXDBsetWinHeight */ + + +/* +** _tuiSetWinHeight_command(). +** Set the height of the specified window, with va_list. +*/ +static void +#ifdef __STDC__ +_tuiXDBsetWinHeight_command ( + char *arg, + int fromTTY) +#else +_tuiXDBsetWinHeight_command (arg, fromTTY) + char *arg; + int fromTTY; +#endif +{ + tuiDo ((TuiOpaqueFuncPtr) _tui_vXDBsetWinHeight, arg, fromTTY); + + return; +} /* _tuiXDBsetWinHeight_command */ + + +/* +** _tuiAdjustWinHeights(). +** Function to adjust all window heights around the primary +*/ +static TuiStatus +#ifdef __STDC__ +_tuiAdjustWinHeights ( + TuiWinInfoPtr primaryWinInfo, + int newHeight) +#else +_tuiAdjustWinHeights (primaryWinInfo, newHeight) + TuiWinInfoPtr primaryWinInfo; + int newHeight; +#endif +{ + TuiStatus status = TUI_FAILURE; + + if (_newHeightOk (primaryWinInfo, newHeight)) + { + status = TUI_SUCCESS; + if (newHeight != primaryWinInfo->generic.height) + { + int i, 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 +#ifdef __STDC__ +_makeInvisibleAndSetNewHeight ( + TuiWinInfoPtr winInfo, + int height) +#else +_makeInvisibleAndSetNewHeight (winInfo, height) + TuiWinInfoPtr winInfo; + int height; +#endif +{ + int i; + struct symtab *s; + 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; + } + + return; +} /* _makeInvisibleAndSetNewHeight */ + + +/* +** _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 +#ifdef __STDC__ +_makeVisibleWithNewHeight ( + TuiWinInfoPtr winInfo) +#else +_makeVisibleWithNewHeight (winInfo) + TuiWinInfoPtr winInfo; +#endif +{ + int i; + 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; + + 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, + current_source_symtab, + ((winInfo->generic.type == SRC_WIN) ? + (Opaque) lineOrAddr.lineNo : + lineOrAddr.addr), + TRUE); + } + else if (selected_frame != (struct frame_info *) NULL) + { + Opaque line = 0; + extern int current_source_line; + + s = find_pc_symtab (selected_frame->pc); + if (winInfo->generic.type == SRC_WIN) + line = (Opaque) current_source_line; + else + line = (Opaque) find_line_pc (s, current_source_line); + tuiUpdateSourceWindow (winInfo, s, line, TRUE); + } + if (m_hasLocator (winInfo)) + { + m_beVisible (locatorWinInfoPtr ()); + tuiClearLocatorDisplay (); + 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 +#ifdef __STDC__ +_newHeightOk ( + TuiWinInfoPtr primaryWinInfo, + int newHeight) +#else +_newHeightOk (primaryWinInfo, newHeight) + TuiWinInfoPtr primaryWinInfo; + int newHeight; +#endif +{ + int ok = (newHeight < termHeight ()); + + if (ok) + { + int diff, curHeight; + 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; + 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. + */ + 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 +#ifdef __STDC__ +_parseScrollingArgs ( + char *arg, + TuiWinInfoPtr * winToScroll, + int *numToScroll) +#else +_parseScrollingArgs (arg, winToScroll, numToScroll) + char *arg; + TuiWinInfoPtr *winToScroll; + int *numToScroll; +#endif +{ + 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 = tuiStrDup (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; + + /* 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/tuiWin.h b/gdb/tui/tuiWin.h new file mode 100644 index 00000000000..cb8455dd8e0 --- /dev/null +++ b/gdb/tui/tuiWin.h @@ -0,0 +1,28 @@ +#ifndef _TUI_WIN_H +#define _TUI_WIN_H +/* +** This header file supports +*/ + +/***************************************** +** TYPE DEFINITIONS ** +******************************************/ + + + +/***************************************** +** PUBLIC FUNCTION EXTERNAL DECLS ** +******************************************/ +extern void tuiScrollForward PARAMS ((TuiWinInfoPtr, int)); +extern void tuiScrollBackward PARAMS ((TuiWinInfoPtr, int)); +extern void tuiScrollLeft PARAMS ((TuiWinInfoPtr, int)); +extern void tuiScrollRight PARAMS ((TuiWinInfoPtr, int)); +extern void tui_vScroll PARAMS ((va_list)); +extern void tuiSetWinFocusTo PARAMS ((TuiWinInfoPtr)); +extern void tuiClearWinFocusFrom PARAMS ((TuiWinInfoPtr)); +extern void tuiClearWinFocus PARAMS ((void)); +extern void tuiResizeAll PARAMS ((void)); +extern void tuiRefreshAll PARAMS ((void)); +extern void tuiSigwinchHandler PARAMS ((int)); + +#endif /*_TUI_WIN_H*/