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