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