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