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