Home | History | Annotate | Line # | Download | only in tui
tui-winsource.c revision 1.7
      1  1.1  christos /* TUI display source/assembly window.
      2  1.1  christos 
      3  1.7  christos    Copyright (C) 1998-2017 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.5  christos 	  struct tui_win_element *element = win_info->generic.content[i];
    223  1.1  christos 
    224  1.1  christos 	  element->which_element.source.has_break = FALSE;
    225  1.1  christos 	  element->which_element.source.is_exec_point = FALSE;
    226  1.1  christos 	}
    227  1.1  christos     }
    228  1.1  christos }
    229  1.1  christos 
    230  1.1  christos 
    231  1.1  christos void
    232  1.1  christos tui_erase_source_content (struct tui_win_info *win_info,
    233  1.1  christos 			  int display_prompt)
    234  1.1  christos {
    235  1.1  christos   int x_pos;
    236  1.1  christos   int half_width = (win_info->generic.width - 2) / 2;
    237  1.1  christos 
    238  1.1  christos   if (win_info->generic.handle != (WINDOW *) NULL)
    239  1.1  christos     {
    240  1.1  christos       werase (win_info->generic.handle);
    241  1.1  christos       tui_check_and_display_highlight_if_needed (win_info);
    242  1.1  christos       if (display_prompt == EMPTY_SOURCE_PROMPT)
    243  1.1  christos 	{
    244  1.7  christos 	  const char *no_src_str;
    245  1.1  christos 
    246  1.1  christos 	  if (win_info->generic.type == SRC_WIN)
    247  1.1  christos 	    no_src_str = NO_SRC_STRING;
    248  1.1  christos 	  else
    249  1.1  christos 	    no_src_str = NO_DISASSEM_STRING;
    250  1.1  christos 	  if (strlen (no_src_str) >= half_width)
    251  1.1  christos 	    x_pos = 1;
    252  1.1  christos 	  else
    253  1.1  christos 	    x_pos = half_width - strlen (no_src_str);
    254  1.1  christos 	  mvwaddstr (win_info->generic.handle,
    255  1.1  christos 		     (win_info->generic.height / 2),
    256  1.1  christos 		     x_pos,
    257  1.7  christos 		     (char *) no_src_str);
    258  1.1  christos 
    259  1.1  christos 	  /* elz: Added this function call to set the real contents of
    260  1.1  christos 	     the window to what is on the screen, so that later calls
    261  1.1  christos 	     to refresh, do display the correct stuff, and not the old
    262  1.1  christos 	     image.  */
    263  1.1  christos 
    264  1.1  christos 	  tui_set_source_content_nil (win_info, no_src_str);
    265  1.1  christos 	}
    266  1.1  christos       tui_refresh_win (&win_info->generic);
    267  1.1  christos     }
    268  1.1  christos }
    269  1.1  christos 
    270  1.1  christos 
    271  1.1  christos /* Redraw the complete line of a source or disassembly window.  */
    272  1.1  christos static void
    273  1.1  christos tui_show_source_line (struct tui_win_info *win_info, int lineno)
    274  1.1  christos {
    275  1.1  christos   struct tui_win_element *line;
    276  1.6  christos   int x;
    277  1.1  christos 
    278  1.5  christos   line = win_info->generic.content[lineno - 1];
    279  1.1  christos   if (line->which_element.source.is_exec_point)
    280  1.1  christos     wattron (win_info->generic.handle, A_STANDOUT);
    281  1.1  christos 
    282  1.1  christos   mvwaddstr (win_info->generic.handle, lineno, 1,
    283  1.7  christos              (char *) line->which_element.source.line);
    284  1.1  christos   if (line->which_element.source.is_exec_point)
    285  1.1  christos     wattroff (win_info->generic.handle, A_STANDOUT);
    286  1.1  christos 
    287  1.1  christos   /* Clear to end of line but stop before the border.  */
    288  1.6  christos   x = getcurx (win_info->generic.handle);
    289  1.1  christos   while (x + 1 < win_info->generic.width)
    290  1.1  christos     {
    291  1.1  christos       waddch (win_info->generic.handle, ' ');
    292  1.6  christos       x = getcurx (win_info->generic.handle);
    293  1.1  christos     }
    294  1.1  christos }
    295  1.1  christos 
    296  1.1  christos void
    297  1.1  christos tui_show_source_content (struct tui_win_info *win_info)
    298  1.1  christos {
    299  1.1  christos   if (win_info->generic.content_size > 0)
    300  1.1  christos     {
    301  1.1  christos       int lineno;
    302  1.1  christos 
    303  1.1  christos       for (lineno = 1; lineno <= win_info->generic.content_size; lineno++)
    304  1.1  christos         tui_show_source_line (win_info, lineno);
    305  1.1  christos     }
    306  1.1  christos   else
    307  1.1  christos     tui_erase_source_content (win_info, TRUE);
    308  1.1  christos 
    309  1.1  christos   tui_check_and_display_highlight_if_needed (win_info);
    310  1.1  christos   tui_refresh_win (&win_info->generic);
    311  1.1  christos   win_info->generic.content_in_use = TRUE;
    312  1.1  christos }
    313  1.1  christos 
    314  1.1  christos 
    315  1.1  christos /* Scroll the source forward or backward horizontally.  */
    316  1.1  christos void
    317  1.1  christos tui_horizontal_source_scroll (struct tui_win_info *win_info,
    318  1.1  christos 			      enum tui_scroll_direction direction,
    319  1.1  christos 			      int num_to_scroll)
    320  1.1  christos {
    321  1.1  christos   if (win_info->generic.content != NULL)
    322  1.1  christos     {
    323  1.1  christos       struct gdbarch *gdbarch = win_info->detail.source_info.gdbarch;
    324  1.1  christos       int offset;
    325  1.1  christos       struct symtab *s = NULL;
    326  1.1  christos 
    327  1.1  christos       if (win_info->generic.type == SRC_WIN)
    328  1.1  christos 	{
    329  1.1  christos 	  struct symtab_and_line cursal
    330  1.1  christos 	    = get_current_source_symtab_and_line ();
    331  1.1  christos 
    332  1.1  christos 	  if (cursal.symtab == NULL)
    333  1.3  christos 	    s = find_pc_line_symtab (get_frame_pc (get_selected_frame (NULL)));
    334  1.1  christos 	  else
    335  1.1  christos 	    s = cursal.symtab;
    336  1.1  christos 	}
    337  1.1  christos 
    338  1.1  christos       if (direction == LEFT_SCROLL)
    339  1.1  christos 	offset = win_info->detail.source_info.horizontal_offset
    340  1.1  christos 	  + num_to_scroll;
    341  1.1  christos       else
    342  1.1  christos 	{
    343  1.1  christos 	  offset = win_info->detail.source_info.horizontal_offset
    344  1.1  christos 	    - num_to_scroll;
    345  1.1  christos 	  if (offset < 0)
    346  1.1  christos 	    offset = 0;
    347  1.1  christos 	}
    348  1.1  christos       win_info->detail.source_info.horizontal_offset = offset;
    349  1.1  christos       tui_update_source_window_as_is (win_info, gdbarch, s,
    350  1.5  christos 				      win_info->generic.content[0]
    351  1.5  christos 					->which_element.source.line_or_addr,
    352  1.1  christos 				      FALSE);
    353  1.1  christos     }
    354  1.1  christos 
    355  1.1  christos   return;
    356  1.1  christos }
    357  1.1  christos 
    358  1.1  christos 
    359  1.1  christos /* Set or clear the has_break flag in the line whose line is
    360  1.1  christos    line_no.  */
    361  1.1  christos 
    362  1.1  christos void
    363  1.1  christos tui_set_is_exec_point_at (struct tui_line_or_address l,
    364  1.1  christos 			  struct tui_win_info *win_info)
    365  1.1  christos {
    366  1.1  christos   int changed = 0;
    367  1.1  christos   int i;
    368  1.1  christos   tui_win_content content = (tui_win_content) win_info->generic.content;
    369  1.1  christos 
    370  1.1  christos   i = 0;
    371  1.1  christos   while (i < win_info->generic.content_size)
    372  1.1  christos     {
    373  1.1  christos       int new_state;
    374  1.1  christos       struct tui_line_or_address content_loa =
    375  1.1  christos 	content[i]->which_element.source.line_or_addr;
    376  1.1  christos 
    377  1.1  christos       gdb_assert (l.loa == LOA_ADDRESS || l.loa == LOA_LINE);
    378  1.1  christos       gdb_assert (content_loa.loa == LOA_LINE
    379  1.1  christos 		  || content_loa.loa == LOA_ADDRESS);
    380  1.1  christos       if (content_loa.loa == l.loa
    381  1.1  christos 	  && ((l.loa == LOA_LINE && content_loa.u.line_no == l.u.line_no)
    382  1.1  christos               || (content_loa.u.addr == l.u.addr)))
    383  1.1  christos         new_state = TRUE;
    384  1.1  christos       else
    385  1.1  christos 	new_state = FALSE;
    386  1.1  christos       if (new_state != content[i]->which_element.source.is_exec_point)
    387  1.1  christos         {
    388  1.1  christos           changed++;
    389  1.1  christos           content[i]->which_element.source.is_exec_point = new_state;
    390  1.1  christos           tui_show_source_line (win_info, i + 1);
    391  1.1  christos         }
    392  1.1  christos       i++;
    393  1.1  christos     }
    394  1.1  christos   if (changed)
    395  1.1  christos     tui_refresh_win (&win_info->generic);
    396  1.1  christos }
    397  1.1  christos 
    398  1.1  christos /* Update the execution windows to show the active breakpoints.
    399  1.1  christos    This is called whenever a breakpoint is inserted, removed or
    400  1.1  christos    has its state changed.  */
    401  1.1  christos void
    402  1.1  christos tui_update_all_breakpoint_info (void)
    403  1.1  christos {
    404  1.1  christos   struct tui_list *list = tui_source_windows ();
    405  1.1  christos   int i;
    406  1.1  christos 
    407  1.1  christos   for (i = 0; i < list->count; i++)
    408  1.1  christos     {
    409  1.1  christos       struct tui_win_info *win = list->list[i];
    410  1.1  christos 
    411  1.1  christos       if (tui_update_breakpoint_info (win, FALSE))
    412  1.1  christos         {
    413  1.1  christos           tui_update_exec_info (win);
    414  1.1  christos         }
    415  1.1  christos     }
    416  1.1  christos }
    417  1.1  christos 
    418  1.1  christos 
    419  1.1  christos /* Scan the source window and the breakpoints to update the has_break
    420  1.1  christos    information for each line.
    421  1.1  christos 
    422  1.1  christos    Returns 1 if something changed and the execution window must be
    423  1.1  christos    refreshed.  */
    424  1.1  christos 
    425  1.1  christos int
    426  1.1  christos tui_update_breakpoint_info (struct tui_win_info *win,
    427  1.1  christos 			    int current_only)
    428  1.1  christos {
    429  1.1  christos   int i;
    430  1.1  christos   int need_refresh = 0;
    431  1.1  christos   struct tui_source_info *src = &win->detail.source_info;
    432  1.1  christos 
    433  1.1  christos   for (i = 0; i < win->generic.content_size; i++)
    434  1.1  christos     {
    435  1.1  christos       struct breakpoint *bp;
    436  1.1  christos       extern struct breakpoint *breakpoint_chain;
    437  1.1  christos       int mode;
    438  1.1  christos       struct tui_source_element *line;
    439  1.1  christos 
    440  1.5  christos       line = &win->generic.content[i]->which_element.source;
    441  1.1  christos       if (current_only && !line->is_exec_point)
    442  1.1  christos          continue;
    443  1.1  christos 
    444  1.1  christos       /* Scan each breakpoint to see if the current line has something to
    445  1.1  christos          do with it.  Identify enable/disabled breakpoints as well as
    446  1.1  christos          those that we already hit.  */
    447  1.1  christos       mode = 0;
    448  1.1  christos       for (bp = breakpoint_chain;
    449  1.1  christos            bp != (struct breakpoint *) NULL;
    450  1.1  christos            bp = bp->next)
    451  1.1  christos         {
    452  1.1  christos 	  struct bp_location *loc;
    453  1.1  christos 
    454  1.1  christos 	  gdb_assert (line->line_or_addr.loa == LOA_LINE
    455  1.1  christos 		      || line->line_or_addr.loa == LOA_ADDRESS);
    456  1.1  christos 
    457  1.1  christos 	  for (loc = bp->loc; loc != NULL; loc = loc->next)
    458  1.1  christos 	    {
    459  1.1  christos 	      if ((win == TUI_SRC_WIN
    460  1.1  christos 		   && loc->symtab != NULL
    461  1.1  christos 		   && filename_cmp (src->fullname,
    462  1.1  christos 				    symtab_to_fullname (loc->symtab)) == 0
    463  1.1  christos 		   && line->line_or_addr.loa == LOA_LINE
    464  1.1  christos 		   && loc->line_number == line->line_or_addr.u.line_no)
    465  1.1  christos 		  || (win == TUI_DISASM_WIN
    466  1.1  christos 		      && line->line_or_addr.loa == LOA_ADDRESS
    467  1.1  christos 		      && loc->address == line->line_or_addr.u.addr))
    468  1.1  christos 		{
    469  1.1  christos 		  if (bp->enable_state == bp_disabled)
    470  1.1  christos 		    mode |= TUI_BP_DISABLED;
    471  1.1  christos 		  else
    472  1.1  christos 		    mode |= TUI_BP_ENABLED;
    473  1.1  christos 		  if (bp->hit_count)
    474  1.1  christos 		    mode |= TUI_BP_HIT;
    475  1.1  christos 		  if (bp->loc->cond)
    476  1.1  christos 		    mode |= TUI_BP_CONDITIONAL;
    477  1.1  christos 		  if (bp->type == bp_hardware_breakpoint)
    478  1.1  christos 		    mode |= TUI_BP_HARDWARE;
    479  1.1  christos 		}
    480  1.1  christos 	    }
    481  1.1  christos         }
    482  1.1  christos       if (line->has_break != mode)
    483  1.1  christos         {
    484  1.1  christos           line->has_break = mode;
    485  1.1  christos           need_refresh = 1;
    486  1.1  christos         }
    487  1.1  christos     }
    488  1.1  christos   return need_refresh;
    489  1.1  christos }
    490  1.1  christos 
    491  1.1  christos 
    492  1.1  christos /* Function to initialize the content of the execution info window,
    493  1.1  christos    based upon the input window which is either the source or
    494  1.1  christos    disassembly window.  */
    495  1.1  christos enum tui_status
    496  1.1  christos tui_set_exec_info_content (struct tui_win_info *win_info)
    497  1.1  christos {
    498  1.1  christos   enum tui_status ret = TUI_SUCCESS;
    499  1.1  christos 
    500  1.1  christos   if (win_info->detail.source_info.execution_info
    501  1.1  christos       != (struct tui_gen_win_info *) NULL)
    502  1.1  christos     {
    503  1.1  christos       struct tui_gen_win_info *exec_info_ptr
    504  1.1  christos 	= win_info->detail.source_info.execution_info;
    505  1.1  christos 
    506  1.1  christos       if (exec_info_ptr->content == NULL)
    507  1.1  christos 	exec_info_ptr->content =
    508  1.5  christos 	  tui_alloc_content (win_info->generic.height, exec_info_ptr->type);
    509  1.1  christos       if (exec_info_ptr->content != NULL)
    510  1.1  christos 	{
    511  1.1  christos 	  int i;
    512  1.1  christos 
    513  1.1  christos           tui_update_breakpoint_info (win_info, 1);
    514  1.1  christos 	  for (i = 0; i < win_info->generic.content_size; i++)
    515  1.1  christos 	    {
    516  1.1  christos 	      struct tui_win_element *element;
    517  1.1  christos 	      struct tui_win_element *src_element;
    518  1.1  christos               int mode;
    519  1.1  christos 
    520  1.5  christos 	      element = exec_info_ptr->content[i];
    521  1.5  christos 	      src_element = win_info->generic.content[i];
    522  1.1  christos 
    523  1.1  christos               memset(element->which_element.simple_string, ' ',
    524  1.1  christos                      sizeof(element->which_element.simple_string));
    525  1.1  christos               element->which_element.simple_string[TUI_EXECINFO_SIZE - 1] = 0;
    526  1.1  christos 
    527  1.1  christos 	      /* Now update the exec info content based upon the state
    528  1.1  christos                  of each line as indicated by the source content.  */
    529  1.1  christos               mode = src_element->which_element.source.has_break;
    530  1.1  christos               if (mode & TUI_BP_HIT)
    531  1.1  christos                 element->which_element.simple_string[TUI_BP_HIT_POS] =
    532  1.1  christos                   (mode & TUI_BP_HARDWARE) ? 'H' : 'B';
    533  1.1  christos               else if (mode & (TUI_BP_ENABLED | TUI_BP_DISABLED))
    534  1.1  christos                 element->which_element.simple_string[TUI_BP_HIT_POS] =
    535  1.1  christos                   (mode & TUI_BP_HARDWARE) ? 'h' : 'b';
    536  1.1  christos 
    537  1.1  christos               if (mode & TUI_BP_ENABLED)
    538  1.1  christos                 element->which_element.simple_string[TUI_BP_BREAK_POS] = '+';
    539  1.1  christos               else if (mode & TUI_BP_DISABLED)
    540  1.1  christos                 element->which_element.simple_string[TUI_BP_BREAK_POS] = '-';
    541  1.1  christos 
    542  1.1  christos               if (src_element->which_element.source.is_exec_point)
    543  1.1  christos                 element->which_element.simple_string[TUI_EXEC_POS] = '>';
    544  1.1  christos 	    }
    545  1.1  christos 	  exec_info_ptr->content_size = win_info->generic.content_size;
    546  1.1  christos 	}
    547  1.1  christos       else
    548  1.1  christos 	ret = TUI_FAILURE;
    549  1.1  christos     }
    550  1.1  christos 
    551  1.1  christos   return ret;
    552  1.1  christos }
    553  1.1  christos 
    554  1.1  christos 
    555  1.1  christos void
    556  1.1  christos tui_show_exec_info_content (struct tui_win_info *win_info)
    557  1.1  christos {
    558  1.1  christos   struct tui_gen_win_info *exec_info
    559  1.1  christos     = win_info->detail.source_info.execution_info;
    560  1.1  christos   int cur_line;
    561  1.1  christos 
    562  1.7  christos   if (exec_info->handle == NULL)
    563  1.7  christos     return;
    564  1.7  christos 
    565  1.1  christos   werase (exec_info->handle);
    566  1.1  christos   tui_refresh_win (exec_info);
    567  1.1  christos   for (cur_line = 1; (cur_line <= exec_info->content_size); cur_line++)
    568  1.1  christos     mvwaddstr (exec_info->handle,
    569  1.1  christos 	       cur_line,
    570  1.1  christos 	       0,
    571  1.7  christos 	       (char *) exec_info->content[cur_line - 1]
    572  1.7  christos 			  ->which_element.simple_string);
    573  1.1  christos   tui_refresh_win (exec_info);
    574  1.1  christos   exec_info->content_in_use = TRUE;
    575  1.1  christos }
    576  1.1  christos 
    577  1.1  christos 
    578  1.1  christos void
    579  1.1  christos tui_erase_exec_info_content (struct tui_win_info *win_info)
    580  1.1  christos {
    581  1.1  christos   struct tui_gen_win_info *exec_info
    582  1.1  christos     = win_info->detail.source_info.execution_info;
    583  1.1  christos 
    584  1.7  christos   if (exec_info->handle == NULL)
    585  1.7  christos     return;
    586  1.7  christos 
    587  1.1  christos   werase (exec_info->handle);
    588  1.1  christos   tui_refresh_win (exec_info);
    589  1.1  christos }
    590  1.1  christos 
    591  1.1  christos void
    592  1.1  christos tui_clear_exec_info_content (struct tui_win_info *win_info)
    593  1.1  christos {
    594  1.1  christos   win_info->detail.source_info.execution_info->content_in_use = FALSE;
    595  1.1  christos   tui_erase_exec_info_content (win_info);
    596  1.1  christos 
    597  1.1  christos   return;
    598  1.1  christos }
    599  1.1  christos 
    600  1.1  christos /* Function to update the execution info window.  */
    601  1.1  christos void
    602  1.1  christos tui_update_exec_info (struct tui_win_info *win_info)
    603  1.1  christos {
    604  1.1  christos   tui_set_exec_info_content (win_info);
    605  1.1  christos   tui_show_exec_info_content (win_info);
    606  1.1  christos }
    607  1.1  christos 
    608  1.1  christos enum tui_status
    609  1.1  christos tui_alloc_source_buffer (struct tui_win_info *win_info)
    610  1.1  christos {
    611  1.1  christos   char *src_line_buf;
    612  1.1  christos   int i, line_width, max_lines;
    613  1.1  christos 
    614  1.7  christos   /* The window width/height includes the highlight box.  Determine actual
    615  1.7  christos      content dimensions, including string null-terminators.  */
    616  1.7  christos   max_lines = win_info->generic.height - 2;
    617  1.7  christos   line_width = win_info->generic.width - 2 + 1;
    618  1.7  christos 
    619  1.1  christos   /*
    620  1.1  christos    * Allocate the buffer for the source lines.  Do this only once
    621  1.1  christos    * since they will be re-used for all source displays.  The only
    622  1.1  christos    * other time this will be done is when a window's size changes.
    623  1.1  christos    */
    624  1.1  christos   if (win_info->generic.content == NULL)
    625  1.1  christos     {
    626  1.1  christos       src_line_buf = (char *)
    627  1.1  christos 	xmalloc ((max_lines * line_width) * sizeof (char));
    628  1.1  christos       /* Allocate the content list.  */
    629  1.5  christos       win_info->generic.content = tui_alloc_content (max_lines, SRC_WIN);
    630  1.1  christos       for (i = 0; i < max_lines; i++)
    631  1.5  christos 	win_info->generic.content[i]->which_element.source.line
    632  1.5  christos 	  = src_line_buf + (line_width * i);
    633  1.1  christos     }
    634  1.1  christos 
    635  1.1  christos   return TUI_SUCCESS;
    636  1.1  christos }
    637  1.1  christos 
    638  1.1  christos 
    639  1.1  christos /* Answer whether a particular line number or address is displayed
    640  1.1  christos    in the current source window.  */
    641  1.1  christos int
    642  1.1  christos tui_line_is_displayed (int line,
    643  1.1  christos 		       struct tui_win_info *win_info,
    644  1.1  christos 		       int check_threshold)
    645  1.1  christos {
    646  1.1  christos   int is_displayed = FALSE;
    647  1.1  christos   int i, threshold;
    648  1.1  christos 
    649  1.1  christos   if (check_threshold)
    650  1.1  christos     threshold = SCROLL_THRESHOLD;
    651  1.1  christos   else
    652  1.1  christos     threshold = 0;
    653  1.1  christos   i = 0;
    654  1.1  christos   while (i < win_info->generic.content_size - threshold
    655  1.1  christos 	 && !is_displayed)
    656  1.1  christos     {
    657  1.5  christos       is_displayed
    658  1.5  christos 	= win_info->generic.content[i]
    659  1.5  christos 	    ->which_element.source.line_or_addr.loa == LOA_LINE
    660  1.5  christos 	  && win_info->generic.content[i]
    661  1.5  christos 	       ->which_element.source.line_or_addr.u.line_no == (int) line;
    662  1.1  christos       i++;
    663  1.1  christos     }
    664  1.1  christos 
    665  1.1  christos   return is_displayed;
    666  1.1  christos }
    667  1.1  christos 
    668  1.1  christos 
    669  1.1  christos /* Answer whether a particular line number or address is displayed
    670  1.1  christos    in the current source window.  */
    671  1.1  christos int
    672  1.1  christos tui_addr_is_displayed (CORE_ADDR addr,
    673  1.1  christos 		       struct tui_win_info *win_info,
    674  1.1  christos 		       int check_threshold)
    675  1.1  christos {
    676  1.1  christos   int is_displayed = FALSE;
    677  1.1  christos   int i, threshold;
    678  1.1  christos 
    679  1.1  christos   if (check_threshold)
    680  1.1  christos     threshold = SCROLL_THRESHOLD;
    681  1.1  christos   else
    682  1.1  christos     threshold = 0;
    683  1.1  christos   i = 0;
    684  1.1  christos   while (i < win_info->generic.content_size - threshold
    685  1.1  christos 	 && !is_displayed)
    686  1.1  christos     {
    687  1.5  christos       is_displayed
    688  1.5  christos 	= win_info->generic.content[i]
    689  1.5  christos 	    ->which_element.source.line_or_addr.loa == LOA_ADDRESS
    690  1.5  christos 	  && win_info->generic.content[i]
    691  1.5  christos 	       ->which_element.source.line_or_addr.u.addr == addr;
    692  1.1  christos       i++;
    693  1.1  christos     }
    694  1.1  christos 
    695  1.1  christos   return is_displayed;
    696  1.1  christos }
    697  1.1  christos 
    698  1.1  christos 
    699  1.1  christos /*****************************************
    700  1.1  christos ** STATIC LOCAL FUNCTIONS               **
    701  1.1  christos ******************************************/
    702