Home | History | Annotate | Line # | Download | only in tui
tui-winsource.c revision 1.8
      1  1.1  christos /* TUI display source/assembly window.
      2  1.1  christos 
      3  1.8  christos    Copyright (C) 1998-2019 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.8  christos #include "tui/tui-io.h"
     35  1.1  christos #include "tui/tui-stack.h"
     36  1.1  christos #include "tui/tui-win.h"
     37  1.1  christos #include "tui/tui-wingeneral.h"
     38  1.1  christos #include "tui/tui-winsource.h"
     39  1.1  christos #include "tui/tui-source.h"
     40  1.1  christos #include "tui/tui-disasm.h"
     41  1.1  christos #include "gdb_curses.h"
     42  1.1  christos 
     43  1.1  christos /* Function to display the "main" routine.  */
     44  1.1  christos void
     45  1.1  christos tui_display_main (void)
     46  1.1  christos {
     47  1.1  christos   if ((tui_source_windows ())->count > 0)
     48  1.1  christos     {
     49  1.1  christos       struct gdbarch *gdbarch;
     50  1.1  christos       CORE_ADDR addr;
     51  1.1  christos 
     52  1.1  christos       tui_get_begin_asm_address (&gdbarch, &addr);
     53  1.1  christos       if (addr != (CORE_ADDR) 0)
     54  1.1  christos 	{
     55  1.3  christos 	  struct symtab *s;
     56  1.1  christos 
     57  1.1  christos 	  tui_update_source_windows_with_addr (gdbarch, addr);
     58  1.3  christos 	  s = find_pc_line_symtab (addr);
     59  1.3  christos           if (s != NULL)
     60  1.3  christos              tui_update_locator_fullname (symtab_to_fullname (s));
     61  1.1  christos           else
     62  1.1  christos              tui_update_locator_fullname ("??");
     63  1.1  christos 	}
     64  1.1  christos     }
     65  1.1  christos }
     66  1.1  christos 
     67  1.1  christos 
     68  1.1  christos 
     69  1.1  christos /* Function to display source in the source window.  This function
     70  1.1  christos    initializes the horizontal scroll to 0.  */
     71  1.1  christos void
     72  1.1  christos tui_update_source_window (struct tui_win_info *win_info,
     73  1.1  christos 			  struct gdbarch *gdbarch,
     74  1.1  christos 			  struct symtab *s,
     75  1.1  christos 			  struct tui_line_or_address line_or_addr,
     76  1.1  christos 			  int noerror)
     77  1.1  christos {
     78  1.1  christos   win_info->detail.source_info.horizontal_offset = 0;
     79  1.1  christos   tui_update_source_window_as_is (win_info, gdbarch, s, line_or_addr, noerror);
     80  1.1  christos 
     81  1.1  christos   return;
     82  1.1  christos }
     83  1.1  christos 
     84  1.1  christos 
     85  1.1  christos /* Function to display source in the source/asm window.  This function
     86  1.1  christos    shows the source as specified by the horizontal offset.  */
     87  1.1  christos void
     88  1.1  christos tui_update_source_window_as_is (struct tui_win_info *win_info,
     89  1.1  christos 				struct gdbarch *gdbarch,
     90  1.1  christos 				struct symtab *s,
     91  1.1  christos 				struct tui_line_or_address line_or_addr,
     92  1.1  christos 				int noerror)
     93  1.1  christos {
     94  1.1  christos   enum tui_status ret;
     95  1.1  christos 
     96  1.1  christos   if (win_info->generic.type == SRC_WIN)
     97  1.1  christos     ret = tui_set_source_content (s, line_or_addr.u.line_no, noerror);
     98  1.1  christos   else
     99  1.1  christos     ret = tui_set_disassem_content (gdbarch, line_or_addr.u.addr);
    100  1.1  christos 
    101  1.1  christos   if (ret == TUI_FAILURE)
    102  1.1  christos     {
    103  1.1  christos       tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT);
    104  1.1  christos       tui_clear_exec_info_content (win_info);
    105  1.1  christos     }
    106  1.1  christos   else
    107  1.1  christos     {
    108  1.1  christos       tui_update_breakpoint_info (win_info, 0);
    109  1.1  christos       tui_show_source_content (win_info);
    110  1.1  christos       tui_update_exec_info (win_info);
    111  1.1  christos       if (win_info->generic.type == SRC_WIN)
    112  1.1  christos 	{
    113  1.8  christos 	  symtab_and_line sal;
    114  1.8  christos 
    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.8  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.8  christos     tui_set_reverse_mode (win_info->generic.handle, true);
    281  1.1  christos 
    282  1.8  christos   wmove (win_info->generic.handle, lineno, 1);
    283  1.8  christos   tui_puts (line->which_element.source.line,
    284  1.8  christos 	    win_info->generic.handle);
    285  1.1  christos   if (line->which_element.source.is_exec_point)
    286  1.8  christos     tui_set_reverse_mode (win_info->generic.handle, false);
    287  1.1  christos 
    288  1.1  christos   /* Clear to end of line but stop before the border.  */
    289  1.6  christos   x = getcurx (win_info->generic.handle);
    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.6  christos       x = getcurx (win_info->generic.handle);
    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.8  christos /* Refill the source window's source cache and update it.  If WIN_INFO
    316  1.8  christos    is a disassembly window, then just update it.  */
    317  1.8  christos 
    318  1.8  christos void
    319  1.8  christos tui_refill_source_window (struct tui_win_info *win_info)
    320  1.8  christos {
    321  1.8  christos   symtab *s = nullptr;
    322  1.8  christos 
    323  1.8  christos   if (win_info->generic.type == SRC_WIN)
    324  1.8  christos     {
    325  1.8  christos       symtab_and_line cursal = get_current_source_symtab_and_line ();
    326  1.8  christos       s = (cursal.symtab == NULL
    327  1.8  christos 	   ? find_pc_line_symtab (get_frame_pc (get_selected_frame (NULL)))
    328  1.8  christos 	   : cursal.symtab);
    329  1.8  christos     }
    330  1.8  christos 
    331  1.8  christos   tui_update_source_window_as_is (win_info,
    332  1.8  christos 				  win_info->detail.source_info.gdbarch,
    333  1.8  christos 				  s,
    334  1.8  christos 				  win_info->generic.content[0]
    335  1.8  christos 				    ->which_element.source.line_or_addr,
    336  1.8  christos 				  FALSE);
    337  1.8  christos }
    338  1.1  christos 
    339  1.1  christos /* Scroll the source forward or backward horizontally.  */
    340  1.8  christos 
    341  1.1  christos void
    342  1.1  christos tui_horizontal_source_scroll (struct tui_win_info *win_info,
    343  1.1  christos 			      enum tui_scroll_direction direction,
    344  1.1  christos 			      int num_to_scroll)
    345  1.1  christos {
    346  1.1  christos   if (win_info->generic.content != NULL)
    347  1.1  christos     {
    348  1.1  christos       int offset;
    349  1.1  christos 
    350  1.1  christos       if (direction == LEFT_SCROLL)
    351  1.1  christos 	offset = win_info->detail.source_info.horizontal_offset
    352  1.1  christos 	  + num_to_scroll;
    353  1.1  christos       else
    354  1.1  christos 	{
    355  1.1  christos 	  offset = win_info->detail.source_info.horizontal_offset
    356  1.1  christos 	    - num_to_scroll;
    357  1.1  christos 	  if (offset < 0)
    358  1.1  christos 	    offset = 0;
    359  1.1  christos 	}
    360  1.1  christos       win_info->detail.source_info.horizontal_offset = offset;
    361  1.8  christos       tui_refill_source_window (win_info);
    362  1.1  christos     }
    363  1.1  christos }
    364  1.1  christos 
    365  1.1  christos 
    366  1.1  christos /* Set or clear the has_break flag in the line whose line is
    367  1.1  christos    line_no.  */
    368  1.1  christos 
    369  1.1  christos void
    370  1.1  christos tui_set_is_exec_point_at (struct tui_line_or_address l,
    371  1.1  christos 			  struct tui_win_info *win_info)
    372  1.1  christos {
    373  1.1  christos   int changed = 0;
    374  1.1  christos   int i;
    375  1.8  christos   tui_win_content content = win_info->generic.content;
    376  1.1  christos 
    377  1.1  christos   i = 0;
    378  1.1  christos   while (i < win_info->generic.content_size)
    379  1.1  christos     {
    380  1.1  christos       int new_state;
    381  1.1  christos       struct tui_line_or_address content_loa =
    382  1.1  christos 	content[i]->which_element.source.line_or_addr;
    383  1.1  christos 
    384  1.1  christos       gdb_assert (l.loa == LOA_ADDRESS || l.loa == LOA_LINE);
    385  1.1  christos       gdb_assert (content_loa.loa == LOA_LINE
    386  1.1  christos 		  || content_loa.loa == LOA_ADDRESS);
    387  1.1  christos       if (content_loa.loa == l.loa
    388  1.1  christos 	  && ((l.loa == LOA_LINE && content_loa.u.line_no == l.u.line_no)
    389  1.1  christos               || (content_loa.u.addr == l.u.addr)))
    390  1.1  christos         new_state = TRUE;
    391  1.1  christos       else
    392  1.1  christos 	new_state = FALSE;
    393  1.1  christos       if (new_state != content[i]->which_element.source.is_exec_point)
    394  1.1  christos         {
    395  1.1  christos           changed++;
    396  1.1  christos           content[i]->which_element.source.is_exec_point = new_state;
    397  1.1  christos           tui_show_source_line (win_info, i + 1);
    398  1.1  christos         }
    399  1.1  christos       i++;
    400  1.1  christos     }
    401  1.1  christos   if (changed)
    402  1.8  christos     tui_refill_source_window (win_info);
    403  1.1  christos }
    404  1.1  christos 
    405  1.1  christos /* Update the execution windows to show the active breakpoints.
    406  1.1  christos    This is called whenever a breakpoint is inserted, removed or
    407  1.1  christos    has its state changed.  */
    408  1.1  christos void
    409  1.1  christos tui_update_all_breakpoint_info (void)
    410  1.1  christos {
    411  1.1  christos   struct tui_list *list = tui_source_windows ();
    412  1.1  christos   int i;
    413  1.1  christos 
    414  1.1  christos   for (i = 0; i < list->count; i++)
    415  1.1  christos     {
    416  1.1  christos       struct tui_win_info *win = list->list[i];
    417  1.1  christos 
    418  1.1  christos       if (tui_update_breakpoint_info (win, FALSE))
    419  1.1  christos         {
    420  1.1  christos           tui_update_exec_info (win);
    421  1.1  christos         }
    422  1.1  christos     }
    423  1.1  christos }
    424  1.1  christos 
    425  1.1  christos 
    426  1.1  christos /* Scan the source window and the breakpoints to update the has_break
    427  1.1  christos    information for each line.
    428  1.1  christos 
    429  1.1  christos    Returns 1 if something changed and the execution window must be
    430  1.1  christos    refreshed.  */
    431  1.1  christos 
    432  1.1  christos int
    433  1.1  christos tui_update_breakpoint_info (struct tui_win_info *win,
    434  1.1  christos 			    int current_only)
    435  1.1  christos {
    436  1.1  christos   int i;
    437  1.1  christos   int need_refresh = 0;
    438  1.1  christos   struct tui_source_info *src = &win->detail.source_info;
    439  1.1  christos 
    440  1.1  christos   for (i = 0; i < win->generic.content_size; i++)
    441  1.1  christos     {
    442  1.1  christos       struct breakpoint *bp;
    443  1.1  christos       extern struct breakpoint *breakpoint_chain;
    444  1.1  christos       int mode;
    445  1.1  christos       struct tui_source_element *line;
    446  1.1  christos 
    447  1.5  christos       line = &win->generic.content[i]->which_element.source;
    448  1.1  christos       if (current_only && !line->is_exec_point)
    449  1.1  christos          continue;
    450  1.1  christos 
    451  1.1  christos       /* Scan each breakpoint to see if the current line has something to
    452  1.1  christos          do with it.  Identify enable/disabled breakpoints as well as
    453  1.1  christos          those that we already hit.  */
    454  1.1  christos       mode = 0;
    455  1.1  christos       for (bp = breakpoint_chain;
    456  1.1  christos            bp != (struct breakpoint *) NULL;
    457  1.1  christos            bp = bp->next)
    458  1.1  christos         {
    459  1.1  christos 	  struct bp_location *loc;
    460  1.1  christos 
    461  1.1  christos 	  gdb_assert (line->line_or_addr.loa == LOA_LINE
    462  1.1  christos 		      || line->line_or_addr.loa == LOA_ADDRESS);
    463  1.1  christos 
    464  1.1  christos 	  for (loc = bp->loc; loc != NULL; loc = loc->next)
    465  1.1  christos 	    {
    466  1.1  christos 	      if ((win == TUI_SRC_WIN
    467  1.1  christos 		   && loc->symtab != NULL
    468  1.1  christos 		   && filename_cmp (src->fullname,
    469  1.1  christos 				    symtab_to_fullname (loc->symtab)) == 0
    470  1.1  christos 		   && line->line_or_addr.loa == LOA_LINE
    471  1.1  christos 		   && loc->line_number == line->line_or_addr.u.line_no)
    472  1.1  christos 		  || (win == TUI_DISASM_WIN
    473  1.1  christos 		      && line->line_or_addr.loa == LOA_ADDRESS
    474  1.1  christos 		      && loc->address == line->line_or_addr.u.addr))
    475  1.1  christos 		{
    476  1.1  christos 		  if (bp->enable_state == bp_disabled)
    477  1.1  christos 		    mode |= TUI_BP_DISABLED;
    478  1.1  christos 		  else
    479  1.1  christos 		    mode |= TUI_BP_ENABLED;
    480  1.1  christos 		  if (bp->hit_count)
    481  1.1  christos 		    mode |= TUI_BP_HIT;
    482  1.1  christos 		  if (bp->loc->cond)
    483  1.1  christos 		    mode |= TUI_BP_CONDITIONAL;
    484  1.1  christos 		  if (bp->type == bp_hardware_breakpoint)
    485  1.1  christos 		    mode |= TUI_BP_HARDWARE;
    486  1.1  christos 		}
    487  1.1  christos 	    }
    488  1.1  christos         }
    489  1.1  christos       if (line->has_break != mode)
    490  1.1  christos         {
    491  1.1  christos           line->has_break = mode;
    492  1.1  christos           need_refresh = 1;
    493  1.1  christos         }
    494  1.1  christos     }
    495  1.1  christos   return need_refresh;
    496  1.1  christos }
    497  1.1  christos 
    498  1.1  christos 
    499  1.1  christos /* Function to initialize the content of the execution info window,
    500  1.1  christos    based upon the input window which is either the source or
    501  1.1  christos    disassembly window.  */
    502  1.1  christos enum tui_status
    503  1.1  christos tui_set_exec_info_content (struct tui_win_info *win_info)
    504  1.1  christos {
    505  1.1  christos   enum tui_status ret = TUI_SUCCESS;
    506  1.1  christos 
    507  1.1  christos   if (win_info->detail.source_info.execution_info
    508  1.1  christos       != (struct tui_gen_win_info *) NULL)
    509  1.1  christos     {
    510  1.1  christos       struct tui_gen_win_info *exec_info_ptr
    511  1.1  christos 	= win_info->detail.source_info.execution_info;
    512  1.1  christos 
    513  1.1  christos       if (exec_info_ptr->content == NULL)
    514  1.1  christos 	exec_info_ptr->content =
    515  1.5  christos 	  tui_alloc_content (win_info->generic.height, exec_info_ptr->type);
    516  1.1  christos       if (exec_info_ptr->content != NULL)
    517  1.1  christos 	{
    518  1.1  christos 	  int i;
    519  1.1  christos 
    520  1.1  christos           tui_update_breakpoint_info (win_info, 1);
    521  1.1  christos 	  for (i = 0; i < win_info->generic.content_size; i++)
    522  1.1  christos 	    {
    523  1.1  christos 	      struct tui_win_element *element;
    524  1.1  christos 	      struct tui_win_element *src_element;
    525  1.1  christos               int mode;
    526  1.1  christos 
    527  1.5  christos 	      element = exec_info_ptr->content[i];
    528  1.5  christos 	      src_element = 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.7  christos   if (exec_info->handle == NULL)
    570  1.7  christos     return;
    571  1.7  christos 
    572  1.1  christos   werase (exec_info->handle);
    573  1.1  christos   tui_refresh_win (exec_info);
    574  1.1  christos   for (cur_line = 1; (cur_line <= exec_info->content_size); cur_line++)
    575  1.1  christos     mvwaddstr (exec_info->handle,
    576  1.1  christos 	       cur_line,
    577  1.1  christos 	       0,
    578  1.7  christos 	       (char *) exec_info->content[cur_line - 1]
    579  1.7  christos 			  ->which_element.simple_string);
    580  1.1  christos   tui_refresh_win (exec_info);
    581  1.1  christos   exec_info->content_in_use = TRUE;
    582  1.1  christos }
    583  1.1  christos 
    584  1.1  christos 
    585  1.1  christos void
    586  1.1  christos tui_erase_exec_info_content (struct tui_win_info *win_info)
    587  1.1  christos {
    588  1.1  christos   struct tui_gen_win_info *exec_info
    589  1.1  christos     = win_info->detail.source_info.execution_info;
    590  1.1  christos 
    591  1.7  christos   if (exec_info->handle == NULL)
    592  1.7  christos     return;
    593  1.7  christos 
    594  1.1  christos   werase (exec_info->handle);
    595  1.1  christos   tui_refresh_win (exec_info);
    596  1.1  christos }
    597  1.1  christos 
    598  1.1  christos void
    599  1.1  christos tui_clear_exec_info_content (struct tui_win_info *win_info)
    600  1.1  christos {
    601  1.1  christos   win_info->detail.source_info.execution_info->content_in_use = FALSE;
    602  1.1  christos   tui_erase_exec_info_content (win_info);
    603  1.1  christos 
    604  1.1  christos   return;
    605  1.1  christos }
    606  1.1  christos 
    607  1.1  christos /* Function to update the execution info window.  */
    608  1.1  christos void
    609  1.1  christos tui_update_exec_info (struct tui_win_info *win_info)
    610  1.1  christos {
    611  1.1  christos   tui_set_exec_info_content (win_info);
    612  1.1  christos   tui_show_exec_info_content (win_info);
    613  1.1  christos }
    614  1.1  christos 
    615  1.1  christos enum tui_status
    616  1.1  christos tui_alloc_source_buffer (struct tui_win_info *win_info)
    617  1.1  christos {
    618  1.1  christos   int i, line_width, max_lines;
    619  1.1  christos 
    620  1.7  christos   /* The window width/height includes the highlight box.  Determine actual
    621  1.7  christos      content dimensions, including string null-terminators.  */
    622  1.7  christos   max_lines = win_info->generic.height - 2;
    623  1.7  christos   line_width = win_info->generic.width - 2 + 1;
    624  1.7  christos 
    625  1.8  christos   /* Allocate the buffer for the source lines.  */
    626  1.1  christos   if (win_info->generic.content == NULL)
    627  1.1  christos     {
    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.8  christos 	  = (char *) xmalloc (line_width);
    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.8  christos 	       ->which_element.source.line_or_addr.u.line_no == 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