]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/tui/tui-regs.c
2004-02-06 Andrew Cagney <cagney@redhat.com>
[thirdparty/binutils-gdb.git] / gdb / tui / tui-regs.c
1 /* TUI display registers in window.
2
3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
4 Foundation, Inc.
5
6 Contributed by Hewlett-Packard Company.
7
8 This file is part of GDB.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 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
22 Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
24
25 #include "defs.h"
26 #include "tui/tui.h"
27 #include "tui/tui-data.h"
28 #include "symtab.h"
29 #include "gdbtypes.h"
30 #include "gdbcmd.h"
31 #include "frame.h"
32 #include "regcache.h"
33 #include "inferior.h"
34 #include "target.h"
35 #include "tui/tui-layout.h"
36 #include "tui/tui-win.h"
37 #include "tui/tui-windata.h"
38 #include "tui/tui-wingeneral.h"
39 #include "tui/tui-file.h"
40
41 #ifdef HAVE_NCURSES_H
42 #include <ncurses.h>
43 #else
44 #ifdef HAVE_CURSES_H
45 #include <curses.h>
46 #endif
47 #endif
48
49 /*****************************************
50 ** LOCAL DEFINITIONS **
51 ******************************************/
52 #define DOUBLE_FLOAT_LABEL_WIDTH 6
53 #define DOUBLE_FLOAT_LABEL_FMT "%6.6s: "
54 #define DOUBLE_FLOAT_VALUE_WIDTH 30 /*min of 16 but may be in sci notation */
55
56 #define SINGLE_FLOAT_LABEL_WIDTH 6
57 #define SINGLE_FLOAT_LABEL_FMT "%6.6s: "
58 #define SINGLE_FLOAT_VALUE_WIDTH 25 /* min of 8 but may be in sci notation */
59
60 #define SINGLE_LABEL_WIDTH 16
61 #define SINGLE_LABEL_FMT "%10.10s: "
62 #define SINGLE_VALUE_WIDTH 20 /* minimum of 8 but may be in sci notation */
63
64 /* In the code HP gave Cygnus, this was actually a function call to a
65 PA-specific function, which was supposed to determine whether the
66 target was a 64-bit or 32-bit processor. However, the 64-bit
67 support wasn't complete, so we didn't merge that in, so we leave
68 this here as a stub. */
69 #define IS_64BIT 0
70
71 /*****************************************
72 ** STATIC DATA **
73 ******************************************/
74
75
76 /*****************************************
77 ** STATIC LOCAL FUNCTIONS FORWARD DECLS **
78 ******************************************/
79 static TuiStatus _tuiSetRegsContent
80 (int, int, struct frame_info *, TuiRegisterDisplayType, int);
81 static const char *_tuiRegisterName (int);
82 static TuiStatus _tuiGetRegisterRawValue (int, char *, struct frame_info *);
83 static void _tuiSetRegisterElement
84 (int, struct frame_info *, TuiDataElementPtr, int);
85 static void _tuiDisplayRegister (int, TuiGenWinInfoPtr, enum precision_type);
86 static void _tuiRegisterFormat
87 (char *, int, int, TuiDataElementPtr, enum precision_type);
88 static TuiStatus _tuiSetGeneralRegsContent (int);
89 static TuiStatus _tuiSetSpecialRegsContent (int);
90 static TuiStatus _tuiSetGeneralAndSpecialRegsContent (int);
91 static TuiStatus _tuiSetFloatRegsContent (TuiRegisterDisplayType, int);
92 static int _tuiRegValueHasChanged
93 (TuiDataElementPtr, struct frame_info *, char *);
94 static void _tuiShowFloat_command (char *, int);
95 static void _tuiShowGeneral_command (char *, int);
96 static void _tuiShowSpecial_command (char *, int);
97 static void _tui_vShowRegisters_commandSupport (TuiRegisterDisplayType);
98 static void _tuiToggleFloatRegs_command (char *, int);
99 static void _tuiScrollRegsForward_command (char *, int);
100 static void _tuiScrollRegsBackward_command (char *, int);
101
102
103
104 /*****************************************
105 ** PUBLIC FUNCTIONS **
106 ******************************************/
107
108 /* Answer the number of the last line in the regs display. If there
109 are no registers (-1) is returned. */
110 int
111 tui_last_regs_line_no (void)
112 {
113 register int numLines = (-1);
114
115 if (dataWin->detail.dataDisplayInfo.regsContentCount > 0)
116 {
117 numLines = (dataWin->detail.dataDisplayInfo.regsContentCount /
118 dataWin->detail.dataDisplayInfo.regsColumnCount);
119 if (dataWin->detail.dataDisplayInfo.regsContentCount %
120 dataWin->detail.dataDisplayInfo.regsColumnCount)
121 numLines++;
122 }
123 return numLines;
124 }
125
126
127 /* Answer the line number that the register element at elementNo is
128 on. If elementNo is greater than the number of register elements
129 there are, -1 is returned. */
130 int
131 tui_line_from_reg_element_no (int elementNo)
132 {
133 if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount)
134 {
135 int i, line = (-1);
136
137 i = 1;
138 while (line == (-1))
139 {
140 if (elementNo <
141 (dataWin->detail.dataDisplayInfo.regsColumnCount * i))
142 line = i - 1;
143 else
144 i++;
145 }
146
147 return line;
148 }
149 else
150 return (-1);
151 }
152
153
154 /* Answer the index of the first element in lineNo. If lineNo is past
155 the register area (-1) is returned. */
156 int
157 tui_first_reg_element_no_inline (int lineNo)
158 {
159 if ((lineNo * dataWin->detail.dataDisplayInfo.regsColumnCount)
160 <= dataWin->detail.dataDisplayInfo.regsContentCount)
161 return ((lineNo + 1) *
162 dataWin->detail.dataDisplayInfo.regsColumnCount) -
163 dataWin->detail.dataDisplayInfo.regsColumnCount;
164 else
165 return (-1);
166 }
167
168
169 /*
170 ** tuiLastRegElementNoInLine()
171 ** Answer the index of the last element in lineNo. If lineNo is past
172 ** the register area (-1) is returned.
173 */
174 int
175 tuiLastRegElementNoInLine (int lineNo)
176 {
177 if ((lineNo * dataWin->detail.dataDisplayInfo.regsColumnCount) <=
178 dataWin->detail.dataDisplayInfo.regsContentCount)
179 return ((lineNo + 1) *
180 dataWin->detail.dataDisplayInfo.regsColumnCount) - 1;
181 else
182 return (-1);
183 } /* tuiLastRegElementNoInLine */
184
185
186 /* Calculate the number of columns that should be used to display the
187 registers. */
188 int
189 tui_calculate_regs_column_count (TuiRegisterDisplayType dpyType)
190 {
191 int colCount, colWidth;
192
193 if (IS_64BIT || dpyType == TUI_DFLOAT_REGS)
194 colWidth = DOUBLE_FLOAT_VALUE_WIDTH + DOUBLE_FLOAT_LABEL_WIDTH;
195 else
196 {
197 if (dpyType == TUI_SFLOAT_REGS)
198 colWidth = SINGLE_FLOAT_VALUE_WIDTH + SINGLE_FLOAT_LABEL_WIDTH;
199 else
200 colWidth = SINGLE_VALUE_WIDTH + SINGLE_LABEL_WIDTH;
201 }
202 colCount = (dataWin->generic.width - 2) / colWidth;
203
204 return colCount;
205 } /* tuiCalulateRegsColumnCount */
206
207
208 /* Show the registers int the data window as indicated by dpyType. If
209 there is any other registers being displayed, then they are
210 cleared. What registers are displayed is dependent upon dpyType. */
211 void
212 tui_show_registers (TuiRegisterDisplayType dpyType)
213 {
214 TuiStatus ret = TUI_FAILURE;
215 int refreshValuesOnly = FALSE;
216
217 /* Say that registers should be displayed, even if there is a problem */
218 dataWin->detail.dataDisplayInfo.displayRegs = TRUE;
219
220 if (target_has_registers)
221 {
222 refreshValuesOnly =
223 (dpyType == dataWin->detail.dataDisplayInfo.regsDisplayType);
224 switch (dpyType)
225 {
226 case TUI_GENERAL_REGS:
227 ret = _tuiSetGeneralRegsContent (refreshValuesOnly);
228 break;
229 case TUI_SFLOAT_REGS:
230 case TUI_DFLOAT_REGS:
231 ret = _tuiSetFloatRegsContent (dpyType, refreshValuesOnly);
232 break;
233
234 /* could ifdef out */
235
236 case TUI_SPECIAL_REGS:
237 ret = _tuiSetSpecialRegsContent (refreshValuesOnly);
238 break;
239 case TUI_GENERAL_AND_SPECIAL_REGS:
240 ret = _tuiSetGeneralAndSpecialRegsContent (refreshValuesOnly);
241 break;
242
243 /* end of potential if def */
244
245 default:
246 break;
247 }
248 }
249 if (ret == TUI_FAILURE)
250 {
251 dataWin->detail.dataDisplayInfo.regsDisplayType = TUI_UNDEFINED_REGS;
252 tui_erase_data_content (NO_REGS_STRING);
253 }
254 else
255 {
256 int i;
257
258 /* Clear all notation of changed values */
259 for (i = 0; (i < dataWin->detail.dataDisplayInfo.regsContentCount); i++)
260 {
261 TuiGenWinInfoPtr dataItemWin;
262
263 dataItemWin = &dataWin->detail.dataDisplayInfo.
264 regsContent[i]->whichElement.dataWindow;
265 (&((TuiWinElementPtr)
266 dataItemWin->content[0])->whichElement.data)->highlight = FALSE;
267 }
268 dataWin->detail.dataDisplayInfo.regsDisplayType = dpyType;
269 tui_display_all_data ();
270 }
271 (tuiLayoutDef ())->regsDisplayType = dpyType;
272
273 return;
274 }
275
276
277 /* Function to display the registers in the content from
278 'startElementNo' until the end of the register content or the end
279 of the display height. No checking for displaying past the end of
280 the registers is done here. */
281 void
282 tui_display_registers_from (int startElementNo)
283 {
284 if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL &&
285 dataWin->detail.dataDisplayInfo.regsContentCount > 0)
286 {
287 register int i = startElementNo;
288 int j, valueCharsWide, itemWinWidth, curY, labelWidth;
289 enum precision_type precision;
290
291 precision = (dataWin->detail.dataDisplayInfo.regsDisplayType
292 == TUI_DFLOAT_REGS) ?
293 double_precision : unspecified_precision;
294 if (IS_64BIT ||
295 dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS)
296 {
297 valueCharsWide = DOUBLE_FLOAT_VALUE_WIDTH;
298 labelWidth = DOUBLE_FLOAT_LABEL_WIDTH;
299 }
300 else
301 {
302 if (dataWin->detail.dataDisplayInfo.regsDisplayType ==
303 TUI_SFLOAT_REGS)
304 {
305 valueCharsWide = SINGLE_FLOAT_VALUE_WIDTH;
306 labelWidth = SINGLE_FLOAT_LABEL_WIDTH;
307 }
308 else
309 {
310 valueCharsWide = SINGLE_VALUE_WIDTH;
311 labelWidth = SINGLE_LABEL_WIDTH;
312 }
313 }
314 itemWinWidth = valueCharsWide + labelWidth;
315 /*
316 ** Now create each data "sub" window, and write the display into it.
317 */
318 curY = 1;
319 while (i < dataWin->detail.dataDisplayInfo.regsContentCount &&
320 curY <= dataWin->generic.viewportHeight)
321 {
322 for (j = 0;
323 (j < dataWin->detail.dataDisplayInfo.regsColumnCount &&
324 i < dataWin->detail.dataDisplayInfo.regsContentCount); j++)
325 {
326 TuiGenWinInfoPtr dataItemWin;
327 TuiDataElementPtr dataElementPtr;
328
329 /* create the window if necessary */
330 dataItemWin = &dataWin->detail.dataDisplayInfo.
331 regsContent[i]->whichElement.dataWindow;
332 dataElementPtr = &((TuiWinElementPtr)
333 dataItemWin->content[0])->whichElement.data;
334 if (dataItemWin->handle == (WINDOW *) NULL)
335 {
336 dataItemWin->height = 1;
337 dataItemWin->width = (precision == double_precision) ?
338 itemWinWidth + 2 : itemWinWidth + 1;
339 dataItemWin->origin.x = (itemWinWidth * j) + 1;
340 dataItemWin->origin.y = curY;
341 tui_make_window (dataItemWin, DONT_BOX_WINDOW);
342 scrollok (dataItemWin->handle, FALSE);
343 }
344 touchwin (dataItemWin->handle);
345
346 /*
347 ** Get the printable representation of the register
348 ** and display it
349 */
350 _tuiDisplayRegister (
351 dataElementPtr->itemNo, dataItemWin, precision);
352 i++; /* next register */
353 }
354 curY++; /* next row; */
355 }
356 }
357
358 return;
359 }
360
361
362 /*
363 ** tuiDisplayRegElementAtLine().
364 ** Function to display the registers in the content from
365 ** 'startElementNo' on 'startLineNo' until the end of the
366 ** register content or the end of the display height.
367 ** This function checks that we won't display off the end
368 ** of the register display.
369 */
370 void
371 tuiDisplayRegElementAtLine (int startElementNo, int startLineNo)
372 {
373 if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL &&
374 dataWin->detail.dataDisplayInfo.regsContentCount > 0)
375 {
376 register int elementNo = startElementNo;
377
378 if (startElementNo != 0 && startLineNo != 0)
379 {
380 register int lastLineNo, firstLineOnLastPage;
381
382 lastLineNo = tui_last_regs_line_no ();
383 firstLineOnLastPage = lastLineNo - (dataWin->generic.height - 2);
384 if (firstLineOnLastPage < 0)
385 firstLineOnLastPage = 0;
386 /*
387 ** If there is no other data displayed except registers,
388 ** and the elementNo causes us to scroll past the end of the
389 ** registers, adjust what element to really start the display at.
390 */
391 if (dataWin->detail.dataDisplayInfo.dataContentCount <= 0 &&
392 startLineNo > firstLineOnLastPage)
393 elementNo = tui_first_reg_element_no_inline (firstLineOnLastPage);
394 }
395 tui_display_registers_from (elementNo);
396 }
397
398 return;
399 } /* tuiDisplayRegElementAtLine */
400
401
402
403 /* Function to display the registers starting at line lineNo in the
404 data window. Answers the line number that the display actually
405 started from. If nothing is displayed (-1) is returned. */
406 int
407 tui_display_registers_from_line (int lineNo, int forceDisplay)
408 {
409 if (dataWin->detail.dataDisplayInfo.regsContentCount > 0)
410 {
411 int line, elementNo;
412
413 if (lineNo < 0)
414 line = 0;
415 else if (forceDisplay)
416 { /*
417 ** If we must display regs (forceDisplay is true), then make
418 ** sure that we don't display off the end of the registers.
419 */
420 if (lineNo >= tui_last_regs_line_no ())
421 {
422 if ((line = tui_line_from_reg_element_no (
423 dataWin->detail.dataDisplayInfo.regsContentCount - 1)) < 0)
424 line = 0;
425 }
426 else
427 line = lineNo;
428 }
429 else
430 line = lineNo;
431
432 elementNo = tui_first_reg_element_no_inline (line);
433 if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount)
434 tuiDisplayRegElementAtLine (elementNo, line);
435 else
436 line = (-1);
437
438 return line;
439 }
440
441 return (-1); /* nothing was displayed */
442 }
443
444
445 /* This function check all displayed registers for changes in values,
446 given a particular frame. If the values have changed, they are
447 updated with the new value and highlighted. */
448 void
449 tui_check_register_values (struct frame_info *frame)
450 {
451 if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
452 {
453 if (dataWin->detail.dataDisplayInfo.regsContentCount <= 0 &&
454 dataWin->detail.dataDisplayInfo.displayRegs)
455 tui_show_registers ((tuiLayoutDef ())->regsDisplayType);
456 else
457 {
458 int i, j;
459 char rawBuf[MAX_REGISTER_SIZE];
460
461 for (i = 0;
462 (i < dataWin->detail.dataDisplayInfo.regsContentCount); i++)
463 {
464 TuiDataElementPtr dataElementPtr;
465 TuiGenWinInfoPtr dataItemWinPtr;
466 int wasHilighted;
467
468 dataItemWinPtr = &dataWin->detail.dataDisplayInfo.
469 regsContent[i]->whichElement.dataWindow;
470 dataElementPtr = &((TuiWinElementPtr)
471 dataItemWinPtr->content[0])->whichElement.data;
472 wasHilighted = dataElementPtr->highlight;
473 dataElementPtr->highlight =
474 _tuiRegValueHasChanged (dataElementPtr, frame, &rawBuf[0]);
475 if (dataElementPtr->highlight)
476 {
477 int size;
478
479 size = DEPRECATED_REGISTER_RAW_SIZE (dataElementPtr->itemNo);
480 for (j = 0; j < size; j++)
481 ((char *) dataElementPtr->value)[j] = rawBuf[j];
482 _tuiDisplayRegister (
483 dataElementPtr->itemNo,
484 dataItemWinPtr,
485 ((dataWin->detail.dataDisplayInfo.regsDisplayType ==
486 TUI_DFLOAT_REGS) ?
487 double_precision : unspecified_precision));
488 }
489 else if (wasHilighted)
490 {
491 dataElementPtr->highlight = FALSE;
492 _tuiDisplayRegister (
493 dataElementPtr->itemNo,
494 dataItemWinPtr,
495 ((dataWin->detail.dataDisplayInfo.regsDisplayType ==
496 TUI_DFLOAT_REGS) ?
497 double_precision : unspecified_precision));
498 }
499 }
500 }
501 }
502 return;
503 }
504
505
506 /*
507 ** tuiToggleFloatRegs().
508 */
509 void
510 tuiToggleFloatRegs (void)
511 {
512 TuiLayoutDefPtr layoutDef = tuiLayoutDef ();
513
514 if (layoutDef->floatRegsDisplayType == TUI_SFLOAT_REGS)
515 layoutDef->floatRegsDisplayType = TUI_DFLOAT_REGS;
516 else
517 layoutDef->floatRegsDisplayType = TUI_SFLOAT_REGS;
518
519 if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible &&
520 (dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_SFLOAT_REGS ||
521 dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS))
522 tui_show_registers (layoutDef->floatRegsDisplayType);
523
524 return;
525 } /* tuiToggleFloatRegs */
526
527
528 void
529 _initialize_tuiRegs (void)
530 {
531 if (xdb_commands)
532 {
533 add_com ("fr", class_tui, _tuiShowFloat_command,
534 "Display only floating point registers\n");
535 add_com ("gr", class_tui, _tuiShowGeneral_command,
536 "Display only general registers\n");
537 add_com ("sr", class_tui, _tuiShowSpecial_command,
538 "Display only special registers\n");
539 add_com ("+r", class_tui, _tuiScrollRegsForward_command,
540 "Scroll the registers window forward\n");
541 add_com ("-r", class_tui, _tuiScrollRegsBackward_command,
542 "Scroll the register window backward\n");
543 add_com ("tf", class_tui, _tuiToggleFloatRegs_command,
544 "Toggle between single and double precision floating point registers.\n");
545 add_cmd (TUI_FLOAT_REGS_NAME_LOWER,
546 class_tui,
547 _tuiToggleFloatRegs_command,
548 "Toggle between single and double precision floating point \
549 registers.\n",
550 &togglelist);
551 }
552 }
553
554
555 /*****************************************
556 ** STATIC LOCAL FUNCTIONS **
557 ******************************************/
558
559
560 /*
561 ** _tuiRegisterName().
562 ** Return the register name.
563 */
564 static const char *
565 _tuiRegisterName (int regNum)
566 {
567 return REGISTER_NAME (regNum);
568 }
569 extern int pagination_enabled;
570
571 static void
572 tui_restore_gdbout (void *ui)
573 {
574 ui_file_delete (gdb_stdout);
575 gdb_stdout = (struct ui_file*) ui;
576 pagination_enabled = 1;
577 }
578
579 /*
580 ** _tuiRegisterFormat
581 ** Function to format the register name and value into a buffer,
582 ** suitable for printing or display
583 */
584 static void
585 _tuiRegisterFormat (char *buf, int bufLen, int regNum,
586 TuiDataElementPtr dataElement,
587 enum precision_type precision)
588 {
589 struct ui_file *stream;
590 struct ui_file *old_stdout;
591 const char *name;
592 struct cleanup *cleanups;
593 char *p;
594 int pos;
595
596 name = REGISTER_NAME (regNum);
597 if (name == 0)
598 {
599 strcpy (buf, "");
600 return;
601 }
602
603 pagination_enabled = 0;
604 old_stdout = gdb_stdout;
605 stream = tui_sfileopen (bufLen);
606 gdb_stdout = stream;
607 cleanups = make_cleanup (tui_restore_gdbout, (void*) old_stdout);
608 gdbarch_print_registers_info (current_gdbarch, stream, deprecated_selected_frame,
609 regNum, 1);
610
611 /* Save formatted output in the buffer. */
612 p = tui_file_get_strbuf (stream);
613 pos = 0;
614 while (*p && *p == *name++ && bufLen)
615 {
616 *buf++ = *p++;
617 bufLen--;
618 pos++;
619 }
620 while (*p == ' ')
621 p++;
622 while (pos < 8 && bufLen)
623 {
624 *buf++ = ' ';
625 bufLen--;
626 pos++;
627 }
628 strncpy (buf, p, bufLen);
629
630 /* Remove the possible \n. */
631 p = strchr (buf, '\n');
632 if (p)
633 *p = 0;
634
635 do_cleanups (cleanups);
636 }
637
638
639 #define NUM_GENERAL_REGS 32
640 /*
641 ** _tuiSetGeneralRegsContent().
642 ** Set the content of the data window to consist of the general registers.
643 */
644 static TuiStatus
645 _tuiSetGeneralRegsContent (int refreshValuesOnly)
646 {
647 return (_tuiSetRegsContent (0,
648 NUM_GENERAL_REGS - 1,
649 deprecated_selected_frame,
650 TUI_GENERAL_REGS,
651 refreshValuesOnly));
652
653 } /* _tuiSetGeneralRegsContent */
654
655
656 #ifndef PCOQ_HEAD_REGNUM
657 #define START_SPECIAL_REGS 0
658 #else
659 #define START_SPECIAL_REGS PCOQ_HEAD_REGNUM
660 #endif
661
662 /*
663 ** _tuiSetSpecialRegsContent().
664 ** Set the content of the data window to consist of the special registers.
665 */
666 static TuiStatus
667 _tuiSetSpecialRegsContent (int refreshValuesOnly)
668 {
669 TuiStatus ret = TUI_FAILURE;
670 int endRegNum;
671
672 endRegNum = FP0_REGNUM - 1;
673 ret = _tuiSetRegsContent (START_SPECIAL_REGS,
674 endRegNum,
675 deprecated_selected_frame,
676 TUI_SPECIAL_REGS,
677 refreshValuesOnly);
678
679 return ret;
680 } /* _tuiSetSpecialRegsContent */
681
682
683 /*
684 ** _tuiSetGeneralAndSpecialRegsContent().
685 ** Set the content of the data window to consist of the special registers.
686 */
687 static TuiStatus
688 _tuiSetGeneralAndSpecialRegsContent (int refreshValuesOnly)
689 {
690 TuiStatus ret = TUI_FAILURE;
691 int endRegNum = (-1);
692
693 endRegNum = FP0_REGNUM - 1;
694 ret = _tuiSetRegsContent (
695 0, endRegNum, deprecated_selected_frame, TUI_SPECIAL_REGS, refreshValuesOnly);
696
697 return ret;
698 } /* _tuiSetGeneralAndSpecialRegsContent */
699
700 /*
701 ** _tuiSetFloatRegsContent().
702 ** Set the content of the data window to consist of the float registers.
703 */
704 static TuiStatus
705 _tuiSetFloatRegsContent (TuiRegisterDisplayType dpyType, int refreshValuesOnly)
706 {
707 TuiStatus ret = TUI_FAILURE;
708 int startRegNum;
709
710 startRegNum = FP0_REGNUM;
711 ret = _tuiSetRegsContent (startRegNum,
712 NUM_REGS - 1,
713 deprecated_selected_frame,
714 dpyType,
715 refreshValuesOnly);
716
717 return ret;
718 } /* _tuiSetFloatRegsContent */
719
720
721 /*
722 ** _tuiRegValueHasChanged().
723 ** Answer TRUE if the register's value has changed, FALSE otherwise.
724 ** If TRUE, newValue is filled in with the new value.
725 */
726 static int
727 _tuiRegValueHasChanged (TuiDataElementPtr dataElement,
728 struct frame_info *frame,
729 char *newValue)
730 {
731 int hasChanged = FALSE;
732
733 if (dataElement->itemNo != UNDEFINED_ITEM &&
734 _tuiRegisterName (dataElement->itemNo) != (char *) NULL)
735 {
736 char rawBuf[MAX_REGISTER_SIZE];
737 int i;
738
739 if (_tuiGetRegisterRawValue (
740 dataElement->itemNo, rawBuf, frame) == TUI_SUCCESS)
741 {
742 int size = DEPRECATED_REGISTER_RAW_SIZE (dataElement->itemNo);
743
744 for (i = 0; (i < size && !hasChanged); i++)
745 hasChanged = (((char *) dataElement->value)[i] != rawBuf[i]);
746 if (hasChanged && newValue != (char *) NULL)
747 {
748 for (i = 0; i < size; i++)
749 newValue[i] = rawBuf[i];
750 }
751 }
752 }
753 return hasChanged;
754 } /* _tuiRegValueHasChanged */
755
756
757
758 /*
759 ** _tuiGetRegisterRawValue().
760 ** Get the register raw value. The raw value is returned in regValue.
761 */
762 static TuiStatus
763 _tuiGetRegisterRawValue (int regNum, char *regValue, struct frame_info *frame)
764 {
765 TuiStatus ret = TUI_FAILURE;
766
767 if (target_has_registers)
768 {
769 get_frame_register (frame, regNum, regValue);
770 /* NOTE: cagney/2003-03-13: This is bogus. It is refering to
771 the register cache and not the frame which could have pulled
772 the register value off the stack. */
773 if (register_cached (regNum) >= 0)
774 ret = TUI_SUCCESS;
775 }
776 return ret;
777 } /* _tuiGetRegisterRawValue */
778
779
780
781 /*
782 ** _tuiSetRegisterElement().
783 ** Function to initialize a data element with the input and
784 ** the register value.
785 */
786 static void
787 _tuiSetRegisterElement (int regNum, struct frame_info *frame,
788 TuiDataElementPtr dataElement,
789 int refreshValueOnly)
790 {
791 if (dataElement != (TuiDataElementPtr) NULL)
792 {
793 if (!refreshValueOnly)
794 {
795 dataElement->itemNo = regNum;
796 dataElement->name = _tuiRegisterName (regNum);
797 dataElement->highlight = FALSE;
798 }
799 if (dataElement->value == (Opaque) NULL)
800 dataElement->value = (Opaque) xmalloc (MAX_REGISTER_SIZE);
801 if (dataElement->value != (Opaque) NULL)
802 _tuiGetRegisterRawValue (regNum, dataElement->value, frame);
803 }
804
805 return;
806 } /* _tuiSetRegisterElement */
807
808
809 /*
810 ** _tuiSetRegsContent().
811 ** Set the content of the data window to consist of the registers
812 ** numbered from startRegNum to endRegNum. Note that if
813 ** refreshValuesOnly is TRUE, startRegNum and endRegNum are ignored.
814 */
815 static TuiStatus
816 _tuiSetRegsContent (int startRegNum, int endRegNum,
817 struct frame_info *frame,
818 TuiRegisterDisplayType dpyType,
819 int refreshValuesOnly)
820 {
821 TuiStatus ret = TUI_FAILURE;
822 int numRegs = endRegNum - startRegNum + 1;
823 int allocatedHere = FALSE;
824
825 if (dataWin->detail.dataDisplayInfo.regsContentCount > 0 &&
826 !refreshValuesOnly)
827 {
828 freeDataContent (dataWin->detail.dataDisplayInfo.regsContent,
829 dataWin->detail.dataDisplayInfo.regsContentCount);
830 dataWin->detail.dataDisplayInfo.regsContentCount = 0;
831 }
832 if (dataWin->detail.dataDisplayInfo.regsContentCount <= 0)
833 {
834 dataWin->detail.dataDisplayInfo.regsContent =
835 allocContent (numRegs, DATA_WIN);
836 allocatedHere = TRUE;
837 }
838
839 if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL)
840 {
841 int i;
842
843 if (!refreshValuesOnly || allocatedHere)
844 {
845 dataWin->generic.content = (OpaquePtr) NULL;
846 dataWin->generic.contentSize = 0;
847 addContentElements (&dataWin->generic, numRegs);
848 dataWin->detail.dataDisplayInfo.regsContent =
849 (TuiWinContent) dataWin->generic.content;
850 dataWin->detail.dataDisplayInfo.regsContentCount = numRegs;
851 }
852 /*
853 ** Now set the register names and values
854 */
855 for (i = startRegNum; (i <= endRegNum); i++)
856 {
857 TuiGenWinInfoPtr dataItemWin;
858
859 dataItemWin = &dataWin->detail.dataDisplayInfo.
860 regsContent[i - startRegNum]->whichElement.dataWindow;
861 _tuiSetRegisterElement (
862 i,
863 frame,
864 &((TuiWinElementPtr) dataItemWin->content[0])->whichElement.data,
865 !allocatedHere && refreshValuesOnly);
866 }
867 dataWin->detail.dataDisplayInfo.regsColumnCount =
868 tui_calculate_regs_column_count (dpyType);
869 #ifdef LATER
870 if (dataWin->detail.dataDisplayInfo.dataContentCount > 0)
871 {
872 /* delete all the windows? */
873 /* realloc content equal to dataContentCount + regsContentCount */
874 /* append dataWin->detail.dataDisplayInfo.dataContent to content */
875 }
876 #endif
877 dataWin->generic.contentSize =
878 dataWin->detail.dataDisplayInfo.regsContentCount +
879 dataWin->detail.dataDisplayInfo.dataContentCount;
880 ret = TUI_SUCCESS;
881 }
882
883 return ret;
884 } /* _tuiSetRegsContent */
885
886
887 /*
888 ** _tuiDisplayRegister().
889 ** Function to display a register in a window. If hilite is TRUE,
890 ** than the value will be displayed in reverse video
891 */
892 static void
893 _tuiDisplayRegister (int regNum,
894 TuiGenWinInfoPtr winInfo, /* the data item window */
895 enum precision_type precision)
896 {
897 if (winInfo->handle != (WINDOW *) NULL)
898 {
899 int i;
900 char buf[40];
901 int valueCharsWide, labelWidth;
902 TuiDataElementPtr dataElementPtr = &((TuiWinContent)
903 winInfo->content)[0]->whichElement.data;
904
905 if (IS_64BIT ||
906 dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS)
907 {
908 valueCharsWide = DOUBLE_FLOAT_VALUE_WIDTH;
909 labelWidth = DOUBLE_FLOAT_LABEL_WIDTH;
910 }
911 else
912 {
913 if (dataWin->detail.dataDisplayInfo.regsDisplayType ==
914 TUI_SFLOAT_REGS)
915 {
916 valueCharsWide = SINGLE_FLOAT_VALUE_WIDTH;
917 labelWidth = SINGLE_FLOAT_LABEL_WIDTH;
918 }
919 else
920 {
921 valueCharsWide = SINGLE_VALUE_WIDTH;
922 labelWidth = SINGLE_LABEL_WIDTH;
923 }
924 }
925
926 buf[0] = (char) 0;
927 _tuiRegisterFormat (buf,
928 valueCharsWide + labelWidth,
929 regNum,
930 dataElementPtr,
931 precision);
932
933 if (dataElementPtr->highlight)
934 wstandout (winInfo->handle);
935
936 wmove (winInfo->handle, 0, 0);
937 for (i = 1; i < winInfo->width; i++)
938 waddch (winInfo->handle, ' ');
939 wmove (winInfo->handle, 0, 0);
940 waddstr (winInfo->handle, buf);
941
942 if (dataElementPtr->highlight)
943 wstandend (winInfo->handle);
944 tui_refresh_win (winInfo);
945 }
946 return;
947 } /* _tuiDisplayRegister */
948
949
950 static void
951 _tui_vShowRegisters_commandSupport (TuiRegisterDisplayType dpyType)
952 {
953
954 if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
955 { /* Data window already displayed, show the registers */
956 if (dataWin->detail.dataDisplayInfo.regsDisplayType != dpyType)
957 tui_show_registers (dpyType);
958 }
959 else
960 (tuiLayoutDef ())->regsDisplayType = dpyType;
961
962 return;
963 } /* _tui_vShowRegisters_commandSupport */
964
965
966 static void
967 _tuiShowFloat_command (char *arg, int fromTTY)
968 {
969 if (m_winPtrIsNull (dataWin) || !dataWin->generic.isVisible ||
970 (dataWin->detail.dataDisplayInfo.regsDisplayType != TUI_SFLOAT_REGS &&
971 dataWin->detail.dataDisplayInfo.regsDisplayType != TUI_DFLOAT_REGS))
972 _tui_vShowRegisters_commandSupport ((tuiLayoutDef ())->floatRegsDisplayType);
973
974 return;
975 } /* _tuiShowFloat_command */
976
977
978 static void
979 _tuiShowGeneral_command (char *arg, int fromTTY)
980 {
981 _tui_vShowRegisters_commandSupport (TUI_GENERAL_REGS);
982 }
983
984
985 static void
986 _tuiShowSpecial_command (char *arg, int fromTTY)
987 {
988 _tui_vShowRegisters_commandSupport (TUI_SPECIAL_REGS);
989 }
990
991
992 static void
993 _tuiToggleFloatRegs_command (char *arg, int fromTTY)
994 {
995 if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
996 tuiToggleFloatRegs ();
997 else
998 {
999 TuiLayoutDefPtr layoutDef = tuiLayoutDef ();
1000
1001 if (layoutDef->floatRegsDisplayType == TUI_SFLOAT_REGS)
1002 layoutDef->floatRegsDisplayType = TUI_DFLOAT_REGS;
1003 else
1004 layoutDef->floatRegsDisplayType = TUI_SFLOAT_REGS;
1005 }
1006
1007
1008 return;
1009 } /* _tuiToggleFloatRegs_command */
1010
1011
1012 static void
1013 _tuiScrollRegsForward_command (char *arg, int fromTTY)
1014 {
1015 tui_scroll (FORWARD_SCROLL, dataWin, 1);
1016 }
1017
1018
1019 static void
1020 _tuiScrollRegsBackward_command (char *arg, int fromTTY)
1021 {
1022 tui_scroll (BACKWARD_SCROLL, dataWin, 1);
1023 }