Home | History | Annotate | Line # | Download | only in tui
tui-regs.c revision 1.1
      1  1.1  christos /* TUI display registers in window.
      2  1.1  christos 
      3  1.1  christos    Copyright (C) 1998-2014 Free Software Foundation, Inc.
      4  1.1  christos 
      5  1.1  christos    Contributed by Hewlett-Packard Company.
      6  1.1  christos 
      7  1.1  christos    This file is part of GDB.
      8  1.1  christos 
      9  1.1  christos    This program is free software; you can redistribute it and/or modify
     10  1.1  christos    it under the terms of the GNU General Public License as published by
     11  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     12  1.1  christos    (at your option) any later version.
     13  1.1  christos 
     14  1.1  christos    This program is distributed in the hope that it will be useful,
     15  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     16  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17  1.1  christos    GNU General Public License for more details.
     18  1.1  christos 
     19  1.1  christos    You should have received a copy of the GNU General Public License
     20  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     21  1.1  christos 
     22  1.1  christos #include "defs.h"
     23  1.1  christos #include "arch-utils.h"
     24  1.1  christos #include "tui/tui.h"
     25  1.1  christos #include "tui/tui-data.h"
     26  1.1  christos #include "symtab.h"
     27  1.1  christos #include "gdbtypes.h"
     28  1.1  christos #include "gdbcmd.h"
     29  1.1  christos #include "frame.h"
     30  1.1  christos #include "regcache.h"
     31  1.1  christos #include "inferior.h"
     32  1.1  christos #include "target.h"
     33  1.1  christos #include <string.h>
     34  1.1  christos #include "tui/tui-layout.h"
     35  1.1  christos #include "tui/tui-win.h"
     36  1.1  christos #include "tui/tui-windata.h"
     37  1.1  christos #include "tui/tui-wingeneral.h"
     38  1.1  christos #include "tui/tui-file.h"
     39  1.1  christos #include "tui/tui-regs.h"
     40  1.1  christos #include "reggroups.h"
     41  1.1  christos #include "valprint.h"
     42  1.1  christos 
     43  1.1  christos #include "gdb_curses.h"
     44  1.1  christos 
     45  1.1  christos 
     46  1.1  christos /*****************************************
     47  1.1  christos ** STATIC LOCAL FUNCTIONS FORWARD DECLS    **
     48  1.1  christos ******************************************/
     49  1.1  christos static void
     50  1.1  christos tui_display_register (struct tui_data_element *data,
     51  1.1  christos                       struct tui_gen_win_info *win_info);
     52  1.1  christos 
     53  1.1  christos static enum tui_status tui_show_register_group (struct reggroup *group,
     54  1.1  christos 						struct frame_info *frame,
     55  1.1  christos 						int refresh_values_only);
     56  1.1  christos 
     57  1.1  christos static enum tui_status tui_get_register (struct frame_info *frame,
     58  1.1  christos 					 struct tui_data_element *data,
     59  1.1  christos 					 int regnum, int *changedp);
     60  1.1  christos 
     61  1.1  christos static void tui_scroll_regs_forward_command (char *, int);
     62  1.1  christos static void tui_scroll_regs_backward_command (char *, int);
     63  1.1  christos 
     64  1.1  christos 
     65  1.1  christos 
     66  1.1  christos /*****************************************
     67  1.1  christos ** PUBLIC FUNCTIONS                     **
     68  1.1  christos ******************************************/
     69  1.1  christos 
     70  1.1  christos /* Answer the number of the last line in the regs display.  If there
     71  1.1  christos    are no registers (-1) is returned.  */
     72  1.1  christos int
     73  1.1  christos tui_last_regs_line_no (void)
     74  1.1  christos {
     75  1.1  christos   int num_lines = (-1);
     76  1.1  christos 
     77  1.1  christos   if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
     78  1.1  christos     {
     79  1.1  christos       num_lines = (TUI_DATA_WIN->detail.data_display_info.regs_content_count /
     80  1.1  christos 		  TUI_DATA_WIN->detail.data_display_info.regs_column_count);
     81  1.1  christos       if (TUI_DATA_WIN->detail.data_display_info.regs_content_count %
     82  1.1  christos 	  TUI_DATA_WIN->detail.data_display_info.regs_column_count)
     83  1.1  christos 	num_lines++;
     84  1.1  christos     }
     85  1.1  christos   return num_lines;
     86  1.1  christos }
     87  1.1  christos 
     88  1.1  christos 
     89  1.1  christos /* Answer the line number that the register element at element_no is
     90  1.1  christos    on.  If element_no is greater than the number of register elements
     91  1.1  christos    there are, -1 is returned.  */
     92  1.1  christos int
     93  1.1  christos tui_line_from_reg_element_no (int element_no)
     94  1.1  christos {
     95  1.1  christos   if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count)
     96  1.1  christos     {
     97  1.1  christos       int i, line = (-1);
     98  1.1  christos 
     99  1.1  christos       i = 1;
    100  1.1  christos       while (line == (-1))
    101  1.1  christos 	{
    102  1.1  christos 	  if (element_no <
    103  1.1  christos 	      (TUI_DATA_WIN->detail.data_display_info.regs_column_count * i))
    104  1.1  christos 	    line = i - 1;
    105  1.1  christos 	  else
    106  1.1  christos 	    i++;
    107  1.1  christos 	}
    108  1.1  christos 
    109  1.1  christos       return line;
    110  1.1  christos     }
    111  1.1  christos   else
    112  1.1  christos     return (-1);
    113  1.1  christos }
    114  1.1  christos 
    115  1.1  christos 
    116  1.1  christos /* Answer the index of the first element in line_no.  If line_no is
    117  1.1  christos    past the register area (-1) is returned.  */
    118  1.1  christos int
    119  1.1  christos tui_first_reg_element_no_inline (int line_no)
    120  1.1  christos {
    121  1.1  christos   if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count)
    122  1.1  christos       <= TUI_DATA_WIN->detail.data_display_info.regs_content_count)
    123  1.1  christos     return ((line_no + 1) *
    124  1.1  christos 	    TUI_DATA_WIN->detail.data_display_info.regs_column_count) -
    125  1.1  christos       TUI_DATA_WIN->detail.data_display_info.regs_column_count;
    126  1.1  christos   else
    127  1.1  christos     return (-1);
    128  1.1  christos }
    129  1.1  christos 
    130  1.1  christos 
    131  1.1  christos /* Show the registers of the given group in the data window
    132  1.1  christos    and refresh the window.  */
    133  1.1  christos void
    134  1.1  christos tui_show_registers (struct reggroup *group)
    135  1.1  christos {
    136  1.1  christos   enum tui_status ret = TUI_FAILURE;
    137  1.1  christos   struct tui_data_info *display_info;
    138  1.1  christos 
    139  1.1  christos   /* Make sure the curses mode is enabled.  */
    140  1.1  christos   tui_enable ();
    141  1.1  christos 
    142  1.1  christos   /* Make sure the register window is visible.  If not, select an
    143  1.1  christos      appropriate layout.  */
    144  1.1  christos   if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->generic.is_visible)
    145  1.1  christos     tui_set_layout_for_display_command (DATA_NAME);
    146  1.1  christos 
    147  1.1  christos   display_info = &TUI_DATA_WIN->detail.data_display_info;
    148  1.1  christos   if (group == 0)
    149  1.1  christos     group = general_reggroup;
    150  1.1  christos 
    151  1.1  christos   /* Say that registers should be displayed, even if there is a
    152  1.1  christos      problem.  */
    153  1.1  christos   display_info->display_regs = TRUE;
    154  1.1  christos 
    155  1.1  christos   if (target_has_registers && target_has_stack && target_has_memory)
    156  1.1  christos     {
    157  1.1  christos       ret = tui_show_register_group (group, get_selected_frame (NULL),
    158  1.1  christos                                      group == display_info->current_group);
    159  1.1  christos     }
    160  1.1  christos   if (ret == TUI_FAILURE)
    161  1.1  christos     {
    162  1.1  christos       display_info->current_group = 0;
    163  1.1  christos       tui_erase_data_content (NO_REGS_STRING);
    164  1.1  christos     }
    165  1.1  christos   else
    166  1.1  christos     {
    167  1.1  christos       int i;
    168  1.1  christos 
    169  1.1  christos       /* Clear all notation of changed values.  */
    170  1.1  christos       for (i = 0; i < display_info->regs_content_count; i++)
    171  1.1  christos 	{
    172  1.1  christos 	  struct tui_gen_win_info *data_item_win;
    173  1.1  christos           struct tui_win_element *win;
    174  1.1  christos 
    175  1.1  christos 	  data_item_win = &display_info->regs_content[i]
    176  1.1  christos             ->which_element.data_window;
    177  1.1  christos           win = (struct tui_win_element *) data_item_win->content[0];
    178  1.1  christos           win->which_element.data.highlight = FALSE;
    179  1.1  christos 	}
    180  1.1  christos       display_info->current_group = group;
    181  1.1  christos       tui_display_all_data ();
    182  1.1  christos     }
    183  1.1  christos }
    184  1.1  christos 
    185  1.1  christos 
    186  1.1  christos /* Set the data window to display the registers of the register group
    187  1.1  christos    using the given frame.  Values are refreshed only when
    188  1.1  christos    refresh_values_only is TRUE.  */
    189  1.1  christos 
    190  1.1  christos static enum tui_status
    191  1.1  christos tui_show_register_group (struct reggroup *group,
    192  1.1  christos                          struct frame_info *frame,
    193  1.1  christos 			 int refresh_values_only)
    194  1.1  christos {
    195  1.1  christos   struct gdbarch *gdbarch = get_frame_arch (frame);
    196  1.1  christos   enum tui_status ret = TUI_FAILURE;
    197  1.1  christos   int nr_regs;
    198  1.1  christos   int allocated_here = FALSE;
    199  1.1  christos   int regnum, pos;
    200  1.1  christos   char title[80];
    201  1.1  christos   struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info;
    202  1.1  christos 
    203  1.1  christos   /* Make a new title showing which group we display.  */
    204  1.1  christos   snprintf (title, sizeof (title) - 1, "Register group: %s",
    205  1.1  christos             reggroup_name (group));
    206  1.1  christos   xfree (TUI_DATA_WIN->generic.title);
    207  1.1  christos   TUI_DATA_WIN->generic.title = xstrdup (title);
    208  1.1  christos 
    209  1.1  christos   /* See how many registers must be displayed.  */
    210  1.1  christos   nr_regs = 0;
    211  1.1  christos   for (regnum = 0;
    212  1.1  christos        regnum < gdbarch_num_regs (gdbarch)
    213  1.1  christos 		+ gdbarch_num_pseudo_regs (gdbarch);
    214  1.1  christos        regnum++)
    215  1.1  christos     {
    216  1.1  christos       const char *name;
    217  1.1  christos 
    218  1.1  christos       /* Must be in the group.  */
    219  1.1  christos       if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
    220  1.1  christos 	continue;
    221  1.1  christos 
    222  1.1  christos       /* If the register name is empty, it is undefined for this
    223  1.1  christos 	 processor, so don't display anything.  */
    224  1.1  christos       name = gdbarch_register_name (gdbarch, regnum);
    225  1.1  christos       if (name == 0 || *name == '\0')
    226  1.1  christos 	continue;
    227  1.1  christos 
    228  1.1  christos       nr_regs++;
    229  1.1  christos     }
    230  1.1  christos 
    231  1.1  christos   if (display_info->regs_content_count > 0 && !refresh_values_only)
    232  1.1  christos     {
    233  1.1  christos       tui_free_data_content (display_info->regs_content,
    234  1.1  christos                              display_info->regs_content_count);
    235  1.1  christos       display_info->regs_content_count = 0;
    236  1.1  christos     }
    237  1.1  christos 
    238  1.1  christos   if (display_info->regs_content_count <= 0)
    239  1.1  christos     {
    240  1.1  christos       display_info->regs_content = tui_alloc_content (nr_regs, DATA_WIN);
    241  1.1  christos       allocated_here = TRUE;
    242  1.1  christos       refresh_values_only = FALSE;
    243  1.1  christos     }
    244  1.1  christos 
    245  1.1  christos   if (display_info->regs_content != (tui_win_content) NULL)
    246  1.1  christos     {
    247  1.1  christos       if (!refresh_values_only || allocated_here)
    248  1.1  christos 	{
    249  1.1  christos 	  TUI_DATA_WIN->generic.content = (void*) NULL;
    250  1.1  christos 	  TUI_DATA_WIN->generic.content_size = 0;
    251  1.1  christos 	  tui_add_content_elements (&TUI_DATA_WIN->generic, nr_regs);
    252  1.1  christos 	  display_info->regs_content
    253  1.1  christos             = (tui_win_content) TUI_DATA_WIN->generic.content;
    254  1.1  christos 	  display_info->regs_content_count = nr_regs;
    255  1.1  christos 	}
    256  1.1  christos 
    257  1.1  christos       /* Now set the register names and values.  */
    258  1.1  christos       pos = 0;
    259  1.1  christos       for (regnum = 0;
    260  1.1  christos 	   regnum < gdbarch_num_regs (gdbarch)
    261  1.1  christos 		    + gdbarch_num_pseudo_regs (gdbarch);
    262  1.1  christos 	   regnum++)
    263  1.1  christos         {
    264  1.1  christos 	  struct tui_gen_win_info *data_item_win;
    265  1.1  christos           struct tui_data_element *data;
    266  1.1  christos           const char *name;
    267  1.1  christos 
    268  1.1  christos           /* Must be in the group.  */
    269  1.1  christos           if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
    270  1.1  christos             continue;
    271  1.1  christos 
    272  1.1  christos 	  /* If the register name is empty, it is undefined for this
    273  1.1  christos 	     processor, so don't display anything.  */
    274  1.1  christos 	  name = gdbarch_register_name (gdbarch, regnum);
    275  1.1  christos 	  if (name == 0 || *name == '\0')
    276  1.1  christos 	    continue;
    277  1.1  christos 
    278  1.1  christos 	  data_item_win =
    279  1.1  christos             &display_info->regs_content[pos]->which_element.data_window;
    280  1.1  christos           data = &((struct tui_win_element *)
    281  1.1  christos 		   data_item_win->content[0])->which_element.data;
    282  1.1  christos           if (data)
    283  1.1  christos             {
    284  1.1  christos               if (!refresh_values_only)
    285  1.1  christos                 {
    286  1.1  christos                   data->item_no = regnum;
    287  1.1  christos                   data->name = name;
    288  1.1  christos                   data->highlight = FALSE;
    289  1.1  christos                 }
    290  1.1  christos               tui_get_register (frame, data, regnum, 0);
    291  1.1  christos             }
    292  1.1  christos           pos++;
    293  1.1  christos 	}
    294  1.1  christos 
    295  1.1  christos       TUI_DATA_WIN->generic.content_size =
    296  1.1  christos 	display_info->regs_content_count + display_info->data_content_count;
    297  1.1  christos       ret = TUI_SUCCESS;
    298  1.1  christos     }
    299  1.1  christos 
    300  1.1  christos   return ret;
    301  1.1  christos }
    302  1.1  christos 
    303  1.1  christos /* Function to display the registers in the content from
    304  1.1  christos    'start_element_no' until the end of the register content or the end
    305  1.1  christos    of the display height.  No checking for displaying past the end of
    306  1.1  christos    the registers is done here.  */
    307  1.1  christos void
    308  1.1  christos tui_display_registers_from (int start_element_no)
    309  1.1  christos {
    310  1.1  christos   struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info;
    311  1.1  christos 
    312  1.1  christos   if (display_info->regs_content != (tui_win_content) NULL
    313  1.1  christos       && display_info->regs_content_count > 0)
    314  1.1  christos     {
    315  1.1  christos       int i = start_element_no;
    316  1.1  christos       int j, item_win_width, cur_y;
    317  1.1  christos 
    318  1.1  christos       int max_len = 0;
    319  1.1  christos       for (i = 0; i < display_info->regs_content_count; i++)
    320  1.1  christos         {
    321  1.1  christos           struct tui_data_element *data;
    322  1.1  christos           struct tui_gen_win_info *data_item_win;
    323  1.1  christos           char *p;
    324  1.1  christos           int len;
    325  1.1  christos 
    326  1.1  christos           data_item_win
    327  1.1  christos 	    = &display_info->regs_content[i]->which_element.data_window;
    328  1.1  christos           data = &((struct tui_win_element *)
    329  1.1  christos                    data_item_win->content[0])->which_element.data;
    330  1.1  christos           len = 0;
    331  1.1  christos           p = data->content;
    332  1.1  christos           if (p != 0)
    333  1.1  christos             while (*p)
    334  1.1  christos               {
    335  1.1  christos                 if (*p++ == '\t')
    336  1.1  christos                   len = 8 * ((len / 8) + 1);
    337  1.1  christos                 else
    338  1.1  christos                   len++;
    339  1.1  christos               }
    340  1.1  christos 
    341  1.1  christos           if (len > max_len)
    342  1.1  christos             max_len = len;
    343  1.1  christos         }
    344  1.1  christos       item_win_width = max_len + 1;
    345  1.1  christos       i = start_element_no;
    346  1.1  christos 
    347  1.1  christos       display_info->regs_column_count =
    348  1.1  christos         (TUI_DATA_WIN->generic.width - 2) / item_win_width;
    349  1.1  christos       if (display_info->regs_column_count == 0)
    350  1.1  christos         display_info->regs_column_count = 1;
    351  1.1  christos       item_win_width =
    352  1.1  christos         (TUI_DATA_WIN->generic.width - 2) / display_info->regs_column_count;
    353  1.1  christos 
    354  1.1  christos       /* Now create each data "sub" window, and write the display into
    355  1.1  christos 	 it.  */
    356  1.1  christos       cur_y = 1;
    357  1.1  christos       while (i < display_info->regs_content_count
    358  1.1  christos 	     && cur_y <= TUI_DATA_WIN->generic.viewport_height)
    359  1.1  christos 	{
    360  1.1  christos 	  for (j = 0;
    361  1.1  christos 	       j < display_info->regs_column_count
    362  1.1  christos 		 && i < display_info->regs_content_count;
    363  1.1  christos 	       j++)
    364  1.1  christos 	    {
    365  1.1  christos 	      struct tui_gen_win_info *data_item_win;
    366  1.1  christos 	      struct tui_data_element *data_element_ptr;
    367  1.1  christos 
    368  1.1  christos 	      /* Create the window if necessary.  */
    369  1.1  christos 	      data_item_win = &display_info->regs_content[i]
    370  1.1  christos                 ->which_element.data_window;
    371  1.1  christos 	      data_element_ptr = &((struct tui_win_element *)
    372  1.1  christos 				   data_item_win->content[0])->which_element.data;
    373  1.1  christos               if (data_item_win->handle != (WINDOW*) NULL
    374  1.1  christos                   && (data_item_win->height != 1
    375  1.1  christos                       || data_item_win->width != item_win_width
    376  1.1  christos                       || data_item_win->origin.x != (item_win_width * j) + 1
    377  1.1  christos                       || data_item_win->origin.y != cur_y))
    378  1.1  christos                 {
    379  1.1  christos                   tui_delete_win (data_item_win->handle);
    380  1.1  christos                   data_item_win->handle = 0;
    381  1.1  christos                 }
    382  1.1  christos 
    383  1.1  christos 	      if (data_item_win->handle == (WINDOW *) NULL)
    384  1.1  christos 		{
    385  1.1  christos 		  data_item_win->height = 1;
    386  1.1  christos 		  data_item_win->width = item_win_width;
    387  1.1  christos 		  data_item_win->origin.x = (item_win_width * j) + 1;
    388  1.1  christos 		  data_item_win->origin.y = cur_y;
    389  1.1  christos 		  tui_make_window (data_item_win, DONT_BOX_WINDOW);
    390  1.1  christos                   scrollok (data_item_win->handle, FALSE);
    391  1.1  christos 		}
    392  1.1  christos               touchwin (data_item_win->handle);
    393  1.1  christos 
    394  1.1  christos 	      /* Get the printable representation of the register
    395  1.1  christos                  and display it.  */
    396  1.1  christos               tui_display_register (data_element_ptr, data_item_win);
    397  1.1  christos 	      i++;		/* Next register.  */
    398  1.1  christos 	    }
    399  1.1  christos 	  cur_y++;		/* Next row.  */
    400  1.1  christos 	}
    401  1.1  christos     }
    402  1.1  christos }
    403  1.1  christos 
    404  1.1  christos 
    405  1.1  christos /* Function to display the registers in the content from
    406  1.1  christos    'start_element_no' on 'start_line_no' until the end of the register
    407  1.1  christos    content or the end of the display height.  This function checks
    408  1.1  christos    that we won't display off the end of the register display.  */
    409  1.1  christos static void
    410  1.1  christos tui_display_reg_element_at_line (int start_element_no,
    411  1.1  christos 				 int start_line_no)
    412  1.1  christos {
    413  1.1  christos   if (TUI_DATA_WIN->detail.data_display_info.regs_content
    414  1.1  christos       != (tui_win_content) NULL
    415  1.1  christos       && TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
    416  1.1  christos     {
    417  1.1  christos       int element_no = start_element_no;
    418  1.1  christos 
    419  1.1  christos       if (start_element_no != 0 && start_line_no != 0)
    420  1.1  christos 	{
    421  1.1  christos 	  int last_line_no, first_line_on_last_page;
    422  1.1  christos 
    423  1.1  christos 	  last_line_no = tui_last_regs_line_no ();
    424  1.1  christos 	  first_line_on_last_page
    425  1.1  christos 	    = last_line_no - (TUI_DATA_WIN->generic.height - 2);
    426  1.1  christos 	  if (first_line_on_last_page < 0)
    427  1.1  christos 	    first_line_on_last_page = 0;
    428  1.1  christos 
    429  1.1  christos 	  /* If there is no other data displayed except registers, and
    430  1.1  christos 	     the element_no causes us to scroll past the end of the
    431  1.1  christos 	     registers, adjust what element to really start the
    432  1.1  christos 	     display at.  */
    433  1.1  christos 	  if (TUI_DATA_WIN->detail.data_display_info.data_content_count <= 0
    434  1.1  christos 	      && start_line_no > first_line_on_last_page)
    435  1.1  christos 	    element_no
    436  1.1  christos 	      = tui_first_reg_element_no_inline (first_line_on_last_page);
    437  1.1  christos 	}
    438  1.1  christos       tui_display_registers_from (element_no);
    439  1.1  christos     }
    440  1.1  christos }
    441  1.1  christos 
    442  1.1  christos 
    443  1.1  christos 
    444  1.1  christos /* Function to display the registers starting at line line_no in the
    445  1.1  christos    data window.  Answers the line number that the display actually
    446  1.1  christos    started from.  If nothing is displayed (-1) is returned.  */
    447  1.1  christos int
    448  1.1  christos tui_display_registers_from_line (int line_no,
    449  1.1  christos 				 int force_display)
    450  1.1  christos {
    451  1.1  christos   if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
    452  1.1  christos     {
    453  1.1  christos       int line, element_no;
    454  1.1  christos 
    455  1.1  christos       if (line_no < 0)
    456  1.1  christos 	line = 0;
    457  1.1  christos       else if (force_display)
    458  1.1  christos 	{ /* If we must display regs (force_display is true), then
    459  1.1  christos 	     make sure that we don't display off the end of the
    460  1.1  christos 	     registers.  */
    461  1.1  christos 	  if (line_no >= tui_last_regs_line_no ())
    462  1.1  christos 	    {
    463  1.1  christos 	      if ((line = tui_line_from_reg_element_no (
    464  1.1  christos 		 TUI_DATA_WIN->detail.data_display_info.regs_content_count - 1)) < 0)
    465  1.1  christos 		line = 0;
    466  1.1  christos 	    }
    467  1.1  christos 	  else
    468  1.1  christos 	    line = line_no;
    469  1.1  christos 	}
    470  1.1  christos       else
    471  1.1  christos 	line = line_no;
    472  1.1  christos 
    473  1.1  christos       element_no = tui_first_reg_element_no_inline (line);
    474  1.1  christos       if (element_no
    475  1.1  christos 	  < TUI_DATA_WIN->detail.data_display_info.regs_content_count)
    476  1.1  christos 	tui_display_reg_element_at_line (element_no, line);
    477  1.1  christos       else
    478  1.1  christos 	line = (-1);
    479  1.1  christos 
    480  1.1  christos       return line;
    481  1.1  christos     }
    482  1.1  christos 
    483  1.1  christos   return (-1);			/* Nothing was displayed.  */
    484  1.1  christos }
    485  1.1  christos 
    486  1.1  christos 
    487  1.1  christos /* This function check all displayed registers for changes in values,
    488  1.1  christos    given a particular frame.  If the values have changed, they are
    489  1.1  christos    updated with the new value and highlighted.  */
    490  1.1  christos void
    491  1.1  christos tui_check_register_values (struct frame_info *frame)
    492  1.1  christos {
    493  1.1  christos   if (TUI_DATA_WIN != NULL
    494  1.1  christos       && TUI_DATA_WIN->generic.is_visible)
    495  1.1  christos     {
    496  1.1  christos       struct tui_data_info *display_info
    497  1.1  christos         = &TUI_DATA_WIN->detail.data_display_info;
    498  1.1  christos 
    499  1.1  christos       if (display_info->regs_content_count <= 0
    500  1.1  christos 	  && display_info->display_regs)
    501  1.1  christos 	tui_show_registers (display_info->current_group);
    502  1.1  christos       else
    503  1.1  christos 	{
    504  1.1  christos 	  int i;
    505  1.1  christos 
    506  1.1  christos 	  for (i = 0; (i < display_info->regs_content_count); i++)
    507  1.1  christos 	    {
    508  1.1  christos 	      struct tui_data_element *data;
    509  1.1  christos 	      struct tui_gen_win_info *data_item_win_ptr;
    510  1.1  christos 	      int was_hilighted;
    511  1.1  christos 
    512  1.1  christos 	      data_item_win_ptr = &display_info->regs_content[i]->
    513  1.1  christos                 which_element.data_window;
    514  1.1  christos 	      data = &((struct tui_win_element *)
    515  1.1  christos                        data_item_win_ptr->content[0])->which_element.data;
    516  1.1  christos 	      was_hilighted = data->highlight;
    517  1.1  christos 
    518  1.1  christos               tui_get_register (frame, data,
    519  1.1  christos                                 data->item_no, &data->highlight);
    520  1.1  christos 
    521  1.1  christos 	      if (data->highlight || was_hilighted)
    522  1.1  christos 		{
    523  1.1  christos                   tui_display_register (data, data_item_win_ptr);
    524  1.1  christos 		}
    525  1.1  christos 	    }
    526  1.1  christos 	}
    527  1.1  christos     }
    528  1.1  christos }
    529  1.1  christos 
    530  1.1  christos /* Display a register in a window.  If hilite is TRUE, then the value
    531  1.1  christos    will be displayed in reverse video.  */
    532  1.1  christos static void
    533  1.1  christos tui_display_register (struct tui_data_element *data,
    534  1.1  christos                       struct tui_gen_win_info *win_info)
    535  1.1  christos {
    536  1.1  christos   if (win_info->handle != (WINDOW *) NULL)
    537  1.1  christos     {
    538  1.1  christos       int i;
    539  1.1  christos 
    540  1.1  christos       if (data->highlight)
    541  1.1  christos 	/* We ignore the return value, casting it to void in order to avoid
    542  1.1  christos 	   a compiler warning.  The warning itself was introduced by a patch
    543  1.1  christos 	   to ncurses 5.7 dated 2009-08-29, changing this macro to expand
    544  1.1  christos 	   to code that causes the compiler to generate an unused-value
    545  1.1  christos 	   warning.  */
    546  1.1  christos 	(void) wstandout (win_info->handle);
    547  1.1  christos 
    548  1.1  christos       wmove (win_info->handle, 0, 0);
    549  1.1  christos       for (i = 1; i < win_info->width; i++)
    550  1.1  christos         waddch (win_info->handle, ' ');
    551  1.1  christos       wmove (win_info->handle, 0, 0);
    552  1.1  christos       if (data->content)
    553  1.1  christos         waddstr (win_info->handle, data->content);
    554  1.1  christos 
    555  1.1  christos       if (data->highlight)
    556  1.1  christos 	/* We ignore the return value, casting it to void in order to avoid
    557  1.1  christos 	   a compiler warning.  The warning itself was introduced by a patch
    558  1.1  christos 	   to ncurses 5.7 dated 2009-08-29, changing this macro to expand
    559  1.1  christos 	   to code that causes the compiler to generate an unused-value
    560  1.1  christos 	   warning.  */
    561  1.1  christos 	(void) wstandend (win_info->handle);
    562  1.1  christos       tui_refresh_win (win_info);
    563  1.1  christos     }
    564  1.1  christos }
    565  1.1  christos 
    566  1.1  christos static void
    567  1.1  christos tui_reg_next_command (char *arg, int from_tty)
    568  1.1  christos {
    569  1.1  christos   struct gdbarch *gdbarch = get_current_arch ();
    570  1.1  christos 
    571  1.1  christos   if (TUI_DATA_WIN != 0)
    572  1.1  christos     {
    573  1.1  christos       struct reggroup *group
    574  1.1  christos         = TUI_DATA_WIN->detail.data_display_info.current_group;
    575  1.1  christos 
    576  1.1  christos       group = reggroup_next (gdbarch, group);
    577  1.1  christos       if (group == 0)
    578  1.1  christos         group = reggroup_next (gdbarch, 0);
    579  1.1  christos 
    580  1.1  christos       if (group)
    581  1.1  christos         tui_show_registers (group);
    582  1.1  christos     }
    583  1.1  christos }
    584  1.1  christos 
    585  1.1  christos static void
    586  1.1  christos tui_reg_float_command (char *arg, int from_tty)
    587  1.1  christos {
    588  1.1  christos   tui_show_registers (float_reggroup);
    589  1.1  christos }
    590  1.1  christos 
    591  1.1  christos static void
    592  1.1  christos tui_reg_general_command (char *arg, int from_tty)
    593  1.1  christos {
    594  1.1  christos   tui_show_registers (general_reggroup);
    595  1.1  christos }
    596  1.1  christos 
    597  1.1  christos static void
    598  1.1  christos tui_reg_system_command (char *arg, int from_tty)
    599  1.1  christos {
    600  1.1  christos   tui_show_registers (system_reggroup);
    601  1.1  christos }
    602  1.1  christos 
    603  1.1  christos static struct cmd_list_element *tuireglist;
    604  1.1  christos 
    605  1.1  christos static void
    606  1.1  christos tui_reg_command (char *args, int from_tty)
    607  1.1  christos {
    608  1.1  christos   printf_unfiltered (_("\"tui reg\" must be followed by the name of a "
    609  1.1  christos                      "tui reg command.\n"));
    610  1.1  christos   help_list (tuireglist, "tui reg ", -1, gdb_stdout);
    611  1.1  christos }
    612  1.1  christos 
    613  1.1  christos /* Provide a prototype to silence -Wmissing-prototypes.  */
    614  1.1  christos extern initialize_file_ftype _initialize_tui_regs;
    615  1.1  christos 
    616  1.1  christos void
    617  1.1  christos _initialize_tui_regs (void)
    618  1.1  christos {
    619  1.1  christos   struct cmd_list_element **tuicmd;
    620  1.1  christos 
    621  1.1  christos   tuicmd = tui_get_cmd_list ();
    622  1.1  christos 
    623  1.1  christos   add_prefix_cmd ("reg", class_tui, tui_reg_command,
    624  1.1  christos                   _("TUI commands to control the register window."),
    625  1.1  christos                   &tuireglist, "tui reg ", 0,
    626  1.1  christos                   tuicmd);
    627  1.1  christos 
    628  1.1  christos   add_cmd ("float", class_tui, tui_reg_float_command,
    629  1.1  christos            _("Display only floating point registers."),
    630  1.1  christos            &tuireglist);
    631  1.1  christos   add_cmd ("general", class_tui, tui_reg_general_command,
    632  1.1  christos            _("Display only general registers."),
    633  1.1  christos            &tuireglist);
    634  1.1  christos   add_cmd ("system", class_tui, tui_reg_system_command,
    635  1.1  christos            _("Display only system registers."),
    636  1.1  christos            &tuireglist);
    637  1.1  christos   add_cmd ("next", class_tui, tui_reg_next_command,
    638  1.1  christos            _("Display next register group."),
    639  1.1  christos            &tuireglist);
    640  1.1  christos 
    641  1.1  christos   if (xdb_commands)
    642  1.1  christos     {
    643  1.1  christos       add_com ("fr", class_tui, tui_reg_float_command,
    644  1.1  christos 	       _("Display only floating point registers\n"));
    645  1.1  christos       add_com ("gr", class_tui, tui_reg_general_command,
    646  1.1  christos 	       _("Display only general registers\n"));
    647  1.1  christos       add_com ("sr", class_tui, tui_reg_system_command,
    648  1.1  christos 	       _("Display only special registers\n"));
    649  1.1  christos       add_com ("+r", class_tui, tui_scroll_regs_forward_command,
    650  1.1  christos 	       _("Scroll the registers window forward\n"));
    651  1.1  christos       add_com ("-r", class_tui, tui_scroll_regs_backward_command,
    652  1.1  christos 	       _("Scroll the register window backward\n"));
    653  1.1  christos     }
    654  1.1  christos }
    655  1.1  christos 
    656  1.1  christos 
    657  1.1  christos /*****************************************
    658  1.1  christos ** STATIC LOCAL FUNCTIONS                 **
    659  1.1  christos ******************************************/
    660  1.1  christos 
    661  1.1  christos static void
    662  1.1  christos tui_restore_gdbout (void *ui)
    663  1.1  christos {
    664  1.1  christos   ui_file_delete (gdb_stdout);
    665  1.1  christos   gdb_stdout = (struct ui_file*) ui;
    666  1.1  christos   pagination_enabled = 1;
    667  1.1  christos }
    668  1.1  christos 
    669  1.1  christos /* Get the register from the frame and return a printable
    670  1.1  christos    representation of it.  */
    671  1.1  christos 
    672  1.1  christos static char *
    673  1.1  christos tui_register_format (struct frame_info *frame, int regnum)
    674  1.1  christos {
    675  1.1  christos   struct gdbarch *gdbarch = get_frame_arch (frame);
    676  1.1  christos   struct ui_file *stream;
    677  1.1  christos   struct ui_file *old_stdout;
    678  1.1  christos   struct cleanup *cleanups;
    679  1.1  christos   char *p, *s;
    680  1.1  christos   char *ret;
    681  1.1  christos 
    682  1.1  christos   pagination_enabled = 0;
    683  1.1  christos   old_stdout = gdb_stdout;
    684  1.1  christos   stream = tui_sfileopen (256);
    685  1.1  christos   gdb_stdout = stream;
    686  1.1  christos   cleanups = make_cleanup (tui_restore_gdbout, (void*) old_stdout);
    687  1.1  christos   gdbarch_print_registers_info (gdbarch, stream, frame, regnum, 1);
    688  1.1  christos 
    689  1.1  christos   /* Save formatted output in the buffer.  */
    690  1.1  christos   p = tui_file_get_strbuf (stream);
    691  1.1  christos 
    692  1.1  christos   /* Remove the possible \n.  */
    693  1.1  christos   s = strrchr (p, '\n');
    694  1.1  christos   if (s && s[1] == 0)
    695  1.1  christos     *s = 0;
    696  1.1  christos 
    697  1.1  christos   ret = xstrdup (p);
    698  1.1  christos   do_cleanups (cleanups);
    699  1.1  christos 
    700  1.1  christos   return ret;
    701  1.1  christos }
    702  1.1  christos 
    703  1.1  christos /* Get the register value from the given frame and format it for the
    704  1.1  christos    display.  When changep is set, check if the new register value has
    705  1.1  christos    changed with respect to the previous call.  */
    706  1.1  christos static enum tui_status
    707  1.1  christos tui_get_register (struct frame_info *frame,
    708  1.1  christos                   struct tui_data_element *data,
    709  1.1  christos 		  int regnum, int *changedp)
    710  1.1  christos {
    711  1.1  christos   enum tui_status ret = TUI_FAILURE;
    712  1.1  christos 
    713  1.1  christos   if (changedp)
    714  1.1  christos     *changedp = FALSE;
    715  1.1  christos   if (target_has_registers)
    716  1.1  christos     {
    717  1.1  christos       char *prev_content = data->content;
    718  1.1  christos 
    719  1.1  christos       data->content = tui_register_format (frame, regnum);
    720  1.1  christos 
    721  1.1  christos       if (changedp != NULL
    722  1.1  christos 	  && strcmp (prev_content, data->content) != 0)
    723  1.1  christos 	*changedp = 1;
    724  1.1  christos 
    725  1.1  christos       xfree (prev_content);
    726  1.1  christos 
    727  1.1  christos       ret = TUI_SUCCESS;
    728  1.1  christos     }
    729  1.1  christos   return ret;
    730  1.1  christos }
    731  1.1  christos 
    732  1.1  christos static void
    733  1.1  christos tui_scroll_regs_forward_command (char *arg, int from_tty)
    734  1.1  christos {
    735  1.1  christos   tui_scroll (FORWARD_SCROLL, TUI_DATA_WIN, 1);
    736  1.1  christos }
    737  1.1  christos 
    738  1.1  christos 
    739  1.1  christos static void
    740  1.1  christos tui_scroll_regs_backward_command (char *arg, int from_tty)
    741  1.1  christos {
    742  1.1  christos   tui_scroll (BACKWARD_SCROLL, TUI_DATA_WIN, 1);
    743  1.1  christos }
    744