1 /* TUI display registers in window.
3 Copyright (C) 1998-2015 Free Software Foundation, Inc.
5 Contributed by Hewlett-Packard Company.
7 This file is part of GDB.
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.
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.
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/>. */
23 #include "arch-utils.h"
25 #include "tui/tui-data.h"
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"
38 #include "tui/tui-regs.h"
39 #include "reggroups.h"
42 #include "gdb_curses.h"
45 /*****************************************
46 ** STATIC LOCAL FUNCTIONS FORWARD DECLS **
47 ******************************************/
49 tui_display_register (struct tui_data_element *data,
50 struct tui_gen_win_info *win_info);
52 static enum tui_status tui_show_register_group (struct reggroup *group,
53 struct frame_info *frame,
54 int refresh_values_only);
56 static enum tui_status tui_get_register (struct frame_info *frame,
57 struct tui_data_element *data,
58 int regnum, int *changedp);
60 static void tui_scroll_regs_forward_command (char *, int);
61 static void tui_scroll_regs_backward_command (char *, int);
65 /*****************************************
66 ** PUBLIC FUNCTIONS **
67 ******************************************/
69 /* Answer the number of the last line in the regs display. If there
70 are no registers (-1) is returned. */
72 tui_last_regs_line_no (void)
76 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
78 num_lines = (TUI_DATA_WIN->detail.data_display_info.regs_content_count /
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)
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
90 there are, -1 is returned. */
92 tui_line_from_reg_element_no (int element_no)
94 if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count)
102 (TUI_DATA_WIN->detail.data_display_info.regs_column_count * i))
115 /* Answer the index of the first element in line_no. If line_no is
116 past the register area (-1) is returned. */
118 tui_first_reg_element_no_inline (int line_no)
120 if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count)
121 <= TUI_DATA_WIN->detail.data_display_info.regs_content_count)
122 return ((line_no + 1) *
123 TUI_DATA_WIN->detail.data_display_info.regs_column_count) -
124 TUI_DATA_WIN->detail.data_display_info.regs_column_count;
130 /* Show the registers of the given group in the data window
131 and refresh the window. */
133 tui_show_registers (struct reggroup *group)
135 enum tui_status ret = TUI_FAILURE;
136 struct tui_data_info *display_info;
138 /* Make sure the curses mode is enabled. */
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);
146 display_info = &TUI_DATA_WIN->detail.data_display_info;
148 group = general_reggroup;
150 /* Say that registers should be displayed, even if there is a
152 display_info->display_regs = TRUE;
154 if (target_has_registers && target_has_stack && target_has_memory)
156 ret = tui_show_register_group (group, get_selected_frame (NULL),
157 group == display_info->current_group);
159 if (ret == TUI_FAILURE)
161 display_info->current_group = 0;
162 tui_erase_data_content (NO_REGS_STRING);
168 /* Clear all notation of changed values. */
169 for (i = 0; i < display_info->regs_content_count; i++)
171 struct tui_gen_win_info *data_item_win;
172 struct tui_win_element *win;
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;
179 display_info->current_group = group;
180 tui_display_all_data ();
185 /* Set the data window to display the registers of the register group
186 using the given frame. Values are refreshed only when
187 refresh_values_only is TRUE. */
189 static enum tui_status
190 tui_show_register_group (struct reggroup *group,
191 struct frame_info *frame,
192 int refresh_values_only)
194 struct gdbarch *gdbarch = get_frame_arch (frame);
195 enum tui_status ret = TUI_FAILURE;
197 int allocated_here = FALSE;
200 struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info;
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);
208 /* See how many registers must be displayed. */
211 regnum < gdbarch_num_regs (gdbarch)
212 + gdbarch_num_pseudo_regs (gdbarch);
217 /* Must be in the group. */
218 if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
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')
230 if (display_info->regs_content_count > 0 && !refresh_values_only)
232 tui_free_data_content (display_info->regs_content,
233 display_info->regs_content_count);
234 display_info->regs_content_count = 0;
237 if (display_info->regs_content_count <= 0)
239 display_info->regs_content = tui_alloc_content (nr_regs, DATA_WIN);
240 allocated_here = TRUE;
241 refresh_values_only = FALSE;
244 if (display_info->regs_content != (tui_win_content) NULL)
246 if (!refresh_values_only || allocated_here)
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;
256 /* Now set the register names and values. */
259 regnum < gdbarch_num_regs (gdbarch)
260 + gdbarch_num_pseudo_regs (gdbarch);
263 struct tui_gen_win_info *data_item_win;
264 struct tui_data_element *data;
267 /* Must be in the group. */
268 if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
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')
278 &display_info->regs_content[pos]->which_element.data_window;
279 data = &((struct tui_win_element *)
280 data_item_win->content[0])->which_element.data;
283 if (!refresh_values_only)
285 data->item_no = regnum;
287 data->highlight = FALSE;
289 tui_get_register (frame, data, regnum, 0);
294 TUI_DATA_WIN->generic.content_size =
295 display_info->regs_content_count + display_info->data_content_count;
302 /* Function to display the registers in the content from
303 'start_element_no' until the end of the register content or the end
304 of the display height. No checking for displaying past the end of
305 the registers is done here. */
307 tui_display_registers_from (int start_element_no)
309 struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info;
311 if (display_info->regs_content != (tui_win_content) NULL
312 && display_info->regs_content_count > 0)
314 int i = start_element_no;
315 int j, item_win_width, cur_y;
318 for (i = 0; i < display_info->regs_content_count; i++)
320 struct tui_data_element *data;
321 struct tui_gen_win_info *data_item_win;
326 = &display_info->regs_content[i]->which_element.data_window;
327 data = &((struct tui_win_element *)
328 data_item_win->content[0])->which_element.data;
335 len = 8 * ((len / 8) + 1);
343 item_win_width = max_len + 1;
344 i = start_element_no;
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;
351 (TUI_DATA_WIN->generic.width - 2) / display_info->regs_column_count;
353 /* Now create each data "sub" window, and write the display into
356 while (i < display_info->regs_content_count
357 && cur_y <= TUI_DATA_WIN->generic.viewport_height)
360 j < display_info->regs_column_count
361 && i < display_info->regs_content_count;
364 struct tui_gen_win_info *data_item_win;
365 struct tui_data_element *data_element_ptr;
367 /* Create the window if necessary. */
368 data_item_win = &display_info->regs_content[i]
369 ->which_element.data_window;
370 data_element_ptr = &((struct tui_win_element *)
371 data_item_win->content[0])->which_element.data;
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))
378 tui_delete_win (data_item_win->handle);
379 data_item_win->handle = 0;
382 if (data_item_win->handle == (WINDOW *) NULL)
384 data_item_win->height = 1;
385 data_item_win->width = item_win_width;
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);
391 touchwin (data_item_win->handle);
393 /* Get the printable representation of the register
395 tui_display_register (data_element_ptr, data_item_win);
396 i++; /* Next register. */
398 cur_y++; /* Next row. */
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. */
409 tui_display_reg_element_at_line (int start_element_no,
412 if (TUI_DATA_WIN->detail.data_display_info.regs_content
413 != (tui_win_content) NULL
414 && TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
416 int element_no = start_element_no;
418 if (start_element_no != 0 && start_line_no != 0)
420 int last_line_no, first_line_on_last_page;
422 last_line_no = tui_last_regs_line_no ();
423 first_line_on_last_page
424 = last_line_no - (TUI_DATA_WIN->generic.height - 2);
425 if (first_line_on_last_page < 0)
426 first_line_on_last_page = 0;
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
432 if (TUI_DATA_WIN->detail.data_display_info.data_content_count <= 0
433 && start_line_no > first_line_on_last_page)
435 = tui_first_reg_element_no_inline (first_line_on_last_page);
437 tui_display_registers_from (element_no);
443 /* Function to display the registers starting at line line_no in the
444 data window. Answers the line number that the display actually
445 started from. If nothing is displayed (-1) is returned. */
447 tui_display_registers_from_line (int line_no,
450 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
452 int line, element_no;
456 else if (force_display)
457 { /* If we must display regs (force_display is true), then
458 make sure that we don't display off the end of the
460 if (line_no >= tui_last_regs_line_no ())
462 if ((line = tui_line_from_reg_element_no (
463 TUI_DATA_WIN->detail.data_display_info.regs_content_count - 1)) < 0)
472 element_no = tui_first_reg_element_no_inline (line);
474 < TUI_DATA_WIN->detail.data_display_info.regs_content_count)
475 tui_display_reg_element_at_line (element_no, line);
482 return (-1); /* Nothing was displayed. */
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. */
490 tui_check_register_values (struct frame_info *frame)
492 if (TUI_DATA_WIN != NULL
493 && TUI_DATA_WIN->generic.is_visible)
495 struct tui_data_info *display_info
496 = &TUI_DATA_WIN->detail.data_display_info;
498 if (display_info->regs_content_count <= 0
499 && display_info->display_regs)
500 tui_show_registers (display_info->current_group);
505 for (i = 0; (i < display_info->regs_content_count); i++)
507 struct tui_data_element *data;
508 struct tui_gen_win_info *data_item_win_ptr;
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;
517 tui_get_register (frame, data,
518 data->item_no, &data->highlight);
520 if (data->highlight || was_hilighted)
522 tui_display_register (data, data_item_win_ptr);
529 /* Display a register in a window. If hilite is TRUE, then the value
530 will be displayed in reverse video. */
532 tui_display_register (struct tui_data_element *data,
533 struct tui_gen_win_info *win_info)
535 if (win_info->handle != (WINDOW *) NULL)
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
545 (void) wstandout (win_info->handle);
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);
552 waddstr (win_info->handle, data->content);
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
560 (void) wstandend (win_info->handle);
561 tui_refresh_win (win_info);
566 tui_reg_next_command (char *arg, int from_tty)
568 struct gdbarch *gdbarch = get_current_arch ();
570 if (TUI_DATA_WIN != 0)
572 struct reggroup *group
573 = TUI_DATA_WIN->detail.data_display_info.current_group;
575 group = reggroup_next (gdbarch, group);
577 group = reggroup_next (gdbarch, 0);
580 tui_show_registers (group);
585 tui_reg_float_command (char *arg, int from_tty)
587 tui_show_registers (float_reggroup);
591 tui_reg_general_command (char *arg, int from_tty)
593 tui_show_registers (general_reggroup);
597 tui_reg_system_command (char *arg, int from_tty)
599 tui_show_registers (system_reggroup);
602 static struct cmd_list_element *tuireglist;
605 tui_reg_command (char *args, int from_tty)
607 printf_unfiltered (_("\"tui reg\" must be followed by the name of a "
608 "tui reg command.\n"));
609 help_list (tuireglist, "tui reg ", all_commands, gdb_stdout);
612 /* Provide a prototype to silence -Wmissing-prototypes. */
613 extern initialize_file_ftype _initialize_tui_regs;
616 _initialize_tui_regs (void)
618 struct cmd_list_element **tuicmd;
620 tuicmd = tui_get_cmd_list ();
622 add_prefix_cmd ("reg", class_tui, tui_reg_command,
623 _("TUI commands to control the register window."),
624 &tuireglist, "tui reg ", 0,
627 add_cmd ("float", class_tui, tui_reg_float_command,
628 _("Display only floating point registers."),
630 add_cmd ("general", class_tui, tui_reg_general_command,
631 _("Display only general registers."),
633 add_cmd ("system", class_tui, tui_reg_system_command,
634 _("Display only system registers."),
636 add_cmd ("next", class_tui, tui_reg_next_command,
637 _("Display next register group."),
642 add_com ("fr", class_tui, tui_reg_float_command,
643 _("Display only floating point registers\n"));
644 add_com ("gr", class_tui, tui_reg_general_command,
645 _("Display only general registers\n"));
646 add_com ("sr", class_tui, tui_reg_system_command,
647 _("Display only special registers\n"));
648 add_com ("+r", class_tui, tui_scroll_regs_forward_command,
649 _("Scroll the registers window forward\n"));
650 add_com ("-r", class_tui, tui_scroll_regs_backward_command,
651 _("Scroll the register window backward\n"));
656 /*****************************************
657 ** STATIC LOCAL FUNCTIONS **
658 ******************************************/
661 tui_restore_gdbout (void *ui)
663 ui_file_delete (gdb_stdout);
664 gdb_stdout = (struct ui_file*) ui;
665 pagination_enabled = 1;
668 /* Get the register from the frame and return a printable
669 representation of it. */
672 tui_register_format (struct frame_info *frame, int regnum)
674 struct gdbarch *gdbarch = get_frame_arch (frame);
675 struct ui_file *stream;
676 struct ui_file *old_stdout;
677 struct cleanup *cleanups;
681 pagination_enabled = 0;
682 old_stdout = gdb_stdout;
683 stream = tui_sfileopen (256);
685 cleanups = make_cleanup (tui_restore_gdbout, (void*) old_stdout);
686 gdbarch_print_registers_info (gdbarch, stream, frame, regnum, 1);
688 /* Save formatted output in the buffer. */
689 p = tui_file_get_strbuf (stream);
691 /* Remove the possible \n. */
692 s = strrchr (p, '\n');
697 do_cleanups (cleanups);
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. */
705 static enum tui_status
706 tui_get_register (struct frame_info *frame,
707 struct tui_data_element *data,
708 int regnum, int *changedp)
710 enum tui_status ret = TUI_FAILURE;
714 if (target_has_registers)
716 char *prev_content = data->content;
718 data->content = tui_register_format (frame, regnum);
721 && strcmp (prev_content, data->content) != 0)
724 xfree (prev_content);
732 tui_scroll_regs_forward_command (char *arg, int from_tty)
734 tui_scroll (FORWARD_SCROLL, TUI_DATA_WIN, 1);
739 tui_scroll_regs_backward_command (char *arg, int from_tty)
741 tui_scroll (BACKWARD_SCROLL, TUI_DATA_WIN, 1);