2004-02-06 Andrew Cagney <cagney@redhat.com>
[external/binutils.git] / gdb / tui / tui-data.c
1 /* TUI data manipulation routines.
2
3    Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation,
4    Inc.
5
6    Contributed by Hewlett-Packard Company.
7
8    This file is part of GDB.
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 2 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330,
23    Boston, MA 02111-1307, USA.  */
24
25 #include "defs.h"
26 #include "symtab.h"
27 #include "tui/tui.h"
28 #include "tui/tui-data.h"
29 #include "tui/tui-wingeneral.h"
30
31 #ifdef HAVE_NCURSES_H       
32 #include <ncurses.h>
33 #else
34 #ifdef HAVE_CURSES_H
35 #include <curses.h>
36 #endif
37 #endif
38
39 /****************************
40 ** GLOBAL DECLARATIONS
41 ****************************/
42 TuiWinInfoPtr winList[MAX_MAJOR_WINDOWS];
43
44 /***************************
45 ** Private data
46 ****************************/
47 static TuiLayoutType _currentLayout = UNDEFINED_LAYOUT;
48 static int _termHeight, _termWidth;
49 static TuiGenWinInfo _locator;
50 static TuiGenWinInfo _execInfo[2];
51 static TuiWinInfoPtr _srcWinList[2];
52 static TuiList _sourceWindows =
53 {(OpaqueList) _srcWinList, 0};
54 static int _defaultTabLen = DEFAULT_TAB_LEN;
55 static TuiWinInfoPtr _winWithFocus = (TuiWinInfoPtr) NULL;
56 static TuiLayoutDef _layoutDef =
57 {SRC_WIN,                       /* displayMode */
58  FALSE,                         /* split */
59  TUI_UNDEFINED_REGS,            /* regsDisplayType */
60  TUI_SFLOAT_REGS};              /* floatRegsDisplayType */
61 static int _winResized = FALSE;
62
63
64 /*********************************
65 ** Static function forward decls
66 **********************************/
67 static void freeContent (TuiWinContent, int, TuiWinType);
68 static void freeContentElements (TuiWinContent, int, TuiWinType);
69
70
71
72 /*********************************
73 ** PUBLIC FUNCTIONS
74 **********************************/
75
76 /******************************************
77 ** ACCESSORS & MUTATORS FOR PRIVATE DATA
78 ******************************************/
79
80 /*
81    ** tuiWinResized().
82    **        Answer a whether the terminal window has been resized or not
83  */
84 int
85 tuiWinResized (void)
86 {
87   return _winResized;
88 }                               /* tuiWinResized */
89
90
91 /*
92    ** tuiSetWinResized().
93    **        Set a whether the terminal window has been resized or not
94  */
95 void
96 tuiSetWinResizedTo (int resized)
97 {
98   _winResized = resized;
99
100   return;
101 }                               /* tuiSetWinResizedTo */
102
103
104 /*
105    ** tuiLayoutDef().
106    **        Answer a pointer to the current layout definition
107  */
108 TuiLayoutDefPtr
109 tuiLayoutDef (void)
110 {
111   return &_layoutDef;
112 }                               /* tuiLayoutDef */
113
114
115 /*
116    ** tuiWinWithFocus().
117    **        Answer the window with the logical focus
118  */
119 TuiWinInfoPtr
120 tuiWinWithFocus (void)
121 {
122   return _winWithFocus;
123 }                               /* tuiWinWithFocus */
124
125
126 /*
127    ** tuiSetWinWithFocus().
128    **        Set the window that has the logical focus
129  */
130 void
131 tuiSetWinWithFocus (TuiWinInfoPtr winInfo)
132 {
133   _winWithFocus = winInfo;
134
135   return;
136 }                               /* tuiSetWinWithFocus */
137
138
139 /*
140    ** tuiDefaultTabLen().
141    **        Answer the length in chars, of tabs
142  */
143 int
144 tuiDefaultTabLen (void)
145 {
146   return _defaultTabLen;
147 }                               /* tuiDefaultTabLen */
148
149
150 /*
151    ** tuiSetDefaultTabLen().
152    **        Set the length in chars, of tabs
153  */
154 void
155 tuiSetDefaultTabLen (int len)
156 {
157   _defaultTabLen = len;
158
159   return;
160 }                               /* tuiSetDefaultTabLen */
161
162
163 /*
164    ** currentSourceWin()
165    **        Accessor for the current source window.  Usually there is only
166    **        one source window (either source or disassembly), but both can
167    **        be displayed at the same time.
168  */
169 TuiListPtr
170 sourceWindows (void)
171 {
172   return &_sourceWindows;
173 }                               /* currentSourceWindows */
174
175
176 /*
177    ** clearSourceWindows()
178    **        Clear the list of source windows.  Usually there is only one
179    **        source window (either source or disassembly), but both can be
180    **        displayed at the same time.
181  */
182 void
183 clearSourceWindows (void)
184 {
185   _sourceWindows.list[0] = (Opaque) NULL;
186   _sourceWindows.list[1] = (Opaque) NULL;
187   _sourceWindows.count = 0;
188
189   return;
190 }                               /* currentSourceWindows */
191
192
193 /*
194    ** clearSourceWindowsDetail()
195    **        Clear the pertinant detail in the source windows.
196  */
197 void
198 clearSourceWindowsDetail (void)
199 {
200   int i;
201
202   for (i = 0; i < (sourceWindows ())->count; i++)
203     clearWinDetail ((TuiWinInfoPtr) (sourceWindows ())->list[i]);
204
205   return;
206 }                               /* currentSourceWindows */
207
208
209 /*
210    ** addSourceWindowToList().
211    **       Add a window to the list of source windows.  Usually there is
212    **       only one source window (either source or disassembly), but
213    **       both can be displayed at the same time.
214  */
215 void
216 addToSourceWindows (TuiWinInfoPtr winInfo)
217 {
218   if (_sourceWindows.count < 2)
219     _sourceWindows.list[_sourceWindows.count++] = (Opaque) winInfo;
220
221   return;
222 }                               /* addToSourceWindows */
223
224
225 /*
226    ** clearWinDetail()
227    **        Clear the pertinant detail in the windows.
228  */
229 void
230 clearWinDetail (TuiWinInfoPtr winInfo)
231 {
232   if (m_winPtrNotNull (winInfo))
233     {
234       switch (winInfo->generic.type)
235         {
236         case SRC_WIN:
237         case DISASSEM_WIN:
238           winInfo->detail.sourceInfo.startLineOrAddr.addr = 0;
239           winInfo->detail.sourceInfo.horizontalOffset = 0;
240           break;
241         case CMD_WIN:
242           winInfo->detail.commandInfo.curLine =
243             winInfo->detail.commandInfo.curch = 0;
244           break;
245         case DATA_WIN:
246           winInfo->detail.dataDisplayInfo.dataContent =
247             (TuiWinContent) NULL;
248           winInfo->detail.dataDisplayInfo.dataContentCount = 0;
249           winInfo->detail.dataDisplayInfo.regsContent =
250             (TuiWinContent) NULL;
251           winInfo->detail.dataDisplayInfo.regsContentCount = 0;
252           winInfo->detail.dataDisplayInfo.regsDisplayType =
253             TUI_UNDEFINED_REGS;
254           winInfo->detail.dataDisplayInfo.regsColumnCount = 1;
255           winInfo->detail.dataDisplayInfo.displayRegs = FALSE;
256           break;
257         default:
258           break;
259         }
260     }
261
262   return;
263 }                               /* clearWinDetail */
264
265
266 /*
267    ** sourceExecInfoPtr().
268    **        Accessor for the source execution info ptr.
269  */
270 TuiGenWinInfoPtr
271 sourceExecInfoWinPtr (void)
272 {
273   return &_execInfo[0];
274 }                               /* sourceExecInfoWinPtr */
275
276
277 /*
278    ** disassemExecInfoPtr().
279    **        Accessor for the disassem execution info ptr.
280  */
281 TuiGenWinInfoPtr
282 disassemExecInfoWinPtr (void)
283 {
284   return &_execInfo[1];
285 }                               /* disassemExecInfoWinPtr */
286
287
288 /*
289    ** locatorWinInfoPtr().
290    **        Accessor for the locator win info.  Answers a pointer to the
291    **        static locator win info struct.
292  */
293 TuiGenWinInfoPtr
294 locatorWinInfoPtr (void)
295 {
296   return &_locator;
297 }                               /* locatorWinInfoPtr */
298
299
300 /*
301    ** termHeight().
302    **        Accessor for the termHeight
303  */
304 int
305 termHeight (void)
306 {
307   return _termHeight;
308 }                               /* termHeight */
309
310
311 /*
312    ** setTermHeightTo().
313    **        Mutator for the term height
314  */
315 void
316 setTermHeightTo (int h)
317 {
318   _termHeight = h;
319
320   return;
321 }                               /* setTermHeightTo */
322
323
324 /*
325    ** termWidth().
326    **        Accessor for the termWidth
327  */
328 int
329 termWidth (void)
330 {
331   return _termWidth;
332 }                               /* termWidth */
333
334
335 /*
336    ** setTermWidth().
337    **        Mutator for the termWidth
338  */
339 void
340 setTermWidthTo (int w)
341 {
342   _termWidth = w;
343
344   return;
345 }                               /* setTermWidthTo */
346
347
348 /*
349    ** currentLayout().
350    **        Accessor for the current layout
351  */
352 TuiLayoutType
353 currentLayout (void)
354 {
355   return _currentLayout;
356 }                               /* currentLayout */
357
358
359 /*
360    ** setCurrentLayoutTo().
361    **        Mutator for the current layout
362  */
363 void
364 setCurrentLayoutTo (TuiLayoutType newLayout)
365 {
366   _currentLayout = newLayout;
367
368   return;
369 }                               /* setCurrentLayoutTo */
370
371
372 /*
373    ** setGenWinOrigin().
374    **        Set the origin of the window
375  */
376 void
377 setGenWinOrigin (TuiGenWinInfoPtr winInfo, int x, int y)
378 {
379   winInfo->origin.x = x;
380   winInfo->origin.y = y;
381
382   return;
383 }                               /* setGenWinOrigin */
384
385
386 /*****************************
387 ** OTHER PUBLIC FUNCTIONS
388 *****************************/
389
390
391 /*
392    ** tuiNextWin().
393    **        Answer the next window in the list, cycling back to the top
394    **        if necessary
395  */
396 TuiWinInfoPtr
397 tuiNextWin (TuiWinInfoPtr curWin)
398 {
399   TuiWinType type = curWin->generic.type;
400   TuiWinInfoPtr nextWin = (TuiWinInfoPtr) NULL;
401
402   if (curWin->generic.type == CMD_WIN)
403     type = SRC_WIN;
404   else
405     type = curWin->generic.type + 1;
406   while (type != curWin->generic.type && m_winPtrIsNull (nextWin))
407     {
408       if (winList[type] && winList[type]->generic.isVisible)
409         nextWin = winList[type];
410       else
411         {
412           if (type == CMD_WIN)
413             type = SRC_WIN;
414           else
415             type++;
416         }
417     }
418
419   return nextWin;
420 }                               /* tuiNextWin */
421
422
423 /*
424    ** tuiPrevWin().
425    **        Answer the prev window in the list, cycling back to the bottom
426    **        if necessary
427  */
428 TuiWinInfoPtr
429 tuiPrevWin (TuiWinInfoPtr curWin)
430 {
431   TuiWinType type = curWin->generic.type;
432   TuiWinInfoPtr prev = (TuiWinInfoPtr) NULL;
433
434   if (curWin->generic.type == SRC_WIN)
435     type = CMD_WIN;
436   else
437     type = curWin->generic.type - 1;
438   while (type != curWin->generic.type && m_winPtrIsNull (prev))
439     {
440       if (winList[type]->generic.isVisible)
441         prev = winList[type];
442       else
443         {
444           if (type == SRC_WIN)
445             type = CMD_WIN;
446           else
447             type--;
448         }
449     }
450
451   return prev;
452 }
453
454
455 /*
456    **  partialWinByName().
457    **      Answer the window represented by name
458  */
459 TuiWinInfoPtr
460 partialWinByName (char *name)
461 {
462   TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL;
463
464   if (name != (char *) NULL)
465     {
466       int i = 0;
467
468       while (i < MAX_MAJOR_WINDOWS && m_winPtrIsNull (winInfo))
469         {
470           if (winList[i] != 0)
471             {
472               char *curName = winName (&winList[i]->generic);
473               if (strlen (name) <= strlen (curName) &&
474                   strncmp (name, curName, strlen (name)) == 0)
475                 winInfo = winList[i];
476             }
477           i++;
478         }
479     }
480
481   return winInfo;
482 }                               /* partialWinByName */
483
484
485 /*
486    ** winName().
487    **      Answer the name of the window
488  */
489 char *
490 winName (TuiGenWinInfoPtr winInfo)
491 {
492   char *name = (char *) NULL;
493
494   switch (winInfo->type)
495     {
496     case SRC_WIN:
497       name = SRC_NAME;
498       break;
499     case CMD_WIN:
500       name = CMD_NAME;
501       break;
502     case DISASSEM_WIN:
503       name = DISASSEM_NAME;
504       break;
505     case DATA_WIN:
506       name = DATA_NAME;
507       break;
508     default:
509       name = "";
510       break;
511     }
512
513   return name;
514 }                               /* winName */
515
516
517 /*
518    ** initializeStaticData
519  */
520 void
521 initializeStaticData (void)
522 {
523   initGenericPart (sourceExecInfoWinPtr ());
524   initGenericPart (disassemExecInfoWinPtr ());
525   initGenericPart (locatorWinInfoPtr ());
526
527   return;
528 }                               /* initializeStaticData */
529
530
531 /*
532    ** allocGenericWinInfo().
533  */
534 TuiGenWinInfoPtr
535 allocGenericWinInfo (void)
536 {
537   TuiGenWinInfoPtr win;
538
539   if ((win = (TuiGenWinInfoPtr) xmalloc (
540                      sizeof (TuiGenWinInfoPtr))) != (TuiGenWinInfoPtr) NULL)
541     initGenericPart (win);
542
543   return win;
544 }                               /* allocGenericWinInfo */
545
546
547 /*
548    ** initGenericPart().
549  */
550 void
551 initGenericPart (TuiGenWinInfoPtr win)
552 {
553   win->width =
554     win->height =
555     win->origin.x =
556     win->origin.y =
557     win->viewportHeight =
558     win->contentSize =
559     win->lastVisibleLine = 0;
560   win->handle = (WINDOW *) NULL;
561   win->content = (OpaquePtr) NULL;
562   win->contentInUse =
563     win->isVisible = FALSE;
564   win->title = 0;
565 }
566
567
568 /*
569    ** initContentElement().
570  */
571 void
572 initContentElement (TuiWinElementPtr element, TuiWinType type)
573 {
574   element->highlight = FALSE;
575   switch (type)
576     {
577     case SRC_WIN:
578     case DISASSEM_WIN:
579       element->whichElement.source.line = (char *) NULL;
580       element->whichElement.source.lineOrAddr.lineNo = 0;
581       element->whichElement.source.isExecPoint = FALSE;
582       element->whichElement.source.hasBreak = FALSE;
583       break;
584     case DATA_WIN:
585       initGenericPart (&element->whichElement.dataWindow);
586       element->whichElement.dataWindow.type = DATA_ITEM_WIN;
587       ((TuiGenWinInfoPtr) & element->whichElement.dataWindow)->content =
588         (OpaquePtr) allocContent (1, DATA_ITEM_WIN);
589       ((TuiGenWinInfoPtr)
590        & element->whichElement.dataWindow)->contentSize = 1;
591       break;
592     case CMD_WIN:
593       element->whichElement.command.line = (char *) NULL;
594       break;
595     case DATA_ITEM_WIN:
596       element->whichElement.data.name = (char *) NULL;
597       element->whichElement.data.type = TUI_REGISTER;
598       element->whichElement.data.itemNo = UNDEFINED_ITEM;
599       element->whichElement.data.value = (Opaque) NULL;
600       element->whichElement.data.highlight = FALSE;
601       break;
602     case LOCATOR_WIN:
603       element->whichElement.locator.fileName[0] =
604         element->whichElement.locator.procName[0] = (char) 0;
605       element->whichElement.locator.lineNo = 0;
606       element->whichElement.locator.addr = 0;
607       break;
608     case EXEC_INFO_WIN:
609       memset(element->whichElement.simpleString, ' ',
610              sizeof(element->whichElement.simpleString));
611       break;
612     default:
613       break;
614     }
615   return;
616 }                               /* initContentElement */
617
618 /*
619    ** initWinInfo().
620  */
621 void
622 initWinInfo (TuiWinInfoPtr winInfo)
623 {
624   initGenericPart (&winInfo->generic);
625   winInfo->canHighlight =
626     winInfo->isHighlighted = FALSE;
627   switch (winInfo->generic.type)
628     {
629     case SRC_WIN:
630     case DISASSEM_WIN:
631       winInfo->detail.sourceInfo.executionInfo = (TuiGenWinInfoPtr) NULL;
632       winInfo->detail.sourceInfo.hasLocator = FALSE;
633       winInfo->detail.sourceInfo.horizontalOffset = 0;
634       winInfo->detail.sourceInfo.startLineOrAddr.addr = 0;
635       winInfo->detail.sourceInfo.filename = 0;
636       break;
637     case DATA_WIN:
638       winInfo->detail.dataDisplayInfo.dataContent = (TuiWinContent) NULL;
639       winInfo->detail.dataDisplayInfo.dataContentCount = 0;
640       winInfo->detail.dataDisplayInfo.regsContent = (TuiWinContent) NULL;
641       winInfo->detail.dataDisplayInfo.regsContentCount = 0;
642       winInfo->detail.dataDisplayInfo.regsDisplayType =
643         TUI_UNDEFINED_REGS;
644       winInfo->detail.dataDisplayInfo.regsColumnCount = 1;
645       winInfo->detail.dataDisplayInfo.displayRegs = FALSE;
646       break;
647     case CMD_WIN:
648       winInfo->detail.commandInfo.curLine = 0;
649       winInfo->detail.commandInfo.curch = 0;
650       break;
651     default:
652       winInfo->detail.opaque = (Opaque) NULL;
653       break;
654     }
655
656   return;
657 }                               /* initWinInfo */
658
659
660 /*
661    ** allocWinInfo().
662  */
663 TuiWinInfoPtr
664 allocWinInfo (TuiWinType type)
665 {
666   TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL;
667
668   winInfo = (TuiWinInfoPtr) xmalloc (sizeof (TuiWinInfo));
669   if (m_winPtrNotNull (winInfo))
670     {
671       winInfo->generic.type = type;
672       initWinInfo (winInfo);
673     }
674
675   return winInfo;
676 }                               /* allocWinInfo */
677
678
679 /*
680    ** allocContent().
681    **        Allocates the content and elements in a block.
682  */
683 TuiWinContent
684 allocContent (int numElements, TuiWinType type)
685 {
686   TuiWinContent content = (TuiWinContent) NULL;
687   char *elementBlockPtr = (char *) NULL;
688   int i;
689
690   if ((content = (TuiWinContent)
691   xmalloc (sizeof (TuiWinElementPtr) * numElements)) != (TuiWinContent) NULL)
692     {                           /*
693                                    ** All windows, except the data window, can allocate the elements
694                                    ** in a chunk.  The data window cannot because items can be
695                                    ** added/removed from the data display by the user at any time.
696                                  */
697       if (type != DATA_WIN)
698         {
699           if ((elementBlockPtr = (char *)
700            xmalloc (sizeof (TuiWinElement) * numElements)) != (char *) NULL)
701             {
702               for (i = 0; i < numElements; i++)
703                 {
704                   content[i] = (TuiWinElementPtr) elementBlockPtr;
705                   initContentElement (content[i], type);
706                   elementBlockPtr += sizeof (TuiWinElement);
707                 }
708             }
709           else
710             {
711               tuiFree ((char *) content);
712               content = (TuiWinContent) NULL;
713             }
714         }
715     }
716
717   return content;
718 }                               /* allocContent */
719
720
721 /*
722    ** addContentElements().
723    **        Adds the input number of elements to the windows's content.  If
724    **        no content has been allocated yet, allocContent() is called to
725    **        do this.  The index of the first element added is returned,
726    **        unless there is a memory allocation error, in which case, (-1)
727    **        is returned.
728  */
729 int
730 addContentElements (TuiGenWinInfoPtr winInfo, int numElements)
731 {
732   TuiWinElementPtr elementPtr;
733   int i, indexStart;
734
735   if (winInfo->content == (OpaquePtr) NULL)
736     {
737       winInfo->content = (OpaquePtr) allocContent (numElements, winInfo->type);
738       indexStart = 0;
739     }
740   else
741     indexStart = winInfo->contentSize;
742   if (winInfo->content != (OpaquePtr) NULL)
743     {
744       for (i = indexStart; (i < numElements + indexStart); i++)
745         {
746           if ((elementPtr = (TuiWinElementPtr)
747                xmalloc (sizeof (TuiWinElement))) != (TuiWinElementPtr) NULL)
748             {
749               winInfo->content[i] = (Opaque) elementPtr;
750               initContentElement (elementPtr, winInfo->type);
751               winInfo->contentSize++;
752             }
753           else                  /* things must be really hosed now! We ran out of memory!? */
754             return (-1);
755         }
756     }
757
758   return indexStart;
759 }                               /* addContentElements */
760
761
762 /* Delete all curses windows associated with winInfo, leaving everything
763    else intact.  */
764 void
765 tuiDelWindow (TuiWinInfoPtr winInfo)
766 {
767   TuiGenWinInfoPtr genericWin;
768
769   switch (winInfo->generic.type)
770     {
771     case SRC_WIN:
772     case DISASSEM_WIN:
773       genericWin = locatorWinInfoPtr ();
774       if (genericWin != (TuiGenWinInfoPtr) NULL)
775         {
776           tui_delete_win (genericWin->handle);
777           genericWin->handle = (WINDOW *) NULL;
778           genericWin->isVisible = FALSE;
779         }
780       if (winInfo->detail.sourceInfo.filename)
781         {
782           xfree (winInfo->detail.sourceInfo.filename);
783           winInfo->detail.sourceInfo.filename = 0;
784         }
785       genericWin = winInfo->detail.sourceInfo.executionInfo;
786       if (genericWin != (TuiGenWinInfoPtr) NULL)
787         {
788           tui_delete_win (genericWin->handle);
789           genericWin->handle = (WINDOW *) NULL;
790           genericWin->isVisible = FALSE;
791         }
792       break;
793     case DATA_WIN:
794       if (winInfo->generic.content != (OpaquePtr) NULL)
795         {
796           tuiDelDataWindows (winInfo->detail.dataDisplayInfo.regsContent,
797                              winInfo->detail.dataDisplayInfo.regsContentCount);
798           tuiDelDataWindows (winInfo->detail.dataDisplayInfo.dataContent,
799                              winInfo->detail.dataDisplayInfo.dataContentCount);
800         }
801       break;
802     default:
803       break;
804     }
805   if (winInfo->generic.handle != (WINDOW *) NULL)
806     {
807       tui_delete_win (winInfo->generic.handle);
808       winInfo->generic.handle = (WINDOW *) NULL;
809       winInfo->generic.isVisible = FALSE;
810     }
811 }
812
813
814 /*
815    **  freeWindow().
816  */
817 void
818 freeWindow (TuiWinInfoPtr winInfo)
819 {
820   TuiGenWinInfoPtr genericWin;
821
822   switch (winInfo->generic.type)
823     {
824     case SRC_WIN:
825     case DISASSEM_WIN:
826       genericWin = locatorWinInfoPtr ();
827       if (genericWin != (TuiGenWinInfoPtr) NULL)
828         {
829           tui_delete_win (genericWin->handle);
830           genericWin->handle = (WINDOW *) NULL;
831         }
832       freeWinContent (genericWin);
833       if (winInfo->detail.sourceInfo.filename)
834         {
835           xfree (winInfo->detail.sourceInfo.filename);
836           winInfo->detail.sourceInfo.filename = 0;
837         }
838       genericWin = winInfo->detail.sourceInfo.executionInfo;
839       if (genericWin != (TuiGenWinInfoPtr) NULL)
840         {
841           tui_delete_win (genericWin->handle);
842           genericWin->handle = (WINDOW *) NULL;
843           freeWinContent (genericWin);
844         }
845       break;
846     case DATA_WIN:
847       if (winInfo->generic.content != (OpaquePtr) NULL)
848         {
849           freeDataContent (
850                             winInfo->detail.dataDisplayInfo.regsContent,
851                           winInfo->detail.dataDisplayInfo.regsContentCount);
852           winInfo->detail.dataDisplayInfo.regsContent =
853             (TuiWinContent) NULL;
854           winInfo->detail.dataDisplayInfo.regsContentCount = 0;
855           freeDataContent (
856                             winInfo->detail.dataDisplayInfo.dataContent,
857                           winInfo->detail.dataDisplayInfo.dataContentCount);
858           winInfo->detail.dataDisplayInfo.dataContent =
859             (TuiWinContent) NULL;
860           winInfo->detail.dataDisplayInfo.dataContentCount = 0;
861           winInfo->detail.dataDisplayInfo.regsDisplayType =
862             TUI_UNDEFINED_REGS;
863           winInfo->detail.dataDisplayInfo.regsColumnCount = 1;
864           winInfo->detail.dataDisplayInfo.displayRegs = FALSE;
865           winInfo->generic.content = (OpaquePtr) NULL;
866           winInfo->generic.contentSize = 0;
867         }
868       break;
869     default:
870       break;
871     }
872   if (winInfo->generic.handle != (WINDOW *) NULL)
873     {
874       tui_delete_win (winInfo->generic.handle);
875       winInfo->generic.handle = (WINDOW *) NULL;
876       freeWinContent (&winInfo->generic);
877     }
878   if (winInfo->generic.title)
879     xfree (winInfo->generic.title);
880   xfree (winInfo);
881 }
882
883
884 /*
885    ** freeAllSourceWinsContent().
886  */
887 void
888 freeAllSourceWinsContent (void)
889 {
890   int i;
891
892   for (i = 0; i < (sourceWindows ())->count; i++)
893     {
894       TuiWinInfoPtr winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i];
895
896       if (m_winPtrNotNull (winInfo))
897         {
898           freeWinContent (&(winInfo->generic));
899           freeWinContent (winInfo->detail.sourceInfo.executionInfo);
900         }
901     }
902
903   return;
904 }                               /* freeAllSourceWinsContent */
905
906
907 /*
908    ** freeWinContent().
909  */
910 void
911 freeWinContent (TuiGenWinInfoPtr winInfo)
912 {
913   if (winInfo->content != (OpaquePtr) NULL)
914     {
915       freeContent ((TuiWinContent) winInfo->content,
916                    winInfo->contentSize,
917                    winInfo->type);
918       winInfo->content = (OpaquePtr) NULL;
919     }
920   winInfo->contentSize = 0;
921
922   return;
923 }                               /* freeWinContent */
924
925
926 void
927 tuiDelDataWindows (TuiWinContent content, int contentSize)
928 {
929   int i;
930
931   /*
932      ** Remember that data window content elements are of type TuiGenWinInfoPtr,
933      ** each of which whose single element is a data element.
934    */
935   for (i = 0; i < contentSize; i++)
936     {
937       TuiGenWinInfoPtr genericWin = &content[i]->whichElement.dataWindow;
938
939       if (genericWin != (TuiGenWinInfoPtr) NULL)
940         {
941           tui_delete_win (genericWin->handle);
942           genericWin->handle = (WINDOW *) NULL;
943           genericWin->isVisible = FALSE;
944         }
945     }
946
947   return;
948 }                               /* tuiDelDataWindows */
949
950
951 void
952 freeDataContent (TuiWinContent content, int contentSize)
953 {
954   int i;
955
956   /*
957      ** Remember that data window content elements are of type TuiGenWinInfoPtr,
958      ** each of which whose single element is a data element.
959    */
960   for (i = 0; i < contentSize; i++)
961     {
962       TuiGenWinInfoPtr genericWin = &content[i]->whichElement.dataWindow;
963
964       if (genericWin != (TuiGenWinInfoPtr) NULL)
965         {
966           tui_delete_win (genericWin->handle);
967           genericWin->handle = (WINDOW *) NULL;
968           freeWinContent (genericWin);
969         }
970     }
971   freeContent (content,
972                contentSize,
973                DATA_WIN);
974
975   return;
976 }                               /* freeDataContent */
977
978
979 /**********************************
980 ** LOCAL STATIC FUNCTIONS        **
981 **********************************/
982
983
984 /*
985    ** freeContent().
986  */
987 static void
988 freeContent (TuiWinContent content, int contentSize, TuiWinType winType)
989 {
990   if (content != (TuiWinContent) NULL)
991     {
992       freeContentElements (content, contentSize, winType);
993       tuiFree ((char *) content);
994     }
995
996   return;
997 }                               /* freeContent */
998
999
1000 /*
1001    ** freeContentElements().
1002  */
1003 static void
1004 freeContentElements (TuiWinContent content, int contentSize, TuiWinType type)
1005 {
1006   if (content != (TuiWinContent) NULL)
1007     {
1008       int i;
1009
1010       if (type == SRC_WIN || type == DISASSEM_WIN)
1011         {
1012           /* free whole source block */
1013           if (content[0]->whichElement.source.line != (char *) NULL)
1014             tuiFree (content[0]->whichElement.source.line);
1015         }
1016       else
1017         {
1018           for (i = 0; i < contentSize; i++)
1019             {
1020               TuiWinElementPtr element;
1021
1022               element = content[i];
1023               if (element != (TuiWinElementPtr) NULL)
1024                 {
1025                   switch (type)
1026                     {
1027                     case DATA_WIN:
1028                       tuiFree ((char *) element);
1029                       break;
1030                     case DATA_ITEM_WIN:
1031                       /*
1032                          ** Note that data elements are not allocated
1033                          ** in a single block, but individually, as needed.
1034                        */
1035                       if (element->whichElement.data.type != TUI_REGISTER)
1036                         tuiFree ((char *)
1037                                  element->whichElement.data.name);
1038                       tuiFree ((char *) element->whichElement.data.value);
1039                       tuiFree ((char *) element);
1040                       break;
1041                     case CMD_WIN:
1042                       tuiFree ((char *) element->whichElement.command.line);
1043                       break;
1044                     default:
1045                       break;
1046                     }
1047                 }
1048             }
1049         }
1050       if (type != DATA_WIN && type != DATA_ITEM_WIN)
1051         tuiFree ((char *) content[0]);  /* free the element block */
1052     }
1053
1054   return;
1055 }                               /* freeContentElements */