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