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