Home | History | Annotate | Line # | Download | only in tui
tui-winsource.c revision 1.1
      1  1.1  christos /* TUI display source/assembly window.
      2  1.1  christos 
      3  1.1  christos    Copyright (C) 1998-2014 Free Software Foundation, Inc.
      4  1.1  christos 
      5  1.1  christos    Contributed by Hewlett-Packard Company.
      6  1.1  christos 
      7  1.1  christos    This file is part of GDB.
      8  1.1  christos 
      9  1.1  christos    This program is free software; you can redistribute it and/or modify
     10  1.1  christos    it under the terms of the GNU General Public License as published by
     11  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     12  1.1  christos    (at your option) any later version.
     13  1.1  christos 
     14  1.1  christos    This program is distributed in the hope that it will be useful,
     15  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     16  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17  1.1  christos    GNU General Public License for more details.
     18  1.1  christos 
     19  1.1  christos    You should have received a copy of the GNU General Public License
     20  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     21  1.1  christos 
     22  1.1  christos #include "defs.h"
     23  1.1  christos #include <ctype.h>
     24  1.1  christos #include "symtab.h"
     25  1.1  christos #include "frame.h"
     26  1.1  christos #include "breakpoint.h"
     27  1.1  christos #include "value.h"
     28  1.1  christos #include "source.h"
     29  1.1  christos #include "objfiles.h"
     30  1.1  christos #include "filenames.h"
     31  1.1  christos 
     32  1.1  christos #include "tui/tui.h"
     33  1.1  christos #include "tui/tui-data.h"
     34  1.1  christos #include "tui/tui-stack.h"
     35  1.1  christos #include "tui/tui-win.h"
     36  1.1  christos #include "tui/tui-wingeneral.h"
     37  1.1  christos #include "tui/tui-winsource.h"
     38  1.1  christos #include "tui/tui-source.h"
     39  1.1  christos #include "tui/tui-disasm.h"
     40  1.1  christos 
     41  1.1  christos #include <string.h>
     42  1.1  christos #include "gdb_curses.h"
     43  1.1  christos #include "gdb_assert.h"
     44  1.1  christos 
     45  1.1  christos /* Function to display the "main" routine.  */
     46  1.1  christos void
     47  1.1  christos tui_display_main (void)
     48  1.1  christos {
     49  1.1  christos   if ((tui_source_windows ())->count > 0)
     50  1.1  christos     {
     51  1.1  christos       struct gdbarch *gdbarch;
     52  1.1  christos       CORE_ADDR addr;
     53  1.1  christos 
     54  1.1  christos       tui_get_begin_asm_address (&gdbarch, &addr);
     55  1.1  christos       if (addr != (CORE_ADDR) 0)
     56  1.1  christos 	{
     57  1.1  christos 	  struct symtab_and_line sal;
     58  1.1  christos 
     59  1.1  christos 	  tui_update_source_windows_with_addr (gdbarch, addr);
     60  1.1  christos 	  sal = find_pc_line (addr, 0);
     61  1.1  christos           if (sal.symtab)
     62  1.1  christos              tui_update_locator_fullname (symtab_to_fullname (sal.symtab));
     63  1.1  christos           else
     64  1.1  christos              tui_update_locator_fullname ("??");
     65  1.1  christos 	}
     66  1.1  christos     }
     67  1.1  christos }
     68  1.1  christos 
     69  1.1  christos 
     70  1.1  christos 
     71  1.1  christos /* Function to display source in the source window.  This function
     72  1.1  christos    initializes the horizontal scroll to 0.  */
     73  1.1  christos void
     74  1.1  christos tui_update_source_window (struct tui_win_info *win_info,
     75  1.1  christos 			  struct gdbarch *gdbarch,
     76  1.1  christos 			  struct symtab *s,
     77  1.1  christos 			  struct tui_line_or_address line_or_addr,
     78  1.1  christos 			  int noerror)
     79  1.1  christos {
     80  1.1  christos   win_info->detail.source_info.horizontal_offset = 0;
     81  1.1  christos   tui_update_source_window_as_is (win_info, gdbarch, s, line_or_addr, noerror);
     82  1.1  christos 
     83  1.1  christos   return;
     84  1.1  christos }
     85  1.1  christos 
     86  1.1  christos 
     87  1.1  christos /* Function to display source in the source/asm window.  This function
     88  1.1  christos    shows the source as specified by the horizontal offset.  */
     89  1.1  christos void
     90  1.1  christos tui_update_source_window_as_is (struct tui_win_info *win_info,
     91  1.1  christos 				struct gdbarch *gdbarch,
     92  1.1  christos 				struct symtab *s,
     93  1.1  christos 				struct tui_line_or_address line_or_addr,
     94  1.1  christos 				int noerror)
     95  1.1  christos {
     96  1.1  christos   enum tui_status ret;
     97  1.1  christos 
     98  1.1  christos   if (win_info->generic.type == SRC_WIN)
     99  1.1  christos     ret = tui_set_source_content (s, line_or_addr.u.line_no, noerror);
    100  1.1  christos   else
    101  1.1  christos     ret = tui_set_disassem_content (gdbarch, line_or_addr.u.addr);
    102  1.1  christos 
    103  1.1  christos   if (ret == TUI_FAILURE)
    104  1.1  christos     {
    105  1.1  christos       tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT);
    106  1.1  christos       tui_clear_exec_info_content (win_info);
    107  1.1  christos     }
    108  1.1  christos   else
    109  1.1  christos     {
    110  1.1  christos       tui_update_breakpoint_info (win_info, 0);
    111  1.1  christos       tui_show_source_content (win_info);
    112  1.1  christos       tui_update_exec_info (win_info);
    113  1.1  christos       if (win_info->generic.type == SRC_WIN)
    114  1.1  christos 	{
    115  1.1  christos 	  struct symtab_and_line sal;
    116  1.1  christos 
    117  1.1  christos 	  init_sal (&sal);
    118  1.1  christos 	  sal.line = line_or_addr.u.line_no +
    119  1.1  christos 	    (win_info->generic.content_size - 2);
    120  1.1  christos 	  sal.symtab = s;
    121  1.1  christos 	  sal.pspace = s->objfile->pspace;
    122  1.1  christos 	  set_current_source_symtab_and_line (&sal);
    123  1.1  christos 	  /* If the focus was in the asm win, put it in the src win if
    124  1.1  christos 	     we don't have a split layout.  */
    125  1.1  christos 	  if (tui_win_with_focus () == TUI_DISASM_WIN
    126  1.1  christos 	      && tui_current_layout () != SRC_DISASSEM_COMMAND)
    127  1.1  christos 	    tui_set_win_focus_to (TUI_SRC_WIN);
    128  1.1  christos 	}
    129  1.1  christos     }
    130  1.1  christos 
    131  1.1  christos 
    132  1.1  christos   return;
    133  1.1  christos }
    134  1.1  christos 
    135  1.1  christos 
    136  1.1  christos /* Function to ensure that the source and/or disassemly windows
    137  1.1  christos    reflect the input address.  */
    138  1.1  christos void
    139  1.1  christos tui_update_source_windows_with_addr (struct gdbarch *gdbarch, CORE_ADDR addr)
    140  1.1  christos {
    141  1.1  christos   if (addr != 0)
    142  1.1  christos     {
    143  1.1  christos       struct symtab_and_line sal;
    144  1.1  christos       struct tui_line_or_address l;
    145  1.1  christos 
    146  1.1  christos       switch (tui_current_layout ())
    147  1.1  christos 	{
    148  1.1  christos 	case DISASSEM_COMMAND:
    149  1.1  christos 	case DISASSEM_DATA_COMMAND:
    150  1.1  christos 	  tui_show_disassem (gdbarch, addr);
    151  1.1  christos 	  break;
    152  1.1  christos 	case SRC_DISASSEM_COMMAND:
    153  1.1  christos 	  tui_show_disassem_and_update_source (gdbarch, addr);
    154  1.1  christos 	  break;
    155  1.1  christos 	default:
    156  1.1  christos 	  sal = find_pc_line (addr, 0);
    157  1.1  christos 	  l.loa = LOA_LINE;
    158  1.1  christos 	  l.u.line_no = sal.line;
    159  1.1  christos 	  tui_show_symtab_source (gdbarch, sal.symtab, l, FALSE);
    160  1.1  christos 	  break;
    161  1.1  christos 	}
    162  1.1  christos     }
    163  1.1  christos   else
    164  1.1  christos     {
    165  1.1  christos       int i;
    166  1.1  christos 
    167  1.1  christos       for (i = 0; i < (tui_source_windows ())->count; i++)
    168  1.1  christos 	{
    169  1.1  christos 	  struct tui_win_info *win_info = (tui_source_windows ())->list[i];
    170  1.1  christos 
    171  1.1  christos 	  tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT);
    172  1.1  christos 	  tui_clear_exec_info_content (win_info);
    173  1.1  christos 	}
    174  1.1  christos     }
    175  1.1  christos }
    176  1.1  christos 
    177  1.1  christos /* Function to ensure that the source and/or disassemly windows
    178  1.1  christos    reflect the input address.  */
    179  1.1  christos void
    180  1.1  christos tui_update_source_windows_with_line (struct symtab *s, int line)
    181  1.1  christos {
    182  1.1  christos   struct gdbarch *gdbarch;
    183  1.1  christos   CORE_ADDR pc;
    184  1.1  christos   struct tui_line_or_address l;
    185  1.1  christos 
    186  1.1  christos   if (!s)
    187  1.1  christos     return;
    188  1.1  christos 
    189  1.1  christos   gdbarch = get_objfile_arch (s->objfile);
    190  1.1  christos 
    191  1.1  christos   switch (tui_current_layout ())
    192  1.1  christos     {
    193  1.1  christos     case DISASSEM_COMMAND:
    194  1.1  christos     case DISASSEM_DATA_COMMAND:
    195  1.1  christos       find_line_pc (s, line, &pc);
    196  1.1  christos       tui_update_source_windows_with_addr (gdbarch, pc);
    197  1.1  christos       break;
    198  1.1  christos     default:
    199  1.1  christos       l.loa = LOA_LINE;
    200  1.1  christos       l.u.line_no = line;
    201  1.1  christos       tui_show_symtab_source (gdbarch, s, l, FALSE);
    202  1.1  christos       if (tui_current_layout () == SRC_DISASSEM_COMMAND)
    203  1.1  christos 	{
    204  1.1  christos 	  find_line_pc (s, line, &pc);
    205  1.1  christos 	  tui_show_disassem (gdbarch, pc);
    206  1.1  christos 	}
    207  1.1  christos       break;
    208  1.1  christos     }
    209  1.1  christos 
    210  1.1  christos   return;
    211  1.1  christos }
    212  1.1  christos 
    213  1.1  christos void
    214  1.1  christos tui_clear_source_content (struct tui_win_info *win_info,
    215  1.1  christos 			  int display_prompt)
    216  1.1  christos {
    217  1.1  christos   if (win_info != NULL)
    218  1.1  christos     {
    219  1.1  christos       int i;
    220  1.1  christos 
    221  1.1  christos       win_info->generic.content_in_use = FALSE;
    222  1.1  christos       tui_erase_source_content (win_info, display_prompt);
    223  1.1  christos       for (i = 0; i < win_info->generic.content_size; i++)
    224  1.1  christos 	{
    225  1.1  christos 	  struct tui_win_element *element =
    226  1.1  christos 	    (struct tui_win_element *) win_info->generic.content[i];
    227  1.1  christos 
    228  1.1  christos 	  element->which_element.source.has_break = FALSE;
    229  1.1  christos 	  element->which_element.source.is_exec_point = FALSE;
    230  1.1  christos 	}
    231  1.1  christos     }
    232  1.1  christos }
    233  1.1  christos 
    234  1.1  christos 
    235  1.1  christos void
    236  1.1  christos tui_erase_source_content (struct tui_win_info *win_info,
    237  1.1  christos 			  int display_prompt)
    238  1.1  christos {
    239  1.1  christos   int x_pos;
    240  1.1  christos   int half_width = (win_info->generic.width - 2) / 2;
    241  1.1  christos 
    242  1.1  christos   if (win_info->generic.handle != (WINDOW *) NULL)
    243  1.1  christos     {
    244  1.1  christos       werase (win_info->generic.handle);
    245  1.1  christos       tui_check_and_display_highlight_if_needed (win_info);
    246  1.1  christos       if (display_prompt == EMPTY_SOURCE_PROMPT)
    247  1.1  christos 	{
    248  1.1  christos 	  char *no_src_str;
    249  1.1  christos 
    250  1.1  christos 	  if (win_info->generic.type == SRC_WIN)
    251  1.1  christos 	    no_src_str = NO_SRC_STRING;
    252  1.1  christos 	  else
    253  1.1  christos 	    no_src_str = NO_DISASSEM_STRING;
    254  1.1  christos 	  if (strlen (no_src_str) >= half_width)
    255  1.1  christos 	    x_pos = 1;
    256  1.1  christos 	  else
    257  1.1  christos 	    x_pos = half_width - strlen (no_src_str);
    258  1.1  christos 	  mvwaddstr (win_info->generic.handle,
    259  1.1  christos 		     (win_info->generic.height / 2),
    260  1.1  christos 		     x_pos,
    261  1.1  christos 		     no_src_str);
    262  1.1  christos 
    263  1.1  christos 	  /* elz: Added this function call to set the real contents of
    264  1.1  christos 	     the window to what is on the screen, so that later calls
    265  1.1  christos 	     to refresh, do display the correct stuff, and not the old
    266  1.1  christos 	     image.  */
    267  1.1  christos 
    268  1.1  christos 	  tui_set_source_content_nil (win_info, no_src_str);
    269  1.1  christos 	}
    270  1.1  christos       tui_refresh_win (&win_info->generic);
    271  1.1  christos     }
    272  1.1  christos }
    273  1.1  christos 
    274  1.1  christos 
    275  1.1  christos /* Redraw the complete line of a source or disassembly window.  */
    276  1.1  christos static void
    277  1.1  christos tui_show_source_line (struct tui_win_info *win_info, int lineno)
    278  1.1  christos {
    279  1.1  christos   struct tui_win_element *line;
    280  1.1  christos   int x, y;
    281  1.1  christos 
    282  1.1  christos   line = (struct tui_win_element *) win_info->generic.content[lineno - 1];
    283  1.1  christos   if (line->which_element.source.is_exec_point)
    284  1.1  christos     wattron (win_info->generic.handle, A_STANDOUT);
    285  1.1  christos 
    286  1.1  christos   mvwaddstr (win_info->generic.handle, lineno, 1,
    287  1.1  christos              line->which_element.source.line);
    288  1.1  christos   if (line->which_element.source.is_exec_point)
    289  1.1  christos     wattroff (win_info->generic.handle, A_STANDOUT);
    290  1.1  christos 
    291  1.1  christos   /* Clear to end of line but stop before the border.  */
    292  1.1  christos   getyx (win_info->generic.handle, y, x);
    293  1.1  christos   while (x + 1 < win_info->generic.width)
    294  1.1  christos     {
    295  1.1  christos       waddch (win_info->generic.handle, ' ');
    296  1.1  christos       getyx (win_info->generic.handle, y, x);
    297  1.1  christos     }
    298  1.1  christos }
    299  1.1  christos 
    300  1.1  christos void
    301  1.1  christos tui_show_source_content (struct tui_win_info *win_info)
    302  1.1  christos {
    303  1.1  christos   if (win_info->generic.content_size > 0)
    304  1.1  christos     {
    305  1.1  christos       int lineno;
    306  1.1  christos 
    307  1.1  christos       for (lineno = 1; lineno <= win_info->generic.content_size; lineno++)
    308  1.1  christos         tui_show_source_line (win_info, lineno);
    309  1.1  christos     }
    310  1.1  christos   else
    311  1.1  christos     tui_erase_source_content (win_info, TRUE);
    312  1.1  christos 
    313  1.1  christos   tui_check_and_display_highlight_if_needed (win_info);
    314  1.1  christos   tui_refresh_win (&win_info->generic);
    315  1.1  christos   win_info->generic.content_in_use = TRUE;
    316  1.1  christos }
    317  1.1  christos 
    318  1.1  christos 
    319  1.1  christos /* Scroll the source forward or backward horizontally.  */
    320  1.1  christos void
    321  1.1  christos tui_horizontal_source_scroll (struct tui_win_info *win_info,
    322  1.1  christos 			      enum tui_scroll_direction direction,
    323  1.1  christos 			      int num_to_scroll)
    324  1.1  christos {
    325  1.1  christos   if (win_info->generic.content != NULL)
    326  1.1  christos     {
    327  1.1  christos       struct gdbarch *gdbarch = win_info->detail.source_info.gdbarch;
    328  1.1  christos       int offset;
    329  1.1  christos       struct symtab *s = NULL;
    330  1.1  christos 
    331  1.1  christos       if (win_info->generic.type == SRC_WIN)
    332  1.1  christos 	{
    333  1.1  christos 	  struct symtab_and_line cursal
    334  1.1  christos 	    = get_current_source_symtab_and_line ();
    335  1.1  christos 
    336  1.1  christos 	  if (cursal.symtab == NULL)
    337  1.1  christos 	    s = find_pc_symtab (get_frame_pc (get_selected_frame (NULL)));
    338  1.1  christos 	  else
    339  1.1  christos 	    s = cursal.symtab;
    340  1.1  christos 	}
    341  1.1  christos 
    342  1.1  christos       if (direction == LEFT_SCROLL)
    343  1.1  christos 	offset = win_info->detail.source_info.horizontal_offset
    344  1.1  christos 	  + num_to_scroll;
    345  1.1  christos       else
    346  1.1  christos 	{
    347  1.1  christos 	  offset = win_info->detail.source_info.horizontal_offset
    348  1.1  christos 	    - num_to_scroll;
    349  1.1  christos 	  if (offset < 0)
    350  1.1  christos 	    offset = 0;
    351  1.1  christos 	}
    352  1.1  christos       win_info->detail.source_info.horizontal_offset = offset;
    353  1.1  christos       tui_update_source_window_as_is (win_info, gdbarch, s,
    354  1.1  christos 				      ((struct tui_win_element *)
    355  1.1  christos 				       win_info->generic.content[0])->which_element.source.line_or_addr,
    356  1.1  christos 				      FALSE);
    357  1.1  christos     }
    358  1.1  christos 
    359  1.1  christos   return;
    360  1.1  christos }
    361  1.1  christos 
    362  1.1  christos 
    363  1.1  christos /* Set or clear the has_break flag in the line whose line is
    364  1.1  christos    line_no.  */
    365  1.1  christos 
    366  1.1  christos void
    367  1.1  christos tui_set_is_exec_point_at (struct tui_line_or_address l,
    368  1.1  christos 			  struct tui_win_info *win_info)
    369  1.1  christos {
    370  1.1  christos   int changed = 0;
    371  1.1  christos   int i;
    372  1.1  christos   tui_win_content content = (tui_win_content) win_info->generic.content;
    373  1.1  christos 
    374  1.1  christos   i = 0;
    375  1.1  christos   while (i < win_info->generic.content_size)
    376  1.1  christos     {
    377  1.1  christos       int new_state;
    378  1.1  christos       struct tui_line_or_address content_loa =
    379  1.1  christos 	content[i]->which_element.source.line_or_addr;
    380  1.1  christos 
    381  1.1  christos       gdb_assert (l.loa == LOA_ADDRESS || l.loa == LOA_LINE);
    382  1.1  christos       gdb_assert (content_loa.loa == LOA_LINE
    383  1.1  christos 		  || content_loa.loa == LOA_ADDRESS);
    384  1.1  christos       if (content_loa.loa == l.loa
    385  1.1  christos 	  && ((l.loa == LOA_LINE && content_loa.u.line_no == l.u.line_no)
    386  1.1  christos               || (content_loa.u.addr == l.u.addr)))
    387  1.1  christos         new_state = TRUE;
    388  1.1  christos       else
    389  1.1  christos 	new_state = FALSE;
    390  1.1  christos       if (new_state != content[i]->which_element.source.is_exec_point)
    391  1.1  christos         {
    392  1.1  christos           changed++;
    393  1.1  christos           content[i]->which_element.source.is_exec_point = new_state;
    394  1.1  christos           tui_show_source_line (win_info, i + 1);
    395  1.1  christos         }
    396  1.1  christos       i++;
    397  1.1  christos     }
    398  1.1  christos   if (changed)
    399  1.1  christos     tui_refresh_win (&win_info->generic);
    400  1.1  christos }
    401  1.1  christos 
    402  1.1  christos /* Update the execution windows to show the active breakpoints.
    403  1.1  christos    This is called whenever a breakpoint is inserted, removed or
    404  1.1  christos    has its state changed.  */
    405  1.1  christos void
    406  1.1  christos tui_update_all_breakpoint_info (void)
    407  1.1  christos {
    408  1.1  christos   struct tui_list *list = tui_source_windows ();
    409  1.1  christos   int i;
    410  1.1  christos 
    411  1.1  christos   for (i = 0; i < list->count; i++)
    412  1.1  christos     {
    413  1.1  christos       struct tui_win_info *win = list->list[i];
    414  1.1  christos 
    415  1.1  christos       if (tui_update_breakpoint_info (win, FALSE))
    416  1.1  christos         {
    417  1.1  christos           tui_update_exec_info (win);
    418  1.1  christos         }
    419  1.1  christos     }
    420  1.1  christos }
    421  1.1  christos 
    422  1.1  christos 
    423  1.1  christos /* Scan the source window and the breakpoints to update the has_break
    424  1.1  christos    information for each line.
    425  1.1  christos 
    426  1.1  christos    Returns 1 if something changed and the execution window must be
    427  1.1  christos    refreshed.  */
    428  1.1  christos 
    429  1.1  christos int
    430  1.1  christos tui_update_breakpoint_info (struct tui_win_info *win,
    431  1.1  christos 			    int current_only)
    432  1.1  christos {
    433  1.1  christos   int i;
    434  1.1  christos   int need_refresh = 0;
    435  1.1  christos   struct tui_source_info *src = &win->detail.source_info;
    436  1.1  christos 
    437  1.1  christos   for (i = 0; i < win->generic.content_size; i++)
    438  1.1  christos     {
    439  1.1  christos       struct breakpoint *bp;
    440  1.1  christos       extern struct breakpoint *breakpoint_chain;
    441  1.1  christos       int mode;
    442  1.1  christos       struct tui_source_element *line;
    443  1.1  christos 
    444  1.1  christos       line = &((struct tui_win_element *)
    445  1.1  christos 	       win->generic.content[i])->which_element.source;
    446  1.1  christos       if (current_only && !line->is_exec_point)
    447  1.1  christos          continue;
    448  1.1  christos 
    449  1.1  christos       /* Scan each breakpoint to see if the current line has something to
    450  1.1  christos          do with it.  Identify enable/disabled breakpoints as well as
    451  1.1  christos          those that we already hit.  */
    452  1.1  christos       mode = 0;
    453  1.1  christos       for (bp = breakpoint_chain;
    454  1.1  christos            bp != (struct breakpoint *) NULL;
    455  1.1  christos            bp = bp->next)
    456  1.1  christos         {
    457  1.1  christos 	  struct bp_location *loc;
    458  1.1  christos 
    459  1.1  christos 	  gdb_assert (line->line_or_addr.loa == LOA_LINE
    460  1.1  christos 		      || line->line_or_addr.loa == LOA_ADDRESS);
    461  1.1  christos 
    462  1.1  christos 	  for (loc = bp->loc; loc != NULL; loc = loc->next)
    463  1.1  christos 	    {
    464  1.1  christos 	      if ((win == TUI_SRC_WIN
    465  1.1  christos 		   && loc->symtab != NULL
    466  1.1  christos 		   && filename_cmp (src->fullname,
    467  1.1  christos 				    symtab_to_fullname (loc->symtab)) == 0
    468  1.1  christos 		   && line->line_or_addr.loa == LOA_LINE
    469  1.1  christos 		   && loc->line_number == line->line_or_addr.u.line_no)
    470  1.1  christos 		  || (win == TUI_DISASM_WIN
    471  1.1  christos 		      && line->line_or_addr.loa == LOA_ADDRESS
    472  1.1  christos 		      && loc->address == line->line_or_addr.u.addr))
    473  1.1  christos 		{
    474  1.1  christos 		  if (bp->enable_state == bp_disabled)
    475  1.1  christos 		    mode |= TUI_BP_DISABLED;
    476  1.1  christos 		  else
    477  1.1  christos 		    mode |= TUI_BP_ENABLED;
    478  1.1  christos 		  if (bp->hit_count)
    479  1.1  christos 		    mode |= TUI_BP_HIT;
    480  1.1  christos 		  if (bp->loc->cond)
    481  1.1  christos 		    mode |= TUI_BP_CONDITIONAL;
    482  1.1  christos 		  if (bp->type == bp_hardware_breakpoint)
    483  1.1  christos 		    mode |= TUI_BP_HARDWARE;
    484  1.1  christos 		}
    485  1.1  christos 	    }
    486  1.1  christos         }
    487  1.1  christos       if (line->has_break != mode)
    488  1.1  christos         {
    489  1.1  christos           line->has_break = mode;
    490  1.1  christos           need_refresh = 1;
    491  1.1  christos         }
    492  1.1  christos     }
    493  1.1  christos   return need_refresh;
    494  1.1  christos }
    495  1.1  christos 
    496  1.1  christos 
    497  1.1  christos /* Function to initialize the content of the execution info window,
    498  1.1  christos    based upon the input window which is either the source or
    499  1.1  christos    disassembly window.  */
    500  1.1  christos enum tui_status
    501  1.1  christos tui_set_exec_info_content (struct tui_win_info *win_info)
    502  1.1  christos {
    503  1.1  christos   enum tui_status ret = TUI_SUCCESS;
    504  1.1  christos 
    505  1.1  christos   if (win_info->detail.source_info.execution_info
    506  1.1  christos       != (struct tui_gen_win_info *) NULL)
    507  1.1  christos     {
    508  1.1  christos       struct tui_gen_win_info *exec_info_ptr
    509  1.1  christos 	= win_info->detail.source_info.execution_info;
    510  1.1  christos 
    511  1.1  christos       if (exec_info_ptr->content == NULL)
    512  1.1  christos 	exec_info_ptr->content =
    513  1.1  christos 	  (void **) tui_alloc_content (win_info->generic.height,
    514  1.1  christos 					 exec_info_ptr->type);
    515  1.1  christos       if (exec_info_ptr->content != NULL)
    516  1.1  christos 	{
    517  1.1  christos 	  int i;
    518  1.1  christos 
    519  1.1  christos           tui_update_breakpoint_info (win_info, 1);
    520  1.1  christos 	  for (i = 0; i < win_info->generic.content_size; i++)
    521  1.1  christos 	    {
    522  1.1  christos 	      struct tui_win_element *element;
    523  1.1  christos 	      struct tui_win_element *src_element;
    524  1.1  christos               int mode;
    525  1.1  christos 
    526  1.1  christos 	      element = (struct tui_win_element *) exec_info_ptr->content[i];
    527  1.1  christos 	      src_element = (struct tui_win_element *)
    528  1.1  christos 		win_info->generic.content[i];
    529  1.1  christos 
    530  1.1  christos               memset(element->which_element.simple_string, ' ',
    531  1.1  christos                      sizeof(element->which_element.simple_string));
    532  1.1  christos               element->which_element.simple_string[TUI_EXECINFO_SIZE - 1] = 0;
    533  1.1  christos 
    534  1.1  christos 	      /* Now update the exec info content based upon the state
    535  1.1  christos                  of each line as indicated by the source content.  */
    536  1.1  christos               mode = src_element->which_element.source.has_break;
    537  1.1  christos               if (mode & TUI_BP_HIT)
    538  1.1  christos                 element->which_element.simple_string[TUI_BP_HIT_POS] =
    539  1.1  christos                   (mode & TUI_BP_HARDWARE) ? 'H' : 'B';
    540  1.1  christos               else if (mode & (TUI_BP_ENABLED | TUI_BP_DISABLED))
    541  1.1  christos                 element->which_element.simple_string[TUI_BP_HIT_POS] =
    542  1.1  christos                   (mode & TUI_BP_HARDWARE) ? 'h' : 'b';
    543  1.1  christos 
    544  1.1  christos               if (mode & TUI_BP_ENABLED)
    545  1.1  christos                 element->which_element.simple_string[TUI_BP_BREAK_POS] = '+';
    546  1.1  christos               else if (mode & TUI_BP_DISABLED)
    547  1.1  christos                 element->which_element.simple_string[TUI_BP_BREAK_POS] = '-';
    548  1.1  christos 
    549  1.1  christos               if (src_element->which_element.source.is_exec_point)
    550  1.1  christos                 element->which_element.simple_string[TUI_EXEC_POS] = '>';
    551  1.1  christos 	    }
    552  1.1  christos 	  exec_info_ptr->content_size = win_info->generic.content_size;
    553  1.1  christos 	}
    554  1.1  christos       else
    555  1.1  christos 	ret = TUI_FAILURE;
    556  1.1  christos     }
    557  1.1  christos 
    558  1.1  christos   return ret;
    559  1.1  christos }
    560  1.1  christos 
    561  1.1  christos 
    562  1.1  christos void
    563  1.1  christos tui_show_exec_info_content (struct tui_win_info *win_info)
    564  1.1  christos {
    565  1.1  christos   struct tui_gen_win_info *exec_info
    566  1.1  christos     = win_info->detail.source_info.execution_info;
    567  1.1  christos   int cur_line;
    568  1.1  christos 
    569  1.1  christos   werase (exec_info->handle);
    570  1.1  christos   tui_refresh_win (exec_info);
    571  1.1  christos   for (cur_line = 1; (cur_line <= exec_info->content_size); cur_line++)
    572  1.1  christos     mvwaddstr (exec_info->handle,
    573  1.1  christos 	       cur_line,
    574  1.1  christos 	       0,
    575  1.1  christos 	       ((struct tui_win_element *)
    576  1.1  christos 		exec_info->content[cur_line - 1])->which_element.simple_string);
    577  1.1  christos   tui_refresh_win (exec_info);
    578  1.1  christos   exec_info->content_in_use = TRUE;
    579  1.1  christos }
    580  1.1  christos 
    581  1.1  christos 
    582  1.1  christos void
    583  1.1  christos tui_erase_exec_info_content (struct tui_win_info *win_info)
    584  1.1  christos {
    585  1.1  christos   struct tui_gen_win_info *exec_info
    586  1.1  christos     = win_info->detail.source_info.execution_info;
    587  1.1  christos 
    588  1.1  christos   werase (exec_info->handle);
    589  1.1  christos   tui_refresh_win (exec_info);
    590  1.1  christos }
    591  1.1  christos 
    592  1.1  christos void
    593  1.1  christos tui_clear_exec_info_content (struct tui_win_info *win_info)
    594  1.1  christos {
    595  1.1  christos   win_info->detail.source_info.execution_info->content_in_use = FALSE;
    596  1.1  christos   tui_erase_exec_info_content (win_info);
    597  1.1  christos 
    598  1.1  christos   return;
    599  1.1  christos }
    600  1.1  christos 
    601  1.1  christos /* Function to update the execution info window.  */
    602  1.1  christos void
    603  1.1  christos tui_update_exec_info (struct tui_win_info *win_info)
    604  1.1  christos {
    605  1.1  christos   tui_set_exec_info_content (win_info);
    606  1.1  christos   tui_show_exec_info_content (win_info);
    607  1.1  christos }
    608  1.1  christos 
    609  1.1  christos enum tui_status
    610  1.1  christos tui_alloc_source_buffer (struct tui_win_info *win_info)
    611  1.1  christos {
    612  1.1  christos   char *src_line_buf;
    613  1.1  christos   int i, line_width, max_lines;
    614  1.1  christos 
    615  1.1  christos   max_lines = win_info->generic.height;	/* Less the highlight box.  */
    616  1.1  christos   line_width = win_info->generic.width - 1;
    617  1.1  christos   /*
    618  1.1  christos    * Allocate the buffer for the source lines.  Do this only once
    619  1.1  christos    * since they will be re-used for all source displays.  The only
    620  1.1  christos    * other time this will be done is when a window's size changes.
    621  1.1  christos    */
    622  1.1  christos   if (win_info->generic.content == NULL)
    623  1.1  christos     {
    624  1.1  christos       src_line_buf = (char *)
    625  1.1  christos 	xmalloc ((max_lines * line_width) * sizeof (char));
    626  1.1  christos       if (src_line_buf == (char *) NULL)
    627  1.1  christos 	{
    628  1.1  christos 	  fputs_unfiltered ("Unable to Allocate Memory for "
    629  1.1  christos 			    "Source or Disassembly Display.\n",
    630  1.1  christos 			    gdb_stderr);
    631  1.1  christos 	  return TUI_FAILURE;
    632  1.1  christos 	}
    633  1.1  christos       /* Allocate the content list.  */
    634  1.1  christos       if ((win_info->generic.content =
    635  1.1  christos 	   (void **) tui_alloc_content (max_lines, SRC_WIN)) == NULL)
    636  1.1  christos 	{
    637  1.1  christos 	  xfree (src_line_buf);
    638  1.1  christos 	  fputs_unfiltered ("Unable to Allocate Memory for "
    639  1.1  christos 			    "Source or Disassembly Display.\n",
    640  1.1  christos 			    gdb_stderr);
    641  1.1  christos 	  return TUI_FAILURE;
    642  1.1  christos 	}
    643  1.1  christos       for (i = 0; i < max_lines; i++)
    644  1.1  christos 	((struct tui_win_element *)
    645  1.1  christos 	 win_info->generic.content[i])->which_element.source.line =
    646  1.1  christos 	  src_line_buf + (line_width * i);
    647  1.1  christos     }
    648  1.1  christos 
    649  1.1  christos   return TUI_SUCCESS;
    650  1.1  christos }
    651  1.1  christos 
    652  1.1  christos 
    653  1.1  christos /* Answer whether a particular line number or address is displayed
    654  1.1  christos    in the current source window.  */
    655  1.1  christos int
    656  1.1  christos tui_line_is_displayed (int line,
    657  1.1  christos 		       struct tui_win_info *win_info,
    658  1.1  christos 		       int check_threshold)
    659  1.1  christos {
    660  1.1  christos   int is_displayed = FALSE;
    661  1.1  christos   int i, threshold;
    662  1.1  christos 
    663  1.1  christos   if (check_threshold)
    664  1.1  christos     threshold = SCROLL_THRESHOLD;
    665  1.1  christos   else
    666  1.1  christos     threshold = 0;
    667  1.1  christos   i = 0;
    668  1.1  christos   while (i < win_info->generic.content_size - threshold
    669  1.1  christos 	 && !is_displayed)
    670  1.1  christos     {
    671  1.1  christos       is_displayed = (((struct tui_win_element *)
    672  1.1  christos 		       win_info->generic.content[i])->which_element.source.line_or_addr.loa
    673  1.1  christos 		      == LOA_LINE)
    674  1.1  christos 	&& (((struct tui_win_element *)
    675  1.1  christos 	     win_info->generic.content[i])->which_element.source.line_or_addr.u.line_no
    676  1.1  christos 	    == (int) line);
    677  1.1  christos       i++;
    678  1.1  christos     }
    679  1.1  christos 
    680  1.1  christos   return is_displayed;
    681  1.1  christos }
    682  1.1  christos 
    683  1.1  christos 
    684  1.1  christos /* Answer whether a particular line number or address is displayed
    685  1.1  christos    in the current source window.  */
    686  1.1  christos int
    687  1.1  christos tui_addr_is_displayed (CORE_ADDR addr,
    688  1.1  christos 		       struct tui_win_info *win_info,
    689  1.1  christos 		       int check_threshold)
    690  1.1  christos {
    691  1.1  christos   int is_displayed = FALSE;
    692  1.1  christos   int i, threshold;
    693  1.1  christos 
    694  1.1  christos   if (check_threshold)
    695  1.1  christos     threshold = SCROLL_THRESHOLD;
    696  1.1  christos   else
    697  1.1  christos     threshold = 0;
    698  1.1  christos   i = 0;
    699  1.1  christos   while (i < win_info->generic.content_size - threshold
    700  1.1  christos 	 && !is_displayed)
    701  1.1  christos     {
    702  1.1  christos       is_displayed = (((struct tui_win_element *)
    703  1.1  christos 		       win_info->generic.content[i])->which_element.source.line_or_addr.loa
    704  1.1  christos 		      == LOA_ADDRESS)
    705  1.1  christos 	&& (((struct tui_win_element *)
    706  1.1  christos 	     win_info->generic.content[i])->which_element.source.line_or_addr.u.addr
    707  1.1  christos 	    == addr);
    708  1.1  christos       i++;
    709  1.1  christos     }
    710  1.1  christos 
    711  1.1  christos   return is_displayed;
    712  1.1  christos }
    713  1.1  christos 
    714  1.1  christos 
    715  1.1  christos /*****************************************
    716  1.1  christos ** STATIC LOCAL FUNCTIONS               **
    717  1.1  christos ******************************************/
    718