/* TUI data manipulation routines. Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Contributed by Hewlett-Packard Company. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* FIXME: cagney/2002-02-28: The GDB coding standard indicates that "defs.h" should be included first. Unfortunatly some systems (currently Debian GNU/Linux) include the via and they clash with "bfd.h"'s definiton of true/false. The correct fix is to remove true/false from "bfd.h", however, until that happens, hack around it by including "config.h" and first. */ #include "config.h" #ifdef HAVE_NCURSES_H #include #else #ifdef HAVE_CURSES_H #include #endif #endif #include "defs.h" #include "tui.h" #include "tuiData.h" #include "tuiGeneralWin.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 (TuiWinContent, int, TuiWinType); static void freeContentElements (TuiWinContent, int, TuiWinType); /********************************* ** PUBLIC FUNCTIONS **********************************/ /****************************************** ** ACCESSORS & MUTATORS FOR PRIVATE DATA ******************************************/ /* ** tuiWinResized(). ** Answer a whether the terminal window has been resized or not */ int tuiWinResized (void) { return _winResized; } /* tuiWinResized */ /* ** tuiSetWinResized(). ** Set a whether the terminal window has been resized or not */ void tuiSetWinResizedTo (int resized) { _winResized = resized; return; } /* tuiSetWinResizedTo */ /* ** tuiLayoutDef(). ** Answer a pointer to the current layout definition */ TuiLayoutDefPtr tuiLayoutDef (void) { return &_layoutDef; } /* tuiLayoutDef */ /* ** tuiWinWithFocus(). ** Answer the window with the logical focus */ TuiWinInfoPtr tuiWinWithFocus (void) { return _winWithFocus; } /* tuiWinWithFocus */ /* ** tuiSetWinWithFocus(). ** Set the window that has the logical focus */ void tuiSetWinWithFocus (TuiWinInfoPtr winInfo) { _winWithFocus = winInfo; return; } /* tuiSetWinWithFocus */ /* ** tuiDefaultTabLen(). ** Answer the length in chars, of tabs */ int tuiDefaultTabLen (void) { return _defaultTabLen; } /* tuiDefaultTabLen */ /* ** tuiSetDefaultTabLen(). ** Set the length in chars, of tabs */ void tuiSetDefaultTabLen (int len) { _defaultTabLen = len; return; } /* tuiSetDefaultTabLen */ /* ** currentSourceWin() ** Accessor for the current source window. Usually there is only ** one source window (either source or disassembly), but both can ** be displayed at the same time. */ TuiListPtr sourceWindows (void) { return &_sourceWindows; } /* currentSourceWindows */ /* ** clearSourceWindows() ** Clear the list of source windows. Usually there is only one ** source window (either source or disassembly), but both can be ** displayed at the same time. */ void clearSourceWindows (void) { _sourceWindows.list[0] = (Opaque) NULL; _sourceWindows.list[1] = (Opaque) NULL; _sourceWindows.count = 0; return; } /* currentSourceWindows */ /* ** clearSourceWindowsDetail() ** Clear the pertinant detail in the source windows. */ void clearSourceWindowsDetail (void) { int i; for (i = 0; i < (sourceWindows ())->count; i++) clearWinDetail ((TuiWinInfoPtr) (sourceWindows ())->list[i]); return; } /* currentSourceWindows */ /* ** addSourceWindowToList(). ** Add a window to the list of source windows. Usually there is ** only one source window (either source or disassembly), but ** both can be displayed at the same time. */ void addToSourceWindows (TuiWinInfoPtr winInfo) { if (_sourceWindows.count < 2) _sourceWindows.list[_sourceWindows.count++] = (Opaque) winInfo; return; } /* addToSourceWindows */ /* ** clearWinDetail() ** Clear the pertinant detail in the windows. */ void clearWinDetail (TuiWinInfoPtr winInfo) { if (m_winPtrNotNull (winInfo)) { switch (winInfo->generic.type) { case SRC_WIN: case DISASSEM_WIN: winInfo->detail.sourceInfo.startLineOrAddr.addr = 0; winInfo->detail.sourceInfo.horizontalOffset = 0; break; case CMD_WIN: winInfo->detail.commandInfo.curLine = winInfo->detail.commandInfo.curch = 0; break; case DATA_WIN: winInfo->detail.dataDisplayInfo.dataContent = (TuiWinContent) NULL; winInfo->detail.dataDisplayInfo.dataContentCount = 0; winInfo->detail.dataDisplayInfo.regsContent = (TuiWinContent) NULL; winInfo->detail.dataDisplayInfo.regsContentCount = 0; winInfo->detail.dataDisplayInfo.regsDisplayType = TUI_UNDEFINED_REGS; winInfo->detail.dataDisplayInfo.regsColumnCount = 1; winInfo->detail.dataDisplayInfo.displayRegs = FALSE; break; default: break; } } return; } /* clearWinDetail */ /* ** blankStr() ** Accessor for the blank string. */ char * blankStr (void) { return _tuiBlankStr; } /* blankStr */ /* ** locationStr() ** Accessor for the location string. */ char * locationStr (void) { return _tuiLocationStr; } /* locationStr */ /* ** breakStr() ** Accessor for the break string. */ char * breakStr (void) { return _tuiBreakStr; } /* breakStr */ /* ** breakLocationStr() ** Accessor for the breakLocation string. */ char * breakLocationStr (void) { return _tuiBreakLocationStr; } /* breakLocationStr */ /* ** nullStr() ** Accessor for the null string. */ char * nullStr (void) { return _tuiNullStr; } /* nullStr */ /* ** sourceExecInfoPtr(). ** Accessor for the source execution info ptr. */ TuiGenWinInfoPtr sourceExecInfoWinPtr (void) { return &_execInfo[0]; } /* sourceExecInfoWinPtr */ /* ** disassemExecInfoPtr(). ** Accessor for the disassem execution info ptr. */ TuiGenWinInfoPtr disassemExecInfoWinPtr (void) { return &_execInfo[1]; } /* disassemExecInfoWinPtr */ /* ** locatorWinInfoPtr(). ** Accessor for the locator win info. Answers a pointer to the ** static locator win info struct. */ TuiGenWinInfoPtr locatorWinInfoPtr (void) { return &_locator; } /* locatorWinInfoPtr */ /* ** historyLimit(). ** Accessor for the history limit */ int historyLimit (void) { return _historyLimit; } /* historyLimit */ /* ** setHistoryLimitTo(). ** Mutator for the history limit */ void setHistoryLimitTo (int h) { _historyLimit = h; return; } /* setHistoryLimitTo */ /* ** termHeight(). ** Accessor for the termHeight */ int termHeight (void) { return _termHeight; } /* termHeight */ /* ** setTermHeightTo(). ** Mutator for the term height */ void setTermHeightTo (int h) { _termHeight = h; return; } /* setTermHeightTo */ /* ** termWidth(). ** Accessor for the termWidth */ int termWidth (void) { return _termWidth; } /* termWidth */ /* ** setTermWidth(). ** Mutator for the termWidth */ void setTermWidthTo (int w) { _termWidth = w; return; } /* setTermWidthTo */ /* ** currentLayout(). ** Accessor for the current layout */ TuiLayoutType currentLayout (void) { return _currentLayout; } /* currentLayout */ /* ** setCurrentLayoutTo(). ** Mutator for the current layout */ void setCurrentLayoutTo (TuiLayoutType newLayout) { _currentLayout = newLayout; return; } /* setCurrentLayoutTo */ /* ** setGenWinOrigin(). ** Set the origin of the window */ void setGenWinOrigin (TuiGenWinInfoPtr winInfo, int x, int y) { winInfo->origin.x = x; winInfo->origin.y = y; return; } /* setGenWinOrigin */ /***************************** ** OTHER PUBLIC FUNCTIONS *****************************/ /* ** tuiNextWin(). ** Answer the next window in the list, cycling back to the top ** if necessary */ TuiWinInfoPtr tuiNextWin (TuiWinInfoPtr curWin) { TuiWinType type = curWin->generic.type; TuiWinInfoPtr nextWin = (TuiWinInfoPtr) NULL; if (curWin->generic.type == CMD_WIN) type = SRC_WIN; else type = curWin->generic.type + 1; while (type != curWin->generic.type && m_winPtrIsNull (nextWin)) { if (winList[type] && winList[type]->generic.isVisible) nextWin = winList[type]; else { if (type == CMD_WIN) type = SRC_WIN; else type++; } } return nextWin; } /* tuiNextWin */ /* ** tuiPrevWin(). ** Answer the prev window in the list, cycling back to the bottom ** if necessary */ TuiWinInfoPtr tuiPrevWin (TuiWinInfoPtr curWin) { TuiWinType type = curWin->generic.type; TuiWinInfoPtr prev = (TuiWinInfoPtr) NULL; if (curWin->generic.type == SRC_WIN) type = CMD_WIN; else type = curWin->generic.type - 1; while (type != curWin->generic.type && m_winPtrIsNull (prev)) { if (winList[type]->generic.isVisible) prev = winList[type]; else { if (type == SRC_WIN) type = CMD_WIN; else type--; } } return prev; } /* 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 * displayableWinContentOf (TuiGenWinInfoPtr winInfo, TuiWinElementPtr elementPtr) { 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 != 0) sprintf (pc, "0x%lx", (long) 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 * displayableWinContentAt (TuiGenWinInfoPtr winInfo, int index) { return (displayableWinContentOf (winInfo, (TuiWinElementPtr) winInfo->content[index])); } /* winContentAt */ /* ** winElementHeight(). ** Answer the height of the element in lines */ int winElementHeight (TuiGenWinInfoPtr winInfo, TuiWinElementPtr element) { 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 winByName (char *name) { 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 partialWinByName (char *name) { TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL; if (name != (char *) NULL) { int i = 0; while (i < MAX_MAJOR_WINDOWS && m_winPtrIsNull (winInfo)) { if (winList[i] != 0) { char *curName = winName (&winList[i]->generic); if (strlen (name) <= strlen (curName) && strncmp (name, curName, strlen (name)) == 0) winInfo = winList[i]; } i++; } } return winInfo; } /* partialWinByName */ /* ** winName(). ** Answer the name of the window */ char * winName (TuiGenWinInfoPtr winInfo) { char *name = (char *) NULL; switch (winInfo->type) { case SRC_WIN: name = SRC_NAME; break; case CMD_WIN: name = CMD_NAME; break; case DISASSEM_WIN: name = DISASSEM_NAME; break; case DATA_WIN: name = DATA_NAME; break; default: name = ""; break; } return name; } /* winName */ /* ** initializeStaticData */ void initializeStaticData (void) { initGenericPart (sourceExecInfoWinPtr ()); initGenericPart (disassemExecInfoWinPtr ()); initGenericPart (locatorWinInfoPtr ()); return; } /* initializeStaticData */ /* ** allocGenericWinInfo(). */ TuiGenWinInfoPtr allocGenericWinInfo (void) { TuiGenWinInfoPtr win; if ((win = (TuiGenWinInfoPtr) xmalloc ( sizeof (TuiGenWinInfoPtr))) != (TuiGenWinInfoPtr) NULL) initGenericPart (win); return win; } /* allocGenericWinInfo */ /* ** initGenericPart(). */ void initGenericPart (TuiGenWinInfoPtr win) { win->width = win->height = win->origin.x = win->origin.y = win->viewportHeight = win->contentSize = win->lastVisibleLine = 0; win->handle = (WINDOW *) NULL; win->content = (OpaquePtr) NULL; win->contentInUse = win->isVisible = FALSE; win->title = 0; } /* ** initContentElement(). */ void initContentElement (TuiWinElementPtr element, TuiWinType type) { element->highlight = FALSE; switch (type) { case SRC_WIN: case DISASSEM_WIN: element->whichElement.source.line = (char *) NULL; element->whichElement.source.lineOrAddr.lineNo = 0; element->whichElement.source.isExecPoint = FALSE; element->whichElement.source.hasBreak = FALSE; break; case DATA_WIN: initGenericPart (&element->whichElement.dataWindow); element->whichElement.dataWindow.type = DATA_ITEM_WIN; ((TuiGenWinInfoPtr) & element->whichElement.dataWindow)->content = (OpaquePtr) allocContent (1, DATA_ITEM_WIN); ((TuiGenWinInfoPtr) & element->whichElement.dataWindow)->contentSize = 1; break; case CMD_WIN: element->whichElement.command.line = (char *) NULL; break; case DATA_ITEM_WIN: element->whichElement.data.name = (char *) NULL; element->whichElement.data.type = TUI_REGISTER; element->whichElement.data.itemNo = UNDEFINED_ITEM; element->whichElement.data.value = (Opaque) NULL; element->whichElement.data.highlight = FALSE; break; case LOCATOR_WIN: element->whichElement.locator.fileName[0] = element->whichElement.locator.procName[0] = (char) 0; element->whichElement.locator.lineNo = 0; element->whichElement.locator.addr = 0; break; case EXEC_INFO_WIN: element->whichElement.simpleString = blankStr (); break; default: break; } return; } /* initContentElement */ /* ** initWinInfo(). */ void initWinInfo (TuiWinInfoPtr winInfo) { initGenericPart (&winInfo->generic); winInfo->canHighlight = winInfo->isHighlighted = FALSE; switch (winInfo->generic.type) { case SRC_WIN: case DISASSEM_WIN: winInfo->detail.sourceInfo.executionInfo = (TuiGenWinInfoPtr) NULL; winInfo->detail.sourceInfo.hasLocator = FALSE; winInfo->detail.sourceInfo.horizontalOffset = 0; winInfo->detail.sourceInfo.startLineOrAddr.addr = 0; winInfo->detail.sourceInfo.filename = 0; break; case DATA_WIN: winInfo->detail.dataDisplayInfo.dataContent = (TuiWinContent) NULL; winInfo->detail.dataDisplayInfo.dataContentCount = 0; winInfo->detail.dataDisplayInfo.regsContent = (TuiWinContent) NULL; winInfo->detail.dataDisplayInfo.regsContentCount = 0; winInfo->detail.dataDisplayInfo.regsDisplayType = TUI_UNDEFINED_REGS; winInfo->detail.dataDisplayInfo.regsColumnCount = 1; winInfo->detail.dataDisplayInfo.displayRegs = FALSE; break; case CMD_WIN: winInfo->detail.commandInfo.curLine = 0; winInfo->detail.commandInfo.curch = 0; break; default: winInfo->detail.opaque = (Opaque) NULL; break; } return; } /* initWinInfo */ /* ** allocWinInfo(). */ TuiWinInfoPtr allocWinInfo (TuiWinType type) { TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL; winInfo = (TuiWinInfoPtr) xmalloc (sizeof (TuiWinInfo)); if (m_winPtrNotNull (winInfo)) { winInfo->generic.type = type; initWinInfo (winInfo); } return winInfo; } /* allocWinInfo */ /* ** allocContent(). ** Allocates the content and elements in a block. */ TuiWinContent allocContent (int numElements, TuiWinType type) { TuiWinContent content = (TuiWinContent) NULL; char *elementBlockPtr = (char *) NULL; int i; if ((content = (TuiWinContent) xmalloc (sizeof (TuiWinElementPtr) * numElements)) != (TuiWinContent) NULL) { /* ** All windows, except the data window, can allocate the elements ** in a chunk. The data window cannot because items can be ** added/removed from the data display by the user at any time. */ if (type != DATA_WIN) { if ((elementBlockPtr = (char *) xmalloc (sizeof (TuiWinElement) * numElements)) != (char *) NULL) { for (i = 0; i < numElements; i++) { content[i] = (TuiWinElementPtr) elementBlockPtr; initContentElement (content[i], type); elementBlockPtr += sizeof (TuiWinElement); } } else { tuiFree ((char *) content); content = (TuiWinContent) NULL; } } } return content; } /* allocContent */ /* ** addContentElements(). ** Adds the input number of elements to the windows's content. If ** no content has been allocated yet, allocContent() is called to ** do this. The index of the first element added is returned, ** unless there is a memory allocation error, in which case, (-1) ** is returned. */ int addContentElements (TuiGenWinInfoPtr winInfo, int numElements) { TuiWinElementPtr elementPtr; int i, indexStart; if (winInfo->content == (OpaquePtr) NULL) { winInfo->content = (OpaquePtr) allocContent (numElements, winInfo->type); indexStart = 0; } else indexStart = winInfo->contentSize; if (winInfo->content != (OpaquePtr) NULL) { for (i = indexStart; (i < numElements + indexStart); i++) { if ((elementPtr = (TuiWinElementPtr) xmalloc (sizeof (TuiWinElement))) != (TuiWinElementPtr) NULL) { winInfo->content[i] = (Opaque) elementPtr; initContentElement (elementPtr, winInfo->type); winInfo->contentSize++; } else /* things must be really hosed now! We ran out of memory!? */ return (-1); } } return indexStart; } /* addContentElements */ /* Delete all curses windows associated with winInfo, leaving everything else intact. */ void tuiDelWindow (TuiWinInfoPtr winInfo) { TuiGenWinInfoPtr genericWin; switch (winInfo->generic.type) { case SRC_WIN: case DISASSEM_WIN: genericWin = locatorWinInfoPtr (); if (genericWin != (TuiGenWinInfoPtr) NULL) { tuiDelwin (genericWin->handle); genericWin->handle = (WINDOW *) NULL; genericWin->isVisible = FALSE; } if (winInfo->detail.sourceInfo.filename) { xfree (winInfo->detail.sourceInfo.filename); winInfo->detail.sourceInfo.filename = 0; } genericWin = winInfo->detail.sourceInfo.executionInfo; if (genericWin != (TuiGenWinInfoPtr) NULL) { tuiDelwin (genericWin->handle); genericWin->handle = (WINDOW *) NULL; genericWin->isVisible = FALSE; } break; case DATA_WIN: if (winInfo->generic.content != (OpaquePtr) NULL) { tuiDelDataWindows (winInfo->detail.dataDisplayInfo.regsContent, winInfo->detail.dataDisplayInfo.regsContentCount); tuiDelDataWindows (winInfo->detail.dataDisplayInfo.dataContent, winInfo->detail.dataDisplayInfo.dataContentCount); } break; default: break; } if (winInfo->generic.handle != (WINDOW *) NULL) { tuiDelwin (winInfo->generic.handle); winInfo->generic.handle = (WINDOW *) NULL; winInfo->generic.isVisible = FALSE; } } /* ** freeWindow(). */ void freeWindow (TuiWinInfoPtr winInfo) { TuiGenWinInfoPtr genericWin; switch (winInfo->generic.type) { case SRC_WIN: case DISASSEM_WIN: genericWin = locatorWinInfoPtr (); if (genericWin != (TuiGenWinInfoPtr) NULL) { tuiDelwin (genericWin->handle); genericWin->handle = (WINDOW *) NULL; } freeWinContent (genericWin); if (winInfo->detail.sourceInfo.filename) { xfree (winInfo->detail.sourceInfo.filename); winInfo->detail.sourceInfo.filename = 0; } genericWin = winInfo->detail.sourceInfo.executionInfo; if (genericWin != (TuiGenWinInfoPtr) NULL) { tuiDelwin (genericWin->handle); genericWin->handle = (WINDOW *) NULL; freeWinContent (genericWin); } break; case DATA_WIN: if (winInfo->generic.content != (OpaquePtr) NULL) { freeDataContent ( winInfo->detail.dataDisplayInfo.regsContent, winInfo->detail.dataDisplayInfo.regsContentCount); winInfo->detail.dataDisplayInfo.regsContent = (TuiWinContent) NULL; winInfo->detail.dataDisplayInfo.regsContentCount = 0; freeDataContent ( winInfo->detail.dataDisplayInfo.dataContent, winInfo->detail.dataDisplayInfo.dataContentCount); winInfo->detail.dataDisplayInfo.dataContent = (TuiWinContent) NULL; winInfo->detail.dataDisplayInfo.dataContentCount = 0; winInfo->detail.dataDisplayInfo.regsDisplayType = TUI_UNDEFINED_REGS; winInfo->detail.dataDisplayInfo.regsColumnCount = 1; winInfo->detail.dataDisplayInfo.displayRegs = FALSE; winInfo->generic.content = (OpaquePtr) NULL; winInfo->generic.contentSize = 0; } break; default: break; } if (winInfo->generic.handle != (WINDOW *) NULL) { tuiDelwin (winInfo->generic.handle); winInfo->generic.handle = (WINDOW *) NULL; freeWinContent (&winInfo->generic); } if (winInfo->generic.title) xfree (winInfo->generic.title); xfree (winInfo); } /* ** freeAllSourceWinsContent(). */ void freeAllSourceWinsContent (void) { int i; for (i = 0; i < (sourceWindows ())->count; i++) { TuiWinInfoPtr winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i]; if (m_winPtrNotNull (winInfo)) { freeWinContent (&(winInfo->generic)); freeWinContent (winInfo->detail.sourceInfo.executionInfo); } } return; } /* freeAllSourceWinsContent */ /* ** freeWinContent(). */ void freeWinContent (TuiGenWinInfoPtr winInfo) { if (winInfo->content != (OpaquePtr) NULL) { freeContent ((TuiWinContent) winInfo->content, winInfo->contentSize, winInfo->type); winInfo->content = (OpaquePtr) NULL; } winInfo->contentSize = 0; return; } /* freeWinContent */ /* ** freeAllWindows(). */ void freeAllWindows (void) { 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 tuiDelDataWindows (TuiWinContent content, int contentSize) { int i; /* ** Remember that data window content elements are of type TuiGenWinInfoPtr, ** each of which whose single element is a data element. */ for (i = 0; i < contentSize; i++) { TuiGenWinInfoPtr genericWin = &content[i]->whichElement.dataWindow; if (genericWin != (TuiGenWinInfoPtr) NULL) { tuiDelwin (genericWin->handle); genericWin->handle = (WINDOW *) NULL; genericWin->isVisible = FALSE; } } return; } /* tuiDelDataWindows */ void freeDataContent (TuiWinContent content, int contentSize) { int i; /* ** Remember that data window content elements are of type TuiGenWinInfoPtr, ** each of which whose single element is a data element. */ for (i = 0; i < contentSize; i++) { TuiGenWinInfoPtr genericWin = &content[i]->whichElement.dataWindow; if (genericWin != (TuiGenWinInfoPtr) NULL) { tuiDelwin (genericWin->handle); genericWin->handle = (WINDOW *) NULL; freeWinContent (genericWin); } } freeContent (content, contentSize, DATA_WIN); return; } /* freeDataContent */ /********************************** ** LOCAL STATIC FUNCTIONS ** **********************************/ /* ** freeContent(). */ static void freeContent (TuiWinContent content, int contentSize, TuiWinType winType) { if (content != (TuiWinContent) NULL) { freeContentElements (content, contentSize, winType); tuiFree ((char *) content); } return; } /* freeContent */ /* ** freeContentElements(). */ static void freeContentElements (TuiWinContent content, int contentSize, TuiWinType type) { if (content != (TuiWinContent) NULL) { int i; if (type == SRC_WIN || type == DISASSEM_WIN) { /* free whole source block */ if (content[0]->whichElement.source.line != (char *) NULL) tuiFree (content[0]->whichElement.source.line); } else { for (i = 0; i < contentSize; i++) { TuiWinElementPtr element; element = content[i]; if (element != (TuiWinElementPtr) NULL) { switch (type) { case DATA_WIN: tuiFree ((char *) element); break; case DATA_ITEM_WIN: /* ** Note that data elements are not allocated ** in a single block, but individually, as needed. */ if (element->whichElement.data.type != TUI_REGISTER) tuiFree ((char *) element->whichElement.data.name); tuiFree ((char *) element->whichElement.data.value); tuiFree ((char *) element); break; case CMD_WIN: tuiFree ((char *) element->whichElement.command.line); break; default: break; } } } } if (type != DATA_WIN && type != DATA_ITEM_WIN) tuiFree ((char *) content[0]); /* free the element block */ } return; } /* freeContentElements */