1130803Smarcel/* TUI data manipulation routines.
2130803Smarcel
3130803Smarcel   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
4130803Smarcel   Foundation, Inc.
5130803Smarcel
6130803Smarcel   Contributed by Hewlett-Packard Company.
7130803Smarcel
8130803Smarcel   This file is part of GDB.
9130803Smarcel
10130803Smarcel   This program is free software; you can redistribute it and/or modify
11130803Smarcel   it under the terms of the GNU General Public License as published by
12130803Smarcel   the Free Software Foundation; either version 2 of the License, or
13130803Smarcel   (at your option) any later version.
14130803Smarcel
15130803Smarcel   This program is distributed in the hope that it will be useful,
16130803Smarcel   but WITHOUT ANY WARRANTY; without even the implied warranty of
17130803Smarcel   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18130803Smarcel   GNU General Public License for more details.
19130803Smarcel
20130803Smarcel   You should have received a copy of the GNU General Public License
21130803Smarcel   along with this program; if not, write to the Free Software
22130803Smarcel   Foundation, Inc., 59 Temple Place - Suite 330,
23130803Smarcel   Boston, MA 02111-1307, USA.  */
24130803Smarcel
25130803Smarcel#include "defs.h"
26130803Smarcel#include "symtab.h"
27130803Smarcel#include "tui/tui.h"
28130803Smarcel#include "tui/tui-data.h"
29130803Smarcel#include "tui/tui-wingeneral.h"
30130803Smarcel
31130803Smarcel#include "gdb_string.h"
32130803Smarcel#include "gdb_curses.h"
33130803Smarcel
34130803Smarcel/****************************
35130803Smarcel** GLOBAL DECLARATIONS
36130803Smarcel****************************/
37130803Smarcelstruct tui_win_info *(tui_win_list[MAX_MAJOR_WINDOWS]);
38130803Smarcel
39130803Smarcel/***************************
40130803Smarcel** Private data
41130803Smarcel****************************/
42130803Smarcelstatic enum tui_layout_type current_layout = UNDEFINED_LAYOUT;
43130803Smarcelstatic int term_height, term_width;
44130803Smarcelstatic struct tui_gen_win_info _locator;
45130803Smarcelstatic struct tui_gen_win_info exec_info[2];
46130803Smarcelstatic struct tui_win_info * src_win_list[2];
47130803Smarcelstatic struct tui_list source_windows = {(void **) src_win_list, 0};
48130803Smarcelstatic int default_tab_len = DEFAULT_TAB_LEN;
49130803Smarcelstatic struct tui_win_info * win_with_focus = (struct tui_win_info *) NULL;
50130803Smarcelstatic struct tui_layout_def layout_def =
51130803Smarcel{SRC_WIN,			/* DISPLAY_MODE */
52130803Smarcel FALSE,				/* SPLIT */
53130803Smarcel TUI_UNDEFINED_REGS,		/* REGS_DISPLAY_TYPE */
54130803Smarcel TUI_SFLOAT_REGS};		/* FLOAT_REGS_DISPLAY_TYPE */
55130803Smarcelstatic int win_resized = FALSE;
56130803Smarcel
57130803Smarcel
58130803Smarcel/*********************************
59130803Smarcel** Static function forward decls
60130803Smarcel**********************************/
61130803Smarcelstatic void free_content (tui_win_content, int, enum tui_win_type);
62130803Smarcelstatic void free_content_elements (tui_win_content, int, enum tui_win_type);
63130803Smarcel
64130803Smarcel
65130803Smarcel
66130803Smarcel/*********************************
67130803Smarcel** PUBLIC FUNCTIONS
68130803Smarcel**********************************/
69130803Smarcel
70130803Smarcelint
71130803Smarceltui_win_is_source_type (enum tui_win_type win_type)
72130803Smarcel{
73130803Smarcel  return (win_type == SRC_WIN || win_type == DISASSEM_WIN);
74130803Smarcel}
75130803Smarcel
76130803Smarcelint
77130803Smarceltui_win_is_auxillary (enum tui_win_type win_type)
78130803Smarcel{
79130803Smarcel  return (win_type > MAX_MAJOR_WINDOWS);
80130803Smarcel}
81130803Smarcel
82130803Smarcelint
83130803Smarceltui_win_has_locator (struct tui_win_info *win_info)
84130803Smarcel{
85130803Smarcel  return (win_info != NULL \
86130803Smarcel	  && win_info->detail.source_info.has_locator);
87130803Smarcel}
88130803Smarcel
89130803Smarcelvoid
90130803Smarceltui_set_win_highlight (struct tui_win_info *win_info, int highlight)
91130803Smarcel{
92130803Smarcel  if (win_info != NULL)
93130803Smarcel    win_info->is_highlighted = highlight;
94130803Smarcel}
95130803Smarcel
96130803Smarcel/******************************************
97130803Smarcel** ACCESSORS & MUTATORS FOR PRIVATE DATA
98130803Smarcel******************************************/
99130803Smarcel
100130803Smarcel/* Answer a whether the terminal window has been resized or not.   */
101130803Smarcelint
102130803Smarceltui_win_resized (void)
103130803Smarcel{
104130803Smarcel  return win_resized;
105130803Smarcel}
106130803Smarcel
107130803Smarcel
108130803Smarcel/* Set a whether the terminal window has been resized or not.   */
109130803Smarcelvoid
110130803Smarceltui_set_win_resized_to (int resized)
111130803Smarcel{
112130803Smarcel  win_resized = resized;
113130803Smarcel}
114130803Smarcel
115130803Smarcel
116130803Smarcel/* Answer a pointer to the current layout definition.   */
117130803Smarcelstruct tui_layout_def *
118130803Smarceltui_layout_def (void)
119130803Smarcel{
120130803Smarcel  return &layout_def;
121130803Smarcel}
122130803Smarcel
123130803Smarcel
124130803Smarcel/* Answer the window with the logical focus.    */
125130803Smarcelstruct tui_win_info *
126130803Smarceltui_win_with_focus (void)
127130803Smarcel{
128130803Smarcel  return win_with_focus;
129130803Smarcel}
130130803Smarcel
131130803Smarcel
132130803Smarcel/* Set the window that has the logical focus.   */
133130803Smarcelvoid
134130803Smarceltui_set_win_with_focus (struct tui_win_info * win_info)
135130803Smarcel{
136130803Smarcel  win_with_focus = win_info;
137130803Smarcel}
138130803Smarcel
139130803Smarcel
140130803Smarcel/* Answer the length in chars, of tabs.    */
141130803Smarcelint
142130803Smarceltui_default_tab_len (void)
143130803Smarcel{
144130803Smarcel  return default_tab_len;
145130803Smarcel}
146130803Smarcel
147130803Smarcel
148130803Smarcel/* Set the length in chars, of tabs.   */
149130803Smarcelvoid
150130803Smarceltui_set_default_tab_len (int len)
151130803Smarcel{
152130803Smarcel  default_tab_len = len;
153130803Smarcel}
154130803Smarcel
155130803Smarcel
156130803Smarcel/* Accessor for the current source window.  Usually there is only one
157130803Smarcel   source window (either source or disassembly), but both can be
158130803Smarcel   displayed at the same time.  */
159130803Smarcelstruct tui_list *
160130803Smarceltui_source_windows (void)
161130803Smarcel{
162130803Smarcel  return &source_windows;
163130803Smarcel}
164130803Smarcel
165130803Smarcel
166130803Smarcel/* Clear the list of source windows.  Usually there is only one source
167130803Smarcel   window (either source or disassembly), but both can be displayed at
168130803Smarcel   the same time.  */
169130803Smarcelvoid
170130803Smarceltui_clear_source_windows (void)
171130803Smarcel{
172130803Smarcel  source_windows.list[0] = NULL;
173130803Smarcel  source_windows.list[1] = NULL;
174130803Smarcel  source_windows.count = 0;
175130803Smarcel}
176130803Smarcel
177130803Smarcel
178130803Smarcel/* Clear the pertinant detail in the source windows.   */
179130803Smarcelvoid
180130803Smarceltui_clear_source_windows_detail (void)
181130803Smarcel{
182130803Smarcel  int i;
183130803Smarcel
184130803Smarcel  for (i = 0; i < (tui_source_windows ())->count; i++)
185130803Smarcel    tui_clear_win_detail ((struct tui_win_info *) (tui_source_windows ())->list[i]);
186130803Smarcel}
187130803Smarcel
188130803Smarcel
189130803Smarcel/* Add a window to the list of source windows.  Usually there is only
190130803Smarcel   one source window (either source or disassembly), but both can be
191130803Smarcel   displayed at the same time.  */
192130803Smarcelvoid
193130803Smarceltui_add_to_source_windows (struct tui_win_info * win_info)
194130803Smarcel{
195130803Smarcel  if (source_windows.count < 2)
196130803Smarcel    source_windows.list[source_windows.count++] = (void *) win_info;
197130803Smarcel}
198130803Smarcel
199130803Smarcel
200130803Smarcel/* Clear the pertinant detail in the windows.   */
201130803Smarcelvoid
202130803Smarceltui_clear_win_detail (struct tui_win_info * win_info)
203130803Smarcel{
204130803Smarcel  if (win_info != NULL)
205130803Smarcel    {
206130803Smarcel      switch (win_info->generic.type)
207130803Smarcel	{
208130803Smarcel	case SRC_WIN:
209130803Smarcel	case DISASSEM_WIN:
210130803Smarcel	  win_info->detail.source_info.start_line_or_addr.addr = 0;
211130803Smarcel	  win_info->detail.source_info.horizontal_offset = 0;
212130803Smarcel	  break;
213130803Smarcel	case CMD_WIN:
214130803Smarcel	  win_info->detail.command_info.cur_line =
215130803Smarcel	    win_info->detail.command_info.curch = 0;
216130803Smarcel	  break;
217130803Smarcel	case DATA_WIN:
218130803Smarcel	  win_info->detail.data_display_info.data_content =
219130803Smarcel	    (tui_win_content) NULL;
220130803Smarcel	  win_info->detail.data_display_info.data_content_count = 0;
221130803Smarcel	  win_info->detail.data_display_info.regs_content =
222130803Smarcel	    (tui_win_content) NULL;
223130803Smarcel	  win_info->detail.data_display_info.regs_content_count = 0;
224130803Smarcel	  win_info->detail.data_display_info.regs_display_type =
225130803Smarcel	    TUI_UNDEFINED_REGS;
226130803Smarcel	  win_info->detail.data_display_info.regs_column_count = 1;
227130803Smarcel	  win_info->detail.data_display_info.display_regs = FALSE;
228130803Smarcel	  break;
229130803Smarcel	default:
230130803Smarcel	  break;
231130803Smarcel	}
232130803Smarcel    }
233130803Smarcel}
234130803Smarcel
235130803Smarcel
236130803Smarcel/* Accessor for the source execution info ptr.  */
237130803Smarcelstruct tui_gen_win_info *
238130803Smarceltui_source_exec_info_win_ptr (void)
239130803Smarcel{
240130803Smarcel  return &exec_info[0];
241130803Smarcel}
242130803Smarcel
243130803Smarcel
244130803Smarcel/* Accessor for the disassem execution info ptr.  */
245130803Smarcelstruct tui_gen_win_info *
246130803Smarceltui_disassem_exec_info_win_ptr (void)
247130803Smarcel{
248130803Smarcel  return &exec_info[1];
249130803Smarcel}
250130803Smarcel
251130803Smarcel
252130803Smarcel/* Accessor for the locator win info.  Answers a pointer to the static
253130803Smarcel   locator win info struct.  */
254130803Smarcelstruct tui_gen_win_info *
255130803Smarceltui_locator_win_info_ptr (void)
256130803Smarcel{
257130803Smarcel  return &_locator;
258130803Smarcel}
259130803Smarcel
260130803Smarcel
261130803Smarcel/* Accessor for the term_height.  */
262130803Smarcelint
263130803Smarceltui_term_height (void)
264130803Smarcel{
265130803Smarcel  return term_height;
266130803Smarcel}
267130803Smarcel
268130803Smarcel
269130803Smarcel/* Mutator for the term height.   */
270130803Smarcelvoid
271130803Smarceltui_set_term_height_to (int h)
272130803Smarcel{
273130803Smarcel  term_height = h;
274130803Smarcel}
275130803Smarcel
276130803Smarcel
277130803Smarcel/* Accessor for the term_width.   */
278130803Smarcelint
279130803Smarceltui_term_width (void)
280130803Smarcel{
281130803Smarcel  return term_width;
282130803Smarcel}
283130803Smarcel
284130803Smarcel
285130803Smarcel/* Mutator for the term_width.  */
286130803Smarcelvoid
287130803Smarceltui_set_term_width_to (int w)
288130803Smarcel{
289130803Smarcel  term_width = w;
290130803Smarcel}
291130803Smarcel
292130803Smarcel
293130803Smarcel/* Accessor for the current layout.   */
294130803Smarcelenum tui_layout_type
295130803Smarceltui_current_layout (void)
296130803Smarcel{
297130803Smarcel  return current_layout;
298130803Smarcel}
299130803Smarcel
300130803Smarcel
301130803Smarcel/* Mutator for the current layout.  */
302130803Smarcelvoid
303130803Smarceltui_set_current_layout_to (enum tui_layout_type new_layout)
304130803Smarcel{
305130803Smarcel  current_layout = new_layout;
306130803Smarcel}
307130803Smarcel
308130803Smarcel
309130803Smarcel/* Set the origin of the window.  */
310130803Smarcelvoid
311130803Smarcelset_gen_win_origin (struct tui_gen_win_info * win_info, int x, int y)
312130803Smarcel{
313130803Smarcel  win_info->origin.x = x;
314130803Smarcel  win_info->origin.y = y;
315130803Smarcel}
316130803Smarcel
317130803Smarcel
318130803Smarcel/*****************************
319130803Smarcel** OTHER PUBLIC FUNCTIONS
320130803Smarcel*****************************/
321130803Smarcel
322130803Smarcel
323130803Smarcel/* Answer the next window in the list, cycling back to the top if
324130803Smarcel   necessary.  */
325130803Smarcelstruct tui_win_info *
326130803Smarceltui_next_win (struct tui_win_info * cur_win)
327130803Smarcel{
328130803Smarcel  enum tui_win_type type = cur_win->generic.type;
329130803Smarcel  struct tui_win_info * next_win = (struct tui_win_info *) NULL;
330130803Smarcel
331130803Smarcel  if (cur_win->generic.type == CMD_WIN)
332130803Smarcel    type = SRC_WIN;
333130803Smarcel  else
334130803Smarcel    type = cur_win->generic.type + 1;
335130803Smarcel  while (type != cur_win->generic.type && (next_win == NULL))
336130803Smarcel    {
337130803Smarcel      if (tui_win_list[type] && tui_win_list[type]->generic.is_visible)
338130803Smarcel	next_win = tui_win_list[type];
339130803Smarcel      else
340130803Smarcel	{
341130803Smarcel	  if (type == CMD_WIN)
342130803Smarcel	    type = SRC_WIN;
343130803Smarcel	  else
344130803Smarcel	    type++;
345130803Smarcel	}
346130803Smarcel    }
347130803Smarcel
348130803Smarcel  return next_win;
349130803Smarcel}
350130803Smarcel
351130803Smarcel
352130803Smarcel/* Answer the prev window in the list, cycling back to the bottom if
353130803Smarcel   necessary.  */
354130803Smarcelstruct tui_win_info *
355130803Smarceltui_prev_win (struct tui_win_info * cur_win)
356130803Smarcel{
357130803Smarcel  enum tui_win_type type = cur_win->generic.type;
358130803Smarcel  struct tui_win_info * prev = (struct tui_win_info *) NULL;
359130803Smarcel
360130803Smarcel  if (cur_win->generic.type == SRC_WIN)
361130803Smarcel    type = CMD_WIN;
362130803Smarcel  else
363130803Smarcel    type = cur_win->generic.type - 1;
364130803Smarcel  while (type != cur_win->generic.type && (prev == NULL))
365130803Smarcel    {
366130803Smarcel      if (tui_win_list[type]->generic.is_visible)
367130803Smarcel	prev = tui_win_list[type];
368130803Smarcel      else
369130803Smarcel	{
370130803Smarcel	  if (type == SRC_WIN)
371130803Smarcel	    type = CMD_WIN;
372130803Smarcel	  else
373130803Smarcel	    type--;
374130803Smarcel	}
375130803Smarcel    }
376130803Smarcel
377130803Smarcel  return prev;
378130803Smarcel}
379130803Smarcel
380130803Smarcel
381130803Smarcel/* Answer the window represented by name.    */
382130803Smarcelstruct tui_win_info *
383130803Smarceltui_partial_win_by_name (char *name)
384130803Smarcel{
385130803Smarcel  struct tui_win_info * win_info = (struct tui_win_info *) NULL;
386130803Smarcel
387130803Smarcel  if (name != (char *) NULL)
388130803Smarcel    {
389130803Smarcel      int i = 0;
390130803Smarcel
391130803Smarcel      while (i < MAX_MAJOR_WINDOWS && win_info == NULL)
392130803Smarcel	{
393130803Smarcel          if (tui_win_list[i] != 0)
394130803Smarcel            {
395130803Smarcel              char *cur_name = tui_win_name (&tui_win_list[i]->generic);
396130803Smarcel              if (strlen (name) <= strlen (cur_name) &&
397130803Smarcel                  strncmp (name, cur_name, strlen (name)) == 0)
398130803Smarcel                win_info = tui_win_list[i];
399130803Smarcel            }
400130803Smarcel	  i++;
401130803Smarcel	}
402130803Smarcel    }
403130803Smarcel
404130803Smarcel  return win_info;
405130803Smarcel}
406130803Smarcel
407130803Smarcel
408130803Smarcel/* Answer the name of the window.  */
409130803Smarcelchar *
410130803Smarceltui_win_name (struct tui_gen_win_info * win_info)
411130803Smarcel{
412130803Smarcel  char *name = (char *) NULL;
413130803Smarcel
414130803Smarcel  switch (win_info->type)
415130803Smarcel    {
416130803Smarcel    case SRC_WIN:
417130803Smarcel      name = SRC_NAME;
418130803Smarcel      break;
419130803Smarcel    case CMD_WIN:
420130803Smarcel      name = CMD_NAME;
421130803Smarcel      break;
422130803Smarcel    case DISASSEM_WIN:
423130803Smarcel      name = DISASSEM_NAME;
424130803Smarcel      break;
425130803Smarcel    case DATA_WIN:
426130803Smarcel      name = DATA_NAME;
427130803Smarcel      break;
428130803Smarcel    default:
429130803Smarcel      name = "";
430130803Smarcel      break;
431130803Smarcel    }
432130803Smarcel
433130803Smarcel  return name;
434130803Smarcel}
435130803Smarcel
436130803Smarcel
437130803Smarcelvoid
438130803Smarceltui_initialize_static_data (void)
439130803Smarcel{
440130803Smarcel  tui_init_generic_part (tui_source_exec_info_win_ptr ());
441130803Smarcel  tui_init_generic_part (tui_disassem_exec_info_win_ptr ());
442130803Smarcel  tui_init_generic_part (tui_locator_win_info_ptr ());
443130803Smarcel}
444130803Smarcel
445130803Smarcel
446130803Smarcelstruct tui_gen_win_info *
447130803Smarceltui_alloc_generic_win_info (void)
448130803Smarcel{
449130803Smarcel  struct tui_gen_win_info * win;
450130803Smarcel
451130803Smarcel  if ((win = (struct tui_gen_win_info *) xmalloc (
452130803Smarcel		     sizeof (struct tui_gen_win_info *))) != (struct tui_gen_win_info *) NULL)
453130803Smarcel    tui_init_generic_part (win);
454130803Smarcel
455130803Smarcel  return win;
456130803Smarcel}
457130803Smarcel
458130803Smarcel
459130803Smarcelvoid
460130803Smarceltui_init_generic_part (struct tui_gen_win_info * win)
461130803Smarcel{
462130803Smarcel  win->width =
463130803Smarcel    win->height =
464130803Smarcel    win->origin.x =
465130803Smarcel    win->origin.y =
466130803Smarcel    win->viewport_height =
467130803Smarcel    win->content_size =
468130803Smarcel    win->last_visible_line = 0;
469130803Smarcel  win->handle = (WINDOW *) NULL;
470130803Smarcel  win->content = NULL;
471130803Smarcel  win->content_in_use =
472130803Smarcel    win->is_visible = FALSE;
473130803Smarcel  win->title = 0;
474130803Smarcel}
475130803Smarcel
476130803Smarcel
477130803Smarcel/*
478130803Smarcel   ** init_content_element().
479130803Smarcel */
480130803Smarcelvoid
481130803Smarcelinit_content_element (struct tui_win_element * element, enum tui_win_type type)
482130803Smarcel{
483130803Smarcel  element->highlight = FALSE;
484130803Smarcel  switch (type)
485130803Smarcel    {
486130803Smarcel    case SRC_WIN:
487130803Smarcel    case DISASSEM_WIN:
488130803Smarcel      element->which_element.source.line = (char *) NULL;
489130803Smarcel      element->which_element.source.line_or_addr.line_no = 0;
490130803Smarcel      element->which_element.source.is_exec_point = FALSE;
491130803Smarcel      element->which_element.source.has_break = FALSE;
492130803Smarcel      break;
493130803Smarcel    case DATA_WIN:
494130803Smarcel      tui_init_generic_part (&element->which_element.data_window);
495130803Smarcel      element->which_element.data_window.type = DATA_ITEM_WIN;
496130803Smarcel      ((struct tui_gen_win_info *) & element->which_element.data_window)->content =
497130803Smarcel	(void **) tui_alloc_content (1, DATA_ITEM_WIN);
498130803Smarcel      ((struct tui_gen_win_info *)
499130803Smarcel       & element->which_element.data_window)->content_size = 1;
500130803Smarcel      break;
501130803Smarcel    case CMD_WIN:
502130803Smarcel      element->which_element.command.line = (char *) NULL;
503130803Smarcel      break;
504130803Smarcel    case DATA_ITEM_WIN:
505130803Smarcel      element->which_element.data.name = (char *) NULL;
506130803Smarcel      element->which_element.data.type = TUI_REGISTER;
507130803Smarcel      element->which_element.data.item_no = UNDEFINED_ITEM;
508130803Smarcel      element->which_element.data.value = NULL;
509130803Smarcel      element->which_element.data.highlight = FALSE;
510130803Smarcel      element->which_element.data.content = (char*) NULL;
511130803Smarcel      break;
512130803Smarcel    case LOCATOR_WIN:
513130803Smarcel      element->which_element.locator.file_name[0] =
514130803Smarcel	element->which_element.locator.proc_name[0] = (char) 0;
515130803Smarcel      element->which_element.locator.line_no = 0;
516130803Smarcel      element->which_element.locator.addr = 0;
517130803Smarcel      break;
518130803Smarcel    case EXEC_INFO_WIN:
519130803Smarcel      memset(element->which_element.simple_string, ' ',
520130803Smarcel             sizeof(element->which_element.simple_string));
521130803Smarcel      break;
522130803Smarcel    default:
523130803Smarcel      break;
524130803Smarcel    }
525130803Smarcel}
526130803Smarcel
527130803Smarcelvoid
528130803Smarcelinit_win_info (struct tui_win_info * win_info)
529130803Smarcel{
530130803Smarcel  tui_init_generic_part (&win_info->generic);
531130803Smarcel  win_info->can_highlight =
532130803Smarcel    win_info->is_highlighted = FALSE;
533130803Smarcel  switch (win_info->generic.type)
534130803Smarcel    {
535130803Smarcel    case SRC_WIN:
536130803Smarcel    case DISASSEM_WIN:
537130803Smarcel      win_info->detail.source_info.execution_info = (struct tui_gen_win_info *) NULL;
538130803Smarcel      win_info->detail.source_info.has_locator = FALSE;
539130803Smarcel      win_info->detail.source_info.horizontal_offset = 0;
540130803Smarcel      win_info->detail.source_info.start_line_or_addr.addr = 0;
541130803Smarcel      win_info->detail.source_info.filename = 0;
542130803Smarcel      break;
543130803Smarcel    case DATA_WIN:
544130803Smarcel      win_info->detail.data_display_info.data_content = (tui_win_content) NULL;
545130803Smarcel      win_info->detail.data_display_info.data_content_count = 0;
546130803Smarcel      win_info->detail.data_display_info.regs_content = (tui_win_content) NULL;
547130803Smarcel      win_info->detail.data_display_info.regs_content_count = 0;
548130803Smarcel      win_info->detail.data_display_info.regs_display_type =
549130803Smarcel	TUI_UNDEFINED_REGS;
550130803Smarcel      win_info->detail.data_display_info.regs_column_count = 1;
551130803Smarcel      win_info->detail.data_display_info.display_regs = FALSE;
552130803Smarcel      win_info->detail.data_display_info.current_group = 0;
553130803Smarcel      break;
554130803Smarcel    case CMD_WIN:
555130803Smarcel      win_info->detail.command_info.cur_line = 0;
556130803Smarcel      win_info->detail.command_info.curch = 0;
557130803Smarcel      break;
558130803Smarcel    default:
559130803Smarcel      win_info->detail.opaque = NULL;
560130803Smarcel      break;
561130803Smarcel    }
562130803Smarcel}
563130803Smarcel
564130803Smarcel
565130803Smarcelstruct tui_win_info *
566130803Smarceltui_alloc_win_info (enum tui_win_type type)
567130803Smarcel{
568130803Smarcel  struct tui_win_info * win_info = (struct tui_win_info *) NULL;
569130803Smarcel
570130803Smarcel  win_info = (struct tui_win_info *) xmalloc (sizeof (struct tui_win_info));
571130803Smarcel  if ((win_info != NULL))
572130803Smarcel    {
573130803Smarcel      win_info->generic.type = type;
574130803Smarcel      init_win_info (win_info);
575130803Smarcel    }
576130803Smarcel
577130803Smarcel  return win_info;
578130803Smarcel}
579130803Smarcel
580130803Smarcel
581130803Smarcel/* Allocates the content and elements in a block.  */
582130803Smarceltui_win_content
583130803Smarceltui_alloc_content (int num_elements, enum tui_win_type type)
584130803Smarcel{
585130803Smarcel  tui_win_content content = (tui_win_content) NULL;
586130803Smarcel  char *element_block_ptr = (char *) NULL;
587130803Smarcel  int i;
588130803Smarcel
589130803Smarcel  if ((content = (tui_win_content)
590130803Smarcel  xmalloc (sizeof (struct tui_win_element *) * num_elements)) != (tui_win_content) NULL)
591130803Smarcel    {				/*
592130803Smarcel				   ** All windows, except the data window, can allocate the elements
593130803Smarcel				   ** in a chunk.  The data window cannot because items can be
594130803Smarcel				   ** added/removed from the data display by the user at any time.
595130803Smarcel				 */
596130803Smarcel      if (type != DATA_WIN)
597130803Smarcel	{
598130803Smarcel	  if ((element_block_ptr = (char *)
599130803Smarcel	   xmalloc (sizeof (struct tui_win_element) * num_elements)) != (char *) NULL)
600130803Smarcel	    {
601130803Smarcel	      for (i = 0; i < num_elements; i++)
602130803Smarcel		{
603130803Smarcel		  content[i] = (struct tui_win_element *) element_block_ptr;
604130803Smarcel		  init_content_element (content[i], type);
605130803Smarcel		  element_block_ptr += sizeof (struct tui_win_element);
606130803Smarcel		}
607130803Smarcel	    }
608130803Smarcel	  else
609130803Smarcel	    {
610130803Smarcel	      xfree (content);
611130803Smarcel	      content = (tui_win_content) NULL;
612130803Smarcel	    }
613130803Smarcel	}
614130803Smarcel    }
615130803Smarcel
616130803Smarcel  return content;
617130803Smarcel}
618130803Smarcel
619130803Smarcel
620130803Smarcel/* Adds the input number of elements to the windows's content.  If no
621130803Smarcel   content has been allocated yet, alloc_content() is called to do
622130803Smarcel   this.  The index of the first element added is returned, unless
623130803Smarcel   there is a memory allocation error, in which case, (-1) is
624130803Smarcel   returned.  */
625130803Smarcelint
626130803Smarceltui_add_content_elements (struct tui_gen_win_info * win_info, int num_elements)
627130803Smarcel{
628130803Smarcel  struct tui_win_element * element_ptr;
629130803Smarcel  int i, index_start;
630130803Smarcel
631130803Smarcel  if (win_info->content == NULL)
632130803Smarcel    {
633130803Smarcel      win_info->content = (void **) tui_alloc_content (num_elements, win_info->type);
634130803Smarcel      index_start = 0;
635130803Smarcel    }
636130803Smarcel  else
637130803Smarcel    index_start = win_info->content_size;
638130803Smarcel  if (win_info->content != NULL)
639130803Smarcel    {
640130803Smarcel      for (i = index_start; (i < num_elements + index_start); i++)
641130803Smarcel	{
642130803Smarcel	  if ((element_ptr = (struct tui_win_element *)
643130803Smarcel	       xmalloc (sizeof (struct tui_win_element))) != (struct tui_win_element *) NULL)
644130803Smarcel	    {
645130803Smarcel	      win_info->content[i] = (void *) element_ptr;
646130803Smarcel	      init_content_element (element_ptr, win_info->type);
647130803Smarcel	      win_info->content_size++;
648130803Smarcel	    }
649130803Smarcel	  else			/* things must be really hosed now! We ran out of memory!? */
650130803Smarcel	    return (-1);
651130803Smarcel	}
652130803Smarcel    }
653130803Smarcel
654130803Smarcel  return index_start;
655130803Smarcel}
656130803Smarcel
657130803Smarcel
658130803Smarcel/* Delete all curses windows associated with win_info, leaving everything
659130803Smarcel   else intact.  */
660130803Smarcelvoid
661130803Smarceltui_del_window (struct tui_win_info * win_info)
662130803Smarcel{
663130803Smarcel  struct tui_gen_win_info * generic_win;
664130803Smarcel
665130803Smarcel  switch (win_info->generic.type)
666130803Smarcel    {
667130803Smarcel    case SRC_WIN:
668130803Smarcel    case DISASSEM_WIN:
669130803Smarcel      generic_win = tui_locator_win_info_ptr ();
670130803Smarcel      if (generic_win != (struct tui_gen_win_info *) NULL)
671130803Smarcel	{
672130803Smarcel	  tui_delete_win (generic_win->handle);
673130803Smarcel	  generic_win->handle = (WINDOW *) NULL;
674130803Smarcel	  generic_win->is_visible = FALSE;
675130803Smarcel	}
676130803Smarcel      if (win_info->detail.source_info.filename)
677130803Smarcel        {
678130803Smarcel          xfree (win_info->detail.source_info.filename);
679130803Smarcel          win_info->detail.source_info.filename = 0;
680130803Smarcel        }
681130803Smarcel      generic_win = win_info->detail.source_info.execution_info;
682130803Smarcel      if (generic_win != (struct tui_gen_win_info *) NULL)
683130803Smarcel	{
684130803Smarcel	  tui_delete_win (generic_win->handle);
685130803Smarcel	  generic_win->handle = (WINDOW *) NULL;
686130803Smarcel	  generic_win->is_visible = FALSE;
687130803Smarcel	}
688130803Smarcel      break;
689130803Smarcel    case DATA_WIN:
690130803Smarcel      if (win_info->generic.content != NULL)
691130803Smarcel	{
692130803Smarcel	  tui_del_data_windows (win_info->detail.data_display_info.regs_content,
693130803Smarcel				win_info->detail.data_display_info.regs_content_count);
694130803Smarcel	  tui_del_data_windows (win_info->detail.data_display_info.data_content,
695130803Smarcel				win_info->detail.data_display_info.data_content_count);
696130803Smarcel	}
697130803Smarcel      break;
698130803Smarcel    default:
699130803Smarcel      break;
700130803Smarcel    }
701130803Smarcel  if (win_info->generic.handle != (WINDOW *) NULL)
702130803Smarcel    {
703130803Smarcel      tui_delete_win (win_info->generic.handle);
704130803Smarcel      win_info->generic.handle = (WINDOW *) NULL;
705130803Smarcel      win_info->generic.is_visible = FALSE;
706130803Smarcel    }
707130803Smarcel}
708130803Smarcel
709130803Smarcel
710130803Smarcelvoid
711130803Smarceltui_free_window (struct tui_win_info * win_info)
712130803Smarcel{
713130803Smarcel  struct tui_gen_win_info * generic_win;
714130803Smarcel
715130803Smarcel  switch (win_info->generic.type)
716130803Smarcel    {
717130803Smarcel    case SRC_WIN:
718130803Smarcel    case DISASSEM_WIN:
719130803Smarcel      generic_win = tui_locator_win_info_ptr ();
720130803Smarcel      if (generic_win != (struct tui_gen_win_info *) NULL)
721130803Smarcel	{
722130803Smarcel	  tui_delete_win (generic_win->handle);
723130803Smarcel	  generic_win->handle = (WINDOW *) NULL;
724130803Smarcel	}
725130803Smarcel      tui_free_win_content (generic_win);
726130803Smarcel      if (win_info->detail.source_info.filename)
727130803Smarcel        {
728130803Smarcel          xfree (win_info->detail.source_info.filename);
729130803Smarcel          win_info->detail.source_info.filename = 0;
730130803Smarcel        }
731130803Smarcel      generic_win = win_info->detail.source_info.execution_info;
732130803Smarcel      if (generic_win != (struct tui_gen_win_info *) NULL)
733130803Smarcel	{
734130803Smarcel	  tui_delete_win (generic_win->handle);
735130803Smarcel	  generic_win->handle = (WINDOW *) NULL;
736130803Smarcel	  tui_free_win_content (generic_win);
737130803Smarcel	}
738130803Smarcel      break;
739130803Smarcel    case DATA_WIN:
740130803Smarcel      if (win_info->generic.content != NULL)
741130803Smarcel	{
742130803Smarcel	  tui_free_data_content (win_info->detail.data_display_info.regs_content,
743130803Smarcel				 win_info->detail.data_display_info.regs_content_count);
744130803Smarcel	  win_info->detail.data_display_info.regs_content =
745130803Smarcel	    (tui_win_content) NULL;
746130803Smarcel	  win_info->detail.data_display_info.regs_content_count = 0;
747130803Smarcel	  tui_free_data_content (win_info->detail.data_display_info.data_content,
748130803Smarcel				 win_info->detail.data_display_info.data_content_count);
749130803Smarcel	  win_info->detail.data_display_info.data_content =
750130803Smarcel	    (tui_win_content) NULL;
751130803Smarcel	  win_info->detail.data_display_info.data_content_count = 0;
752130803Smarcel	  win_info->detail.data_display_info.regs_display_type =
753130803Smarcel	    TUI_UNDEFINED_REGS;
754130803Smarcel	  win_info->detail.data_display_info.regs_column_count = 1;
755130803Smarcel	  win_info->detail.data_display_info.display_regs = FALSE;
756130803Smarcel	  win_info->generic.content = NULL;
757130803Smarcel	  win_info->generic.content_size = 0;
758130803Smarcel	}
759130803Smarcel      break;
760130803Smarcel    default:
761130803Smarcel      break;
762130803Smarcel    }
763130803Smarcel  if (win_info->generic.handle != (WINDOW *) NULL)
764130803Smarcel    {
765130803Smarcel      tui_delete_win (win_info->generic.handle);
766130803Smarcel      win_info->generic.handle = (WINDOW *) NULL;
767130803Smarcel      tui_free_win_content (&win_info->generic);
768130803Smarcel    }
769130803Smarcel  if (win_info->generic.title)
770130803Smarcel    xfree (win_info->generic.title);
771130803Smarcel  xfree (win_info);
772130803Smarcel}
773130803Smarcel
774130803Smarcel
775130803Smarcelvoid
776130803Smarceltui_free_all_source_wins_content (void)
777130803Smarcel{
778130803Smarcel  int i;
779130803Smarcel
780130803Smarcel  for (i = 0; i < (tui_source_windows ())->count; i++)
781130803Smarcel    {
782130803Smarcel      struct tui_win_info * win_info = (struct tui_win_info *) (tui_source_windows ())->list[i];
783130803Smarcel
784130803Smarcel      if (win_info != NULL)
785130803Smarcel	{
786130803Smarcel	  tui_free_win_content (&(win_info->generic));
787130803Smarcel	  tui_free_win_content (win_info->detail.source_info.execution_info);
788130803Smarcel	}
789130803Smarcel    }
790130803Smarcel}
791130803Smarcel
792130803Smarcel
793130803Smarcelvoid
794130803Smarceltui_free_win_content (struct tui_gen_win_info * win_info)
795130803Smarcel{
796130803Smarcel  if (win_info->content != NULL)
797130803Smarcel    {
798130803Smarcel      free_content ((tui_win_content) win_info->content,
799130803Smarcel		   win_info->content_size,
800130803Smarcel		   win_info->type);
801130803Smarcel      win_info->content = NULL;
802130803Smarcel    }
803130803Smarcel  win_info->content_size = 0;
804130803Smarcel}
805130803Smarcel
806130803Smarcel
807130803Smarcelvoid
808130803Smarceltui_del_data_windows (tui_win_content content, int content_size)
809130803Smarcel{
810130803Smarcel  int i;
811130803Smarcel
812130803Smarcel  /*
813130803Smarcel     ** Remember that data window content elements are of type struct tui_gen_win_info *,
814130803Smarcel     ** each of which whose single element is a data element.
815130803Smarcel   */
816130803Smarcel  for (i = 0; i < content_size; i++)
817130803Smarcel    {
818130803Smarcel      struct tui_gen_win_info * generic_win = &content[i]->which_element.data_window;
819130803Smarcel
820130803Smarcel      if (generic_win != (struct tui_gen_win_info *) NULL)
821130803Smarcel	{
822130803Smarcel	  tui_delete_win (generic_win->handle);
823130803Smarcel	  generic_win->handle = (WINDOW *) NULL;
824130803Smarcel	  generic_win->is_visible = FALSE;
825130803Smarcel	}
826130803Smarcel    }
827130803Smarcel}
828130803Smarcel
829130803Smarcel
830130803Smarcelvoid
831130803Smarceltui_free_data_content (tui_win_content content, int content_size)
832130803Smarcel{
833130803Smarcel  int i;
834130803Smarcel
835130803Smarcel  /*
836130803Smarcel     ** Remember that data window content elements are of type struct tui_gen_win_info *,
837130803Smarcel     ** each of which whose single element is a data element.
838130803Smarcel   */
839130803Smarcel  for (i = 0; i < content_size; i++)
840130803Smarcel    {
841130803Smarcel      struct tui_gen_win_info * generic_win = &content[i]->which_element.data_window;
842130803Smarcel
843130803Smarcel      if (generic_win != (struct tui_gen_win_info *) NULL)
844130803Smarcel	{
845130803Smarcel	  tui_delete_win (generic_win->handle);
846130803Smarcel	  generic_win->handle = (WINDOW *) NULL;
847130803Smarcel	  tui_free_win_content (generic_win);
848130803Smarcel	}
849130803Smarcel    }
850130803Smarcel  free_content (content,
851130803Smarcel	       content_size,
852130803Smarcel	       DATA_WIN);
853130803Smarcel}
854130803Smarcel
855130803Smarcel
856130803Smarcel/**********************************
857130803Smarcel** LOCAL STATIC FUNCTIONS        **
858130803Smarcel**********************************/
859130803Smarcel
860130803Smarcel
861130803Smarcelstatic void
862130803Smarcelfree_content (tui_win_content content, int content_size, enum tui_win_type win_type)
863130803Smarcel{
864130803Smarcel  if (content != (tui_win_content) NULL)
865130803Smarcel    {
866130803Smarcel      free_content_elements (content, content_size, win_type);
867130803Smarcel      xfree (content);
868130803Smarcel    }
869130803Smarcel}
870130803Smarcel
871130803Smarcel
872130803Smarcel/*
873130803Smarcel   ** free_content_elements().
874130803Smarcel */
875130803Smarcelstatic void
876130803Smarcelfree_content_elements (tui_win_content content, int content_size, enum tui_win_type type)
877130803Smarcel{
878130803Smarcel  if (content != (tui_win_content) NULL)
879130803Smarcel    {
880130803Smarcel      int i;
881130803Smarcel
882130803Smarcel      if (type == SRC_WIN || type == DISASSEM_WIN)
883130803Smarcel	{
884130803Smarcel	  /* free whole source block */
885130803Smarcel	  xfree (content[0]->which_element.source.line);
886130803Smarcel	}
887130803Smarcel      else
888130803Smarcel	{
889130803Smarcel	  for (i = 0; i < content_size; i++)
890130803Smarcel	    {
891130803Smarcel	      struct tui_win_element * element;
892130803Smarcel
893130803Smarcel	      element = content[i];
894130803Smarcel	      if (element != (struct tui_win_element *) NULL)
895130803Smarcel		{
896130803Smarcel		  switch (type)
897130803Smarcel		    {
898130803Smarcel		    case DATA_WIN:
899130803Smarcel		      xfree (element);
900130803Smarcel		      break;
901130803Smarcel		    case DATA_ITEM_WIN:
902130803Smarcel		      /*
903130803Smarcel		         ** Note that data elements are not allocated
904130803Smarcel		         ** in a single block, but individually, as needed.
905130803Smarcel		       */
906130803Smarcel		      if (element->which_element.data.type != TUI_REGISTER)
907130803Smarcel			xfree ((void *)element->which_element.data.name);
908130803Smarcel		      xfree (element->which_element.data.value);
909130803Smarcel                      xfree (element->which_element.data.content);
910130803Smarcel		      xfree (element);
911130803Smarcel		      break;
912130803Smarcel		    case CMD_WIN:
913130803Smarcel		      xfree (element->which_element.command.line);
914130803Smarcel		      break;
915130803Smarcel		    default:
916130803Smarcel		      break;
917130803Smarcel		    }
918130803Smarcel		}
919130803Smarcel	    }
920130803Smarcel	}
921130803Smarcel      if (type != DATA_WIN && type != DATA_ITEM_WIN)
922130803Smarcel	xfree (content[0]);	/* free the element block */
923130803Smarcel    }
924130803Smarcel}
925