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