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