1130803Smarcel/* TUI display source/assembly window.
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 <ctype.h>
27130803Smarcel#include "symtab.h"
28130803Smarcel#include "frame.h"
29130803Smarcel#include "breakpoint.h"
30130803Smarcel#include "value.h"
31130803Smarcel#include "source.h"
32130803Smarcel
33130803Smarcel#include "tui/tui.h"
34130803Smarcel#include "tui/tui-data.h"
35130803Smarcel#include "tui/tui-stack.h"
36130803Smarcel#include "tui/tui-win.h"
37130803Smarcel#include "tui/tui-wingeneral.h"
38130803Smarcel#include "tui/tui-winsource.h"
39130803Smarcel#include "tui/tui-source.h"
40130803Smarcel#include "tui/tui-disasm.h"
41130803Smarcel
42130803Smarcel#include "gdb_string.h"
43130803Smarcel#include "gdb_curses.h"
44130803Smarcel
45130803Smarcel/* Function to display the "main" routine.  */
46130803Smarcelvoid
47130803Smarceltui_display_main (void)
48130803Smarcel{
49130803Smarcel  if ((tui_source_windows ())->count > 0)
50130803Smarcel    {
51130803Smarcel      CORE_ADDR addr;
52130803Smarcel
53130803Smarcel      addr = tui_get_begin_asm_address ();
54130803Smarcel      if (addr != (CORE_ADDR) 0)
55130803Smarcel	{
56130803Smarcel	  struct symtab_and_line sal;
57130803Smarcel
58130803Smarcel	  tui_update_source_windows_with_addr (addr);
59130803Smarcel	  sal = find_pc_line (addr, 0);
60130803Smarcel          if (sal.symtab)
61130803Smarcel             tui_update_locator_filename (sal.symtab->filename);
62130803Smarcel          else
63130803Smarcel             tui_update_locator_filename ("??");
64130803Smarcel	}
65130803Smarcel    }
66130803Smarcel}
67130803Smarcel
68130803Smarcel
69130803Smarcel
70130803Smarcel/* Function to display source in the source window.  This function
71130803Smarcel   initializes the horizontal scroll to 0.  */
72130803Smarcelvoid
73130803Smarceltui_update_source_window (struct tui_win_info * win_info, struct symtab *s,
74130803Smarcel			  union tui_line_or_address line_or_addr, int noerror)
75130803Smarcel{
76130803Smarcel  win_info->detail.source_info.horizontal_offset = 0;
77130803Smarcel  tui_update_source_window_as_is (win_info, s, line_or_addr, noerror);
78130803Smarcel
79130803Smarcel  return;
80130803Smarcel}
81130803Smarcel
82130803Smarcel
83130803Smarcel/* Function to display source in the source/asm window.  This function
84130803Smarcel   shows the source as specified by the horizontal offset.  */
85130803Smarcelvoid
86130803Smarceltui_update_source_window_as_is (struct tui_win_info * win_info, struct symtab *s,
87130803Smarcel				union tui_line_or_address line_or_addr, int noerror)
88130803Smarcel{
89130803Smarcel  enum tui_status ret;
90130803Smarcel
91130803Smarcel  if (win_info->generic.type == SRC_WIN)
92130803Smarcel    ret = tui_set_source_content (s, line_or_addr.line_no, noerror);
93130803Smarcel  else
94130803Smarcel    ret = tui_set_disassem_content (line_or_addr.addr);
95130803Smarcel
96130803Smarcel  if (ret == TUI_FAILURE)
97130803Smarcel    {
98130803Smarcel      tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT);
99130803Smarcel      tui_clear_exec_info_content (win_info);
100130803Smarcel    }
101130803Smarcel  else
102130803Smarcel    {
103130803Smarcel      tui_update_breakpoint_info (win_info, 0);
104130803Smarcel      tui_show_source_content (win_info);
105130803Smarcel      tui_update_exec_info (win_info);
106130803Smarcel      if (win_info->generic.type == SRC_WIN)
107130803Smarcel	{
108130803Smarcel	  struct symtab_and_line sal;
109130803Smarcel
110130803Smarcel	  sal.line = line_or_addr.line_no +
111130803Smarcel	    (win_info->generic.content_size - 2);
112130803Smarcel	  sal.symtab = s;
113130803Smarcel	  set_current_source_symtab_and_line (&sal);
114130803Smarcel	  /*
115130803Smarcel	     ** If the focus was in the asm win, put it in the src
116130803Smarcel	     ** win if we don't have a split layout
117130803Smarcel	   */
118130803Smarcel	  if (tui_win_with_focus () == TUI_DISASM_WIN &&
119130803Smarcel	      tui_current_layout () != SRC_DISASSEM_COMMAND)
120130803Smarcel	    tui_set_win_focus_to (TUI_SRC_WIN);
121130803Smarcel	}
122130803Smarcel    }
123130803Smarcel
124130803Smarcel
125130803Smarcel  return;
126130803Smarcel}
127130803Smarcel
128130803Smarcel
129130803Smarcel/* Function to ensure that the source and/or disassemly windows
130130803Smarcel   reflect the input address.  */
131130803Smarcelvoid
132130803Smarceltui_update_source_windows_with_addr (CORE_ADDR addr)
133130803Smarcel{
134130803Smarcel  if (addr != 0)
135130803Smarcel    {
136130803Smarcel      struct symtab_and_line sal;
137130803Smarcel      union tui_line_or_address l;
138130803Smarcel
139130803Smarcel      switch (tui_current_layout ())
140130803Smarcel	{
141130803Smarcel	case DISASSEM_COMMAND:
142130803Smarcel	case DISASSEM_DATA_COMMAND:
143130803Smarcel	  tui_show_disassem (addr);
144130803Smarcel	  break;
145130803Smarcel	case SRC_DISASSEM_COMMAND:
146130803Smarcel	  tui_show_disassem_and_update_source (addr);
147130803Smarcel	  break;
148130803Smarcel	default:
149130803Smarcel	  sal = find_pc_line (addr, 0);
150130803Smarcel	  l.line_no = sal.line;
151130803Smarcel	  tui_show_symtab_source (sal.symtab, l, FALSE);
152130803Smarcel	  break;
153130803Smarcel	}
154130803Smarcel    }
155130803Smarcel  else
156130803Smarcel    {
157130803Smarcel      int i;
158130803Smarcel
159130803Smarcel      for (i = 0; i < (tui_source_windows ())->count; i++)
160130803Smarcel	{
161130803Smarcel	  struct tui_win_info * win_info = (struct tui_win_info *) (tui_source_windows ())->list[i];
162130803Smarcel
163130803Smarcel	  tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT);
164130803Smarcel	  tui_clear_exec_info_content (win_info);
165130803Smarcel	}
166130803Smarcel    }
167130803Smarcel}
168130803Smarcel
169130803Smarcel/* Function to ensure that the source and/or disassemly windows
170130803Smarcel   reflect the input address.  */
171130803Smarcelvoid
172130803Smarceltui_update_source_windows_with_line (struct symtab *s, int line)
173130803Smarcel{
174130803Smarcel  CORE_ADDR pc;
175130803Smarcel  union tui_line_or_address l;
176130803Smarcel
177130803Smarcel  switch (tui_current_layout ())
178130803Smarcel    {
179130803Smarcel    case DISASSEM_COMMAND:
180130803Smarcel    case DISASSEM_DATA_COMMAND:
181130803Smarcel      find_line_pc (s, line, &pc);
182130803Smarcel      tui_update_source_windows_with_addr (pc);
183130803Smarcel      break;
184130803Smarcel    default:
185130803Smarcel      l.line_no = line;
186130803Smarcel      tui_show_symtab_source (s, l, FALSE);
187130803Smarcel      if (tui_current_layout () == SRC_DISASSEM_COMMAND)
188130803Smarcel	{
189130803Smarcel	  find_line_pc (s, line, &pc);
190130803Smarcel	  tui_show_disassem (pc);
191130803Smarcel	}
192130803Smarcel      break;
193130803Smarcel    }
194130803Smarcel
195130803Smarcel  return;
196130803Smarcel}
197130803Smarcel
198130803Smarcelvoid
199130803Smarceltui_clear_source_content (struct tui_win_info * win_info, int display_prompt)
200130803Smarcel{
201130803Smarcel  if (win_info != NULL)
202130803Smarcel    {
203130803Smarcel      int i;
204130803Smarcel
205130803Smarcel      win_info->generic.content_in_use = FALSE;
206130803Smarcel      tui_erase_source_content (win_info, display_prompt);
207130803Smarcel      for (i = 0; i < win_info->generic.content_size; i++)
208130803Smarcel	{
209130803Smarcel	  struct tui_win_element * element =
210130803Smarcel	  (struct tui_win_element *) win_info->generic.content[i];
211130803Smarcel	  element->which_element.source.has_break = FALSE;
212130803Smarcel	  element->which_element.source.is_exec_point = FALSE;
213130803Smarcel	}
214130803Smarcel    }
215130803Smarcel}
216130803Smarcel
217130803Smarcel
218130803Smarcelvoid
219130803Smarceltui_erase_source_content (struct tui_win_info * win_info, int display_prompt)
220130803Smarcel{
221130803Smarcel  int x_pos;
222130803Smarcel  int half_width = (win_info->generic.width - 2) / 2;
223130803Smarcel
224130803Smarcel  if (win_info->generic.handle != (WINDOW *) NULL)
225130803Smarcel    {
226130803Smarcel      werase (win_info->generic.handle);
227130803Smarcel      tui_check_and_display_highlight_if_needed (win_info);
228130803Smarcel      if (display_prompt == EMPTY_SOURCE_PROMPT)
229130803Smarcel	{
230130803Smarcel	  char *no_src_str;
231130803Smarcel
232130803Smarcel	  if (win_info->generic.type == SRC_WIN)
233130803Smarcel	    no_src_str = NO_SRC_STRING;
234130803Smarcel	  else
235130803Smarcel	    no_src_str = NO_DISASSEM_STRING;
236130803Smarcel	  if (strlen (no_src_str) >= half_width)
237130803Smarcel	    x_pos = 1;
238130803Smarcel	  else
239130803Smarcel	    x_pos = half_width - strlen (no_src_str);
240130803Smarcel	  mvwaddstr (win_info->generic.handle,
241130803Smarcel		     (win_info->generic.height / 2),
242130803Smarcel		     x_pos,
243130803Smarcel		     no_src_str);
244130803Smarcel
245130803Smarcel	  /* elz: added this function call to set the real contents of
246130803Smarcel	     the window to what is on the  screen, so that later calls
247130803Smarcel	     to refresh, do display
248130803Smarcel	     the correct stuff, and not the old image */
249130803Smarcel
250130803Smarcel	  tui_set_source_content_nil (win_info, no_src_str);
251130803Smarcel	}
252130803Smarcel      tui_refresh_win (&win_info->generic);
253130803Smarcel    }
254130803Smarcel}
255130803Smarcel
256130803Smarcel
257130803Smarcel/* Redraw the complete line of a source or disassembly window.  */
258130803Smarcelstatic void
259130803Smarceltui_show_source_line (struct tui_win_info * win_info, int lineno)
260130803Smarcel{
261130803Smarcel  struct tui_win_element * line;
262130803Smarcel  int x, y;
263130803Smarcel
264130803Smarcel  line = (struct tui_win_element *) win_info->generic.content[lineno - 1];
265130803Smarcel  if (line->which_element.source.is_exec_point)
266130803Smarcel    wattron (win_info->generic.handle, A_STANDOUT);
267130803Smarcel
268130803Smarcel  mvwaddstr (win_info->generic.handle, lineno, 1,
269130803Smarcel             line->which_element.source.line);
270130803Smarcel  if (line->which_element.source.is_exec_point)
271130803Smarcel    wattroff (win_info->generic.handle, A_STANDOUT);
272130803Smarcel
273130803Smarcel  /* Clear to end of line but stop before the border.  */
274130803Smarcel  getyx (win_info->generic.handle, y, x);
275130803Smarcel  while (x + 1 < win_info->generic.width)
276130803Smarcel    {
277130803Smarcel      waddch (win_info->generic.handle, ' ');
278130803Smarcel      getyx (win_info->generic.handle, y, x);
279130803Smarcel    }
280130803Smarcel}
281130803Smarcel
282130803Smarcelvoid
283130803Smarceltui_show_source_content (struct tui_win_info * win_info)
284130803Smarcel{
285130803Smarcel  if (win_info->generic.content_size > 0)
286130803Smarcel    {
287130803Smarcel      int lineno;
288130803Smarcel
289130803Smarcel      for (lineno = 1; lineno <= win_info->generic.content_size; lineno++)
290130803Smarcel        tui_show_source_line (win_info, lineno);
291130803Smarcel    }
292130803Smarcel  else
293130803Smarcel    tui_erase_source_content (win_info, TRUE);
294130803Smarcel
295130803Smarcel  tui_check_and_display_highlight_if_needed (win_info);
296130803Smarcel  tui_refresh_win (&win_info->generic);
297130803Smarcel  win_info->generic.content_in_use = TRUE;
298130803Smarcel}
299130803Smarcel
300130803Smarcel
301130803Smarcel/* Scroll the source forward or backward horizontally.  */
302130803Smarcelvoid
303130803Smarceltui_horizontal_source_scroll (struct tui_win_info * win_info,
304130803Smarcel			      enum tui_scroll_direction direction,
305130803Smarcel			      int num_to_scroll)
306130803Smarcel{
307130803Smarcel  if (win_info->generic.content != NULL)
308130803Smarcel    {
309130803Smarcel      int offset;
310130803Smarcel      struct symtab *s;
311130803Smarcel      struct symtab_and_line cursal = get_current_source_symtab_and_line ();
312130803Smarcel
313130803Smarcel      if (cursal.symtab == (struct symtab *) NULL)
314130803Smarcel	s = find_pc_symtab (get_frame_pc (deprecated_selected_frame));
315130803Smarcel      else
316130803Smarcel	s = cursal.symtab;
317130803Smarcel
318130803Smarcel      if (direction == LEFT_SCROLL)
319130803Smarcel	offset = win_info->detail.source_info.horizontal_offset + num_to_scroll;
320130803Smarcel      else
321130803Smarcel	{
322130803Smarcel	  if ((offset =
323130803Smarcel	     win_info->detail.source_info.horizontal_offset - num_to_scroll) < 0)
324130803Smarcel	    offset = 0;
325130803Smarcel	}
326130803Smarcel      win_info->detail.source_info.horizontal_offset = offset;
327130803Smarcel      tui_update_source_window_as_is (win_info, s,
328130803Smarcel				      ((struct tui_win_element *)
329130803Smarcel				       win_info->generic.content[0])->which_element.source.line_or_addr,
330130803Smarcel				      FALSE);
331130803Smarcel    }
332130803Smarcel
333130803Smarcel  return;
334130803Smarcel}
335130803Smarcel
336130803Smarcel
337130803Smarcel/* Set or clear the has_break flag in the line whose line is line_no.  */
338130803Smarcelvoid
339130803Smarceltui_set_is_exec_point_at (union tui_line_or_address l, struct tui_win_info * win_info)
340130803Smarcel{
341130803Smarcel  int changed = 0;
342130803Smarcel  int i;
343130803Smarcel  tui_win_content content = (tui_win_content) win_info->generic.content;
344130803Smarcel
345130803Smarcel  i = 0;
346130803Smarcel  while (i < win_info->generic.content_size)
347130803Smarcel    {
348130803Smarcel      int new_state;
349130803Smarcel
350130803Smarcel      if (content[i]->which_element.source.line_or_addr.addr == l.addr)
351130803Smarcel        new_state = TRUE;
352130803Smarcel      else
353130803Smarcel	new_state = FALSE;
354130803Smarcel      if (new_state != content[i]->which_element.source.is_exec_point)
355130803Smarcel        {
356130803Smarcel          changed++;
357130803Smarcel          content[i]->which_element.source.is_exec_point = new_state;
358130803Smarcel          tui_show_source_line (win_info, i + 1);
359130803Smarcel        }
360130803Smarcel      i++;
361130803Smarcel    }
362130803Smarcel  if (changed)
363130803Smarcel    tui_refresh_win (&win_info->generic);
364130803Smarcel}
365130803Smarcel
366130803Smarcel/* Update the execution windows to show the active breakpoints.
367130803Smarcel   This is called whenever a breakpoint is inserted, removed or
368130803Smarcel   has its state changed.  */
369130803Smarcelvoid
370130803Smarceltui_update_all_breakpoint_info (void)
371130803Smarcel{
372130803Smarcel  struct tui_list *list = tui_source_windows ();
373130803Smarcel  int i;
374130803Smarcel
375130803Smarcel  for (i = 0; i < list->count; i++)
376130803Smarcel    {
377130803Smarcel      struct tui_win_info * win = (struct tui_win_info *) list->list[i];
378130803Smarcel
379130803Smarcel      if (tui_update_breakpoint_info (win, FALSE))
380130803Smarcel        {
381130803Smarcel          tui_update_exec_info (win);
382130803Smarcel        }
383130803Smarcel    }
384130803Smarcel}
385130803Smarcel
386130803Smarcel
387130803Smarcel/* Scan the source window and the breakpoints to update the
388130803Smarcel   has_break information for each line.
389130803Smarcel   Returns 1 if something changed and the execution window
390130803Smarcel   must be refreshed.  */
391130803Smarcelint
392130803Smarceltui_update_breakpoint_info (struct tui_win_info * win, int current_only)
393130803Smarcel{
394130803Smarcel  int i;
395130803Smarcel  int need_refresh = 0;
396130803Smarcel  struct tui_source_info * src = &win->detail.source_info;
397130803Smarcel
398130803Smarcel  for (i = 0; i < win->generic.content_size; i++)
399130803Smarcel    {
400130803Smarcel      struct breakpoint *bp;
401130803Smarcel      extern struct breakpoint *breakpoint_chain;
402130803Smarcel      int mode;
403130803Smarcel      struct tui_source_element* line;
404130803Smarcel
405130803Smarcel      line = &((struct tui_win_element *) win->generic.content[i])->which_element.source;
406130803Smarcel      if (current_only && !line->is_exec_point)
407130803Smarcel         continue;
408130803Smarcel
409130803Smarcel      /* Scan each breakpoint to see if the current line has something to
410130803Smarcel         do with it.  Identify enable/disabled breakpoints as well as
411130803Smarcel         those that we already hit.  */
412130803Smarcel      mode = 0;
413130803Smarcel      for (bp = breakpoint_chain;
414130803Smarcel           bp != (struct breakpoint *) NULL;
415130803Smarcel           bp = bp->next)
416130803Smarcel        {
417130803Smarcel          if ((win == TUI_SRC_WIN
418130803Smarcel               && bp->source_file
419130803Smarcel               && (strcmp (src->filename, bp->source_file) == 0)
420130803Smarcel               && bp->line_number == line->line_or_addr.line_no)
421130803Smarcel              || (win == TUI_DISASM_WIN
422130803Smarcel                  && bp->loc->address == line->line_or_addr.addr))
423130803Smarcel            {
424130803Smarcel              if (bp->enable_state == bp_disabled)
425130803Smarcel                mode |= TUI_BP_DISABLED;
426130803Smarcel              else
427130803Smarcel                mode |= TUI_BP_ENABLED;
428130803Smarcel              if (bp->hit_count)
429130803Smarcel                mode |= TUI_BP_HIT;
430130803Smarcel              if (bp->cond)
431130803Smarcel                mode |= TUI_BP_CONDITIONAL;
432130803Smarcel              if (bp->type == bp_hardware_breakpoint)
433130803Smarcel                mode |= TUI_BP_HARDWARE;
434130803Smarcel            }
435130803Smarcel        }
436130803Smarcel      if (line->has_break != mode)
437130803Smarcel        {
438130803Smarcel          line->has_break = mode;
439130803Smarcel          need_refresh = 1;
440130803Smarcel        }
441130803Smarcel    }
442130803Smarcel  return need_refresh;
443130803Smarcel}
444130803Smarcel
445130803Smarcel
446130803Smarcel/* Function to initialize the content of the execution info window,
447130803Smarcel   based upon the input window which is either the source or
448130803Smarcel   disassembly window.  */
449130803Smarcelenum tui_status
450130803Smarceltui_set_exec_info_content (struct tui_win_info * win_info)
451130803Smarcel{
452130803Smarcel  enum tui_status ret = TUI_SUCCESS;
453130803Smarcel
454130803Smarcel  if (win_info->detail.source_info.execution_info != (struct tui_gen_win_info *) NULL)
455130803Smarcel    {
456130803Smarcel      struct tui_gen_win_info * exec_info_ptr = win_info->detail.source_info.execution_info;
457130803Smarcel
458130803Smarcel      if (exec_info_ptr->content == NULL)
459130803Smarcel	exec_info_ptr->content =
460130803Smarcel	  (void **) tui_alloc_content (win_info->generic.height,
461130803Smarcel					 exec_info_ptr->type);
462130803Smarcel      if (exec_info_ptr->content != NULL)
463130803Smarcel	{
464130803Smarcel	  int i;
465130803Smarcel
466130803Smarcel          tui_update_breakpoint_info (win_info, 1);
467130803Smarcel	  for (i = 0; i < win_info->generic.content_size; i++)
468130803Smarcel	    {
469130803Smarcel	      struct tui_win_element * element;
470130803Smarcel	      struct tui_win_element * src_element;
471130803Smarcel              int mode;
472130803Smarcel
473130803Smarcel	      element = (struct tui_win_element *) exec_info_ptr->content[i];
474130803Smarcel	      src_element = (struct tui_win_element *) win_info->generic.content[i];
475130803Smarcel
476130803Smarcel              memset(element->which_element.simple_string, ' ',
477130803Smarcel                     sizeof(element->which_element.simple_string));
478130803Smarcel              element->which_element.simple_string[TUI_EXECINFO_SIZE - 1] = 0;
479130803Smarcel
480130803Smarcel	      /* Now update the exec info content based upon the state
481130803Smarcel                 of each line as indicated by the source content.  */
482130803Smarcel              mode = src_element->which_element.source.has_break;
483130803Smarcel              if (mode & TUI_BP_HIT)
484130803Smarcel                element->which_element.simple_string[TUI_BP_HIT_POS] =
485130803Smarcel                  (mode & TUI_BP_HARDWARE) ? 'H' : 'B';
486130803Smarcel              else if (mode & (TUI_BP_ENABLED | TUI_BP_DISABLED))
487130803Smarcel                element->which_element.simple_string[TUI_BP_HIT_POS] =
488130803Smarcel                  (mode & TUI_BP_HARDWARE) ? 'h' : 'b';
489130803Smarcel
490130803Smarcel              if (mode & TUI_BP_ENABLED)
491130803Smarcel                element->which_element.simple_string[TUI_BP_BREAK_POS] = '+';
492130803Smarcel              else if (mode & TUI_BP_DISABLED)
493130803Smarcel                element->which_element.simple_string[TUI_BP_BREAK_POS] = '-';
494130803Smarcel
495130803Smarcel              if (src_element->which_element.source.is_exec_point)
496130803Smarcel                element->which_element.simple_string[TUI_EXEC_POS] = '>';
497130803Smarcel	    }
498130803Smarcel	  exec_info_ptr->content_size = win_info->generic.content_size;
499130803Smarcel	}
500130803Smarcel      else
501130803Smarcel	ret = TUI_FAILURE;
502130803Smarcel    }
503130803Smarcel
504130803Smarcel  return ret;
505130803Smarcel}
506130803Smarcel
507130803Smarcel
508130803Smarcelvoid
509130803Smarceltui_show_exec_info_content (struct tui_win_info * win_info)
510130803Smarcel{
511130803Smarcel  struct tui_gen_win_info * exec_info = win_info->detail.source_info.execution_info;
512130803Smarcel  int cur_line;
513130803Smarcel
514130803Smarcel  werase (exec_info->handle);
515130803Smarcel  tui_refresh_win (exec_info);
516130803Smarcel  for (cur_line = 1; (cur_line <= exec_info->content_size); cur_line++)
517130803Smarcel    mvwaddstr (exec_info->handle,
518130803Smarcel	       cur_line,
519130803Smarcel	       0,
520130803Smarcel	       ((struct tui_win_element *)
521130803Smarcel		exec_info->content[cur_line - 1])->which_element.simple_string);
522130803Smarcel  tui_refresh_win (exec_info);
523130803Smarcel  exec_info->content_in_use = TRUE;
524130803Smarcel}
525130803Smarcel
526130803Smarcel
527130803Smarcelvoid
528130803Smarceltui_erase_exec_info_content (struct tui_win_info * win_info)
529130803Smarcel{
530130803Smarcel  struct tui_gen_win_info * exec_info = win_info->detail.source_info.execution_info;
531130803Smarcel
532130803Smarcel  werase (exec_info->handle);
533130803Smarcel  tui_refresh_win (exec_info);
534130803Smarcel}
535130803Smarcel
536130803Smarcelvoid
537130803Smarceltui_clear_exec_info_content (struct tui_win_info * win_info)
538130803Smarcel{
539130803Smarcel  win_info->detail.source_info.execution_info->content_in_use = FALSE;
540130803Smarcel  tui_erase_exec_info_content (win_info);
541130803Smarcel
542130803Smarcel  return;
543130803Smarcel}
544130803Smarcel
545130803Smarcel/* Function to update the execution info window.  */
546130803Smarcelvoid
547130803Smarceltui_update_exec_info (struct tui_win_info * win_info)
548130803Smarcel{
549130803Smarcel  tui_set_exec_info_content (win_info);
550130803Smarcel  tui_show_exec_info_content (win_info);
551130803Smarcel}
552130803Smarcel
553130803Smarcelenum tui_status
554130803Smarceltui_alloc_source_buffer (struct tui_win_info *win_info)
555130803Smarcel{
556130803Smarcel  char *src_line_buf;
557130803Smarcel  int i, line_width, max_lines;
558130803Smarcel  enum tui_status ret = TUI_FAILURE;
559130803Smarcel
560130803Smarcel  max_lines = win_info->generic.height;	/* less the highlight box */
561130803Smarcel  line_width = win_info->generic.width - 1;
562130803Smarcel  /*
563130803Smarcel     ** Allocate the buffer for the source lines.  Do this only once since they
564130803Smarcel     ** will be re-used for all source displays.  The only other time this will
565130803Smarcel     ** be done is when a window's size changes.
566130803Smarcel   */
567130803Smarcel  if (win_info->generic.content == NULL)
568130803Smarcel    {
569130803Smarcel      src_line_buf = (char *) xmalloc ((max_lines * line_width) * sizeof (char));
570130803Smarcel      if (src_line_buf == (char *) NULL)
571130803Smarcel	fputs_unfiltered (
572130803Smarcel	   "Unable to Allocate Memory for Source or Disassembly Display.\n",
573130803Smarcel			   gdb_stderr);
574130803Smarcel      else
575130803Smarcel	{
576130803Smarcel	  /* allocate the content list */
577130803Smarcel	  if ((win_info->generic.content =
578130803Smarcel	  (void **) tui_alloc_content (max_lines, SRC_WIN)) == NULL)
579130803Smarcel	    {
580130803Smarcel	      xfree (src_line_buf);
581130803Smarcel	      src_line_buf = (char *) NULL;
582130803Smarcel	      fputs_unfiltered (
583130803Smarcel				 "Unable to Allocate Memory for Source or Disassembly Display.\n",
584130803Smarcel				 gdb_stderr);
585130803Smarcel	    }
586130803Smarcel	}
587130803Smarcel      for (i = 0; i < max_lines; i++)
588130803Smarcel	((struct tui_win_element *)
589130803Smarcel	 win_info->generic.content[i])->which_element.source.line =
590130803Smarcel	  src_line_buf + (line_width * i);
591130803Smarcel      ret = TUI_SUCCESS;
592130803Smarcel    }
593130803Smarcel  else
594130803Smarcel    ret = TUI_SUCCESS;
595130803Smarcel
596130803Smarcel  return ret;
597130803Smarcel}
598130803Smarcel
599130803Smarcel
600130803Smarcel/* Answer whether the a particular line number or address is displayed
601130803Smarcel   in the current source window.  */
602130803Smarcelint
603130803Smarceltui_line_is_displayed (int line, struct tui_win_info * win_info,
604130803Smarcel		       int check_threshold)
605130803Smarcel{
606130803Smarcel  int is_displayed = FALSE;
607130803Smarcel  int i, threshold;
608130803Smarcel
609130803Smarcel  if (check_threshold)
610130803Smarcel    threshold = SCROLL_THRESHOLD;
611130803Smarcel  else
612130803Smarcel    threshold = 0;
613130803Smarcel  i = 0;
614130803Smarcel  while (i < win_info->generic.content_size - threshold && !is_displayed)
615130803Smarcel    {
616130803Smarcel      is_displayed = (((struct tui_win_element *)
617130803Smarcel		      win_info->generic.content[i])->which_element.source.line_or_addr.line_no
618130803Smarcel		     == (int) line);
619130803Smarcel      i++;
620130803Smarcel    }
621130803Smarcel
622130803Smarcel  return is_displayed;
623130803Smarcel}
624130803Smarcel
625130803Smarcel
626130803Smarcel/* Answer whether the a particular line number or address is displayed
627130803Smarcel   in the current source window.  */
628130803Smarcelint
629130803Smarceltui_addr_is_displayed (CORE_ADDR addr, struct tui_win_info * win_info,
630130803Smarcel		    int check_threshold)
631130803Smarcel{
632130803Smarcel  int is_displayed = FALSE;
633130803Smarcel  int i, threshold;
634130803Smarcel
635130803Smarcel  if (check_threshold)
636130803Smarcel    threshold = SCROLL_THRESHOLD;
637130803Smarcel  else
638130803Smarcel    threshold = 0;
639130803Smarcel  i = 0;
640130803Smarcel  while (i < win_info->generic.content_size - threshold && !is_displayed)
641130803Smarcel    {
642130803Smarcel      is_displayed = (((struct tui_win_element *)
643130803Smarcel		      win_info->generic.content[i])->which_element.source.line_or_addr.addr
644130803Smarcel		     == addr);
645130803Smarcel      i++;
646130803Smarcel    }
647130803Smarcel
648130803Smarcel  return is_displayed;
649130803Smarcel}
650130803Smarcel
651130803Smarcel
652130803Smarcel/*****************************************
653130803Smarcel** STATIC LOCAL FUNCTIONS               **
654130803Smarcel******************************************/
655