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