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